aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuha Vehviläinen <jusu@users.sourceforge.net>2002-07-06 17:50:18 +0000
committerJuha Vehviläinen <jusu@users.sourceforge.net>2002-07-06 17:50:18 +0000
commit4d64e4cd434426234a5c313c151cd79b6afc299e (patch)
tree5c23dd6acc65b869741d3bb9d33912d74bb7407d
*** empty log message ***svn2git-root
svn path=/trunk/Framestein/; revision=27
-rw-r--r--CHANGELOG.txt130
-rw-r--r--Filters/BossTota.8bfbin0 -> 57344 bytes
-rw-r--r--Filters/BubbSpac.8bfbin0 -> 57344 bytes
-rw-r--r--Filters/ChloeMag.8bfbin0 -> 57344 bytes
-rw-r--r--Filters/ColSteps.8bfbin0 -> 57344 bytes
-rw-r--r--Filters/README.txt9
-rwxr-xr-xFramestein.exebin0 -> 874496 bytes
-rw-r--r--HARMON.jpgbin0 -> 31376 bytes
-rw-r--r--Patches/00 example-basics.pd38
-rw-r--r--Patches/01 example-video.pd30
-rw-r--r--Patches/02 example-docking.pd88
-rw-r--r--Patches/03 example-docking2.pd15
-rw-r--r--Patches/04 example-draganddrop.pd25
-rw-r--r--Patches/05 example-plugins.pd127
-rw-r--r--Patches/06 example-photoshopfilters.pd105
-rw-r--r--Patches/07 example-blending.pd57
-rw-r--r--Patches/08 example-masking.pd66
-rw-r--r--Patches/09 example-sonogram.pd74
-rw-r--r--Patches/10 example-waveformdisplay.pd126
-rw-r--r--Patches/11 example-browser.pd30
-rw-r--r--Patches/12 example-network.pd62
-rw-r--r--Patches/13 example-avioutput.pd61
-rw-r--r--Patches/14 example-hist.pd46
-rw-r--r--Patches/15 example-searchpath.pd28
-rw-r--r--Patches/README.txt1
-rw-r--r--Patches/arraysize.c44
-rw-r--r--Patches/arraysize.dllbin0 -> 36864 bytes
-rw-r--r--Patches/arraysize.expbin0 -> 594 bytes
-rw-r--r--Patches/arraysize.libbin0 -> 1986 bytes
-rw-r--r--Patches/arraysize.objbin0 -> 1761 bytes
-rw-r--r--Patches/bangx.pd10
-rw-r--r--Patches/buildstr.c51
-rw-r--r--Patches/buildstr.dllbin0 -> 36864 bytes
-rw-r--r--Patches/buildstr.expbin0 -> 586 bytes
-rw-r--r--Patches/buildstr.libbin0 -> 1970 bytes
-rw-r--r--Patches/buildstr.objbin0 -> 1830 bytes
-rw-r--r--Patches/count.pd17
-rw-r--r--Patches/displaydepth.h19
-rw-r--r--Patches/dllcall.h46
-rw-r--r--Patches/externals-documentation.pd342
-rw-r--r--Patches/fps.pd25
-rw-r--r--Patches/fs.avi.pd33
-rw-r--r--Patches/fs.blend.pd37
-rw-r--r--Patches/fs.browser.pd48
-rw-r--r--Patches/fs.copy.pd51
-rw-r--r--Patches/fs.draw.pd32
-rw-r--r--Patches/fs.event.pd30
-rw-r--r--Patches/fs.film.pd47
-rw-r--r--Patches/fs.frame.pd137
-rw-r--r--Patches/fs.framed.pd24
-rw-r--r--Patches/fs.fx.pd21
-rw-r--r--Patches/fs.hist.pd39
-rw-r--r--Patches/fs.info.pd33
-rw-r--r--Patches/fs.main.pd52
-rw-r--r--Patches/fs.mask.pd39
-rw-r--r--Patches/fs.rgb.pd31
-rw-r--r--Patches/fs.sonogram.pd63
-rw-r--r--Patches/fs.text.pd29
-rw-r--r--Patches/fs.waveform.pd146
-rw-r--r--Patches/fs.waveselection.pd47
-rw-r--r--Patches/fs_sender.pd7
-rw-r--r--Patches/init.pd9
-rw-r--r--Patches/l2s.c89
-rw-r--r--Patches/l2s.dllbin0 -> 28672 bytes
-rw-r--r--Patches/l2s.expbin0 -> 546 bytes
-rw-r--r--Patches/l2s.libbin0 -> 1884 bytes
-rw-r--r--Patches/l2s.objbin0 -> 2407 bytes
-rw-r--r--Patches/makefile38
-rw-r--r--Patches/noize.dllbin0 -> 36864 bytes
-rw-r--r--Patches/ooo.pd19
-rw-r--r--Patches/play.pd8
-rw-r--r--Patches/ramp.pd35
-rw-r--r--Patches/randombox.pd19
-rw-r--r--Patches/reset.pd8
-rw-r--r--Patches/sameonce.pd15
-rw-r--r--Patches/snapOut~.pd45
-rw-r--r--Patches/vcolor~.c96
-rw-r--r--Patches/vcolor~.dllbin0 -> 49152 bytes
-rw-r--r--Patches/vcolor~.expbin0 -> 599 bytes
-rw-r--r--Patches/vcolor~.libbin0 -> 1976 bytes
-rw-r--r--Patches/vcolor~.objbin0 -> 3898 bytes
-rw-r--r--Patches/vcopy.pd16
-rw-r--r--Patches/vdrawarray.c131
-rw-r--r--Patches/vdrawarray.dllbin0 -> 49152 bytes
-rw-r--r--Patches/vdrawarray.expbin0 -> 602 bytes
-rw-r--r--Patches/vdrawarray.libbin0 -> 2004 bytes
-rw-r--r--Patches/vdrawarray.objbin0 -> 4031 bytes
-rw-r--r--Patches/vframe.c262
-rw-r--r--Patches/vframe.dllbin0 -> 49152 bytes
-rw-r--r--Patches/vframe.expbin0 -> 570 bytes
-rw-r--r--Patches/vframe.h66
-rw-r--r--Patches/vframe.libbin0 -> 1936 bytes
-rw-r--r--Patches/vframe.objbin0 -> 7069 bytes
-rw-r--r--Patches/vframeread~.c123
-rw-r--r--Patches/vframeread~.dllbin0 -> 49152 bytes
-rw-r--r--Patches/vframeread~.expbin0 -> 631 bytes
-rw-r--r--Patches/vframeread~.libbin0 -> 2044 bytes
-rw-r--r--Patches/vframeread~.objbin0 -> 3703 bytes
-rw-r--r--Patches/videoscrub.pd29
-rw-r--r--Patches/vimport.pd11
-rw-r--r--Patches/vplugin.pd9
-rw-r--r--Patches/vref.pd10
-rw-r--r--Patches/vrgb~.c117
-rw-r--r--Patches/vrgb~.dllbin0 -> 49152 bytes
-rw-r--r--Patches/vrgb~.expbin0 -> 583 bytes
-rw-r--r--Patches/vrgb~.libbin0 -> 1942 bytes
-rw-r--r--Patches/vrgb~.objbin0 -> 3717 bytes
-rw-r--r--Patches/vsig~.c123
-rw-r--r--Patches/vsig~.dllbin0 -> 49152 bytes
-rw-r--r--Patches/vsig~.expbin0 -> 583 bytes
-rw-r--r--Patches/vsig~.libbin0 -> 1942 bytes
-rw-r--r--Patches/vsig~.objbin0 -> 3346 bytes
-rw-r--r--Patches/vsnapshot~.c139
-rw-r--r--Patches/vsnapshot~.dllbin0 -> 49152 bytes
-rw-r--r--Patches/vsnapshot~.expbin0 -> 623 bytes
-rw-r--r--Patches/vsnapshot~.libbin0 -> 2028 bytes
-rw-r--r--Patches/vsnapshot~.objbin0 -> 4210 bytes
-rw-r--r--Patches/vsnap~.pd18
-rw-r--r--PeRColate Framestein.pdfbin0 -> 7998 bytes
-rw-r--r--Plugins/2colors.cpp21
-rw-r--r--Plugins/2colors.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/2colors.expbin0 -> 627 bytes
-rw-r--r--Plugins/2colors.libbin0 -> 2066 bytes
-rw-r--r--Plugins/2colors.objbin0 -> 1133 bytes
-rw-r--r--Plugins/README.txt12
-rw-r--r--Plugins/bend.c86
-rw-r--r--Plugins/bend.dllbin0 -> 49152 bytes
-rw-r--r--Plugins/bend.expbin0 -> 697 bytes
-rw-r--r--Plugins/bend.libbin0 -> 2110 bytes
-rw-r--r--Plugins/bend.objbin0 -> 1726 bytes
-rw-r--r--Plugins/black.c13
-rw-r--r--Plugins/black.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/black.expbin0 -> 700 bytes
-rw-r--r--Plugins/black.libbin0 -> 2120 bytes
-rw-r--r--Plugins/black.objbin0 -> 560 bytes
-rw-r--r--Plugins/colortv.c69
-rw-r--r--Plugins/colortv.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/colortv.expbin0 -> 708 bytes
-rw-r--r--Plugins/colortv.libbin0 -> 2146 bytes
-rw-r--r--Plugins/colortv.objbin0 -> 864 bytes
-rw-r--r--Plugins/copy_vert.c30
-rw-r--r--Plugins/copy_vert.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/copy_vert.expbin0 -> 583 bytes
-rw-r--r--Plugins/copy_vert.libbin0 -> 1970 bytes
-rw-r--r--Plugins/copy_vert.objbin0 -> 816 bytes
-rw-r--r--Plugins/fs2vf.c49
-rw-r--r--Plugins/fs2vf.dllbin0 -> 36864 bytes
-rw-r--r--Plugins/fs2vf.expbin0 -> 575 bytes
-rw-r--r--Plugins/fs2vf.libbin0 -> 1932 bytes
-rw-r--r--Plugins/fs2vf.objbin0 -> 1894 bytes
-rw-r--r--Plugins/gol.c89
-rw-r--r--Plugins/gol.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/gol.expbin0 -> 567 bytes
-rw-r--r--Plugins/gol.libbin0 -> 1908 bytes
-rw-r--r--Plugins/gol.objbin0 -> 1878 bytes
-rw-r--r--Plugins/green.cpp14
-rw-r--r--Plugins/green.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/green.expbin0 -> 619 bytes
-rw-r--r--Plugins/green.libbin0 -> 2042 bytes
-rw-r--r--Plugins/green.objbin0 -> 849 bytes
-rw-r--r--Plugins/hist.cpp54
-rw-r--r--Plugins/hist.dllbin0 -> 45056 bytes
-rw-r--r--Plugins/hist.expbin0 -> 614 bytes
-rw-r--r--Plugins/hist.libbin0 -> 2032 bytes
-rw-r--r--Plugins/hist.objbin0 -> 1986 bytes
-rw-r--r--Plugins/makefile82
-rw-r--r--Plugins/makesliders.c40
-rw-r--r--Plugins/makesliders.dllbin0 -> 36864 bytes
-rw-r--r--Plugins/makesliders.expbin0 -> 599 bytes
-rw-r--r--Plugins/makesliders.libbin0 -> 2004 bytes
-rw-r--r--Plugins/makesliders.objbin0 -> 940 bytes
-rw-r--r--Plugins/ms.dllbin0 -> 36864 bytes
-rw-r--r--Plugins/noize.c21
-rw-r--r--Plugins/noize.dllbin0 -> 36864 bytes
-rw-r--r--Plugins/noize.expbin0 -> 700 bytes
-rw-r--r--Plugins/noize.libbin0 -> 2120 bytes
-rw-r--r--Plugins/noize.objbin0 -> 865 bytes
-rw-r--r--Plugins/pixels.h117
-rw-r--r--Plugins/plot.cpp25
-rw-r--r--Plugins/plot.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/plot.expbin0 -> 614 bytes
-rw-r--r--Plugins/plot.libbin0 -> 2032 bytes
-rw-r--r--Plugins/plot.objbin0 -> 1011 bytes
-rw-r--r--Plugins/plugin.h119
-rw-r--r--Plugins/rgb.c62
-rw-r--r--Plugins/rgb.dllbin0 -> 36864 bytes
-rw-r--r--Plugins/rgb.expbin0 -> 567 bytes
-rw-r--r--Plugins/rgb.libbin0 -> 1908 bytes
-rw-r--r--Plugins/rgb.objbin0 -> 1180 bytes
-rw-r--r--Plugins/rgbcopy.cpp28
-rw-r--r--Plugins/rgbcopy.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/rgbcopy.expbin0 -> 621 bytes
-rw-r--r--Plugins/rgbcopy.libbin0 -> 2062 bytes
-rw-r--r--Plugins/rgbcopy.objbin0 -> 1884 bytes
-rw-r--r--Plugins/setbits.c11
-rw-r--r--Plugins/setbits.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/setbits.expbin0 -> 583 bytes
-rw-r--r--Plugins/setbits.libbin0 -> 1956 bytes
-rw-r--r--Plugins/setbits.objbin0 -> 514 bytes
-rw-r--r--Plugins/sharemem.h61
-rw-r--r--Plugins/shuffle.c42
-rw-r--r--Plugins/shuffle.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/shuffle.expbin0 -> 583 bytes
-rw-r--r--Plugins/shuffle.libbin0 -> 1956 bytes
-rw-r--r--Plugins/shuffle.objbin0 -> 1020 bytes
-rw-r--r--Plugins/sonogram.cpp82
-rw-r--r--Plugins/sonogram.dllbin0 -> 45056 bytes
-rw-r--r--Plugins/sonogram.expbin0 -> 630 bytes
-rw-r--r--Plugins/sonogram.libbin0 -> 2080 bytes
-rw-r--r--Plugins/sonogram.objbin0 -> 2306 bytes
-rw-r--r--Plugins/subtract.cpp38
-rw-r--r--Plugins/subtract.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/subtract.expbin0 -> 630 bytes
-rw-r--r--Plugins/subtract.libbin0 -> 2080 bytes
-rw-r--r--Plugins/subtract.objbin0 -> 1409 bytes
-rw-r--r--Plugins/swap.cpp62
-rw-r--r--Plugins/swap.dllbin0 -> 36864 bytes
-rw-r--r--Plugins/swap.expbin0 -> 608 bytes
-rw-r--r--Plugins/swap.libbin0 -> 2026 bytes
-rw-r--r--Plugins/swap.objbin0 -> 1893 bytes
-rw-r--r--Plugins/tile.cpp59
-rw-r--r--Plugins/tile.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/tile.expbin0 -> 608 bytes
-rw-r--r--Plugins/tile.libbin0 -> 2026 bytes
-rw-r--r--Plugins/tile.objbin0 -> 1312 bytes
-rw-r--r--Plugins/vf2fs.c49
-rw-r--r--Plugins/vf2fs.dllbin0 -> 36864 bytes
-rw-r--r--Plugins/vf2fs.expbin0 -> 575 bytes
-rw-r--r--Plugins/vf2fs.libbin0 -> 1932 bytes
-rw-r--r--Plugins/vf2fs.objbin0 -> 1894 bytes
-rw-r--r--Plugins/xbend.c99
-rw-r--r--Plugins/xbend.dllbin0 -> 36864 bytes
-rw-r--r--Plugins/xbend.expbin0 -> 700 bytes
-rw-r--r--Plugins/xbend.libbin0 -> 2120 bytes
-rw-r--r--Plugins/xbend.objbin0 -> 1832 bytes
-rw-r--r--Plugins/xshred.c20
-rw-r--r--Plugins/xshred.dllbin0 -> 28672 bytes
-rw-r--r--Plugins/xshred.expbin0 -> 570 bytes
-rw-r--r--Plugins/xshred.libbin0 -> 1936 bytes
-rw-r--r--Plugins/xshred.objbin0 -> 640 bytes
-rw-r--r--README.txt75
-rw-r--r--Reija/01.jpgbin0 -> 37151 bytes
-rw-r--r--Reija/02.jpgbin0 -> 24320 bytes
-rw-r--r--Reija/03.jpgbin0 -> 30982 bytes
-rw-r--r--Reija/04.jpgbin0 -> 31003 bytes
-rw-r--r--Reija/05.jpgbin0 -> 26077 bytes
-rw-r--r--Reija/06.jpgbin0 -> 37365 bytes
-rw-r--r--Reija/07.jpgbin0 -> 35830 bytes
-rw-r--r--Reija/08.jpgbin0 -> 36637 bytes
-rw-r--r--Source/Filez.pas87
-rw-r--r--Source/Framestein.cfg39
-rw-r--r--Source/Framestein.dof91
-rw-r--r--Source/Framestein.dpr46
-rw-r--r--Source/Framestein.dsk222
-rw-r--r--Source/Framestein.resbin0 -> 4056 bytes
-rw-r--r--Source/FsAviWriter.pas888
-rw-r--r--Source/GPL.txt340
-rw-r--r--Source/README.txt36
-rw-r--r--Source/Strz.pas182
-rw-r--r--Source/configureunit.dfm157
-rw-r--r--Source/configureunit.pas120
-rw-r--r--Source/dc.inc42
-rw-r--r--Source/effectsunit.pas109
-rw-r--r--Source/fsDcAvi.pas1615
-rw-r--r--Source/fsaviunit.dfm23
-rw-r--r--Source/fsaviunit.pas103
-rw-r--r--Source/fsbrowserunit.dfm35
-rw-r--r--Source/fsbrowserunit.pas113
-rw-r--r--Source/fscopyunit.dfm26
-rw-r--r--Source/fscopyunit.pas349
-rw-r--r--Source/fsdrawunit.dfm17
-rw-r--r--Source/fsdrawunit.pas101
-rw-r--r--Source/fsformunit.pas18
-rw-r--r--Source/fsframeunit.dfm146
-rw-r--r--Source/fsframeunit.pas1098
-rw-r--r--Source/fsinfounit.dfm16
-rw-r--r--Source/fsinfounit.pas53
-rw-r--r--Source/fsspeedbutton.pas48
-rw-r--r--Source/fstextunit.dfm18
-rw-r--r--Source/fstextunit.pas148
-rw-r--r--Source/logunit.dfm100
-rw-r--r--Source/logunit.pas60
-rw-r--r--Source/mainunit.dfm3547
-rw-r--r--Source/mainunit.pas903
-rw-r--r--Source/pluginunit.pas227
-rw-r--r--Source/pshostunit.pas145
-rw-r--r--extract.wavbin0 -> 229580 bytes
-rw-r--r--head.avibin0 -> 82944 bytes
-rw-r--r--ijl15.dllbin0 -> 372736 bytes
289 files changed, 16850 insertions, 0 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
new file mode 100644
index 0000000..426adc3
--- /dev/null
+++ b/CHANGELOG.txt
@@ -0,0 +1,130 @@
+0.30
+- vframe supports plugin parameters
+- doubleclicking the framestein-logo equals "reset"
+- fs.frame "stayontop" OFF by default
+- got rid of the console, "Show debug" in menu instead (right-click the framestein-logo)
+- l2s from zexy included in Patches-dir, zexy no longer needed
+- disconnecting pd from fs will cause a reset
+
+0.29
+- example-basics.pd is really just the basics now
+- fs.event.pd: get more events from fs.frame (mousedown, mouseup, dropped filename)
+- fs.waveform.pd: array display with selection capabilities, see example-waveformdisplay.pd
+- new external vdrawarray for the previous: draw array contents on vframe
+- the really cool fs.mask.pd and example-masking.pd
+- the really cool fs.blend.pd and example-blending.pd
+- fs.frame button widget. try "button <receivename> <x> <y> <buttoncaption>"
+ (no more widgets are planned)
+- dragging fs.frame with <alt> down moves window, ignoring mousetrack_1
+- fs.sonogram made compatible with latest pd test-version
+- cleaned up some examples..
+
+0.28
+- finally, the ability to write AVIs! see example-avioutput.pd
+- added searchpath, see example-searchpath.pd
+
+ new in fs.frame:
+
+- "use <directory>" - like buffer, but no buffering (load on demand)
+- new popupmenu commands: save image as, undock
+- mousewheel functions as zoom (shift down to preserve aspect ratio)
+- fix: borders/stayontop discarded the image
+- dock <window title> string matching is now substring
+
+0.27
+- runs Adobe Photoshop Filter Plugins, see example-photoshopfilters.pd
+- hide/show messed fs.frame positions
+- vsnap~, wrapper for vsnapshot~
+
+0.26
+- no more typing docked window positions! see example-docking2.pd
+- easy loading of images from fs.frame popup-menu
+- new fs.frame commands: minimize, maximize, bringtofront, hidecursor_1, bufferize (copy to image buffer)
+- dock main window to pd on connect (out of the way)
+- init.pd to load patches correctly
+
+0.25
+- vframeread~: read image with a control-signal
+- vcolor~, merge r g and b channels (must be used with vrgb~)
+
+0.24
+- externals: vframe, vsig~, vsnapshot~, vrgb~, ...
+ in short, the ability to convert video to signal and back,
+ and run framestein plugins in pd.
+ see Patches\externals-documentation.pd
+
+0.23
+- fs.film
+- fs.hist and example-hist.pd
+- fs.sonogram and example-sonogram.pd
+- mouserect_1 will report rectangle "drawn" in frame (mousetrack_1 must be on)
+
+0.22
+- add: drag and drop images/video to fs.frame
+- add: videoscrub.pd
+
+0.21
+- add: dock frames to pd patches, see example-docking.pd
+- add: fs.info, get information of images (width, height and framecount)
+- add: fs.rgb, get rgb information of pixel at x, y
+- add: fs.frame reports mouse x and y thru second outlet
+- add: easy moving of frames (drag the window when mousetrack is off)
+- improved fs.browser, see example-browser.pd
+
+0.20
+- add: send_auto to automate sending frames thru network. works like send but
+ keeps sending frames on each flip until you give it send_manual
+- add: BETA of fs.browser, see example-browser.pd
+- fix: execution order of events was reversed. what was i thinking?
+- fix: most plugins now work on displays other than 16 bits
+- more meaningless plugins: copy_vert
+
+0.19
+- major fix: bigger patches were not initialized correctly
+- new plugins: rgbcopy
+- fix: colors to fs.draw and fs.text are now given in r g b,
+ instead of impossible one number
+- fix: more intelligent default positioning of fs.frames
+- fix: banging fs.main's reset-inlet resets framestein before recreating fs.*-objects
+- add: play.pd, really just |inlet|-|fps $1|-|next|-|outlet|, but i do that a lot
+
+0.18
+- add: sending frames thru network jpeg-compressed, see example-network.pd
+- add: some plugins, notably xbend, bend, shuffle, tile
+- add: pixels-class for easy iteration thru pixels in c++, see pixels.h and green.cpp
+- fix: finally fixed the annoying "asynchronous socket error" when exiting pd before fs
+
+0.17
+- add: plugins, write effects with C without recompiling Framestein
+- add: plugins colortv, noize and subtract
+
+0.16
+- add: effectsunit.pas shows how easy it is to add pixel level routines
+- fix: alpha, sub and add modes of fs.copy had fixed values :(
+- add: blend mode to fs.copy, same as alpha but i'm trying to make it faster
+- add: some raster operations for fs.copy, see fs.copy.pd for info
+- add: fs.draw for drawing boxes, lines and pixels
+- add: some implementation on fs.text
+- fix: access violation when closing a frame under copy operations
+- loading video no longer sets display to 1:1
+
+0.15
+- add: fs.frame accepts "SAVE <directory> <"BMP" or number for jpeg quality>"
+- add: framestein-link.pd and framestein-demo.pd
+
+0.14
+- fix: occasional access violation with "SEEK"
+- default copymodes are now "source_all" and "dest_all"
+- add: "reset" inlet to fs.main
+
+0.13
+- add: "Reset" to main popup-menu (right-click the logo)
+- "prev" for previous frame/buffered image
+- "seek 0.5*" will seek to middle of video/buffered images
+- updated documentation in fs.frame.pd
+
+0.12
+With source under GPL.
+
+0.1
+Initial version.
diff --git a/Filters/BossTota.8bf b/Filters/BossTota.8bf
new file mode 100644
index 0000000..9d1845a
--- /dev/null
+++ b/Filters/BossTota.8bf
Binary files differ
diff --git a/Filters/BubbSpac.8bf b/Filters/BubbSpac.8bf
new file mode 100644
index 0000000..f2d39f8
--- /dev/null
+++ b/Filters/BubbSpac.8bf
Binary files differ
diff --git a/Filters/ChloeMag.8bf b/Filters/ChloeMag.8bf
new file mode 100644
index 0000000..4c4c056
--- /dev/null
+++ b/Filters/ChloeMag.8bf
Binary files differ
diff --git a/Filters/ColSteps.8bf b/Filters/ColSteps.8bf
new file mode 100644
index 0000000..3354df5
--- /dev/null
+++ b/Filters/ColSteps.8bf
Binary files differ
diff --git a/Filters/README.txt b/Filters/README.txt
new file mode 100644
index 0000000..104d1b0
--- /dev/null
+++ b/Filters/README.txt
@@ -0,0 +1,9 @@
+Framestein will look for filters in this directory in 8BF-format.
+
+The example filters are (C) Andrew Buckle and were downloaded from
+http://showcase.netins.net/web/wolf359/plugins.htm.
+
+There are more than a thousand more available on that page.
+
+A good program to convert various formats to 8BF is Plugin Commander Light,
+available from http://thepluginsite.com/products/picopro/index.htm.
diff --git a/Framestein.exe b/Framestein.exe
new file mode 100755
index 0000000..4879d1f
--- /dev/null
+++ b/Framestein.exe
Binary files differ
diff --git a/HARMON.jpg b/HARMON.jpg
new file mode 100644
index 0000000..b84472c
--- /dev/null
+++ b/HARMON.jpg
Binary files differ
diff --git a/Patches/00 example-basics.pd b/Patches/00 example-basics.pd
new file mode 100644
index 0000000..ca9ab3f
--- /dev/null
+++ b/Patches/00 example-basics.pd
@@ -0,0 +1,38 @@
+#N canvas 228 3 648 661 12;
+#X obj 5 31 fs.main;
+#X msg 5 7 6001;
+#X msg 56 7 reset;
+#X text 32 103 fs.main connects pure data and Framestein. Only one
+at a time!;
+#X text 33 143 1st inlet: re-establish connection to given port number
+;
+#X text 33 159 2nd inlet: "reset" will re-create all fs.*-objects;
+#X obj 36 206 fs.frame;
+#X text 119 206 -- load images and video \, perform effects \, run
+plugins \, photoshop-filters \, and more ...;
+#X text 120 273 some commands are listed here;
+#X obj 358 273 fs.fx;
+#X text 120 304 1st outlet: fs.frame ID. Connect this to other fs.*-objects
+\, like fs.copy \, fs.info \, fs.event etc.;
+#X text 120 344 2nd outlet: reports mouse movement in the frame when
+mousetrack_1 is set. See example-docking.pd!;
+#X text 119 384 3rd outlet: report the window position when docked
+\, see example-docking2.pd!;
+#X obj 45 442 fs.copy;
+#X text 121 442 -- connect two fs.frames to copy pixels by built-in
+copy operations \, plugins or photoshop-filters.;
+#X text 122 486 1st inlet: connect the first outlet of fs.frame here.
+;
+#X text 122 505 2nd inlet: name of the copy operation \, or other parameter.
+See inside fs.copy for list of built-ins. See example-plugins.pd and
+example-photoshopfilters.pd.;
+#X text 123 557 1st outlet: connect to the fs.frame to copy to.;
+#X text 31 70 The central objects to get started with:;
+#X text 49 602 Have fun!;
+#X text 119 253 1st inlet: for a list of commands \, look inside the
+patch.;
+#X obj 344 320 fs.info;
+#X obj 416 320 fs.event;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
diff --git a/Patches/01 example-video.pd b/Patches/01 example-video.pd
new file mode 100644
index 0000000..3624331
--- /dev/null
+++ b/Patches/01 example-video.pd
@@ -0,0 +1,30 @@
+#N canvas 243 28 638 555 12;
+#X obj 7 34 fs.main;
+#X msg 7 8 6001;
+#X msg 46 8 reset;
+#X obj 300 209 fs.framed video;
+#X msg 424 209 82 + 128;
+#X text 41 64 drag & drop your favorite .avi here;
+#X obj 442 185 init;
+#X obj 303 121 hsl 256 15 0 1 0 0 empty empty empty 20 8 0 8 -262144
+-1 -1 9200 1;
+#X obj 300 272 fs.copy;
+#X msg 300 146 seek \$1* \, bang;
+#X obj 300 348 fs.framed video;
+#X msg 424 348 82 + 330;
+#X msg 392 271 source_random \, dest_random;
+#X text 314 299 Look inside fs.copy for more commands.;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
+#X connect 3 0 8 0;
+#X connect 3 2 4 0;
+#X connect 4 0 3 0;
+#X connect 6 0 4 0;
+#X connect 6 0 11 0;
+#X connect 7 0 9 0;
+#X connect 8 0 10 0;
+#X connect 9 0 3 0;
+#X connect 10 2 11 0;
+#X connect 11 0 10 0;
+#X connect 12 0 8 1;
diff --git a/Patches/02 example-docking.pd b/Patches/02 example-docking.pd
new file mode 100644
index 0000000..bf29cc8
--- /dev/null
+++ b/Patches/02 example-docking.pd
@@ -0,0 +1,88 @@
+#N canvas 385 33 594 516 12;
+#X obj 13 33 fs.main;
+#X obj 250 231 fs.framed example-docking 27+117;
+#X msg 13 6 6001;
+#X msg 64 5 reset;
+#X floatatom 211 414 4 0 0;
+#X floatatom 251 414 4 0 0;
+#X floatatom 292 414 4 0 0;
+#X obj 211 382 unpack f f f;
+#X obj 386 367 fs.info;
+#X floatatom 386 402 4 0 0;
+#X floatatom 428 402 4 0 0;
+#X floatatom 471 402 4 0 0;
+#X obj 385 292 unpack f f;
+#X floatatom 385 320 4 0 0;
+#X floatatom 460 319 4 0 0;
+#X msg 233 192 bang;
+#X text 87 442 scrub the pict with mouse to get r g b values;
+#X text 386 266 mouse x and y;
+#X msg 268 322 bang;
+#X obj 211 350 fs.rgb;
+#N canvas 0 0 296 396 beeper 0;
+#X obj 90 56 inlet;
+#X obj 91 92 unpack f f f;
+#X obj 171 130 *;
+#X obj 123 252 osc~;
+#X obj 155 170 / 256;
+#X obj 86 132 / 256;
+#X obj 123 203 *;
+#X obj 125 323 dac~;
+#X obj 127 284 *~ 0.1;
+#X obj 85 161 * 20000;
+#X obj 196 243 / 256;
+#X obj 200 332 * 0.1;
+#X connect 0 0 1 0;
+#X connect 1 0 5 0;
+#X connect 1 0 10 0;
+#X connect 1 1 2 0;
+#X connect 1 2 2 1;
+#X connect 2 0 4 0;
+#X connect 3 0 8 0;
+#X connect 4 0 6 0;
+#X connect 5 0 9 0;
+#X connect 6 0 3 0;
+#X connect 8 0 7 0;
+#X connect 8 0 7 1;
+#X connect 9 0 6 1;
+#X connect 10 0 11 0;
+#X connect 11 0 8 1;
+#X restore 124 398 pd beeper;
+#X msg 43 362 \; pd dsp 1;
+#X msg 43 402 \; pd dsp 0;
+#X msg 284 193 mousetrack_1;
+#X obj 297 256 videoscrub;
+#X text 264 77 or drop a videofile to the frame ...;
+#X obj 206 51 init;
+#X floatatom 513 402 5 0 0;
+#X msg 250 51 HARMON.JPG;
+#X text 42 336 Play the harmon!;
+#X connect 1 0 19 0;
+#X connect 1 0 8 0;
+#X connect 1 0 24 0;
+#X connect 1 1 12 0;
+#X connect 1 1 19 1;
+#X connect 1 1 18 0;
+#X connect 1 1 24 1;
+#X connect 2 0 0 0;
+#X connect 2 0 3 0;
+#X connect 3 0 0 1;
+#X connect 7 0 4 0;
+#X connect 7 1 5 0;
+#X connect 7 2 6 0;
+#X connect 8 0 9 0;
+#X connect 8 1 10 0;
+#X connect 8 2 11 0;
+#X connect 8 3 27 0;
+#X connect 12 0 13 0;
+#X connect 12 1 14 0;
+#X connect 15 0 1 0;
+#X connect 18 0 19 0;
+#X connect 19 0 7 0;
+#X connect 19 0 20 0;
+#X connect 23 0 1 0;
+#X connect 24 0 1 0;
+#X connect 26 0 28 0;
+#X connect 26 0 15 0;
+#X connect 26 0 23 0;
+#X connect 28 0 1 0;
diff --git a/Patches/03 example-docking2.pd b/Patches/03 example-docking2.pd
new file mode 100644
index 0000000..f5687e5
--- /dev/null
+++ b/Patches/03 example-docking2.pd
@@ -0,0 +1,15 @@
+#N canvas 345 114 641 488 12;
+#X obj 11 40 fs.main;
+#X msg 11 12 6001;
+#X msg 62 12 reset;
+#X obj 26 133 fs.framed example-docking2;
+#X msg 229 161 365 + 203;
+#X obj 240 133 init;
+#X text 24 78 Used this way the frame position is saved with the patch
+automatically. Try moving the frame around!;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
+#X connect 3 2 4 0;
+#X connect 4 0 3 0;
+#X connect 5 0 4 0;
diff --git a/Patches/04 example-draganddrop.pd b/Patches/04 example-draganddrop.pd
new file mode 100644
index 0000000..2c68f99
--- /dev/null
+++ b/Patches/04 example-draganddrop.pd
@@ -0,0 +1,25 @@
+#N canvas 323 36 587 428 12;
+#X obj 15 37 fs.main;
+#X msg 66 12 reset;
+#X obj 38 185 fs.framed draganddrop;
+#X msg 201 212 352 + 233;
+#X obj 38 244 fs.event;
+#X msg 50 288 set \$1;
+#X obj 92 150 init;
+#X obj 48 151 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 18 95 Using fs.frame to provide drag & drop:;
+#X text 352 180 Drop a file here:;
+#X msg 15 12 6001;
+#X msg 67 329;
+#X connect 1 0 0 1;
+#X connect 2 0 4 0;
+#X connect 2 2 3 0;
+#X connect 3 0 2 0;
+#X connect 4 0 5 0;
+#X connect 5 0 11 0;
+#X connect 6 0 3 0;
+#X connect 6 0 2 0;
+#X connect 7 0 2 0;
+#X connect 10 0 0 0;
+#X connect 10 0 1 0;
diff --git a/Patches/05 example-plugins.pd b/Patches/05 example-plugins.pd
new file mode 100644
index 0000000..f6187a2
--- /dev/null
+++ b/Patches/05 example-plugins.pd
@@ -0,0 +1,127 @@
+#N canvas 344 18 621 620 12;
+#X obj 11 41 fs.main;
+#X msg 11 11 6001;
+#X msg 62 12 reset;
+#X obj 70 216 fs.frame;
+#X msg 103 177 noize;
+#X text 106 154 send the name of the plugin to fs.frame to execute
+;
+#X obj 70 466 fs.frame;
+#X obj 70 302 fs.copy;
+#X msg 141 216 bang;
+#X text 161 249 plugins can also be copy operations;
+#X msg 153 177 colortv;
+#X msg 158 278 colortv;
+#X msg 220 177 subtract \$1 \$2 \$3;
+#X obj 376 205 pack f f f;
+#X floatatom 368 177 4 0 0;
+#X floatatom 409 177 4 0 0;
+#X floatatom 450 177 4 0 0;
+#X msg 460 205 bang;
+#X obj 255 355 pack f f;
+#X msg 323 355 bang;
+#X floatatom 255 331 4 0 0;
+#X floatatom 295 331 4 0 0;
+#X obj 466 408 int;
+#X msg 320 379 \$1 180;
+#N canvas 686 105 602 402 funny 0;
+#X obj 47 97 random 352;
+#X obj 135 97 random 352;
+#X obj 73 145 pack f f;
+#X obj 80 186 outlet;
+#X obj 76 13 inlet;
+#X obj 86 56 t b b;
+#X connect 0 0 2 0;
+#X connect 1 0 2 1;
+#X connect 2 0 3 0;
+#X connect 4 0 5 0;
+#X connect 5 0 0 0;
+#X connect 5 1 1 0;
+#X restore 255 412 pd funny;
+#X msg 324 412 bang;
+#X msg 158 331 xbend \$1 \$2;
+#N canvas 638 233 375 411 bend 0;
+#X obj 18 328 outlet;
+#X msg 43 281 bend \$1 \$2 \$3 \$4;
+#X obj 55 242 pack f f f f;
+#X msg 158 242 bang;
+#X floatatom 35 159 4 0 0;
+#X floatatom 77 159 4 0 0;
+#X floatatom 124 159 4 0 0;
+#X floatatom 168 159 4 0 0;
+#X msg 200 262 158 161 154 214;
+#X text 187 315 oh i'm sorry virve...;
+#X msg 209 290 94 95 280 214;
+#X msg 187 339 169 144 262 162;
+#X text 132 365 but this thing is killing me;
+#X text 67 13 bend works in both x and y;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 2 0;
+#X connect 4 0 2 0;
+#X connect 5 0 2 1;
+#X connect 5 0 3 0;
+#X connect 6 0 2 2;
+#X connect 6 0 3 0;
+#X connect 7 0 2 3;
+#X connect 7 0 3 0;
+#X connect 8 0 1 0;
+#X connect 10 0 1 0;
+#X connect 11 0 1 0;
+#X restore 255 442 pd bend;
+#X text 71 503 note: 16 bit display is way faster than 24 or 32 in
+my machine \, so i recommend trying out which one performs best.;
+#X text 69 555 there are more plugins.. see the Framestein/Plugins-dir.
+;
+#X msg 70 118 virvezoom.jpg;
+#X obj 186 118 init;
+#X obj 94 407 init;
+#X text 367 412 click here;
+#X text 320 442 look here;
+#X msg 94 438 291 x 325 \, 0 + 370;
+#X obj 466 433 sameonce;
+#X obj 466 384 ramp;
+#X msg 466 356 220 66 10;
+#X msg 466 333 66 220 10;
+#X text 467 309 and here ..;
+#X text 340 330 try these ..;
+#X text 147 42 PLUGINS -- effects and copy operations;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
+#X connect 3 0 7 0;
+#X connect 4 0 3 0;
+#X connect 7 0 6 0;
+#X connect 8 0 3 0;
+#X connect 10 0 3 0;
+#X connect 11 0 7 1;
+#X connect 11 0 8 0;
+#X connect 12 0 3 0;
+#X connect 13 0 12 0;
+#X connect 14 0 13 0;
+#X connect 15 0 13 1;
+#X connect 15 0 17 0;
+#X connect 16 0 13 2;
+#X connect 16 0 17 0;
+#X connect 17 0 13 0;
+#X connect 18 0 26 0;
+#X connect 19 0 18 0;
+#X connect 20 0 18 0;
+#X connect 21 0 18 1;
+#X connect 21 0 19 0;
+#X connect 22 0 36 0;
+#X connect 23 0 18 0;
+#X connect 24 0 26 0;
+#X connect 25 0 24 0;
+#X connect 26 0 7 1;
+#X connect 26 0 8 0;
+#X connect 27 0 7 1;
+#X connect 27 0 8 0;
+#X connect 30 0 3 0;
+#X connect 31 0 30 0;
+#X connect 32 0 35 0;
+#X connect 35 0 6 0;
+#X connect 36 0 18 0;
+#X connect 37 0 22 0;
+#X connect 38 0 37 0;
+#X connect 39 0 37 0;
diff --git a/Patches/06 example-photoshopfilters.pd b/Patches/06 example-photoshopfilters.pd
new file mode 100644
index 0000000..2b7a359
--- /dev/null
+++ b/Patches/06 example-photoshopfilters.pd
@@ -0,0 +1,105 @@
+#N canvas 221 6 707 598 12;
+#X obj 16 54 fs.main;
+#X msg 16 27 6001;
+#X msg 58 27 reset;
+#X obj 460 157 init;
+#X msg 434 122 28 + 128;
+#X obj 262 398 fs.copy;
+#X obj 262 477 fs.framed example-pho;
+#X obj 262 122 fs.framed example-pho;
+#X msg 434 477 28 + 308;
+#X obj 461 447 init;
+#X msg 333 252 bosstota;
+#X msg 281 157 next \, bang;
+#X msg 345 285 bubbspac;
+#X msg 357 320 chloemag;
+#X msg 370 351 colsteps;
+#X text 493 241 without parameters;
+#X text 496 266 a dialog will pop;
+#N canvas 298 218 624 424 realtime 0;
+#X obj 42 347 outlet;
+#X floatatom 42 241 5 0 0;
+#X floatatom 91 241 5 0 0;
+#X floatatom 140 241 5 0 0;
+#X floatatom 189 241 5 0 0;
+#X floatatom 238 241 5 0 0;
+#X floatatom 287 241 5 0 0;
+#X floatatom 336 241 5 0 0;
+#X floatatom 385 241 5 0 0;
+#X obj 88 33 inlet;
+#X obj 88 109 fps 0;
+#X floatatom 88 79 5 0 0;
+#X obj 181 175 random 255;
+#X obj 189 199 random 255;
+#X obj 267 175 random 255;
+#X obj 275 199 random 255;
+#X obj 353 175 random 255;
+#X obj 361 199 random 255;
+#X obj 94 175 random 255;
+#X obj 102 199 random 255;
+#X obj 42 282 pack f f f f f f f f;
+#X msg 42 318 colsteps \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8;
+#X connect 1 0 20 0;
+#X connect 2 0 20 1;
+#X connect 3 0 20 2;
+#X connect 4 0 20 3;
+#X connect 5 0 20 4;
+#X connect 6 0 20 5;
+#X connect 7 0 20 6;
+#X connect 8 0 20 7;
+#X connect 9 0 11 0;
+#X connect 10 0 12 0;
+#X connect 10 0 13 0;
+#X connect 10 0 14 0;
+#X connect 10 0 15 0;
+#X connect 10 0 16 0;
+#X connect 10 0 17 0;
+#X connect 10 0 18 0;
+#X connect 10 0 19 0;
+#X connect 11 0 10 0;
+#X connect 12 0 3 0;
+#X connect 13 0 4 0;
+#X connect 14 0 5 0;
+#X connect 15 0 6 0;
+#X connect 16 0 7 0;
+#X connect 17 0 8 0;
+#X connect 18 0 1 0;
+#X connect 19 0 2 0;
+#X connect 20 0 21 0;
+#X connect 21 0 0 0;
+#X restore 520 391 pd realtime;
+#X text 472 336 this is the real-time way;
+#X floatatom 520 365 5 0 0;
+#X msg 572 365 2;
+#X obj 520 421 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1
+-1;
+#X text 266 535 the example-filters are (C) Andrew Buckle.;
+#X text 266 555 see Filters/README.TXT for more info.;
+#X msg 262 62 head.avi;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
+#X connect 3 0 24 0;
+#X connect 3 0 4 0;
+#X connect 4 0 7 0;
+#X connect 5 0 6 0;
+#X connect 6 2 8 0;
+#X connect 7 0 5 0;
+#X connect 7 2 4 0;
+#X connect 8 0 6 0;
+#X connect 9 0 8 0;
+#X connect 10 0 5 1;
+#X connect 10 0 11 0;
+#X connect 11 0 7 0;
+#X connect 12 0 5 1;
+#X connect 12 0 11 0;
+#X connect 13 0 5 1;
+#X connect 13 0 11 0;
+#X connect 14 0 5 1;
+#X connect 14 0 11 0;
+#X connect 17 0 5 1;
+#X connect 17 0 21 0;
+#X connect 19 0 17 0;
+#X connect 20 0 19 0;
+#X connect 21 0 11 0;
+#X connect 24 0 7 0;
diff --git a/Patches/07 example-blending.pd b/Patches/07 example-blending.pd
new file mode 100644
index 0000000..d11e887
--- /dev/null
+++ b/Patches/07 example-blending.pd
@@ -0,0 +1,57 @@
+#N canvas 5 47 1010 514 10;
+#X obj 12 52 fs.main;
+#X msg 10 23 6001;
+#X msg 56 23 reset;
+#X msg 210 190 597 + 108;
+#X msg 495 188 815 + 109;
+#X msg 343 365 696 + 342;
+#X floatatom 227 272 4 0 0;
+#X obj 150 273 fs.blend;
+#X obj 235 38 fps 0;
+#X floatatom 193 38 4 0 0;
+#X msg 286 96 next \, bang;
+#X msg 207 94 next \, bang;
+#X obj 220 167 init;
+#X obj 503 163 init;
+#X obj 353 335 init;
+#X text 166 419 note: fs.blend initializes this frame to flip_manual.
+;
+#X text 174 441 in manual mode \, you need to send "flip" to update
+the display after changing the image. the default mode is "flip_auto".
+;
+#X text 239 246 blend amount \, 0 - 255;
+#X text 682 44 drag and drop your videos here;
+#X text 748 291 the result;
+#X msg 299 290 127;
+#X obj 236 65 t b b;
+#X text 196 14 frame rate. start with something modest \, like 1;
+#X obj 731 257 hsl 128 15 255 0 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 0 1;
+#X obj 21 189 fs.framed blending;
+#X obj 306 187 fs.framed blending;
+#X obj 150 363 fs.framed blending;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
+#X connect 3 0 24 0;
+#X connect 4 0 25 0;
+#X connect 5 0 26 0;
+#X connect 6 0 7 2;
+#X connect 7 0 26 0;
+#X connect 8 0 21 0;
+#X connect 9 0 8 0;
+#X connect 10 0 25 0;
+#X connect 11 0 24 0;
+#X connect 12 0 3 0;
+#X connect 13 0 4 0;
+#X connect 14 0 5 0;
+#X connect 14 0 20 0;
+#X connect 20 0 6 0;
+#X connect 21 0 11 0;
+#X connect 21 1 10 0;
+#X connect 23 0 6 0;
+#X connect 24 0 7 0;
+#X connect 24 2 3 0;
+#X connect 25 0 7 1;
+#X connect 25 2 4 0;
+#X connect 26 2 5 0;
diff --git a/Patches/08 example-masking.pd b/Patches/08 example-masking.pd
new file mode 100644
index 0000000..8e546a6
--- /dev/null
+++ b/Patches/08 example-masking.pd
@@ -0,0 +1,66 @@
+#N canvas 50 107 926 549 10;
+#X obj 9 33 fs.main;
+#X msg 8 8 6001;
+#X msg 45 8 reset;
+#X msg 115 196 412 + 104;
+#X msg 18 122 next \, bang;
+#X obj 18 294 fs.mask;
+#X msg 248 279 601 + 104;
+#X obj 18 99 fps 0;
+#X floatatom 18 76 4 0 0;
+#X obj 199 332 fs.draw;
+#X msg 199 308 rect \$1 \$2 \$3 \$4;
+#X msg 211 230 mousetrack_1 \, mouserect_1;
+#X msg 219 372 pen 0 0 0 \, brush 0 0 0;
+#X obj 130 173 init;
+#X msg 219 395 pen 255 255 255 \, brush 255 255 255;
+#X obj 18 173 fs.framed masking;
+#X obj 151 257 fs.framed masking;
+#X obj 18 392 fs.framed masking;
+#X obj 130 392 init;
+#X obj 259 257 init;
+#X obj 235 421 init;
+#X text 359 372 click here to draw black to the mask;
+#X text 435 394 draw white;
+#X text 409 51 1) drag & drop a video here:;
+#X text 598 51 2) draw rectanges to this frame:;
+#X text 599 262 the result is...;
+#X msg 115 417 601 + 313;
+#X text 116 47 fs.mask -- copy with mask;
+#X text 116 66 1st inlet: fs.frame to copy from;
+#X text 116 81 2nd inlet: fs.frame of the mask;
+#X text 134 95 outlet: output fs.frame;
+#X msg 52 76 2;
+#X obj 65 99 init;
+#X msg 364 443 invert;
+#X text 364 423 try inverting the mask..;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
+#X connect 3 0 15 0;
+#X connect 4 0 15 0;
+#X connect 5 0 17 0;
+#X connect 6 0 16 0;
+#X connect 7 0 4 0;
+#X connect 8 0 7 0;
+#X connect 9 0 16 0;
+#X connect 10 0 9 0;
+#X connect 11 0 16 0;
+#X connect 12 0 9 0;
+#X connect 13 0 3 0;
+#X connect 14 0 9 0;
+#X connect 15 0 5 0;
+#X connect 15 2 3 0;
+#X connect 16 0 5 1;
+#X connect 16 1 10 0;
+#X connect 16 2 6 0;
+#X connect 17 2 26 0;
+#X connect 18 0 26 0;
+#X connect 19 0 6 0;
+#X connect 19 0 11 0;
+#X connect 19 0 16 0;
+#X connect 20 0 14 0;
+#X connect 26 0 17 0;
+#X connect 31 0 8 0;
+#X connect 32 0 31 0;
+#X connect 33 0 16 0;
diff --git a/Patches/09 example-sonogram.pd b/Patches/09 example-sonogram.pd
new file mode 100644
index 0000000..5c99688
--- /dev/null
+++ b/Patches/09 example-sonogram.pd
@@ -0,0 +1,74 @@
+#N canvas 308 -3 605 676 12;
+#X obj 13 40 fs.main;
+#X msg 13 13 6001;
+#X msg 64 12 reset;
+#X obj 330 486 fs.sonogram;
+#X msg 488 452 bang;
+#X obj 488 419 fps 0;
+#X floatatom 488 392 5 0 0;
+#X msg 488 364 5;
+#N canvas 0 0 608 408 play 0;
+#X graph graph2 0 -1 114739 1 70 171 270 31;
+#X array music 114740 float 0;
+#X pop;
+#X msg 341 137 read -resize \$1 music;
+#X obj 341 168 soundfiler;
+#X obj 333 70 inlet;
+#X obj 341 103 symbol;
+#X obj 193 242 phasor~ 1;
+#X obj 203 290 *~;
+#X obj 209 359 outlet~;
+#X obj 203 320 tabread4~ music;
+#X floatatom 193 213 5 0 0;
+#X obj 92 214 osc~ 0.01;
+#X obj 92 239 avg~;
+#X connect 1 0 2 0;
+#X connect 2 0 6 1;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 6 0;
+#X connect 6 0 8 0;
+#X connect 8 0 7 0;
+#X connect 9 0 5 0;
+#X connect 10 0 11 0;
+#X connect 11 0 9 0;
+#X restore 330 349 pd play;
+#X msg 248 48 c:/fsrel/framestein/extract.wav;
+#X obj 251 480 dac~;
+#X msg 364 558 200x128 \, display 200x512;
+#X floatatom 355 427 5 0 0;
+#X obj 263 450 *~ 0.2;
+#X text 348 403 amplify display;
+#X obj 295 529 fs.framed example-sonogram 20+120;
+#X msg 370 587 setbits 246;
+#X msg 358 100 \; pd dsp 1;
+#X obj 116 13 loadbang;
+#X text 441 110 must be on ..;
+#X text 453 332 start drawing;
+#X text 242 23 correct path and click ..;
+#X text 28 617 NOTE: fs.sonogram writes temporary files to your c:/.
+;
+#X text 77 636 modify fs.sonogram.pd for a proper temporary path.;
+#X obj 330 451 *~ 4;
+#X obj 479 592 init;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
+#X connect 3 0 15 0;
+#X connect 4 0 3 1;
+#X connect 5 0 4 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 0;
+#X connect 8 0 13 0;
+#X connect 8 0 24 0;
+#X connect 9 0 8 0;
+#X connect 11 0 15 0;
+#X connect 12 0 24 1;
+#X connect 13 0 10 0;
+#X connect 13 0 10 0;
+#X connect 13 0 10 1;
+#X connect 16 0 15 0;
+#X connect 18 0 2 0;
+#X connect 24 0 3 0;
+#X connect 25 0 11 0;
+#X connect 25 0 16 0;
diff --git a/Patches/10 example-waveformdisplay.pd b/Patches/10 example-waveformdisplay.pd
new file mode 100644
index 0000000..f44763a
--- /dev/null
+++ b/Patches/10 example-waveformdisplay.pd
@@ -0,0 +1,126 @@
+#N canvas 197 11 743 561 12;
+#X obj 5 34 fs.main;
+#X msg 5 7 6001;
+#X msg 45 7 reset;
+#X text 155 394 drag & drop a SOUND FILE to one of the frames above
+...;
+#X text 234 413 then make a selection with mouse;
+#N canvas 0 0 1002 426 implementation 0;
+#X obj 26 260 table snd;
+#X obj 108 206 fs.event;
+#X msg 108 234 read -resize \$1 snd;
+#X obj 159 286 soundfiler;
+#X obj 125 105 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 206 161 fs.waveform snd 512 256;
+#X obj 197 101 fs.waveform snd 512 32;
+#X obj 230 134 t b f;
+#X floatatom 295 192 8 0 0;
+#X floatatom 368 192 8 0 0;
+#X text 288 230 selection in samples;
+#N canvas 35 295 458 308 init 0;
+#X obj 105 91 init;
+#X obj 92 209 outlet;
+#X obj 145 209 outlet;
+#X msg 83 125 dock waveformd \, 118+105 \, bang;
+#X msg 74 151 dock waveformd \, 118+138 \, bang;
+#X connect 0 0 3 0;
+#X connect 0 0 4 0;
+#X connect 3 0 2 0;
+#X connect 4 0 1 0;
+#X restore 146 74 pd init;
+#X msg 394 97 118 + 105;
+#X msg 406 153 118 + 138;
+#X obj 108 260 t b b a;
+#X msg 128 286 0;
+#X text 499 72 fs.waveform -- array display with range selection;
+#X text 513 104 args: <array name> <width> <height>;
+#X text 513 130 inlet 1: bang or command to fs.frame;
+#X text 513 166 inlet 3: endpoint of display in samples;
+#X text 513 148 inlet 2: startpoint of display in samples;
+#X text 513 184 inlet 4: display selection in inverse (0 or 1);
+#X text 513 217 outlets 1 & 2: first two outlets of the fs.frame inside
+;
+#X text 513 235 outlets 3 & 4: start and end of selected range in samples
+;
+#X text 513 254 outlet 5: third outlet of the fs.frame inside;
+#N canvas 0 0 481 421 playselection 0;
+#X obj 302 117 inlet;
+#X obj 348 117 inlet;
+#X obj 302 182 -;
+#X obj 302 210 abs;
+#X obj 94 185 *~;
+#X obj 94 214 +~;
+#X obj 94 151 phasor~;
+#X obj 334 310 /;
+#X obj 327 277 samplerate~;
+#X obj 302 237 t f b f;
+#X obj 94 245 tabread4~ snd;
+#X obj 149 283 r vol;
+#X obj 94 319 dac~;
+#X obj 94 283 *~ 0.1;
+#X obj 123 50 inlet;
+#X text 74 24 mouseup from fs.event;
+#X text 301 94 range;
+#X obj 94 127 f;
+#X obj 123 185 f;
+#X obj 123 214 f;
+#X connect 0 0 2 0;
+#X connect 0 0 19 1;
+#X connect 1 0 2 1;
+#X connect 2 0 3 0;
+#X connect 3 0 9 0;
+#X connect 4 0 5 0;
+#X connect 5 0 10 0;
+#X connect 6 0 4 0;
+#X connect 7 0 17 1;
+#X connect 8 0 7 0;
+#X connect 9 0 18 1;
+#X connect 9 1 8 0;
+#X connect 9 2 7 1;
+#X connect 10 0 13 0;
+#X connect 11 0 13 1;
+#X connect 13 0 12 0;
+#X connect 13 0 12 1;
+#X connect 14 0 17 0;
+#X connect 14 0 18 0;
+#X connect 14 0 19 0;
+#X connect 17 0 6 0;
+#X connect 18 0 4 1;
+#X connect 19 0 5 1;
+#X restore 294 299 pd playselection;
+#X text 195 353 Sorry about the mess..;
+#X connect 1 0 2 0;
+#X connect 1 2 25 0;
+#X connect 2 0 14 0;
+#X connect 4 0 6 0;
+#X connect 5 0 1 0;
+#X connect 5 2 8 0;
+#X connect 5 2 25 1;
+#X connect 5 3 9 0;
+#X connect 5 3 25 2;
+#X connect 5 4 13 0;
+#X connect 6 0 1 0;
+#X connect 6 2 7 0;
+#X connect 6 3 5 2;
+#X connect 6 4 12 0;
+#X connect 7 0 5 0;
+#X connect 7 1 5 1;
+#X connect 11 0 5 0;
+#X connect 11 1 6 0;
+#X connect 14 0 6 0;
+#X connect 14 0 5 0;
+#X connect 14 1 15 0;
+#X connect 14 2 3 0;
+#X connect 15 0 6 1;
+#X connect 15 0 6 2;
+#X connect 15 0 5 1;
+#X connect 15 0 5 2;
+#X restore 252 475 pd implementation and docs;
+#X obj 32 388 vsl 15 128 0 1 0 0 vol empty volume 0 -8 128 8 -262144
+-1 -1 7800 1;
+#X msg 54 497 \; pd dsp 1;
+#X text 57 472 play it ...;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
diff --git a/Patches/11 example-browser.pd b/Patches/11 example-browser.pd
new file mode 100644
index 0000000..3e68922
--- /dev/null
+++ b/Patches/11 example-browser.pd
@@ -0,0 +1,30 @@
+#N canvas 335 300 661 349 12;
+#X obj 11 37 fs.main;
+#X obj 88 185 fs.browser;
+#X msg 11 8 6001;
+#X msg 62 8 reset;
+#X obj 88 255 fs.frame;
+#X msg 88 133 bang;
+#X msg 190 82 1000x480;
+#X obj 88 221 fs.copy;
+#X msg 164 282 xbend 110 120;
+#X floatatom 287 273 4 0 0;
+#X obj 287 299 bangx;
+#X msg 287 247 10;
+#X text 54 110 click here;
+#X obj 181 15 init;
+#X msg 181 122 http://pinktwins.com;
+#X connect 1 0 7 0;
+#X connect 2 0 0 0;
+#X connect 2 0 3 0;
+#X connect 3 0 0 1;
+#X connect 5 0 1 0;
+#X connect 6 0 1 0;
+#X connect 7 0 4 0;
+#X connect 8 0 4 0;
+#X connect 9 0 10 0;
+#X connect 10 0 8 0;
+#X connect 11 0 9 0;
+#X connect 13 0 6 0;
+#X connect 13 0 14 0;
+#X connect 14 0 1 0;
diff --git a/Patches/12 example-network.pd b/Patches/12 example-network.pd
new file mode 100644
index 0000000..81490d1
--- /dev/null
+++ b/Patches/12 example-network.pd
@@ -0,0 +1,62 @@
+#N canvas 242 39 740 613 12;
+#X obj 15 44 fs.main;
+#X msg 15 14 6001;
+#X msg 66 14 reset;
+#X obj 108 221 fs.frame;
+#X msg 143 113 buffer c:/fsrel/Framestein/Reija;
+#X msg 207 179 next;
+#X obj 82 520 fs.frame;
+#X msg 29 481 receive hello;
+#X text 162 511 use "receive <nametag>" on the receiving end to control
+where your frames go.;
+#X text 208 234 send <nametag> <jpeg quality>;
+#X text 357 142 connect <address> <port>;
+#X text 208 259 use "pure" as jpeg quality to send uncompressed frames.
+this will take much more bandwidth but less cpu.;
+#X msg 207 209 send hello 33;
+#X msg 24 311 disconnect;
+#X text 443 328 use send_auto to automate sending (send frame on each
+flip);
+#X msg 397 303 send_auto hello 33;
+#X msg 397 328 next;
+#X obj 336 465 fs.copy;
+#X msg 347 440 bang;
+#X msg 398 378 bang;
+#X msg 398 465 source_random \, dest_random \, srcand;
+#N canvas 519 266 380 369 test 0;
+#X obj 110 209 outlet;
+#X obj 113 54 inlet;
+#X msg 122 87 bang;
+#X obj 115 122 random 20;
+#X obj 115 149 bangx;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X restore 398 402 pd test;
+#X msg 172 142 connect localhost 6010;
+#X obj 29 454 reset;
+#X obj 398 440 init;
+#X text 414 112 correct this path;
+#X text 139 37 -- Sending frames through network --;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
+#X connect 3 0 17 0;
+#X connect 4 0 3 0;
+#X connect 5 0 3 0;
+#X connect 5 0 12 0;
+#X connect 7 0 6 0;
+#X connect 12 0 3 0;
+#X connect 13 0 3 0;
+#X connect 15 0 3 0;
+#X connect 16 0 3 0;
+#X connect 17 0 3 0;
+#X connect 18 0 3 0;
+#X connect 19 0 16 0;
+#X connect 19 0 21 0;
+#X connect 20 0 17 1;
+#X connect 21 0 3 0;
+#X connect 22 0 3 0;
+#X connect 23 0 7 0;
+#X connect 24 0 20 0;
diff --git a/Patches/13 example-avioutput.pd b/Patches/13 example-avioutput.pd
new file mode 100644
index 0000000..b7fad86
--- /dev/null
+++ b/Patches/13 example-avioutput.pd
@@ -0,0 +1,61 @@
+#N canvas 252 23 721 631 12;
+#X obj 13 39 fs.main;
+#X msg 13 12 6001;
+#X msg 64 13 reset;
+#X obj 247 147 fs.framed aviout;
+#X msg 385 147 37 + 127;
+#X msg 75 39 path c:/fsrel/framestein;
+#X obj 282 204 fs.copy;
+#X msg 385 190 source_random;
+#X obj 385 59 init;
+#X msg 247 102 head.avi \, flip_manual;
+#X msg 502 127 next \, bang \, flip;
+#X floatatom 521 76 5 0 0;
+#X obj 247 178 t s s;
+#X obj 502 103 fps 0;
+#X msg 484 76 5;
+#X obj 269 361 fs.avi;
+#X floatatom 269 387 5 0 0;
+#X text 326 388 # of frames saved;
+#X msg 349 273 fps 10;
+#X text 412 273 set frames per second;
+#X obj 349 249 init;
+#X msg 349 318 write;
+#X text 400 318 apply compression and finish;
+#X text 482 50 start writing!;
+#X text 158 481 Bang fs.frame to fs.avi to save one frame of video
+;
+#X text 158 508 Finish it off with "write [filename.avi]";
+#X msg 434 220 xbend \$1;
+#X floatatom 507 220 5 0 0;
+#X msg 507 195 75;
+#X msg 550 103 0;
+#X text 584 102 stop;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
+#X connect 2 0 5 0;
+#X connect 3 0 12 0;
+#X connect 3 2 4 0;
+#X connect 4 0 3 0;
+#X connect 5 0 0 1;
+#X connect 6 0 3 0;
+#X connect 7 0 6 1;
+#X connect 8 0 9 0;
+#X connect 8 0 4 0;
+#X connect 8 0 7 0;
+#X connect 9 0 3 0;
+#X connect 10 0 3 0;
+#X connect 11 0 13 0;
+#X connect 12 0 15 0;
+#X connect 12 1 6 0;
+#X connect 13 0 10 0;
+#X connect 14 0 13 0;
+#X connect 15 0 16 0;
+#X connect 18 0 15 0;
+#X connect 20 0 18 0;
+#X connect 21 0 15 0;
+#X connect 26 0 6 1;
+#X connect 27 0 26 0;
+#X connect 28 0 27 0;
+#X connect 29 0 13 0;
diff --git a/Patches/14 example-hist.pd b/Patches/14 example-hist.pd
new file mode 100644
index 0000000..e9c378c
--- /dev/null
+++ b/Patches/14 example-hist.pd
@@ -0,0 +1,46 @@
+#N canvas 276 11 723 503 12;
+#X obj 243 98 videoscrub;
+#X floatatom 230 39 5 0 0;
+#X obj 279 40 play 0;
+#X msg 332 40 mousetrack_1;
+#X graph graph1 0 -1 255 1 498 164 698 24;
+#X array red 256 float 0;
+#X pop;
+#X msg 212 11 bang;
+#X obj 9 39 fs.main;
+#X msg 9 13 6001;
+#X msg 60 13 reset;
+#X obj 212 70 fs.framed example-hist 11+97;
+#X graph graph2 0 -1 255 1 498 311 698 171;
+#X array green 256 float 0;
+#X pop;
+#X graph graph3 0 -1 255 1 498 459 698 319;
+#X array blue 256 float 0;
+#X pop;
+#X obj 217 183 fs.hist 0 red;
+#X obj 230 208 fs.hist 1 green;
+#X obj 245 234 fs.hist 2 blue;
+#X text 110 13 click reset;
+#X text 6 271 drop your favorite videofile to the frame .. then scrub
+it!;
+#X text 6 442 NOTE: fs.hist writes temporary files to your c:/.;
+#X text 55 461 modify fs.hist.pd for a proper temporary path.;
+#X obj 332 14 init;
+#X msg 243 127 HARMON.JPG;
+#X connect 0 0 9 0;
+#X connect 1 0 2 0;
+#X connect 2 0 9 0;
+#X connect 3 0 9 0;
+#X connect 5 0 9 0;
+#X connect 7 0 6 0;
+#X connect 7 0 8 0;
+#X connect 8 0 6 1;
+#X connect 9 0 0 0;
+#X connect 9 0 12 0;
+#X connect 9 0 13 0;
+#X connect 9 0 14 0;
+#X connect 9 1 0 1;
+#X connect 9 1 5 0;
+#X connect 19 0 3 0;
+#X connect 19 0 20 0;
+#X connect 20 0 9 0;
diff --git a/Patches/15 example-searchpath.pd b/Patches/15 example-searchpath.pd
new file mode 100644
index 0000000..ed1bd25
--- /dev/null
+++ b/Patches/15 example-searchpath.pd
@@ -0,0 +1,28 @@
+#N canvas 309 76 603 483 12;
+#X obj 16 42 fs.main;
+#X msg 16 16 6001;
+#X msg 67 16 reset;
+#X obj 270 314 fs.framed searchpath;
+#X msg 435 314 35 + 148;
+#X msg 163 60 path /framestein \, path /fsrel/framestein;
+#X text 162 32 use "path <dir>" to tell where to search for images
+;
+#X msg 276 186 harmon.jpg;
+#X msg 296 216 virvezoom.jpg;
+#X msg 311 247 yska320x240.jpg;
+#X msg 259 159 head.avi;
+#X text 68 380 The dir where Framestein.exe was started from is always
+in the search path.;
+#X obj 435 290 init;
+#X text 260 131 .. to make it easy to load them:;
+#X connect 1 0 0 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 1;
+#X connect 3 2 4 0;
+#X connect 4 0 3 0;
+#X connect 5 0 0 1;
+#X connect 7 0 3 0;
+#X connect 8 0 3 0;
+#X connect 9 0 3 0;
+#X connect 10 0 3 0;
+#X connect 12 0 4 0;
diff --git a/Patches/README.txt b/Patches/README.txt
new file mode 100644
index 0000000..0fa86fe
--- /dev/null
+++ b/Patches/README.txt
@@ -0,0 +1 @@
+See externals-documentation.pd in this folder.
diff --git a/Patches/arraysize.c b/Patches/arraysize.c
new file mode 100644
index 0000000..3393e8f
--- /dev/null
+++ b/Patches/arraysize.c
@@ -0,0 +1,44 @@
+#include <m_pd.h>
+
+static t_class *arraysize_class;
+
+typedef struct _arraysize {
+ t_object x_obj;
+ t_symbol *array_name;
+} t_arraysize;
+
+void arraysize_set(t_arraysize *x, t_symbol *s)
+{
+ x->array_name = s;
+}
+
+void arraysize_bang(t_arraysize *x)
+{
+ t_garray *garray;
+
+ if(!(garray = (t_garray *)pd_findbyclass(x->array_name,garray_class))) {
+ pd_error(x, "%s: no such table", x->array_name->s_name);
+ } else {
+ outlet_float(x->x_obj.ob_outlet, garray_npoints(garray));
+ }
+}
+
+void *arraysize_new(t_symbol *s)
+{
+ t_arraysize *x = (t_arraysize *)pd_new(arraysize_class);
+
+ outlet_new(&x->x_obj, gensym("float"));
+
+ x->array_name = s;
+
+ return (void *)x;
+}
+
+void arraysize_setup(void)
+{
+
+ arraysize_class = class_new(gensym("arraysize"), (t_newmethod)arraysize_new, 0, sizeof(t_arraysize), CLASS_DEFAULT, A_DEFSYMBOL, 0);
+
+ class_addmethod(arraysize_class,arraysize_set,gensym("set"), A_DEFSYM, 0);
+ class_addbang(arraysize_class,arraysize_bang);
+}
diff --git a/Patches/arraysize.dll b/Patches/arraysize.dll
new file mode 100644
index 0000000..ffa3c8f
--- /dev/null
+++ b/Patches/arraysize.dll
Binary files differ
diff --git a/Patches/arraysize.exp b/Patches/arraysize.exp
new file mode 100644
index 0000000..6292542
--- /dev/null
+++ b/Patches/arraysize.exp
Binary files differ
diff --git a/Patches/arraysize.lib b/Patches/arraysize.lib
new file mode 100644
index 0000000..c0342cf
--- /dev/null
+++ b/Patches/arraysize.lib
Binary files differ
diff --git a/Patches/arraysize.obj b/Patches/arraysize.obj
new file mode 100644
index 0000000..8c664e8
--- /dev/null
+++ b/Patches/arraysize.obj
Binary files differ
diff --git a/Patches/bangx.pd b/Patches/bangx.pd
new file mode 100644
index 0000000..2bd5f82
--- /dev/null
+++ b/Patches/bangx.pd
@@ -0,0 +1,10 @@
+#N canvas 286 240 264 239 12;
+#X obj 42 89 until;
+#X obj 42 61 f 1;
+#X obj 42 32 inlet;
+#X obj 42 152 outlet;
+#X msg 42 118 bang;
+#X connect 0 0 4 0;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 4 0 3 0;
diff --git a/Patches/buildstr.c b/Patches/buildstr.c
new file mode 100644
index 0000000..6ba6b15
--- /dev/null
+++ b/Patches/buildstr.c
@@ -0,0 +1,51 @@
+#include <m_pd.h>
+
+#define MAXLEN 500
+
+static t_class *buildstr_class;
+
+typedef struct _buildstr {
+ t_object x_obj;
+ t_symbol s;
+ char buf[MAXLEN];
+ int pos;
+} t_buildstr;
+
+void buildstr_bang(t_buildstr *x)
+{
+ x->s.s_name = t_getbytes(strlen(x->buf)+1);
+ strcpy(x->s.s_name, x->buf);
+ outlet_symbol(x->x_obj.ob_outlet, &x->s);
+ t_freebytes(x->s.s_name, strlen(x->buf)+1);
+}
+
+void buildstr_float(t_buildstr *x, t_float f)
+{
+ x->buf[x->pos] = (char)f;
+ x->pos++;
+
+ if(f==0)
+ {
+ x->pos=0;
+ buildstr_bang(x);
+ }
+}
+
+void *buildstr_new(t_symbol *s)
+{
+ t_buildstr *x = (t_buildstr *)pd_new(buildstr_class);
+
+ x->pos = 0;
+
+ outlet_new(&x->x_obj, gensym("symbol"));
+
+ return (void *)x;
+}
+
+void buildstr_setup(void)
+{
+ buildstr_class = class_new(gensym("buildstr"), (t_newmethod)buildstr_new, 0, sizeof(t_buildstr), CLASS_DEFAULT, A_DEFSYMBOL, 0);
+
+ class_addbang(buildstr_class, buildstr_bang);
+ class_addfloat(buildstr_class, buildstr_float);
+}
diff --git a/Patches/buildstr.dll b/Patches/buildstr.dll
new file mode 100644
index 0000000..92de6a3
--- /dev/null
+++ b/Patches/buildstr.dll
Binary files differ
diff --git a/Patches/buildstr.exp b/Patches/buildstr.exp
new file mode 100644
index 0000000..38c60e9
--- /dev/null
+++ b/Patches/buildstr.exp
Binary files differ
diff --git a/Patches/buildstr.lib b/Patches/buildstr.lib
new file mode 100644
index 0000000..d1aa14c
--- /dev/null
+++ b/Patches/buildstr.lib
Binary files differ
diff --git a/Patches/buildstr.obj b/Patches/buildstr.obj
new file mode 100644
index 0000000..a916941
--- /dev/null
+++ b/Patches/buildstr.obj
Binary files differ
diff --git a/Patches/count.pd b/Patches/count.pd
new file mode 100644
index 0000000..a627e99
--- /dev/null
+++ b/Patches/count.pd
@@ -0,0 +1,17 @@
+#N canvas 0 0 454 304 10;
+#X obj 170 53 inlet;
+#X text 177 7 count to n;
+#X obj 170 168 f;
+#X obj 170 211 outlet;
+#X obj 170 85 t f b;
+#X obj 145 131 bangx;
+#X obj 198 168 + 1;
+#X msg 203 116 1;
+#X connect 0 0 4 0;
+#X connect 2 0 6 0;
+#X connect 2 0 3 0;
+#X connect 4 0 5 0;
+#X connect 4 1 7 0;
+#X connect 5 0 2 0;
+#X connect 6 0 2 1;
+#X connect 7 0 2 1;
diff --git a/Patches/displaydepth.h b/Patches/displaydepth.h
new file mode 100644
index 0000000..3df0471
--- /dev/null
+++ b/Patches/displaydepth.h
@@ -0,0 +1,19 @@
+#ifndef __DISPLAYDEPTH_H
+#define __DISPLAYDEPTH_H
+
+#include "windows.h"
+
+int getdisplaydepth(void)
+{
+ DEVMODE dm;
+
+ dm.dmSize = sizeof(DEVMODE);
+ dm.dmDriverExtra = 0;
+
+ if(!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
+ return(0);
+
+ return(dm.dmBitsPerPel);
+}
+
+#endif
diff --git a/Patches/dllcall.h b/Patches/dllcall.h
new file mode 100644
index 0000000..ab7b128
--- /dev/null
+++ b/Patches/dllcall.h
@@ -0,0 +1,46 @@
+#ifndef __DLLCALL_H
+#define __DLLCALL_H
+
+#include "windows.h"
+
+void loadeffect(HMODULE *lib, FARPROC *proc, char *name)
+{
+ if(*lib) FreeLibrary(*lib);
+
+ *lib = LoadLibrary(name);
+ if(!*lib)
+ {
+ post("loadeffect: failed to load %s", name);
+ return;
+ }
+ *proc = GetProcAddress(*lib, "perform_effect");
+ if(!*proc)
+ {
+ post("loadeffect: failed to get perform_effect from %s", name);
+ FreeLibrary(*lib);
+ *lib=NULL;
+ return;
+ }
+}
+
+void loadcopy(HMODULE *lib, FARPROC *proc, char *name)
+{
+ if(*lib) FreeLibrary(*lib);
+
+ *lib = LoadLibrary(name);
+ if(!*lib)
+ {
+ post("loadcopy: failed to load %s", name);
+ return;
+ }
+ *proc = GetProcAddress(*lib, "perform_copy");
+ if(!*proc)
+ {
+ post("loadcopy: failed to get perform_copy from %s", name);
+ FreeLibrary(*lib);
+ *lib=NULL;
+ return;
+ }
+}
+
+#endif
diff --git a/Patches/externals-documentation.pd b/Patches/externals-documentation.pd
new file mode 100644
index 0000000..f065834
--- /dev/null
+++ b/Patches/externals-documentation.pd
@@ -0,0 +1,342 @@
+#N canvas 438 30 545 591 12;
+#X text 21 21 Externals for video:;
+#N canvas 148 3 734 663 vframe 0;
+#X obj 34 275 fs.frame;
+#X obj 55 377 vimport;
+#X obj 221 427 fs.frame;
+#X msg 244 398 320x240;
+#X msg 253 178 bang;
+#X text 302 176 set vframe to import to;
+#X text 26 509 Connect vframe directly to fs.frame to display it with
+a bang.;
+#X msg 253 206 bang;
+#X text 302 198 import image \, and bang vframe again to display it
+;
+#X obj 150 331 vframe 640 480;
+#X msg 34 245 320x240 \, noize \, colortv;
+#X text 17 14 vframe holds memory for a single image and is the basis
+of Pure Data-externals-based image handling in Framestein.;
+#X text 26 553 Here \, vframe is bigger (640x480) than the two fs.frames
+(320x240). This is okay - as long as the fs.frames you import from
+and to are of the same size \, the image will be right. If you import
+to fs.frame of a different size than the fs.frame you imported from
+-> garbage.;
+#X text 17 109 vframe has no image loading and display functionality.
+Images can be imported to and from fs.frame:;
+#X msg 349 423 dock vframe \, 330+260;
+#X text 16 59 Initialization arguments determine the width and height
+of the image \, as in below. Defaults are 176 and 144;
+#X obj 34 220 init;
+#X obj 244 373 init;
+#X connect 0 0 1 0;
+#X connect 3 0 2 0;
+#X connect 4 0 9 0;
+#X connect 7 0 0 0;
+#X connect 7 0 9 0;
+#X connect 9 0 1 1;
+#X connect 9 0 2 0;
+#X connect 10 0 0 0;
+#X connect 14 0 2 0;
+#X connect 16 0 10 0;
+#X connect 17 0 3 0;
+#X restore 64 216 pd vframe;
+#X obj 67 122 fs.main;
+#X msg 67 86 6001;
+#X text 160 215 basic image container;
+#N canvas 256 206 618 418 vplugin 0;
+#X obj 94 226 vframe;
+#X obj 143 156 vplugin;
+#X text 13 10 vframe can execute Framestein-plugins. vplugin has the
+path to these plugins - open it up \, correct the path \, and try it.
+;
+#X msg 161 99 noize;
+#X msg 218 99 colortv;
+#X obj 94 286 fs.frame;
+#X msg 201 240 dock vplugin \, 200+235;
+#X connect 0 0 5 0;
+#X connect 1 0 0 0;
+#X connect 3 0 1 0;
+#X connect 4 0 1 0;
+#X connect 6 0 5 0;
+#X restore 64 262 pd vplugin;
+#X text 158 261 execute Framestein-plugins;
+#N canvas 187 -3 640 677 vcopy 0;
+#X obj 87 204 vcopy;
+#X msg 240 145 tile \$1;
+#X floatatom 240 116 5 0 0;
+#X floatatom 240 176 5 0 0;
+#X msg 240 201 xbend \$1;
+#X obj 87 341 fs.frame;
+#X obj 114 61 r vcopyexample;
+#X obj 87 129 vref;
+#X msg 87 98 bang;
+#X floatatom 97 159 5 0 0;
+#X msg 167 341 320x240;
+#X obj 87 294 vframe 320 240;
+#X msg 240 283 xbend \$1 \$2;
+#X obj 240 258 pack f f;
+#X floatatom 240 233 5 0 0;
+#X floatatom 299 233 5 0 0;
+#X msg 311 259 bang;
+#X obj 386 201 random 320;
+#X obj 386 227 random 320;
+#X floatatom 386 113 5 0 0;
+#X msg 118 379 dock vcopy \, 90+400;
+#X text 17 9 Some plugins operate on two images. This is done with
+vcopy:;
+#X obj 167 315 init;
+#X obj 386 139 fps 0.25;
+#X connect 0 0 11 0;
+#X connect 1 0 0 1;
+#X connect 1 0 8 0;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 1;
+#X connect 4 0 8 0;
+#X connect 6 0 7 1;
+#X connect 7 0 0 0;
+#X connect 7 0 9 0;
+#X connect 8 0 7 0;
+#X connect 10 0 5 0;
+#X connect 11 0 5 0;
+#X connect 12 0 0 1;
+#X connect 12 0 8 0;
+#X connect 13 0 12 0;
+#X connect 14 0 13 0;
+#X connect 15 0 13 1;
+#X connect 15 0 16 0;
+#X connect 16 0 13 0;
+#X connect 17 0 14 0;
+#X connect 18 0 15 0;
+#X connect 19 0 23 0;
+#X connect 20 0 5 0;
+#X connect 22 0 10 0;
+#X connect 23 0 17 0;
+#X connect 23 0 18 0;
+#X restore 64 310 pd vcopy;
+#X text 159 309 execute plugins that use two images;
+#N canvas 148 7 833 572 vsig~ 0;
+#X text 14 9 vsig~: convert image to signal;
+#X obj 201 140 vframe;
+#X obj 209 182 vsig~;
+#X obj 209 446 vsnapshot~;
+#X obj 257 185 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1
+-1;
+#X obj 201 109 vplugin;
+#X obj 284 413 vframe;
+#X msg 201 75 noize \, colortv;
+#X msg 378 99 \; pd dsp 1;
+#X obj 209 485 fs.frame;
+#X msg 284 387 bang;
+#X text 402 204 - image signal;
+#X text 403 228 - sync signal;
+#X text 403 253 - bang when bottomright of image is reached;
+#X text 383 302 vsnapshot~ inlets:;
+#X text 382 180 vsig~ outlets:;
+#X text 402 330 - image signal;
+#X text 403 354 - sync signal;
+#X text 403 380 - vframe to write image to;
+#X obj 45 289 dac~;
+#X floatatom 89 255 5 0 0;
+#X text 83 289 sounds great!;
+#X obj 45 255 *~ 0;
+#X text 14 25 vsnapshot~: convert signal to image;
+#X msg 273 102 black;
+#X obj 44 370 osc~ 2;
+#X obj 44 397 *~ 0;
+#X floatatom 86 397 5 0 0;
+#X text 100 372 looks great!;
+#X floatatom 44 345 5 0 0;
+#X msg 44 485 dock vsig~ \, 12+87;
+#X obj 378 72 init;
+#X obj 284 361 init;
+#X connect 1 0 2 0;
+#X connect 2 0 22 0;
+#X connect 2 0 3 0;
+#X connect 2 1 3 1;
+#X connect 2 2 4 0;
+#X connect 3 0 9 0;
+#X connect 5 0 1 0;
+#X connect 6 0 3 2;
+#X connect 7 0 5 0;
+#X connect 10 0 6 0;
+#X connect 20 0 22 1;
+#X connect 22 0 19 0;
+#X connect 22 0 19 1;
+#X connect 24 0 5 0;
+#X connect 25 0 26 0;
+#X connect 26 0 3 0;
+#X connect 27 0 26 1;
+#X connect 29 0 25 0;
+#X connect 30 0 9 0;
+#X connect 31 0 8 0;
+#X connect 31 0 7 0;
+#X connect 32 0 10 0;
+#X restore 64 360 pd vsig~ and vsnapshot~;
+#X text 161 392 convert image to signal and back;
+#N canvas 239 28 735 584 vrgb~ 0;
+#X obj 389 140 vframe 320 240;
+#X obj 389 171 vsig~;
+#X text 9 7 vrgb~: separate red \, green and blue channels;
+#X obj 240 239 vimport;
+#X obj 181 188 fs.frame;
+#X obj 188 77 reset;
+#X obj 188 102 t b b b;
+#X msg 234 77 bang;
+#X msg 277 77 \; pd dsp 1;
+#X obj 435 174 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1
+-1;
+#X obj 389 221 vrgb~;
+#X obj 389 345 vsnapshot~;
+#X obj 482 327 vframe 320 240;
+#X obj 482 277 reset;
+#X msg 482 302 bang;
+#X obj 389 387 fs.frame;
+#X msg 482 379 320x240;
+#X obj 427 269 *~ 1;
+#X obj 571 88 phasor~ 1;
+#X obj 571 112 avg~;
+#X obj 571 141 < 0.5;
+#X obj 571 166 * -1;
+#X obj 616 141 >= 0.5;
+#X obj 616 166 * 1;
+#X obj 571 191 +;
+#X floatatom 571 216 5 0 0;
+#X floatatom 571 63 5 0 0;
+#X msg 367 429 dock vrgb~ \, 25+300;
+#X obj 567 360 s vcopyexample;
+#X obj 389 304 vcolor~;
+#X obj 389 269 *~ 1;
+#X text 8 26 vcolor~: merge red \, green and blue channels;
+#X msg 41 152 yska320x240.jpg \, bang;
+#X connect 0 0 1 0;
+#X connect 0 0 3 1;
+#X connect 1 0 10 0;
+#X connect 1 1 11 1;
+#X connect 1 2 9 0;
+#X connect 4 0 3 0;
+#X connect 5 0 6 0;
+#X connect 5 0 7 0;
+#X connect 6 0 0 0;
+#X connect 6 1 32 0;
+#X connect 6 2 0 0;
+#X connect 7 0 6 0;
+#X connect 7 0 8 0;
+#X connect 7 0 6 0;
+#X connect 10 0 30 0;
+#X connect 10 1 17 0;
+#X connect 11 0 15 0;
+#X connect 12 0 11 2;
+#X connect 12 0 28 0;
+#X connect 13 0 14 0;
+#X connect 14 0 12 0;
+#X connect 14 0 16 0;
+#X connect 16 0 15 0;
+#X connect 17 0 29 1;
+#X connect 18 0 19 0;
+#X connect 19 0 22 0;
+#X connect 19 0 20 0;
+#X connect 20 0 21 0;
+#X connect 21 0 24 0;
+#X connect 22 0 23 0;
+#X connect 23 0 24 1;
+#X connect 24 0 25 0;
+#X connect 25 0 17 1;
+#X connect 25 0 30 1;
+#X connect 26 0 18 0;
+#X connect 27 0 15 0;
+#X connect 29 0 11 0;
+#X connect 30 0 29 0;
+#X connect 32 0 4 0;
+#X restore 64 440 pd vrgb~;
+#X text 162 439 separate red \, green and blue channels;
+#X text 159 144 ... click on "dock" on subpatches.;
+#X msg 118 86 reset;
+#X msg 339 82 minimizeall;
+#X text 159 122 start by clicking reset... and minimizeall;
+#N canvas 233 -13 700 660 vframeread~ 0;
+#X text 11 7 vframeread~ uses a sync-signal to read the image:;
+#X obj 212 308 vframe;
+#X obj 161 337 vimport;
+#X obj 71 297 fs.frame;
+#X obj 71 326 fs.copy;
+#X obj 71 353 fs.frame;
+#X msg 212 280 bang;
+#X obj 212 251 reset;
+#X msg 71 116 dock vframeread~ \, 10+100;
+#X text 13 47 drop a movie (.avi) here...;
+#X text 82 96 click here;
+#X obj 361 92 vframeread~;
+#X obj 361 312 vsnapshot~;
+#X obj 14 307 fps 5;
+#X floatatom 53 427 5 0 0;
+#X msg 81 270 next \, bang;
+#X obj 361 372 fs.frame;
+#X msg 361 469 dock vframeread~ \, 330+440;
+#X text 380 445 click here;
+#X obj 436 287 vframe;
+#X obj 436 237 reset;
+#X msg 436 262 bang;
+#X obj 361 344 vref;
+#X floatatom 482 130 5 0 0;
+#X obj 482 159 phasor~ 1;
+#X obj 491 259 vplugin;
+#X msg 491 235 black;
+#X text 107 426 set framerate;
+#X msg 482 104 14.9;
+#X obj 482 79 reset;
+#X text 534 130 see how it's done;
+#X text 17 595 This gives a better frame-rate \, compromizing the image
+quality..;
+#X obj 361 204 *~ 1;
+#X floatatom 388 179 5 0 0;
+#X msg 87 398 25;
+#X msg 524 104 25.19;
+#X msg 388 152 1;
+#X msg 419 152 -1;
+#X msg 53 398 15;
+#X connect 1 0 2 1;
+#X connect 1 0 11 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 5 0 2 0;
+#X connect 6 0 1 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 0;
+#X connect 8 0 3 0;
+#X connect 11 0 32 0;
+#X connect 12 0 22 1;
+#X connect 13 0 15 0;
+#X connect 13 0 5 0;
+#X connect 13 0 22 0;
+#X connect 14 0 13 0;
+#X connect 15 0 3 0;
+#X connect 17 0 16 0;
+#X connect 19 0 12 2;
+#X connect 20 0 21 0;
+#X connect 21 0 19 0;
+#X connect 22 0 16 0;
+#X connect 23 0 24 0;
+#X connect 23 0 26 0;
+#X connect 24 0 12 1;
+#X connect 24 0 11 0;
+#X connect 25 0 19 0;
+#X connect 26 0 25 0;
+#X connect 28 0 23 0;
+#X connect 29 0 28 0;
+#X connect 32 0 12 0;
+#X connect 33 0 32 1;
+#X connect 34 0 14 0;
+#X connect 35 0 23 0;
+#X connect 36 0 33 0;
+#X connect 37 0 33 0;
+#X connect 38 0 14 0;
+#X restore 64 487 pd vframeread~;
+#X text 195 486 read image with a sync-signal;
+#X obj 339 57 init;
+#X text 65 530 vdrawarray is documented on example-vdrawarray.;
+#X connect 3 0 2 0;
+#X connect 3 0 14 0;
+#X connect 14 0 2 1;
+#X connect 15 0 2 1;
+#X connect 19 0 15 0;
diff --git a/Patches/fps.pd b/Patches/fps.pd
new file mode 100644
index 0000000..3e61074
--- /dev/null
+++ b/Patches/fps.pd
@@ -0,0 +1,25 @@
+#N canvas 17 261 466 316 12;
+#X obj 307 192 /;
+#X obj 319 128 t b f;
+#X obj 67 27 inlet;
+#X msg 293 157 1000;
+#X obj 87 222 outlet;
+#X obj 87 112 metro 1000;
+#X text 10 -1 sends bangs to make "frames per second";
+#X obj 226 62 float \$1;
+#X obj 226 32 loadbang;
+#X obj 307 218 abs;
+#X obj 344 37 inlet;
+#X text 354 61 "cold" inlet;
+#X connect 0 0 9 0;
+#X connect 1 0 3 0;
+#X connect 1 1 0 1;
+#X connect 2 0 1 0;
+#X connect 2 0 5 0;
+#X connect 3 0 0 0;
+#X connect 5 0 4 0;
+#X connect 7 0 1 0;
+#X connect 7 0 5 0;
+#X connect 8 0 7 0;
+#X connect 9 0 5 1;
+#X connect 10 0 1 0;
diff --git a/Patches/fs.avi.pd b/Patches/fs.avi.pd
new file mode 100644
index 0000000..909e4d9
--- /dev/null
+++ b/Patches/fs.avi.pd
@@ -0,0 +1,33 @@
+#N canvas 237 45 692 382 12;
+#X obj 172 80 loadbang;
+#X obj 126 275 fs_sender;
+#X obj 51 27 inlet;
+#X obj 51 55 l2s;
+#X obj 51 102 pack s s;
+#X obj 172 203 symbol;
+#X obj 189 147 r fs_reset;
+#X msg 189 172 bang;
+#X text 287 28 commands:;
+#X obj 172 110 symbol \$0A;
+#X msg 172 228 avi \$1;
+#X msg 51 137 \$2 \$1;
+#X text 103 28 command;
+#X text 318 56 fs.frame id to save one frame of video;
+#X obj 59 310 r \$0Apos;
+#X obj 59 340 outlet;
+#X text 326 96 write <filename.avi> to write it out;
+#X text 323 115 (without filename a dialog will pop);
+#X text 330 161 "fps 10" to set frames per second.;
+#X text 318 182 (only effective before adding frames);
+#X connect 0 0 9 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 4 0 11 0;
+#X connect 5 0 10 0;
+#X connect 6 0 7 0;
+#X connect 7 0 5 0;
+#X connect 9 0 4 1;
+#X connect 9 0 5 0;
+#X connect 10 0 1 0;
+#X connect 11 0 1 0;
+#X connect 14 0 15 0;
diff --git a/Patches/fs.blend.pd b/Patches/fs.blend.pd
new file mode 100644
index 0000000..32ce7e0
--- /dev/null
+++ b/Patches/fs.blend.pd
@@ -0,0 +1,37 @@
+#N canvas 30 209 749 354 10;
+#X obj 55 42 inlet;
+#X obj 159 301 outlet;
+#X obj 239 43 inlet;
+#X obj 90 143 fs.copy;
+#X obj 173 146 fs.copy;
+#X obj 192 104 symbol;
+#X obj 330 44 inlet;
+#X msg 329 100 alpha \$1;
+#X msg 289 176 127;
+#X msg 286 215 flip_manual;
+#X obj 346 174 init;
+#X obj 63 91 t b s b;
+#X msg 24 134 flip;
+#X text 47 20 fs.frame;
+#X text 229 19 fs.frame;
+#X text 152 322 fs.frame;
+#X text 314 21 blend amount;
+#X text 447 21 fs.blend -- mix two images with parameter;
+#X text 447 44 see example-blending.pd!;
+#X obj 330 71 int;
+#X connect 0 0 11 0;
+#X connect 2 0 5 1;
+#X connect 3 0 1 0;
+#X connect 4 0 1 0;
+#X connect 5 0 4 0;
+#X connect 6 0 19 0;
+#X connect 7 0 3 1;
+#X connect 8 0 7 0;
+#X connect 9 0 1 0;
+#X connect 10 0 8 0;
+#X connect 10 0 9 0;
+#X connect 11 0 12 0;
+#X connect 11 1 3 0;
+#X connect 11 2 5 0;
+#X connect 12 0 1 0;
+#X connect 19 0 7 0;
diff --git a/Patches/fs.browser.pd b/Patches/fs.browser.pd
new file mode 100644
index 0000000..cac5233
--- /dev/null
+++ b/Patches/fs.browser.pd
@@ -0,0 +1,48 @@
+#N canvas 43 99 953 532 12;
+#X obj 444 24 loadbang;
+#X obj 276 380 fs_sender;
+#X obj 76 25 inlet;
+#X obj 76 55 route bang;
+#X obj 76 91 symbol;
+#X obj 151 111 route fs_op;
+#X obj 151 153 pack s s s;
+#X obj 76 125 outlet;
+#X obj 276 193 l2s;
+#X obj 276 226 pack s s;
+#X msg 276 259 \$2 \$1;
+#X text 450 149 inlet accepts:;
+#X obj 444 91 symbol;
+#X obj 538 83 r fs_reset;
+#X msg 538 108 bang;
+#X obj 444 54 symbol \$0fs.browser;
+#X msg 444 119 browser \$1;
+#X text 492 181 <url> or "open <url>";
+#X text 491 210 "refresh" "stop";
+#X text 491 240 "640x480" to set display size;
+#X obj 461 327 r \$0fs.browserlink;
+#X obj 461 380 symbol;
+#X obj 461 406 outlet;
+#X text 461 304 report clicked links starting with "fs:";
+#X obj 461 353 buildstr;
+#X connect 0 0 15 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 3 1 5 0;
+#X connect 4 0 7 0;
+#X connect 5 0 6 0;
+#X connect 5 1 8 0;
+#X connect 6 0 1 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 1 0;
+#X connect 12 0 16 0;
+#X connect 13 0 14 0;
+#X connect 14 0 12 0;
+#X connect 15 0 4 1;
+#X connect 15 0 6 2;
+#X connect 15 0 9 1;
+#X connect 15 0 12 0;
+#X connect 16 0 1 0;
+#X connect 20 0 24 0;
+#X connect 21 0 22 0;
+#X connect 24 0 21 0;
diff --git a/Patches/fs.copy.pd b/Patches/fs.copy.pd
new file mode 100644
index 0000000..8598ae9
--- /dev/null
+++ b/Patches/fs.copy.pd
@@ -0,0 +1,51 @@
+#N canvas 205 60 932 444 12;
+#X obj 173 21 loadbang;
+#X obj 208 271 fs_sender;
+#X msg 173 204 copy \$1;
+#X obj 352 14 inlet;
+#X text 465 118 dest_all;
+#X text 465 132 dest_random;
+#X text 465 152 copy;
+#X text 465 167 alpha <value>;
+#X text 466 197 sub <value>;
+#X text 465 183 add <value>;
+#X text 466 62 source_all;
+#X text 466 79 source_random;
+#X obj 23 22 inlet;
+#X obj 23 155 outlet;
+#X obj 23 62 pack s s;
+#X msg 23 95 fs_op \$2 \$1;
+#X obj 352 156 pack s s;
+#X msg 352 185 \$2 \$1;
+#X obj 352 127 l2s;
+#X text 466 47 source <left> <top> <right> <bottom>;
+#X text 465 104 dest <left> <top> <right> <bottom>;
+#X text 399 15 for these commands:;
+#X obj 173 174 symbol;
+#X obj 194 114 r fs_reset;
+#X msg 194 140 bang;
+#X text 467 267 blackness dstinvert mergecopy mergepaint notsrccopy
+notsrcerase patcopy patinvert patpaint srcand srccopy srcerase srcinvert
+srcpaint whiteness;
+#X text 466 226 try these raster operations: (some of them do nothing)
+;
+#X text 468 329 transparent_0/1 mirrorleftright_0/1 mirrorupdown_0/1
+;
+#X text 467 358 "plugin_name" (see example-plugins.pd);
+#X obj 173 51 symbol \$0C;
+#X text 467 389 "filter_name" (see example-photoshopfilters.pd);
+#X connect 0 0 29 0;
+#X connect 2 0 1 0;
+#X connect 3 0 18 0;
+#X connect 12 0 14 0;
+#X connect 14 0 15 0;
+#X connect 15 0 13 0;
+#X connect 16 0 17 0;
+#X connect 17 0 1 0;
+#X connect 18 0 16 0;
+#X connect 22 0 2 0;
+#X connect 23 0 24 0;
+#X connect 24 0 29 0;
+#X connect 29 0 14 1;
+#X connect 29 0 16 1;
+#X connect 29 0 22 0;
diff --git a/Patches/fs.draw.pd b/Patches/fs.draw.pd
new file mode 100644
index 0000000..cc9ea77
--- /dev/null
+++ b/Patches/fs.draw.pd
@@ -0,0 +1,32 @@
+#N canvas 301 30 843 370 12;
+#X obj 172 80 loadbang;
+#X obj 126 275 fs_sender;
+#X obj 51 27 inlet;
+#X obj 51 55 l2s;
+#X obj 51 102 pack s s;
+#X msg 51 137 fs_op \$2 \$1;
+#X obj 172 203 symbol;
+#X obj 189 147 r fs_reset;
+#X msg 189 172 bang;
+#X text 100 28 command;
+#X text 344 89 commands:;
+#X text 363 123 rect <x1> <y1> <x2> <y2>;
+#X msg 172 228 draw \$1;
+#X obj 51 176 outlet;
+#X text 362 143 line <x1> <y1> <x2> <y2>;
+#X text 363 162 plot <x> <y>;
+#X text 363 234 mode_solid mode_clear;
+#X text 362 196 pen <r> <g> <b> (to set pen color);
+#X text 362 215 brush <r> <g> <b> (to set brush color);
+#X obj 172 110 symbol \$0D;
+#X connect 0 0 19 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 5 0 13 0;
+#X connect 6 0 12 0;
+#X connect 7 0 8 0;
+#X connect 8 0 6 0;
+#X connect 12 0 1 0;
+#X connect 19 0 4 1;
+#X connect 19 0 6 0;
diff --git a/Patches/fs.event.pd b/Patches/fs.event.pd
new file mode 100644
index 0000000..fa56b61
--- /dev/null
+++ b/Patches/fs.event.pd
@@ -0,0 +1,30 @@
+#N canvas 381 52 466 526 12;
+#X obj 37 50 inlet;
+#X text 86 50 fs.frame 1st outlet;
+#X obj 96 107 symbol \$0E;
+#X obj 37 132 pack s s;
+#X obj 96 83 loadbang;
+#X msg 37 166 \; \$1event \$2;
+#X obj 323 373 r \$0Emouseup;
+#X obj 323 459 outlet;
+#X obj 38 460 outlet;
+#X text 323 350 report mouseup;
+#X obj 169 461 outlet;
+#X text 168 350 report mousedown;
+#X obj 169 375 r \$0Emousedown;
+#X text 16 13 fs.event - events from fs.frame;
+#X text 38 334 report drag&drop filename;
+#X obj 38 374 r \$0Efile;
+#X obj 38 431 symbol;
+#X msg 169 430 bang;
+#X msg 323 428 bang;
+#X connect 0 0 3 0;
+#X connect 2 0 3 1;
+#X connect 3 0 5 0;
+#X connect 4 0 2 0;
+#X connect 6 0 18 0;
+#X connect 12 0 17 0;
+#X connect 15 0 16 0;
+#X connect 16 0 8 0;
+#X connect 17 0 10 0;
+#X connect 18 0 7 0;
diff --git a/Patches/fs.film.pd b/Patches/fs.film.pd
new file mode 100644
index 0000000..84d64e8
--- /dev/null
+++ b/Patches/fs.film.pd
@@ -0,0 +1,47 @@
+#N canvas 31 111 536 458 12;
+#X obj 121 289 fs.frame;
+#X obj 323 218 reset;
+#X msg 323 246 hide;
+#X obj 28 31 inlet;
+#X obj 121 374 outlet;
+#X obj 180 374 outlet;
+#X obj 25 332 fs.info;
+#X msg 247 211 bang;
+#X obj 28 68 route open start stop;
+#X obj 28 128 openpanel;
+#X msg 56 156 bang;
+#X msg 221 129 bang;
+#X msg 273 128 0;
+#X obj 234 182 play 0;
+#X msg 209 69 bang;
+#X obj 221 154 int;
+#X floatatom 42 360 5 0 0;
+#X msg 28 103 bang;
+#X obj 121 331 symbol;
+#X floatatom 318 154 5 0 0;
+#X connect 0 0 6 0;
+#X connect 0 0 18 1;
+#X connect 0 1 5 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 0;
+#X connect 3 0 8 0;
+#X connect 6 3 15 1;
+#X connect 6 3 16 0;
+#X connect 7 0 18 0;
+#X connect 8 0 17 0;
+#X connect 8 1 11 0;
+#X connect 8 2 12 0;
+#X connect 8 3 0 0;
+#X connect 8 3 14 0;
+#X connect 9 0 0 0;
+#X connect 9 0 10 0;
+#X connect 10 0 0 0;
+#X connect 11 0 15 0;
+#X connect 12 0 13 0;
+#X connect 13 0 0 0;
+#X connect 13 0 7 0;
+#X connect 14 0 0 0;
+#X connect 15 0 13 0;
+#X connect 17 0 9 0;
+#X connect 18 0 4 0;
+#X connect 19 0 13 0;
diff --git a/Patches/fs.frame.pd b/Patches/fs.frame.pd
new file mode 100644
index 0000000..bac2004
--- /dev/null
+++ b/Patches/fs.frame.pd
@@ -0,0 +1,137 @@
+#N canvas 19 -3 1010 686 12;
+#X msg 444 119 frame \$1;
+#X obj 276 355 fs_sender;
+#X obj 76 25 inlet;
+#X obj 76 145 symbol;
+#X obj 151 126 route fs_op;
+#X obj 151 168 pack s s s;
+#X obj 76 192 outlet;
+#X obj 276 193 l2s;
+#X obj 276 226 pack s s;
+#X msg 276 259 \$2 \$1;
+#X text 468 227 "next" "prev" "random" "seek <number>" to show frames
+in video or buffered images.;
+#X text 469 264 "clear" to flush buffered images.;
+#X text 468 300 "flip_auto" "flip_manual" "flip" controls how the display
+should reflect changes in the image.;
+#X text 468 343 "320x240" to set image size "100+100" to set frame
+position "display 600x450" to set display size;
+#X text 469 382 "borders_0" "borders_1" "stayontop_0"/1 "mute_0"/1
+\, also right-click the image for display options.;
+#X text 450 149 inlet accepts:;
+#X obj 444 91 symbol;
+#X text 469 428 "save <directory> <"bmp" or number for jpeg quality>"
+save image in directory under name fs000001 \, fs000002 ...;
+#X text 467 470 "plugin_name" (see example-plugins.pd);
+#X text 471 494 mousetrack_1 and mousetrack_0 to report mouse x \,
+y thru second outlet;
+#X msg 19 295 bang;
+#X text 27 244 drag&drop will bang;
+#X obj 275 482 outlet;
+#X text 471 530 mouserect_1 and mouserect_0 to report dragged rectangle
+;
+#X obj 444 24 reset;
+#X obj 76 55 route bang float;
+#X msg 137 98 vf2fs \$1;
+#N canvas 0 0 646 581 report 0;
+#X obj 54 94 pack f f;
+#X obj 88 248 pack f f f f;
+#X text 58 17 report mouse x \, y;
+#X text 88 130 report mouse rect;
+#X text 115 297 report moving the window;
+#X obj 15 522 outlet;
+#X obj 126 382 pack f f;
+#X msg 126 411 set \$1 + \$2;
+#X obj 54 39 r \$0Fx;
+#X obj 61 63 r \$0Fy;
+#X obj 84 151 r \$0Fx1;
+#X obj 84 175 r \$0Fy1;
+#X obj 84 198 r \$0Fx2;
+#X obj 85 222 r \$0Fy2;
+#X obj 142 324 r \$0Fwinx;
+#X obj 142 348 r \$0Fwiny;
+#X obj 68 522 outlet;
+#X obj 383 101 pack f s;
+#X obj 497 57 r \$0Fevent;
+#X obj 453 101 symbol;
+#X text 383 164 report mouseup;
+#X obj 383 187 r \$0Fmouseup;
+#X obj 383 248 pack f s;
+#X obj 497 204 r \$0Fevent;
+#X msg 383 275 \; \$2mouseup \$1;
+#X obj 453 248 symbol;
+#X text 383 17 report mousedown;
+#X msg 383 128 \; \$2mousedown \$1;
+#X obj 383 40 r \$0Fmousedown;
+#X text 384 341 report drag&drop filename;
+#X obj 384 366 r \$0Ffile;
+#X obj 384 419 buildstr;
+#X obj 384 456 pack s s;
+#X obj 493 412 r \$0Fevent;
+#X obj 454 456 symbol;
+#X msg 384 487 \; \$2file \$1;
+#X obj 384 392 f;
+#X connect 0 0 5 0;
+#X connect 1 0 5 0;
+#X connect 6 0 7 0;
+#X connect 7 0 16 0;
+#X connect 8 0 0 0;
+#X connect 9 0 0 1;
+#X connect 10 0 1 0;
+#X connect 11 0 1 1;
+#X connect 12 0 1 2;
+#X connect 13 0 1 3;
+#X connect 14 0 6 0;
+#X connect 15 0 6 1;
+#X connect 17 0 27 0;
+#X connect 18 0 19 0;
+#X connect 19 0 17 1;
+#X connect 21 0 22 0;
+#X connect 22 0 24 0;
+#X connect 23 0 25 0;
+#X connect 25 0 22 1;
+#X connect 28 0 17 0;
+#X connect 30 0 36 0;
+#X connect 31 0 32 0;
+#X connect 32 0 35 0;
+#X connect 33 0 34 0;
+#X connect 34 0 32 1;
+#X connect 36 0 31 0;
+#X restore 275 440 pd report;
+#X obj 444 54 symbol \$0F;
+#X obj 140 25 r \$0Finlet;
+#X obj 19 269 r \$0Fbang;
+#X obj 327 482 outlet;
+#X text 472 575 minimize \, maximize \, bringtofront;
+#X text 471 553 bufferize will copy the current image to image buffer
+;
+#X text 471 600 hidecursor_1 \, hidecursor_0;
+#X text 470 622 use "directory" - like buffer \, without buffering
+(load on demand);
+#X text 468 190 "buffer <filename(.bmp .jpg)>" to load to memory;
+#X text 469 171 filename to load and display (.avi .bmp .jpg);
+#X text 468 208 "buffer <directory>" to load all images in dir;
+#X connect 0 0 1 0;
+#X connect 2 0 25 0;
+#X connect 3 0 6 0;
+#X connect 4 0 5 0;
+#X connect 4 1 7 0;
+#X connect 5 0 1 0;
+#X connect 7 0 8 0;
+#X connect 8 0 9 0;
+#X connect 9 0 1 0;
+#X connect 16 0 0 0;
+#X connect 20 0 3 0;
+#X connect 24 0 28 0;
+#X connect 25 0 3 0;
+#X connect 25 1 26 0;
+#X connect 25 2 4 0;
+#X connect 26 0 4 0;
+#X connect 27 0 22 0;
+#X connect 27 1 31 0;
+#X connect 28 0 3 1;
+#X connect 28 0 5 2;
+#X connect 28 0 8 1;
+#X connect 28 0 16 0;
+#X connect 29 0 25 0;
+#X connect 30 0 20 0;
diff --git a/Patches/fs.framed.pd b/Patches/fs.framed.pd
new file mode 100644
index 0000000..14c4fb4
--- /dev/null
+++ b/Patches/fs.framed.pd
@@ -0,0 +1,24 @@
+#N canvas 61 76 511 375 12;
+#X obj 92 199 fs.frame;
+#X obj 263 129 symbol \$1;
+#X obj 92 91 inlet;
+#X obj 92 291 outlet;
+#X msg 263 155 dock \$1;
+#X text 9 5 fs.framed - docked fs.frame;
+#X obj 151 291 outlet;
+#X obj 186 129 symbol \$2;
+#X obj 186 93 t b b;
+#X obj 209 291 outlet;
+#X obj 186 68 reset;
+#X text 35 30 usage: fs.framed <substring of windowtitle> <position>
+;
+#X connect 0 0 3 0;
+#X connect 0 1 6 0;
+#X connect 0 2 9 0;
+#X connect 1 0 4 0;
+#X connect 2 0 0 0;
+#X connect 4 0 0 0;
+#X connect 7 0 0 0;
+#X connect 8 0 7 0;
+#X connect 8 1 1 0;
+#X connect 10 0 8 0;
diff --git a/Patches/fs.fx.pd b/Patches/fs.fx.pd
new file mode 100644
index 0000000..f6bedc2
--- /dev/null
+++ b/Patches/fs.fx.pd
@@ -0,0 +1,21 @@
+#N canvas 275 32 645 476 12;
+#X obj 22 171 outlet;
+#X obj 22 138 inlet;
+#X text 114 91 - effects:;
+#X text 130 115 mosaic <value>;
+#X text 129 265 saturation <value>;
+#X text 129 290 addition <r> <g> <b>;
+#X text 130 313 gamma <r> <g> <b>;
+#X text 130 337 contrast <r> <g> <b>;
+#X text 130 361 lightness <r> <g> <b>;
+#X text 130 235 without parameters: invert \, soft \, sharp \, emboss
+;
+#X text 129 139 rotate <degrees counterwise>;
+#X text 130 163 rotozoom <degrees counterwise> <zoom val (65536=none)>
+;
+#X text 130 190 "smooth_1" and "smooth_0" sets smoothing on/off for
+rotate and rotozoom (default is on).;
+#X text 9 34 (you can send these commands directly to fs.frame \, but
+using fs.fx might make your patches more clear);
+#X text 10 6 Yeah \, quite an abstraction!;
+#X connect 1 0 0 0;
diff --git a/Patches/fs.hist.pd b/Patches/fs.hist.pd
new file mode 100644
index 0000000..93f875f
--- /dev/null
+++ b/Patches/fs.hist.pd
@@ -0,0 +1,39 @@
+#N canvas 283 252 725 432 12;
+#X text 13 9 fs.hist - an array of 256 elements \, where x = intensity
+and y = number of colors with that intensity;
+#X obj 40 70 inlet;
+#X obj 40 148 pack s f s s;
+#X obj 252 135 reset;
+#X obj 252 161 symbol \$0hist;
+#X obj 227 69 inlet;
+#X text 277 70 0=red 1=green 2=blue;
+#X text 94 70 fs.frame;
+#X obj 252 193 makefilename c:/%s;
+#X text 249 223 if you run pd and fs on separate machines \, you need
+a mapped network drive to pass the data. sorry.;
+#X obj 111 248 r \$0histbang;
+#X msg 111 273 bang;
+#X obj 40 209 fs_sender;
+#X msg 40 180 \$1 hist \$2 \$3 \$4bang;
+#X obj 227 96 float \$1;
+#X obj 213 298 symbol \$2;
+#X obj 111 304 pack f s s;
+#X msg 111 348 \; \$2 read16 \$3;
+#X text 220 357 2nd arg must be name of table with 256 elements.;
+#X text 383 170 change c:/ to some temp-directory..;
+#X connect 1 0 2 0;
+#X connect 2 0 13 0;
+#X connect 3 0 4 0;
+#X connect 3 0 14 0;
+#X connect 3 0 15 0;
+#X connect 4 0 2 3;
+#X connect 4 0 8 0;
+#X connect 5 0 2 1;
+#X connect 8 0 2 2;
+#X connect 8 0 16 2;
+#X connect 10 0 11 0;
+#X connect 11 0 16 0;
+#X connect 13 0 12 0;
+#X connect 14 0 2 1;
+#X connect 15 0 16 1;
+#X connect 16 0 17 0;
diff --git a/Patches/fs.info.pd b/Patches/fs.info.pd
new file mode 100644
index 0000000..0eeb1e1
--- /dev/null
+++ b/Patches/fs.info.pd
@@ -0,0 +1,33 @@
+#N canvas 19 200 713 421 12;
+#X obj 49 37 inlet;
+#X obj 46 348 outlet;
+#X obj 256 114 symbol;
+#X msg 256 142 info \$1;
+#X obj 49 124 pack s s;
+#X text 14 7 connection from fs.frame;
+#X obj 49 219 fs_sender;
+#X obj 181 344 outlet;
+#X obj 324 340 outlet;
+#X msg 49 190 \$2 \$1 \$2width \$2height \$2framecount \$2framerate
+;
+#X obj 499 339 outlet;
+#X obj 256 69 symbol \$0I;
+#X obj 46 283 r \$0Iwidth;
+#X obj 181 283 r \$0Iheight;
+#X obj 324 283 r \$0Iframecount;
+#X obj 499 283 r \$0Iframerate;
+#X obj 256 39 reset;
+#X text 47 258 report frame width \, height \, video framecount and
+framerate:;
+#X connect 0 0 4 0;
+#X connect 2 0 3 0;
+#X connect 3 0 6 0;
+#X connect 4 0 9 0;
+#X connect 9 0 6 0;
+#X connect 11 0 2 0;
+#X connect 11 0 4 1;
+#X connect 12 0 1 0;
+#X connect 13 0 7 0;
+#X connect 14 0 8 0;
+#X connect 15 0 10 0;
+#X connect 16 0 11 0;
diff --git a/Patches/fs.main.pd b/Patches/fs.main.pd
new file mode 100644
index 0000000..845121d
--- /dev/null
+++ b/Patches/fs.main.pd
@@ -0,0 +1,52 @@
+#N canvas 278 0 700 494 12;
+#X obj 27 293 netsend;
+#X floatatom 27 322 4 0 0;
+#X obj 207 160 loadbang;
+#X msg 206 254 disconnect;
+#X msg 27 253 send \$1;
+#X obj 27 203 r fs_main;
+#X msg 207 185 6001;
+#X obj 127 128 inlet;
+#X text 175 126 port;
+#X obj 127 170 t f b;
+#X text 9 30 only one fs.main at a time \,;
+#X text 9 46 or your commands will be doubled.;
+#X obj 393 42 inlet;
+#X text 439 42 reset;
+#X obj 393 132 t b b;
+#X msg 428 158 send reset;
+#X obj 157 382 pack s f;
+#X floatatom 272 378 4 0 0;
+#X text 10 7 fs.main - handles communication with Framestein.;
+#X msg 157 411 \; \$1 \$2;
+#X text 149 291 you can run framestein and the control-patches on separate
+machines by changing "localhost" to "your.windows.slave" above and
+configuring fs likewise (right-click fs).;
+#X msg 393 199 \; fs_reset bang;
+#X obj 393 78 route reset;
+#X obj 476 114 fs_sender;
+#X obj 157 353 netreceive 6002;
+#X msg 207 225 connect localhost \$1;
+#X obj 408 385 r symbolmousedown;
+#X obj 408 408 r symbolmouseup;
+#X text 404 364 ignore some errors;
+#X obj 408 431 r symbolfile;
+#X connect 0 0 1 0;
+#X connect 2 0 6 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 4 0;
+#X connect 6 0 25 0;
+#X connect 7 0 9 0;
+#X connect 9 0 25 0;
+#X connect 9 1 3 0;
+#X connect 12 0 22 0;
+#X connect 14 0 21 0;
+#X connect 14 1 15 0;
+#X connect 15 0 0 0;
+#X connect 16 0 19 0;
+#X connect 22 0 14 0;
+#X connect 22 1 23 0;
+#X connect 24 0 16 0;
+#X connect 24 1 17 0;
+#X connect 25 0 0 0;
diff --git a/Patches/fs.mask.pd b/Patches/fs.mask.pd
new file mode 100644
index 0000000..b17dee9
--- /dev/null
+++ b/Patches/fs.mask.pd
@@ -0,0 +1,39 @@
+#N canvas 484 206 513 402 10;
+#X obj 33 22 inlet;
+#X obj 51 200 fs.copy;
+#X obj 51 351 outlet;
+#X obj 115 22 inlet;
+#X msg 142 166 srcand;
+#X obj 51 249 fs.frame;
+#X obj 51 158 symbol;
+#X obj 73 116 fs.copy;
+#X obj 51 287 fs.copy;
+#X obj 33 79 t b b s;
+#X obj 180 132 init;
+#X msg 157 190 transparent_1;
+#X msg 168 218 mute_1 \, hide;
+#X msg 168 244 mute_0 \, show;
+#X text 223 42 fs.mask -- copy with mask;
+#X text 223 61 1st inlet: fs.frame to copy from;
+#X text 223 76 2nd inlet: fs.frame of the mask;
+#X text 241 106 outlet: output fs.frame;
+#X obj 165 22 inlet;
+#X text 223 91 3rd inlet: commands to the internal fs.frame;
+#X connect 0 0 9 0;
+#X connect 1 0 5 0;
+#X connect 3 0 6 1;
+#X connect 4 0 1 1;
+#X connect 5 0 8 0;
+#X connect 6 0 1 0;
+#X connect 7 0 5 0;
+#X connect 8 0 2 0;
+#X connect 9 0 5 0;
+#X connect 9 1 6 0;
+#X connect 9 2 7 0;
+#X connect 10 0 4 0;
+#X connect 10 0 11 0;
+#X connect 10 0 12 0;
+#X connect 11 0 8 1;
+#X connect 12 0 5 0;
+#X connect 13 0 5 0;
+#X connect 18 0 5 0;
diff --git a/Patches/fs.rgb.pd b/Patches/fs.rgb.pd
new file mode 100644
index 0000000..164085c
--- /dev/null
+++ b/Patches/fs.rgb.pd
@@ -0,0 +1,31 @@
+#N canvas 46 193 827 465 12;
+#X obj 53 97 inlet;
+#X obj 54 386 outlet;
+#X text 26 414 outputs red \, green and blue;
+#X text 21 61 connection from fs.frame | x and y packed;
+#X obj 244 95 inlet;
+#X obj 53 241 fs_sender;
+#X text 159 187 tell plugin where to send results!;
+#X obj 77 343 pack f f f;
+#X obj 339 150 symbol \$0rgb;
+#X obj 77 310 r \$0rgbred;
+#X obj 162 310 r \$0rgbgreen;
+#X obj 263 310 r \$0rgbblue;
+#X obj 53 164 pack s f f s;
+#X msg 53 209 \$1 rgb \$2 \$3 \$4red \$4green \$4blue;
+#X obj 122 132 unpack f f;
+#X obj 339 126 reset;
+#X text 23 16 fs.rgb -- output red \, green and blue from a given position.
+;
+#X connect 0 0 12 0;
+#X connect 4 0 14 0;
+#X connect 7 0 1 0;
+#X connect 8 0 12 3;
+#X connect 9 0 7 0;
+#X connect 10 0 7 1;
+#X connect 11 0 7 2;
+#X connect 12 0 13 0;
+#X connect 13 0 5 0;
+#X connect 14 0 12 1;
+#X connect 14 1 12 2;
+#X connect 15 0 8 0;
diff --git a/Patches/fs.sonogram.pd b/Patches/fs.sonogram.pd
new file mode 100644
index 0000000..543e91e
--- /dev/null
+++ b/Patches/fs.sonogram.pd
@@ -0,0 +1,63 @@
+#N canvas 143 280 484 334 12;
+#X msg 188 80 bang;
+#X obj 28 47 inlet~;
+#X text 86 48 sound data;
+#X obj 188 48 inlet;
+#X text 243 49 bang to get sonogram;
+#X obj 70 225 outlet;
+#X text 134 224 to fs.frame;
+#N canvas 211 133 544 441 writesono 0;
+#X obj 46 48 inlet~;
+#X obj 144 50 inlet;
+#X obj 46 78 rfft~;
+#X obj 46 111 *~;
+#X obj 77 111 *~;
+#X obj 46 141 sqrt~;
+#X obj 382 17 block~ 1024 1;
+#X obj 218 309 table \$0spectrum;
+#X obj 46 187 tabwrite~ \$0spectrum;
+#X obj 67 359 outlet;
+#X obj 144 92 t b b b;
+#X msg 99 308 sonogram \$1;
+#X obj 218 241 symbol;
+#X msg 301 51 bang;
+#X obj 301 24 reset;
+#X obj 99 241 symbol;
+#X obj 301 106 makefilename c:/%s;
+#X obj 301 77 symbol \$0sono;
+#X msg 317 363 resize 128;
+#X obj 366 333 reset;
+#X msg 317 389 bounds 0 0 128 500;
+#X msg 218 276 write \$1;
+#X text 365 130 maybe c:/temp/?;
+#X obj 291 276 s \$0spectrum;
+#X connect 0 0 2 0;
+#X connect 1 0 10 0;
+#X connect 2 0 3 0;
+#X connect 2 0 3 1;
+#X connect 2 1 4 0;
+#X connect 2 1 4 1;
+#X connect 3 0 5 0;
+#X connect 4 0 5 0;
+#X connect 5 0 8 0;
+#X connect 10 0 15 0;
+#X connect 10 1 12 0;
+#X connect 10 2 8 0;
+#X connect 11 0 9 0;
+#X connect 12 0 21 0;
+#X connect 13 0 17 0;
+#X connect 14 0 13 0;
+#X connect 15 0 11 0;
+#X connect 16 0 12 1;
+#X connect 16 0 15 1;
+#X connect 17 0 16 0;
+#X connect 18 0 23 0;
+#X connect 19 0 18 0;
+#X connect 19 0 20 0;
+#X connect 20 0 23 0;
+#X connect 21 0 23 0;
+#X restore 78 151 pd writesono;
+#X connect 0 0 7 1;
+#X connect 1 0 7 0;
+#X connect 3 0 0 0;
+#X connect 7 0 5 0;
diff --git a/Patches/fs.text.pd b/Patches/fs.text.pd
new file mode 100644
index 0000000..d666c99
--- /dev/null
+++ b/Patches/fs.text.pd
@@ -0,0 +1,29 @@
+#N canvas 90 92 825 352 12;
+#X obj 172 80 loadbang;
+#X obj 126 275 fs_sender;
+#X obj 51 27 inlet;
+#X msg 172 228 text \$1;
+#X obj 172 110 symbol \$0fs.text;
+#X obj 51 55 l2s;
+#X obj 51 102 pack s s;
+#X msg 51 137 fs_op \$2 \$1;
+#X obj 51 175 outlet;
+#X obj 172 203 symbol;
+#X obj 189 147 r fs_reset;
+#X msg 189 172 bang;
+#X text 100 28 text to write \, or one of these commands:;
+#X text 430 95 size <number>;
+#X text 430 117 font <font name> (look in your /winnt/fonts-dir);
+#X text 429 141 pos <x> <y>;
+#X text 430 73 color <r> <g> <b>;
+#X connect 0 0 4 0;
+#X connect 2 0 5 0;
+#X connect 3 0 1 0;
+#X connect 4 0 6 1;
+#X connect 4 0 9 0;
+#X connect 5 0 6 0;
+#X connect 6 0 7 0;
+#X connect 7 0 8 0;
+#X connect 9 0 3 0;
+#X connect 10 0 11 0;
+#X connect 11 0 9 0;
diff --git a/Patches/fs.waveform.pd b/Patches/fs.waveform.pd
new file mode 100644
index 0000000..1b6d39a
--- /dev/null
+++ b/Patches/fs.waveform.pd
@@ -0,0 +1,146 @@
+#N canvas 107 0 702 664 12;
+#X obj 75 360 fs.frame;
+#X obj 40 130 inlet;
+#X obj 27 588 outlet;
+#X obj 215 587 outlet;
+#X obj 126 129 inlet;
+#X obj 270 283 init;
+#X obj 408 586 outlet;
+#X obj 107 326 vdrawarray \$1;
+#X obj 107 295 vframe \$2 \$3;
+#X text 10 50 args: <array name> <width> <height>;
+#X obj 270 340 f \$2;
+#X obj 306 340 f \$3;
+#X obj 270 368 pack f f;
+#X obj 270 310 t b b b;
+#X obj 40 174 route bang;
+#X obj 110 395 fs.waveselection;
+#X obj 171 370 spigot;
+#X obj 330 161 loadbang;
+#X msg 330 186 1;
+#X obj 310 128 inlet;
+#X text 309 105 show selection (0 / 1);
+#X text 215 612 selection in samples;
+#X text 410 610 fs.frame position;
+#X msg 270 395 \$1 x \$2 \, mousetrack_1 \, mouserect_1 \, flip_manual
+;
+#X msg 33 360 flip;
+#X text 11 69 note that the fs.frame here is in flip_manual-mode;
+#X text 9 5 fs.waveform - wrapper to display array in fs.frame with
+selection features;
+#X text 39 104 bang;
+#N canvas 147 197 699 425 samples 0;
+#X obj 120 50 inlet;
+#X obj 172 50 inlet;
+#X obj 148 324 outlet;
+#X obj 202 324 outlet;
+#X obj 102 153 fs.info;
+#X obj 172 216 /;
+#X obj 172 123 unpack f f f f;
+#X obj 202 216 /;
+#X obj 202 244 *;
+#X obj 172 244 *;
+#X obj 256 194 arraysize \$1;
+#X obj 302 139 init;
+#X msg 302 164 bang;
+#X obj 270 52 inlet;
+#X text 120 24 fs.frame;
+#X text 268 24 reset to arraysize;
+#X text 447 24 offsets in samples;
+#X obj 452 50 inlet;
+#X obj 500 50 inlet;
+#X obj 481 124 -;
+#X obj 481 149 abs;
+#X obj 172 273 + 0;
+#X obj 202 273 + 0;
+#X obj 339 80 f;
+#X obj 500 85 t f f;
+#X obj 430 85 t b f f;
+#X obj 339 108 sel 0;
+#X msg 302 236 0;
+#X connect 0 0 4 0;
+#X connect 1 0 6 0;
+#X connect 4 0 5 1;
+#X connect 4 0 7 1;
+#X connect 5 0 9 0;
+#X connect 6 0 5 0;
+#X connect 6 2 7 0;
+#X connect 7 0 8 0;
+#X connect 8 0 22 0;
+#X connect 9 0 21 0;
+#X connect 10 0 8 1;
+#X connect 10 0 9 1;
+#X connect 10 0 27 0;
+#X connect 11 0 12 0;
+#X connect 12 0 10 0;
+#X connect 12 0 27 0;
+#X connect 13 0 12 0;
+#X connect 17 0 25 0;
+#X connect 18 0 24 0;
+#X connect 19 0 20 0;
+#X connect 20 0 8 1;
+#X connect 20 0 9 1;
+#X connect 21 0 2 0;
+#X connect 22 0 3 0;
+#X connect 23 0 26 0;
+#X connect 24 0 19 1;
+#X connect 24 1 23 1;
+#X connect 25 0 23 0;
+#X connect 25 1 22 1;
+#X connect 25 1 21 1;
+#X connect 25 2 19 0;
+#X connect 26 0 12 0;
+#X connect 27 0 22 1;
+#X connect 27 0 21 1;
+#X restore 143 520 pd samples;
+#X obj 123 267 vplugin;
+#X msg 123 244 black;
+#X obj 40 201 t b b b b b;
+#X obj 184 489 minmax;
+#X obj 184 463 pack f f;
+#X obj 173 129 inlet;
+#X text 123 104 offsets in samples;
+#X obj 273 587 outlet;
+#X obj 85 588 outlet;
+#X text 25 613 fs.frame outlets 1&2;
+#X connect 0 0 2 0;
+#X connect 0 0 15 0;
+#X connect 0 0 28 0;
+#X connect 0 1 16 0;
+#X connect 0 1 28 1;
+#X connect 0 1 37 0;
+#X connect 0 2 6 0;
+#X connect 1 0 14 0;
+#X connect 4 0 7 1;
+#X connect 4 0 33 0;
+#X connect 5 0 13 0;
+#X connect 7 0 0 0;
+#X connect 8 0 7 0;
+#X connect 10 0 12 0;
+#X connect 11 0 12 1;
+#X connect 12 0 23 0;
+#X connect 13 0 31 0;
+#X connect 13 1 10 0;
+#X connect 13 2 11 0;
+#X connect 14 0 31 0;
+#X connect 14 1 0 0;
+#X connect 15 0 0 0;
+#X connect 16 0 15 1;
+#X connect 17 0 18 0;
+#X connect 18 0 16 1;
+#X connect 19 0 16 1;
+#X connect 23 0 0 0;
+#X connect 24 0 0 0;
+#X connect 28 0 3 0;
+#X connect 28 1 36 0;
+#X connect 29 0 8 0;
+#X connect 30 0 29 0;
+#X connect 31 0 15 2;
+#X connect 31 1 0 0;
+#X connect 31 2 24 0;
+#X connect 31 3 30 0;
+#X connect 32 0 28 3;
+#X connect 32 1 28 4;
+#X connect 33 0 32 0;
+#X connect 34 0 7 2;
+#X connect 34 0 33 1;
diff --git a/Patches/fs.waveselection.pd b/Patches/fs.waveselection.pd
new file mode 100644
index 0000000..440e500
--- /dev/null
+++ b/Patches/fs.waveselection.pd
@@ -0,0 +1,47 @@
+#N canvas 0 0 626 444 12;
+#X obj 188 80 inlet;
+#X obj 223 279 fs.copy;
+#X msg 328 296 dstinvert;
+#X obj 363 324 init;
+#X obj 223 376 outlet;
+#X obj 21 80 inlet;
+#X obj 223 219 symbol;
+#X obj 188 112 t l b;
+#X obj 358 79 inlet;
+#X text 12 8 fs.waveselection - show fs.waveform selection by inverting
+the selected area;
+#X text 71 81 fs.frame 1st;
+#X text 241 80 fs.frame 2nd;
+#X text 410 78 reset;
+#X text 280 377 to fs.frame 1st inlet;
+#X obj 185 155 t b b l l;
+#X msg 185 312 flip;
+#X msg 289 247 source \$1 0 \$3 \$5;
+#X msg 432 247 dest \$1 0 \$3 \$5;
+#X obj 289 219 pack f f f f f;
+#X obj 442 150 fs.info;
+#X msg 358 106 0 0 0 0 0;
+#X obj 432 217 pack f f f f f;
+#X connect 0 0 7 0;
+#X connect 1 0 4 0;
+#X connect 2 0 1 1;
+#X connect 3 0 2 0;
+#X connect 5 0 6 1;
+#X connect 5 0 19 0;
+#X connect 6 0 1 0;
+#X connect 7 0 14 0;
+#X connect 7 1 6 0;
+#X connect 8 0 20 0;
+#X connect 14 0 15 0;
+#X connect 14 1 6 0;
+#X connect 14 2 21 0;
+#X connect 14 3 18 0;
+#X connect 15 0 4 0;
+#X connect 16 0 1 1;
+#X connect 17 0 1 1;
+#X connect 18 0 16 0;
+#X connect 19 1 18 4;
+#X connect 19 1 21 4;
+#X connect 20 0 18 0;
+#X connect 20 0 21 0;
+#X connect 21 0 17 0;
diff --git a/Patches/fs_sender.pd b/Patches/fs_sender.pd
new file mode 100644
index 0000000..e53a3b6
--- /dev/null
+++ b/Patches/fs_sender.pd
@@ -0,0 +1,7 @@
+#N canvas 595 435 271 174 12;
+#X obj 37 13 inlet;
+#X obj 37 77 s fs_main;
+#X obj 93 42 print sender;
+#X obj 37 43 l2s;
+#X connect 0 0 3 0;
+#X connect 3 0 1 0;
diff --git a/Patches/init.pd b/Patches/init.pd
new file mode 100644
index 0000000..7a1b9d8
--- /dev/null
+++ b/Patches/init.pd
@@ -0,0 +1,9 @@
+#N canvas 361 230 591 286 12;
+#X obj 44 177 outlet;
+#X obj 44 81 reset;
+#X text 14 10 use init to set parameters at load time;
+#X msg 44 152 bang;
+#X obj 44 126 pipe 1000;
+#X connect 1 0 4 0;
+#X connect 3 0 0 0;
+#X connect 4 0 3 0;
diff --git a/Patches/l2s.c b/Patches/l2s.c
new file mode 100644
index 0000000..b8a7701
--- /dev/null
+++ b/Patches/l2s.c
@@ -0,0 +1,89 @@
+/*
+ l2s is from ZEXY, the excellent pure data library by Johannes Zmoelnig.
+ Get it from ftp://iem.kug.ac.at/pd/Externals/ZEXY/
+*/
+
+/* not needed #include "zexy.h" */
+#include "m_pd.h"
+#include <stdlib.h>
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#define sqrtf sqrt
+#endif
+
+/* ------------------------- list2symbol ------------------------------- */
+
+/* compare 2 lists ( == for lists) */
+
+static t_class *list2symbol_class;
+
+typedef struct _list2symbol
+{
+ t_object x_obj;
+
+ t_binbuf *bbuf;
+} t_list2symbol;
+
+static void list2symbol_bang(t_list2symbol *x)
+{
+ char *str=0, *s2;
+ int n=0;
+
+ binbuf_gettext(x->bbuf, &str, &n);
+ /* memory bug ! detected and fixed by Jusu */
+ s2 = copybytes(str, n+1);
+ s2[n]=0;
+
+ outlet_symbol(x->x_obj.ob_outlet, gensym(s2));
+ freebytes(str, n);
+ freebytes(s2,n+1);
+}
+
+static void list2symbol_list(t_list2symbol *x, t_symbol *s, int argc, t_atom *argv)
+{
+ binbuf_clear(x->bbuf);
+ binbuf_add(x->bbuf, argc, argv);
+
+ list2symbol_bang(x);
+}
+static void list2symbol_anything(t_list2symbol *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_atom ap;
+ binbuf_clear(x->bbuf);
+ SETSYMBOL(&ap, s);
+ binbuf_add(x->bbuf, 1, &ap);
+ binbuf_add(x->bbuf, argc, argv);
+
+ list2symbol_bang(x);
+}
+
+static void *list2symbol_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_list2symbol *x = (t_list2symbol *)pd_new(list2symbol_class);
+
+ outlet_new(&x->x_obj, 0);
+ x->bbuf = binbuf_new();
+ binbuf_add(x->bbuf, argc, argv);
+
+ return (x);
+}
+
+static void list2symbol_free(t_list2symbol *x)
+{
+ binbuf_free(x->bbuf);
+}
+
+void l2s_setup(void)
+{
+ list2symbol_class = class_new(gensym("l2s"), (t_newmethod)list2symbol_new,
+ (t_method)list2symbol_free, sizeof(t_list2symbol), 0, A_GIMME, 0);
+
+ class_addcreator((t_newmethod)list2symbol_new, gensym("list2symbol"), A_GIMME, 0);
+ class_addbang (list2symbol_class, list2symbol_bang);
+ class_addlist (list2symbol_class, list2symbol_list);
+ class_addanything(list2symbol_class, list2symbol_anything);
+
+ class_sethelpsymbol(list2symbol_class, gensym("zexy/list2symbol"));
+}
diff --git a/Patches/l2s.dll b/Patches/l2s.dll
new file mode 100644
index 0000000..c46d150
--- /dev/null
+++ b/Patches/l2s.dll
Binary files differ
diff --git a/Patches/l2s.exp b/Patches/l2s.exp
new file mode 100644
index 0000000..18ec776
--- /dev/null
+++ b/Patches/l2s.exp
Binary files differ
diff --git a/Patches/l2s.lib b/Patches/l2s.lib
new file mode 100644
index 0000000..b875e0b
--- /dev/null
+++ b/Patches/l2s.lib
Binary files differ
diff --git a/Patches/l2s.obj b/Patches/l2s.obj
new file mode 100644
index 0000000..c4e67b2
--- /dev/null
+++ b/Patches/l2s.obj
Binary files differ
diff --git a/Patches/makefile b/Patches/makefile
new file mode 100644
index 0000000..55d610f
--- /dev/null
+++ b/Patches/makefile
@@ -0,0 +1,38 @@
+all: vframe vsig vsnapshot vrgb vcolor vframeread vdrawarray arraysize buildstr l2s
+
+# FLAGS:
+#
+# note: maximum optimization (/Ox) causes crashes with plugins..
+
+F = /DNT /DPD /LD /Gd /GD /Ogitb1 /Gs /I\system\pd\src /I..\Plugins
+L = \system\pdt17\bin\pd.lib
+
+vframe:
+ cl vframe.c $(F) /link /export:vframe_setup $(L) user32.lib
+
+vsig:
+ cl vsig~.c $(F) /link /export:vsig_tilde_setup $(L)
+
+vsnapshot:
+ cl vsnapshot~.c $(F) /link /export:vsnapshot_tilde_setup $(L)
+
+vrgb:
+ cl vrgb~.c $(F) /link /export:vrgb_tilde_setup $(L) user32.lib
+
+vcolor:
+ cl vcolor~.c $(F) /link /export:vcolor_tilde_setup $(L) user32.lib
+
+vframeread:
+ cl vframeread~.c $(F) /link /export:vframeread_tilde_setup $(L)
+
+vdrawarray:
+ cl vdrawarray.c $(F) /link /export:vdrawarray_setup $(L)
+
+arraysize:
+ cl arraysize.c $(F) /link /export:arraysize_setup $(L)
+
+buildstr:
+ cl buildstr.c $(F) /link /export:buildstr_setup $(L)
+
+l2s:
+ cl l2s.c $(F) /link /export:l2s_setup $(L)
diff --git a/Patches/noize.dll b/Patches/noize.dll
new file mode 100644
index 0000000..cdd4326
--- /dev/null
+++ b/Patches/noize.dll
Binary files differ
diff --git a/Patches/ooo.pd b/Patches/ooo.pd
new file mode 100644
index 0000000..a10612b
--- /dev/null
+++ b/Patches/ooo.pd
@@ -0,0 +1,19 @@
+#N canvas 483 310 458 308 12;
+#X obj 167 136 random 10;
+#X obj 199 66 inlet;
+#X obj 134 68 inlet;
+#X obj 167 176 sel 0;
+#X obj 167 216 outlet;
+#X text 14 8 ooo - one out of ...;
+#X obj 290 58 float \$1;
+#X obj 302 32 loadbang;
+#X obj 216 103 - 1;
+#X msg 148 103 bang;
+#X connect 0 0 3 0;
+#X connect 1 0 8 0;
+#X connect 2 0 9 0;
+#X connect 3 0 4 0;
+#X connect 6 0 8 0;
+#X connect 7 0 6 0;
+#X connect 8 0 0 1;
+#X connect 9 0 0 0;
diff --git a/Patches/play.pd b/Patches/play.pd
new file mode 100644
index 0000000..053c019
--- /dev/null
+++ b/Patches/play.pd
@@ -0,0 +1,8 @@
+#N canvas 290 207 206 201 12;
+#X obj 35 60 fps \$1;
+#X msg 35 90 next;
+#X obj 35 119 outlet;
+#X obj 35 30 inlet;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 3 0 0 0;
diff --git a/Patches/ramp.pd b/Patches/ramp.pd
new file mode 100644
index 0000000..5f84056
--- /dev/null
+++ b/Patches/ramp.pd
@@ -0,0 +1,35 @@
+#N canvas 60 34 505 412 10;
+#X obj 60 40 inlet;
+#X text 106 40 from \, to \, steps;
+#X obj 54 372 outlet;
+#X text 108 373 float;
+#X obj 68 77 unpack f f f;
+#X obj 277 177 f;
+#X obj 277 201 bangx;
+#X obj 144 131 f;
+#X obj 144 177 -;
+#X text 175 178 to - from;
+#X obj 144 204 /;
+#X text 174 205 div steps;
+#X obj 128 254 +;
+#X obj 68 124 t b b f f;
+#X obj 101 254 f;
+#X obj 101 277 t f f;
+#X connect 0 0 4 0;
+#X connect 4 0 13 0;
+#X connect 4 1 7 1;
+#X connect 4 2 5 1;
+#X connect 4 2 10 1;
+#X connect 5 0 6 0;
+#X connect 6 0 14 0;
+#X connect 7 0 8 0;
+#X connect 8 0 10 0;
+#X connect 10 0 12 1;
+#X connect 12 0 14 1;
+#X connect 13 0 5 0;
+#X connect 13 1 7 0;
+#X connect 13 2 8 1;
+#X connect 13 3 14 1;
+#X connect 14 0 15 0;
+#X connect 15 0 2 0;
+#X connect 15 1 12 0;
diff --git a/Patches/randombox.pd b/Patches/randombox.pd
new file mode 100644
index 0000000..b7de22b
--- /dev/null
+++ b/Patches/randombox.pd
@@ -0,0 +1,19 @@
+#N canvas 261 155 452 302 12;
+#X obj 128 198 pack f f f f;
+#X obj 128 102 random \$1;
+#X obj 158 125 random \$2;
+#X obj 188 148 random \$1;
+#X obj 219 171 random \$2;
+#X obj 128 31 inlet;
+#X obj 128 67 t b b b b;
+#X obj 128 235 outlet;
+#X connect 0 0 7 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 1;
+#X connect 3 0 0 2;
+#X connect 4 0 0 3;
+#X connect 5 0 6 0;
+#X connect 6 0 1 0;
+#X connect 6 1 2 0;
+#X connect 6 2 3 0;
+#X connect 6 3 4 0;
diff --git a/Patches/reset.pd b/Patches/reset.pd
new file mode 100644
index 0000000..0a33ffc
--- /dev/null
+++ b/Patches/reset.pd
@@ -0,0 +1,8 @@
+#N canvas 365 282 350 242 12;
+#X obj 44 34 loadbang;
+#X obj 130 34 r fs_reset;
+#X obj 60 100 outlet;
+#X msg 130 60 bang;
+#X connect 0 0 2 0;
+#X connect 1 0 3 0;
+#X connect 3 0 2 0;
diff --git a/Patches/sameonce.pd b/Patches/sameonce.pd
new file mode 100644
index 0000000..0d8d1f6
--- /dev/null
+++ b/Patches/sameonce.pd
@@ -0,0 +1,15 @@
+#N canvas 115 170 321 367 12;
+#X obj 71 73 inlet;
+#X obj 147 322 outlet;
+#X obj 147 142 float;
+#X msg 204 178 bang;
+#X obj 71 200 moses 1;
+#X obj 71 142 != -1;
+#X text 8 6 pass float if different from previous;
+#X connect 0 0 2 1;
+#X connect 0 0 5 0;
+#X connect 2 0 5 1;
+#X connect 2 0 1 0;
+#X connect 3 0 2 0;
+#X connect 4 1 3 0;
+#X connect 5 0 4 0;
diff --git a/Patches/snapOut~.pd b/Patches/snapOut~.pd
new file mode 100644
index 0000000..2712c45
--- /dev/null
+++ b/Patches/snapOut~.pd
@@ -0,0 +1,45 @@
+#N canvas 620 1 504 354 10;
+#X obj 39 16 inlet~;
+#X msg 128 134 1;
+#X msg 159 134 0;
+#X obj 128 162 metro 100;
+#X obj 119 16 inlet;
+#X text 160 15 snapout size in seconds;
+#X floatatom 260 48 4 0 0;
+#X obj 211 82 * 1000;
+#X floatatom 209 134 4 0 0;
+#X msg 54 134 bang;
+#X obj 39 188 tabwrite~ \$1;
+#X obj 303 132 symbol \$1;
+#X obj 303 109 loadbang;
+#X msg 260 186 \; \$2 resize \$1;
+#X obj 260 156 pack f s;
+#X obj 260 219 print;
+#X obj 367 15 loadbang;
+#X obj 367 37 samplerate~;
+#X obj 260 82 *;
+#X obj 341 69 / 100;
+#X obj 260 109 -;
+#X obj 119 55 switch~;
+#X connect 0 0 10 0;
+#X connect 1 0 3 0;
+#X connect 2 0 3 0;
+#X connect 3 0 10 0;
+#X connect 4 0 6 0;
+#X connect 4 0 21 0;
+#X connect 6 0 7 0;
+#X connect 6 0 18 0;
+#X connect 7 0 8 0;
+#X connect 8 0 3 1;
+#X connect 8 0 3 0;
+#X connect 9 0 10 0;
+#X connect 11 0 14 1;
+#X connect 12 0 11 0;
+#X connect 13 0 15 0;
+#X connect 14 0 13 0;
+#X connect 16 0 17 0;
+#X connect 17 0 18 1;
+#X connect 17 0 19 0;
+#X connect 18 0 20 0;
+#X connect 19 0 20 1;
+#X connect 20 0 14 0;
diff --git a/Patches/vcolor~.c b/Patches/vcolor~.c
new file mode 100644
index 0000000..0de7fe6
--- /dev/null
+++ b/Patches/vcolor~.c
@@ -0,0 +1,96 @@
+#include "m_pd.h"
+#include "math.h"
+#include "sharemem.h"
+#include "vframe.h"
+#include "plugin.h"
+#include "displaydepth.h"
+
+/* -------------------------- vcolor~ ------------------------------ */
+static t_class *vcolor_class;
+
+typedef struct _vcolor
+{
+ t_object x_obj;
+ float x_r;
+ float x_g;
+ float x_b;
+ int depth;
+} t_vcolor;
+
+static t_int *vcolor_perform(t_int *w)
+{
+ t_float *in_r = (t_float *)(w[1]);
+ t_float *in_g = (t_float *)(w[2]);
+ t_float *in_b = (t_float *)(w[3]);
+ t_float *out = (t_float *)(w[4]);
+ int n = (int)(w[5]);
+ t_vcolor *x = (t_vcolor *)(w[6]);
+
+ switch(x->depth)
+ {
+ case 16:
+ while (n--)
+ {
+ *out++ = colortosample16(rgbtocolor16(
+ (byte)(*in_r++*255.0),
+ (byte)(*in_g++*255.0),
+ (byte)(*in_b++*255.0)
+ ));
+ }
+ break;
+ case 32:
+ while (n--)
+ {
+ *out++ = colortosample32(rgbtocolor32(
+ (byte)(*in_r++*255.0),
+ (byte)(*in_g++*255.0),
+ (byte)(*in_b++*255.0)));
+ }
+ break;
+ }
+ return (w+7);
+}
+
+static void vcolor_dsp(t_vcolor *x, t_signal **sp)
+{
+ dsp_add(vcolor_perform, 6,
+ sp[0]->s_vec,
+ sp[1]->s_vec,
+ sp[2]->s_vec,
+ sp[3]->s_vec,
+ sp[0]->s_n,
+ x);
+}
+
+static void vcolor_float(t_vcolor *x, t_float f)
+{
+}
+
+static void *vcolor_new(t_floatarg f)
+{
+ t_vcolor *x = (t_vcolor *)pd_new(vcolor_class);
+ x->depth = getdisplaydepth();
+ if(!x->depth)
+ {
+ post("vcolor~: getdisplaydepth() failed, defaulting to 16.");
+ x->depth = 16;
+ }
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+ outlet_new(&x->x_obj, gensym("signal"));
+ return (x);
+}
+
+static void vcolor_destroy(t_vcolor *x)
+{
+}
+
+void vcolor_tilde_setup(void)
+{
+ vcolor_class = class_new(gensym("vcolor~"),
+ (t_newmethod)vcolor_new, (t_method)vcolor_destroy,
+ sizeof(t_vcolor), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(vcolor_class, t_vcolor, x_r);
+ class_addfloat(vcolor_class, (t_method)vcolor_float);
+ class_addmethod(vcolor_class, (t_method)vcolor_dsp, gensym("dsp"), 0);
+}
diff --git a/Patches/vcolor~.dll b/Patches/vcolor~.dll
new file mode 100644
index 0000000..ba9ff30
--- /dev/null
+++ b/Patches/vcolor~.dll
Binary files differ
diff --git a/Patches/vcolor~.exp b/Patches/vcolor~.exp
new file mode 100644
index 0000000..f07ba8c
--- /dev/null
+++ b/Patches/vcolor~.exp
Binary files differ
diff --git a/Patches/vcolor~.lib b/Patches/vcolor~.lib
new file mode 100644
index 0000000..6092fa3
--- /dev/null
+++ b/Patches/vcolor~.lib
Binary files differ
diff --git a/Patches/vcolor~.obj b/Patches/vcolor~.obj
new file mode 100644
index 0000000..80e68ad
--- /dev/null
+++ b/Patches/vcolor~.obj
Binary files differ
diff --git a/Patches/vcopy.pd b/Patches/vcopy.pd
new file mode 100644
index 0000000..00e109d
--- /dev/null
+++ b/Patches/vcopy.pd
@@ -0,0 +1,16 @@
+#N canvas 471 263 464 314 12;
+#X obj 46 27 inlet;
+#X obj 97 211 outlet;
+#X obj 235 27 inlet;
+#X obj 235 57 l2s;
+#X obj 196 91 vplugin;
+#X obj 97 125 pack f s;
+#X obj 324 32 reset;
+#X msg 324 58 black;
+#X connect 0 0 5 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 1;
+#X connect 5 0 1 0;
+#X connect 6 0 7 0;
+#X connect 7 0 4 0;
diff --git a/Patches/vdrawarray.c b/Patches/vdrawarray.c
new file mode 100644
index 0000000..fa8fab7
--- /dev/null
+++ b/Patches/vdrawarray.c
@@ -0,0 +1,131 @@
+#include "m_pd.h"
+#include "math.h"
+#include "sharemem.h"
+#include "vframe.h"
+
+/* -------------------------- vdrawarray ------------------------------ */
+static t_class *vdrawarray_class;
+
+typedef struct _vdrawarray
+{
+ t_object x_obj;
+ t_symbol *array_name;
+ t_float startpos, endpos;
+ int id;
+ HANDLE hvf, hbits;
+ LPVOID memvf, membits;
+ struct vframeimage *vfp;
+} t_vdrawarray;
+
+void vdrawarray_set(t_vdrawarray *x, t_symbol *s)
+{
+ x->array_name = s;
+}
+
+static void vdrawarray_bang(t_vdrawarray *x)
+{
+ int i, o, h, y, bytesize, gsize, pos, len;
+ t_float *gdata, tmpf;
+ byte *p;
+ t_garray *g;
+
+ if(!x->id)
+ {
+ post("vdrawarray: connect vframe first");
+ return;
+ }
+
+ if(!(g = (t_garray *)pd_findbyclass(x->array_name, garray_class)))
+ {
+ pd_error(x, "vdrawarray: %s: no such table", x->array_name->s_name);
+ return;
+ }
+
+ garray_getfloatarray(g, &gsize, &gdata);
+
+ h = x->vfp->f.height;
+ p = (byte*)x->membits;
+ bytesize = x->vfp->f.pixelformat/8;
+
+ if(x->startpos==0 && x->endpos==0)
+ x->endpos=gsize;
+
+ if(x->startpos<0) x->startpos=0;
+ if(x->startpos>gsize) x->startpos=gsize;
+ if(x->endpos<0) x->endpos=0;
+ if(x->endpos>gsize) x->endpos=gsize;
+
+ if(x->endpos<x->startpos)
+ {
+ tmpf = x->endpos;
+ x->endpos = x->startpos;
+ x->startpos = tmpf;
+ }
+
+ for(i=0; i<x->vfp->f.width; i++)
+ {
+ pos = (int)((i / (float)x->vfp->f.width) * (x->endpos-x->startpos) + x->startpos );
+ len = (int)((fabs(gdata[pos]) * (float)x->vfp->f.height));
+
+ o = (x->vfp->f.height - len) / 2;
+ for(y=o; y<o+len && y<x->vfp->f.height; y++)
+ memset(&p[y*x->vfp->f.lpitch+i*bytesize], 253, bytesize);
+ }
+}
+
+static void vdrawarray_float(t_vdrawarray *x, t_float f)
+{
+ if(x->id==f && x->membits!=NULL)
+ {
+ outlet_float(x->x_obj.ob_outlet, x->id);
+ vdrawarray_bang(x);
+ return;
+ }
+
+ x->id = f;
+
+ openframedatabyid(x->id,
+ &x->hvf, &x->hbits, &x->memvf, &x->membits, &x->vfp);
+ if(!x->membits)
+ {
+ post("vdrawarray: no memory at %d", x->id);
+ return;
+ } else
+ {
+ outlet_float(x->x_obj.ob_outlet, x->id);
+ vdrawarray_bang(x);
+ }
+}
+
+static void *vdrawarray_new(t_symbol *s)
+{
+ t_vdrawarray *x = (t_vdrawarray *)pd_new(vdrawarray_class);
+
+ x->array_name = s;
+ x->id=0;
+ x->hvf=NULL;
+ x->memvf=NULL;
+ x->hbits=NULL;
+ x->membits=NULL;
+ x->startpos=x->endpos=0;
+ outlet_new(&x->x_obj, gensym("float"));
+ floatinlet_new(&x->x_obj, &x->startpos);
+ floatinlet_new(&x->x_obj, &x->endpos);
+ return (x);
+}
+
+static void vdrawarray_destroy(t_vdrawarray *x)
+{
+ if(x->membits!=NULL) smfree(&x->hbits, x->membits);
+ if(x->memvf!=NULL) smfree(&x->hvf, x->memvf);
+}
+
+void vdrawarray_setup(void)
+{
+ vdrawarray_class = class_new(gensym("vdrawarray"),
+ (t_newmethod)vdrawarray_new, (t_method)vdrawarray_destroy,
+ sizeof(t_vdrawarray), 0, A_DEFSYM, 0);
+ class_addfloat(vdrawarray_class, (t_method)vdrawarray_float);
+ class_addbang(vdrawarray_class, (t_method)vdrawarray_bang);
+ class_addmethod(vdrawarray_class, (t_method)vdrawarray_set, gensym("set"), A_DEFSYM, 0);
+}
diff --git a/Patches/vdrawarray.dll b/Patches/vdrawarray.dll
new file mode 100644
index 0000000..f14883b
--- /dev/null
+++ b/Patches/vdrawarray.dll
Binary files differ
diff --git a/Patches/vdrawarray.exp b/Patches/vdrawarray.exp
new file mode 100644
index 0000000..00b8adf
--- /dev/null
+++ b/Patches/vdrawarray.exp
Binary files differ
diff --git a/Patches/vdrawarray.lib b/Patches/vdrawarray.lib
new file mode 100644
index 0000000..53139da
--- /dev/null
+++ b/Patches/vdrawarray.lib
Binary files differ
diff --git a/Patches/vdrawarray.obj b/Patches/vdrawarray.obj
new file mode 100644
index 0000000..bf12d3c
--- /dev/null
+++ b/Patches/vdrawarray.obj
Binary files differ
diff --git a/Patches/vframe.c b/Patches/vframe.c
new file mode 100644
index 0000000..ee1bf37
--- /dev/null
+++ b/Patches/vframe.c
@@ -0,0 +1,262 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "m_pd.h"
+#include "sharemem.h"
+#include "vframe.h"
+#include "dllcall.h"
+#include "displaydepth.h"
+
+/* vframe */
+
+static t_class *vframe_class;
+
+typedef struct _vframe
+{
+ t_object x_obj;
+
+ int id;
+ HANDLE hlvframe, hlbits;
+ LPVOID memvframe, membits;
+
+ HMODULE effectlib, copylib;
+ cdecl FARPROC effectproc, copyproc;
+ char effectplugin[80], effectloaded[80],
+ copyplugin[80], copyloaded[80];
+ char effectparams[256];
+} t_vframe;
+
+static void vframe_effect(t_vframe *x)
+{
+ struct vframeimage *vfp;
+ byte *bp;
+ int i1, i2, i3, i4;
+ char *s1=0, s2[256];
+
+ if(!x->membits)
+ {
+ post("vframe: init has failed.");
+ return;
+ }
+ if(!x->effectplugin) return;
+ if(strcmp(x->effectloaded, x->effectplugin))
+ {
+ loadeffect(&x->effectlib, &x->effectproc, x->effectplugin);
+ if(!x->effectlib || !x->effectproc)
+ {
+ post("vframe: failed to load effect from %s", x->effectplugin);
+ strcpy(x->effectloaded, "-");
+ return;
+ }
+ strcpy(x->effectloaded, x->effectplugin);
+ }
+ vfp = x->memvframe;
+ bp = x->membits;
+ i1 = vfp->f.lpitch;
+ i2 = vfp->f.width;
+ i3 = vfp->f.height;
+ i4 = vfp->f.pixelformat;
+
+ (*x->effectproc)(bp, i1, i2, i3, i4, &x->effectparams, &s2);
+ outlet_float(x->x_obj.ob_outlet, x->id);
+}
+
+static void vframe_copy(t_vframe *x, float source, char *cmd)
+{
+ char *t, *args=0;
+ HANDLE h1, h2;
+ LPVOID p1=NULL, p2=NULL;
+ struct vframeimage *vfp1=NULL, *vfp2=NULL;
+ byte *b1, *b2;
+ int i1, i2, i3, i4, i5, i6, i7, i8;
+ char returnbuf[256];
+
+ if(!x->membits)
+ {
+ post("vframe: init has failed.");
+ return;
+ }
+ strcpy(x->copyplugin, cmd);
+ t = strstr(x->copyplugin, " ");
+ if(t)
+ {
+ t[0]=0;
+ args=t+1;
+ }
+
+ if(!x->copyplugin) return;
+ if(strcmp(x->copyloaded, x->copyplugin))
+ {
+ loadcopy(&x->copylib, &x->copyproc, x->copyplugin);
+ if(!x->copylib || !x->copyproc)
+ {
+ post("vframe: failed to load copy from %s", x->copyplugin);
+ strcpy(x->copyloaded, "-");
+ return;
+ }
+ strcpy(x->copyloaded, x->copyplugin);
+ }
+
+ p2 = openframedatabyid((int)source, &h1, &h2, &p1, &p2, &vfp1);
+ if(!p2)
+ {
+ if(source) post("vframe: no memory at %f", source);
+ return;
+ }
+
+ vfp2 = (struct vframeimage *)x->memvframe;
+
+ b1 = p2;
+ i1 = vfp1->f.lpitch;
+ i2 = vfp1->f.width;
+ i3 = vfp1->f.height;
+ i4 = vfp1->f.pixelformat;
+
+ b2 = x->membits;
+ i5 = vfp2->f.lpitch;
+ i6 = vfp2->f.width;
+ i7 = vfp2->f.height;
+ i8 = vfp2->f.pixelformat;
+
+ (*x->copyproc)(
+ b1, i1, i2, i3, i4,
+ b2, i5, i6, i7, i8,
+ args, &returnbuf
+ );
+
+ outlet_float(x->x_obj.ob_outlet, x->id);
+}
+
+static void vframe_float(t_vframe *x, t_float f)
+{
+ post("float %f", f);
+}
+
+static void vframe_symbol(t_vframe *x, t_symbol *s)
+{
+ char *t;
+
+ strcpy(x->effectplugin, s->s_name);
+ x->effectparams[0]=0;
+
+ t = strstr(x->effectplugin, " ");
+ if(t)
+ {
+ strcpy(x->effectparams, t+1);
+ t[0]=0;
+ }
+ vframe_effect(x);
+}
+
+static void vframe_list(t_vframe *x, t_symbol *s, int ac, t_atom *av)
+{
+ float f;
+ char *s2;
+ if (!ac || ac!=2) return;
+
+ f = atom_getfloatarg(0, ac, av);
+ s2 = atom_getsymbolarg(1, ac, av)->s_name;
+ vframe_copy(x, f, s2);
+}
+
+static void vframe_anything(t_vframe *x, t_symbol *s, int argc, t_atom *argv)
+{
+ char *t;
+
+ strcpy(x->effectplugin, s->s_name);
+ x->effectparams[0]=0;
+
+ t = strstr(x->effectplugin, " ");
+ if(t)
+ {
+ strcpy(x->effectparams, t+1);
+ t[0]=0;
+ }
+ vframe_effect(x);
+}
+
+static void vframe_bang(t_vframe *x, t_floatarg fa)
+{
+ if(x->membits!=NULL)
+ outlet_float(x->x_obj.ob_outlet, x->id);
+}
+
+static void *vframe_new(t_symbol *sym, int argc, t_atom *argv)
+{
+ t_vframe *x = (t_vframe *)pd_new(vframe_class);
+
+ struct vframeimage vf;
+ int width=176, height=144, pixelformat=16;
+ char s[20];
+
+ if(argc>=2)
+ {
+ width = atom_getfloat(argv);
+ height = atom_getfloat(argv+1);
+ }
+ pixelformat = getdisplaydepth();
+ if(pixelformat!=16 && pixelformat!=24 && pixelformat!=32)
+ {
+ post("vframe: bad display depth, should be 16, 24 or 32. defaulting to 16.");
+ pixelformat = 16;
+ }
+
+ // allocate shared memory for bits and struct frameimage
+ x->id = rand();
+ itoa(x->id, s, 10);
+
+ x->membits = smalloc(&x->hlbits, s, width*height*(pixelformat/8));
+ if(x->membits==NULL)
+ {
+ post("vframe: membits smalloc() failed.");
+ } else
+ {
+ strcpy(vf.bitsname, s);
+ vf.f.width = width;
+ vf.f.height = height;
+ vf.f.pixelformat = pixelformat;
+ vf.f.lpitch = vf.f.width*(pixelformat/8); /* + some more for directx-crap??? */
+ vf.f.bits=NULL;
+
+ x->id = rand();
+ itoa(x->id, s, 10);
+
+ x->memvframe = smalloc(&x->hlvframe, s,
+ sizeof(struct vframeimage));
+
+ if(x->memvframe==NULL)
+ {
+ post("vframeimage smalloc() failed.");
+ } else
+ {
+ memcpy(x->memvframe, &vf, sizeof(struct vframeimage));
+ }
+ }
+
+ x->effectlib=NULL;
+ strcpy(x->effectloaded, "n o t h i n g");
+ x->copylib=NULL;
+ strcpy(x->copyloaded, "n o t h i n g");
+
+ outlet_new(&x->x_obj, gensym("float"));
+ return((void *)x);
+}
+
+static void vframe_destroy(t_vframe *x)
+{
+ if(x->membits!=NULL) smfree(&x->hlbits, x->membits);
+ if(x->memvframe!=NULL) smfree(&x->hlvframe, x->memvframe);
+ if(x->effectlib) FreeLibrary(x->effectlib);
+ if(x->copylib) FreeLibrary(x->copylib);
+}
+
+void vframe_setup(void)
+{
+ vframe_class = class_new(gensym("vframe"),
+ (t_newmethod)vframe_new, (t_method)vframe_destroy,
+ sizeof(t_vframe), CLASS_DEFAULT, A_GIMME, 0);
+ class_addfloat(vframe_class, vframe_float);
+ class_addbang(vframe_class, vframe_bang);
+ class_addsymbol(vframe_class, vframe_symbol);
+ class_addanything(vframe_class, vframe_anything);
+ class_addlist(vframe_class, vframe_list);
+}
diff --git a/Patches/vframe.dll b/Patches/vframe.dll
new file mode 100644
index 0000000..677c448
--- /dev/null
+++ b/Patches/vframe.dll
Binary files differ
diff --git a/Patches/vframe.exp b/Patches/vframe.exp
new file mode 100644
index 0000000..de5412f
--- /dev/null
+++ b/Patches/vframe.exp
Binary files differ
diff --git a/Patches/vframe.h b/Patches/vframe.h
new file mode 100644
index 0000000..232b166
--- /dev/null
+++ b/Patches/vframe.h
@@ -0,0 +1,66 @@
+#ifndef __VFRAME_H
+#define __VFRAME_H
+
+#include "plugin.h"
+
+struct vframeimage
+{
+ char bitsname[40]; // name of shared memory to image data
+ // use this, not f.bits!
+ _frame f; // image header, see Plugins\plugin.h
+};
+
+LPVOID openframedatabyid( int id,
+ HANDLE *hvf, HANDLE *hbits,
+ LPVOID *memvf, LPVOID *membits,
+ struct vframeimage **vfp )
+{
+ char s[80];
+
+ if(*membits!=NULL) smfree(hbits, *membits);
+ if(*memvf!=NULL) smfree(hvf, *memvf);
+
+ *membits=NULL;
+
+ itoa(id, s, 10);
+
+ *memvf = smopen(hvf, s);
+ if(*memvf!=NULL)
+ {
+ *vfp = *memvf;
+
+ *membits = smopen(hbits, ((struct vframeimage *)*vfp)->bitsname);
+ if(*membits==NULL)
+ {
+ printf("membits open error.\n");
+ smfree(hvf, *memvf);
+ } else {
+ }
+ }
+ return(*membits);
+}
+
+float max16 = 2<<14;
+float max32 = 2<<23;
+
+__inline float colortosample16(short c)
+{
+ return(c / max16);
+}
+
+__inline float colortosample32(long c)
+{
+ return(c / max32);
+}
+
+__inline short sampletocolor16(float s)
+{
+ return(s * max16);
+}
+
+__inline long sampletocolor32(float s)
+{
+ return(s * max32);
+}
+
+#endif
diff --git a/Patches/vframe.lib b/Patches/vframe.lib
new file mode 100644
index 0000000..f03cc5a
--- /dev/null
+++ b/Patches/vframe.lib
Binary files differ
diff --git a/Patches/vframe.obj b/Patches/vframe.obj
new file mode 100644
index 0000000..9f6f8cc
--- /dev/null
+++ b/Patches/vframe.obj
Binary files differ
diff --git a/Patches/vframeread~.c b/Patches/vframeread~.c
new file mode 100644
index 0000000..fe61836
--- /dev/null
+++ b/Patches/vframeread~.c
@@ -0,0 +1,123 @@
+#include "m_pd.h"
+#include "math.h"
+#include "sharemem.h"
+#include "vframe.h"
+
+/* -------------------------- vframeread~ ------------------------------ */
+static t_class *vframeread_class;
+
+typedef struct _vframeread
+{
+ t_object x_obj;
+ float x_f;
+ float x_sigf;
+ int id;
+ HANDLE hvf, hbits;
+ LPVOID memvf, membits;
+ unsigned long pos, size;
+} t_vframeread;
+
+static t_int *vframeread_perform(t_int *w)
+{
+ t_vframeread *x = (t_vframeread *)(w[1]);
+ t_float *in_sync = (t_float *)(w[2]);
+ t_float *out = (t_float *)(w[3]);
+ int n = (int)(w[4]);
+ short *p16;
+ long *p32;
+ struct vframeimage *vfp=x->memvf;
+ unsigned long bytespp;
+
+ if(!vfp || !x->membits) return(w+5);
+
+ bytespp = vfp->f.pixelformat / 8;
+
+ switch(vfp->f.pixelformat)
+ {
+ case 16:
+ p16 = (short *)x->membits;
+ while (n--)
+ {
+ if(*in_sync>=0 && *in_sync<=1)
+ x->pos = *in_sync * (float)(x->size / bytespp);
+ in_sync++;
+ *out++ = colortosample16(p16[x->pos++]);
+ if(x->pos*bytespp >= x->size)
+ x->pos=0;
+ }
+ break;
+ case 32:
+ p32 = (long *)x->membits;
+ while (n--)
+ {
+ if(*in_sync>=0 && *in_sync<1)
+ x->pos = *in_sync * (float)(x->size / bytespp);
+ in_sync++;
+ *out++ = colortosample32(p32[x->pos++]);
+ if(x->pos*bytespp >= x->size)
+ x->pos=0;
+ }
+ break;
+ }
+ return (w+5);
+}
+
+static void vframeread_dsp(t_vframeread *x, t_signal **sp)
+{
+ dsp_add(vframeread_perform, 4,
+ x,
+ sp[0]->s_vec,
+ sp[1]->s_vec,
+ sp[0]->s_n);
+}
+
+static void vframeread_float(t_vframeread *x, t_float f)
+{
+ struct vframeimage *vfp;
+
+ if(x->id==f && x->membits) return;
+
+ x->id = x->x_f = f;
+
+ openframedatabyid(x->id,
+ &x->hvf, &x->hbits, &x->memvf, &x->membits, &vfp);
+ if(!x->membits)
+ {
+ post("vframeread~: no memory at %d", x->id);
+ return;
+ } else
+ {
+ x->size = vfp->f.height*vfp->f.lpitch;
+ x->pos = 0;
+ }
+}
+
+static void *vframeread_new(t_floatarg f)
+{
+ t_vframeread *x = (t_vframeread *)pd_new(vframeread_class);
+ x->id = -1;
+ x->x_f = f;
+ x->x_sigf = 0;
+ x->hvf=NULL;
+ x->memvf=NULL;
+ x->hbits=NULL;
+ x->membits=NULL;
+ outlet_new(&x->x_obj, gensym("signal"));
+ return (x);
+}
+
+static void vframeread_destroy(t_vframeread *x)
+{
+ if(x->membits!=NULL) smfree(&x->hbits, x->membits);
+ if(x->memvf!=NULL) smfree(&x->hvf, x->memvf);
+}
+
+void vframeread_tilde_setup(void)
+{
+ vframeread_class = class_new(gensym("vframeread~"),
+ (t_newmethod)vframeread_new, (t_method)vframeread_destroy,
+ sizeof(t_vframeread), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(vframeread_class, t_vframeread, x_sigf);
+ class_addfloat(vframeread_class, (t_method)vframeread_float);
+ class_addmethod(vframeread_class, (t_method)vframeread_dsp, gensym("dsp"), 0);
+}
diff --git a/Patches/vframeread~.dll b/Patches/vframeread~.dll
new file mode 100644
index 0000000..c433e65
--- /dev/null
+++ b/Patches/vframeread~.dll
Binary files differ
diff --git a/Patches/vframeread~.exp b/Patches/vframeread~.exp
new file mode 100644
index 0000000..ca173e8
--- /dev/null
+++ b/Patches/vframeread~.exp
Binary files differ
diff --git a/Patches/vframeread~.lib b/Patches/vframeread~.lib
new file mode 100644
index 0000000..c5e2974
--- /dev/null
+++ b/Patches/vframeread~.lib
Binary files differ
diff --git a/Patches/vframeread~.obj b/Patches/vframeread~.obj
new file mode 100644
index 0000000..72813aa
--- /dev/null
+++ b/Patches/vframeread~.obj
Binary files differ
diff --git a/Patches/videoscrub.pd b/Patches/videoscrub.pd
new file mode 100644
index 0000000..00c304b
--- /dev/null
+++ b/Patches/videoscrub.pd
@@ -0,0 +1,29 @@
+#N canvas 306 359 496 310 12;
+#X obj 43 24 inlet;
+#X text 97 25 fs.frame;
+#X obj 55 67 fs.info;
+#X obj 36 231 outlet;
+#X text 100 231 fs.frame (same as inlet!);
+#X msg 204 193 mousetrack_1;
+#X obj 213 26 inlet;
+#X text 268 26 second outlet of fs.frame;
+#X obj 213 66 unpack f f;
+#X obj 36 118 /;
+#X obj 36 151 *;
+#X msg 36 181 seek \$1;
+#X obj 188 159 init;
+#X floatatom 102 121 5 0 0;
+#X floatatom 151 121 5 0 0;
+#X connect 0 0 2 0;
+#X connect 2 0 9 1;
+#X connect 2 0 13 0;
+#X connect 2 2 10 1;
+#X connect 2 2 14 0;
+#X connect 5 0 3 0;
+#X connect 6 0 8 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 11 0;
+#X connect 11 0 3 0;
+#X connect 12 0 3 0;
+#X connect 12 0 5 0;
diff --git a/Patches/vimport.pd b/Patches/vimport.pd
new file mode 100644
index 0000000..08433db
--- /dev/null
+++ b/Patches/vimport.pd
@@ -0,0 +1,11 @@
+#N canvas 257 346 509 298 12;
+#X obj 46 39 inlet;
+#X obj 313 41 inlet;
+#X text 21 12 fs.frame to import from;
+#X text 292 14 vframe to import to;
+#X obj 179 122 pack s f;
+#X text 329 192 import plugin;
+#X msg 179 182 \; \$1inlet fs2vf \$2;
+#X connect 0 0 4 0;
+#X connect 1 0 4 1;
+#X connect 4 0 6 0;
diff --git a/Patches/vplugin.pd b/Patches/vplugin.pd
new file mode 100644
index 0000000..1639dfa
--- /dev/null
+++ b/Patches/vplugin.pd
@@ -0,0 +1,9 @@
+#N canvas 0 0 464 314 12;
+#X obj 70 26 inlet;
+#X obj 70 172 makefilename c:/lab/framestein/plugins/%s;
+#X obj 70 272 outlet;
+#X text 125 200 correct this path to your installation;
+#X obj 70 142 l2s;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 4 0 1 0;
diff --git a/Patches/vref.pd b/Patches/vref.pd
new file mode 100644
index 0000000..452d36a
--- /dev/null
+++ b/Patches/vref.pd
@@ -0,0 +1,10 @@
+#N canvas 529 226 471 302 12;
+#X obj 61 95 inlet;
+#X obj 133 95 inlet;
+#X obj 101 151 f;
+#X obj 101 203 outlet;
+#X text 10 5 vref: reference to vframe. use this to make your patches
+more clear.;
+#X connect 0 0 2 0;
+#X connect 1 0 2 1;
+#X connect 2 0 3 0;
diff --git a/Patches/vrgb~.c b/Patches/vrgb~.c
new file mode 100644
index 0000000..d4e2cec
--- /dev/null
+++ b/Patches/vrgb~.c
@@ -0,0 +1,117 @@
+#include "m_pd.h"
+#include "math.h"
+#include "sharemem.h"
+#include "vframe.h"
+#include "plugin.h"
+#include "displaydepth.h"
+
+/* -------------------------- vrgb~ ------------------------------ */
+static t_class *vrgb_class;
+
+typedef struct _vrgb
+{
+ t_object x_obj;
+ float x_f;
+ float mode; /* 0=rgb 1=r ... */
+ int depth;
+} t_vrgb;
+
+static t_int *vrgb_perform(t_int *w)
+{
+ t_float *in = (t_float *)(w[1]);
+ t_float *r = (t_float *)(w[2]);
+ t_float *g = (t_float *)(w[3]);
+ t_float *b = (t_float *)(w[4]);
+ int n = (int)(w[5]);
+ t_vrgb *x = (t_vrgb *)(w[6]);
+ byte cr, cg, cb;
+ short c16;
+ long c32;
+
+ // support "x->mode" later....
+
+ switch(x->depth)
+ {
+ case 16:
+ while (n--)
+ {
+ c16 = sampletocolor16(*in++);
+ cr = r16(c16);
+ cg = g16(c16);
+ cb = b16(c16);
+ *r++ = cr / 255.0;
+ *g++ = cg / 255.0;
+ *b++ = cb / 255.0;
+
+/* *r++ = colortosample16(rgbtocolor16(cr, 0, 0));
+ *g++ = colortosample16(rgbtocolor16(0, cg, 0));
+ *b++ = colortosample16(rgbtocolor16(0, 0, cb));
+*/ }
+ break;
+ case 32:
+ while (n--)
+ {
+ c32 = sampletocolor32(*in++);
+ cr = r32(c32);
+ cg = g32(c32);
+ cb = b32(c32);
+ *r++ = cr / 255.0;
+ *g++ = cg / 255.0;
+ *b++ = cb / 255.0;
+
+/* *b++ = colortosample32(rgbtocolor32(cr, 0, 0));
+ *g++ = colortosample32(rgbtocolor32(0, cg, 0));
+ *r++ = colortosample32(rgbtocolor32(0, 0, cb));
+*/ }
+ break;
+ }
+ return (w+7);
+}
+
+static void vrgb_dsp(t_vrgb *x, t_signal **sp)
+{
+ dsp_add(vrgb_perform, 6,
+ sp[0]->s_vec,
+ sp[1]->s_vec,
+ sp[2]->s_vec,
+ sp[3]->s_vec,
+ sp[0]->s_n,
+ x);
+}
+
+static void vrgb_float(t_vrgb *x, t_float f)
+{
+ x->mode = f;
+post("mode %f", f);
+}
+
+static void *vrgb_new(t_floatarg f)
+{
+ t_vrgb *x = (t_vrgb *)pd_new(vrgb_class);
+ x->x_f = f;
+ x->mode=0;
+ x->depth = getdisplaydepth();
+ if(!x->depth)
+ {
+ post("vrgb~: getdisplaydepth() failed, defaulting to 16.");
+ x->depth = 16;
+ }
+ outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, gensym("signal"));
+ return (x);
+}
+
+static void vrgb_destroy(t_vrgb *x)
+{
+}
+
+void vrgb_tilde_setup(void)
+{
+ vrgb_class = class_new(gensym("vrgb~"),
+ (t_newmethod)vrgb_new, (t_method)vrgb_destroy,
+ sizeof(t_vrgb), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(vrgb_class, t_vrgb, x_f);
+ class_addfloat(vrgb_class, (t_method)vrgb_float);
+ class_addmethod(vrgb_class, (t_method)vrgb_dsp, gensym("dsp"), 0);
+}
diff --git a/Patches/vrgb~.dll b/Patches/vrgb~.dll
new file mode 100644
index 0000000..dba660b
--- /dev/null
+++ b/Patches/vrgb~.dll
Binary files differ
diff --git a/Patches/vrgb~.exp b/Patches/vrgb~.exp
new file mode 100644
index 0000000..431dc6d
--- /dev/null
+++ b/Patches/vrgb~.exp
Binary files differ
diff --git a/Patches/vrgb~.lib b/Patches/vrgb~.lib
new file mode 100644
index 0000000..49d8fdb
--- /dev/null
+++ b/Patches/vrgb~.lib
Binary files differ
diff --git a/Patches/vrgb~.obj b/Patches/vrgb~.obj
new file mode 100644
index 0000000..a49f96d
--- /dev/null
+++ b/Patches/vrgb~.obj
Binary files differ
diff --git a/Patches/vsig~.c b/Patches/vsig~.c
new file mode 100644
index 0000000..f177723
--- /dev/null
+++ b/Patches/vsig~.c
@@ -0,0 +1,123 @@
+#include "m_pd.h"
+#include "math.h"
+#include "sharemem.h"
+#include "vframe.h"
+
+/* -------------------------- vsig~ ------------------------------ */
+static t_class *vsig_class;
+
+typedef struct _vsig
+{
+ t_object x_obj;
+ float x_f;
+ t_outlet *x_bang;
+ int id;
+ HANDLE hvf, hbits;
+ LPVOID memvf, membits;
+ unsigned long pos, size;
+} t_vsig;
+
+static t_int *vsig_perform(t_int *w)
+{
+ t_vsig *x = (t_vsig *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_float *sync = (t_float *)(w[3]);
+ int n = (int)(w[4]);
+ short *p16;
+ long *p32;
+ struct vframeimage *vfp=x->memvf;
+ int bitspp;
+
+ if(!vfp || !x->membits) return(w+5);
+
+ bitspp = vfp->f.pixelformat / 8;
+
+ switch(vfp->f.pixelformat)
+ {
+ case 16:
+ p16 = (short *)x->membits;
+ while (n--)
+ {
+ *out++ = colortosample16(p16[x->pos++]);
+ if(x->pos*bitspp >= x->size)
+ {
+ x->pos=0;
+ *sync = 1; // moveto topleft
+ outlet_bang(x->x_bang);
+ } else *sync = -1; // continue from whereever you are
+ sync++;
+ }
+ break;
+ case 32:
+ p32 = (long *)x->membits;
+ while (n--)
+ {
+ *out++ = colortosample32(p32[x->pos++]);
+ if(x->pos*bitspp >= x->size)
+ {
+ x->pos=0;
+ *sync = 1;
+ outlet_bang(x->x_bang);
+ } else *sync = -1;
+ sync++;
+ }
+ break;
+ }
+ return (w+5);
+}
+
+static void vsig_dsp(t_vsig *x, t_signal **sp)
+{
+ dsp_add(vsig_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+static void vsig_float(t_vsig *x, t_float f)
+{
+ struct vframeimage *vfp;
+
+ if(x->id==f && x->membits!=NULL) return;
+
+ x->id = x->x_f = f;
+
+ openframedatabyid(x->id,
+ &x->hvf, &x->hbits, &x->memvf, &x->membits, &vfp);
+ if(!x->membits)
+ {
+ post("vsig~: no memory at %d", x->id);
+ return;
+ } else
+ {
+ x->size = vfp->f.height*vfp->f.lpitch;
+ x->pos = 0;
+ }
+}
+
+static void *vsig_new(t_floatarg f)
+{
+ t_vsig *x = (t_vsig *)pd_new(vsig_class);
+ x->id = -1;
+ x->x_f = f;
+ x->hvf=NULL;
+ x->memvf=NULL;
+ x->hbits=NULL;
+ x->membits=NULL;
+ outlet_new(&x->x_obj, gensym("signal"));
+ outlet_new(&x->x_obj, gensym("signal"));
+ x->x_bang = outlet_new(&x->x_obj, gensym("bang"));
+ return (x);
+}
+
+static void vsig_destroy(t_vsig *x)
+{
+ if(x->membits!=NULL) smfree(&x->hbits, x->membits);
+ if(x->memvf!=NULL) smfree(&x->hvf, x->memvf);
+}
+
+void vsig_tilde_setup(void)
+{
+ vsig_class = class_new(gensym("vsig~"),
+ (t_newmethod)vsig_new, (t_method)vsig_destroy,
+ sizeof(t_vsig), 0, A_DEFFLOAT, 0);
+ class_addfloat(vsig_class, (t_method)vsig_float);
+ class_addmethod(vsig_class, (t_method)vsig_dsp, gensym("dsp"), 0);
+}
diff --git a/Patches/vsig~.dll b/Patches/vsig~.dll
new file mode 100644
index 0000000..554cdfe
--- /dev/null
+++ b/Patches/vsig~.dll
Binary files differ
diff --git a/Patches/vsig~.exp b/Patches/vsig~.exp
new file mode 100644
index 0000000..26db989
--- /dev/null
+++ b/Patches/vsig~.exp
Binary files differ
diff --git a/Patches/vsig~.lib b/Patches/vsig~.lib
new file mode 100644
index 0000000..fa4c919
--- /dev/null
+++ b/Patches/vsig~.lib
Binary files differ
diff --git a/Patches/vsig~.obj b/Patches/vsig~.obj
new file mode 100644
index 0000000..ba38233
--- /dev/null
+++ b/Patches/vsig~.obj
Binary files differ
diff --git a/Patches/vsnapshot~.c b/Patches/vsnapshot~.c
new file mode 100644
index 0000000..ba5e980
--- /dev/null
+++ b/Patches/vsnapshot~.c
@@ -0,0 +1,139 @@
+#include "m_pd.h"
+#include "math.h"
+#include "sharemem.h"
+#include "vframe.h"
+
+/* -------------------------- vsnapshot~ ------------------------------ */
+static t_class *vsnapshot_class;
+
+typedef struct _vsnapshot
+{
+ t_object x_obj;
+ float x_f;
+ int id;
+ HANDLE hvf, hbits;
+ LPVOID memvf, membits;
+ unsigned long pos, size;
+} t_vsnapshot;
+
+static t_int *vsnapshot_perform(t_int *w)
+{
+ t_vsnapshot *x = (t_vsnapshot *)(w[1]);
+ t_float *in = (t_sample *)(w[2]);
+ t_float *sync = (t_sample *)(w[3]);
+ int n = (int)(w[4]);
+ short *p16;
+ long *p32;
+ struct vframeimage *vfp=x->memvf;
+ unsigned long bytespp;
+
+ if(!vfp || !x->membits) return(w+5);
+
+ bytespp = vfp->f.pixelformat / 8;
+
+ switch(vfp->f.pixelformat)
+ {
+ case 16:
+ p16 = x->membits;
+ while (n--)
+ {
+ if(*sync>0 && *sync<1)
+ x->pos=*sync * (float)(x->size / bytespp);
+ else
+ if(*sync==1) x->pos=(x->size / bytespp)-1;
+
+ p16[x->pos++] = sampletocolor16(*in);
+ in++;
+ sync++;
+ if(x->pos*bytespp >= x->size)
+ {
+ x->pos=0;
+ outlet_float(x->x_obj.ob_outlet, x->id);
+ }
+ }
+ break;
+ case 32:
+ p32 = x->membits;
+ while (n--)
+ {
+ if(*sync>0 && *sync<1)
+ x->pos=*sync * (float)(x->size / bytespp);
+ else
+ if(*sync==1) x->pos=(x->size / bytespp)-1;
+
+ p32[x->pos++] = sampletocolor32(*in);
+ in++;
+ sync++;
+ if(x->pos*bytespp >= x->size)
+ {
+ x->pos=0;
+ outlet_float(x->x_obj.ob_outlet, x->id);
+ }
+ }
+ break;
+ }
+ return(w+5);
+}
+
+static void vsnapshot_dsp(t_vsnapshot *x, t_signal **sp)
+{
+ dsp_add(vsnapshot_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+static void vsnapshot_float(t_vsnapshot *x, t_float f)
+{
+ struct vframeimage *vfp;
+
+ if(x->id==f && x->membits!=NULL)
+ {
+ outlet_float(x->x_obj.ob_outlet, x->id);
+ return;
+ }
+
+ x->id = x->x_f = f;
+
+ openframedatabyid(x->id,
+ &x->hvf, &x->hbits, &x->memvf, &x->membits, &vfp);
+ if(!x->membits)
+ {
+ post("vsnapshot~: no memory at %d", x->id);
+ return;
+ } else
+ {
+ x->size = vfp->f.height*vfp->f.lpitch;
+ x->pos = 0;
+ outlet_float(x->x_obj.ob_outlet, x->id);
+ }
+}
+
+static void *vsnapshot_new(t_floatarg f)
+{
+ t_vsnapshot *x = (t_vsnapshot *)pd_new(vsnapshot_class);
+ x->x_f = f;
+ x->pos=0;
+ x->hvf=NULL;
+ x->memvf=NULL;
+ x->hbits=NULL;
+ x->membits=NULL;
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
+ outlet_new(&x->x_obj, gensym("float"));
+ return (x);
+}
+
+static void vsnapshot_destroy(t_vsnapshot *x)
+{
+ if(x->membits!=NULL) smfree(&x->hbits, x->membits);
+ if(x->memvf!=NULL) smfree(&x->hvf, x->memvf);
+}
+
+void vsnapshot_tilde_setup(void)
+{
+ vsnapshot_class = class_new(gensym("vsnapshot~"),
+ (t_newmethod)vsnapshot_new, (t_method)vsnapshot_destroy,
+ sizeof(t_vsnapshot), 0, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(vsnapshot_class, t_vsnapshot, x_f);
+ class_addmethod(vsnapshot_class, (t_method)vsnapshot_float,
+ gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(vsnapshot_class, (t_method)vsnapshot_dsp, gensym("dsp"), 0);
+}
diff --git a/Patches/vsnapshot~.dll b/Patches/vsnapshot~.dll
new file mode 100644
index 0000000..bc3187a
--- /dev/null
+++ b/Patches/vsnapshot~.dll
Binary files differ
diff --git a/Patches/vsnapshot~.exp b/Patches/vsnapshot~.exp
new file mode 100644
index 0000000..2d397e5
--- /dev/null
+++ b/Patches/vsnapshot~.exp
Binary files differ
diff --git a/Patches/vsnapshot~.lib b/Patches/vsnapshot~.lib
new file mode 100644
index 0000000..b6ac3d4
--- /dev/null
+++ b/Patches/vsnapshot~.lib
Binary files differ
diff --git a/Patches/vsnapshot~.obj b/Patches/vsnapshot~.obj
new file mode 100644
index 0000000..a199364
--- /dev/null
+++ b/Patches/vsnapshot~.obj
Binary files differ
diff --git a/Patches/vsnap~.pd b/Patches/vsnap~.pd
new file mode 100644
index 0000000..241e8ba
--- /dev/null
+++ b/Patches/vsnap~.pd
@@ -0,0 +1,18 @@
+#N canvas 86 302 458 308 12;
+#X obj 164 170 vsnapshot~;
+#X obj 239 80 reset;
+#X obj 239 131 vframe \$1 \$2;
+#X obj 164 211 outlet;
+#X obj 120 80 inlet~;
+#X obj 179 80 inlet~;
+#X text 13 6 wrapper for vsnapshot~;
+#X text 67 45 video signal | sync signal;
+#X text 170 242 outlet to fs.frame;
+#X obj 253 108 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1
+-1;
+#X connect 0 0 3 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 2;
+#X connect 4 0 0 0;
+#X connect 5 0 0 1;
+#X connect 9 0 2 0;
diff --git a/PeRColate Framestein.pdf b/PeRColate Framestein.pdf
new file mode 100644
index 0000000..e8d027e
--- /dev/null
+++ b/PeRColate Framestein.pdf
Binary files differ
diff --git a/Plugins/2colors.cpp b/Plugins/2colors.cpp
new file mode 100644
index 0000000..b76be62
--- /dev/null
+++ b/Plugins/2colors.cpp
@@ -0,0 +1,21 @@
+#include <stdlib.h>
+#include "plugin.h"
+#include "pixels.h"
+
+// 2colors: make the image consist of black and white pixels only.
+// I haven't tested this yet and it most likely WILL NOT WORK!!!
+
+void perform_effect(_frame f, _args a)
+{
+ pixels p(f);
+ int i=127, o; // intensity
+
+ if(a.s) i=atoi(a.s);
+
+ while(!p.eof())
+ {
+ o = (p.red() + p.green() + p.blue()) / 3;
+ if(i<o) p.putrgb(0, 0, 0); else p.putrgb(255, 255, 255);
+ p.next();
+ }
+}
diff --git a/Plugins/2colors.dll b/Plugins/2colors.dll
new file mode 100644
index 0000000..ba62b0f
--- /dev/null
+++ b/Plugins/2colors.dll
Binary files differ
diff --git a/Plugins/2colors.exp b/Plugins/2colors.exp
new file mode 100644
index 0000000..a0e870b
--- /dev/null
+++ b/Plugins/2colors.exp
Binary files differ
diff --git a/Plugins/2colors.lib b/Plugins/2colors.lib
new file mode 100644
index 0000000..38cf84a
--- /dev/null
+++ b/Plugins/2colors.lib
Binary files differ
diff --git a/Plugins/2colors.obj b/Plugins/2colors.obj
new file mode 100644
index 0000000..2013b69
--- /dev/null
+++ b/Plugins/2colors.obj
Binary files differ
diff --git a/Plugins/README.txt b/Plugins/README.txt
new file mode 100644
index 0000000..893a4ad
--- /dev/null
+++ b/Plugins/README.txt
@@ -0,0 +1,12 @@
+Put your dlls with proper exported perform-functions here, and Framestein
+will load them on startup.
+
+Read plugin.h and noize.c and try example-plugins.pd for the whole story.
+Pixels.h and green.cpp or tile.cpp demonstrate the easy-to-use pixels-class.
+
+If you write plugins please contribute them to the Framestein distribution.
+
+(type "make" to build plugins in this directory with MS Visual C++.)
+
+NOTE: I'm distributing my Plugins-directory as-is, some of them are
+feature-incomplete.
diff --git a/Plugins/bend.c b/Plugins/bend.c
new file mode 100644
index 0000000..753159d
--- /dev/null
+++ b/Plugins/bend.c
@@ -0,0 +1,86 @@
+#include <stdlib.h>
+#include <string.h>
+#include "plugin.h"
+
+void perform_effect(_frame f, _args a)
+{
+ printf("NOTE: bend as effect does nothing. Use bend as copy operation.\n");
+}
+
+void perform_copy(_frame f1, _frame f2, _args a)
+{
+ int x, y, w, h, pos, pos2, src, ysrc, ypos1, ypos2,
+ widthminuspos, widthminuspos2, widthminusone,
+ heightminusypos1, heightminusypos2;
+ pixel8 *p1, *p2, tp=0, tpy=0;
+ char *t;
+ byte pixelsize = f1.pixelformat/8;
+
+ if(!a.s) return;
+ pos = atoi(a.s);
+ if(t = strstr(a.s, " "))
+ {
+ pos2 = atoi(t+1);
+ tp = 1;
+ if(t = strstr(t+1, " "))
+ {
+ ypos1 = atoi(t+1);
+ if(t = strstr(t+1, " "))
+ {
+ ypos2 = atoi(t+1);
+ if(ypos1>0||ypos2>0) tpy = 1;
+ }
+ }
+ }
+
+ w = f1.width<f2.width ? f1.width : f2.width;
+ h = f1.height<f2.height ? f1.height : f2.height;
+
+ if(pos<0) pos=0;
+ if(pos>=w) pos=w-1;
+ if(pos2<0) pos2=0;
+ if(pos2>=w) pos2=w-1;
+
+ if(ypos1<0) ypos1=0;
+ if(ypos1>=w) ypos1=w-1;
+ if(ypos2<0) ypos2=0;
+ if(ypos2>=w) ypos2=w-1;
+
+ widthminuspos = f1.width-pos;
+ widthminuspos2 = f1.width-pos2;
+ widthminusone = w-1;
+
+ heightminusypos1 = f1.height-ypos1;
+ heightminusypos2 = f1.height-ypos2;
+
+ // here we'll avoid checking for pixelformat by taking the source and destination
+ // offsets as 8-bit, and multiplying that by pixelsize
+
+ for(y=0; y<h; y++)
+ {
+ p1 = scanline(f1, y);
+ p2 = scanline(f2, y);
+ for(x=0; x<w; x++)
+ {
+ if(!tp)
+ {
+ memcpy(&p2[x*pixelsize], x<pos||pos-(x-pos)<0 ? &p1[x*pixelsize]
+ : &p1[(pos-(x-pos))*pixelsize], pixelsize);
+ } else
+ {
+ src = x<pos ? x/(float)pos*pos2
+ : pos2+((x-pos)/(float)widthminuspos*widthminuspos2);
+
+ if(!tpy) {
+ memcpy(&p2[x*pixelsize], &p1[src*pixelsize], pixelsize);
+ } else {
+ ysrc = y<ypos1 ? y/(float)ypos1*ypos2
+ : ypos2+((y-ypos1)/(float)heightminusypos1*heightminusypos2);
+
+ memcpy(&p2[x*pixelsize], &scanline(f1, ysrc)[src*pixelsize],
+ pixelsize);
+ }
+ }
+ }
+ }
+}
diff --git a/Plugins/bend.dll b/Plugins/bend.dll
new file mode 100644
index 0000000..220d616
--- /dev/null
+++ b/Plugins/bend.dll
Binary files differ
diff --git a/Plugins/bend.exp b/Plugins/bend.exp
new file mode 100644
index 0000000..6f7f43a
--- /dev/null
+++ b/Plugins/bend.exp
Binary files differ
diff --git a/Plugins/bend.lib b/Plugins/bend.lib
new file mode 100644
index 0000000..ebb3f95
--- /dev/null
+++ b/Plugins/bend.lib
Binary files differ
diff --git a/Plugins/bend.obj b/Plugins/bend.obj
new file mode 100644
index 0000000..3ac109f
--- /dev/null
+++ b/Plugins/bend.obj
Binary files differ
diff --git a/Plugins/black.c b/Plugins/black.c
new file mode 100644
index 0000000..3716767
--- /dev/null
+++ b/Plugins/black.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include "plugin.h"
+
+void perform_effect(_frame f, _args a)
+{
+ memset(f.bits, 0, f.height*f.lpitch);
+}
+
+void perform_copy(_frame f1, _frame f2, _args a)
+{
+ memset(f1.bits, 0, f1.height*f1.lpitch);
+ memset(f2.bits, 0, f2.height*f2.lpitch);
+}
diff --git a/Plugins/black.dll b/Plugins/black.dll
new file mode 100644
index 0000000..cb8b57a
--- /dev/null
+++ b/Plugins/black.dll
Binary files differ
diff --git a/Plugins/black.exp b/Plugins/black.exp
new file mode 100644
index 0000000..4399f54
--- /dev/null
+++ b/Plugins/black.exp
Binary files differ
diff --git a/Plugins/black.lib b/Plugins/black.lib
new file mode 100644
index 0000000..a21da90
--- /dev/null
+++ b/Plugins/black.lib
Binary files differ
diff --git a/Plugins/black.obj b/Plugins/black.obj
new file mode 100644
index 0000000..45e140d
--- /dev/null
+++ b/Plugins/black.obj
Binary files differ
diff --git a/Plugins/colortv.c b/Plugins/colortv.c
new file mode 100644
index 0000000..1885d1f
--- /dev/null
+++ b/Plugins/colortv.c
@@ -0,0 +1,69 @@
+#include "plugin.h"
+
+void perform_effect(struct frame f, struct args a)
+{
+ int x, y;
+ pixel16 *p16;
+ pixel32 *p32;
+ pixel16 c1, c2, c3;
+
+ switch(f.pixelformat)
+ {
+ case 16:
+ for(y=0; y<f.height; y++)
+ {
+ p16=scanline16(f, y);
+ for(x=1; x<f.width; x++)
+ {
+ p16[x]=(p16[x]+p16[x-1])/2;
+ }
+ }
+ break;
+ case 32:
+ for(y=0; y<f.height; y++)
+ {
+ p32=scanline32(f, y);
+ for(x=1; x<f.width; x++)
+ {
+ p32[x]=(p32[x]+p32[x-1])/2;
+ }
+ }
+ break;
+ }
+}
+
+void perform_copy(struct frame f1, struct frame f2, struct args a)
+{
+ int x, y, w, h;
+ pixel16 *p1_16, *p2_16, c1, c2, c3;
+ pixel32 *p1_32, *p2_32;
+
+ w = f1.width<f2.width ? f1.width : f2.width;
+ h = f1.height<f2.height ? f1.height : f2.height;
+
+ switch(f1.pixelformat)
+ {
+ case 16:
+ for(y=0; y<h; y++)
+ {
+ p1_16 = scanline16(f1, y);
+ p2_16 = scanline16(f2, y);
+ for(x=1; x<w; x++)
+ {
+ p2_16[x]=(p1_16[x]+p2_16[x])/2;
+ }
+ }
+ break;
+ case 32:
+ for(y=0; y<h; y++)
+ {
+ p1_32 = scanline32(f1, y);
+ p2_32 = scanline32(f2, y);
+ for(x=1; x<w; x++)
+ {
+ p2_32[x]=(p1_32[x]+p2_32[x])/2;
+ }
+ }
+ break;
+ }
+}
diff --git a/Plugins/colortv.dll b/Plugins/colortv.dll
new file mode 100644
index 0000000..cf5dacf
--- /dev/null
+++ b/Plugins/colortv.dll
Binary files differ
diff --git a/Plugins/colortv.exp b/Plugins/colortv.exp
new file mode 100644
index 0000000..53c82e7
--- /dev/null
+++ b/Plugins/colortv.exp
Binary files differ
diff --git a/Plugins/colortv.lib b/Plugins/colortv.lib
new file mode 100644
index 0000000..f08d5a3
--- /dev/null
+++ b/Plugins/colortv.lib
Binary files differ
diff --git a/Plugins/colortv.obj b/Plugins/colortv.obj
new file mode 100644
index 0000000..dcb2aa3
--- /dev/null
+++ b/Plugins/colortv.obj
Binary files differ
diff --git a/Plugins/copy_vert.c b/Plugins/copy_vert.c
new file mode 100644
index 0000000..cb7b093
--- /dev/null
+++ b/Plugins/copy_vert.c
@@ -0,0 +1,30 @@
+#include <stdlib.h>
+#include <string.h>
+#include "plugin.h"
+
+void perform_copy(_frame f1, _frame f2, _args a)
+{
+ byte pixelsize = f1.pixelformat/8;
+ short x, y, xoff, w, h, size=1;
+ char *t;
+
+ if(!a.s) return;
+ xoff = atoi(a.s);
+
+ if(t = strstr(a.s, " ")) size=atoi(t+1);
+
+ w = f1.width<f2.width ? f1.width : f2.width;
+ h = f1.height<f2.height ? f1.height : f2.height;
+
+ if(xoff+size>=w)
+ {
+ size = w - xoff;
+ if(!size) return;
+ }
+
+ if(xoff<0 || xoff>=w) return;
+
+ for(y=0; y<h; y++)
+ memcpy(&f2.bits[y*f2.lpitch+xoff*pixelsize], &f1.bits[y*f1.lpitch+xoff*pixelsize],
+ size*pixelsize);
+}
diff --git a/Plugins/copy_vert.dll b/Plugins/copy_vert.dll
new file mode 100644
index 0000000..95aab74
--- /dev/null
+++ b/Plugins/copy_vert.dll
Binary files differ
diff --git a/Plugins/copy_vert.exp b/Plugins/copy_vert.exp
new file mode 100644
index 0000000..d7f0589
--- /dev/null
+++ b/Plugins/copy_vert.exp
Binary files differ
diff --git a/Plugins/copy_vert.lib b/Plugins/copy_vert.lib
new file mode 100644
index 0000000..790bae5
--- /dev/null
+++ b/Plugins/copy_vert.lib
Binary files differ
diff --git a/Plugins/copy_vert.obj b/Plugins/copy_vert.obj
new file mode 100644
index 0000000..543c39f
--- /dev/null
+++ b/Plugins/copy_vert.obj
Binary files differ
diff --git a/Plugins/fs2vf.c b/Plugins/fs2vf.c
new file mode 100644
index 0000000..3d1d4bc
--- /dev/null
+++ b/Plugins/fs2vf.c
@@ -0,0 +1,49 @@
+//
+// writevf.c
+// put image data to vframe
+//
+// 1st argument is name of shared memory
+// to struct vframeimage (see Externals\vframe.h)
+//
+
+#include <memory.h>
+#include "plugin.h"
+#include "sharemem.h"
+#include "vframe.h"
+
+void perform_effect(_frame f, _args a)
+{
+ HANDLE hlvframe=NULL, hl=NULL;
+ LPVOID p=NULL;
+ struct vframeimage *vfp=NULL;
+ unsigned long c;
+
+ if(!a.s) return;
+
+ vfp = (struct vframeimage *)smopen(&hlvframe, a.s);
+ if(vfp==NULL) return;
+
+// printf("name %s width %d height %d pf %d bits %s\n",
+// a.s, vfp->f.width, vfp->f.height, vfp->f.pixelformat, vfp->bitsname);
+
+ if(f.pixelformat != vfp->f.pixelformat)
+ {
+ printf("fs2vf: pixelformats are different. no resampling available.\n");
+ return;
+ }
+
+ p = smopen(&hl, vfp->bitsname);
+ if(p==NULL)
+ {
+ CloseHandle(hlvframe);
+ return;
+ }
+
+ c = (f.height*f.lpitch < vfp->f.height*vfp->f.lpitch) ?
+ f.height*f.lpitch : vfp->f.height*vfp->f.lpitch;
+
+ memcpy(p, f.bits, c);
+
+ smfree(&hl, p);
+ smfree(&hlvframe, vfp);
+}
diff --git a/Plugins/fs2vf.dll b/Plugins/fs2vf.dll
new file mode 100644
index 0000000..974de86
--- /dev/null
+++ b/Plugins/fs2vf.dll
Binary files differ
diff --git a/Plugins/fs2vf.exp b/Plugins/fs2vf.exp
new file mode 100644
index 0000000..f3d5fba
--- /dev/null
+++ b/Plugins/fs2vf.exp
Binary files differ
diff --git a/Plugins/fs2vf.lib b/Plugins/fs2vf.lib
new file mode 100644
index 0000000..038bb12
--- /dev/null
+++ b/Plugins/fs2vf.lib
Binary files differ
diff --git a/Plugins/fs2vf.obj b/Plugins/fs2vf.obj
new file mode 100644
index 0000000..4996274
--- /dev/null
+++ b/Plugins/fs2vf.obj
Binary files differ
diff --git a/Plugins/gol.c b/Plugins/gol.c
new file mode 100644
index 0000000..89ff284
--- /dev/null
+++ b/Plugins/gol.c
@@ -0,0 +1,89 @@
+
+//
+// Game of Life .. what a waste of time
+//
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "plugin.h"
+
+#define BORN 1
+#define DYING 2
+
+int dead = 0;
+
+int aroundme(_frame f, int x, int y)
+{
+ int i=0;
+ if(r16(scanline16(f, y-1)[x-1])>dead) i++;
+ if(r16(scanline16(f, y-1)[x])>dead) i++;
+ if(r16(scanline16(f, y-1)[x+1])>dead) i++;
+ if(r16(scanline16(f, y)[x-1])>dead) i++;
+ if(r16(scanline16(f, y)[x+1])>dead) i++;
+ if(r16(scanline16(f, y+1)[x-1])>dead) i++;
+ if(r16(scanline16(f, y+1)[x])>dead) i++;
+ if(r16(scanline16(f, y+1)[x+1])>dead) i++;
+ return i;
+}
+
+void setstate(_frame f, byte *t, int x, int y)
+{
+ int i = aroundme(f, x, y);
+
+ if(i<=1 || i>=4) t[y*f.width+x]=DYING;
+ else
+ if(i==3) t[y*f.width+x]=BORN;
+}
+
+void perform_effect(struct frame f, struct args a)
+{
+ int x,y,i,r;
+ pixel16 *p, c;
+ byte *t;
+
+ if(f.pixelformat!=16) return;
+
+ t = malloc(f.width*f.height);
+ memset(t, 0, f.width*f.height);
+
+ for(y=2; y<f.height-3; y++)
+ {
+ p = scanline16(f, y);
+ for(x=2; x<f.width-3; x++)
+ {
+ if(r16(p[x])>0)
+ {
+ setstate(f, t, x-1, y-1);
+ setstate(f, t, x, y-1);
+ setstate(f, t, x+1, y-1);
+ setstate(f, t, x-1, y);
+ setstate(f, t, x, y);
+ setstate(f, t, x+1, y);
+ setstate(f, t, x-1, y+1);
+ setstate(f, t, x, y+1);
+ setstate(f, t, x+1, y+1);
+ }
+ }
+ }
+
+ for(y=2; y<f.height-3; y++)
+ {
+ p = scanline16(f, y);
+ for(x=2; x<f.width-3; x++)
+ {
+ switch(t[y*f.width+x])
+ {
+ case BORN:
+ c = p[x];
+ r = r16(c);
+ p[x] = rgbtocolor16(r>0 ? r : 255, g16(c), b16(c));
+ break;
+ case DYING:
+ c = p[+x];
+ p[x] = rgbtocolor16(0, g16(c), b16(c));
+ break;
+ }
+ }
+ }
+ free(t);
+}
diff --git a/Plugins/gol.dll b/Plugins/gol.dll
new file mode 100644
index 0000000..dfd2fd6
--- /dev/null
+++ b/Plugins/gol.dll
Binary files differ
diff --git a/Plugins/gol.exp b/Plugins/gol.exp
new file mode 100644
index 0000000..2dcf523
--- /dev/null
+++ b/Plugins/gol.exp
Binary files differ
diff --git a/Plugins/gol.lib b/Plugins/gol.lib
new file mode 100644
index 0000000..c38fb4e
--- /dev/null
+++ b/Plugins/gol.lib
Binary files differ
diff --git a/Plugins/gol.obj b/Plugins/gol.obj
new file mode 100644
index 0000000..e571ee0
--- /dev/null
+++ b/Plugins/gol.obj
Binary files differ
diff --git a/Plugins/green.cpp b/Plugins/green.cpp
new file mode 100644
index 0000000..c66e3e6
--- /dev/null
+++ b/Plugins/green.cpp
@@ -0,0 +1,14 @@
+// this is just an example of using the pixels-class..
+
+#include "plugin.h"
+#include "pixels.h"
+
+void perform_effect(_frame f, _args a)
+{
+ pixels p(f);
+ while(!p.eof())
+ {
+ p.putrgb(0, p.green(), 0);
+ p.next();
+ }
+}
diff --git a/Plugins/green.dll b/Plugins/green.dll
new file mode 100644
index 0000000..3dc1016
--- /dev/null
+++ b/Plugins/green.dll
Binary files differ
diff --git a/Plugins/green.exp b/Plugins/green.exp
new file mode 100644
index 0000000..bba3425
--- /dev/null
+++ b/Plugins/green.exp
Binary files differ
diff --git a/Plugins/green.lib b/Plugins/green.lib
new file mode 100644
index 0000000..f79b6b6
--- /dev/null
+++ b/Plugins/green.lib
Binary files differ
diff --git a/Plugins/green.obj b/Plugins/green.obj
new file mode 100644
index 0000000..d32d5ab
--- /dev/null
+++ b/Plugins/green.obj
Binary files differ
diff --git a/Plugins/hist.cpp b/Plugins/hist.cpp
new file mode 100644
index 0000000..f525db1
--- /dev/null
+++ b/Plugins/hist.cpp
@@ -0,0 +1,54 @@
+//
+// build an array where x=color intensity and y=number of colors with that intensity.
+// use with fs.hist.pd.
+//
+// array is passed in a file, a better solution would be to use vframe...
+//
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream.h>
+#include <fstream.h>
+#include <string.h>
+#include "plugin.h"
+#include "pixels.h"
+
+void perform_effect(_frame f, _args a)
+{
+ if(!a.s) return;
+
+ // parameters: <color> <filename for output> <pd receivename to bang>
+ // get gol
+ byte col = atoi(a.s);
+
+ // get filename
+ char *t;
+ if(!(t = strstr(a.s, " "))) return;
+ char *filename = t+1;
+
+ // get receivename
+ if(!(t = strstr(t+1, " "))) return;
+ char *retname = t+1;
+ t[0]=0; // tell filename and receivename apart
+
+ pixels p(f);
+ signed short hist[256]; // 16bits, for read16 on pd
+
+// count colors from zero up
+ memset(hist, 0, sizeof(hist));
+// or count from -2^15 (bottom of graph)?
+// short i, v=1<<15;
+// for(i=0; i<256; hist[i++]=v) ;
+
+ while(!p.eof())
+ {
+ ++hist[col==0 ? p.red() : col==1 ? p.green() : col==2 ? p.blue() : 0];
+ p.next();
+ }
+
+ ofstream of(filename, ios::out|ios::binary);
+ of.write((char *)&hist, sizeof(hist));
+ of.close();
+
+ sprintf(a.ret, "%s=1", retname); // bang to indicate we're done
+}
diff --git a/Plugins/hist.dll b/Plugins/hist.dll
new file mode 100644
index 0000000..7c0bc44
--- /dev/null
+++ b/Plugins/hist.dll
Binary files differ
diff --git a/Plugins/hist.exp b/Plugins/hist.exp
new file mode 100644
index 0000000..238ffc2
--- /dev/null
+++ b/Plugins/hist.exp
Binary files differ
diff --git a/Plugins/hist.lib b/Plugins/hist.lib
new file mode 100644
index 0000000..d8d0ddc
--- /dev/null
+++ b/Plugins/hist.lib
Binary files differ
diff --git a/Plugins/hist.obj b/Plugins/hist.obj
new file mode 100644
index 0000000..760936d
--- /dev/null
+++ b/Plugins/hist.obj
Binary files differ
diff --git a/Plugins/makefile b/Plugins/makefile
new file mode 100644
index 0000000..e899fe2
--- /dev/null
+++ b/Plugins/makefile
@@ -0,0 +1,82 @@
+all: noize colortv subtract xbend bend gol shuffle green tile rgbcopy copyvert black rgb hist setbits xshred sonogram vf2fs fs2vf swap 2colors plot makesliders
+ dir *.dll
+
+# FLAGS:
+#
+# <opts!!!>
+
+FLAGS = /LD /Gd /GD /Ox
+
+EFFECT = /export:perform_effect
+COPY = /export:perform_copy
+BOTH = /export:perform_effect /export:perform_copy
+
+noize:
+ cl noize.c $(FLAGS) /link $(BOTH)
+
+colortv:
+ cl colortv.c $(FLAGS) /link $(BOTH)
+
+subtract:
+ cl subtract.cpp $(FLAGS) /link $(EFFECT)
+
+xbend:
+ cl xbend.c $(FLAGS) /link $(BOTH)
+
+bend:
+ cl bend.c $(FLAGS) /link $(BOTH)
+
+gol:
+ cl gol.c $(FLAGS) /link $(EFFECT)
+
+shuffle:
+ cl shuffle.c $(FLAGS) /link $(EFFECT)
+
+green:
+ cl green.cpp $(FLAGS) /link $(EFFECT)
+
+tile:
+ cl tile.cpp $(FLAGS) /link $(COPY)
+
+rgbcopy:
+ cl rgbcopy.cpp $(FLAGS) /link $(COPY)
+
+copyvert:
+ cl copy_vert.c $(FLAGS) /link $(COPY)
+
+black:
+ cl black.c $(FLAGS) /link $(BOTH)
+
+rgb:
+ cl rgb.c $(FLAGS) /link $(EFFECT)
+
+hist:
+ cl hist.cpp $(FLAGS) /link $(EFFECT)
+
+setbits:
+ cl setbits.c $(FLAGS) /link $(EFFECT)
+
+sonogram:
+ cl sonogram.cpp $(FLAGS) /link $(EFFECT)
+
+xshred:
+ cl xshred.c $(FLAGS) /link $(COPY)
+
+vf2fs:
+ cl vf2fs.c $(FLAGS) /I..\Externals /link $(EFFECT)
+
+fs2vf:
+ cl fs2vf.c $(FLAGS) /I..\Externals /link $(EFFECT)
+
+swap:
+ cl swap.cpp $(FLAGS) /link $(COPY)
+
+2colors:
+ cl 2colors.cpp $(FLAGS) /link $(EFFECT)
+
+plot:
+ cl plot.cpp $(FLAGS) /link $(EFFECT)
+
+makesliders:
+ cl makesliders.c $(FLAGS) /link $(EFFECT)
+ copy makesliders.dll ms.dll
diff --git a/Plugins/makesliders.c b/Plugins/makesliders.c
new file mode 100644
index 0000000..5c0b209
--- /dev/null
+++ b/Plugins/makesliders.c
@@ -0,0 +1,40 @@
+//
+// makesliders: display slider values
+//
+// usage: makesliders 14 56 76 140
+// displays four sliders with given values
+//
+
+#include <string.h>
+#include "plugin.h"
+
+#define MAXVALS 128
+
+void perform_effect(_frame f, _args a)
+{
+ pixel8 *p8;
+ char *t=a.s;
+ int val[MAXVALS], valcount=0, i, y, bitsperpixel=f.pixelformat / 8, col;
+
+ if(!t) return;
+
+ while(t && valcount<MAXVALS)
+ {
+ val[valcount++] = atoi(t);
+ t = strstr(t, " ");
+ if(t) t++;
+ }
+
+ memset(f.bits, 0, f.height*f.lpitch);
+ col = rand()%256;
+
+ for(i=0; i<f.width; i++)
+ {
+ y = val[(int)(i / (float)f.width * (float)valcount)];
+ if(y>=0 && y<f.height)
+ {
+ p8 = scanline(f, y);
+ memset(p8+i*bitsperpixel, 200, bitsperpixel);
+ }
+ }
+}
diff --git a/Plugins/makesliders.dll b/Plugins/makesliders.dll
new file mode 100644
index 0000000..5491ab8
--- /dev/null
+++ b/Plugins/makesliders.dll
Binary files differ
diff --git a/Plugins/makesliders.exp b/Plugins/makesliders.exp
new file mode 100644
index 0000000..307b3d6
--- /dev/null
+++ b/Plugins/makesliders.exp
Binary files differ
diff --git a/Plugins/makesliders.lib b/Plugins/makesliders.lib
new file mode 100644
index 0000000..40bd42c
--- /dev/null
+++ b/Plugins/makesliders.lib
Binary files differ
diff --git a/Plugins/makesliders.obj b/Plugins/makesliders.obj
new file mode 100644
index 0000000..c7326db
--- /dev/null
+++ b/Plugins/makesliders.obj
Binary files differ
diff --git a/Plugins/ms.dll b/Plugins/ms.dll
new file mode 100644
index 0000000..5491ab8
--- /dev/null
+++ b/Plugins/ms.dll
Binary files differ
diff --git a/Plugins/noize.c b/Plugins/noize.c
new file mode 100644
index 0000000..d6d2b3a
--- /dev/null
+++ b/Plugins/noize.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include "plugin.h"
+
+void perform_effect(struct frame f, struct args a)
+{
+ int i,o,x,y;
+ byte bits = f.pixelformat/8;
+
+ o=(f.width*f.height)/10;
+ for(i=0; i<o; i++)
+ {
+ x=rand()%(f.width);
+ y=rand()%(f.height);
+ f.bits[y*f.lpitch+x*bits+1]=rand()%(256);
+ }
+}
+
+void perform_copy(struct frame f1, struct frame f2, struct args a)
+{
+ printf("Using noize as copy operation does nothing!\n");
+}
diff --git a/Plugins/noize.dll b/Plugins/noize.dll
new file mode 100644
index 0000000..b761095
--- /dev/null
+++ b/Plugins/noize.dll
Binary files differ
diff --git a/Plugins/noize.exp b/Plugins/noize.exp
new file mode 100644
index 0000000..489c203
--- /dev/null
+++ b/Plugins/noize.exp
Binary files differ
diff --git a/Plugins/noize.lib b/Plugins/noize.lib
new file mode 100644
index 0000000..cbdfba5
--- /dev/null
+++ b/Plugins/noize.lib
Binary files differ
diff --git a/Plugins/noize.obj b/Plugins/noize.obj
new file mode 100644
index 0000000..302298a
--- /dev/null
+++ b/Plugins/noize.obj
Binary files differ
diff --git a/Plugins/pixels.h b/Plugins/pixels.h
new file mode 100644
index 0000000..4dd1264
--- /dev/null
+++ b/Plugins/pixels.h
@@ -0,0 +1,117 @@
+// Easy iteration thru pixels, see green.cpp and tile.cpp for examples
+// NOTE: using this class could be a bit slower than manipulating the bits directly..
+//
+// changes to 0.20
+// - pixelformat-aware functions red() green() blue() and putrgb()
+// - dot16() dot24() and dot32() added
+// - get/put dot() removed, use above
+
+#include "plugin.h"
+
+#ifndef _PIXELSH
+#define _PIXELSH
+
+class pixels
+{
+private:
+ _frame m_f;
+ pixel8 *p8; // pointer to a row of 8-bit pixels
+ pixel16 *p16;
+ pixel24 *p24;
+ pixel32 *p32;
+
+ __inline void updaterowp();
+public:
+ int x, y;
+
+ pixels(const _frame &f)
+ {
+ m_f = f;
+ x = -1;
+ y = 0;
+ p8 = 0;
+ next();
+ }
+
+ __inline pixel8 dot8() { return p8[x]; }
+ __inline pixel16 dot16() { return p16[x]; }
+ __inline pixel24 dot24() { return p24[x]; }
+ __inline pixel32 dot32() { return p32[x]; }
+
+ __inline void dot8(pixel8 c) { p8[x] = c; }
+ __inline void dot16(pixel16 c) { p16[x] = c; }
+ __inline void dot24(pixel24 c) { p24[x] = c; }
+ __inline void dot32(pixel32 c) { p32[x] = c; }
+
+ __inline byte red();
+ __inline byte green();
+ __inline byte blue();
+
+ __inline void putrgb(byte r, byte g, byte b);
+
+ __inline void moveto(int tox, int toy)
+ { if(tox<m_f.width) x=tox; if(toy<m_f.height) { y=toy; updaterowp(); } }
+
+ __inline int eof() { return y==m_f.height ? 1 : 0; }
+ void next();
+};
+
+byte pixels::red()
+{
+ switch(m_f.pixelformat)
+ {
+ case 16: return r16(p16[x]);
+ case 24: return r24(p24[x]);
+ case 32: return r32(p32[x]);
+ default: return 0;
+ }
+}
+
+byte pixels::green()
+{
+ switch(m_f.pixelformat)
+ {
+ case 16: return g16(p16[x]);
+ case 24: return g24(p24[x]);
+ case 32: return g32(p32[x]);
+ default: return 0;
+ }
+}
+
+byte pixels::blue()
+{
+ switch(m_f.pixelformat)
+ {
+ case 16: return b16(p16[x]);
+ case 24: return b24(p24[x]);
+ case 32: return b32(p32[x]);
+ default: return 0;
+ }
+}
+
+void pixels::putrgb(byte r, byte g, byte b)
+{
+ switch(m_f.pixelformat)
+ {
+ case 16: p16[x] = rgbtocolor16(r, g, b); break;
+ case 24: p24[x] = rgbtocolor24(r, g, b); break;
+ case 32: p32[x] = rgbtocolor32(r, g, b); break;
+ }
+}
+
+void pixels::next()
+{
+ x++;
+ if(x==m_f.width) { y++; x=0; p8=0; }
+ if(!p8) updaterowp();
+}
+
+void pixels::updaterowp()
+{
+ p8 = scanline(m_f, y);
+ p16 = (pixel16 *)p8;
+ p24 = (pixel24 *)p8;
+ p32 = (pixel32 *)p8;
+}
+
+#endif // #ifndef _PIXELSH
diff --git a/Plugins/plot.cpp b/Plugins/plot.cpp
new file mode 100644
index 0000000..67c264c
--- /dev/null
+++ b/Plugins/plot.cpp
@@ -0,0 +1,25 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "plugin.h"
+#include "pixels.h"
+
+// plot exists to provide plotting to vframe - much faster than
+// plot with fs.draw which goes thru network.
+
+void perform_effect(_frame f, _args a)
+{
+ if(!a.s) return;
+
+ char *t=strstr(a.s, " ");
+ if(!t) return;
+
+ t[0]=0;
+
+ int x=atoi(a.s);
+ int y=atoi(t+1);
+
+ pixels p(f);
+ p.moveto(x, y);
+ p.putrgb(255, 255, 255);
+}
diff --git a/Plugins/plot.dll b/Plugins/plot.dll
new file mode 100644
index 0000000..93cff6a
--- /dev/null
+++ b/Plugins/plot.dll
Binary files differ
diff --git a/Plugins/plot.exp b/Plugins/plot.exp
new file mode 100644
index 0000000..1d5ce2f
--- /dev/null
+++ b/Plugins/plot.exp
Binary files differ
diff --git a/Plugins/plot.lib b/Plugins/plot.lib
new file mode 100644
index 0000000..afdc085
--- /dev/null
+++ b/Plugins/plot.lib
Binary files differ
diff --git a/Plugins/plot.obj b/Plugins/plot.obj
new file mode 100644
index 0000000..c48c30f
--- /dev/null
+++ b/Plugins/plot.obj
Binary files differ
diff --git a/Plugins/plugin.h b/Plugins/plugin.h
new file mode 100644
index 0000000..00d3514
--- /dev/null
+++ b/Plugins/plugin.h
@@ -0,0 +1,119 @@
+//
+// send the name of the plugin to fs.frame, and fs will call
+// perform_effect(struct frame f, struct args a) in your dll.
+//
+// send it to the right inlet of fs.copy, and
+// perform_copy(struct frame f1, struct frame f2, struct args a)
+// will be used as a copy operation.
+//
+
+#ifndef _PLUGINH
+#define _PLUGINH
+
+typedef unsigned char byte;
+#define pixel8 byte
+#define pixel16 unsigned short
+#define pixel24 struct pixel24data
+#define pixel32 unsigned long
+#define _frame struct frame
+#define _args struct args
+
+struct pixel24data { byte b; byte g; byte r; };
+
+struct frame
+{
+ byte *bits; // pixel data
+ int lpitch; // used to get row position in bits, see scanline below
+ // this is not always width*(pixelformat/8), you tell me why
+ int width;
+ int height;
+ int pixelformat; // pixelformat is bitcount of your screen, 8, 16, 24 or 32.
+};
+
+struct args
+{
+ char *s; // effect/copy arguments in a string
+ char *ret; // return values. data given in the form
+ // "pd_receive_name=value;..." will be sent back to Pd.
+ // memory allocated: 256 characters.
+};
+
+// 8-bit pointer to row y
+__inline byte *scanline(struct frame f, int y) { return &f.bits[y*f.lpitch]; }
+
+// pointer to 16 bit pixels
+__inline pixel16 *scanline16(struct frame f, int y) { return (pixel16 *)scanline(f, y); }
+
+// pointer to 24 bit pixels
+__inline pixel24 *scanline24(struct frame f, int y) { return (pixel24 *)scanline(f, y); }
+
+// pointer to 32 bit pixels
+__inline pixel32 *scanline32(struct frame f, int y) { return (pixel32 *)scanline(f, y); }
+
+__inline byte r16(pixel16 color)
+{
+ return (color >> 11) << 3;
+}
+
+__inline byte g16(pixel16 color)
+{
+ return ((color & 2016) >> 5) << 2;
+}
+
+__inline byte b16(pixel16 color)
+{
+ return (color & 31) << 3;
+}
+
+__inline byte r24(pixel24 color)
+{
+ return color.r;
+}
+
+__inline byte g24(pixel24 color)
+{
+ return color.g;
+}
+
+__inline byte b24(pixel24 color)
+{
+ return color.b;
+}
+
+__inline byte r32(pixel32 color)
+{
+ return (byte)color;
+}
+
+__inline byte g32(pixel32 color)
+{
+ return (byte)(((pixel16)color) >> 8);
+}
+
+__inline byte b32(pixel32 color)
+{
+ return (byte)(color >> 16);
+}
+
+__inline pixel16 rgbtocolor16(byte r, byte g, byte b)
+{
+ return ((r >> 3) << 11) | // r value shifted
+ ((g >> 2) << 5) | // g value shifted
+ (b >> 3); // add blue
+}
+
+__inline pixel24 rgbtocolor24(byte r, byte g, byte b)
+{
+ pixel24 p;
+ p.r = r;
+ p.g = g;
+ p.b = b;
+ return p;
+}
+
+__inline pixel32 rgbtocolor32(byte r, byte g, byte b)
+{
+ return (b << 16) | (g << 8) | r;
+}
+
+#endif // #ifndef _PLUGINH
diff --git a/Plugins/rgb.c b/Plugins/rgb.c
new file mode 100644
index 0000000..d58f784
--- /dev/null
+++ b/Plugins/rgb.c
@@ -0,0 +1,62 @@
+#include <string.h>
+#include "plugin.h"
+
+void perform_effect(_frame f, _args a)
+{
+ char *t;
+ short x, y;
+ pixel16 c16;
+ pixel24 c24;
+ pixel32 c32;
+ byte r, g, b;
+ char *ret_r, *ret_g, *ret_b;
+
+ if(!a.s) return;
+
+ // get x and y params
+ x = atoi(a.s);
+ if(!(t = strstr(a.s, " "))) return;
+ y = atoi(t+1);
+
+ // get returnvaluereceivenames
+ if(!(t = strstr(t+1, " "))) return;
+ ret_r = t+1;
+ if(!(t = strstr(t+1, " "))) return;
+ ret_g = t+1;
+ t[0]=0;
+ if(!(t = strstr(t+1, " "))) return;
+ ret_b = t+1;
+ t[0]=0;
+
+ if(x<0||x>=f.width) return;
+ if(y<0||y>=f.height) return;
+
+ switch(f.pixelformat)
+ {
+ case 16:
+ c16 = scanline16(f, y)[x];
+ r = r16(c16);
+ g = g16(c16);
+ b = b16(c16);
+ break;
+ case 24:
+ c24 = scanline24(f, y)[x];
+ r = r24(c24);
+ g = g24(c24);
+ b = b24(c24);
+ break;
+ case 32:
+ c32 = scanline32(f, y)[x];
+ r = r32(c32);
+ g = g32(c32);
+ b = b32(c32);
+ break;
+ }
+
+ // return-values:
+ //
+ // framestein will send data given in the form "pd_receiver_name=value"
+ // back to pd.
+
+ sprintf(a.ret, "%s=%d;%s=%d;%s=%d", ret_b, b, ret_g, g, ret_r, r);
+}
diff --git a/Plugins/rgb.dll b/Plugins/rgb.dll
new file mode 100644
index 0000000..ba7dfd2
--- /dev/null
+++ b/Plugins/rgb.dll
Binary files differ
diff --git a/Plugins/rgb.exp b/Plugins/rgb.exp
new file mode 100644
index 0000000..cc7feab
--- /dev/null
+++ b/Plugins/rgb.exp
Binary files differ
diff --git a/Plugins/rgb.lib b/Plugins/rgb.lib
new file mode 100644
index 0000000..8e364a1
--- /dev/null
+++ b/Plugins/rgb.lib
Binary files differ
diff --git a/Plugins/rgb.obj b/Plugins/rgb.obj
new file mode 100644
index 0000000..69b7892
--- /dev/null
+++ b/Plugins/rgb.obj
Binary files differ
diff --git a/Plugins/rgbcopy.cpp b/Plugins/rgbcopy.cpp
new file mode 100644
index 0000000..b226e23
--- /dev/null
+++ b/Plugins/rgbcopy.cpp
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <string.h>
+#include "plugin.h"
+#include "pixels.h"
+
+void perform_copy(_frame f1, _frame f2, _args a)
+{
+ pixels p1(f1), p2(f2);
+ char *t;
+ short r=0, g=0, b=0;
+
+ if(!a.s) return;
+
+ if(strstr(a.s, "r") || strstr(a.s, "R")) r=1;
+ if(strstr(a.s, "g") || strstr(a.s, "G")) g=1;
+ if(strstr(a.s, "b") || strstr(a.s, "B")) b=1;
+
+ while(!p1.eof()&&!p2.eof())
+ {
+ p2.putrgb(
+ r ? p1.red() : p2.red(),
+ g ? p1.green() : p2.green(),
+ b ? p1.blue() : p2.blue()
+ );
+ p1.next();
+ p2.next();
+ }
+}
diff --git a/Plugins/rgbcopy.dll b/Plugins/rgbcopy.dll
new file mode 100644
index 0000000..1a995d3
--- /dev/null
+++ b/Plugins/rgbcopy.dll
Binary files differ
diff --git a/Plugins/rgbcopy.exp b/Plugins/rgbcopy.exp
new file mode 100644
index 0000000..b85e71e
--- /dev/null
+++ b/Plugins/rgbcopy.exp
Binary files differ
diff --git a/Plugins/rgbcopy.lib b/Plugins/rgbcopy.lib
new file mode 100644
index 0000000..09edbd5
--- /dev/null
+++ b/Plugins/rgbcopy.lib
Binary files differ
diff --git a/Plugins/rgbcopy.obj b/Plugins/rgbcopy.obj
new file mode 100644
index 0000000..5d7194c
--- /dev/null
+++ b/Plugins/rgbcopy.obj
Binary files differ
diff --git a/Plugins/setbits.c b/Plugins/setbits.c
new file mode 100644
index 0000000..dddc5eb
--- /dev/null
+++ b/Plugins/setbits.c
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include "plugin.h"
+
+void perform_effect(_frame f, _args a)
+{
+ unsigned char c;
+
+ if(!a.s) return;
+ c = atoi(a.s);
+ memset(f.bits, c, f.height*f.lpitch);
+}
diff --git a/Plugins/setbits.dll b/Plugins/setbits.dll
new file mode 100644
index 0000000..9a772ab
--- /dev/null
+++ b/Plugins/setbits.dll
Binary files differ
diff --git a/Plugins/setbits.exp b/Plugins/setbits.exp
new file mode 100644
index 0000000..484fe3b
--- /dev/null
+++ b/Plugins/setbits.exp
Binary files differ
diff --git a/Plugins/setbits.lib b/Plugins/setbits.lib
new file mode 100644
index 0000000..1e1db08
--- /dev/null
+++ b/Plugins/setbits.lib
Binary files differ
diff --git a/Plugins/setbits.obj b/Plugins/setbits.obj
new file mode 100644
index 0000000..09a9196
--- /dev/null
+++ b/Plugins/setbits.obj
Binary files differ
diff --git a/Plugins/sharemem.h b/Plugins/sharemem.h
new file mode 100644
index 0000000..a26d198
--- /dev/null
+++ b/Plugins/sharemem.h
@@ -0,0 +1,61 @@
+#ifndef __SHAREMEM_H
+#define __SHAREMEM_H
+
+#include <windows.h>
+#include <memory.h>
+
+//
+// allocate named shared memory
+//
+LPVOID smalloc(HANDLE *h, char *name, DWORD size)
+{
+ LPVOID p;
+
+ *h = CreateFileMapping(
+ INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
+ size, name
+ );
+
+ if(*h==NULL) return(NULL);
+
+ p = MapViewOfFile( *h, FILE_MAP_WRITE, 0, 0, 0);
+
+ if(p==NULL)
+ {
+ CloseHandle(*h);
+ return(NULL);
+ }
+ return(p);
+}
+
+//
+// open access to named shared memory
+//
+LPVOID smopen(HANDLE *h, char *name)
+{
+ LPVOID p;
+
+ *h = OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, name);
+
+ if(*h==NULL) return(NULL);
+
+ p = MapViewOfFile(*h, FILE_MAP_WRITE, 0, 0, 0);
+
+ if(p==NULL)
+ {
+ CloseHandle(*h);
+ return(NULL);
+ }
+ return(p);
+}
+
+//
+// cleanup
+//
+void smfree(HANDLE *h, LPVOID p)
+{
+ UnmapViewOfFile(p);
+ CloseHandle(*h);
+}
+
+#endif
diff --git a/Plugins/shuffle.c b/Plugins/shuffle.c
new file mode 100644
index 0000000..0604595
--- /dev/null
+++ b/Plugins/shuffle.c
@@ -0,0 +1,42 @@
+#include <string.h>
+#include "plugin.h"
+
+void perform_effect(_frame f, _args a)
+{
+ int i, o=1000, x1, y1, x2, y2, range=10;
+ char *t;
+ pixel8 *p1, *p2;
+ pixel32 dot;
+ byte pixelsize=f.pixelformat/8;
+
+ if(f.pixelformat>32) return;
+
+ if(a.s)
+ {
+ o = atoi(a.s);
+ if(o==0) o=1000;
+
+ if(t = strstr(a.s, " "))
+ if((range = atoi(t+1))==0) return;
+ }
+
+ for(i=0; i<o; i++)
+ {
+ x1 = rand()%f.width;
+ y1 = rand()%f.height;
+ x2 = x1 + (rand()%(range*2) - range);
+ y2 = y1 + (rand()%(range*2) - range);
+
+ if(x2<0) x2=0;
+ if(x2>=f.width) x2=f.width-1;
+ if(y2<0) y2=0;
+ if(y2>=f.height) y2=f.height-1;
+
+ p1 = scanline(f, y1);
+ p2 = scanline(f, y2);
+
+ memcpy(&dot, &p2[x2*pixelsize], pixelsize);
+ memcpy(&p2[x2*pixelsize], &p1[x1*pixelsize], pixelsize);
+ memcpy(&p1[x1*pixelsize], &dot, pixelsize);
+ }
+}
diff --git a/Plugins/shuffle.dll b/Plugins/shuffle.dll
new file mode 100644
index 0000000..bd5d552
--- /dev/null
+++ b/Plugins/shuffle.dll
Binary files differ
diff --git a/Plugins/shuffle.exp b/Plugins/shuffle.exp
new file mode 100644
index 0000000..2802b94
--- /dev/null
+++ b/Plugins/shuffle.exp
Binary files differ
diff --git a/Plugins/shuffle.lib b/Plugins/shuffle.lib
new file mode 100644
index 0000000..d1bc16f
--- /dev/null
+++ b/Plugins/shuffle.lib
Binary files differ
diff --git a/Plugins/shuffle.obj b/Plugins/shuffle.obj
new file mode 100644
index 0000000..5c70ab2
--- /dev/null
+++ b/Plugins/shuffle.obj
Binary files differ
diff --git a/Plugins/sonogram.cpp b/Plugins/sonogram.cpp
new file mode 100644
index 0000000..821b94a
--- /dev/null
+++ b/Plugins/sonogram.cpp
@@ -0,0 +1,82 @@
+//
+// sonogram.cpp
+//
+// use with fs.sonogram
+//
+// see example-sonogram.pd
+//
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream.h>
+#include <fstream.h>
+#include <string.h>
+#include "plugin.h"
+#include "pixels.h"
+
+#define SONOSIZE 128
+#define SONOMAXVAL 500
+#define sonotype float
+
+int callcount=-1;
+
+void perform_effect(_frame f, _args a)
+{
+ if(!a.s) return;
+
+ if(++callcount>=f.width) callcount=0;
+
+ FILE *inf;
+ if((inf = fopen(a.s, "rb"))==NULL)
+ {
+ printf("sonogram: error opening %s\n", a.s);
+ return;
+ }
+
+ char buf[80];
+ sonotype sono[SONOSIZE];
+ int i=0;
+
+ while(!feof(inf))
+ {
+ if(!fgets(buf, 80, inf))
+ {
+ printf("sonogram: read error.\n");
+ return;
+ }
+ sono[i] = atof(buf);
+ if(++i>=SONOSIZE) break;
+ }
+ fclose(inf);
+
+ int y;
+
+ for(i=0; i<SONOSIZE; i++)
+ {
+ // scale values 0-500 to 0-255
+ if(sono[i]>SONOMAXVAL) sono[i]=SONOMAXVAL;
+ sono[i] = (sonotype)((sono[i] / (float)SONOMAXVAL)*255);
+ // white = no sound
+ sono[i] = abs(sono[i]-255);
+
+ y = (int)((i / (float)SONOSIZE) * (float)f.height);
+ // bottom = bass
+ y = abs((f.height-1) - y);
+
+ switch(f.pixelformat)
+ {
+ case 16:
+ scanline16(f, y)[callcount] =
+ rgbtocolor16(sono[i], sono[i], sono[i]);
+ break;
+ case 24:
+ scanline24(f, y)[callcount] =
+ rgbtocolor24(sono[i], sono[i], sono[i]);
+ break;
+ case 32:
+ scanline32(f, y)[callcount] =
+ rgbtocolor32(sono[i], sono[i], sono[i]);
+ break;
+ }
+ }
+}
diff --git a/Plugins/sonogram.dll b/Plugins/sonogram.dll
new file mode 100644
index 0000000..db6e132
--- /dev/null
+++ b/Plugins/sonogram.dll
Binary files differ
diff --git a/Plugins/sonogram.exp b/Plugins/sonogram.exp
new file mode 100644
index 0000000..40a6fae
--- /dev/null
+++ b/Plugins/sonogram.exp
Binary files differ
diff --git a/Plugins/sonogram.lib b/Plugins/sonogram.lib
new file mode 100644
index 0000000..484c38d
--- /dev/null
+++ b/Plugins/sonogram.lib
Binary files differ
diff --git a/Plugins/sonogram.obj b/Plugins/sonogram.obj
new file mode 100644
index 0000000..7dd6ee5
--- /dev/null
+++ b/Plugins/sonogram.obj
Binary files differ
diff --git a/Plugins/subtract.cpp b/Plugins/subtract.cpp
new file mode 100644
index 0000000..89ba216
--- /dev/null
+++ b/Plugins/subtract.cpp
@@ -0,0 +1,38 @@
+// 0.20
+// - from c to c++
+// - pixelformat-aware
+
+#include <stdlib.h>
+#include <string.h>
+#include "plugin.h"
+#include "pixels.h"
+
+void perform_effect(_frame f, _args a)
+{
+ pixels p(f);
+ char *t;
+ byte tr, tg, tb, r=0, g=0, b=0;
+
+ if(!a.s) return;
+
+ r = atoi(a.s);
+ if(t = strstr(a.s, " "))
+ {
+ g = atoi(t+1);
+ if (t = strstr(t+1, " "))
+ b = atoi(t+1);
+ }
+
+ while(!p.eof())
+ {
+ tr = p.red();
+ tg = p.green();
+ tb = p.blue();
+ p.putrgb(
+ tr>r ? tr-r : 0,
+ tg>g ? tg-g : 0,
+ tb>b ? tb-b : 0
+ );
+ p.next();
+ }
+}
diff --git a/Plugins/subtract.dll b/Plugins/subtract.dll
new file mode 100644
index 0000000..883c541
--- /dev/null
+++ b/Plugins/subtract.dll
Binary files differ
diff --git a/Plugins/subtract.exp b/Plugins/subtract.exp
new file mode 100644
index 0000000..9a066ba
--- /dev/null
+++ b/Plugins/subtract.exp
Binary files differ
diff --git a/Plugins/subtract.lib b/Plugins/subtract.lib
new file mode 100644
index 0000000..5132561
--- /dev/null
+++ b/Plugins/subtract.lib
Binary files differ
diff --git a/Plugins/subtract.obj b/Plugins/subtract.obj
new file mode 100644
index 0000000..8405ccc
--- /dev/null
+++ b/Plugins/subtract.obj
Binary files differ
diff --git a/Plugins/swap.cpp b/Plugins/swap.cpp
new file mode 100644
index 0000000..d1389f4
--- /dev/null
+++ b/Plugins/swap.cpp
@@ -0,0 +1,62 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "plugin.h"
+#include "pixels.h"
+
+// swap selected area on two images
+// args: swap sourcex1 sourcey1 sourcex2 sourcey2 destx desty
+// (the selection is of equal size on both images)
+
+void swapint(int *a, int *b)
+{
+ int i = *b;
+ *b = *a;
+ *a = i;
+}
+
+void perform_copy(_frame f1, _frame f2, _args a)
+{
+ if(!a.s) return;
+
+ // get args
+ int sx1, sy1, sx2, sy2, dx1, dy1;
+ char *t;
+
+ sx1 = atoi(a.s);
+ if(!(t = strstr(a.s, " "))) return;
+ sy1 = atoi(t);
+ if(!(t = strstr(t+1, " "))) return;
+ sx2 = atoi(t);
+ if(!(t = strstr(t+1, " "))) return;
+ sy2 = atoi(t);
+ if(!(t = strstr(t+1, " "))) return;
+ dx1 = atoi(t);
+ if(!(t = strstr(t+1, " "))) return;
+ dy1 = atoi(t);
+
+ if(sx1>sx2) swapint(&sx1, &sx2);
+ if(sy1>sy2) swapint(&sy1, &sy2);
+
+printf("swap: %d %d %d %d - %d %d\n", sx1, sy1, sx2, sy2, dx1, dy1);
+
+ int x, y, i, o;
+ pixel16 c16;
+ pixels p1(f1), p2(f2);
+
+ for(y=sy1; y<=sy2; y++)
+ for(x=sx1; x<=sx2; x++)
+ {
+ if(x>=f1.width || y>=f1.height) continue;
+ i = dx1+(x-sx1);
+ o = dy1+(y-sy1);
+ if(i>=f2.width || o>=f2.height) continue;
+
+ p1.moveto(x, y);
+ p2.moveto(i, o);
+
+ c16 = p2.dot16();
+ p2.dot16(p1.dot16());
+ p1.dot16(c16);
+ }
+}
diff --git a/Plugins/swap.dll b/Plugins/swap.dll
new file mode 100644
index 0000000..ee04f4c
--- /dev/null
+++ b/Plugins/swap.dll
Binary files differ
diff --git a/Plugins/swap.exp b/Plugins/swap.exp
new file mode 100644
index 0000000..8015b40
--- /dev/null
+++ b/Plugins/swap.exp
Binary files differ
diff --git a/Plugins/swap.lib b/Plugins/swap.lib
new file mode 100644
index 0000000..bda1a31
--- /dev/null
+++ b/Plugins/swap.lib
Binary files differ
diff --git a/Plugins/swap.obj b/Plugins/swap.obj
new file mode 100644
index 0000000..cca03a8
--- /dev/null
+++ b/Plugins/swap.obj
Binary files differ
diff --git a/Plugins/tile.cpp b/Plugins/tile.cpp
new file mode 100644
index 0000000..47fa5ca
--- /dev/null
+++ b/Plugins/tile.cpp
@@ -0,0 +1,59 @@
+#include <stdlib.h>
+#include <string.h>
+#include "plugin.h"
+#include "pixels.h"
+
+void perform_copy(_frame f1, _frame f2, _args a)
+{
+ pixels px(f2);
+ pixel16 *p16;
+ pixel24 *p24;
+ pixel32 *p32;
+ int tile, tiley=-1, prevy=-1;
+ char *t;
+
+ tile = atoi(a.s);
+ if(tile<=0) tile=2;
+ if(t = strstr(a.s, " "))
+ {
+ tiley = atoi(t+1);
+ if(tiley<=0) tiley=2;
+ }
+
+ // i could have the switch() inside the while-loop..
+ // but is it more efficient this way?
+
+ switch(f1.pixelformat)
+ {
+ case 16:
+ while(!px.eof()) {
+ if(px.y != prevy) {
+ p16 = scanline16(f1, (px.y * (tiley>0 ? tiley : tile))%f1.height);
+ prevy = px.y;
+ }
+ px.dot16(p16[ (px.x * tile)%f1.width ]);
+ px.next();
+ }
+ break;
+ case 24:
+ while(!px.eof()) {
+ if(px.y != prevy) {
+ p24 = scanline24(f1, (px.y * (tiley>0 ? tiley : tile))%f1.height);
+ prevy = px.y;
+ }
+ px.dot24(p24[ (px.x * tile)%f1.width ]);
+ px.next();
+ }
+ break;
+ case 32:
+ while(!px.eof()) {
+ if(px.y != prevy) {
+ p32 = scanline32(f1, (px.y * (tiley>0 ? tiley : tile))%f1.height);
+ prevy = px.y;
+ }
+ px.dot32(p32[ (px.x * tile)%f1.width ]);
+ px.next();
+ }
+ break;
+ }
+}
diff --git a/Plugins/tile.dll b/Plugins/tile.dll
new file mode 100644
index 0000000..58a8886
--- /dev/null
+++ b/Plugins/tile.dll
Binary files differ
diff --git a/Plugins/tile.exp b/Plugins/tile.exp
new file mode 100644
index 0000000..69d5907
--- /dev/null
+++ b/Plugins/tile.exp
Binary files differ
diff --git a/Plugins/tile.lib b/Plugins/tile.lib
new file mode 100644
index 0000000..1f0732e
--- /dev/null
+++ b/Plugins/tile.lib
Binary files differ
diff --git a/Plugins/tile.obj b/Plugins/tile.obj
new file mode 100644
index 0000000..8409075
--- /dev/null
+++ b/Plugins/tile.obj
Binary files differ
diff --git a/Plugins/vf2fs.c b/Plugins/vf2fs.c
new file mode 100644
index 0000000..47e856e
--- /dev/null
+++ b/Plugins/vf2fs.c
@@ -0,0 +1,49 @@
+//
+// readvf.c
+// used to display vframe objects
+//
+// 1st argument is name of shared memory
+// to struct vframeimage (see Externals\vframe.h)
+//
+
+#include <memory.h>
+#include "plugin.h"
+#include "sharemem.h"
+#include "vframe.h"
+
+void perform_effect(_frame f, _args a)
+{
+ HANDLE hlvframe=NULL, hl=NULL;
+ LPVOID p=NULL;
+ struct vframeimage *vfp=NULL;
+ unsigned long c;
+
+ if(!a.s) return;
+
+ vfp = (struct vframeimage *)smopen(&hlvframe, a.s);
+ if(vfp==NULL) return;
+
+// printf("name %s width %d height %d pf %d bits %s\n",
+// a.s, vfp->f.width, vfp->f.height, vfp->f.pixelformat, vfp->bitsname);
+
+ if(f.pixelformat != vfp->f.pixelformat)
+ {
+ printf("vf2fs: pixelformats are different. no resampling available.\n");
+ return;
+ }
+
+ p = smopen(&hl, vfp->bitsname);
+ if(p==NULL)
+ {
+ CloseHandle(hlvframe);
+ return;
+ }
+
+ c = (f.height*f.lpitch < vfp->f.height*vfp->f.lpitch) ?
+ f.height*f.lpitch : vfp->f.height*vfp->f.lpitch;
+
+ memcpy(f.bits, p, c);
+
+ smfree(&hl, p);
+ smfree(&hlvframe, vfp);
+}
diff --git a/Plugins/vf2fs.dll b/Plugins/vf2fs.dll
new file mode 100644
index 0000000..d51abad
--- /dev/null
+++ b/Plugins/vf2fs.dll
Binary files differ
diff --git a/Plugins/vf2fs.exp b/Plugins/vf2fs.exp
new file mode 100644
index 0000000..c9ce25b
--- /dev/null
+++ b/Plugins/vf2fs.exp
Binary files differ
diff --git a/Plugins/vf2fs.lib b/Plugins/vf2fs.lib
new file mode 100644
index 0000000..0c52583
--- /dev/null
+++ b/Plugins/vf2fs.lib
Binary files differ
diff --git a/Plugins/vf2fs.obj b/Plugins/vf2fs.obj
new file mode 100644
index 0000000..4c0a7bd
--- /dev/null
+++ b/Plugins/vf2fs.obj
Binary files differ
diff --git a/Plugins/xbend.c b/Plugins/xbend.c
new file mode 100644
index 0000000..1ba9959
--- /dev/null
+++ b/Plugins/xbend.c
@@ -0,0 +1,99 @@
+#include <stdlib.h>
+#include <string.h>
+#include "plugin.h"
+
+void perform_effect(_frame f, _args a)
+{
+ byte pixelsize = f.pixelformat/8;
+ int x, y, pos, pos2, widthminuspos, widthminuspos2;
+ pixel8 *p, *tp=0;
+ char *t;
+
+ if(!a.s) return;
+
+ pos = atoi(a.s);
+ if(t = strstr(a.s, " "))
+ {
+ pos2 = atoi(t+1);
+ tp = (pixel8 *)malloc(f.width*pixelsize);
+ }
+
+ if(pos<0) pos=0;
+ if(pos>=f.width) pos=f.width-1;
+ if(pos2<0) pos2=0;
+ if(pos2>=f.width) pos2=f.width-1;
+
+ widthminuspos = f.width-pos;
+ widthminuspos2 = f.width-pos2;
+
+ for(y=0; y<f.height; y++)
+ {
+ p = scanline(f, y);
+ for(x=0; x<f.width; x++)
+ {
+ if(!tp)
+// p[x] = x<pos||pos-(x-pos)<0 ? p[x] : p[pos-(x-pos)];
+ memcpy(&p[x*pixelsize],
+ x<pos||pos-(x-pos)<0 ? &p[x*pixelsize] : &p[(pos-(x-pos))*pixelsize],
+ pixelsize);
+ else
+ {
+ memcpy(&tp[x*pixelsize],
+ &p[x<pos ? ((int)(x/(float)pos*pos2))*pixelsize
+ : (pos2+(int)(((x-pos)/(float)widthminuspos*widthminuspos2)))*pixelsize],
+ pixelsize);
+ }
+ }
+ if(tp) memcpy(p, tp, f.width*pixelsize);
+ }
+ if(tp) free(tp);
+}
+
+void perform_copy(_frame f1, _frame f2, _args a)
+{
+ byte pixelsize = f1.pixelformat/8;
+ int x, y, w, h, pos, pos2, widthminuspos, widthminuspos2, widthminusone;
+ pixel8 *p1, *p2, tp=0;
+ char *t;
+
+ if(!a.s) return;
+
+ pos = atoi(a.s);
+ if(t = strstr(a.s, " "))
+ {
+ pos2 = atoi(t+1);
+ tp = 1;
+ }
+
+ w = f1.width<f2.width ? f1.width : f2.width;
+ h = f1.height<f2.height ? f1.height : f2.height;
+
+ if(pos<0) pos=0;
+ if(pos>=w) pos=w-1;
+ if(pos2<0) pos2=0;
+ if(pos2>=w) pos2=w-1;
+
+ widthminuspos = f1.width-pos;
+ widthminuspos2 = f1.width-pos2;
+ widthminusone = w-1;
+
+ for(y=0; y<h; y++)
+ {
+ p1 = scanline(f1, y);
+ p2 = scanline(f2, y);
+ for(x=0; x<w; x++)
+ {
+ if(!tp)
+ memcpy(&p2[x*pixelsize],
+ x<pos||pos-(x-pos)<0 ? &p1[x*pixelsize] : &p1[(pos-(x-pos))*pixelsize],
+ pixelsize);
+ else
+ {
+ memcpy(&p2[x*pixelsize],
+ &p1[ x<pos ? ((int)(x/(float)pos*pos2))*pixelsize
+ : (pos2+(int)(((x-pos)/(float)widthminuspos*widthminuspos2)))*pixelsize],
+ pixelsize);
+ }
+ }
+ }
+}
diff --git a/Plugins/xbend.dll b/Plugins/xbend.dll
new file mode 100644
index 0000000..fb6f033
--- /dev/null
+++ b/Plugins/xbend.dll
Binary files differ
diff --git a/Plugins/xbend.exp b/Plugins/xbend.exp
new file mode 100644
index 0000000..99b93f3
--- /dev/null
+++ b/Plugins/xbend.exp
Binary files differ
diff --git a/Plugins/xbend.lib b/Plugins/xbend.lib
new file mode 100644
index 0000000..b54972e
--- /dev/null
+++ b/Plugins/xbend.lib
Binary files differ
diff --git a/Plugins/xbend.obj b/Plugins/xbend.obj
new file mode 100644
index 0000000..4854676
--- /dev/null
+++ b/Plugins/xbend.obj
Binary files differ
diff --git a/Plugins/xshred.c b/Plugins/xshred.c
new file mode 100644
index 0000000..6918e50
--- /dev/null
+++ b/Plugins/xshred.c
@@ -0,0 +1,20 @@
+#include <stdlib.h>
+#include "plugin.h"
+
+void perform_copy(_frame f1, _frame f2, _args a)
+{
+ int step, w, h, y, pixelsize=f1.pixelformat/8;
+
+ if(!a.s) return;
+
+ step = atoi(a.s);
+ if(step<=0) step=1;
+
+ w = f1.width<f2.width ? f1.width : f2.width;
+ h = f1.height<f2.height ? f1.height : f2.height;
+
+ for(y=0; y<h; y+=step)
+ {
+ memcpy(scanline(f2, y), scanline(f1, y), pixelsize*w);
+ }
+}
diff --git a/Plugins/xshred.dll b/Plugins/xshred.dll
new file mode 100644
index 0000000..9ddf030
--- /dev/null
+++ b/Plugins/xshred.dll
Binary files differ
diff --git a/Plugins/xshred.exp b/Plugins/xshred.exp
new file mode 100644
index 0000000..881e90e
--- /dev/null
+++ b/Plugins/xshred.exp
Binary files differ
diff --git a/Plugins/xshred.lib b/Plugins/xshred.lib
new file mode 100644
index 0000000..c90c4df
--- /dev/null
+++ b/Plugins/xshred.lib
Binary files differ
diff --git a/Plugins/xshred.obj b/Plugins/xshred.obj
new file mode 100644
index 0000000..484ad30
--- /dev/null
+++ b/Plugins/xshred.obj
Binary files differ
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..94e9e84
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,75 @@
+Framestein is software for processing images and video with Miller Puckette's Pure Data.
+For info on Pd, see http://www.pure-data.org.
+
+
+REQUIREMENTS
+
+Windows with DirectX version 7 or later and Pure Data.
+
+
+QUICKSTART
+
+Launch Framestein and Pd. From Pd, choose File|Open and try the examples in
+Patches-directory, starting with example-basics.pd.
+
+Look inside fs.* objects for more documentation.
+
+Later on, you'll need to start Pd with "pd -path c:\Framestein\Patches"
+to tell Pd where to find Framestein's abstractions and externals.
+
+
+LICENCE
+
+Copyright (c) 2001-2002 Juha Vehviläinen.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+
+AUTHORS & CONTRIBUTORS
+
+Juha Vehviläinen, jusu@iki.fi
+
+"Framestein" name and logo: Vesa Vehviläinen
+
+Pink Twins (http://pinktwins.com) are making some heavy use of Framestein.
+Check their site!
+
+Plugins by Olaf Matthes:
+http://www.akustische-kunst.de/puredata/framestein/framestein.html
+
+The girl in "virvezoom.jpg" and "head.avi" is Virve Lukka.
+Pictures under "Reija" are poor reproductions of paintings by Reija Palo-oja.
+Permission to use these pictures outside the included examples is denied.
+
+Framestein makes use of many fine components, namely:
+
+DelphiX by Hiroyuki Hori, http://www.yks.ne.jp/~hori/ <hori@ingjapan.ne.jp>
+FastLib by G-Soft, http://gfody.com <gfody@home.com>
+TDcAviPlay by Dream Company, http://www.dream-com.com <contact@dream-com.com>
+Intel Image Processing Library version 1.5 (ijl15.dll)
+C2PhotoShopHost by Antti Lukats, http://www.case2000.com
+AviWriter by Elliott Shevin (with large pieces of code stolen from Anders Melander)
+l2s from ZEXY by Johannes Zmoelnig, see ftp://iem.kug.ac.at/pd/Externals/ZEXY/.
+
+And, Pure Data by Miller Puckette and others, http://www.crca.ucsd.edu/~msp/software.html
+
+
+OFFICIAL LINKS
+
+download site:
+framestein.org
+
+List for receiving update information:
+http://groups.yahoo.com/group/framestein
+
+Send your feedback, ideas, plugins, ...
+jusu@iki.fi
+.
diff --git a/Reija/01.jpg b/Reija/01.jpg
new file mode 100644
index 0000000..ac17dd9
--- /dev/null
+++ b/Reija/01.jpg
Binary files differ
diff --git a/Reija/02.jpg b/Reija/02.jpg
new file mode 100644
index 0000000..681558a
--- /dev/null
+++ b/Reija/02.jpg
Binary files differ
diff --git a/Reija/03.jpg b/Reija/03.jpg
new file mode 100644
index 0000000..55dc52b
--- /dev/null
+++ b/Reija/03.jpg
Binary files differ
diff --git a/Reija/04.jpg b/Reija/04.jpg
new file mode 100644
index 0000000..d6f834a
--- /dev/null
+++ b/Reija/04.jpg
Binary files differ
diff --git a/Reija/05.jpg b/Reija/05.jpg
new file mode 100644
index 0000000..2716db4
--- /dev/null
+++ b/Reija/05.jpg
Binary files differ
diff --git a/Reija/06.jpg b/Reija/06.jpg
new file mode 100644
index 0000000..c2c8480
--- /dev/null
+++ b/Reija/06.jpg
Binary files differ
diff --git a/Reija/07.jpg b/Reija/07.jpg
new file mode 100644
index 0000000..14e045c
--- /dev/null
+++ b/Reija/07.jpg
Binary files differ
diff --git a/Reija/08.jpg b/Reija/08.jpg
new file mode 100644
index 0000000..77bde9c
--- /dev/null
+++ b/Reija/08.jpg
Binary files differ
diff --git a/Source/Filez.pas b/Source/Filez.pas
new file mode 100644
index 0000000..1560a77
--- /dev/null
+++ b/Source/Filez.pas
@@ -0,0 +1,87 @@
+unit Filez;
+{$I-}
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
+
+type
+ THandleFileEvent = procedure( const SearchRec:TSearchRec;
+ const FullPath: String ) of object;
+ // fullpath contains filepath+filename
+
+ TScanDir = class(TComponent)
+ private
+ { Private declarations }
+ FOnHandleFile : THandleFileEvent;
+ protected
+ { Protected declarations }
+ public
+ { Public declarations }
+ procedure Scan( const Path : String );
+ constructor Create( AOwner:TComponent ); override;
+ published
+ { Published declarations }
+ property OnHandleFile : THandleFileEvent read FOnHandleFile write FOnHandleFile;
+ end;
+
+ function FileSizeByName( const FileName:String ):Longint;
+
+procedure Register;
+
+implementation
+
+uses
+ Strz;
+
+function FileSizeByName( const FileName:String ):Longint;
+var
+ F:file of Byte;
+begin
+ Result := 0;
+ AssignFile(F, FileName);
+ Reset(F);
+ if IoResult<>0 then Exit;
+ Result := FileSize(F);
+ Close(F);
+end;
+
+constructor TScanDir.Create( AOwner:TComponent );
+begin
+ inherited Create( AOwner );
+
+ FOnHandleFile := nil;
+end;
+
+procedure TScanDir.Scan( const Path : String );
+var
+ SearchRec : TSearchRec;
+ Result : Integer;
+ S : String;
+begin
+ if not Assigned(FOnHandleFile) then
+ Exit;
+
+ S := VerifyBackSlash(Path);
+ Result := FindFirst( S+'*.*', faAnyFile, SearchRec);
+ if Result=0 then
+ repeat
+ if (SearchRec.Name='.') or (SearchRec.Name='..') then
+ Continue;
+
+ FOnHandleFile( SearchRec,
+ S+SearchRec.Name );
+
+ if SearchRec.Attr and faDirectory>0 then
+ Scan( S+SearchRec.Name );
+ until FindNext(SearchRec)<>0;
+end;
+
+procedure Register;
+begin
+ RegisterComponents('Labrz', [TScanDir]);
+end;
+
+end.
+
diff --git a/Source/Framestein.cfg b/Source/Framestein.cfg
new file mode 100644
index 0000000..cdbef8d
--- /dev/null
+++ b/Source/Framestein.cfg
@@ -0,0 +1,39 @@
+-$A+
+-$B-
+-$C+
+-$D+
+-$E-
+-$F-
+-$G+
+-$H+
+-$I+
+-$J+
+-$K-
+-$L+
+-$M-
+-$N+
+-$O+
+-$P+
+-$Q-
+-$R-
+-$S-
+-$T-
+-$U-
+-$V+
+-$W-
+-$X+
+-$YD
+-$Z1
+-cg
+-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
+-H+
+-W+
+-M
+-$M16384,1048576
+-K$00400000
+-LE"c:\program files\borland\delphi5\Projects\Bpl"
+-LN"c:\program files\borland\delphi5\Projects\Bpl"
+-U"\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32"
+-O"\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32"
+-I"\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32"
+-R"\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32"
diff --git a/Source/Framestein.dof b/Source/Framestein.dof
new file mode 100644
index 0000000..d217e75
--- /dev/null
+++ b/Source/Framestein.dof
@@ -0,0 +1,91 @@
+[Compiler]
+A=1
+B=0
+C=1
+D=1
+E=0
+F=0
+G=1
+H=1
+I=1
+J=1
+K=0
+L=1
+M=0
+N=1
+O=1
+P=1
+Q=0
+R=0
+S=0
+T=0
+U=0
+V=1
+W=0
+X=1
+Y=1
+Z=1
+ShowHints=1
+ShowWarnings=1
+UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
+[Linker]
+MapFile=0
+OutputObjs=0
+ConsoleApp=1
+DebugInfo=0
+RemoteSymbols=0
+MinStackSize=16384
+MaxStackSize=1048576
+ImageBase=4194304
+ExeDescription=
+[Directories]
+OutputDir=
+UnitOutputDir=
+PackageDLLOutputDir=
+PackageDCPOutputDir=
+SearchPath=\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32
+Packages=Vcl50;Vclx50;VclSmp50;Qrpt50;Vcldb50;Vclbde50;ibevnt50;vcldbx50;TeeUI50;TeeDB50;Tee50;TeeQR50;VCLIB50;vclie50;Inetdb50;Inet50;NMFast50;dclocx50;dclaxserver50;temppak;janDrawPack;pdpak
+Conditionals=
+DebugSourceDirs=
+UsePackages=0
+[Parameters]
+RunParams=
+HostApplication=
+[Language]
+ActiveLang=
+ProjectLang=$0000040B
+RootDir=
+[Version Info]
+IncludeVerInfo=1
+AutoIncBuild=1
+MajorVer=0
+MinorVer=1
+Release=1
+Build=77
+Debug=0
+PreRelease=1
+Special=0
+Private=0
+DLL=0
+Locale=1033
+CodePage=1252
+[Version Info Keys]
+CompanyName=
+FileDescription=
+FileVersion=0.1.1.77
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=Framestein
+ProductVersion=1.0.0.0
+Comments=
+[HistoryLists\hlUnitAliases]
+Count=1
+Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
+[HistoryLists\hlSearchPath]
+Count=4
+Item0=\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32
+Item1=\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost
+Item2=\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib
+Item3=\lab\common;C:\lab\common\DelphiX2000_0717-2\Source
diff --git a/Source/Framestein.dpr b/Source/Framestein.dpr
new file mode 100644
index 0000000..4dd00b2
--- /dev/null
+++ b/Source/Framestein.dpr
@@ -0,0 +1,46 @@
+{ Copyright (C) 2001-2002 Juha Vehviläinen
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.}
+
+program Framestein;
+
+{%ToDo 'Framestein.todo'}
+
+uses
+ Forms,
+ mainunit in 'mainunit.pas' {main},
+ fsframeunit in 'fsframeunit.pas' {fsframe},
+ fscopyunit in 'fscopyunit.pas' {fscopy},
+ fstextunit in 'fstextunit.pas' {fstext},
+ fsformunit in 'fsformunit.pas',
+ fsdrawunit in 'fsdrawunit.pas' {fsdraw},
+ effectsunit in 'effectsunit.pas',
+ pluginunit in 'pluginunit.pas',
+ logunit in 'logunit.pas' {log},
+ fsbrowserunit in 'fsbrowserunit.pas' {fsbrowser},
+ fsinfounit in 'fsinfounit.pas' {fsinfo},
+ configureunit in 'configureunit.pas' {configure},
+ pshostunit in 'pshostunit.pas',
+ fsaviunit in 'fsaviunit.pas' {FsAvi},
+ progressunit in 'progressunit.pas' {Progress};
+
+{$R *.RES}
+
+begin
+ Application.Initialize;
+ Application.Title := 'Framestein';
+ Application.CreateForm(Tmain, main);
+ Application.CreateForm(Tlog, log);
+ Application.CreateForm(Tconfigure, configure);
+ Application.CreateForm(TFsAvi, FsAvi);
+ Application.CreateForm(TProgress, Progress);
+ Application.Run;
+end.
+
diff --git a/Source/Framestein.dsk b/Source/Framestein.dsk
new file mode 100644
index 0000000..69b37b9
--- /dev/null
+++ b/Source/Framestein.dsk
@@ -0,0 +1,222 @@
+[Closed Files]
+File_0=SourceModule,'c:\lab\Framestein\mainunit.pas',0,1,417,14,429,1,0
+File_1=SourceModule,'c:\lab\Framestein\fsframeunit.pas',0,1,746,1,758,1,0
+File_2=SourceModule,'c:\lab\Framestein\fsaviunit.pas',0,1,45,12,56,0,0
+File_3=SourceModule,'c:\lab\Framestein\FsAviWriter.pas',0,1,312,15,323,0,0
+File_4=SourceModule,'C:\lab\Framestein\progressunit.pas',0,1,1,13,10,0,0
+File_5=SourceModule,'c:\lab\Framestein\logunit.pas',0,1,38,1,53,1,0
+File_6=SourceModule,'c:\lab\framestein\fsspeedbutton.pas',0,1,30,1,40,0,0
+File_7=SourceModule,'c:\lab\Framestein\fsbrowserunit.pas',0,1,93,1,105,0,0
+File_8=SourceModule,'c:\lab\Framestein\pluginunit.pas',0,1,134,1,147,0,0
+File_9=SourceModule,'c:\lab\common\Strz.pas',0,1,1,1,1,0,0
+
+[Modules]
+Count=0
+EditWindowCount=0
+
+[C:\Program Files\Borland\Delphi5\Projects\ProjectGroup1.bpg]
+FormState=0
+FormOnTop=0
+
+[c:\lab\Framestein\framestein.dpr]
+FormState=0
+FormOnTop=0
+
+[c:\lab\Framestein\Framestein.todo]
+FormState=0
+FormOnTop=0
+
+[Watches]
+Count=1
+Watch0='longint(pointer(_pshost.fdata+100+((i-1)*4)^)',256,0,18,1,0
+
+[Breakpoints]
+Count=0
+
+[AddressBreakpoints]
+Count=0
+
+[Main Window]
+Create=1
+Visible=1
+State=2
+Left=0
+Top=0
+Width=1024
+Height=105
+MaxLeft=-4
+MaxTop=-4
+MaxWidth=1032
+MaxHeight=105
+ClientWidth=1024
+ClientHeight=78
+
+[ProjectManager]
+Create=1
+Visible=0
+State=0
+Left=245
+Top=124
+Width=148
+Height=449
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=140
+ClientHeight=425
+TBDockHeight=494
+LRDockWidth=140
+Dockable=1
+
+[CPUWindow]
+Create=1
+Visible=0
+State=0
+Left=463
+Top=216
+Width=533
+Height=353
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=525
+ClientHeight=326
+DumpPane=79
+DisassemblyPane=187
+RegisterPane=231
+FlagPane=64
+
+[AlignmentPalette]
+Create=1
+Visible=1
+State=0
+Left=36
+Top=641
+Width=156
+Height=82
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=150
+ClientHeight=60
+
+[PropertyInspector]
+Create=1
+Visible=1
+State=0
+Left=0
+Top=97
+Width=241
+Height=639
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=231
+ClientHeight=613
+TBDockHeight=494
+LRDockWidth=190
+Dockable=0
+SplitPos=140
+ArrangeBy=Name
+SelectedItem=
+ExpandedItems=Anchors,Display,Font,Font.Style,Options,Pen,VertScrollBar
+HiddenCategories=
+ShowStatusBar=1
+
+[WatchWindow]
+Create=1
+Visible=0
+State=0
+Left=246
+Top=567
+Width=813
+Height=187
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=805
+ClientHeight=163
+TBDockHeight=65
+LRDockWidth=421
+Dockable=1
+
+[BreakpointWindow]
+Create=1
+Visible=0
+State=0
+Left=298
+Top=323
+Width=556
+Height=236
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=548
+ClientHeight=212
+TBDockHeight=197
+LRDockWidth=737
+Dockable=1
+Column0Width=100
+Column1Width=60
+Column2Width=240
+Column3Width=40
+Column4Width=75
+Column5Width=75
+
+[CallStackWindow]
+Create=1
+Visible=1
+State=0
+Left=365
+Top=303
+Width=290
+Height=161
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=282
+ClientHeight=137
+TBDockHeight=161
+LRDockWidth=294
+Dockable=1
+
+[ThreadStatusWindow]
+Create=1
+Visible=0
+State=0
+Left=193
+Top=107
+Width=624
+Height=152
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=616
+ClientHeight=128
+TBDockHeight=152
+LRDockWidth=624
+Dockable=1
+Column0Width=145
+Column1Width=100
+Column2Width=115
+Column3Width=250
+
+[ToDo List]
+Create=1
+Visible=1
+State=0
+Left=244
+Top=427
+Width=753
+Height=296
+MaxLeft=-1
+MaxTop=-1
+ClientWidth=745
+ClientHeight=272
+TBDockHeight=170
+LRDockWidth=896
+Dockable=0
+Column0Width=564
+Column1Width=30
+Column2Width=100
+Column3Width=70
+Column4Width=70
+SortOrder=0
+ShowHints=1
+ShowChecked=1
+
+[DockHosts]
+DockHostCount=0
+
diff --git a/Source/Framestein.res b/Source/Framestein.res
new file mode 100644
index 0000000..ee5ac49
--- /dev/null
+++ b/Source/Framestein.res
Binary files differ
diff --git a/Source/FsAviWriter.pas b/Source/FsAviWriter.pas
new file mode 100644
index 0000000..6373846
--- /dev/null
+++ b/Source/FsAviWriter.pas
@@ -0,0 +1,888 @@
+unit FsAviWriter;
+
+//
+// FSAviWriter - Framestein modified version of AviWriter.
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// //
+// AviWriter -- a component to create rudimentary AVI files //
+// by Elliott Shevin, with large pieces of code //
+// stolen from Anders Melander //
+// version 1.0. Please send comments, suggestions, and advice //
+// to shevine@aol.com. //
+/////////////////////////////////////////////////////////////////////////////
+// //
+// AviWriter will build an AVI file containing one stream of any //
+// number of TBitmaps, plus a single WAV file. //
+// //
+// Properties: //
+// Bitmaps : A TList of pointers to TBitmap objects which become //
+// frames of the AVI video stream. The component //
+// allocates and frees the TList, but the caller //
+// is responsible for managing the TBitmaps themselves. //
+// Manipulate the list as you would any other TList. //
+// At least one bitmap is required. //
+// Height, Width: //
+// The dimensions of the AVI video, in pixels. //
+// FrameTime: //
+// The duration of each video frame, in milliseconds. //
+// Stretch: If TRUE, each TBitmap on the Bitmaps list is //
+// stretches to the dimensions specified in Height //
+// and Width. If FALSE, each TBitmap is copied from //
+// its upper left corner without stretching. //
+// FileName: The name of the AVI file to be written. //
+// WAVFileName: //
+// The name of a WAV file which will become the audio //
+// stream for the AVI. Optional. //
+// //
+// Method: //
+// Write: Creates the AVI file named by FileName. //
+/////////////////////////////////////////////////////////////////////////////
+// Wish List: //
+// I'd like to be able to enhance this component in two ways, but //
+// don't know how. Please send ideas to shevine@aol.com. //
+// 1. So far, it's necessary to transform the video stream into //
+// and AVI file on disk. I'd prefer to do this in memory. //
+// 2. MIDI files for audio. //
+/////////////////////////////////////////////////////////////////////////////
+
+interface
+
+uses
+ Windows,Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ StdCtrls, DIB,
+{$ifdef VER90}
+ ole2;
+{$else}
+ ActiveX;
+{$endif}
+
+////////////////////////////////////////////////////////////////////////////////
+// //
+// Video for Windows //
+// //
+////////////////////////////////////////////////////////////////////////////////
+// //
+// Adapted from Thomas Schimming's VFW.PAS //
+// (c) 1996 Thomas Schimming, schimmin@iee1.et.tu-dresden.de //
+// (c) 1998,99 Anders Melander //
+// //
+////////////////////////////////////////////////////////////////////////////////
+// //
+// Ripped all COM/ActiveX stuff and added some AVI stream functions. //
+// //
+////////////////////////////////////////////////////////////////////////////////
+
+type
+
+ { TAVIFileInfoW record }
+
+ LONG = Longint;
+ PVOID = Pointer;
+
+// TAVIFileInfo dwFlag values
+const
+ AVIF_HASINDEX = $00000010;
+ AVIF_MUSTUSEINDEX = $00000020;
+ AVIF_ISINTERLEAVED = $00000100;
+ AVIF_WASCAPTUREFILE = $00010000;
+ AVIF_COPYRIGHTED = $00020000;
+ AVIF_KNOWN_FLAGS = $00030130;
+
+ AVIERR_UNSUPPORTED = $80044065; // MAKE_AVIERR(101)
+ AVIERR_BADFORMAT = $80044066; // MAKE_AVIERR(102)
+ AVIERR_MEMORY = $80044067; // MAKE_AVIERR(103)
+ AVIERR_INTERNAL = $80044068; // MAKE_AVIERR(104)
+ AVIERR_BADFLAGS = $80044069; // MAKE_AVIERR(105)
+ AVIERR_BADPARAM = $8004406A; // MAKE_AVIERR(106)
+ AVIERR_BADSIZE = $8004406B; // MAKE_AVIERR(107)
+ AVIERR_BADHANDLE = $8004406C; // MAKE_AVIERR(108)
+ AVIERR_FILEREAD = $8004406D; // MAKE_AVIERR(109)
+ AVIERR_FILEWRITE = $8004406E; // MAKE_AVIERR(110)
+ AVIERR_FILEOPEN = $8004406F; // MAKE_AVIERR(111)
+ AVIERR_COMPRESSOR = $80044070; // MAKE_AVIERR(112)
+ AVIERR_NOCOMPRESSOR = $80044071; // MAKE_AVIERR(113)
+ AVIERR_READONLY = $80044072; // MAKE_AVIERR(114)
+ AVIERR_NODATA = $80044073; // MAKE_AVIERR(115)
+ AVIERR_BUFFERTOOSMALL = $80044074; // MAKE_AVIERR(116)
+ AVIERR_CANTCOMPRESS = $80044075; // MAKE_AVIERR(117)
+ AVIERR_USERABORT = $800440C6; // MAKE_AVIERR(198)
+ AVIERR_ERROR = $800440C7; // MAKE_AVIERR(199)
+
+type
+ TAVIFileInfoW = record
+ dwMaxBytesPerSec, // max. transfer rate
+ dwFlags, // the ever-present flags
+ dwCaps,
+ dwStreams,
+ dwSuggestedBufferSize,
+
+ dwWidth,
+ dwHeight,
+
+ dwScale,
+ dwRate, // dwRate / dwScale == samples/second
+ dwLength,
+
+ dwEditCount: DWORD;
+
+ szFileType: array[0..63] of WideChar; // descriptive string for file type?
+ end;
+ PAVIFileInfoW = ^TAVIFileInfoW;
+
+// TAVIStreamInfo dwFlag values
+const
+ AVISF_DISABLED = $00000001;
+ AVISF_VIDEO_PALCHANGES= $00010000;
+ AVISF_KNOWN_FLAGS = $00010001;
+
+type
+ TAVIStreamInfoA = record
+ fccType,
+ fccHandler,
+ dwFlags, // Contains AVITF_* flags
+ dwCaps: DWORD;
+ wPriority,
+ wLanguage: WORD;
+ dwScale,
+ dwRate, // dwRate / dwScale == samples/second
+ dwStart,
+ dwLength, // In units above...
+ dwInitialFrames,
+ dwSuggestedBufferSize,
+ dwQuality,
+ dwSampleSize: DWORD;
+ rcFrame: TRect;
+ dwEditCount,
+ dwFormatChangeCount: DWORD;
+ szName: array[0..63] of AnsiChar;
+ end;
+ TAVIStreamInfo = TAVIStreamInfoA;
+ PAVIStreamInfo = ^TAVIStreamInfo;
+
+ { TAVIStreamInfoW record }
+
+ TAVIStreamInfoW = record
+ fccType,
+ fccHandler,
+ dwFlags, // Contains AVITF_* flags
+ dwCaps: DWORD;
+ wPriority,
+ wLanguage: WORD;
+ dwScale,
+ dwRate, // dwRate / dwScale == samples/second
+ dwStart,
+ dwLength, // In units above...
+ dwInitialFrames,
+ dwSuggestedBufferSize,
+ dwQuality,
+ dwSampleSize: DWORD;
+ rcFrame: TRect;
+ dwEditCount,
+ dwFormatChangeCount: DWORD;
+ szName: array[0..63] of WideChar;
+ end;
+
+ PAVIStream = pointer;
+ PAVIFile = pointer;
+ TAVIStreamList = array[0..0] of PAVIStream;
+ PAVIStreamList = ^TAVIStreamList;
+ TAVISaveCallback = function (nPercent: integer): LONG; stdcall;
+
+ TAVICompressOptions = packed record
+ fccType : DWORD;
+ fccHandler : DWORD;
+ dwKeyFrameEvery : DWORD;
+ dwQuality : DWORD;
+ dwBytesPerSecond : DWORD;
+ dwFlags : DWORD;
+ lpFormat : pointer;
+ cbFormat : DWORD;
+ lpParms : pointer;
+ cbParms : DWORD;
+ dwInterleaveEvery : DWORD;
+ end;
+ PAVICompressOptions = ^TAVICompressOptions;
+
+const
+ ICMF_CHOOSE_KEYFRAME = $0001; // show KeyFrame Every box
+ ICMF_CHOOSE_DATARATE = $0002; // show DataRate box
+ ICMF_CHOOSE_PREVIEW = $0004; // allow expanded preview dialog
+
+// Palette change data record
+const
+ RIFF_PaletteChange: DWORD = 1668293411;
+type
+ TAVIPalChange = packed record
+ bFirstEntry : byte;
+ bNumEntries : byte;
+ wFlags : WORD;
+ peNew : array[byte] of TPaletteEntry;
+ end;
+ PAVIPalChange = ^TAVIPalChange;
+
+ APAVISTREAM = array[0..1] of PAVISTREAM;
+ APAVICompressOptions = array[0..1] of PAVICompressOptions;
+ PAPAVICompressOptions = ^APAVICompressOptions;
+
+procedure AVIFileInit; stdcall;
+procedure AVIFileExit; stdcall;
+function AVIFileOpen(var ppfile: PAVIFile; szFile: PChar; uMode: UINT; lpHandler: pointer): HResult; stdcall;
+function AVIFileCreateStream(pfile: PAVIFile; var ppavi: PAVISTREAM; var psi: TAVIStreamInfo): HResult; stdcall;
+function AVIStreamSetFormat(pavi: PAVIStream; lPos: LONG; lpFormat: pointer; cbFormat: LONG): HResult; stdcall;
+function AVIStreamReadFormat(pavi: PAVIStream; lPos: LONG; lpFormat: pointer; var cbFormat: LONG): HResult; stdcall;
+function AVIStreamWrite(pavi: PAVIStream; lStart, lSamples: LONG; lpBuffer: pointer; cbBuffer: LONG; dwFlags: DWORD; var plSampWritten: LONG; var plBytesWritten: LONG): HResult; stdcall;
+function AVIStreamRelease(pavi: PAVISTREAM): ULONG; stdcall;
+function AVIFileRelease(pfile: PAVIFile): ULONG; stdcall;
+function AVIFileGetStream(pfile: PAVIFile; var ppavi: PAVISTREAM; fccType: DWORD; lParam: LONG): HResult; stdcall;
+function CreateEditableStream(var ppsEditable: PAVISTREAM; psSource: PAVISTREAM): HResult; stdcall;
+function AVISaveV(szFile: PChar; pclsidHandler: PCLSID; lpfnCallback: TAVISaveCallback;
+ nStreams: integer; pavi: APAVISTREAM; lpOptions: APAVICompressOptions): HResult; stdcall;
+function AVISaveOptions(hwnd: HWND; uiFlags: UINT; nStreams: integer;
+ ppavi: APAVISTREAM; plpOptions: PAPAVICOMPRESSOPTIONS): Boolean; stdcall; external 'avifil32.dll';
+function AVIMakeCompressedStream(var ppaviCompressed: PAVISTREAM;
+ ppaviSource: PAVISTREAM; plpOptions: APAVICompressOptions;
+ pclsidHandler: PCLSID): HResult; stdcall; external 'avifil32.dll';
+
+const
+ AVIERR_OK = 0;
+
+ AVIIF_LIST = $01;
+ AVIIF_TWOCC = $02;
+ AVIIF_KEYFRAME = $10;
+
+ streamtypeVIDEO = $73646976; // DWORD( 'v', 'i', 'd', 's' )
+ streamtypeAUDIO = $73647561; // DWORD( 'a', 'u', 'd', 's' )
+
+
+type
+ TPixelFormat = (pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit,
+ pf24bit, pf32bit, pfCustom);
+
+type
+ TAviWriter = class(TComponent)
+ private
+ TempFileName : string;
+ pFile : PAVIFile;
+ fHeight : integer;
+ fWidth : integer;
+ fStretch : boolean;
+ fFrameTime : integer;
+ fFileName : string;
+ fWavFileName : string;
+ VideoStream : PAVISTREAM;
+ AudioStream : PAVISTREAM;
+
+ Pstream : PAVISTREAM;
+ StreamInfo : TAVIStreamInfo;
+
+ CompOptions : APAVICompressOptions;
+ cmp1, cmp2 : TAviCompressOptions;
+
+ procedure AddVideo;
+ procedure AddAudio;
+ procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer;
+ var ImageSize: longInt; PixelFormat: TPixelFormat);
+ function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE;
+ var BitmapInfo; var Bits; PixelFormat: TPixelFormat): Boolean;
+ procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var Info: TBitmapInfoHeader;
+ PixelFormat: TPixelFormat);
+ procedure SetWavFileName(value : string);
+ { Private declarations }
+ protected
+ { Protected declarations }
+ public
+ Bitmaps : TList;
+ FramePos : Longint;
+ Prepared : Boolean;
+ fps : Integer;
+ constructor Create(AOwner : TComponent); override;
+ destructor Destroy; override;
+ procedure Write;
+ procedure Prepare;
+ procedure AddFrame(const DIB: TDIB);
+ procedure Finish;
+ { Public declarations }
+ published
+ property Height : integer read fHeight write fHeight;
+ property Width : integer read fWidth write fWidth;
+ property FrameTime: integer read fFrameTime write fFrameTime;
+ property Stretch : boolean read fStretch write fStretch;
+ property FileName : string read fFileName write fFileName;
+ property WavFileName : string read fWavFileName write SetWavFileName;
+ { Published declarations }
+ end;
+
+procedure Register;
+
+implementation
+
+uses
+ mainunit,
+ progressunit;
+
+function MAKEFOURCC(ch0, ch1, ch2, ch3: Char): Cardinal;
+begin
+ Result :=
+ (DWORD(BYTE(ch0))) or (DWORD(BYTE(ch1)) shl 8) or
+ (DWORD(BYTE(ch2)) shl 16) or (DWORD(BYTE(ch3)) shl 24 );
+end;
+
+constructor TAviWriter.Create(AOwner : TComponent);
+var
+ tempdir : string;
+ l : integer;
+begin
+ inherited Create(AOwner);
+ fHeight := screen.height div 10;
+ fWidth := screen.width div 10;
+ fFrameTime := 1000;
+ fStretch := true;
+ fFileName := '';
+ Bitmaps := TList.create;
+ AVIFileInit;
+
+ setlength(tempdir,MAX_PATH + 1);
+ l := GetTempPath(MAX_PATH,pchar(tempdir));
+ setlength(tempdir,l);
+ if copy(tempdir,length(tempdir),1) <> '\'
+ then tempdir := tempdir + '\';
+ TempFileName := tempdir + '~AWTemp.avi';
+ Prepared := False;
+
+ CompOptions[0] := @cmp1;
+ CompOptions[1] := @cmp2;
+
+ FillChar(cmp1, Sizeof(cmp1), 0);
+ FillChar(cmp2, Sizeof(cmp1), 0);
+
+ cmp1.fccType := streamtypeVIDEO;
+ cmp1.fccHandler := MakeFourCC('m','j','p','g');
+// cmp1.dwQuality :=
+
+ fps := 25;
+end;
+
+destructor TAviWriter.Destroy;
+begin
+ Bitmaps.free;
+ AviFileExit;
+ inherited;
+end;
+
+procedure TAviWriter.Write;
+var
+ Bitmap : TBitmap;
+ ExtBitmap : TBitmap;
+ nstreams : integer;
+ i : integer;
+ Streams : APAVISTREAM;
+ CompOptions : APAVICompressOptions;
+ AVIERR : integer;
+ refcount : integer;
+begin
+ AudioStream := nil;
+ VideoStream := nil;
+
+ // If no bitmaps are on the list, raise an error.
+ if Bitmaps.count < 1 then
+ raise Exception.Create('No bitmaps on the Bitmaps list');
+
+ // If anything on the Bitmaps TList is not a bitmap, raise
+ // an error.
+ for i := 0 to Bitmaps.count - 1 do begin
+ ExtBitmap := Bitmaps[i];
+ if not(ExtBitmap is TBitmap)
+ then raise Exception.Create('Bitmaps[' + inttostr(i)
+ + '] is not a TBitmap');
+ end;
+
+ try
+ AddVideo;
+
+ if WavFileName <> ''
+ then AddAudio;
+
+ // Create the output file.
+ if WavFileName <> ''
+ then nstreams := 2
+ else nstreams := 1;
+
+ Streams[0] := VideoStream;
+ Streams[1] := AudioStream;
+ CompOptions[0] := nil;
+ CompOptions[1] := nil;
+
+ AVIERR := AVISaveV(pchar(FileName),
+ nil, // File handler
+ nil, // Callback
+ nStreams, // Number of streams Streams, CompOptions); // Compress options for VideoStream if AVIERR <> AVIERR_OK then raise Exception.Create('Unable to write output file'); finally if assigned(VideoStream) then AviStreamRelease(VideoStream); if assigned(AudioStream)
+ then AviStreamRelease(AudioStream); try repeat
+ refcount := AviFileRelease(pFile);
+ until refcount <= 0;
+ except
+ end;
+
+ DeleteFile(TempFileName);
+ end;
+end;
+
+procedure TAviWriter.AddVideo;
+var
+ Pstream : PAVISTREAM;
+ StreamInfo : TAVIStreamInfo;
+ BitmapInfo : PBitmapInfoHeader;
+ BitmapInfoSize : Integer;
+ BitmapSize : longInt;
+ BitmapBits : pointer;
+ Bitmap : TBitmap;
+ ExtBitmap : TBitmap;
+ Samples_Written : LONG;
+ Bytes_Written : LONG;
+ AVIERR : integer;
+ i : integer;
+ startpos : DWORD;
+ len : DWORD;
+begin
+
+ // Open AVI file for write
+ if (AVIFileOpen(pFile, pchar(TempFileName),
+ OF_WRITE or OF_CREATE OR OF_SHARE_EXCLUSIVE, nil)
+ <> AVIERR_OK)
+ then
+ raise Exception.Create('Failed to create AVI video work file');
+
+ // Allocate the bitmap to which the bitmaps on the Bitmaps Tlist
+ // will be copied.
+ Bitmap := TBitmap.create;
+ Bitmap.Height := self.Height;
+ Bitmap.Width := self.Width;
+
+ // Write the stream header.
+ try
+ FillChar(StreamInfo, sizeof(StreamInfo), 0);
+
+ // Set frame rate and scale
+ StreamInfo.dwRate := 1000;
+ StreamInfo.dwScale := fFrameTime;
+ StreamInfo.fccType := streamtypeVIDEO;
+ StreamInfo.fccHandler := 0;
+ StreamInfo.dwFlags := 0;
+ StreamInfo.dwSuggestedBufferSize := 0;
+ StreamInfo.rcFrame.Right := self.width;
+ StreamInfo.rcFrame.Bottom := self.height;
+
+ // Open AVI data stream
+ if (AVIFileCreateStream(pFile, pStream, StreamInfo) <> AVIERR_OK) then
+ raise Exception.Create('Failed to create AVI video stream');
+
+ try
+ // Write the bitmaps to the stream.
+ for i := 0 to Bitmaps.count - 1 do begin
+ try
+ BitmapInfo := nil;
+ BitmapBits := nil;
+
+ // Copy the bitmap from the list to the AVI bitmap,
+ // stretching if desired. If the caller elects not to
+ // stretch, use the first pixel in the bitmap as a
+ // background color in case either the height or
+ // width of the source is smaller than the output.
+ // If Draw fails, do a StretchDraw.
+ ExtBitmap := Bitmaps[i];
+ if fStretch
+ then Bitmap.Canvas.StretchDraw
+ (Rect(0,0,self.width,self.height),ExtBitmap)
+ else try
+ with Bitmap.Canvas do begin
+ Brush.Color := ExtBitmap.Canvas.Pixels[0,0];
+ Brush.Style := bsSolid;
+ FillRect(Rect(0,0,Bitmap.Width,Bitmap.Height));
+ Draw(0,0,ExtBitmap);
+ end;
+ except
+ Bitmap.Canvas.StretchDraw
+ (Rect(0,0,self.width,self.height),ExtBitmap);
+ end;
+
+ // Determine size of DIB
+ InternalGetDIBSizes(Bitmap.Handle, BitmapInfoSize, BitmapSize, pf8bit);
+ if (BitmapInfoSize = 0) then
+ raise Exception.Create('Failed to retrieve bitmap info');
+
+ // Get DIB header and pixel buffers
+ GetMem(BitmapInfo, BitmapInfoSize);
+ GetMem(BitmapBits, BitmapSize);
+ InternalGetDIB
+ (Bitmap.Handle, 0, BitmapInfo^, BitmapBits^, pf8bit);
+
+ // On the first time through, set the stream format.
+ if i = 0 then
+ if (AVIStreamSetFormat(pStream, 0, BitmapInfo, BitmapInfoSize) <> AVIERR_OK) then
+ raise Exception.Create('Failed to set AVI stream format');
+
+ // Write frame to the video stream
+ AVIERR :=
+ AVIStreamWrite(pStream, i, 1, BitmapBits, BitmapSize, AVIIF_KEYFRAME,
+ Samples_Written, Bytes_Written);
+ if AVIERR <> AVIERR_OK then
+ raise Exception.Create
+ ('Failed to add frame to AVI. Err='
+ + inttohex(AVIERR,8));
+ finally
+ if (BitmapInfo <> nil) then
+ FreeMem(BitmapInfo);
+ if (BitmapBits <> nil) then
+ FreeMem(BitmapBits);
+ end;
+ end;
+
+ // Create the editable VideoStream from pStream.
+ if CreateEditableStream(VideoStream,pStream) <> AVIERR_OK then
+ raise Exception.Create
+ ('Could not create Video Stream');
+ finally
+ AviStreamRelease(pStream);
+ end;
+
+ finally
+ Bitmap.free;
+ end;
+end;
+
+procedure TAviWriter.AddAudio;
+var
+ InputFile : PAVIFILE;
+ hr : integer;
+ InputStream : PAVIStream;
+ avisClip : TAVISTREAMINFO;
+ l, selstart : DWORD;
+ pastecode : integer;
+begin
+ // Open the audio file.
+ hr := AVIFileOpen(InputFile, pchar(WavFileName),OF_READ, nil);
+ case hr of
+ 0: ;
+ AVIERR_BADFORMAT : raise Exception.Create('The file could not be read, indicating a corrupt file or an unrecognized format.');
+ AVIERR_MEMORY : raise Exception.Create('The file could not be opened because of insufficient memory.');
+ AVIERR_FILEREAD : raise Exception.Create('A disk error occurred while reading the audio file.');
+ AVIERR_FILEOPEN : raise Exception.Create('A disk error occurred while opening the audio file.');
+ REGDB_E_CLASSNOTREG : raise Exception.Create('According to the registry, the type of audio file specified in AVIFileOpen does not have a handler to process it.');
+ else raise Exception.Create('Unknown error opening audio file');
+ end;
+
+ // Open the audio stream.
+ try
+ if (AVIFileGetStream(InputFile, InputStream, 0, 0) <> AVIERR_OK) then
+ raise Exception.Create('Unable to get audio stream');
+
+ try
+ // Create AudioStream as a copy of InputStream
+ if (CreateEditableStream(AudioStream,InputStream) <> AVIERR_OK) then
+ raise Exception.Create('Failed to create editable AVI audio stream');
+ finally
+ AviStreamRelease(InputStream);
+ end;
+
+ finally
+ AviFileRelease(InputFile);
+ end;
+end;
+
+// --------------
+// InternalGetDIB
+// --------------
+// Converts a bitmap to a DIB of a specified PixelFormat.
+//
+// Parameters:
+// Bitmap The handle of the source bitmap.
+// Pal The handle of the source palette.
+// BitmapInfo The buffer that will receive the DIB's TBitmapInfo structure.
+// A buffer of sufficient size must have been allocated prior to
+// calling this function.
+// Bits The buffer that will receive the DIB's pixel data.
+// A buffer of sufficient size must have been allocated prior to
+// calling this function.
+// PixelFormat The pixel format of the destination DIB.
+//
+// Returns:
+// True on success, False on failure.
+//
+// Note: The InternalGetDIBSizes function can be used to calculate the
+// nescessary sizes of the BitmapInfo and Bits buffers.
+//
+function TAviWriter.InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE;
+ var BitmapInfo; var Bits; PixelFormat: TPixelFormat): Boolean;
+// From graphics.pas, "optimized" for our use
+var
+ OldPal : HPALETTE;
+ DC : HDC;
+begin
+ InitializeBitmapInfoHeader(Bitmap, TBitmapInfoHeader(BitmapInfo), PixelFormat);
+ OldPal := 0;
+ DC := CreateCompatibleDC(0);
+ try
+ if (Palette <> 0) then
+ begin
+ OldPal := SelectPalette(DC, Palette, False);
+ RealizePalette(DC);
+ end;
+ Result := (GetDIBits(DC, Bitmap, 0, abs(TBitmapInfoHeader(BitmapInfo).biHeight),
+ @Bits, TBitmapInfo(BitmapInfo), DIB_RGB_COLORS) <> 0);
+ finally
+ if (OldPal <> 0) then
+ SelectPalette(DC, OldPal, False);
+ DeleteDC(DC);
+ end;
+end;
+
+
+// -------------------
+// InternalGetDIBSizes
+// -------------------
+// Calculates the buffer sizes nescessary for convertion of a bitmap to a DIB
+// of a specified PixelFormat.
+// See the GetDIBSizes API function for more info.
+//
+// Parameters:
+// Bitmap The handle of the source bitmap.
+// InfoHeaderSize
+// The returned size of a buffer that will receive the DIB's
+// TBitmapInfo structure.
+// ImageSize The returned size of a buffer that will receive the DIB's
+// pixel data.
+// PixelFormat The pixel format of the destination DIB.
+//
+procedure TAviWriter.InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer;
+ var ImageSize: longInt; PixelFormat: TPixelFormat);
+// From graphics.pas, "optimized" for our use
+var
+ Info : TBitmapInfoHeader;
+begin
+ InitializeBitmapInfoHeader(Bitmap, Info, PixelFormat);
+ // Check for palette device format
+ if (Info.biBitCount > 8) then
+ begin
+ // Header but no palette
+ InfoHeaderSize := SizeOf(TBitmapInfoHeader);
+ if ((Info.biCompression and BI_BITFIELDS) <> 0) then
+ Inc(InfoHeaderSize, 12);
+ end else
+ // Header and palette
+ InfoHeaderSize := SizeOf(TBitmapInfoHeader) + SizeOf(TRGBQuad) * (1 shl Info.biBitCount);
+ ImageSize := Info.biSizeImage;
+end;
+
+// --------------------------
+// InitializeBitmapInfoHeader
+// --------------------------
+// Fills a TBitmapInfoHeader with the values of a bitmap when converted to a
+// DIB of a specified PixelFormat.
+//
+// Parameters:
+// Bitmap The handle of the source bitmap.
+// Info The TBitmapInfoHeader buffer that will receive the values.
+// PixelFormat The pixel format of the destination DIB.
+//
+{$IFDEF BAD_STACK_ALIGNMENT}
+ // Disable optimization to circumvent optimizer bug...
+ {$IFOPT O+}
+ {$DEFINE O_PLUS}
+ {$O-}
+ {$ENDIF}
+{$ENDIF}
+
+
+procedure TAviWriter.InitializeBitmapInfoHeader(Bitmap: HBITMAP; var Info: TBitmapInfoHeader;
+ PixelFormat: TPixelFormat);
+// From graphics.pas, "optimized" for our use
+var
+ DIB : TDIBSection;
+ Bytes : Integer;
+ function AlignBit(Bits, BitsPerPixel, Alignment: Cardinal): Cardinal;
+ begin
+ Dec(Alignment);
+ Result := ((Bits * BitsPerPixel) + Alignment) and not Alignment;
+ Result := Result SHR 3;
+ end;
+begin
+ DIB.dsbmih.biSize := 0;
+ Bytes := GetObject(Bitmap, SizeOf(DIB), @DIB);
+ if (Bytes = 0) then
+ raise Exception.Create('Invalid bitmap');
+// Error(sInvalidBitmap);
+
+ if (Bytes >= (sizeof(DIB.dsbm) + sizeof(DIB.dsbmih))) and
+ (DIB.dsbmih.biSize >= sizeof(DIB.dsbmih)) then
+ Info := DIB.dsbmih
+ else
+ begin
+ FillChar(Info, sizeof(Info), 0);
+ with Info, DIB.dsbm do
+ begin
+ biSize := SizeOf(Info);
+ biWidth := bmWidth;
+ biHeight := bmHeight;
+ end;
+ end;
+ case PixelFormat of
+ pf1bit: Info.biBitCount := 1;
+ pf4bit: Info.biBitCount := 4;
+ pf8bit: Info.biBitCount := 8;
+ pf24bit: Info.biBitCount := 24;
+ else
+// Error(sInvalidPixelFormat);
+ raise Exception.Create('Invalid pixel foramt');
+ // Info.biBitCount := DIB.dsbm.bmBitsPixel * DIB.dsbm.bmPlanes;
+ end;
+ Info.biPlanes := 1;
+ Info.biCompression := BI_RGB; // Always return data in RGB format
+ Info.biSizeImage := AlignBit(Info.biWidth, Info.biBitCount, 32) * Cardinal(abs(Info.biHeight));
+end;
+{$IFDEF O_PLUS}
+ {$O+}
+ {$UNDEF O_PLUS}
+{$ENDIF}
+
+procedure TAviWriter.SetWavFileName(value : string);
+begin
+ if lowercase(fWavFileName) <> lowercase(value)
+ then if lowercase(ExtractFileExt(value)) <> '.wav'
+ then raise Exception.Create('WavFileName must name a file '
+ + 'with the .wav extension')
+ else fWavFileName := value;
+end;
+
+
+procedure Register;
+begin
+ RegisterComponents('Labrz', [TAviWriter]);
+end;
+
+ procedure AVIFileInit; stdcall; external 'avifil32.dll' name 'AVIFileInit';
+ procedure AVIFileExit; stdcall; external 'avifil32.dll' name 'AVIFileExit';
+ function AVIFileOpen; external 'avifil32.dll' name 'AVIFileOpenA';
+ function AVIFileCreateStream; external 'avifil32.dll' name 'AVIFileCreateStreamA';
+ function AVIStreamSetFormat; external 'avifil32.dll' name 'AVIStreamSetFormat';
+ function AVIStreamReadFormat; external 'avifil32.dll' name 'AVIStreamReadFormat';
+ function AVIStreamWrite; external 'avifil32.dll' name 'AVIStreamWrite';
+ function AVIStreamRelease; external 'avifil32.dll' name 'AVIStreamRelease';
+ function AVIFileRelease; external 'avifil32.dll' name 'AVIFileRelease';
+ function AVIFileGetStream; external 'avifil32.dll' name 'AVIFileGetStream';
+ function CreateEditableStream; external 'avifil32.dll' name 'CreateEditableStream';
+ function AVISaveV; external 'avifil32.dll' name 'AVISaveV';
+
+procedure TAviWriter.Prepare;
+begin
+ if Prepared then begin
+ main.Post('Finishing previous file..');
+ Finish;
+ end;
+
+ AudioStream := nil;
+ VideoStream := nil;
+
+ if (AVIFileOpen(pFile, pchar(TempFileName),
+ OF_WRITE or OF_CREATE or OF_SHARE_EXCLUSIVE, nil) <> AVIERR_OK) then
+ raise Exception.Create('Failed to create AVI video work file');
+
+ FillChar(StreamInfo, sizeof(StreamInfo), 0);
+
+ // Set frame rate and scale
+ StreamInfo.dwRate := fps*1000;
+ StreamInfo.dwScale := fFrameTime;
+ StreamInfo.fccType := streamtypeVIDEO;
+ StreamInfo.fccHandler := 0;
+ StreamInfo.dwFlags := 0;
+ StreamInfo.dwSuggestedBufferSize := 0;
+ StreamInfo.rcFrame.Right := self.width;
+ StreamInfo.rcFrame.Bottom := self.height;
+
+ // Open AVI data stream
+ if (AVIFileCreateStream(pFile, pStream, StreamInfo) <> AVIERR_OK) then
+ raise Exception.Create('Failed to create AVI video stream');
+
+ FramePos := 0;
+ Prepared := True;
+end;
+
+procedure TAviWriter.AddFrame(const DIB: TDIB);
+var
+ Samples_Written : LONG;
+ Bytes_Written : LONG;
+ AVIERR : integer;
+begin
+ if not Prepared then begin
+ main.Post('fs.avi: internal error, not prepared to add frame.');
+ Exit;
+ end;
+
+ // On the first time through, set the stream format.
+ if FramePos = 0 then begin
+ if (AVIStreamSetFormat(pStream, 0, DIB.BitmapInfo, DIB.BitmapInfoSize) <> AVIERR_OK) then
+ raise Exception.Create('Failed to set AVI stream format');
+ end;
+
+ // Write frame to the video stream
+ AVIERR := AVIStreamWrite(pStream, FramePos, 1, DIB.PBits, DIB.Size, AVIIF_KEYFRAME,
+ Samples_Written, Bytes_Written);
+
+ Inc(FramePos);
+
+ if AVIERR <> AVIERR_OK then
+ raise Exception.Create('Failed to add frame to AVI. Err='+
+ inttohex(AVIERR,8));
+end;
+
+function avisavecallback(nPercent: UINT): ULONG; stdcall;
+begin
+// Write('fs.avi: '+IntToStr(nPercent)+'%'+#13);
+ Progress.pb1.Position := nPercent;
+ Result := AVIERR_OK;
+end;
+
+procedure TAviWriter.Finish;
+var
+ nstreams: Integer;
+ Streams : APAVISTREAM;
+ AVIERR : integer;
+ refcount : integer;
+begin
+ if not Prepared then begin
+ main.Post('fs.avi: nothing to write.');
+ Exit;
+ end;
+
+ if CreateEditableStream(VideoStream,pStream) <> AVIERR_OK then
+ raise Exception.Create('Could not create Video Stream');
+
+ AviStreamRelease(pStream);
+
+ nstreams := 1;
+
+ Streams[0] := VideoStream;
+ Streams[1] := nil;//AudioStream;
+
+ if AVISaveOptions(0, ICMF_CHOOSE_PREVIEW, nStreams, Streams, @CompOptions) then begin
+
+ Progress.Show;
+
+ AVIERR := AVISaveV(pchar(FileName),
+ nil, // File handler
+ @avisavecallback, // Callback
+ nStreams, // Number of streams Streams, CompOptions); // Compress options for VideoStream Progress.Hide; // I get some strange error but the file is always ok so... screw it { if AVIERR <> AVIERR_OK then raise Exception.Create('Error on write - check output file.'); } if assigned(VideoStream) then AviStreamRelease(VideoStream); if assigned(AudioStream)
+ then AviStreamRelease(AudioStream); try repeat
+ refcount := AviFileRelease(pFile);
+ until refcount <= 0;
+ except
+ end;
+
+ DeleteFile(TempFileName);
+
+ Prepared := False;
+ end;
+end;
+
+end.
+
diff --git a/Source/GPL.txt b/Source/GPL.txt
new file mode 100644
index 0000000..14db8fc
--- /dev/null
+++ b/Source/GPL.txt
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/Source/README.txt b/Source/README.txt
new file mode 100644
index 0000000..4037c52
--- /dev/null
+++ b/Source/README.txt
@@ -0,0 +1,36 @@
+To compile:
+
+
+- Install DelphiX by Hiroyuki Hori, http://www.yks.ne.jp/~hori/ <hori@ingjapan.ne.jp>
+
+The above link doesn't always work, try these:
+
+http://turbo.gamedev.net/DelphiX2000_0717a.zip
+http://turbo.gamedev.net/delphix.asp
+
+
+- Install FastLib by G-Soft, http://gfody.com <gfody@home.com>
+
+
+- Install TScanDir in Filez.pas (in this directory).
+
+
+- Correct your Search path and compile!
+
+
+- Framestein needs ijl15.dll (included in Framestein-directory) to load/save jpegs
+ and to send jpeg-compressed frames thru network.
+
+
+--- note to versions >= 0.27 ---
+
+
+The photoshop filter host functionality is based on commercial code from http://www.case2000.com.
+Due to my modifications the original component won't compile with Framestein and
+I don't have the permission to release my modified version.
+
+To compile Fs without the PSHost, ignore errors on C2PhotoShopHost, and comment out
+the implementation in pshostunit.pas.
+
+I'm planning a .dll of my version of the component to rid of this problem.
+Mail me for info.
diff --git a/Source/Strz.pas b/Source/Strz.pas
new file mode 100644
index 0000000..85ad4a7
--- /dev/null
+++ b/Source/Strz.pas
@@ -0,0 +1,182 @@
+unit Strz;
+
+interface
+
+uses
+ Windows;
+
+type
+ CharSet = set of Char;
+
+// General
+function MyStrToInt(const S: String): Integer; // some special checking, no exceptions
+function MyStrToFloat(const S: String): Extended; // some special checking, no exceptions
+function StrToRect(const S: String): TRect;
+function Long2Str(L : LongInt) : string;
+function SearchAndReplace( S, Old, New:String ):String;
+function WordCount(S : string; WordDelims : CharSet) : Integer;
+ {-Given a set of word delimiters, return number of words in S}
+function ExtractWord(N : Integer; S : string; WordDelims : CharSet) : string;
+ {-Given a set of word delimiters, return the N'th word in S}
+
+// Filez
+function VerifyBackSlash( const FileName:String ):String;
+
+implementation
+
+uses
+ Classes, SysUtils;
+
+function StrToRect(const S: String): TRect;
+var
+ i: Integer;
+begin
+ Result := Rect(0, 0, 0, 0);
+ if S='' then Exit;
+ i := WordCount(S, [' ']);
+ Result.Left := MyStrToInt(ExtractWord(1, S, [' ']));
+ if i>1 then
+ Result.Top := MyStrToInt(ExtractWord(2, S, [' ']));
+ if i>2 then
+ Result.Right := MyStrToInt(ExtractWord(3, S, [' ']));
+ if i>3 then
+ Result.Bottom := MyStrToInt(ExtractWord(4, S, [' ']));
+end;
+
+function MyStrToInt(const S: String): Integer;
+var
+ St: String;
+begin
+ Result := 0;
+ if (S='') or (S='-') or (S='0') then Exit;
+ try
+ Result := StrToInt(S);
+ except
+ St := S;
+ while Pos('.', St)>0 do
+ St[Pos('.', St)] := ',';
+ try Result := Trunc(StrToFloat(St)); except end;
+ end;
+end;
+
+function MyStrToFloat(const S: String): Extended;
+var
+ St: String;
+ i: Integer;
+begin
+ Result := 0;
+ if (S='') or (S='-') or (S='0') then Exit;
+ St := S;
+ i := Pos('.', St);
+ if i>0 then
+ St[i] := ',';
+ try
+ Result := StrToFloat(St);
+ except
+ end;
+end;
+
+function VerifyBackSlash( const FileName:String ):String;
+begin
+ if FileName[Length(FileName)]='\' then
+ Result := FileName
+ else
+ Result := FileName + '\';
+end;
+
+function Long2Str(L : LongInt) : string;
+ {-Convert a long/word/integer/byte/shortint to a string}
+var
+ S : string;
+begin
+ Str(L, S);
+ Long2Str := S;
+end;
+
+{-----}
+
+ function WordCount(S : string; WordDelims : CharSet) : Integer;
+ {-Given a set of word delimiters, return number of words in S}
+ var
+ {I,} Count : Integer; {!!.12}
+ I, SLen : Word; {!!.12}
+ begin
+ Count := 0;
+ I := 1;
+ SLen:=Length(S);
+
+ while I <= SLen do begin
+ {skip over delimiters}
+ while (I <= SLen) and (S[I] in WordDelims) do
+ Inc(I);
+
+ {if we're not beyond end of S, we're at the start of a word}
+ if I <= SLen then
+ Inc(Count);
+
+ {find the end of the current word}
+ while (I <= SLen) and not(S[I] in WordDelims) do
+ Inc(I);
+ end;
+
+ WordCount := Count;
+ end;
+
+ function ExtractWord(N : Integer; S : string; WordDelims : CharSet) : string;
+ {-Given a set of word delimiters, return the N'th word in S}
+ var
+ I : Word; {!!.12}
+ Count, Len : Integer;
+ SLen : Longint;
+ Str : String;
+ begin
+ Count := 0;
+ I := 1;
+ Len := 0;
+ Str := '';
+ SLen := Length(S);
+
+// ExtractWord[0] := #0;
+
+ while (I <= SLen) and (Count <> N) do begin
+ {skip over delimiters}
+ while (I <= SLen) and (S[I] in WordDelims) do
+ Inc(I);
+
+ {if we're not beyond end of S, we're at the start of a word}
+ if I <= SLen then
+ Inc(Count);
+
+ {find the end of the current word}
+ while (I <= SLen) and not(S[I] in WordDelims) do begin
+ {if this is the N'th word, add the I'th character to Tmp}
+ if Count = N then begin
+ Inc(Len);
+ SetLength(Str, Len);
+// ExtractWord[0] := Char(Len);
+ Str[Len] := S[I];
+// ExtractWord[Len] := S[I];
+ end;
+
+ Inc(I);
+ end;
+ end;
+ ExtractWord := Str;
+ end;
+
+function SearchAndReplace( S, Old, New:String ):String;
+var
+ Ts : String;
+ i : Integer;
+begin
+ Ts := S;
+ i := Pos(Old, Ts);
+ while i>0 do begin
+ Delete(Ts, i, Length(Old));
+ Insert(New, Ts, i);
+ i := Pos(Old, Ts);
+ end;
+ SearchAndReplace := Ts;
+end;
+
+end.
diff --git a/Source/configureunit.dfm b/Source/configureunit.dfm
new file mode 100644
index 0000000..5a9e46d
--- /dev/null
+++ b/Source/configureunit.dfm
@@ -0,0 +1,157 @@
+object configure: Tconfigure
+ Left = 317
+ Top = 185
+ Width = 443
+ Height = 351
+ BorderWidth = 4
+ Caption = 'Configuration'
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ OldCreateOrder = False
+ Position = poScreenCenter
+ OnCreate = FormCreate
+ PixelsPerInch = 96
+ TextHeight = 13
+ object PageControl1: TPageControl
+ Left = 0
+ Top = 0
+ Width = 427
+ Height = 275
+ ActivePage = TSConnections
+ Align = alClient
+ TabOrder = 0
+ object TSConnections: TTabSheet
+ Caption = 'Connections'
+ object Label1: TLabel
+ Left = 16
+ Top = 36
+ Width = 114
+ Height = 13
+ Caption = 'Host running Pure Data:'
+ end
+ object Label2: TLabel
+ Left = 16
+ Top = 60
+ Width = 95
+ Height = 13
+ Caption = 'Listen to Pd on port:'
+ end
+ object Label3: TLabel
+ Left = 16
+ Top = 84
+ Width = 103
+ Height = 13
+ Caption = 'Pd is listening on port:'
+ end
+ object Label4: TLabel
+ Left = 16
+ Top = 112
+ Width = 385
+ Height = 13
+ Caption =
+ 'NOTE: if you change the default ports, you need to modify fs.mai' +
+ 'n.pd accordingly.'
+ end
+ object Label5: TLabel
+ Left = 16
+ Top = 164
+ Width = 194
+ Height = 13
+ Caption = 'Listen to Framestein connections on port:'
+ end
+ object EditPdHost: TEdit
+ Left = 152
+ Top = 32
+ Width = 225
+ Height = 21
+ Ctl3D = True
+ ParentCtl3D = False
+ TabOrder = 0
+ Text = 'localhost'
+ end
+ object EditPdReceivePort: TEdit
+ Left = 152
+ Top = 56
+ Width = 225
+ Height = 21
+ Ctl3D = True
+ ParentCtl3D = False
+ TabOrder = 1
+ Text = '6001'
+ end
+ object EditPdSendPort: TEdit
+ Left = 152
+ Top = 80
+ Width = 225
+ Height = 21
+ Ctl3D = True
+ ParentCtl3D = False
+ TabOrder = 2
+ Text = '6002'
+ end
+ object EditFsPort: TEdit
+ Left = 224
+ Top = 160
+ Width = 153
+ Height = 21
+ Ctl3D = True
+ ParentCtl3D = False
+ TabOrder = 3
+ Text = '6010'
+ end
+ object CBEnableFSConns: TCheckBox
+ Left = 224
+ Top = 184
+ Width = 97
+ Height = 17
+ Caption = 'Enable'
+ TabOrder = 4
+ end
+ end
+ object TSGeneral: TTabSheet
+ Caption = 'General'
+ ImageIndex = 1
+ object CBDockMain: TCheckBox
+ Left = 16
+ Top = 36
+ Width = 377
+ Height = 17
+ Caption = 'Dock main window to Pd on connect'
+ TabOrder = 0
+ end
+ end
+ end
+ object Panel1: TPanel
+ Left = 0
+ Top = 275
+ Width = 427
+ Height = 41
+ Align = alBottom
+ BevelOuter = bvNone
+ TabOrder = 1
+ object ButtonOk: TButton
+ Left = 8
+ Top = 8
+ Width = 75
+ Height = 25
+ Caption = 'Ok'
+ Default = True
+ TabOrder = 0
+ OnClick = ButtonOkClick
+ end
+ object ButtonCancel: TButton
+ Left = 96
+ Top = 8
+ Width = 75
+ Height = 25
+ Cancel = True
+ Caption = 'Cancel'
+ TabOrder = 1
+ OnClick = ButtonCancelClick
+ end
+ end
+end
diff --git a/Source/configureunit.pas b/Source/configureunit.pas
new file mode 100644
index 0000000..88dff73
--- /dev/null
+++ b/Source/configureunit.pas
@@ -0,0 +1,120 @@
+unit configureunit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ StdCtrls, ExtCtrls, ComCtrls;
+
+type
+ Tconfigure = class(TForm)
+ PageControl1: TPageControl;
+ TSConnections: TTabSheet;
+ Panel1: TPanel;
+ ButtonOk: TButton;
+ ButtonCancel: TButton;
+ Label1: TLabel;
+ EditPdHost: TEdit;
+ Label2: TLabel;
+ EditPdReceivePort: TEdit;
+ Label3: TLabel;
+ EditPdSendPort: TEdit;
+ Label4: TLabel;
+ Label5: TLabel;
+ EditFsPort: TEdit;
+ CBEnableFSConns: TCheckBox;
+ TSGeneral: TTabSheet;
+ CBDockMain: TCheckBox;
+ procedure ButtonCancelClick(Sender: TObject);
+ procedure ButtonOkClick(Sender: TObject);
+ procedure FormCreate(Sender: TObject);
+ private
+ { Private declarations }
+ public
+ { Public declarations }
+ procedure Execute;
+ end;
+
+var
+ configure: Tconfigure;
+
+implementation
+
+uses
+ Registry,
+ mainunit;
+
+{$R *.DFM}
+
+procedure Tconfigure.ButtonOkClick(Sender: TObject);
+var
+ Reg: TRegistry;
+begin
+ Reg := TRegistry.Create;
+ Reg.RootKey := HKEY_CURRENT_USER;
+
+ main.PdHost := EditPdHost.Text;
+ main.PdReceivePort := StrToInt(EditPdReceivePort.Text);
+ main.PdSendPort := StrToInt(EditPdSendPort.Text);
+ main.FSPort := StrToInt(EditFsPort.Text);
+ main.EnableFSConns := CBEnableFSConns.Checked;
+ main.DockMain := CBDockMain.Checked;
+
+ try
+ if Reg.OpenKey('\Software\Framestein', True) then begin
+ Reg.WriteString('PdHost', main.PdHost);
+ Reg.WriteInteger('PDReceivePort', main.PDReceivePort);
+ Reg.WriteInteger('PDSendPort', main.PDSendPort);
+ Reg.WriteInteger('FSPort', main.FSPort);
+ Reg.WriteBool('EnableFSConns', main.EnableFSConns);
+ Reg.WriteBool('DockMain', main.DockMain);
+ end;
+ except
+ end;
+
+ Reg.CloseKey;
+ Reg.Free;
+
+ main.ss1.Active := False;
+ main.ss1.Port := main.PDReceivePort;
+ main.ss1.Active := True;
+
+ main.csToPd.Active := False;
+ main.csToPd.Host := main.PdHost;
+ main.csToPd.Port := main.PdSendPort;
+ main.csToPd.Active := True;
+
+ main.ssfs.Active := False;
+ main.ssfs.Port := main.FSPort;
+ main.ssfs.Active := main.EnableFSConns;
+
+ ModalResult := mrOk;
+end;
+
+procedure Tconfigure.ButtonCancelClick(Sender: TObject);
+begin
+ ModalResult := mrCancel;
+end;
+
+procedure Tconfigure.Execute;
+begin
+ // load values from main
+ EditPdHost.Text := main.PdHost;
+ if EditPdHost.Text='' then EditPdHost.Text:='localhost';
+ EditPdReceivePort.Text := IntToStr(main.PdReceivePort);
+ EditPdSendPort.Text := IntToStr(main.PdSendPort);
+ EditFsPort.Text := IntToStr(main.FSPort);
+ CBEnableFSConns.Checked := main.EnableFSConns;
+ CBDockMain.Checked := main.DockMain;
+ // show
+ ShowModal;
+end;
+
+procedure Tconfigure.FormCreate(Sender: TObject);
+begin
+ if main.RunConfig then
+ Execute;
+end;
+
+end.
+
diff --git a/Source/dc.inc b/Source/dc.inc
new file mode 100644
index 0000000..a90d6f3
--- /dev/null
+++ b/Source/dc.inc
@@ -0,0 +1,42 @@
+{$O+,A+,W-,R-,Q-,B-,X+,T-,P+,H+,J+,C-}
+
+//--------------- Dream Company section ----------------------------
+
+{$IFDEF VER93}
+{$DEFINE BCB}
+{$DEFINE CPB1}
+{$ENDIF}
+
+{$IFNDEF VER80}
+ {$IFNDEF VER90}
+ {$IFNDEF VER93}
+ {$IFDEF VER110}
+ {$DEFINE CPB3} { C++ Builder 3.0 or higher}
+ {$DEFINE BCB}
+ {$ENDIF}
+ {$DEFINE D3} { Delphi 3.0 or higher }
+ {$ENDIF}
+ {$ENDIF}
+{$ENDIF}
+
+{$IFDEF VER120}
+ {$DEFINE D4}
+ {$DEFINE D3}
+ {$DEFINE CPB3}
+{$ENDIF}
+
+{$IFDEF VER125}
+{$DEFINE CPB4}
+{$DEFINE D4}
+{$DEFINE D3}
+{$DEFINE CPB3}
+{$DEFINE BCB}
+{$ENDIF}
+
+{$IFDEF VER130}
+{$DEFINE CPB4}
+{$DEFINE D4}
+{$DEFINE D3}
+{$DEFINE CPB3}
+{$DEFINE D5}
+{$ENDIF}
diff --git a/Source/effectsunit.pas b/Source/effectsunit.pas
new file mode 100644
index 0000000..791eeae
--- /dev/null
+++ b/Source/effectsunit.pas
@@ -0,0 +1,109 @@
+{ Copyright (C) 2001 Juha Vehviläinen
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.}
+
+unit effectsunit;
+{This unit demonstrates how to work on the pixel level..
+
+ If you're adding an effect, all it takes is a couple of lines in
+ fsframeunit.pas to call your routine. Look for 'scramble' there
+ to see how.
+
+ If you're adding a new copymode, look for all occurences of
+ 'dsBlend' in fscopyunit.pas to see how to do that.
+
+ Also see everything in Framestein\Plugins-directory, you can write
+ effects and copymodes as plugins and never recompile framestein..
+ or touch the pascal code. This is likely the way I'll be doing them
+ from now on, to keep the program "core" as simple and small as possible..
+}
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, DirectX, DXDraws;
+
+procedure scramble(const d: TDirectDrawSurface);
+procedure blend(const d1, d2: TDirectDrawSurface; const amount: Extended);
+
+implementation
+
+function ScanLine16(const sd: TDDSurfaceDesc; const y: Integer): Pointer;
+begin
+ Result := Pointer(Integer(sd.lpSurface) + y*sd.lPitch);
+end;
+
+procedure scramble(const d: TDirectDrawSurface);
+var
+ x,y: Integer;
+ p16: PWordArray;
+ sd: TDDSurfaceDesc;
+begin
+ if (d.Width=0) or (d.Height=0) then Exit;
+ d.Lock(sd);
+ case d.BitCount of
+ 16: for y:=0 to d.Height-1 do begin
+ p16 := ScanLine16(sd, y);
+ for x:=0 to d.Width-1 do
+ p16[x]:=random(16777216);
+ end;
+ end;
+ d.UnLock;
+end;
+
+function r16(color: cardinal): byte; register;
+begin;
+ result := (color shr 11) shl 3;
+end;
+
+function g16(color: cardinal): byte; register;
+begin;
+ result := ((color and 2016) shr 5) shl 2;
+end;
+
+function b16(color: cardinal): byte; register;
+begin;
+ result := (color and 31) shl 3;
+end;
+
+procedure blend(const d1, d2: TDirectDrawSurface; const amount: Extended);
+var
+ x, y, w, h: Integer;
+ p1, p2: PWordArray;
+ sd1, sd2: TDDSurfaceDesc;
+ c1,c2: cardinal;
+begin
+ if (d1.Width=0) or (d2.Width=0) or
+ (d1.BitCount<>16) or (d2.BitCount<>16) then Exit;
+ w := d1.Width;
+ h := d1.Height;
+ if d2.Width<w then w:=d2.Width;
+ if d2.Height<h then h:=d2.Height;
+
+ d1.Lock(sd1);
+ d2.Lock(sd2);
+ for y:=0 to h-1 do begin
+ p1:=ScanLine16(sd1, y);
+ p2:=ScanLine16(sd2, y);
+ for x:=0 to w-1 do begin
+ c1 := p1[x];
+ c2 := p2[x];
+ p2[x] :=
+ ((round((1-amount)*r16(c1)+amount*r16(c2)) shr 3) shl 11) or // r value shifted
+ ((round((1-amount)*g16(c1)+amount*g16(c2)) shr 2) shl 5) or // g value shifted
+ (round((1-amount)*b16(c1)+amount*b16(c2)) shr 3); // add blue
+ end;
+ end;
+ d1.UnLock;
+ d2.UnLock;
+end;
+
+end.
+
diff --git a/Source/fsDcAvi.pas b/Source/fsDcAvi.pas
new file mode 100644
index 0000000..889ed82
--- /dev/null
+++ b/Source/fsDcAvi.pas
@@ -0,0 +1,1615 @@
+{*******************************************************}
+{ }
+{ TDCAVIPlayer component }
+{ }
+{ Copyright (c) 1997-1999 Dream Company }
+{ http://www.dream-com.com }
+{ e-mail: contact@dream-com.com }
+{ }
+{*******************************************************}
+{Modified for Framestein, look for '_FS'}
+
+unit fsdcAVI;
+
+interface
+{$I dc.inc}
+uses
+ Windows, Messages, Graphics, Classes, Controls, mmSystem
+ {$IFNDEF D3},SysUtils{$ENDIF};
+
+const
+ WM_NEXTFRAME = WM_USER + 1;
+
+ cBufSize = 2048; {audio buffer size}
+ CAheadBuffers = 8;
+
+type
+ TAudioPlay = class
+ private
+ fBufferSize : integer;
+ fAVI : pointer;
+ fSampleSize : integer;
+ fEnd : integer;
+ fPlaying : boolean;
+ fWaveOut : HWAVEOUT;
+ fBegin : integer;
+ fCurrent : integer;
+
+ function OpenDevice(W : HWND; pAvi : pointer) : boolean;
+ function FillBuffer : boolean;
+ public
+ destructor Destroy; override;
+ procedure AudioPlayMessage(W : PWAVEHDR);
+ procedure Stop;
+ function Play(W : HWND; pAvi : Pointer; lStart, lEnd : longint) : boolean;
+ end;
+
+
+ TDCAVIPlayer = class(TCustomControl)
+ private
+ _dc : THandle;
+ fActive : boolean;
+ fAutoSize : boolean;
+ fCenter : boolean;
+ fFileName : string;
+ fOpen : boolean;
+ fRepetitions : integer;
+ fStartFrame : integer;
+ fStopFrame : integer;
+ fTransparent : boolean;
+ fSkipFrames : boolean;
+ fStretch : boolean;
+ fLength : integer;
+ fFrameWidth : integer;
+ fFrameHeight : integer;
+ fPlaySound : boolean;
+
+ fOnClose : TNotifyEvent;
+ fOnOpen : TNotifyEvent;
+ fOnStart : TNotifyEvent;
+ fOnStop : TNotifyEvent;
+
+ favifile : pointer;
+ faudiostream : pointer;
+ fvideostream : pointer;
+ fFrame : integer;
+ fTimer : THandle;
+ fgetframe : pointer;
+ fdrawing : boolean;
+ fdrawcontrol : integer;
+ ftempdc : THandle;
+ ftempbitmap : THandle;
+ foldbitmap : THandle;
+ frepeatcount : integer;
+ fdelay : integer;
+ fbackchanged : boolean;
+ fBlockChanges : boolean;
+ faudioplay : TAudioPlay;
+ hdrawdib : THandle;
+
+ fxstart : integer;
+ fystart : integer;
+ fofs : integer;
+ fxofs : integer;
+ fyofs : integer;
+ fiwidth : integer;
+ fiheight : integer;
+
+ procedure PlayNextFrame(var Msg : TMessage); message WM_NEXTFRAME;
+ procedure SaveBackground;
+ procedure AdjustControlsize;
+ procedure ShowRect;
+ procedure KillTempDC;
+ procedure HookWndProc;
+ procedure UnHookWndProc;
+ procedure MMWOM_DONE(var M:TMessage); message MM_WOM_DONE;
+ procedure PlayAudio(startframe, endframe : integer);
+ procedure CalcFrameLayout;
+ procedure DisplayChange(var Msg : TMessage); message WM_DISPLAYCHANGE;
+ procedure ValidateFrameNumber(var val : integer);
+ procedure UpdateFrameNumber;
+ function ZOrder : integer;
+ procedure StartDrawing;
+ function GetFrameRate: integer;
+ protected
+ procedure UpdateOtherAVIPlayers;
+ function PaintDisabled : boolean;
+ procedure CreateParams (var Params: TCreateParams); override;
+ procedure ShowFrame;
+ procedure WMPaint(var Msg : TWMPaint); message WM_PAINT;
+ procedure WMEraseBkgnd(var Msg : TMessage); message WM_ERASEBKGND;
+ procedure WMMove (var Msg : TMessage); message WM_MOVE;
+ procedure WMSize (var Msg : TMessage); message WM_SIZE;
+
+ procedure Loaded; override;
+ procedure SetActive (val : boolean); virtual;
+ procedure SetAutoSize (val : boolean); virtual;
+ procedure SetCenter (val : boolean); virtual;
+ procedure SetFileName (val : string); virtual;
+ procedure SetRepetitions (val : integer); virtual;
+ procedure SetStartFrame (val : integer); virtual;
+ procedure SetStopFrame (val : integer); virtual;
+ procedure SetTransparent (val : boolean); virtual;
+ procedure SetStretch (val : boolean); virtual;
+ procedure SetPlaySound(val : boolean); virtual;
+
+ procedure OpenFile; virtual;
+ procedure CloseFile; virtual;
+
+ procedure DoOpen; virtual;
+ procedure DoClose; virtual;
+ procedure DoStart; virtual;
+ procedure DoStop; virtual;
+ public
+ procedure DrawFrameToDC(dc : THandle); {_FS - This was private}
+ constructor Create (AOwner : TComponent); override;
+ destructor Destroy; override;
+ procedure Play (FromFrame, ToFrame: Word; Count: Integer);
+ procedure Reset;
+ procedure Seek (Frame : integer);
+ procedure Stop;
+
+ {_FS - add: property FrameRate}
+ property FrameRate : integer read GetFrameRate;
+ property FrameCount : integer read fLength;
+ property FrameHeight: Integer read FFrameHeight;
+ property FrameWidth : Integer read FFrameWidth;
+
+ property Open : boolean read fOpen;
+
+ published
+ property Active : boolean read fActive write SetActive default false;
+ property AutoSize : boolean read fAutoSize write SetAutoSize default true;
+ property Center : boolean read fCenter write SetCenter default true;
+ property FileName : string read fFileName write SetFileName;
+ property PlaySound : boolean read fPlaySound write SetPlaySound default true;
+ property Repetitions : integer read fRepetitions write SetRepetitions default 0;
+ property StartFrame : integer read fStartFrame write SetStartFrame default 1;
+ property StopFrame : integer read fStopFrame write SetStopFrame default 0;
+ property Stretch : boolean read fStretch write SetStretch default false;
+ property Transparent : boolean read fTransparent write SetTransparent default true;
+
+ property Position : integer read fFrame write Seek;
+
+ property OnOpen: TNotifyEvent read fOnOpen write fOnOpen;
+ property OnClose: TNotifyEvent read fOnClose write fOnClose;
+ property OnStart: TNotifyEvent read fOnStart write fOnStart;
+ property OnStop: TNotifyEvent read fOnStop write fOnStop;
+
+ property Align;
+ property Color;
+ property ParentColor;
+ property ParentShowHint;
+ property ShowHint;
+ property Visible;
+
+ property OnMouseDown;
+ property OnClick;
+ end;
+
+type
+ TAVIStream = record
+ fccType : longint;
+ fccHandler : longint;
+ dwFlags : longint;
+ dwCaps : longint;
+ wPriority : word;
+ wLanguage : word;
+ dwScale : longint;
+ dwRate : longint;
+ dwStart : longint;
+ dwLength : longint;
+ dwInitialFrames : longint;
+ dwSuggestedBufferSize : longint;
+ dwQuality : longint;
+ dwSampleSize : longint;
+ rcFrame : TRect;
+ dwEditCount : longint;
+ dwFormatChangeCount : longint;
+ Name : array [0..64] of char;
+ end;
+
+ PAVIStream = ^TAVIStream;
+
+ PAVIFile = pointer;
+
+ TAVIFileInfo = record
+ dwMaxBytesPerSec : longint; // max. transfer rate
+ dwFlags : longint; // the ever-present flags
+ dwCaps : longint;
+ dwStreams : longint;
+ dwSuggestedBufferSize : longint;
+
+ dwWidth : longint;
+ dwHeight : longint;
+
+ dwScale : longint;
+ dwRate : longint; // dwRate / dwScale == samples/second
+ dwLength : longint;
+
+ dwEditCount : longint;
+
+ szFileType : array[0..63] of char; // descriptive string for file type?
+ end;
+
+ PAVIFileInfo = ^TAVIFileInfo;
+
+ TAVIStreamInfo = record
+ fccType : longint;
+ fccHandler : longint;
+ dwFlags : longint; // Contains AVITF_* flags
+ dwCaps : longint;
+ wPriority : word;
+ wLanguage : word;
+ dwScale : longint;
+ dwRate : longint; // dwRate / dwScale == samples/second
+ dwStart : longint;
+ dwLength : longint; // In units above...
+ dwInitialFrames : longint;
+ dwSuggestedBufferSize : longint;
+ dwQuality : longint;
+ dwSampleSize : longint;
+ rcFrame : TRect;
+ dwEditCount : longint;
+ dwFormatChangeCount : longint;
+ szName : array[0..63] of char;
+ end;
+
+ PAVIStreamInfo = ^TAVIStreamInfo;
+
+
+//BeginSkipConst
+procedure AVIFileInit; stdcall; external 'avifil32.dll' name 'AVIFileInit';
+
+procedure AVIFileExit; stdcall; external 'avifil32.dll' name 'AVIFileExit';
+
+function AVIFileOpen(avifile : pointer; filename : pchar; mode : integer;
+ CLSID : pointer) : integer; stdcall; external 'avifil32.dll' name 'AVIFileOpen';
+
+function AVIFileRelease(avifile : pointer) : longint; stdcall; external 'avifil32.dll' name 'AVIFileRelease';
+
+function AVIFileGetStream(avifile : pointer; avistream : PAVIStream;
+ streamtype : longint; lParam : longint) : integer; stdcall; external 'avifil32.dll' name 'AVIFileGetStream';
+
+function AVIStreamGetFrameOpen(avistream : PAVIStream; bitmapwanted : pointer) : pointer; stdcall; external 'avifil32.dll' name 'AVIStreamGetFrameOpen';
+
+procedure AVIStreamGetFrameClose(pget : pointer); stdcall; external 'avifil32.dll' name 'AVIStreamGetFrameClose';
+
+function AVIStreamGetFrame(getframe : pointer; position : longint) : pointer; stdcall; external 'avifil32.dll' name 'AVIStreamGetFrame';
+
+function AVIStreamOpenFromFile(avistream : PAVIStream; filename : pchar;
+ streamtype : word; lParam : longint;
+ mode : longint; clsid : pointer) : integer; stdcall; external 'avifil32.dll' name 'AVIStreamOpenFromFile';
+
+procedure AVIStreamRelease(avistream : PAVIStream); stdcall; external 'avifil32.dll' name 'AVIStreamRelease';
+function AVIFileInfo(pfile : PAVIFile; pfi : PAVIFileInfo; lSize : longint) : integer; stdcall; external 'avifil32.dll' name 'AVIFileInfo';
+
+function AVIStreamInfo(pstream : PAVIStream; psi : PAVISTREAMINFO; lsize : longint) : integer; stdcall; external 'avifil32.dll' name 'AVIStreamInfo';
+function AVIStreamRead(pavi : PAVIStream; lStart, lSamples : longint;
+ lpBuffer : pointer; cbBuffer : longint;
+ plBytes, plSamples : pointer) : integer; stdcall; external 'avifil32.dll' name 'AVIStreamRead';
+
+function AVIStreamReadFormat(pavi : PAVIStream; lPos : longint;
+ lpFormat : pointer; lpcbFormat : pointer) : integer; stdcall; external 'avifil32.dll' name 'AVIStreamReadFormat';
+
+function AVIStreamBeginStreaming(pavi : PAVIStream; lStart, lEnd, lRate : longint) : integer; stdcall; external 'avifil32.dll' name 'AVIStreamBeginStreaming';
+function AVIStreamEndStreaming(pavi : PAVIStream) : integer; stdcall; external 'avifil32.dll' name 'AVIStreamEndStreaming';
+function AVIStreamStart(pavi : PAVIStream) : longint; stdcall; external 'avifil32.dll' name 'AVIStreamStart';
+function AVIStreamLength(pavi: PAVIStream) : longint; stdcall; external 'avifil32.dll' name 'AVIStreamLength';
+function AVIStreamSampleToTime(pavi : PAVIStream; lSample : longint) : longint; stdcall; external 'avifil32.dll' name 'AVIStreamSampleToTime';
+function AVIStreamTimeToSample(pavi : PAVIStream; Time : longint) : longint; stdcall; external 'avifil32.dll' name 'AVIStreamTimeToSample';
+
+function DrawDIBOpen : THandle; stdcall; external 'msvfw32.dll' name 'DrawDibOpen';
+procedure DrawDIBClose (h : THandle); stdcall; external 'msvfw32.dll' name 'DrawDibClose';
+procedure DrawDibDraw (hdib, dc : THandle; xDst, yDst, dxDst, dyDst : integer;
+ lpbi, lpBits : pointer; xSrc, ySrc, dxSrc, dySrc, wFlags : integer); stdcall; external 'msvfw32.dll' name 'DrawDibDraw';
+//EndSkipConst
+
+const
+ streamtypeAUDIO : longint = $73647561;
+ streamtypeVIDEO : longint = $73646976;
+
+ AVISTREAMREAD_CONVENIENT = -1;
+
+ DDF_HALFTONE = $1000;
+
+{-----------------------------------------------------------------------}
+
+implementation
+
+function Min(A, B: Integer): Integer;
+begin
+ if A < B then
+ Result := A
+ else
+ Result := B;
+end;
+
+function Max(A, B: Integer): Integer;
+begin
+ if A > B then
+ Result := A
+ else
+ Result := B;
+end;
+
+function RectWidth(const R: TRect): Integer;
+begin
+ with R do
+ Result := Right - Left;
+end;
+
+function RectHeight(const R: TRect): Integer;
+begin
+ with R do
+ Result := Bottom - Top;
+end;
+
+{$IFNDEF D3}
+function TransparentStretchBlt(DstDC: HDC; DstX, DstY, DstW, DstH: Integer;
+ SrcDC: HDC; SrcX, SrcY, SrcW, SrcH: Integer; MaskDC: HDC; MaskX,
+ MaskY: Integer): Boolean;
+const
+ ROP_DstCopy = $00AA0029;
+var
+ MemDC : THandle;
+ MemBmp : THandle;
+ Save : THandle;
+ crText : TColorRef;
+ crBack : TColorRef;
+begin
+ Result := True;
+ if (Win32Platform = VER_PLATFORM_WIN32_NT) and (SrcW = DstW) and (SrcH = DstH) then
+ begin
+ MemBmp := CreateCompatibleBitmap(SrcDC, 1, 1);
+ MemBmp := SelectObject(MaskDC, MemBmp);
+ MaskBlt(DstDC, DstX, DstY, DstW, DstH, SrcDC, SrcX, SrcY, MemBmp, MaskX,
+ MaskY, MakeRop4(ROP_DstCopy, SrcCopy));
+ MemBmp := SelectObject(MaskDC, MemBmp);
+ DeleteObject(MemBmp);
+ exit;
+ end;
+
+ MemDC := CreateCompatibleDC(0);
+ MemBmp := CreateCompatibleBitmap(SrcDC, SrcW, SrcH);
+ Save := SelectObject(MemDC, MemBmp);
+ StretchBlt(MemDC, 0, 0, SrcW, SrcH, MaskDC, MaskX, MaskY, SrcW, SrcH, SrcCopy);
+ StretchBlt(MemDC, 0, 0, SrcW, SrcH, SrcDC, SrcX, SrcY, SrcW, SrcH, SrcErase);
+ crText := SetTextColor(DstDC, $0);
+ crBack := SetBkColor(DstDC, $FFFFFF);
+ StretchBlt(DstDC, DstX, DstY, DstW, DstH, MaskDC, MaskX, MaskY, SrcW, SrcH, SrcAnd);
+ StretchBlt(DstDC, DstX, DstY, DstW, DstH, MemDC, 0, 0, SrcW, SrcH, SrcInvert);
+ SetTextColor(DstDC, crText);
+ SetTextColor(DstDC, crBack);
+ SelectObject(MemDC, Save);
+ DeleteObject(MemBmp);
+ DeleteDC(MemDC);
+end;
+{$ENDIF}
+
+Procedure TransparentBitBltEx(sourcedc, destdc: THandle; SrcRect,DstRect: TRect;
+ atranscolor: longint);
+Var
+ monobitmap: THandle;
+ oldbkcolor: longint;
+ monodc: THandle;
+ width: integer;
+ height: integer;
+ oldbitmap: THandle;
+Begin
+ With SrcRect do
+ Begin
+ width := RectWidth(SrcRect);
+ height := RectHeight(SrcRect);
+ monodc := CreateCompatibleDC(sourcedc);
+ monobitmap := CreateCompatibleBitmap(monodc, width, height);
+ oldbitmap := SelectObject(monodc, monobitmap);
+ Try
+ oldbkcolor := SetBkColor(sourcedc, atranscolor);
+ BitBlt(monodc, 0, 0, width, height, sourcedc, Left, Top, SRCCOPY);
+ SetBkColor(sourcedc, oldbkcolor);
+ TransparentStretchBlt(destdc, DstRect.Left, DstRect.Top, RectWidth(DstRect),
+ RectHeight(DstRect), SourceDC, left, top, width, height, monodc, 0, 0);
+ Finally
+ SelectObject(monodc, oldbitmap);
+ DeleteDC(monodc);
+ DeleteObject(monobitmap);
+ End;
+ End;
+End;
+
+Procedure TransparentBitBlt(sourcedc, destdc: THandle; arect: TRect;
+ atranscolor: longint; aoriginX,aoriginY: Integer);
+begin
+ TransparentBitBltEx(sourcedc, destdc,arect,
+ Rect(aoriginX,aoriginY,aoriginX+RectWidth(arect),aoriginY+RectHeight(arect)),
+ atranscolor);
+end;
+
+Function GetTransparentColor(dc: THandle; const arect: TRect): longint;
+Begin
+ Result := GetPixel(dc, arect.left, arect.bottom);
+End;
+
+{-----------------------------------------------------------------------}
+
+function AVIStreamEnd (pavi : PAVIStream) : longint;
+begin
+ result := AVIStreamStart(pavi) + AVIStreamLength(pavi);
+end;
+
+{-----------------------------------------------------------------------}
+
+function AVIStreamFormatSize (pavi : PAVIStream; lPos : longint; plSize : pointer) : longint;
+begin
+ result := AVIStreamReadFormat(pavi, lPos, nil, plSize);
+end;
+
+{-----------------------------------------------------------------------}
+
+constructor TDCAVIPlayer.Create (AOwner : TComponent);
+begin
+ inherited Create(AOwner);
+ width := 100;
+ height := 50;
+
+ fAutoSize := true;
+ fCenter := true;
+ fStartFrame := 1;
+ fTransparent := true;
+ fSkipFrames := true;
+ fAutoSize := true;
+ fBackChanged := true;
+ fblockchanges := true;
+ fPlaySound := true;
+
+ AVIFileInit;
+ faudioplay := TAudioPlay.Create;
+ HookWndProc;
+ hdrawdib := DrawDIBOpen;
+end;
+
+{------------------------------------------------------------------}
+
+destructor TDCAVIPlayer.Destroy;
+begin
+ Stop;
+ UnHookWndProc;
+ DrawDIBClose(hdrawdib);
+ KillTempDC;
+ CloseFile;
+ faudioplay.Free;
+ AVIFileExit;
+ inherited Destroy;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.CreateParams(var Params: TCreateParams);
+begin
+ inherited CreateParams(Params);
+ Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT;
+end;
+
+{------------------------------------------------------------------}
+
+function TDCAVIPlayer.ZOrder : integer;
+begin
+ if Parent <> nil then
+ with Parent do
+ for result := 0 to ControlCount - 1 do
+ if Controls[result] = self then
+ exit;
+
+ result := -1
+end;
+
+{------------------------------------------------------------------}
+
+procedure Timer(uID, uMsg, dwUser, dw1, dw2 : longint); stdcall;
+begin
+ PostMessage(TDCAVIPlayer(dwUser).Handle, WM_NEXTFRAME, 0, 0);
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.PlayAudio(startframe, endframe : integer);
+var
+ astart : integer;
+ aend : integer;
+begin
+ if (faudiostream = nil) or not fPlaySound then
+ exit;
+
+ astart := AVIStreamTimeToSample(faudiostream, AVIStreamSampleToTime(fvideostream, startFrame));
+ aend := AVIStreamTimeToSample(faudiostream, AVIStreamSampleToTime(fvideostream, endFrame));
+ faudioplay.play(handle, faudiostream, astart, aend);
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.Play (FromFrame, ToFrame: Word; Count: Integer);
+var
+ info : TAVIStreamInfo;
+ ainfo : TAVIStreamInfo;
+begin
+ Stop;
+ if not Assigned(fvideostream) then
+ exit;
+
+ fFrame := FromFrame;
+ fStartFrame := FromFrame;
+ fStopFrame := ToFrame;
+ frepeatCount := Count;
+ AVIStreamInfo(fvideostream, @info, sizeof(info));
+ fdelay := MulDiv(info.dwScale, 1000, info.dwRate);
+
+ DoStart;
+ fActive := true;
+ if Assigned(faudiostream) then
+ begin
+ AVIStreamInfo(fvideostream, @ainfo, sizeof(info));
+ PlayAudio(fFrame, fStopFrame);
+ end;
+
+ fTimer := timeSetEvent(fdelay, 0, @Timer, integer(self), TIME_PERIODIC);
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.Stop;
+begin
+ if ftimer <> 0 then
+ begin
+ timeKillEvent(fTimer);
+ fTimer := 0;
+ end;
+
+ if not fActive then
+ exit;
+
+ faudioplay.stop;
+ fActive := false;
+ DoStop;
+ ShowFrame;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.Seek (Frame : integer);
+begin
+ if Frame = fFrame then
+ exit;
+
+ Stop;
+ ValidateFrameNumber(Frame);
+ fFrame := Frame;
+ Invalidate;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.Loaded;
+var
+ _startframe : integer;
+ _stopframe : integer;
+begin
+ inherited Loaded;
+
+ if ffilename <> '' then
+ begin
+ fBlockChanges := false;
+ _startframe := fstartframe;
+ _stopframe := fStopFrame;
+ OpenFile;
+ fstartframe := _startframe;
+ fStopFrame := _stopframe;
+ fBlockChanges := true;
+ end;
+
+
+ if fActive then
+ if fOpen then
+ Play(fStartFrame, fStopFrame, fRepetitions)
+ else
+ fActive := false;
+
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.SetActive(val : boolean);
+begin
+ if val = fActive then
+ exit;
+
+ if not (csReading in ComponentState) then
+ if val then
+ begin
+ Play(fStartFrame, fStopFrame, fRepetitions)
+ end
+ else
+ begin
+ Stop;
+ if csDesigning in ComponentState then
+ begin
+ fFrame := 0;
+ ShowFrame;
+ end;
+ end;
+
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.SetAutoSize(val : boolean);
+begin
+ if val = fAutoSize then
+ exit;
+
+ fAutoSize := val;
+ AdjustControlsize;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.SetCenter(val : boolean);
+begin
+ if val = fCenter then
+ exit;
+
+ fCenter := val;
+ if not fTransparent then
+ Invalidate;
+
+ ShowFrame;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.SetFileName(val : string);
+var
+ wasactive : boolean;
+begin
+ if val = fFileName then
+ exit;
+
+ ffilename := val;
+ if csReading in ComponentState then
+ exit;
+
+ wasactive := fActive;
+
+ Reset;
+
+ Invalidate;
+ ShowFrame;
+
+ if val = '' then
+ begin
+ fbackchanged := true;
+ Parent.Invalidate;
+ UpdateWindow(Parent.Handle);
+ end;
+
+ if wasActive then
+ if not (csReading in ComponentState) then
+ Active := true
+ else
+ fActive := true;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.SetRepetitions(val : integer);
+begin
+ if val = fRepetitions then
+ exit;
+
+ fRepetitions := val;
+ if csDesigning in ComponentState then
+ begin
+ Stop;
+ fFrame := 0;
+ ShowFrame;
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.ValidateFrameNumber(var val : integer);
+begin
+ if fOpen then
+ if val > fLength - 1 then
+ val := fLength - 1
+ else
+ if val < 0 then
+ val := 0;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.SetStartFrame(val : integer);
+begin
+ if (val = fStartFrame) then
+ exit;
+
+ ValidateFrameNumber(val);
+ fStartFrame := val;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.SetStopFrame(val : integer);
+begin
+ if val = fStopFrame then
+ exit;
+
+ ValidateFrameNumber(val);
+ fStopFrame := val;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.SetTransparent(val : boolean);
+begin
+ if val = fTransparent then
+ exit;
+
+ fTransparent := val;
+ Invalidate;
+ ShowFrame;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.SetStretch (val : boolean);
+begin
+ if val = fStretch then
+ exit;
+
+ fStretch := val;
+ if not (csReading in ComponentState) then
+ begin
+ if not val then
+ invalidate;
+
+ if not fActive then
+ ShowFrame;
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.SetPlaySound (val : boolean);
+begin
+ if val = fPlaySound then
+ exit;
+
+ fPlaySound := val;
+ if fActive then
+ if val then
+ PlayAudio(fFrame, fStopFrame)
+ else
+ faudioplay.Stop;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.AdjustControlsize;
+var
+ info : TAVIStreamInfo;
+ r : TRect;
+ r2 : TRect;
+ i : integer;
+ crect : TRect;
+begin
+ if fautosize and fOpen then
+ begin
+ AVIStreamInfo(fvideostream, @info, sizeof(info));
+ if fblockchanges then
+ Parent.Perform(WM_SETREDRAW, 0, 0);
+ r := Rect(left, top, left + width, top + height);
+ with info.rcframe do
+ SetBounds(self.left, self.top, right - left, bottom - top);
+ if fblockchanges then
+ begin
+ Parent.Perform(WM_SETREDRAW, 1, 0);
+ r2 := Rect(left, top, left + width, top + height);
+ SubtractRect(r, r, r2);
+ InvalidateRect(Parent.Handle, @r, true);
+ with Parent do
+ for i := 0 to ControlCount - 1 do
+ begin
+ with Controls[i] do
+ crect := Rect(left, top, left + width, top + height);
+
+ if (Controls[i] is TWinControl) and (Controls[i] <> self) and
+ InterSectRect(r2, r, crect) then
+ Controls[i].Invalidate;
+ end;
+ end;
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.OpenFile;
+var
+ info : TAVIStreamInfo;
+begin
+ if ffilename = '' then
+ exit;
+
+ if (AVIFileOpen(@favifile, @(ffilename[1]), 0, nil) <> 0) then
+ exit;
+
+ if (AVIFileGetStream(favifile, @fvideostream, streamtypeVIDEO, 0) <> 0) then
+ begin
+ AVIFileRelease(favifile);
+ exit;
+ end;
+
+ fgetframe := AVIStreamGetFrameOpen(fvideostream, nil);
+
+ if fgetframe = nil then
+ begin
+ AVIStreamRelease(fvideostream);
+ AVIFileRelease(favifile);
+ exit;
+ end;
+
+ AVIFileGetStream(favifile, @faudiostream, streamtypeAUDIO, 0);
+
+ AVIStreamInfo(fvideostream, @info, sizeof(info));
+ with info do
+ begin
+ fLength := dwlength;
+ fFrameWidth := rcframe.right - rcframe.left;
+ fFrameHeight := rcframe.bottom - rcframe.top;
+ fStartFrame := dwStart;
+ fStopFrame := fLength - 1;
+ end;
+ fFrame := fStartFrame;
+ fOpen := true;
+ SetWindowLong(handle, GWL_EXSTYLE, GetWindowLong(handle, GWL_EXSTYLE) and (not WS_EX_TRANSPARENT));
+ AdjustControlsize;
+ fbackchanged := true;
+ Invalidate;
+{ ShowFrame;
+ Parent.Invalidate;}
+ DoOpen;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.CloseFile;
+begin
+ if not fOpen then
+ exit;
+
+ if fActive then
+ Stop;
+
+ if Assigned(fgetframe) then
+ AVIStreamGetFrameClose(fgetframe);
+
+ if Assigned(faudiostream) then
+ AVIStreamRelease(faudiostream);
+
+ if Assigned(fvideostream) then
+ AVIStreamRelease(fvideostream);
+
+ if Assigned(favifile) then
+ AVIFileRelease(favifile);
+
+ faudiostream := nil;
+ fvideostream := nil;
+ favifile := nil;
+ fgetframe := nil;
+ fOpen := false;
+ fLength := 0;
+ DoClose;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.CalcFrameLayout;
+begin
+ fxstart := 0;
+ fystart := 0;
+ if csDesigning in ComponentState then
+ fofs := 1
+ else
+ fofs := 0;
+
+ if fOpen then
+ begin
+ fiwidth := FrameWidth;
+ fiheight := FrameHeight;
+ end
+ else
+ begin
+ fiwidth := self.width;
+ fiheight := self.height;
+ end;
+
+ if not Stretch and fCenter then
+ begin
+ fxstart := (self.width - fiwidth) div 2;
+ fystart := (self.height - fiheight) div 2;
+ end;
+
+ if not Transparent then
+ begin
+ if fxstart > 0 then
+ fxofs := 0
+ else
+ fxofs := fofs;
+
+ if fystart > 0 then
+ fyofs := 0
+ else
+ fyofs := fofs;
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.StartDrawing;
+begin
+ fdrawing := true;
+ fdrawcontrol := ZOrder;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.DrawFrameToDC(dc : THandle);
+var
+ memdc : THandle;
+ formdc : THandle;
+ image : pointer;
+ imagestart : integer;
+ bitmap : THandle;
+ fbitmap : THandle;
+ oldmemobject : THandle;
+ oldfobject : THandle;
+ width : integer;
+ height : integer;
+
+begin
+{_FS - We're not using your window anyway...}
+// if PaintDisabled then
+// exit;
+
+ if fTransparent and (fBackChanged or not fActive) then
+ begin
+ SaveBackGround;
+ fBackChanged := false;
+ end;
+
+ StartDrawing;
+ memdc := CreateCompatibleDC(dc);
+ formdc := CreateCompatibleDC(dc);
+ try
+ image := AVIStreamGetFrame(fgetframe, fFrame);
+ CalcFrameLayout;
+
+ if fStretch then
+ begin
+ width := self.width;
+ height := self.height;
+ end
+ else
+ begin
+ width := fiwidth;
+ height := fiheight;
+ end;
+
+ imagestart := 0;
+
+ if Assigned(image) then
+ begin
+ SetStretchBltMode(memdc, HALFTONE);
+ imagestart := TBitmapInfoHeader(image^).biSize + TBitmapInfoHeader(image^).biClrUsed * 4;
+ end;
+
+ if fTransparent then
+ begin
+ bitmap := CreateCompatibleBitmap(dc, width, height);
+ oldmemobject := SelectObject(memdc, bitmap);
+
+ StretchDIBits(memdc, 0, 0, width, height, 0, 0, fiwidth, fiheight, pchar(image) + imagestart,
+ TBitmapInfo(image^), 0, SRCCOPY);
+
+ fbitmap := CreateCompatibleBitmap(dc, self.width, self.height);
+ oldfobject := SelectObject(formdc, fbitmap);
+
+ BitBlt(formdc, 0, 0, self.width, self.height, ftempdc, 0, 0, SRCCOPY);
+
+ if Assigned(image) then
+ TransparentBitBlt(memdc, formdc, Rect(0, 0, width, height),
+ GetTransparentColor(memdc, Rect(0, 0, width - 1, height - 1)),
+ fxstart, fystart);
+
+ BitBlt(dc, fofs, fofs, self.width - fofs * 2, self.height - fofs * 2, formdc, fofs, fofs, SRCCOPY);
+
+ SelectObject(formdc, oldfobject);
+ DeleteObject(fbitmap);
+ SelectObject(memdc, oldmemobject);
+ DeleteObject(bitmap);
+ end
+ else
+ DrawDibDraw(hdrawdib, dc, fxstart, fystart, width - fxofs * 2, height - fyofs * 2,
+ image, pchar(image) + imagestart, 0, 0, fiwidth, fiheight, DDF_HALFTONE);
+
+ finally
+ DeleteDC(memdc);
+ DeleteDC(formdc);
+ fdrawing := false;
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+function TDCAVIPlayer.PaintDisabled : boolean;
+begin
+ result := fDrawing or ([csReading, csLoading] * ComponentState <> []) or (Parent = nil)
+ or ([csReading, csLoading] * Parent.ComponentState <> [])
+ or not HandleAllocated or not ({_FS-visible or }(csDesigning in ComponentState));
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.ShowFrame;
+var
+ dc : THandle;
+ brush : THandle;
+begin
+ if PaintDisabled then
+ exit;
+
+ if _dc = 0 then
+ dc := GetDC(handle)
+ else
+ dc := _dc;
+
+ if not (fTransparent or fOpen) then
+ begin
+ brush := CreateSolidBrush(ColorToRGB(Color));
+ FillRect(dc, ClientRect, brush);
+ DeleteObject(brush);
+ end
+ else
+ DrawFrameToDC(dc);
+
+ if _dc = 0 then
+ ReleaseDC(handle, dc);
+
+ ShowRect;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.UpdateFrameNumber;
+begin
+ if (fFrame >= fStopFrame) then
+ begin
+ if frepeatcount > 0 then
+ begin
+ dec(fRepeatCount);
+ if fRepeatCount = 0 then
+ begin
+ Stop;
+ exit;
+ end;
+ end;
+
+ fFrame := fStartFrame - 1;
+ PlayAudio(fStartFrame, fStopFrame);
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.UpdateOtherAVIPlayers;
+var
+ r : TRect;
+ i : integer;
+begin
+ with Parent do
+ for i := ControlCount - 1 downto 0 do
+ begin
+ if (Controls[i] = self) then
+ break;
+
+ if (Controls[i].Visible) and (Controls[i] is TDCAVIPlayer) then
+ with TDCAVIPlayer(Controls[i]) do
+ if [csDestroying, csLoading] * ComponentState = [] then
+ begin
+ fbackchanged := true;
+ r := ClientRect;
+ InvalidateRect(Handle, @r, true);
+ end;
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.PlayNextFrame(var Msg : TMessage);
+begin
+ UpdateFrameNumber;
+ inc(fFrame);
+ if fActive and not fDrawing then
+ begin
+ ShowFrame;
+ UpdateOtherAVIPlayers;
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.SaveBackground;
+var
+ dc : THandle;
+ formdc : THandle;
+ oldfbitmap : THandle;
+ fbitmap : THandle;
+ fdc : THandle;
+begin
+ if Parent = nil then
+ exit;
+
+ StartDrawing;
+ dc := GetDC(handle);
+ fdc := GetDC(parent.handle);
+ formdc := CreateCompatibleDC(fdc);
+ fbitmap := CreateCompatibleBitmap(fdc, parent.width, parent.height);
+ oldfbitmap := SelectObject(formdc, fbitmap);
+
+ if ftempdc = 0 then
+ begin
+ ftempdc := CreateCompatibleDC(dc);
+ ftempbitmap := CreateCompatibleBitmap(dc, width, height);
+ foldbitmap := SelectObject(ftempdc, ftempbitmap);
+ end;
+ IntersectClipRect(formdc, left, top, left + width + 1, top + height + 1);
+
+
+ with parent do
+ PaintTo(formdc, 0, 0);
+
+ SetViewPortOrgEx(formDC, 0, 0, nil);
+ BitBlt(ftempdc, 0, 0, width, height, formdc, left + 1, top + 1, SRCCOPY);
+ SelectObject(formdc, oldfbitmap);
+ DeleteObject(fbitmap);
+ DeleteDC(formdc);
+ ReleaseDC(Parent.Handle, fdc);
+ ReleaseDC(handle, dc);
+
+ fdrawing := false;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.WMPaint(var Msg : TWMPaint);
+var
+ ps : TPaintStruct;
+begin
+ _dc := Msg.DC;
+ if _dc = 0 then
+ _dc := BeginPaint(handle, ps);
+
+ try
+ Msg.result := 0;
+
+{ if name = 'DCAVIPlay3' then
+ asm nop end;}
+
+ ShowFrame;
+
+ finally
+ if Msg.DC = 0 then
+ EndPaint(handle, ps);
+ _dc := 0;
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.WMEraseBkgnd(var Msg : TMessage);
+var
+ brush : THandle;
+ r : TRect;
+ dc : THandle;
+ width : integer;
+ height : integer;
+begin
+ if PaintDisabled then
+ exit;
+
+ if not (fTransparent or fStretch) then
+ begin
+ CalcFrameLayout;
+ if fStretch then
+ begin
+ width := self.width;
+ height := self.height;
+ end
+ else
+ begin
+ width := fiwidth;
+ height := fiheight;
+ end;
+
+ dc := GetDC(handle);
+ brush := CreateSolidBrush(ColorToRGB(Color));
+ r := rect(fofs, fofs, self.width, fystart);
+ FillRect(dc, r, brush);
+
+ r := rect(fofs, fystart, fxstart, self.height);
+ FillRect(dc, r, brush);
+
+ r := rect(fxstart, fystart + height, self.width - fofs * 2, self.height - fofs * 2);
+ FillRect(dc, r, brush);
+
+ r := rect(fxstart + width, fystart, self.width - fofs * 2, fystart + height);
+ FillRect(dc, r, brush);
+
+ DeleteObject(brush);
+ ReleaseDC(handle, dc);
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.WMMove (var Msg : TMessage);
+begin
+ inherited;
+ fbackchanged := true;
+ ShowFrame;
+ UpdateOtherAVIPlayers;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.KillTempDC;
+begin
+ if ftempdc <> 0 then
+ begin
+ SelectObject(ftempdc, foldbitmap);
+ DeleteObject(ftempbitmap);
+ DeleteDC(ftempdc);
+ ftempdc := 0;
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.WMSize (var Msg : TMessage);
+begin
+ StartDrawing;
+ KillTempDC;
+ inherited;
+ fBackChanged := true;
+ fdrawing := false;
+ AdjustControlsize;
+ if not Active then
+ ShowFrame;
+ UpdateOtherAVIPlayers;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.ShowRect;
+var
+ DC : THandle;
+ Pen : THandle;
+ SavePen : THandle;
+ SaveBrush : THandle;
+begin
+ if not (csDesigning in ComponentState) then
+ exit;
+
+ dc := GetDC(Handle);
+ Pen := CreatePen(PS_DOT, 1, clBlack);
+ SavePen := SelectObject(dc, Pen);
+ SaveBrush := SelectObject(dc, GetStockobject(HOLLOW_BRUSH));
+ Rectangle(dc, 0, 0, width, height);
+ SelectObject(DC, SavePen);
+ DeleteObject(Pen);
+ SelectObject(DC, SaveBrush);
+ ReleaseDC(Handle, DC);
+end;
+
+{------------------------------------------------------------------}
+
+var
+ WHook : HHook;
+ hooks : TList;
+
+type TCWPStruct = packed record
+ lParam : LPARAM;
+ wParam : WPARAM;
+ message : integer;
+ wnd : HWND;
+end;
+
+function CallWndProcHook(nCode : integer; wParam : Longint; var Msg : TCWPStruct) : longint; stdcall;
+var
+ i : integer;
+ r : TRect;
+ r2 : TRect;
+
+ function IsPaintMsg : boolean;
+ var
+ c : TWinControl;
+ begin
+ result := false;
+ c := FindControl(msg.wnd);
+ if (c <> nil) and not (c is TDCAVIPlayer) and
+ TDCAVIPlayer(hooks[i]).HandleAllocated and
+ (TDCAVIPlayer(hooks[i]).owner = c.owner) or
+ (TDCAVIPlayer(hooks[i]).owner = c) then
+ begin
+ GetWindowRect(msg.wnd , r);
+ GetWindowRect(TDCAVIPlayer(hooks[i]).handle, r2);
+ result := IntersectRect(r, r, r2);
+ end;
+ end;
+
+begin
+ Result := CallNextHookEx(WHook, nCode, wParam, Longint(@Msg));
+
+ if ((msg.message > CN_BASE) and (msg.message < CN_BASE + 500)) or
+ (msg.message = WM_PAINT) or (msg.message = WM_SIZE)
+{ or (msg.message = WM_ERASEBKGND)} then
+ for i := 0 to hooks.Count - 1 do
+ with TDCAVIPlayer(hooks[i]) do
+ if HandleAllocated and Transparent and IsPaintMsg then
+ begin
+ fbackchanged := true;
+ r := ClientRect;
+ InvalidateRect(Handle, @r, true);
+ end;
+end;
+
+{------------------------------------------------------------------}
+
+procedure AddHook(o : TDCAVIPlayer);
+begin
+ if hooks.Count = 0 then
+ WHook := SetWindowsHookEx(WH_CALLWNDPROC, @CallWndProcHook, 0, GetCurrentThreadId);
+ hooks.Add(o);
+end;
+
+{------------------------------------------------------------------}
+
+procedure RemoveHook(o : TDCAVIPlayer);
+begin
+ hooks.Remove(o);
+ if hooks.Count = 0 then
+ UnHookWindowsHookEx(WHook);
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.HookWndProc;
+begin
+ AddHook(self);
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.UnHookWndProc;
+begin
+ RemoveHook(self);
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.Reset;
+begin
+ CloseFile;
+ OpenFile;
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.DoOpen;
+begin
+ if Assigned(fOnOpen) then
+ fOnOpen(self);
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.DoClose;
+begin
+ if Assigned(fOnClose) then
+ fOnClose(self);
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.DoStart;
+begin
+ if Assigned(fOnStart) then
+ fOnStart(self);
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.MMWOM_DONE(var M:TMessage);
+begin
+ faudioplay.AudioPlayMessage(PWAVEHDR(M.lParam));
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.DoStop;
+begin
+ if Assigned(fOnStop) then
+ fOnStop(Self);
+end;
+
+{------------------------------------------------------------------}
+
+procedure TDCAVIPlayer.DisplayChange(var Msg : TMessage);
+begin
+ DrawDIBClose(hdrawdib);
+ hdrawdib := DrawDIBOpen;
+end;
+
+{------------------------------------------------------}
+
+destructor TAudioPlay.Destroy;
+begin
+ Stop;
+ inherited;
+end;
+
+{--------------------------------------------------------------}
+
+procedure TAudioPlay.AudioPlayMessage(W : PWAVEHDR);
+begin
+ waveOutUnprepareHeader(FWaveOut, W, sizeof(TWAVEHDR));
+ FreeMem(W, FBufferSize + sizeof(TWAVEHDR));
+ if FPlaying then
+ FillBuffer;
+end;
+
+{--------------------------------------------------------------}
+
+function TAudioPlay.FillBuffer : Boolean;
+var
+ AudioBuf : PWAVEHDR;
+ SamplesToPlay : integer;
+ lRead : integer;
+begin
+ Result := false;
+ GetMem(AudioBuf, fBufferSize + sizeof(TWAVEHDR));
+ with AudioBuf^ do
+ begin
+ dwuser := integer(Self);
+ dwFlags := WHDR_DONE;
+ lpData := pointer(integer(AudioBuf) + sizeof(TWAVEHDR));
+ dwBufferLength := fBufferSize;
+ end;
+ if waveOutPrepareHeader(FWaveOut, AudioBuf,
+ sizeof(TWAVEHDR)) <> MMSYSERR_NOERROR then
+ begin
+ FreeMem(AudioBuf, fBufferSize + sizeof(TWAVEHDR));
+ exit;
+ end;
+
+ SamplesToPlay := Min(fEnd - fCurrent, fBufferSize div fSampleSize);
+ if SamplesToPlay > 0 then
+ begin
+ AVIStreamRead(fAvi, fCurrent, SamplesToPlay, AudioBuf.lpData,
+ fBufferSize, @AudioBuf.dwBufferLength, @lRead);
+ if LRead = SamplesToPlay then
+ begin
+ inc(fCurrent, lRead);
+ waveOutWrite(fWaveOut, AudioBuf, sizeof(TWAVEHDR));
+ end;
+ end;
+ fPlaying := true;
+ result := true;
+end;
+
+{--------------------------------------------------------------}
+
+function TAudioPlay.OpenDevice(W : HWND; pAvi : pointer) : boolean;
+var
+ strhdr : TAVISTREAMINFO;
+ lpFormat : pointer;
+ cbFormat : longint;
+begin
+ result := false;
+ fAVI := pAvi;
+ AVIStreamInfo(pAvi, @StrHdr, sizeof(StrHdr));
+ fSampleSize := StrHdr.dwSampleSize;
+ if (fSampleSize <= 0) then
+ exit;
+
+ fBufferSize := Max(fSampleSize, cBufSize);
+ AVIStreamFormatSize(pavi, 0, @cbFormat);
+ GetMem(lpFormat, cbFormat);
+ FillChar(lpFormat^, cbFormat, 0);
+ AVIStreamReadFormat(pAvi, 0, lpFormat, @cbFormat);
+ sndPlaySound(nil, 0);
+ if waveOutOpen(@FWaveOut, WAVE_MAPPER, lpFormat,
+ W, 0, CALLBACK_WINDOW) = 0 then
+ result := true;
+
+ FreeMem(lpFormat, cbFormat);
+end;
+
+{--------------------------------------------------------------}
+
+procedure TAudioPlay.Stop;
+begin
+ if fWaveOut <> 0 then
+ begin
+ FPlaying := false;
+ waveOutReset(FWaveOut);
+ waveOutClose(FWaveOut);
+ fWaveOut := 0;
+ end;
+end;
+
+{--------------------------------------------------------------}
+
+function TAudioPlay.Play(W : HWND; pAvi : Pointer; lStart, lEnd : longint) : boolean;
+var
+ i : integer;
+begin
+ if fPlaying then
+ Stop;
+
+ Result := false;
+ if lStart < 0 then
+ lStart := AVIStreamStart(pavi);
+
+ if lEnd < 0 then
+ lEnd := AVIStreamEnd(pavi);
+
+ if lStart >= lEnd then
+ exit;
+
+ if not OpenDevice(W, pAvi) then
+ exit;
+
+ waveOutPause(fWaveOut);
+ fBegin := lStart;
+ FCurrent := lStart;
+ fEnd := lEnd;
+ fPlaying := true;
+ for i := 1 to CAheadBuffers do
+ FillBuffer;
+
+ waveOutRestart(FWaveOut);
+ result := true;
+end;
+
+{---------------------------------------------------------------------}
+{_FS: add}
+function TDCAVIPlayer.GetFrameRate: integer;
+var
+ info: TAviStreamInfo;
+begin
+ Result:=0;
+ if not Assigned(fvideostream) then Exit;
+ AVIStreamInfo(fvideostream, @info, sizeof(info));
+ Result := info.dwRate div info.dwScale;
+end;
+{_FS: end add}
+
+initialization
+ hooks := TList.Create;
+finalization
+ if hooks.Count > 0 then
+ UnHookWindowsHookEx(WHook);
+ hooks.Free;
+end.
diff --git a/Source/fsaviunit.dfm b/Source/fsaviunit.dfm
new file mode 100644
index 0000000..761db79
--- /dev/null
+++ b/Source/fsaviunit.dfm
@@ -0,0 +1,23 @@
+object FsAvi: TFsAvi
+ Left = 243
+ Top = 106
+ Width = 226
+ Height = 103
+ Caption = 'FsAvi'
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ OldCreateOrder = False
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ PixelsPerInch = 96
+ TextHeight = 13
+ object sd1: TSaveDialog
+ Filter = 'AVI files|*.avi'
+ Left = 8
+ Top = 8
+ end
+end
diff --git a/Source/fsaviunit.pas b/Source/fsaviunit.pas
new file mode 100644
index 0000000..6f81e0b
--- /dev/null
+++ b/Source/fsaviunit.pas
@@ -0,0 +1,103 @@
+unit fsaviunit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ fsformunit,
+ fsaviwriter, ExtCtrls, StdCtrls, Buttons;
+
+type
+ TFsAvi = class(TFsForm)
+ sd1: TSaveDialog;
+ procedure FormCreate(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure BitBtn1Click(Sender: TObject);
+ procedure Button1Click(Sender: TObject);
+ procedure Button2Click(Sender: TObject);
+ private
+ { Private declarations }
+ a: TAviWriter;
+ public
+ { Public declarations }
+ procedure Parse(const S: String); override;
+ end;
+
+var
+ FsAvi: TFsAvi;
+
+implementation
+
+uses
+ fsframeunit, strz, mainunit;
+
+{$R *.DFM}
+
+{ Tavi }
+
+procedure TFsAvi.Parse(const S: String);
+var
+ s1: String;
+ f: TFsFrame;
+begin
+ if S='' then Exit;
+
+ s1 := UpperCase(ExtractWord(1, S, [' ']));
+
+ if s1='WRITE' then begin
+ a.FileName := Copy(S, Length(s1)+2, 255);
+ if a.Filename='' then
+ if sd1.Execute then begin
+ a.Filename := sd1.Filename;
+ if UpperCase(ExtractFileExt(a.Filename))<>'.AVI' then
+ a.Filename := a.Filename+'.avi';
+ end else
+ Exit;
+ a.Finish;
+ Exit;
+ end else
+ if s1='FPS' then begin
+ a.fps := MyStrToInt(Copy(S, Length(s1)+2, 255));
+ Exit;
+ end;
+
+ if not a.Prepared then
+ a.Prepare;
+
+ f := FindFrame(S);
+ if f=nil then Exit;
+
+ a.Width := f.d1.SurfaceWidth;
+ a.Height := f.d1.SurfaceHeight;
+
+ f.dDib.DIB.Assign(f.d1.Surface);
+ a.AddFrame(f.dDib.DIB);
+ main.SendReturnValues(PdName+'pos='+IntToStr(a.FramePos));
+end;
+
+procedure TFsAvi.FormCreate(Sender: TObject);
+begin
+ a := TAviWriter.Create(Self);
+end;
+
+procedure TFsAvi.FormDestroy(Sender: TObject);
+begin
+ a.Free;
+end;
+
+procedure TFsAvi.BitBtn1Click(Sender: TObject);
+begin
+ a.Write;
+end;
+
+procedure TFsAvi.Button1Click(Sender: TObject);
+begin
+ a.Prepare;
+end;
+
+procedure TFsAvi.Button2Click(Sender: TObject);
+begin
+ a.Finish;
+end;
+
+end.
diff --git a/Source/fsbrowserunit.dfm b/Source/fsbrowserunit.dfm
new file mode 100644
index 0000000..97c5299
--- /dev/null
+++ b/Source/fsbrowserunit.dfm
@@ -0,0 +1,35 @@
+inherited fsbrowser: Tfsbrowser
+ Left = 266
+ Top = 377
+ Width = 237
+ Height = 257
+ Caption = 'fsbrowser'
+ FormStyle = fsNormal
+ OldCreateOrder = True
+ PixelsPerInch = 96
+ TextHeight = 13
+ inherited d1: TDXDraw [1]
+ Width = 229
+ Height = 230
+ TabOrder = 2
+ end
+ inherited PanelMute: TPanel [2]
+ Width = 229
+ Height = 230
+ end
+ object br: TWebBrowser [3]
+ Left = 0
+ Top = 0
+ Width = 229
+ Height = 230
+ Align = alClient
+ TabOrder = 0
+ OnBeforeNavigate2 = brBeforeNavigate2
+ ControlData = {
+ 4C000000AB170000C51700000000000000000000000000000000000000000000
+ 000000004C000000000000000000000001000000E0D057007335CF11AE690800
+ 2B2E126208000000000000004C0000000114020000000000C000000000000046
+ 8000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000100000000000000000000000000000000000000}
+ end
+end
diff --git a/Source/fsbrowserunit.pas b/Source/fsbrowserunit.pas
new file mode 100644
index 0000000..b507902
--- /dev/null
+++ b/Source/fsbrowserunit.pas
@@ -0,0 +1,113 @@
+unit fsbrowserunit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ fsframeunit, Filez, DIB, Menus, DXDraws, ExtCtrls, OleCtrls, SHDocVw,
+ C2PhotoShopHost, ExtDlgs, StdCtrls;
+
+type
+ Tfsbrowser = class(Tfsframe)
+ br: TWebBrowser;
+ procedure FormCreate(Sender: TObject);
+ procedure brBeforeNavigate2(Sender: TObject; const pDisp: IDispatch;
+ var URL, Flags, TargetFrameName, PostData, Headers: OleVariant;
+ var Cancel: WordBool);
+ private
+ { Private declarations }
+ public
+ { Public declarations }
+ PdName: String;
+ procedure Parse(const S: String); override;
+ procedure CopyToSurface;
+ end;
+
+var
+ fsbrowser: Tfsbrowser;
+
+implementation
+
+uses
+ ActiveX,
+ Strz, mainunit;
+
+{$R *.DFM}
+
+{ Tfsbrowser }
+
+procedure Tfsbrowser.Parse(const S: String);
+var
+ s1, s2: String;
+begin
+ s1 := Trim(UpperCase(ExtractWord(1, S, [' '])));
+ if s1='' then Exit;
+ if (s1[1] in ['0'..'9']) and
+ (Pos('X', s1)>0) then begin
+ Width := MyStrToInt(ExtractWord(1, s1, ['X']));
+ Height := MyStrToInt(ExtractWord(2, s1, ['X']));
+ end else
+ if s1='OPEN' then begin
+ s2 := Copy(S, Length(s1)+2, 255);
+ br.Navigate(s2);
+ end else
+ if s1='STOP' then begin
+ br.Stop;
+ end else
+ if s1='REFRESH' then begin
+ br.Refresh;
+ end else begin
+ if
+ (UpperCase(Copy(S, 1, 4))='HTTP') or
+ (UpperCase(Copy(S, 1, 4))='FILE')
+ then
+ br.Navigate(S)
+ else
+ inherited Parse(S);
+ end;
+end;
+
+procedure Tfsbrowser.FormCreate(Sender: TObject);
+begin
+ inherited;
+ ClientWidth := 480;
+ ClientHeight := 360;
+end;
+
+procedure Tfsbrowser.CopyToSurface;
+var
+ DrawRect: TRect;
+begin
+ if (br.ClientWidth<>d1.Surface.Width) or
+ (br.ClientHeight<>d1.Surface.Height) then
+ d1.SetSize(br.ClientWidth, br.ClientHeight);
+
+ DrawRect := Rect(0, 0, d1.Surface.Width, d1.Surface.Height);
+ (br.Document as IViewObject).Draw(
+ DVASPECT_CONTENT, 1, nil, nil, 0,
+ d1.Surface.Canvas.Handle, @DrawRect, nil, nil, 0);
+
+ d1.Surface.Canvas.Release;
+end;
+
+procedure Tfsbrowser.brBeforeNavigate2(Sender: TObject;
+ const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
+ Headers: OleVariant; var Cancel: WordBool);
+var
+ St: String;
+begin
+ if UpperCase(Copy(URL, 1, 3))='FS:' then begin
+ St := Copy(URL, 4, 255);
+
+ St := SearchAndReplace(St, '%exepath',
+ ExtractFilePath(Application.ExeName));
+ St := SearchAndReplace(St, '//', '/');
+ St := SearchAndReplace(St, '\/', '/');
+
+ main.SendReturnValuesString(PdName+'link', St);
+ Cancel:=True;
+ end;
+end;
+
+end.
+
diff --git a/Source/fscopyunit.dfm b/Source/fscopyunit.dfm
new file mode 100644
index 0000000..922152d
--- /dev/null
+++ b/Source/fscopyunit.dfm
@@ -0,0 +1,26 @@
+object fscopy: Tfscopy
+ Left = 231
+ Top = 103
+ Width = 257
+ Height = 93
+ Caption = 'fscopy'
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ OldCreateOrder = False
+ WindowState = wsMinimized
+ OnClose = FormClose
+ OnCreate = FormCreate
+ PixelsPerInch = 96
+ TextHeight = 13
+ object copypsh: TC2PhotoShopHost
+ SerialNumber = 0
+ BackColor = clBlack
+ ForeColor = clBlack
+ Left = 8
+ Top = 8
+ end
+end
diff --git a/Source/fscopyunit.pas b/Source/fscopyunit.pas
new file mode 100644
index 0000000..0206d8f
--- /dev/null
+++ b/Source/fscopyunit.pas
@@ -0,0 +1,349 @@
+{ Copyright (C) 2001 Juha Vehviläinen
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.}
+
+unit fscopyunit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ mainunit, fsformunit, fsframeunit, StdCtrls, C2PhotoShopHost;
+
+type
+ TDrawStyles = (dsCopy, dsROP, dsAlpha, dsAdd, dsSub,
+ dsBlend, dsPlugin, dsFilter);
+ TRectTypes = (rtAll, rtRandom, rtSpecific);
+
+ Tfscopy = class(TFsForm)
+ copypsh: TC2PhotoShopHost;
+ procedure FormClose(Sender: TObject; var Action: TCloseAction);
+ procedure FormCreate(Sender: TObject);
+ private
+ { Private declarations }
+ f1, f2: TFsFrame;
+ DrawStyle: TDrawStyles;
+ dsROPMode: Integer;
+ SourceType: TRectTypes;
+ DestType: TRectTypes;
+ SourceRect, DestRect: TRect;
+ iAlpha, iAdd, iSub: Integer;
+ iBlend: Extended;
+ Transparent, MirrorLeftRight, MirrorUpdown: Boolean;
+ iPlugin, iPluginArgs: String;
+ iFilter, iFilterArgs: String;
+
+ procedure GetFrames(const S: String);
+ public
+ { Public declarations }
+ procedure Parse(const S: String); override;
+ end;
+
+var
+ fscopy: Tfscopy;
+
+implementation
+
+{$R *.DFM}
+
+uses
+ DxDraws, DirectX,
+ effectsunit, fsbrowserunit, pshostunit,
+ Strz;
+
+procedure Tfscopy.FormClose(Sender: TObject; var Action: TCloseAction);
+begin
+ Action := caFree;
+end;
+
+procedure Tfscopy.GetFrames(const S: String);
+const
+ f1name: String = '-1';
+ f2name: String = '-1';
+var
+ s1, s2: String;
+begin
+ if (Pos(' ', S)=0) then Exit;
+
+ s1 := UpperCase(ExtractWord(1, S, [' ']));
+ s2 := UpperCase(ExtractWord(2, S, [' ']));
+
+ if (s1<>f1name) or (f1=nil) then
+ f1 := FindFrame(s1);
+
+ if (s2<>f2name) or (f2=nil) then
+ f2 := FindFrame(s2);
+
+ f1name := s1; f2name := s2;
+end;
+
+procedure Tfscopy.Parse(const S: String);
+
+ procedure SwapInt(var i1, i2: Integer);
+ var
+ tmpi: Integer;
+ begin
+ tmpi := i1;
+ i1 := i2;
+ i2 := tmpi;
+ end;
+
+var
+ s1: String;
+ bltFlags: Cardinal;
+ df: TDDBltFX;
+ ddck: TDDColorKey;
+ sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2: Integer;
+begin
+ if (S='') then Exit;
+
+ s1 := UpperCase(ExtractWord(1, S, [' ']));
+
+ if Pos('FS.FRAME', s1)=0 then
+ if s1='COPY' then begin DrawStyle := dsCopy; Exit; end else
+ if s1='BLEND' then begin
+ DrawStyle := dsBlend;
+ iBlend := MyStrToFloat(ExtractWord(2, S, [' ']));
+ Exit;
+ end else
+ if s1='ALPHA' then begin
+ DrawStyle := dsAlpha;
+ iAlpha := MyStrToInt(ExtractWord(2, S, [' ']));
+ Exit;
+ end else
+ if s1='ADD' then begin
+ DrawStyle := dsAdd;
+ iAdd := MyStrToInt(ExtractWord(2, S, [' ']));
+ Exit;
+ end else
+ if s1='SUB' then begin
+ DrawStyle := dsSub;
+ iSub := MyStrToInt(ExtractWord(2, S, [' ']));
+ Exit;
+ end else
+ if s1='SOURCE' then begin
+ if Pos(' ', S)>0 then begin // at least x1 specified
+ SourceRect := StrToRect(Copy(S, Length(s1)+2, 255));
+ SourceType := rtSpecific;
+ Exit;
+ end;
+ end else
+ if s1='DEST' then begin
+ if Pos(' ', S)>0 then begin // at least x1 specified
+ DestRect := StrToRect(Copy(S, Length(s1)+2, 255));
+ DestType := rtSpecific;
+ Exit;
+ end;
+ end else
+ if s1='SOURCE_ALL' then begin SourceType := rtAll; Exit; end else
+ if s1='SOURCE_RANDOM' then begin SourceType := rtRandom; Exit; end else
+ if s1='DEST_ALL' then begin DestType := rtAll; Exit; end else
+ if s1='DEST_RANDOM' then begin DestType := rtRandom; Exit; end else
+
+ if s1='BLACKNESS' then begin DrawStyle := dsROP; dsROPMode := cmBlackness; Exit; end else
+ if s1='DSTINVERT' then begin DrawStyle := dsROP; dsROPMode := cmDstInvert; Exit; end else
+ if s1='MERGECOPY' then begin DrawStyle := dsROP; dsROPMode := cmMergeCopy; Exit; end else
+ if s1='MERGEPAINT' then begin DrawStyle := dsROP; dsROPMode := cmMergePaint; Exit; end else
+ if s1='NOTSRCCOPY' then begin DrawStyle := dsROP; dsROPMode := cmNotSrcCopy; Exit; end else
+ if s1='NOTSRCERASE' then begin DrawStyle := dsROP; dsROPMode := cmNotSrcErase; Exit; end else
+ if s1='PATCOPY' then begin DrawStyle := dsROP; dsROPMode := cmPatCopy; Exit; end else
+ if s1='PATINVERT' then begin DrawStyle := dsROP; dsROPMode := cmPatInvert; Exit; end else
+ if s1='PATPAINT' then begin DrawStyle := dsROP; dsROPMode := cmPatPaint; Exit; end else
+ if s1='SRCAND' then begin DrawStyle := dsROP; dsROPMode := cmSrcAnd; Exit; end else
+ if s1='SRCCOPY' then begin DrawStyle := dsROP; dsROPMode := cmSrcCopy; Exit; end else
+ if s1='SRCERASE' then begin DrawStyle := dsROP; dsROPMode := cmSrcErase; Exit; end else
+ if s1='SRCINVERT' then begin DrawStyle := dsROP; dsROPMode := cmSrcInvert; Exit; end else
+ if s1='SRCPAINT' then begin DrawStyle := dsROP; dsROPMode := cmSrcPaint; Exit; end else
+ if s1='WHITENESS' then begin DrawStyle := dsROP; dsROPMode := cmWhiteness; Exit; end else
+
+ if s1='TRANSPARENT_0' then begin Transparent := False; Exit; end else
+ if s1='TRANSPARENT_1' then begin Transparent := True; Exit; end else
+ if s1='MIRRORLEFTRIGHT_0' then begin MirrorLeftRight := False; Exit; end else
+ if s1='MIRRORLEFTRIGHT_1' then begin MirrorLeftRight := True; Exit; end else
+ if s1='MIRRORUPDOWN_0' then begin MirrorUpDown := False; Exit; end else
+ if s1='MIRRORUPDOWN_1' then begin MirrorUpDown := True; Exit; end else
+ if main.Plugins.IsPlugin(s1) then begin
+ DrawStyle := dsPlugin;
+ iPlugin := s1;
+ iPluginArgs := Copy(S, Length(s1)+2, 255);
+ Exit;
+ end else
+ if pshostunit.IsFilter(s1) then begin
+ DrawStyle := dsFilter;
+ iFilter := s1;
+ iFilterArgs := Copy(S, Length(s1)+2, 255);
+ Exit;
+ end;
+
+
+ GetFrames(S);
+ if (f1=nil) or (f2=nil) then Exit;
+ if (f1.d1=nil) or (f2.d1=nil) then Exit;
+
+ if (f1.ParentWindow>0) and not IsWindow(f1.ParentWindow) then Exit;
+ if (f2.ParentWindow>0) and not IsWindow(f2.ParentWindow) then Exit;
+
+ if f1 is TFsBrowser then begin
+ (f1 as TFsBrowser).CopyToSurface;
+ end;
+
+ case SourceType of
+ rtAll: begin
+ sx1 := 0;
+ sy1 := 0;
+ sx2 := f1.d1.Surface.Width;
+ sy2 := f1.d1.Surface.Height;
+ end;
+ rtRandom: begin
+ sx1 := Random(f1.d1.Surface.Width);
+ sx2 := Random(f1.d1.Surface.Width);
+ sy1 := Random(f1.d1.Surface.Height);
+ sy2 := Random(f1.d1.Surface.Height);
+ end;
+ rtSpecific: begin
+ sx1 := SourceRect.Left;
+ sy1 := SourceRect.Top;
+ sx2 := SourceRect.Right;
+ sy2 := SourceRect.Bottom;
+ end;
+ end;
+
+ case DestType of
+ rtAll: begin
+ dx1 := 0;
+ dy1 := 0;
+ dx2 := f2.d1.Surface.Width;
+ dy2 := f2.d1.Surface.Height;
+ end;
+ rtRandom: begin
+ dx1 := Random(f2.d1.Surface.Width);
+ dx2 := Random(f2.d1.Surface.Width);
+ dy1 := Random(f2.d1.Surface.Height);
+ dy2 := Random(f2.d1.Surface.Height);
+ end;
+ rtSpecific: begin
+ dx1 := DestRect.Left;
+ dy1 := DestRect.Top;
+ dx2 := DestRect.Right;
+ dy2 := DestRect.Bottom;
+ end;
+ end;
+
+ if sx2<sx1 then swapint(sx2, sx1);
+ if sy2<sy1 then swapint(sy2, sy1);
+ if dx2<dx1 then swapint(dx2, dx1);
+ if dy2<dy1 then swapint(dy2, dy1);
+
+ if sx2=sx1 then inc(sx2);
+ if sy2=sy1 then inc(sy2);
+ if dx2=dx1 then inc(dx2);
+ if dy2=dy1 then inc(dy2);
+
+ if sx1<0 then sx1:=0;
+ if sy1<0 then sy1:=0;
+ if sx2>f1.d1.Surface.Width then sx2:=f1.d1.Surface.Width;
+ if sy2>f1.d1.Surface.Height then sy2:=f1.d1.Surface.Height;
+ if dx1<0 then dx1:=0;
+ if dy1<0 then dy1:=0;
+ if dx2>f2.d1.Surface.Width then dx2:=f1.d1.Surface.Width;
+ if dy2>f2.d1.Surface.Height then dy2:=f2.d1.Surface.Height;
+
+ case DrawStyle of
+ dsCopy: begin
+ ddck.dwColorSpaceLowValue := 0;
+ ddck.dwColorSpaceHighValue := 0;
+ DF.dwsize := SizeOf(DF);
+ DF.dwROP := cmSrcCopy;
+ DF.dwDDFX := 0;
+ DF.ddckSrcColorkey := ddck;
+ DF.ddckDestColorkey := ddck;
+ bltFlags := DDBLT_DDFX;
+ if Transparent then bltFlags := bltFlags or DDBLT_KEYSRCOVERRIDE;
+ if MirrorLeftRight then
+ DF.dwDDFX := DF.dwDDFX or DDBLTFX_MIRRORLEFTRIGHT;
+ if MirrorUpDown then
+ DF.dwDDFX := DF.dwDDFX or DDBLTFX_MIRRORUPDOWN;
+
+ if not f2.d1.Surface.Blt(
+ Rect(dx1, dy1, dx2, dy2),
+ Rect(sx1, sy1, sx2, sy2),
+ bltFlags or {DDBLT_ROP or} DDBLT_WAIT,
+ DF, f1.d1.Surface ) then
+ main.Post(Self.Name+': blt failed.')
+ else
+ f2.FlipRequest;
+ end;
+ dsROP: begin
+ StretchBlt(f2.d1.Surface.Canvas.Handle,
+ dx1, dy1, dx2-dx1, dy2-dy1,
+ f1.d1.Surface.Canvas.Handle,
+ sx1, sy1, sx2-sx1, sy2-sy1, dsROPMode);
+
+ f1.d1.Surface.Canvas.Release;
+ f2.d1.Surface.Canvas.Release;
+ f2.FlipRequest;
+ end;
+ dsAlpha: begin
+ f2.d1.Surface.DrawAlpha(
+ Rect(dx1, dy1, dx2, dy2),
+ Rect(sx1, sy1, sx2, sy2),
+ f1.d1.Surface, False, iAlpha);
+ f2.FlipRequest;
+ end;
+ dsAdd: begin
+ f2.d1.Surface.DrawAdd(
+ Rect(dx1, dy1, dx2, dy2),
+ Rect(sx1, sy1, sx2, sy2),
+ f1.d1.Surface, False, iAdd);
+ f2.FlipRequest;
+ end;
+ dsSub: begin
+ f2.d1.Surface.DrawSub(
+ Rect(dx1, dy1, dx2, dy2),
+ Rect(sx1, sy1, sx2, sy2),
+ f1.d1.Surface, False, iSub);
+ f2.FlipRequest;
+ end;
+ dsBlend: begin
+ blend(f1.d1.Surface, f2.d1.Surface, iBlend);
+ f2.FlipRequest;
+ end;
+ dsPlugin: begin
+ if main.Plugins.CallCopy(f1.d1.Surface, f2.d1.Surface,
+ iPlugin, iPluginArgs) then begin
+ f1.FlipRequest;
+ f2.FlipRequest;
+ end;
+ end;
+ dsFilter: begin
+ if pshostunit.Filter_copy(Self.copypsh,
+ f1.d1.Surface, f2.d1.Surface,
+ iFilter, iFilterArgs) then begin
+ f1.FlipRequest;
+ f2.FlipRequest;
+ end;
+ end;
+ end;
+end;
+
+procedure Tfscopy.FormCreate(Sender: TObject);
+begin
+ f1 := nil; f2 := nil;
+ DrawStyle := dsCopy;
+ SourceType := rtAll;
+ DestType := rtAll;
+ iAlpha := 50; iAdd := 255; iSub := 255;
+ Transparent := False;
+ MirrorLeftRight := False;
+ MirrorUpDown := False;
+end;
+
+end.
+
diff --git a/Source/fsdrawunit.dfm b/Source/fsdrawunit.dfm
new file mode 100644
index 0000000..9a73308
--- /dev/null
+++ b/Source/fsdrawunit.dfm
@@ -0,0 +1,17 @@
+object fsdraw: Tfsdraw
+ Left = 245
+ Top = 177
+ Width = 247
+ Height = 106
+ Caption = 'fsdraw'
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ OldCreateOrder = False
+ OnCreate = FormCreate
+ PixelsPerInch = 96
+ TextHeight = 13
+end
diff --git a/Source/fsdrawunit.pas b/Source/fsdrawunit.pas
new file mode 100644
index 0000000..c67b3d4
--- /dev/null
+++ b/Source/fsdrawunit.pas
@@ -0,0 +1,101 @@
+{ Copyright (C) 2001 Juha Vehviläinen
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.}
+
+unit fsdrawunit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ fsformunit, fsframeunit, fstextunit;
+
+type
+ Tfsdraw = class(TFsForm)
+ procedure FormCreate(Sender: TObject);
+ private
+ dest: TFsFrame;
+ { Private declarations }
+ public
+ { Public declarations }
+ procedure Parse(const S: String); override;
+ end;
+
+var
+ fsdraw: Tfsdraw;
+
+implementation
+
+uses
+ mainunit, Strz;
+
+{$R *.DFM}
+
+{ Tfsdraw }
+
+procedure Tfsdraw.Parse(const S: String);
+var
+ r: TRect;
+ x, y: Integer;
+ s1, sa: String;
+ b: Boolean;
+begin
+ if (S='') then Exit;
+ s1 := ExtractWord(WordCount(S, [' ']), S, [' ']);
+ dest := FindFrame(s1);
+ if (dest=nil) or (dest.d1=nil) then Exit;
+
+ sa := UpperCase(Copy(S, 1, Pos(s1, S)-2));
+
+ b := ParsePenProperties(dest.d1.Surface.Canvas, sa);
+ dest.d1.Surface.Canvas.Release;
+
+ s1 := ExtractWord(1, sa, [' ']);
+
+ if b then Exit else
+ if s1='MODE_SOLID' then begin
+ dest.d1.Surface.Canvas.Brush.Style := bsSolid;
+ dest.d1.Surface.Canvas.Release;
+ end else
+ if s1='MODE_CLEAR' then begin
+ dest.d1.Surface.Canvas.Brush.Style := bsClear;
+ dest.d1.Surface.Canvas.Release;
+ end else
+ if s1='RECT' then begin
+ dest.d1.Surface.Canvas.Rectangle(StrToRect(Copy(sa, Length(s1)+2, 255)));
+ dest.d1.Surface.Canvas.Release;
+ dest.FlipRequest;
+ end else
+ if s1='LINE' then begin
+ r := StrToRect(Copy(sa, Length(s1)+2, 255));
+ with dest.d1.Surface.Canvas do begin
+ MoveTo(r.Left, r.Top);
+ LineTo(r.Right, r.Bottom);
+ end;
+ dest.d1.Surface.Canvas.Release;
+ dest.FlipRequest;
+ end else
+ if s1='PLOT' then begin
+ x := MyStrToInt(ExtractWord(2, sa, [' ']));
+ y := MyStrToInt(ExtractWord(3, sa, [' ']));
+ dest.d1.Surface.Canvas.Pixels[x, y] :=
+ dest.d1.Surface.Canvas.Pen.Color;
+ dest.d1.Surface.Canvas.Release;
+ dest.FlipRequest;
+ end else
+end;
+
+procedure Tfsdraw.FormCreate(Sender: TObject);
+begin
+ dest := nil;
+end;
+
+end.
+
diff --git a/Source/fsformunit.pas b/Source/fsformunit.pas
new file mode 100644
index 0000000..3f71db8
--- /dev/null
+++ b/Source/fsformunit.pas
@@ -0,0 +1,18 @@
+unit fsformunit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
+
+type
+ TFsForm = class(TForm)
+ public
+ PdName: String;
+ procedure Parse(const S: String); virtual; abstract;
+ end;
+
+implementation
+
+end.
+ \ No newline at end of file
diff --git a/Source/fsframeunit.dfm b/Source/fsframeunit.dfm
new file mode 100644
index 0000000..3e38f21
--- /dev/null
+++ b/Source/fsframeunit.dfm
@@ -0,0 +1,146 @@
+object fsframe: Tfsframe
+ Left = 583
+ Top = 507
+ Width = 277
+ Height = 198
+ Caption = 'fs.frame'
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ OldCreateOrder = False
+ PopupMenu = PopupMenu1
+ Position = poDefaultSizeOnly
+ OnClose = FormClose
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ OnMouseWheel = FormMouseWheel
+ PixelsPerInch = 96
+ TextHeight = 13
+ object LabelFoo: TLabel
+ Left = 8
+ Top = 136
+ Width = 44
+ Height = 13
+ Caption = 'LabelFoo'
+ Visible = False
+ end
+ object PanelMute: TPanel
+ Left = 0
+ Top = 0
+ Width = 269
+ Height = 171
+ Align = alClient
+ BevelOuter = bvNone
+ Caption = 'mute'
+ Ctl3D = True
+ ParentCtl3D = False
+ TabOrder = 1
+ end
+ object d1: TDXDraw
+ Left = 0
+ Top = 0
+ Width = 269
+ Height = 171
+ AutoInitialize = True
+ AutoSize = False
+ Color = clBtnFace
+ Display.FixedBitCount = False
+ Display.FixedRatio = False
+ Display.FixedSize = False
+ Options = [doStretch, doDirectX7Mode, doHardware, doSelectDriver]
+ SurfaceHeight = 171
+ SurfaceWidth = 269
+ Align = alClient
+ PopupMenu = PopupMenu1
+ TabOrder = 0
+ OnMouseDown = d1MouseDown
+ OnMouseMove = d1MouseMove
+ OnMouseUp = d1MouseUp
+ end
+ object PopupMenu1: TPopupMenu
+ OnPopup = PopupMenu1Popup
+ Left = 8
+ Top = 8
+ object MiBufferImages: TMenuItem
+ Caption = 'Buffer images'
+ OnClick = MiBufferImagesClick
+ end
+ object MiSaveFrame: TMenuItem
+ Caption = 'Save this image as ..'
+ OnClick = MiSaveFrameClick
+ end
+ object Mi11: TMenuItem
+ Caption = 'zoom 1:&1'
+ OnClick = Mi11Click
+ end
+ object Mi12: TMenuItem
+ Caption = 'zoom 1:&2'
+ OnClick = Mi12Click
+ end
+ object Mi176x144: TMenuItem
+ Caption = 'zoom 176x144'
+ OnClick = Mi176x144Click
+ end
+ object MiMute: TMenuItem
+ Caption = 'Mute'
+ OnClick = MiMuteClick
+ end
+ object MiBorders: TMenuItem
+ Caption = 'Borders'
+ Checked = True
+ OnClick = MiBordersClick
+ end
+ object MiStayOnTop: TMenuItem
+ Caption = 'StayOnTop'
+ OnClick = MiStayOnTopClick
+ end
+ object MiMouseTrack: TMenuItem
+ Caption = 'MouseTrack'
+ OnClick = MiMouseTrackClick
+ end
+ object MiHideCursor: TMenuItem
+ Caption = 'HideCursor'
+ OnClick = MiHideCursorClick
+ end
+ object MiUndock: TMenuItem
+ Caption = 'Undock'
+ OnClick = MiUndockClick
+ end
+ end
+ object dDib: TDXDIB
+ Left = 8
+ Top = 40
+ end
+ object dirBuffer: TScanDir
+ OnHandleFile = dirBufferHandleFile
+ Left = 8
+ Top = 72
+ end
+ object opd1: TOpenPictureDialog
+ Filter = 'All (*.jpg;*.bmp;*.avi)|*.jpg;*.bmp;*.avi'
+ Options = [ofHideReadOnly, ofAllowMultiSelect, ofFileMustExist, ofEnableSizing]
+ Left = 8
+ Top = 104
+ end
+ object framepsh: TC2PhotoShopHost
+ SerialNumber = 0
+ BackColor = clBlack
+ ForeColor = clBlack
+ Left = 40
+ Top = 8
+ end
+ object svd1: TSaveDialog
+ Filter = '*.bmp|BMP files'
+ Options = [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist, ofEnableSizing]
+ Left = 40
+ Top = 104
+ end
+ object dirUse: TScanDir
+ OnHandleFile = dirUseHandleFile
+ Left = 40
+ Top = 72
+ end
+end
diff --git a/Source/fsframeunit.pas b/Source/fsframeunit.pas
new file mode 100644
index 0000000..e3316a7
--- /dev/null
+++ b/Source/fsframeunit.pas
@@ -0,0 +1,1098 @@
+{ Copyright (C) 2001 Juha Vehviläinen
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.}
+
+unit fsframeunit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ Menus, Jpeg, DXDraws,
+ FastDIB, fsDcAvi,
+ fsformunit, ExtCtrls, DIB, Filez, ExtDlgs, C2PhotoShopHost, Buttons,
+ StdCtrls;
+
+type
+ TFastDIBList = TList;
+
+ Tfsframe = class(TFsForm)
+ d1: TDXDraw;
+ PopupMenu1: TPopupMenu;
+ Mi11: TMenuItem;
+ Mi12: TMenuItem;
+ MiMute: TMenuItem;
+ dDib: TDXDIB;
+ MiBorders: TMenuItem;
+ MiStayOnTop: TMenuItem;
+ dirBuffer: TScanDir;
+ PanelMute: TPanel;
+ MiMouseTrack: TMenuItem;
+ MiBufferImages: TMenuItem;
+ opd1: TOpenPictureDialog;
+ MiSaveFrame: TMenuItem;
+ Mi176x144: TMenuItem;
+ MiHideCursor: TMenuItem;
+ framepsh: TC2PhotoShopHost;
+ MiUndock: TMenuItem;
+ svd1: TSaveDialog;
+ dirUse: TScanDir;
+ LabelFoo: TLabel;
+ procedure FormClose(Sender: TObject; var Action: TCloseAction);
+ procedure Mi11Click(Sender: TObject);
+ procedure Mi12Click(Sender: TObject);
+ procedure MiMuteClick(Sender: TObject);
+ procedure FormCreate(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure MiBordersClick(Sender: TObject);
+ procedure MiStayOnTopClick(Sender: TObject);
+ procedure dirBufferHandleFile(const SearchRec: TSearchRec;
+ const FullPath: String);
+ procedure d1MouseDown(Sender: TObject; Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
+ procedure d1MouseMove(Sender: TObject; Shift: TShiftState; X,
+ Y: Integer);
+ procedure d1MouseUp(Sender: TObject; Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
+ procedure MiMouseTrackClick(Sender: TObject);
+ procedure MiBufferImagesClick(Sender: TObject);
+ procedure PopupMenu1Popup(Sender: TObject);
+ procedure MiSaveFrameClick(Sender: TObject);
+ procedure Mi176x144Click(Sender: TObject);
+ procedure MiHideCursorClick(Sender: TObject);
+ procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
+ WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
+ procedure MiUndockClick(Sender: TObject);
+ procedure dirUseHandleFile(const SearchRec: TSearchRec;
+ const FullPath: String);
+ protected
+ fx1, fx2: TFastDIB;
+ private
+ { Private declarations }
+ AutoFlip, Smooth: Boolean;
+ picBuf: TFastDIBList;
+ picIndex: Integer;
+ AutoSend: Boolean;
+ AutoSend_Address: String;
+ AutoSend_jpegqualitynet: Integer;
+ AutoSend_sendjpg: Boolean;
+ MouseTrack: Boolean; // report mouse x y
+ MouseRect: Boolean; // report dragged rectangle
+ FHideCursor: Boolean; // hide cursor in this frame
+ jpgquality: Integer;
+ jpegqualitynet: Integer;
+ prevtop: Integer;
+ prevmute: Boolean;
+ filelist: TStringList;
+ filelistIndex: Integer;
+
+ procedure ClearPicBuf;
+ procedure StayOnTop(const Yes: Boolean);
+ function Getnextfilename(const dir, ext: String): String;
+ procedure _prefx;
+ procedure _postfx(const f: TFastDIB);
+ procedure _postavi;
+ procedure SendMouseTrack(const X, Y: Integer);
+ procedure SendMouseRect(const x1, y1, x2, y2: Integer);
+ function GetDocked: Boolean;
+ procedure SetHideCursor(const Value: Boolean);
+ procedure NewButton(const receivename: String;
+ const x, y: Integer; const buttoncaption: String);
+ public
+ { Public declarations }
+ avi: TDcAviPlayer;
+ NameTag: String;
+ procedure Borders(const Yes: Boolean);
+ procedure Parse(const S: String); override;
+ procedure FlipRequest;
+ procedure AutoSendRequest;
+ procedure HandleDroppedFile(const S: String);
+ property Docked: Boolean read GetDocked;
+ property HideCursor: Boolean read FHideCursor write SetHideCursor;
+ end;
+
+var
+ fsframe: Tfsframe;
+
+function FindFrame(const S: String): TFsFrame;
+
+implementation
+
+{$R *.DFM}
+
+uses
+ ShellApi,
+ FastFX, FastFiles,
+ mainunit, effectsunit, fsspeedbutton,
+ Strz,
+ FileCtrl,
+ pshostunit;
+
+function FindFrame(const S: String): TFsFrame;
+begin
+ Result := TFsFrame(main.FindComponent(main.CompName(S)));
+end;
+
+{ Tfsframe }
+
+procedure Tfsframe._prefx;
+begin
+ dDib.DIB.Assign( d1.Surface );
+ fx1.LoadFromHandle( dDib.DIB.Handle );
+end;
+
+procedure Tfsframe._postfx(const f: TFastDIB);
+begin
+ f.Draw(d1.Surface.Canvas.Handle, 0, 0);
+ d1.Surface.Canvas.Release;
+ FlipRequest;
+end;
+
+procedure Tfsframe._postavi;
+begin
+ d1.SetSize(avi.Width, avi.Height);
+ avi.DrawFrameToDC(d1.Surface.Canvas.Handle);
+ d1.Surface.Canvas.Release;
+ FlipRequest;
+end;
+
+procedure Tfsframe.Parse(const S: String);
+var
+ fs, s1, Ext: String;
+ i, o, u, x, y: Integer;
+ fpic: TFastDIB;
+ savejpg, sendjpg: Boolean;
+ R: TRect;
+begin
+ if S='' then Exit;
+ if (ParentWindow>0) and not
+ IsWindow(ParentWindow) then Exit;
+
+ s1 := UpperCase(ExtractWord(1, S, [' ']));
+ Ext := UpperCase(ExtractFileExt(S));
+ if s1='SAVE' then begin // SAVE <dir> <"bmp" or number for jpeg quality>
+ s1 := ExtractWord(2, S, [' ']);
+ if s1='' then Exit;
+ savejpg := True;
+ if WordCount(S, [' '])>2 then begin
+ Ext := UpperCase(ExtractWord(3, S, [' ']));
+ if Ext='BMP' then savejpg := False else begin
+ i := StrToInt(Ext); if i>0 then jpgquality := i;
+ end;
+ end;
+ if not DirectoryExists(s1) then begin
+ main.Post('Save: Directory '+s1+' doesn''t exist.');
+ Exit;
+ end;
+ if savejpg then Ext:='.jpg' else Ext:='.bmp';
+ fs := Getnextfilename(s1, Ext);
+ _prefx;
+ if savejpg then
+ SaveJPGFile(fx1, s1+'\'+fs, jpgquality)
+ else
+ fx1.SaveToFile(s1+'\'+fs);
+ end;
+ if (s1='BUFFER') or (Ext='.JPG') or (Ext='.BMP') then begin
+ fs := S;
+ if UpperCase(ExtractWord(1, fs, [' ']))<>'BUFFER' then begin
+ if main.FileExistsInSearchPath(fs) then begin
+ d1.Surface.LoadFromFile(fs);
+ FlipRequest;
+ end else
+ main.Post('Failed opening '+fs);
+ end else begin
+ fs := Copy(fs, 8, 255);
+ if main.FileExistsInSearchPath(fs) then begin
+ main.Post('buffering '+fs);
+ fpic := TFastDIB.Create;
+ fpic.Bpp := 16;
+ if Ext='.JPG' then
+ LoadJPGFile(fpic, fs, True)
+ else if Ext='.BMP' then
+ fpic.LoadFromFile(fs);
+ picBuf.Add(fpic);
+ end else
+ if DirectoryExists(fs) then begin
+ main.Post('buffering directory '+fs);
+ dirBuffer.Scan(fs);
+ end else
+ main.Post('Failed opening '+fs);
+ end;
+ end else
+ if s1='FLIP_MANUAL' then begin
+ AutoFlip := False;
+ end else
+ if s1='FLIP_AUTO' then begin
+ AutoFlip := True;
+ end else
+ if s1='FLIP' then begin
+ d1.Flip;
+ AutoSendRequest;
+ end else
+ if s1='NEXT' then begin
+ if picBuf.Count=0 then begin
+ if filelist.Count=0 then begin
+ if avi.Open then begin
+ if avi.Position=avi.FrameCount-1 then
+ avi.Seek(0)
+ else
+ avi.Seek(avi.Position+1);
+ _postavi;
+ end;
+ Exit;
+ end;
+ Inc(filelistIndex);
+ if filelistIndex>=filelist.Count then
+ filelistIndex := 0;
+ Parse(filelist.Strings[filelistIndex]);
+ Exit;
+ end;
+ Inc(picIndex);
+ if picIndex>=picBuf.Count then
+ picIndex := 0;
+ fpic := picBuf[picIndex];
+ d1.Surface.SetSize(fpic.Width, fpic.Height);
+ _postfx(fpic);
+ end else
+ if s1='PREV' then begin
+ if picBuf.Count=0 then begin
+ if filelist.Count=0 then begin
+ // avi
+ if avi.Open then begin
+ if avi.Position=0 then
+ avi.Seek(avi.FrameCount-1)
+ else
+ avi.Seek(avi.Position-1);
+ _postavi;
+ end;
+ Exit;
+ end;
+
+ // filelist
+ Dec(filelistIndex);
+ if filelistIndex<0 then
+ filelistIndex := filelist.Count-1;
+ Parse(filelist.Strings[filelistIndex]);
+ Exit;
+
+ end;
+ // picbuf
+ Dec(picIndex);
+ if picIndex<0 then
+ picIndex := PicBuf.Count-1;
+ fpic := picBuf[picIndex];
+ d1.Surface.SetSize(fpic.Width, fpic.Height);
+ _postfx(fpic);
+
+ end else
+ if s1='SEEK' then begin
+ s1 := ExtractWord(2, S, [' ']);
+ if s1='' then Exit;
+ if picBuf.Count=0 then begin
+ if filelist.Count=0 then begin
+ if avi.Open then begin
+ if s1[Length(s1)]='*' then
+ i := Trunc(MyStrToFloat(Copy(s1, 1, Length(s1)-1))*avi.FrameCount-1)
+ else
+ i := MyStrToInt(s1);
+ avi.Seek(i);
+ _postavi;
+ end;
+ Exit;
+ end;
+
+ if s1[Length(s1)]='*' then
+ i := Trunc(MyStrToFloat(Copy(s1, 1, Length(s1)-1))*filelist.Count-1)
+ else
+ i := MyStrToInt(s1);
+ if (i>=0) and (i<filelist.Count) then
+ Parse(filelist.Strings[i]);
+ Exit;
+ end;
+ if s1[Length(s1)]='*' then
+ i := Trunc(MyStrToFloat(Copy(s1, 1, Length(s1)-1))*picBuf.Count-1)
+ else
+ i := MyStrToInt(s1);
+ if (i>=0) and (i<picBuf.Count) then begin
+ fpic := picBuf[i];
+ d1.Surface.SetSize(fpic.Width, fpic.Height);
+ _postfx(fpic);
+ end;
+ end else
+ if s1='RANDOM' then begin
+ if picBuf.Count=0 then begin
+ if filelist.Count=0 then begin
+ if avi.Open then begin
+ avi.Seek(Random(avi.FrameCount));
+ _postavi;
+ end;
+ Exit;
+ end;
+ Parse(filelist.Strings[Random(filelist.Count)]);
+ Exit;
+ end;
+ fpic := picBuf[Random(picBuf.Count)];
+ d1.Surface.SetSize(fpic.Width, fpic.Height);
+ _postfx(fpic);
+ end else
+ if s1='CLEAR' then begin
+ ClearPicBuf;
+ filelist.Clear;
+ end else
+ if (Ext='.AVI') then begin
+ fs := S;
+ if main.FileExistsInSearchPath(fs) then begin
+ avi.FileName := fs;
+ if avi.Open then begin
+ avi.Seek(0);
+ _postavi;
+ end;
+ end else
+ main.Post('Failed opening '+fs);
+ end else
+ if S[1] in ['0'..'9'] then begin
+ s1 := UpperCase(S);
+ if Pos('X', s1)>0 then begin
+ x := MyStrToInt(Trim(ExtractWord(1, s1, ['X'])));
+ y := MyStrToInt(Trim(ExtractWord(2, s1, ['X'])));
+ d1.Surface.SetSize(x, y);
+ d1.Initialize;
+ ClientWidth := x;
+ ClientHeight := y;
+ end else
+ if Pos('+', s1)>0 then begin
+ x := MyStrToInt(Trim(ExtractWord(1, s1, ['+'])));
+ y := MyStrToInt(Trim(ExtractWord(2, s1, ['+'])));
+ Left := x;
+ Top := y;
+ end else
+ Exit;
+ end else
+ if s1='DISPLAY' then begin
+ s1 := UpperCase(Trim(Copy(S, 8, 255)));
+ x := MyStrToInt(Trim(ExtractWord(1, s1, ['X'])));
+ y := MyStrToInt(Trim(ExtractWord(2, s1, ['X'])));
+ if (x>0) and (y>0) then begin
+ ClientWidth := x;
+ ClientHeight := y;
+ end;
+ end else
+ if s1='BORDERS_0' then begin
+ Borders(False);
+ end else
+ if s1='BORDERS_1' then begin
+ Borders(True);
+ end else
+ if s1='STAYONTOP_1' then begin
+ StayOnTop(True);
+ end else
+ if s1='STAYONTOP_0' then begin
+ StayOnTop(False);
+ end else
+ if s1='MUTE_0' then begin
+ MiMute.Checked := True;
+ MiMute.Click;
+ end else
+ if s1='MUTE_1' then begin
+ MiMute.Checked := False;
+ MiMute.Click;
+ end else
+ // FastLib effects
+ if s1='MOSAIC' then begin
+ i := MyStrToInt(ExtractWord(2, S, [' ']));
+ if i=0 then i:=6;
+ _prefx;
+ FastFX.Mosaic(fx1, i, i);
+ _postfx(fx1);
+ end else
+ if s1='SMOOTH_0' then begin
+ Smooth := False;
+ end else
+ if s1='SMOOTH_1' then begin
+ Smooth := True;
+ end else
+ if s1='ROTATE' then begin
+ i := MyStrToInt(ExtractWord(2, S, [' ']));
+ if i=0 then Exit;
+ _prefx;
+ fx2.SetSize(fx1.Width, fx1.Height, fx1.Bpp);
+ fx2.Clear(IntToColor(0));
+ FastFX.Rotate(fx1, fx2, i, Smooth);
+ _postfx(fx2);
+ end else
+ if s1='ROTOZOOM' then begin
+ i := MyStrToInt(ExtractWord(2, S, [' ']));
+ o := MyStrToInt(ExtractWord(3, S, [' ']));
+ if (i=0) and (o=0) then Exit;
+ _prefx;
+ fx2.SetSize(fx1.Width, fx1.Height, fx1.Bpp);
+ fx2.Clear(IntToColor(0));
+ FastFX.Rotozoom(fx1, fx2, i, o, Smooth);
+ _postfx(fx2);
+ end else
+ if s1='SATURATION' then begin
+ i := MyStrToInt(ExtractWord(2, S, [' ']));
+ _prefx;
+ FastFX.Saturation(fx1, i);
+ _postfx(fx1);
+ end else
+ if s1='INVERT' then begin
+ _prefx;
+ FastFX.Invert(fx1);
+ _postfx(fx1);
+ end else
+ if s1='SOFT' then begin
+ _prefx;
+ FastFX.QuickSoft(fx1);
+ _postfx(fx1);
+ end else
+ if s1='SHARP' then begin
+ _prefx;
+ FastFX.QuickSharp(fx1);
+ _postfx(fx1);
+ end else
+ if s1='EMBOSS' then begin
+ _prefx;
+ FastFX.QuickEmboss(fx1);
+ _postfx(fx1);
+ end else
+ if s1='ADDITION' then begin
+ i := MyStrToInt(ExtractWord(2, S, [' ']));
+ o := MyStrToInt(ExtractWord(3, S, [' ']));
+ u := MyStrToInt(ExtractWord(4, S, [' ']));
+ if (i=0) and (o=0) and (u=0) then Exit;
+ _prefx;
+ FastFX.Addition(fx1, i, o, u);
+ _postfx(fx1);
+ end else
+ if s1='GAMMA' then begin
+ i := MyStrToInt(ExtractWord(2, S, [' ']));
+ o := MyStrToInt(ExtractWord(3, S, [' ']));
+ u := MyStrToInt(ExtractWord(4, S, [' ']));
+ if (i=0) and (o=0) and (u=0) then Exit;
+ _prefx;
+ FastFX.Gamma(fx1, i, o, u);
+ _postfx(fx1);
+ end else
+ if s1='CONTRAST' then begin
+ i := MyStrToInt(ExtractWord(2, S, [' ']));
+ o := MyStrToInt(ExtractWord(3, S, [' ']));
+ u := MyStrToInt(ExtractWord(4, S, [' ']));
+ if (i=0) and (o=0) and (u=0) then Exit;
+ _prefx;
+ FastFX.Contrast(fx1, i, o, u);
+ _postfx(fx1);
+ end else
+ if s1='LIGHTNESS' then begin
+ i := MyStrToInt(ExtractWord(2, S, [' ']));
+ o := MyStrToInt(ExtractWord(3, S, [' ']));
+ u := MyStrToInt(ExtractWord(4, S, [' ']));
+ if (i=0) and (o=0) and (u=0) then Exit;
+ _prefx;
+ FastFX.Lightness(fx1, i, o, u);
+ _postfx(fx1);
+ end else
+ if s1='SCRAMBLE' then begin
+ scramble(d1.Surface);
+ FlipRequest;
+ end else
+ if s1='CONNECT' then begin
+ i:=WordCount(S, [' ']);
+ if i<3 then begin
+ main.Post('Usage: Connect <host> <port>');
+ Exit;
+ end;
+ s1:=ExtractWord(2, S, [' ']);
+ i := MyStrToInt(ExtractWord(3, S, [' ']));
+ if i<=0 then Exit;
+ if (main.csfs.Host<>s1) or (main.csfs.Port<>i) then begin
+ if main.csfs.Active then
+ main.csfs.Active:=False;
+ main.csfs.Host:=s1;
+ main.csfs.Port:=i;
+ end;
+ main.csfs.Open;
+ end else
+ if s1='DISCONNECT' then begin
+ main.csfs.Close;
+ end else
+ if (s1='SEND') or (s1='SEND_AUTO') then begin
+ i:=WordCount(S, [' ']);
+ if i<2 then begin
+ main.Post('Usage: Send <nametag> ["pure" for uncompressed or jpeg quality (default=80)]');
+ main.Post('Use "receive <nametag>" to set receiving fs.frame on the other end.');
+ Exit;
+ end;
+ sendjpg := True;
+ if i>2 then begin
+ Ext := UpperCase(ExtractWord(3, S, [' ']));
+ if Ext='PURE' then
+ sendjpg := False
+ else begin
+ jpegqualitynet := MyStrToInt(Ext);
+ if jpegqualitynet<=0 then jpegqualitynet:=80;
+ end;
+ end;
+ if sendjpg then
+ _prefx;
+ main.SendFrame(Self, ExtractWord(2, S, [' ']),
+ fx1, jpegqualitynet, sendjpg);
+ if s1='SEND_AUTO' then begin
+ AutoSend := True;
+ AutoSend_Address := ExtractWord(2, S, [' ']);
+ AutoSend_jpegqualitynet := jpegqualitynet;
+ AutoSend_sendjpg := sendjpg;
+ end;
+ end else
+ if s1='SEND_MANUAL' then begin
+ AutoSend := False;
+ end else
+ if s1='RECEIVE' then begin
+ Self.NameTag := ExtractWord(2, S, [' ']);
+ end else
+ if s1='MOUSETRACK_1' then begin
+ MouseTrack := True;
+ MiMouseTrack.Checked := True;
+ end else
+ if s1='MOUSETRACK_0' then begin
+ MouseTrack := False;
+ MiMouseTrack.Checked := False;
+ end else
+ if s1='MOUSERECT_1' then begin
+ MouseRect := True;
+ end else
+ if s1='MOUSERECT_0' then begin
+ MouseRect := False;
+ end else
+ if s1='HIDECURSOR_1' then begin
+ MiHideCursor.Checked := True;
+ HideCursor := True;
+ end else
+ if s1='HIDECURSOR_0' then begin
+ MiHideCursor.Checked := False;
+ HideCursor := False;
+ end else
+ if s1='DOCK' then begin
+ DockTitle := Copy(S, Length(s1)+2, 255);
+ DockHandle:=0;
+ EnumWindows(@mainunit.WinEnumerator_SubStr, 0);
+ if DockHandle>0 then begin
+ if MiBorders.Checked then
+ MiBorders.Click;
+ if GetWindowRect(DockHandle, R) then begin
+ d1.Hide;
+ WindowState := wsNormal;
+ ParentWindow := 0;
+ Parent := nil;
+ ParentWindow := DockHandle;
+ Left := 0;
+ Top := 0;
+ d1.Show;
+ d1.Initialize;
+ BringToFront;
+ DragAcceptFiles(Handle, True);
+ end;
+ end;
+ end else
+ if s1='SHOW' then begin
+ Self.Top := prevtop;
+ if not prevmute and MiMute.Checked then
+ MiMute.Click;
+ end else
+ if s1='HIDE' then begin
+ // ugly, but.
+ prevtop := Self.Top;
+ Self.Top := Screen.Height;
+ prevmute := MiMute.Checked;
+ if not prevmute then MiMute.Click;
+ end else
+ if s1='BUFFERIZE' then begin
+ _prefx;
+ fpic := TFastDIB.Create;
+ fpic.LoadFromHandle(fx1.Handle);
+ picBuf.Add(fpic);
+ end else
+ if s1='MAXIMIZE' then begin
+ WindowState := wsMaximized;
+ end else
+ if s1='MINIMIZE' then begin
+ WindowState := wsMinimized;
+ end else
+ if s1='BRINGTOFRONT' then begin
+ BringToFront;
+ end else
+ if s1='USE' then begin // use directory
+ s1 := Copy(S, Length(s1)+2, 255);
+ if DirectoryExists(s1) then begin
+ i := filelist.Count;
+ dirUse.Scan(s1);
+ main.Post('Using '+IntToStr(filelist.Count-i)+' images from '+s1+', total of '+IntToStr(filelist.Count));
+ end else
+ main.Post('nonexistent directory: '+s1);
+ end else
+ if s1='BUTTON' then begin
+ s1 := Copy(S, Length(s1)+2, 255);
+ if WordCount(s1, [' '])<>4 then Exit;
+ NewButton(ExtractWord(1, s1, [' ']), // receive name
+ MyStrToInt(ExtractWord(2, s1, [' '])), // x
+ MyStrToInt(ExtractWord(3, s1, [' '])), // y
+ ExtractWord(4, s1, [' ']) // caption
+ );
+ end else
+ if False{your new effect here} then begin
+ end else
+ if main.Plugins.IsPlugin(s1) then begin
+ if main.Plugins.CallEffect(d1.Surface, s1, Copy(S, Length(s1)+2, 255)) then
+ FlipRequest;
+ end else
+ if pshostunit.IsFilter(s1) then begin
+ pshostunit.Filter_effect(framepsh, d1.Surface, s1, Copy(S, Length(s1)+2, 255));
+ FlipRequest;
+ end else
+end;
+
+procedure Tfsframe.FormClose(Sender: TObject; var Action: TCloseAction);
+begin
+ Action := caFree;
+end;
+
+procedure Tfsframe.Mi11Click(Sender: TObject);
+begin
+ ClientWidth := d1.Surface.Width;
+ ClientHeight := d1.Surface.Height;
+end;
+
+procedure Tfsframe.Mi12Click(Sender: TObject);
+begin
+ ClientWidth := d1.Surface.Width * 2;
+ ClientHeight := d1.Surface.Height * 2;
+end;
+
+procedure Tfsframe.MiMuteClick(Sender: TObject);
+begin
+ MiMute.Checked := not MiMute.Checked;
+ d1.Visible := not MiMute.Checked;
+end;
+
+procedure Tfsframe.ClearPicBuf;
+var
+ f: TFastDIB;
+ i: Integer;
+begin
+ if picBuf.Count=0 then Exit;
+ for i:=picBuf.Count-1 downto 0 do begin
+ f := picBuf[i];
+ f.Free;
+ picBuf.Delete(i);
+ end;
+end;
+
+procedure Tfsframe.FlipRequest;
+begin
+ if AutoFlip then begin
+ d1.Flip;
+ AutoSendRequest;
+ end;
+end;
+
+procedure Tfsframe.AutoSendRequest;
+begin
+ if AutoSend and main.csfs.Active then begin
+ if AutoSend_sendjpg then
+ _prefx;
+ main.SendFrame(Self, AutoSend_address,
+ fx1, AutoSend_jpegqualitynet, AutoSend_sendjpg);
+ end;
+end;
+
+procedure Tfsframe.Borders(const Yes: Boolean);
+begin
+ _prefx;
+ d1.Hide;
+ if Yes and (ParentWindow=0) then
+ BorderStyle := bsSizeable
+ else
+ BorderStyle := bsNone;
+ d1.Show;
+ d1.Initialize;
+ _postfx(fx1);
+ MiBorders.Checked := Yes;
+ DragAcceptFiles(Handle, True);
+end;
+
+procedure Tfsframe.StayOnTop(const Yes: Boolean);
+begin
+ _prefx;
+ d1.Hide;
+ if Yes and (ParentWindow=0) then
+ FormStyle := fsStayOnTop
+ else
+ FormStyle := fsNormal;
+ d1.Show;
+ d1.Initialize;
+ _postfx(fx1);
+ MiStayOnTop.Checked := Yes;
+ DragAcceptFiles(Handle, True);
+end;
+
+procedure Tfsframe.MiBordersClick(Sender: TObject);
+begin
+ if Docked then Exit;
+ MiBorders.Checked := not MiBorders.Checked;
+ Borders(MiBorders.Checked);
+end;
+
+procedure Tfsframe.MiStayOnTopClick(Sender: TObject);
+begin
+ if Docked then Exit;
+ MiStayOnTop.Checked := not MiStayOnTop.Checked;
+ StayOnTop(MiStayOnTop.Checked);
+end;
+
+procedure Tfsframe.dirBufferHandleFile(const SearchRec: TSearchRec;
+ const FullPath: String);
+var
+ S: String;
+begin
+ S := UpperCase(ExtractFileExt(FullPath));
+ if (S='.BMP') or (S='.JPG') then
+ Parse('BUFFER '+FullPath);
+end;
+
+procedure Tfsframe.dirUseHandleFile(const SearchRec: TSearchRec;
+ const FullPath: String);
+var
+ S: String;
+begin
+ S := UpperCase(ExtractFileExt(FullPath));
+ if (S='.BMP') or (S='.JPG') then
+ filelist.Add(FullPath);
+end;
+
+function Tfsframe.Getnextfilename(const dir, ext: String): String;
+const
+ pref = 'fs';
+ last: Integer = 0;
+ predir: string = '';
+var
+ S: String;
+begin
+ if dir<>predir then last := 0;
+ repeat
+ Inc(last);
+ S := pref + IntToStr(last);
+ while Length(S)<8 do Insert('0', S, 3);
+ S := S+ext;
+ until not FileExists(S);
+ Result := S;
+ predir := dir;
+end;
+
+procedure Tfsframe.FormCreate(Sender: TObject);
+begin
+ ClientWidth := 176;
+ ClientHeight := 144;
+ d1.SetSize( ClientWidth, ClientHeight );
+ d1.Initialize;
+ with d1.Surface.Canvas do begin
+ Pen.Color := clWhite;
+ Brush.Color := clWhite;
+ Font.Color := clWhite;
+ end;
+ d1.Surface.Canvas.Release;
+ AutoFlip := True;
+ AutoSend := False;
+ Smooth := True;
+ avi := TDcAviPlayer.Create(Self);
+ avi.Parent := Self;
+ avi.Visible := False;
+ avi.Transparent := False;
+ avi.Stretch := False;
+ avi.PlaySound := False;
+ fx1 := TFastDIB.Create;
+ fx2 := TFastDIB.Create;
+ picBuf := TFastDIBList.Create;
+ picIndex := -1;
+ MouseTrack := False;
+ MouseRect := False;
+ HideCursor := False;
+ jpgquality := 85;
+ jpegqualitynet := 80;
+ prevtop := 0;
+ prevmute := False;
+ filelist := TStringList.Create;
+ filelistIndex := -1;
+ DragAcceptFiles(Handle, True);
+end;
+
+procedure Tfsframe.FormDestroy(Sender: TObject);
+begin
+ avi.Free;
+ fx1.Free;
+ fx2.Free;
+ ClearPicBuf;
+ picBuf.Free;
+ filelist.Free;
+end;
+
+var
+ LeftDown: Boolean;
+ OrgX, OrgY: Integer;
+
+procedure Tfsframe.d1MouseDown(Sender: TObject; Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
+begin
+ case Button of
+ mbLeft: begin
+ LeftDown := True;
+ main.SendReturnValues(PdName+'mousedown=1');
+ if MouseTrack and not MouseRect and not (ssAlt in Shift) then
+ SendMouseTrack(X, Y)
+ else begin
+ OrgX := X;
+ OrgY := Y;
+ end;
+ end;
+ end;
+end;
+
+procedure Tfsframe.d1MouseMove(Sender: TObject; Shift: TShiftState; X,
+ Y: Integer);
+begin
+ if LeftDown then begin
+ if MouseTrack and not (ssAlt in Shift) then begin
+ if not MouseRect then
+ SendMouseTrack(X, Y)
+ else
+ SendMouseRect(OrgX, OrgY, X, Y);
+ end else begin
+ Left := Left + (X-OrgX);
+ Top := Top + (Y-OrgY);
+ end;
+ end;
+end;
+
+procedure Tfsframe.d1MouseUp(Sender: TObject; Button: TMouseButton;
+ Shift: TShiftState; X, Y: Integer);
+begin
+ case Button of
+ mbLeft: begin
+ LeftDown:=False;
+(* these values were sent at "mousemove"
+ if MouseRect then
+ SendMouseRect(OrgX, OrgY, X, Y);*)
+ main.SendReturnValues(PdName+'mouseup=1');
+ if not MouseTrack or (ssAlt in Shift) then begin
+// main.Post('moved to '+
+// IntToStr(Left)+'+'+
+// IntToStr(Top)
+// );
+ main.SendReturnValues(
+ PdName+'winy='+IntToStr(Top)+';'+
+ PdName+'winx='+IntToStr(Left)
+ );
+ end;
+ end;
+ end;
+end;
+
+procedure Tfsframe.SendMouseTrack(const X, Y: Integer);
+var
+ a, b: Integer;
+begin
+ a := X;
+ b := Y;
+ // handle aspect ratios different from 1:1
+ if d1.Surface.Width<>d1.Width then
+ a := Trunc((d1.Surface.Width / d1.Width) * X);
+ if d1.Surface.Height<>d1.Height then
+ b := Trunc((d1.Surface.Height / d1.Height) * Y);
+
+ main.SendReturnValues(
+ PdName+'y='+IntToStr(b)+';'+
+ PdName+'x='+IntToStr(a)
+ );
+end;
+
+procedure Tfsframe.SendMouseRect(const x1, y1, x2, y2: Integer);
+var
+ a, b, c, d: Integer;
+begin
+ a := x1;
+ b := y1;
+ c := x2;
+ d := y2;
+ // handle aspect ratios different from 1:1
+ if d1.Surface.Width<>d1.Width then
+ a := Trunc((d1.Surface.Width / d1.Width) * x1);
+ if d1.Surface.Height<>d1.Height then
+ b := Trunc((d1.Surface.Height / d1.Height) * y1);
+ if d1.Surface.Width<>d1.Width then
+ c := Trunc((d1.Surface.Width / d1.Width) * x2);
+ if d1.Surface.Height<>d1.Height then
+ d := Trunc((d1.Surface.Height / d1.Height) * y2);
+
+ main.SendReturnValues(
+ PdName+'y2='+IntToStr(d)+';'+
+ PdName+'x2='+IntToStr(c)+';'+
+ PdName+'y1='+IntToStr(b)+';'+
+ PdName+'x1='+IntToStr(a)
+ );
+end;
+
+procedure Tfsframe.MiMouseTrackClick(Sender: TObject);
+begin
+ MouseTrack := not MouseTrack;
+ MiMouseTrack.Checked := MouseTrack;
+end;
+
+procedure Tfsframe.HandleDroppedFile(const S: String);
+var
+ i: Integer;
+ St: String;
+begin
+ Parse(S);
+ main.SendReturnValues(PdName+'bang=1');
+ // send string as a series of ascii..
+ main.SendReturnValuesString(PDName+'file', S);
+end;
+
+procedure Tfsframe.MiBufferImagesClick(Sender: TObject);
+var
+ i: Integer;
+ s: String;
+begin
+ if opd1.Execute then begin
+ if opd1.Files.Count>0 then
+ for i:=0 to opd1.Files.Count-1 do begin
+ if '.AVI'<>UpperCase(ExtractFileExt(opd1.files[i])) then
+ s := 'BUFFER '
+ else
+ s := '';
+ Parse(s+opd1.files[i]);
+ end;
+ // tee uusi canvas jossa valitut failit....
+ end;
+{
+#N canvas 0 0 700 300 12;
+#X obj 23 17 inlet;
+#X obj 15 45 outlet;
+#X msg 71 17 buffer file1.bmp \, buffer file2.bmp \, buffer file3.bmp;
+#X connect 0 0 2 0;
+#X connect 2 0 1 0;
+}
+end;
+
+function Tfsframe.GetDocked: Boolean;
+begin
+ Result := ParentWindow<>0;
+end;
+
+procedure Tfsframe.PopupMenu1Popup(Sender: TObject);
+begin
+ MiBorders.Enabled := not Docked;
+ MiStayOnTop.Enabled := not Docked;
+ MiUndock.Enabled := Docked;
+end;
+
+procedure Tfsframe.MiSaveFrameClick(Sender: TObject);
+var
+ S: String;
+begin
+ if svd1.Execute then begin
+ S := svd1.Filename;
+ if Uppercase(ExtractFileExt(S))<>'.BMP' then
+ S := S+'.bmp';
+ _prefx;
+ fx1.SaveToFile(S);
+ end;
+{
+ _prefx;
+ if savejpg then
+ SaveJPGFile(fx1, s1+'\'+fs, jpgquality)
+ else
+ fx1.SaveToFile(s1+'\'+fs);
+}
+end;
+
+procedure Tfsframe.Mi176x144Click(Sender: TObject);
+begin
+ Parse('display 176x144');
+end;
+
+procedure Tfsframe.SetHideCursor(const Value: Boolean);
+begin
+ FHideCursor := Value;
+ if Value then
+ d1.Cursor := crNone
+ else
+ d1.Cursor := crDefault;
+end;
+
+procedure Tfsframe.MiHideCursorClick(Sender: TObject);
+begin
+ MiHideCursor.Checked := not MiHideCursor.Checked;
+ HideCursor := MiHideCursor.Checked;
+end;
+
+procedure Tfsframe.FormMouseWheel(Sender: TObject; Shift: TShiftState;
+ WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
+var
+ asp: Extended;
+begin
+ if WheelDelta>0 then begin
+ ClientWidth := Trunc(ClientWidth * (WheelDelta / 100));
+ if not (ssShift in Shift) then
+ ClientHeight := Trunc(ClientHeight * (WheelDelta / 100));
+ end else begin
+ ClientWidth := Trunc(ClientWidth / Abs(WheelDelta / 100));
+ if not (ssShift in Shift) then
+ ClientHeight := Trunc(ClientHeight / Abs(WheelDelta / 100));
+ end;
+ // correct aspect ratio...
+ if ssShift in Shift then begin
+ asp := d1.Surface.Width / d1.Surface.Height;
+ if asp>0 then
+ ClientHeight := Trunc(ClientWidth / asp);
+ end;
+end;
+
+procedure Tfsframe.MiUndockClick(Sender: TObject);
+begin
+ ParentWindow := 0;
+ Borders(True);
+end;
+
+procedure Tfsframe.NewButton(const receivename: String; const x,
+ y: Integer; const buttoncaption: String);
+var
+ p: TPanel;
+ b: TFSSpeedButton;
+begin
+ p := TPanel.Create(Self);
+ b := TFSSpeedButton.Create(Self);
+
+ b.Width := LabelFoo.Canvas.TextWidth(buttoncaption)+12;
+ b.Height := 18;
+ b.Parent := p;
+ b.Left := 0;
+ b.Top := 0;
+ b.Flat := True;
+ b.Caption := buttoncaption;
+ b.Receivename := receivename;
+ p.AutoSize := True;
+ p.Left := x;
+ p.Top := y;
+ p.BevelOuter := bvNone;
+ p.Parent := d1;
+end;
+
+end.
+
diff --git a/Source/fsinfounit.dfm b/Source/fsinfounit.dfm
new file mode 100644
index 0000000..3079d24
--- /dev/null
+++ b/Source/fsinfounit.dfm
@@ -0,0 +1,16 @@
+object fsinfo: Tfsinfo
+ Left = 242
+ Top = 103
+ Width = 356
+ Height = 122
+ Caption = 'fsinfo'
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ OldCreateOrder = False
+ PixelsPerInch = 96
+ TextHeight = 13
+end
diff --git a/Source/fsinfounit.pas b/Source/fsinfounit.pas
new file mode 100644
index 0000000..d8de65d
--- /dev/null
+++ b/Source/fsinfounit.pas
@@ -0,0 +1,53 @@
+unit fsinfounit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ fsformunit;
+
+type
+ Tfsinfo = class(TFsForm)
+ private
+ { Private declarations }
+ public
+ { Public declarations }
+ procedure Parse(const S: String); override;
+ end;
+
+var
+ fsinfo: Tfsinfo;
+
+implementation
+
+uses
+ mainunit, fsframeunit,
+ Strz;
+
+{$R *.DFM}
+
+{ Tfsinfo }
+
+procedure Tfsinfo.Parse(const S: String);
+var
+ s1: String;
+ f: TFsFrame;
+begin
+ if (S='') or
+ (WordCount(S, [' '])<5) or
+ (not main.cstoPd.Active) then Exit;
+
+ s1 := ExtractWord(1, S, [' ']);
+ f := FindFrame(s1);
+ if f=nil then Exit;
+
+ main.SendReturnValues(
+ ExtractWord(5, S, [' '])+'='+IntToStr(f.Avi.FrameRate)+';'+
+ ExtractWord(4, S, [' '])+'='+IntToStr(f.Avi.FrameCount)+';'+
+ ExtractWord(3, S, [' '])+'='+IntToStr(f.d1.Surface.Height)+';'+
+ ExtractWord(2, S, [' '])+'='+IntToStr(f.d1.Surface.Width)
+ );
+end;
+
+end.
+
diff --git a/Source/fsspeedbutton.pas b/Source/fsspeedbutton.pas
new file mode 100644
index 0000000..da3d53a
--- /dev/null
+++ b/Source/fsspeedbutton.pas
@@ -0,0 +1,48 @@
+unit fsspeedbutton;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ Buttons;
+
+type
+ TFSSpeedButton = class(TSpeedButton)
+ private
+ { Private declarations }
+ procedure MyOnClick(Sender: TObject);
+ protected
+ { Protected declarations }
+ public
+ { Public declarations }
+ Receivename: String;
+ constructor Create(AOwner: TComponent); override;
+ published
+ { Published declarations }
+ end;
+
+procedure Register;
+
+implementation
+
+uses
+ mainunit;
+
+procedure Register;
+begin
+end;
+
+{ TFSSpeedButton }
+
+constructor TFSSpeedButton.Create(AOwner: TComponent);
+begin
+ inherited;
+ OnClick := MyOnClick;
+end;
+
+procedure TFSSpeedButton.MyOnClick(Sender: TObject);
+begin
+ main.SendReturnValues(Receivename+'=1');
+end;
+
+end.
diff --git a/Source/fstextunit.dfm b/Source/fstextunit.dfm
new file mode 100644
index 0000000..c8ff138
--- /dev/null
+++ b/Source/fstextunit.dfm
@@ -0,0 +1,18 @@
+object fstext: Tfstext
+ Left = 231
+ Top = 103
+ Width = 236
+ Height = 79
+ Caption = 'fstext'
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ OldCreateOrder = False
+ WindowState = wsMinimized
+ OnCreate = FormCreate
+ PixelsPerInch = 96
+ TextHeight = 13
+end
diff --git a/Source/fstextunit.pas b/Source/fstextunit.pas
new file mode 100644
index 0000000..92230db
--- /dev/null
+++ b/Source/fstextunit.pas
@@ -0,0 +1,148 @@
+{ Copyright (C) 2001 Juha Vehviläinen
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.}
+
+unit fstextunit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ mainunit, fsformunit, fsframeunit;
+
+type
+ Tfstext = class(TFsForm)
+ procedure FormCreate(Sender: TObject);
+ private
+ { Private declarations }
+ dest: TFsFrame;
+ x, y: Integer;
+ public
+ { Public declarations }
+ procedure Parse(const S: String); override;
+ end;
+
+var
+ fstext: Tfstext;
+
+function ParsePenProperties(const Canvas: TCanvas; const S: String): Boolean;
+
+implementation
+
+{$R *.DFM}
+
+uses
+ Strz;
+
+function ParsePenProperties(const Canvas: TCanvas; const S: String): Boolean;
+var
+ s1: String;
+ r, g, b: Integer;
+begin
+ Result := False;
+ s1 := UpperCase(ExtractWord(1, S, [' ']));
+ if s1='PEN' then begin
+ if WordCount(S, [' '])<4 then
+ main.Post('Usage: PEN <r> <g> <b>')
+ else begin
+ r := MyStrToInt(ExtractWord(2, S, [' ']));
+ g := MyStrToInt(ExtractWord(3, S, [' ']));
+ b := MyStrToInt(ExtractWord(4, S, [' ']));
+ Canvas.Pen.Color := RGB(r, g, b);
+ end;
+ Result := True;
+ end else
+ if s1='BRUSH' then begin
+ if WordCount(S, [' '])<4 then
+ main.Post('Usage: BRUSH <r> <g> <b>')
+ else begin
+ r := MyStrToInt(ExtractWord(2, S, [' ']));
+ g := MyStrToInt(ExtractWord(3, S, [' ']));
+ b := MyStrToInt(ExtractWord(4, S, [' ']));
+ Canvas.Brush.Color := RGB(r, g, b);
+ end;
+ Result := True;
+ end else
+ if s1='COLOR' then begin
+ if WordCount(S, [' '])<4 then
+ main.Post('Usage: COLOR <r> <g> <b>')
+ else begin
+ r := MyStrToInt(ExtractWord(2, S, [' ']));
+ g := MyStrToInt(ExtractWord(3, S, [' ']));
+ b := MyStrToInt(ExtractWord(4, S, [' ']));
+ Canvas.Font.Color := RGB(r, g, b);
+ end;
+ Result := True;
+ end else
+ if s1='SIZE' then begin
+ Canvas.Font.Size := MyStrToInt(ExtractWord(2, S, [' ']));
+ Result := True;
+ end else
+ if s1='FONT' then begin
+ Canvas.Font.Name := Copy(S, Length(s1)+2, 255);
+ Result := True;
+ end else
+end;
+
+{ Tfstext }
+
+procedure Tfstext.Parse(const S: String);
+const
+ y: Integer = 0;
+var
+ s1, sa: String;
+ b: Boolean;
+begin
+ if (S='') then Exit;
+
+ s1 := ExtractWord(WordCount(S, [' ']), S, [' ']);
+ dest := FindFrame(s1);
+ if (dest=nil) or (dest.d1=nil) then Exit;
+
+ sa := Copy(S, 1, Pos(s1, S)-2);
+
+ b := ParsePenProperties(dest.d1.Surface.Canvas, UpperCase(sa));
+ dest.d1.Surface.Canvas.Release;
+ if b then Exit;
+
+ s1 := UpperCase(ExtractWord(1, sa, [' ']));
+ if s1='POS' then begin
+ self.x := MyStrToInt(ExtractWord(2, sa, [' ']));
+ self.y := MyStrToInt(ExtractWord(3, sa, [' ']));
+ Exit;
+ end;
+
+ with dest.d1.Surface.Canvas do begin
+ Brush.Style := bsClear;
+
+ if (self.x>-1) and (self.y>-1) then
+ TextOut(self.x, self.y, sa)
+ else begin
+ TextOut(0, y, sa);
+
+ Inc(Y, TextHeight(S));
+ if y>dest.d1.Surface.Height then
+ y := 0;
+ end;
+ end;
+ dest.d1.Surface.Canvas.Release;
+
+ dest.FlipRequest;
+end;
+
+procedure Tfstext.FormCreate(Sender: TObject);
+begin
+ dest := nil;
+ x := -1;
+ y := -1;
+end;
+
+end.
+
diff --git a/Source/logunit.dfm b/Source/logunit.dfm
new file mode 100644
index 0000000..bd8c429
--- /dev/null
+++ b/Source/logunit.dfm
@@ -0,0 +1,100 @@
+object log: Tlog
+ Left = 239
+ Top = 39
+ Width = 603
+ Height = 666
+ BorderStyle = bsSizeToolWin
+ Caption = 'Console / Log'
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ OldCreateOrder = False
+ Position = poDesktopCenter
+ OnCreate = FormCreate
+ PixelsPerInch = 96
+ TextHeight = 13
+ object PanelLog: TPanel
+ Left = 0
+ Top = 221
+ Width = 595
+ Height = 418
+ Align = alClient
+ BevelOuter = bvNone
+ TabOrder = 0
+ object Panel2: TPanel
+ Left = 0
+ Top = 400
+ Width = 595
+ Height = 18
+ Align = alBottom
+ AutoSize = True
+ BevelOuter = bvNone
+ TabOrder = 0
+ object ButtonClear: TButton
+ Left = 75
+ Top = 0
+ Width = 75
+ Height = 18
+ Caption = 'Clear'
+ TabOrder = 1
+ OnClick = ButtonClearClick
+ end
+ object ButtonClose: TButton
+ Left = 0
+ Top = 0
+ Width = 75
+ Height = 18
+ Caption = 'Close'
+ Default = True
+ TabOrder = 0
+ OnClick = ButtonCloseClick
+ end
+ end
+ object RELog: TRichEdit
+ Left = 0
+ Top = 0
+ Width = 595
+ Height = 400
+ Align = alClient
+ BorderStyle = bsNone
+ Ctl3D = True
+ ParentCtl3D = False
+ PlainText = True
+ ScrollBars = ssVertical
+ TabOrder = 1
+ WordWrap = False
+ end
+ end
+ object Panel1: TPanel
+ Left = 0
+ Top = 203
+ Width = 595
+ Height = 18
+ Align = alTop
+ BevelOuter = bvLowered
+ Caption = 'Log'
+ TabOrder = 2
+ end
+ object PanelConsole: TPanel
+ Left = 0
+ Top = 18
+ Width = 595
+ Height = 185
+ Align = alTop
+ BevelOuter = bvNone
+ TabOrder = 1
+ end
+ object Panel3: TPanel
+ Left = 0
+ Top = 0
+ Width = 595
+ Height = 18
+ Align = alTop
+ BevelOuter = bvLowered
+ Caption = 'Console'
+ TabOrder = 3
+ end
+end
diff --git a/Source/logunit.pas b/Source/logunit.pas
new file mode 100644
index 0000000..187684f
--- /dev/null
+++ b/Source/logunit.pas
@@ -0,0 +1,60 @@
+unit logunit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ StdCtrls, ComCtrls, ExtCtrls;
+
+type
+ Tlog = class(TForm)
+ PanelLog: TPanel;
+ Panel2: TPanel;
+ ButtonClear: TButton;
+ RELog: TRichEdit;
+ PanelConsole: TPanel;
+ Panel1: TPanel;
+ Panel3: TPanel;
+ ButtonClose: TButton;
+ procedure ButtonClearClick(Sender: TObject);
+ procedure FormCreate(Sender: TObject);
+ procedure ButtonCloseClick(Sender: TObject);
+ private
+ { Private declarations }
+ public
+ { Public declarations }
+ procedure add(const s: String);
+ end;
+
+var
+ log: Tlog;
+
+implementation
+
+uses mainunit;
+
+{$R *.DFM}
+
+procedure Tlog.add(const s: String);
+begin
+ RELog.Lines.Add(s);
+end;
+
+procedure Tlog.ButtonCloseClick(Sender: TObject);
+begin
+ main.MiLog.Click;
+end;
+
+procedure Tlog.ButtonClearClick(Sender: TObject);
+begin
+ main.REConsole.Lines.Clear;
+ RELog.Lines.Clear;
+end;
+
+procedure Tlog.FormCreate(Sender: TObject);
+begin
+ main.REConsole.Parent := PanelConsole;
+ main.REConsole.Align := alClient;
+end;
+
+end.
diff --git a/Source/mainunit.dfm b/Source/mainunit.dfm
new file mode 100644
index 0000000..46a9252
--- /dev/null
+++ b/Source/mainunit.dfm
@@ -0,0 +1,3547 @@
+object main: Tmain
+ Left = 16
+ Top = 497
+ Width = 239
+ Height = 223
+ Caption = 'Framestein'
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ OldCreateOrder = False
+ OnClose = FormClose
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ PixelsPerInch = 96
+ TextHeight = 13
+ object ImageLogo: TImage
+ Left = 0
+ Top = 0
+ Width = 231
+ Height = 196
+ Align = alClient
+ Picture.Data = {
+ 07544269746D617086AE0100424D86AE0100000000003600000028000000D700
+ 0000AA000000010018000000000050AE0100120B0000120B0000000000000000
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5CED
+ EB325C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5CBDADAF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C6D05BB5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5CF56EED5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C2F
+ E8ED5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C4D6FF85C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00
+ D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2
+ FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00
+ D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF
+ 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2
+ FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF
+ 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2
+ FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00
+ D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF
+ 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2
+ FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00
+ 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2
+ FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00
+ D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF
+ 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5CEDEB325C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5CBDADAF5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C6D05BB5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5CF5
+ 6EED5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C2FE8ED5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C
+ 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C4D6FF8}
+ PopupMenu = PopupMenu1
+ Stretch = True
+ OnDblClick = ImageLogoDblClick
+ end
+ object REConsole: TRichEdit
+ Left = 136
+ Top = 104
+ Width = 81
+ Height = 73
+ BorderStyle = bsNone
+ ReadOnly = True
+ ScrollBars = ssVertical
+ TabOrder = 0
+ end
+ object ss1: TServerSocket
+ Active = False
+ Port = 6001
+ ServerType = stNonBlocking
+ OnClientConnect = ss1ClientConnect
+ OnClientDisconnect = ss1ClientDisconnect
+ OnClientRead = ss1ClientRead
+ OnClientError = ss1ClientError
+ end
+ object PopupMenu1: TPopupMenu
+ Left = 64
+ object MiConfig: TMenuItem
+ Caption = 'Configure'
+ OnClick = MiConfigClick
+ end
+ object MiReset: TMenuItem
+ Caption = 'Reset'
+ OnClick = MiResetClick
+ end
+ object MiReloadPlugins: TMenuItem
+ Caption = 'Reload plugins'
+ OnClick = MiReloadPluginsClick
+ end
+ object MiLog: TMenuItem
+ Caption = 'Show debug'
+ OnClick = MiLogClick
+ end
+ object MiExit: TMenuItem
+ Caption = 'E&xit'
+ OnClick = MiExitClick
+ end
+ end
+ object ssfs: TServerSocket
+ Active = False
+ Port = 6002
+ ServerType = stNonBlocking
+ OnClientConnect = ssfsClientConnect
+ OnClientDisconnect = ssfsClientDisconnect
+ OnClientRead = ssfsClientRead
+ OnClientError = ssfsClientError
+ Top = 56
+ end
+ object csfs: TClientSocket
+ Active = False
+ ClientType = ctNonBlocking
+ Port = 6010
+ OnConnect = csfsConnect
+ OnDisconnect = csfsDisconnect
+ OnError = csfsError
+ Left = 32
+ Top = 56
+ end
+ object csToPd: TClientSocket
+ Active = False
+ ClientType = ctNonBlocking
+ Host = 'localhost'
+ Port = 6002
+ OnConnect = csToPdConnect
+ OnDisconnect = csToPdDisconnect
+ OnError = csToPdError
+ Left = 32
+ end
+end
diff --git a/Source/mainunit.pas b/Source/mainunit.pas
new file mode 100644
index 0000000..ebf3f46
--- /dev/null
+++ b/Source/mainunit.pas
@@ -0,0 +1,903 @@
+{ Copyright (C) 2001-2002 Juha Vehviläinen
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.}
+
+unit mainunit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ StdCtrls, ScktComp,
+ pluginunit, fsformunit, fsframeunit,
+ FastDIB,
+ ExtCtrls, Menus, C2PhotoShopHost, Filez, ComCtrls;
+
+type
+ Tmain = class(TFsForm)
+ ss1: TServerSocket;
+ ImageLogo: TImage;
+ PopupMenu1: TPopupMenu;
+ MiConfig: TMenuItem;
+ MiReset: TMenuItem;
+ MiReloadPlugins: TMenuItem;
+ ssfs: TServerSocket;
+ csfs: TClientSocket;
+ MiLog: TMenuItem;
+ csToPd: TClientSocket;
+ MiExit: TMenuItem;
+ REConsole: TRichEdit;
+ procedure ss1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
+ procedure FormCreate(Sender: TObject);
+ procedure ss1ClientError(Sender: TObject; Socket: TCustomWinSocket;
+ ErrorEvent: TErrorEvent; var ErrorCode: Integer);
+ procedure ss1ClientDisconnect(Sender: TObject;
+ Socket: TCustomWinSocket);
+ procedure MiConfigClick(Sender: TObject);
+ procedure ss1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
+ procedure MiResetClick(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure MiReloadPluginsClick(Sender: TObject);
+ procedure ssfsClientRead(Sender: TObject; Socket: TCustomWinSocket);
+ procedure csfsError(Sender: TObject; Socket: TCustomWinSocket;
+ ErrorEvent: TErrorEvent; var ErrorCode: Integer);
+ procedure csfsDisconnect(Sender: TObject; Socket: TCustomWinSocket);
+ procedure ssfsClientError(Sender: TObject; Socket: TCustomWinSocket;
+ ErrorEvent: TErrorEvent; var ErrorCode: Integer);
+ procedure csfsConnect(Sender: TObject; Socket: TCustomWinSocket);
+ procedure ssfsClientConnect(Sender: TObject; Socket: TCustomWinSocket);
+ procedure ssfsClientDisconnect(Sender: TObject;
+ Socket: TCustomWinSocket);
+ procedure MiLogClick(Sender: TObject);
+ procedure csToPdError(Sender: TObject; Socket: TCustomWinSocket;
+ ErrorEvent: TErrorEvent; var ErrorCode: Integer);
+ procedure csToPdConnect(Sender: TObject; Socket: TCustomWinSocket);
+ procedure csToPdDisconnect(Sender: TObject; Socket: TCustomWinSocket);
+ procedure MiExitClick(Sender: TObject);
+ procedure ImageLogoDblClick(Sender: TObject);
+ procedure FormClose(Sender: TObject; var Action: TCloseAction);
+ private
+ { Private declarations }
+ SocketMem: Pointer;
+ fbmp: TFastDIB;
+ procedure LoadRegSettings;
+ procedure ParsePrim(const S: String);
+ procedure FreeIfCompExists(const S: String);
+ function GetFrameByTag(const tag: String): TFsFrame;
+ function ItemCount( const ClassName: String ): Integer;
+ procedure Reset;
+ procedure minimizeall;
+ procedure ExceptionHandler(Sender: TObject; E: Exception);
+ procedure DropFileHandler(const h: HWND; const DroppedFileName: String);
+ procedure AppMessage(var Msg: Tmsg; var Handled: Boolean);
+ public
+ { Public declarations }
+ RunConfig: Boolean;
+ PdHost: String; // Host running PD
+ PDReceivePort: Integer; // data from PD
+ PDSendPort: Integer; // data to PD
+ FSPort: Integer; // Framestein connections
+ EnableFSConns: Boolean;
+ DockMain: Boolean;
+ logstate: Boolean;
+ Plugins: TPlugins;
+ SearchPath: TStringList;
+
+ function CompName(const S: String): String;
+ procedure Parse(const S: String); override;
+ procedure Post(const S: String);
+ procedure SendFrame(const f: TFsFrame;
+ const NameTag: String; const bmp: TFastDIB;
+ const quality: Integer; const sendjpg: Boolean );
+ procedure SendReturnValues(const S: String);
+ procedure SendReturnValuesString(
+ const PdName: String; const S: String);
+ function FileExistsInSearchPath(var S: String): Boolean; // modifying S allowed!
+ end;
+
+const
+ STARTMSG = 'Framestein 0.30 running...';
+ MCAPTION = 'Framestein 0.30';
+ SocketBufferSize = 100000;
+
+var
+ main: Tmain;
+ DockTitle: String;
+ DockHandle: HWND;
+
+function WinEnumerator(h: HWND; i: LongInt): BOOL; stdcall;
+function WinEnumerator_Exact(h: HWND; i: LongInt): BOOL; stdcall;
+function WinEnumerator_SubStr(h: HWND; i: LongInt): BOOL; stdcall;
+
+implementation
+
+{$R *.DFM}
+
+uses
+ Registry, DirectX, DxDraws, ShellApi,
+ fscopyunit, fstextunit, fsdrawunit, fsbrowserunit,
+ fsinfounit, fsaviunit,
+ fastfiles,
+ Strz, logunit, configureunit;
+
+function WinEnumerator(h: HWND; i: LongInt): BOOL; stdcall;
+var
+ Title: array[0..255] of Char;
+begin
+ Result := True;
+ if GetWindowText(h, Title, SizeOf(Title))>0 then begin
+ if UpperCase(DockTitle)=
+ Copy(UpperCase(StrPas(@Title)), 1, Length(DockTitle)) then begin
+ DockHandle := h;
+ Result := False; // stop enumerating
+ end;
+ end;
+end;
+
+function WinEnumerator_SubStr(h: HWND; i: LongInt): BOOL; stdcall;
+var
+ Title: array[0..255] of Char;
+begin
+ Result := True;
+ if GetWindowText(h, Title, SizeOf(Title))>0 then begin
+ if Pos(UpperCase(DockTitle), UpperCase(StrPas(@Title)))>0 then begin
+ DockHandle := h;
+ Result := False; // stop enumerating
+ end;
+ end;
+end;
+
+function WinEnumerator_Exact(h: HWND; i: LongInt): BOOL; stdcall;
+var
+ Title: array[0..255] of Char;
+begin
+ Result := True;
+ if GetWindowText(h, Title, SizeOf(Title))>0 then begin
+ if UpperCase(DockTitle)=
+ UpperCase(StrPas(@Title)) then begin
+ DockHandle := h;
+ Result := False; // stop enumerating
+ end;
+ end;
+end;
+
+{ TForm1 }
+
+function Tmain.ItemCount( const ClassName: String ): Integer;
+var
+ i, count: Integer;
+begin
+ count:=0;
+ if ComponentCount>0 then
+ for i:=1 to ComponentCount-1 do
+ if UpperCase(Components[i].ClassName)=UpperCase(ClassName) then
+ Inc(count);
+ Result := count;
+end;
+
+function Tmain.CompName(const S: String): String;
+var
+ St: String;
+ a: Integer;
+begin
+ St := S;
+ if Length(St)>0 then
+ for a:=Length(St) downto 1 do
+ if St[a] in ['-','.',',',#10,#13] then
+ Delete(St, a, 1);
+
+ if Length(St)>0 then
+ for a:=1 to Length(St) do
+ if St[a] in ['0'..'9'] then
+ St[a] := Char(Ord('A')+(Ord(St[a])-Ord('0')));
+
+ Result := St;
+end;
+
+procedure Tmain.ParsePrim(const S: String);
+var
+ s1, s2, s_args: String;
+ i: Integer;
+ fsframe: TFsFrame;
+ fscopy: TFsCopy;
+ fstext: TFsText;
+ fsdraw: TFsDraw;
+ fsbrowser: TFsBrowser;
+ fsinfo: TFsInfo;
+ fsavi: TFsAvi;
+ f: TFsForm;
+begin
+ if logstate then
+ log.add(s);
+
+ s1 := UpperCase(ExtractWord(1, S, [' ']));
+ s_args := Copy(S, Length(s1)+2, 255);
+
+ f := TFsForm(FindComponent(CompName(s1)));
+ if f<>nil then begin
+ f.Parse(s_args);
+ Exit;
+ end;
+
+ s2 := ExtractWord(2, S, [' ']);
+
+ if S1='RESET' then begin
+ Reset;
+ end else
+ if S1='FRAME' then begin
+ FreeIfCompExists(CompName(s2));
+ fsframe := TFsFrame.Create(Self);
+ fsframe.PdName := s2;
+ fsframe.Name := CompName(s2);
+ fsframe.Caption := s2;
+ i := ItemCount('TFsFrame')-1;
+ fsframe.Left := fsframe.Width*(i div 4);
+ fsframe.Top := fsframe.Height*(i mod 4);
+ fsframe.Show;
+ end else
+ if S1='COPY' then begin
+ FreeIfCompExists(CompName(s2));
+ fscopy := TFsCopy.Create(Self);
+ fscopy.Name := CompName(s2);
+ fscopy.Caption := s2;
+ end else
+ if S1='TEXT' then begin
+ FreeIfCompExists(CompName(s2));
+ fstext := TFsText.Create(Self);
+ fstext.Name := CompName(s2);
+ fstext.Caption := s2;
+ end else
+ if S1='DRAW' then begin
+ FreeIfCompExists(CompName(s2));
+ fsdraw := TFsDraw.Create(Self);
+ fsdraw.Name := CompName(s2);
+ fsdraw.Caption := s2;
+ end else
+ if S1='BROWSER' then begin
+ FreeIfCompExists(CompName(s2));
+ fsbrowser := TFsBrowser.Create(Self);
+ fsbrowser.PdName := s2;
+ fsbrowser.Name := CompName(s2);
+ fsbrowser.Caption := s2;
+ i := ItemCount('TFsBrowser')-1;
+ fsbrowser.Left := fsbrowser.Width*(i div 4);
+ fsbrowser.Top := fsbrowser.Height*(i mod 4);
+ fsbrowser.Show;
+ end else
+ if S1='INFO' then begin
+ FreeIfCompExists(CompName(s2));
+ fsinfo := TFsInfo.Create(Self);
+ fsinfo.Name := CompName(s2);
+ fsinfo.Caption := s2;
+ end else
+ if S1='AVI' then begin
+ FreeIfCompExists(CompName(s2));
+ fsavi := TFsAvi.Create(Self);
+ fsavi.PdName := s2;
+ fsavi.Name := CompName(s2);
+ fsavi.Caption := s2;
+ end else
+ if S1='MINIMIZEALL' then begin
+ minimizeall;
+ end else
+ if s1='PATH' then begin
+ SearchPath.Add(Copy(S, Length(s1)+2, 255));
+ end else
+end;
+
+procedure Tmain.Parse(const S: String);
+
+ function ComponentCreator(const Str: String): Boolean;
+ var
+ s1: String;
+ begin
+ s1 := UpperCase(ExtractWord(1, Str, [' ']));
+ Result :=
+ (s1='RESET') or
+ (s1='FRAME') or
+ (s1='COPY') or
+ (s1='TEXT') or
+ (s1='DRAW') or
+ (s1='BROWSER') or
+ (s1='INFO') or
+ (s1='AVI');
+ end;
+
+var
+ i, c: Integer;
+ Str: String;
+begin
+ if Pos(';', S)=0 then
+ ParsePrim(S)
+ else begin
+ c := WordCount(S, [';']);
+ // first commands that create fs.* objects
+ for i:=1 to c do begin
+ Str := ExtractWord(i, S, [';']);
+ if ComponentCreator(Str) then
+ ParsePrim(Str);
+ end;
+ // all the rest
+ for i:=1 to c do begin
+ Str := ExtractWord(i, S, [';']);
+ if not ComponentCreator(Str) then
+ ParsePrim(Str);
+ end;
+ end;
+end;
+
+procedure Tmain.ss1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
+var
+ S: String;
+begin
+ S := socket.ReceiveText;
+ while Pos(#10, S)>0 do
+ Delete(S, Pos(#10, S), 1);
+ Parse(S);
+end;
+
+procedure Tmain.FreeIfCompExists(const S: String);
+var
+ c: TComponent;
+begin
+ c := FindComponent(S);
+ if c<>nil then
+ c.Free;
+end;
+
+procedure Tmain.FormCreate(Sender: TObject);
+begin
+ Randomize;
+ RunConfig:=False;
+ PdHost := 'localhost';
+ PDReceivePort := 6001;
+ PDSendPort := 6002;
+ FSPort := 6010;
+ EnableFSConns := False;
+ DockMain := True;
+ LoadRegSettings;
+ if not RunConfig then begin
+ ss1.Port := PDReceivePort;
+ ss1.Active := True;
+ csToPd.Host := PdHost;
+ csToPd.Port := PdSendPort;
+ csToPd.Active := True;
+ ssfs.Port := FSPort;
+ ssfs.Active := EnableFSConns;
+ end;
+
+ main.Post(STARTMSG);
+ Caption := MCAPTION;
+
+ Plugins := TPlugins.Create(Self);
+ Plugins.Load;
+
+ SocketMem := AllocMem(SocketBufferSize);
+ fBmp := TFastDIB.Create;
+ logstate := False;
+
+ SearchPath := TStringList.Create;
+ SearchPath.Add(ExtractFilePath(Application.ExeName));
+
+ Application.OnException := ExceptionHandler;
+ Application.OnMessage := AppMessage;
+end;
+
+procedure Tmain.FormDestroy(Sender: TObject);
+begin
+ Plugins.Free;
+ SearchPath.Free;
+ FreeMem(SocketMem);
+ fBmp.Free;
+end;
+
+procedure Tmain.ss1ClientConnect(Sender: TObject;
+ Socket: TCustomWinSocket);
+begin
+ Post('Connected on port '+IntToStr(PDReceivePort));
+ if not csToPd.Active then
+ csToPd.Active := True;
+
+// just a crazy idea
+ if DockMain then begin
+ DockTitle := 'pd';
+ DockHandle:=0;
+ EnumWindows(@WinEnumerator_Exact, 0);
+ if DockHandle>0 then begin
+ ParentWindow := DockHandle;
+ BorderStyle := bsNone;
+ Left := 4;
+ Top := 120;
+ Width := 40;
+ Height := 40;
+ BringToFront;
+ end;
+ end;
+end;
+
+procedure Tmain.ss1ClientDisconnect(Sender: TObject;
+ Socket: TCustomWinSocket);
+begin
+ Post('Disconnected');
+ csToPd.Active := False;
+ Reset;
+end;
+
+procedure Tmain.csToPdConnect(Sender: TObject; Socket: TCustomWinSocket);
+begin
+ Post('Connected on port '+IntToStr(PDSendPort));
+end;
+
+procedure Tmain.csToPdDisconnect(Sender: TObject;
+ Socket: TCustomWinSocket);
+begin
+ Post('Disconnected');
+end;
+
+procedure Tmain.ss1ClientError(Sender: TObject; Socket: TCustomWinSocket;
+ ErrorEvent: TErrorEvent; var ErrorCode: Integer);
+begin
+ Post('Disconnected');
+ ErrorCode := 0;
+end;
+
+procedure Tmain.LoadRegSettings;
+var
+ Reg: TRegistry;
+begin
+ Reg := TRegistry.Create;
+ try
+ Reg.RootKey := HKEY_CURRENT_USER;
+ if Reg.OpenKey('\Software\Framestein', True) then begin
+ PdHost := Reg.ReadString('PdHost');
+ PDReceivePort := Reg.ReadInteger('PDReceivePort');
+ PDSendPort := Reg.ReadInteger('PDSendPort');
+ FSPort := Reg.ReadInteger('FSPort');
+ EnableFSConns := Reg.ReadBool('EnableFSConns');
+ DockMain := Reg.ReadBool('DockMain');
+ end;
+ except
+ RunConfig := True;
+ end;
+ Reg.CloseKey;
+ Reg.Free;
+end;
+
+procedure Tmain.MiConfigClick(Sender: TObject);
+begin
+ configure.Execute;
+end;
+
+procedure Tmain.Post(const S: String);
+begin
+// Writeln(TimeToStr(Time), ' ', S);
+ REConsole.Lines.Add(TimeToStr(Time)+' '+S);
+end;
+
+procedure Tmain.Reset;
+var
+ i: Integer;
+begin
+ if ComponentCount=0 then Exit;
+ for i:=ComponentCount-1 downto 0 do
+ if Components[i] is TfsForm then
+ Components[i].Free;
+end;
+
+procedure Tmain.MiResetClick(Sender: TObject);
+begin
+ Reset;
+end;
+
+procedure Tmain.MiReloadPluginsClick(Sender: TObject);
+begin
+ Plugins.Reload;
+end;
+
+function Tmain.GetFrameByTag(const tag: String): TFsFrame;
+var
+ i: Integer;
+ fsframe: TFsFrame;
+
+ function makenew: TfsFrame;
+ begin
+ FreeIfCompExists(CompName(tag));
+ fsframe := TFsFrame.Create(Self);
+ fsframe.Name := CompName(tag);
+ fsframe.Caption := tag;
+ fsframe.NameTag := tag;
+ fsframe.Show;
+ Result := fsframe;
+ end;
+
+begin
+ if ComponentCount=0 then begin
+ Result := makenew;
+ Exit;
+ end;
+ for i:=ComponentCount-1 downto 0 do
+ if Components[i] is TfsFrame then begin
+ fsframe := Components[i] as TfsFrame;
+ if fsframe.NameTag = tag then begin
+ Result := fsframe;
+ Exit;
+ end;
+ end;
+ Result := makenew;
+end;
+
+const
+ fsframeHeader = '!FS';
+ fsframeHeaderLen = 27;
+
+procedure Tmain.SendFrame(const F: TFsFrame;
+ const NameTag: String; const bmp: TFastDIB;
+ const quality: Integer; const sendjpg: Boolean );
+
+ function Header(const _size: Integer): String;
+ var
+ s, s2: String;
+ begin
+ s2 := Copy(IntToStr(f.d1.Surface.Width), 1, 4);
+ while Length(s2)<4 do s2:='0'+s2;
+ s := fsframeHeader+s2;
+ s2 := Copy(IntToStr(f.d1.Surface.Height), 1, 4);
+ while Length(s2)<4 do s2:='0'+s2;
+ s := s+s2;
+ s2 := Copy(IntToStr(_size), 1, 7);
+ while Length(s2)<7 do s2:='0'+s2;
+ s := s+s2;
+ s2 := Copy(NameTag, 1, 8);
+ while Length(s2)<8 do s2:=s2+' ';
+ s := s+s2;
+ if sendjpg then s:=s+'1' else s:=s+'0';
+ Result := s;
+ end;
+
+var
+ sd: TDDSurfaceDesc;
+ jSize, dSize: Integer;
+ JP: Pointer;
+begin
+ if not csfs.Active then begin
+ Post('send: not connected');
+ Exit;
+ end;
+ if sendjpg then begin
+ JP := AllocMem(bmp.Size);
+ jSize := SaveJPGMem(bmp, JP, bmp.Size, quality);
+ while csfs.Socket.SendText(Header(jSize))=-1 do
+ Application.HandleMessage;
+ while csfs.Socket.SendBuf(JP^, jSize)=-1 do
+ Application.HandleMessage;
+ FreeMem(JP);
+ end else begin
+ f.d1.Surface.Lock(sd);
+ dSize := sd.lPitch*f.d1.Surface.Height+f.d1.Surface.Width;
+ while csfs.Socket.SendText(Header(dSize))=-1 do
+ Application.HandleMessage;
+ while csfs.Socket.SendBuf(sd.lpSurface^, dSize)=-1 do
+ Application.HandleMessage;
+ f.d1.Surface.UnLock;
+ end;
+end;
+
+// TODO: this procedure is more confusing than it needs to be
+procedure Tmain.ssfsClientRead(Sender: TObject; Socket: TCustomWinSocket);
+const
+ Receiving: Boolean = False;
+ Recd: Integer = 0;
+ fWidth: Integer = 0;
+ fHeight: Integer = 0;
+ fSize: Integer = 0;
+ fJpg: Boolean = True;
+ nametag: String = '';
+ Buf: Pointer = nil;
+ BufPos: Integer = 0;
+var
+ read: Integer;
+ tp: Pointer;
+ s: String;
+ f: TFsFrame;
+ sd: TDDSurfaceDesc;
+ temp: array[0..255] of Char;
+
+ // header was received, extract data about incoming frame
+ procedure GetHeader;
+ var
+ i: Integer;
+ begin
+ S := StrPas(StrLCopy(tp, PChar(SocketMem), fsframeHeaderLen));
+ fWidth := MyStrToInt(Copy(S, 4, 4));
+ fHeight := MyStrToInt(Copy(S, 8, 4));
+ fSize := MyStrToInt(Copy(S, 12, 7));
+ nametag := Trim(Copy(S, 19, 8));
+ fJpg := Boolean(S[27]='1');
+{ Post('Width: '+IntToStr(fWidth)+' Height: '+
+ IntToStr(fHeight)+' Size: '+IntToStr(fSize)+
+ ' nametag: '+nametag+' jpg: '+IntToStr(Integer(fJpg)));
+}
+ Receiving := True;
+ Recd := 0;
+ Buf := AllocMem(fSize);
+ BufPos := 0;
+ if read>fsframeHeaderLen then begin
+ i := read-fsframeHeaderLen;
+ if fSize<i then
+ i := fSize;
+ Move(Pointer(Integer(SocketMem)+fsframeHeaderLen)^,
+ Pointer(Integer(Buf)+BufPos)^, i);
+ Inc(BufPos, read-fsframeHeaderLen);
+ Inc(Recd, read-fsframeHeaderLen);
+ end;
+ end;
+
+ // frame is complete, display it
+ function DoFrame: Boolean;
+ var
+ offset: Integer;
+ begin
+ Result := False;
+ f := GetFrameByTag(nametag);
+ if (f.d1.Surface.Width<>fWidth) or (f.d1.Surface.Height<>fHeight) then
+ f.d1.SetSize(fWidth, fHeight);
+
+ if fJpg then begin
+ LoadJPGMem(fBmp, Buf, fSize, False);
+ fBmp.Draw(f.d1.Surface.Canvas.Handle, 0, 0);
+ f.d1.Surface.Canvas.Release;
+ end else begin
+ f.d1.Surface.Lock(sd);
+ Move(Buf^, sd.lpSurface^, fSize);
+ f.d1.Surface.UnLock;
+ end;
+ f.FlipRequest;
+ FreeMem(Buf);
+ Receiving := False;
+
+ if BufPos>fSize then begin
+ // read: bytes read from socket
+ // bufpos: amount of total data from this and previous reads
+ // fsize: bytes needed for this frame
+ // bufpos - fsize: bytes read belonging to next frame
+ // read - (bufpos - fsize): offset for the next frame
+ offset := read - (BufPos - fSize);
+ read := (BufPos - fSize);
+ Move(Pointer(Integer(SocketMem)+offset)^, SocketMem^, read);
+ Result := True;
+ end;
+ end;
+
+begin
+ tp := @temp;
+ read := Socket.ReceiveBuf(SocketMem^, 100000);
+
+ while True do begin
+// Post('read '+IntToStr(read));
+ if Receiving then begin
+ Inc(Recd, read);
+
+ if BufPos+read > fSize then
+ Move(SocketMem^, Pointer(Integer(Buf)+BufPos)^, fSize-BufPos)
+ else
+ Move(SocketMem^, Pointer(Integer(Buf)+BufPos)^, read);
+
+ Inc(BufPos, read);
+
+ if Recd>=fSize then
+ if DoFrame then
+ Continue;
+ Exit;
+ end;
+ if (StrLComp(PChar(SocketMem), fsframeHeader, Length(fsframeHeader))=0) then begin
+ GetHeader;
+ if Recd>=fSize then
+ if DoFrame then
+ Continue;
+ end;
+ Break;
+ end;
+end;
+
+procedure Tmain.csfsError(Sender: TObject; Socket: TCustomWinSocket;
+ ErrorEvent: TErrorEvent; var ErrorCode: Integer);
+begin
+ ErrorCode := 0;
+end;
+
+procedure Tmain.ssfsClientError(Sender: TObject; Socket: TCustomWinSocket;
+ ErrorEvent: TErrorEvent; var ErrorCode: Integer);
+begin
+ ErrorCode := 0;
+end;
+
+procedure Tmain.csToPdError(Sender: TObject; Socket: TCustomWinSocket;
+ ErrorEvent: TErrorEvent; var ErrorCode: Integer);
+begin
+ ErrorCode := 0;
+end;
+
+procedure Tmain.csfsConnect(Sender: TObject; Socket: TCustomWinSocket);
+begin
+ Post('connected '+csfs.Host+' '+IntToStr(csfs.Port));
+end;
+
+procedure Tmain.csfsDisconnect(Sender: TObject; Socket: TCustomWinSocket);
+begin
+ Post('disconnected '+csfs.Host+' '+IntToStr(csfs.Port));
+end;
+
+procedure Tmain.ssfsClientConnect(Sender: TObject;
+ Socket: TCustomWinSocket);
+begin
+ Post('Connection from '+Socket.RemoteAddress);
+end;
+
+procedure Tmain.ssfsClientDisconnect(Sender: TObject;
+ Socket: TCustomWinSocket);
+begin
+ Post('Disconnected '+Socket.RemoteAddress);
+end;
+
+procedure Tmain.MiLogClick(Sender: TObject);
+begin
+ MiLog.Checked := not MiLog.Checked;
+ log.Visible := MiLog.Checked;
+ logstate := log.Visible;
+end;
+
+procedure Tmain.SendReturnValues(const S: String);
+var
+ i, c: Integer;
+ s2: String;
+begin
+ if not csToPd.Active then Exit;
+ c := WordCount(S, [';']);
+ for i:=1 to c do begin
+ s2 := ExtractWord(i, S, [';']);
+ if Pos('=', s2)>0 then begin
+ csToPd.Socket.SendText(
+ ExtractWord(1, s2, ['='])+' '+
+ ExtractWord(2, s2, ['='])+';'
+ );
+ end;
+ end;
+end;
+
+procedure Tmain.SendReturnValuesString(
+ const PdName: String; const S: String);
+var
+ St: String;
+ i: Integer;
+begin
+ St := S;
+ for i:=1 to Length(St) do begin
+ if St[i]='\' then St[i]:='/';
+ SendReturnValues(PdName+'='+Long2Str(Ord(St[i])));
+ end;
+ SendReturnValues(PdName+'=0');
+end;
+
+procedure Tmain.ExceptionHandler(Sender: TObject; E: Exception);
+var
+ i: Integer;
+ f: TFsFrame;
+begin
+ if Pos('1400', E.Message)>0 then begin // invalid window handle
+ // check any fs.frames with invalid window handles
+ // (due to closing a patch with docked fs.frames)
+ if ComponentCount=0 then Exit;
+ for i:=ComponentCount-1 downto 0 do
+ if Components[i] is TFsFrame then begin
+ f := Components[i] as TFsFrame;
+ if (f.ParentWindow>0) and
+ not IsWindow(f.ParentWindow) then begin
+// Q: close or undock fs.frame?
+// A: this will not happed immediately when a patch is closed,
+// so closing the frame is more intuitive than popping it up
+// after a while.
+ f.Free;
+{ f.ParentWindow := 0;
+ f.Borders(True);}
+ end;
+ end else
+ end else
+ ShowMessage(E.Message);
+end;
+
+procedure Tmain.DropFileHandler(const h: HWND; const DroppedFileName: String);
+var
+ i: Integer;
+ f: TFsFrame;
+begin
+ if ComponentCount=0 then Exit;
+ for i:=ComponentCount-1 downto 0 do
+ if Components[i] is TFsFrame then begin
+ f := Components[i] as TFsFrame;
+ if f.Handle=h then begin
+ f.HandleDroppedFile(DroppedFileName);
+ Break;
+ end;
+ end;
+end;
+
+procedure Tmain.AppMessage(var Msg: Tmsg; var Handled: Boolean);
+const
+ BufferLength : word = 255;
+var
+ DroppedFilename : string;
+ FileIndex : Longword;
+ QtyDroppedFiles : word;
+ pDroppedFilename : array [0..255] of Char;
+// DroppedFileLength : word;
+begin
+ if Msg.Message = WM_DROPFILES then begin
+ FileIndex := $FFFFFFFF;
+ QtyDroppedFiles := DragQueryFile(Msg.WParam, FileIndex,
+ pDroppedFilename, BufferLength);
+ for FileIndex := 0 to (QtyDroppedFiles - 1) do begin
+// DroppedFileLength :=
+ DragQueryFile(Msg.WParam, FileIndex,
+ pDroppedFilename, BufferLength);
+ DroppedFilename := StrPas(pDroppedFilename);
+ DropFileHandler(msg.HWND, DroppedFilename);
+ end;
+ DragFinish(Msg.WParam);
+ Handled := True;
+ end;
+end;
+
+procedure Tmain.minimizeall;
+var
+ i: Integer;
+begin
+ if ComponentCount=0 then Exit;
+ for i:=ComponentCount-1 downto 0 do
+ if Components[i] is TfsForm then
+ TForm(Components[i]).WindowState := wsMinimized;
+end;
+
+procedure Tmain.MiExitClick(Sender: TObject);
+begin
+ Application.Terminate;
+end;
+
+function Tmain.FileExistsInSearchPath(var S: String): Boolean;
+var
+ i: Integer;
+ filestr: String;
+begin
+ Result := FileExists(S);
+ if not Result and (SearchPath.Count>0) then begin
+ filestr := ExtractFileName(S);
+ for i:=0 to SearchPath.Count-1 do begin
+ if FileExists(SearchPath.Strings[i]+'\'+filestr) then begin
+ S := SearchPath.Strings[i]+'\'+filestr;
+ Result := True;
+ Exit;
+ end;
+ end;
+ end;
+end;
+
+procedure Tmain.ImageLogoDblClick(Sender: TObject);
+begin
+ Reset;
+end;
+
+procedure Tmain.FormClose(Sender: TObject; var Action: TCloseAction);
+begin
+ if main.ParentWindow<>0 then begin
+ main.ParentWindow:=0;
+ end;
+end;
+
+end.
+
diff --git a/Source/pluginunit.pas b/Source/pluginunit.pas
new file mode 100644
index 0000000..d4fd51e
--- /dev/null
+++ b/Source/pluginunit.pas
@@ -0,0 +1,227 @@
+{ Copyright (C) 2001 Juha Vehviläinen
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.}
+
+unit pluginunit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ DirectX, DXDraws;
+
+type
+ TEffectProc = procedure(const Bits: Pointer;
+ const lPitch, Width, Height, BitCount: Integer;
+ const args: PChar;
+ const ret: PChar); cdecl;
+
+ TCopyProc = procedure(
+ const Bits1: Pointer;
+ const lPitch1, Width1, Height1, BitCount1: Integer;
+ const Bits2: Pointer;
+ const lPitch2, Width2, Height2, BitCount2: Integer;
+ const args: PChar;
+ const ret: PChar
+ ); cdecl;
+
+ TPointerList = TList;
+ TLibraryList = TList;
+
+ TPlugins = class(TComponent)
+ private
+ Names: TStringList;
+ EffectProcs: TPointerList;
+ CopyProcs: TPointerList;
+ Libs: TLibraryList;
+ procedure LoadHandleFile(const SearchRec: TSearchRec;
+ const FullPath: String);
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure Load;
+ procedure Reload;
+ procedure Clear;
+ function IsPlugin(const s: String): Boolean;
+ function CallEffect(const d: TDirectDrawSurface;
+ const procname: String; const args: String): Boolean;
+ function CallCopy(const d1: TDirectDrawSurface;
+ const d2: TDirectDrawSurface;
+ const procname: String; const args: String): Boolean;
+ end;
+
+implementation
+
+uses
+ mainunit,
+ Filez;
+
+type
+ THandlePtr = ^THandle;
+
+const
+ EffectProcName = 'perform_effect';
+ CopyProcName = 'perform_copy';
+
+{ TPlugins }
+
+constructor TPlugins.Create(AOwner: TComponent);
+begin
+ inherited;
+ Names := TStringList.Create;
+ EffectProcs := TPointerList.Create;
+ CopyProcs := TPointerList.Create;
+ Libs := TLibraryList.Create;
+end;
+
+destructor TPlugins.Destroy;
+begin
+ Clear;
+ Names.Free;
+ EffectProcs.Free;
+ CopyProcs.Free;
+ Libs.Free;
+ inherited;
+end;
+
+procedure TPlugins.Clear;
+var
+ hp: THandlePtr;
+begin
+ while Names.Count>0 do Names.Delete(0);
+ while EffectProcs.Count>0 do EffectProcs.Delete(0);
+ while CopyProcs.Count>0 do CopyProcs.Delete(0);
+ while Libs.Count>0 do begin
+ hp := Libs[0];
+ FreeLibrary(hp^);
+ Libs.Delete(0);
+ end;
+end;
+
+procedure TPlugins.LoadHandleFile(const SearchRec: TSearchRec;
+ const FullPath: String);
+var
+ h: THandle;
+ p: PChar;
+ b: array[0..255] of Char;
+ EffectProc: TEffectProc;
+ CopyProc: TCopyProc;
+ s: String;
+ i: Integer;
+begin
+ p:=@b;
+ if UpperCase(ExtractFileExt(FullPath))='.DLL' then begin
+ h := LoadLibrary(StrPCopy(p, FullPath));
+ if h<>0 then begin
+ @EffectProc := GetProcAddress(h, EffectProcName);
+ @CopyProc := GetProcAddress(h, CopyProcName);
+ s := ExtractFileName(FullPath);
+ i := Pos('.DLL', UpperCase(s));
+ if i>0 then Delete(s, i, 255);
+ Names.Add(s);
+ EffectProcs.Add(@EffectProc);
+ CopyProcs.Add(@CopyProc);
+ Libs.Add(@h);
+ end;
+ end;
+end;
+
+procedure TPlugins.Load;
+var
+ sd: TScanDir;
+ s: String;
+ i: Integer;
+begin
+ sd := TScanDir.Create(Self);
+ sd.OnHandleFile := LoadHandleFile;
+ sd.Scan(ExtractFilePath(Application.ExeName)+'\Plugins');
+ sd.Free;
+ if Names.Count>0 then begin
+ s := '';
+ for i:=0 to Names.Count-1 do begin
+ if s<>'' then s:=s+' ';
+ s:=s+Names[i];
+ end;
+ main.Post('Plugins: '+s);
+ end;
+end;
+
+procedure TPlugins.Reload;
+begin
+ Clear;
+ Load;
+end;
+
+function TPlugins.IsPlugin(const s: String): Boolean;
+begin
+ Result := Names.IndexOf(s)<>-1;
+end;
+
+var
+ argsBuf: array[0..255] of Char;
+
+function TPlugins.CallEffect(const d: TDirectDrawSurface;
+ const procname: String; const args: String): Boolean;
+var
+ i: Integer;
+ Proc: TEffectProc;
+ sd: TDDSurfaceDesc;
+ P: PChar;
+begin
+ Result := False;
+ if (Names.Count=0) or (d.Width=0) or (d.Height=0) then Exit;
+ i := Names.IndexOf(procname);
+ if (i=-1) or (i>=EffectProcs.Count) then Exit;
+ @Proc := EffectProcs[i];
+ if @Proc=nil then Exit;
+ P:=@argsBuf;
+ P[0]:=#0;
+ d.Lock(sd);
+ Proc(sd.lpSurface, sd.lPitch, d.Width, d.Height, d.BitCount,
+ PChar(args), P);
+ d.UnLock;
+ if P[0]<>#0 then
+ main.SendReturnValues(StrPas(P));
+ Result := True;
+end;
+
+function TPlugins.CallCopy(const d1, d2: TDirectDrawSurface;
+ const procname: String; const args: String): Boolean;
+var
+ i: Integer;
+ Proc: TCopyProc;
+ sd1: TDDSurfaceDesc;
+ sd2: TDDSurfaceDesc;
+ P: PChar;
+begin
+ Result := False;
+ if (Names.Count=0) or
+ (d1.Width=0) or (d1.Height=0) or
+ (d2.Width=0) or (d2.Height=0) then Exit;
+ i := Names.IndexOf(procname);
+ if (i=-1) or (i>=CopyProcs.Count) then Exit;
+ @Proc := CopyProcs[i];
+ if @Proc=nil then Exit;
+ P:=@argsBuf;
+ P[0]:=#0;
+ d1.Lock(sd1);
+ d2.Lock(sd2);
+ Proc(sd1.lpSurface, sd1.lPitch, d1.Width, d1.Height, d1.BitCount,
+ sd2.lpSurface, sd2.lPitch, d2.Width, d2.Height, d2.BitCount,
+ PChar(args), P);
+ d1.UnLock;
+ d2.UnLock;
+ if P[0]<>#0 then
+ main.SendReturnValues(StrPas(P));
+ Result := True;
+end;
+
+end.
+
diff --git a/Source/pshostunit.pas b/Source/pshostunit.pas
new file mode 100644
index 0000000..42868c3
--- /dev/null
+++ b/Source/pshostunit.pas
@@ -0,0 +1,145 @@
+unit pshostunit;
+
+interface
+
+uses
+ Forms, SysUtils, DirectX, DxDraws,
+ fsframeunit, C2PhotoShopHost;
+
+function IsFilter(const S: String): Boolean;
+
+function Filter_effect(const psh: TC2PhotoShopHost;
+ const d: TDirectDrawSurface;
+ const procname: String; const args: String): Boolean;
+
+function Filter_copy(const psh: TC2PhotoShopHost;
+ const d1, d2: TDirectDrawSurface;
+ const procname: String; const args: String): Boolean;
+
+implementation
+
+uses
+ Windows, Graphics, DIB,
+ mainunit;
+
+var
+ FilterPath: String;
+
+function FullFilterPath(const S: String): String;
+begin
+ Result := FilterPath+'\'+S;
+ if Uppercase(ExtractFileExt(S))<>'.8BF' then
+ Result := Result+'.8BF';
+end;
+
+function IsFilter(const S: String): Boolean;
+begin
+ Result := FileExists(FullFilterPath(S));
+end;
+
+function Filter_effect(const psh: TC2PhotoShopHost;
+ const d: TDirectDrawSurface;
+ const procname: String; const args: String): Boolean;
+const
+ Active: Boolean = False;
+var
+ sd: TDDSurfaceDesc;
+ dib: TDxDib;
+begin
+ Result := False;
+ if Active then Exit; // disable recursion
+ Active := True;
+ if not psh.LoadFilterDLL(FullFilterPath(procname)) then begin
+ main.Post('Filter load error: '+procname+'. Requires Adobe''s Plugin.dll?');
+ Active := False;
+ Exit;
+ end;
+
+ d.Lock(sd);
+ psh.Surface := @sd;
+
+ if d.BitCount=24 then begin
+ psh.SrcPtr := sd.lpSurface;
+ psh.DstPtr := sd.lpSurface;
+ end else begin
+ // DIB will ensure we're @ 24 bits per pixel...
+ dib := TDxDib.Create(main);
+ dib.DIB.Assign(d);
+
+ psh.DIB := dib;
+ psh.SrcPtr := dib.DIB.PBits;
+ psh.DstPtr := dib.DIB.PBits;
+ end;
+
+ psh.CallDialog := (args='');
+ psh.args := args;
+ psh.RunFilter;
+
+ d.UnLock;
+
+ if d.BitCount<>24 then begin
+ d.Assign(dib.DIB);
+ dib.Free;
+ end;
+ Result := True;
+ Active := False;
+end;
+
+function Filter_copy(const psh: TC2PhotoShopHost;
+ const d1, d2: TDirectDrawSurface;
+ const procname: String; const args: String): Boolean;
+const
+ Active: Boolean = False;
+var
+ sd1, sd2: TDDSurfaceDesc;
+ dib1, dib2: TDxDib;
+begin
+ Result := False;
+ if Active then Exit; // disable recursion
+ Active := True;
+ if not psh.LoadFilterDLL(FullFilterPath(procname)) then begin
+ main.Post('Filter load error: '+procname+'. Requires Adobe''s Plugin.dll?');
+ Active := False;
+ Exit;
+ end;
+
+ d1.Lock(sd1);
+ d2.Lock(sd2);
+
+ psh.Surface := @sd1;
+
+ if d1.BitCount=24 then begin
+ psh.SrcPtr := sd1.lpSurface;
+ psh.DstPtr := sd2.lpSurface;
+ end else begin
+ // DIB will ensure we're @ 24 bits per pixel...
+ dib1 := TDxDib.Create(main);
+ dib2 := TDxDib.Create(main);
+ dib1.DIB.Assign(d1);
+ dib2.DIB.SetSize(dib1.DIB.Width, dib1.DIB.Height, 24);
+
+ psh.DIB := dib1;
+ psh.SrcPtr := dib1.DIB.PBits;
+ psh.DstPtr := dib2.DIB.PBits;
+ end;
+
+ psh.CallDialog := (args='');
+ psh.args := args;
+ psh.RunFilter;
+
+ d1.UnLock;
+ d2.UnLock;
+
+ if d1.BitCount<>24 then begin
+ d2.Assign(dib2.DIB);
+ dib1.Free;
+ dib2.Free;
+ end;
+ Result := True;
+ Active := False;
+end;
+
+begin
+ FilterPath := ExtractFilePath(Application.ExeName)+'\Filters'
+end.
+
diff --git a/extract.wav b/extract.wav
new file mode 100644
index 0000000..11c1b7b
--- /dev/null
+++ b/extract.wav
Binary files differ
diff --git a/head.avi b/head.avi
new file mode 100644
index 0000000..dcae3c1
--- /dev/null
+++ b/head.avi
Binary files differ
diff --git a/ijl15.dll b/ijl15.dll
new file mode 100644
index 0000000..0ea9873
--- /dev/null
+++ b/ijl15.dll
Binary files differ