diff options
author | Juha Vehviläinen <jusu@users.sourceforge.net> | 2002-07-06 17:50:18 +0000 |
---|---|---|
committer | Juha Vehviläinen <jusu@users.sourceforge.net> | 2002-07-06 17:50:18 +0000 |
commit | 4d64e4cd434426234a5c313c151cd79b6afc299e (patch) | |
tree | 5c23dd6acc65b869741d3bb9d33912d74bb7407d |
*** empty log message ***svn2git-root
svn path=/trunk/Framestein/; revision=27
-rw-r--r-- | CHANGELOG.txt | 130 | ||||
-rw-r--r-- | Filters/BossTota.8bf | bin | 0 -> 57344 bytes | |||
-rw-r--r-- | Filters/BubbSpac.8bf | bin | 0 -> 57344 bytes | |||
-rw-r--r-- | Filters/ChloeMag.8bf | bin | 0 -> 57344 bytes | |||
-rw-r--r-- | Filters/ColSteps.8bf | bin | 0 -> 57344 bytes | |||
-rw-r--r-- | Filters/README.txt | 9 | ||||
-rwxr-xr-x | Framestein.exe | bin | 0 -> 874496 bytes | |||
-rw-r--r-- | HARMON.jpg | bin | 0 -> 31376 bytes | |||
-rw-r--r-- | Patches/00 example-basics.pd | 38 | ||||
-rw-r--r-- | Patches/01 example-video.pd | 30 | ||||
-rw-r--r-- | Patches/02 example-docking.pd | 88 | ||||
-rw-r--r-- | Patches/03 example-docking2.pd | 15 | ||||
-rw-r--r-- | Patches/04 example-draganddrop.pd | 25 | ||||
-rw-r--r-- | Patches/05 example-plugins.pd | 127 | ||||
-rw-r--r-- | Patches/06 example-photoshopfilters.pd | 105 | ||||
-rw-r--r-- | Patches/07 example-blending.pd | 57 | ||||
-rw-r--r-- | Patches/08 example-masking.pd | 66 | ||||
-rw-r--r-- | Patches/09 example-sonogram.pd | 74 | ||||
-rw-r--r-- | Patches/10 example-waveformdisplay.pd | 126 | ||||
-rw-r--r-- | Patches/11 example-browser.pd | 30 | ||||
-rw-r--r-- | Patches/12 example-network.pd | 62 | ||||
-rw-r--r-- | Patches/13 example-avioutput.pd | 61 | ||||
-rw-r--r-- | Patches/14 example-hist.pd | 46 | ||||
-rw-r--r-- | Patches/15 example-searchpath.pd | 28 | ||||
-rw-r--r-- | Patches/README.txt | 1 | ||||
-rw-r--r-- | Patches/arraysize.c | 44 | ||||
-rw-r--r-- | Patches/arraysize.dll | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | Patches/arraysize.exp | bin | 0 -> 594 bytes | |||
-rw-r--r-- | Patches/arraysize.lib | bin | 0 -> 1986 bytes | |||
-rw-r--r-- | Patches/arraysize.obj | bin | 0 -> 1761 bytes | |||
-rw-r--r-- | Patches/bangx.pd | 10 | ||||
-rw-r--r-- | Patches/buildstr.c | 51 | ||||
-rw-r--r-- | Patches/buildstr.dll | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | Patches/buildstr.exp | bin | 0 -> 586 bytes | |||
-rw-r--r-- | Patches/buildstr.lib | bin | 0 -> 1970 bytes | |||
-rw-r--r-- | Patches/buildstr.obj | bin | 0 -> 1830 bytes | |||
-rw-r--r-- | Patches/count.pd | 17 | ||||
-rw-r--r-- | Patches/displaydepth.h | 19 | ||||
-rw-r--r-- | Patches/dllcall.h | 46 | ||||
-rw-r--r-- | Patches/externals-documentation.pd | 342 | ||||
-rw-r--r-- | Patches/fps.pd | 25 | ||||
-rw-r--r-- | Patches/fs.avi.pd | 33 | ||||
-rw-r--r-- | Patches/fs.blend.pd | 37 | ||||
-rw-r--r-- | Patches/fs.browser.pd | 48 | ||||
-rw-r--r-- | Patches/fs.copy.pd | 51 | ||||
-rw-r--r-- | Patches/fs.draw.pd | 32 | ||||
-rw-r--r-- | Patches/fs.event.pd | 30 | ||||
-rw-r--r-- | Patches/fs.film.pd | 47 | ||||
-rw-r--r-- | Patches/fs.frame.pd | 137 | ||||
-rw-r--r-- | Patches/fs.framed.pd | 24 | ||||
-rw-r--r-- | Patches/fs.fx.pd | 21 | ||||
-rw-r--r-- | Patches/fs.hist.pd | 39 | ||||
-rw-r--r-- | Patches/fs.info.pd | 33 | ||||
-rw-r--r-- | Patches/fs.main.pd | 52 | ||||
-rw-r--r-- | Patches/fs.mask.pd | 39 | ||||
-rw-r--r-- | Patches/fs.rgb.pd | 31 | ||||
-rw-r--r-- | Patches/fs.sonogram.pd | 63 | ||||
-rw-r--r-- | Patches/fs.text.pd | 29 | ||||
-rw-r--r-- | Patches/fs.waveform.pd | 146 | ||||
-rw-r--r-- | Patches/fs.waveselection.pd | 47 | ||||
-rw-r--r-- | Patches/fs_sender.pd | 7 | ||||
-rw-r--r-- | Patches/init.pd | 9 | ||||
-rw-r--r-- | Patches/l2s.c | 89 | ||||
-rw-r--r-- | Patches/l2s.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Patches/l2s.exp | bin | 0 -> 546 bytes | |||
-rw-r--r-- | Patches/l2s.lib | bin | 0 -> 1884 bytes | |||
-rw-r--r-- | Patches/l2s.obj | bin | 0 -> 2407 bytes | |||
-rw-r--r-- | Patches/makefile | 38 | ||||
-rw-r--r-- | Patches/noize.dll | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | Patches/ooo.pd | 19 | ||||
-rw-r--r-- | Patches/play.pd | 8 | ||||
-rw-r--r-- | Patches/ramp.pd | 35 | ||||
-rw-r--r-- | Patches/randombox.pd | 19 | ||||
-rw-r--r-- | Patches/reset.pd | 8 | ||||
-rw-r--r-- | Patches/sameonce.pd | 15 | ||||
-rw-r--r-- | Patches/snapOut~.pd | 45 | ||||
-rw-r--r-- | Patches/vcolor~.c | 96 | ||||
-rw-r--r-- | Patches/vcolor~.dll | bin | 0 -> 49152 bytes | |||
-rw-r--r-- | Patches/vcolor~.exp | bin | 0 -> 599 bytes | |||
-rw-r--r-- | Patches/vcolor~.lib | bin | 0 -> 1976 bytes | |||
-rw-r--r-- | Patches/vcolor~.obj | bin | 0 -> 3898 bytes | |||
-rw-r--r-- | Patches/vcopy.pd | 16 | ||||
-rw-r--r-- | Patches/vdrawarray.c | 131 | ||||
-rw-r--r-- | Patches/vdrawarray.dll | bin | 0 -> 49152 bytes | |||
-rw-r--r-- | Patches/vdrawarray.exp | bin | 0 -> 602 bytes | |||
-rw-r--r-- | Patches/vdrawarray.lib | bin | 0 -> 2004 bytes | |||
-rw-r--r-- | Patches/vdrawarray.obj | bin | 0 -> 4031 bytes | |||
-rw-r--r-- | Patches/vframe.c | 262 | ||||
-rw-r--r-- | Patches/vframe.dll | bin | 0 -> 49152 bytes | |||
-rw-r--r-- | Patches/vframe.exp | bin | 0 -> 570 bytes | |||
-rw-r--r-- | Patches/vframe.h | 66 | ||||
-rw-r--r-- | Patches/vframe.lib | bin | 0 -> 1936 bytes | |||
-rw-r--r-- | Patches/vframe.obj | bin | 0 -> 7069 bytes | |||
-rw-r--r-- | Patches/vframeread~.c | 123 | ||||
-rw-r--r-- | Patches/vframeread~.dll | bin | 0 -> 49152 bytes | |||
-rw-r--r-- | Patches/vframeread~.exp | bin | 0 -> 631 bytes | |||
-rw-r--r-- | Patches/vframeread~.lib | bin | 0 -> 2044 bytes | |||
-rw-r--r-- | Patches/vframeread~.obj | bin | 0 -> 3703 bytes | |||
-rw-r--r-- | Patches/videoscrub.pd | 29 | ||||
-rw-r--r-- | Patches/vimport.pd | 11 | ||||
-rw-r--r-- | Patches/vplugin.pd | 9 | ||||
-rw-r--r-- | Patches/vref.pd | 10 | ||||
-rw-r--r-- | Patches/vrgb~.c | 117 | ||||
-rw-r--r-- | Patches/vrgb~.dll | bin | 0 -> 49152 bytes | |||
-rw-r--r-- | Patches/vrgb~.exp | bin | 0 -> 583 bytes | |||
-rw-r--r-- | Patches/vrgb~.lib | bin | 0 -> 1942 bytes | |||
-rw-r--r-- | Patches/vrgb~.obj | bin | 0 -> 3717 bytes | |||
-rw-r--r-- | Patches/vsig~.c | 123 | ||||
-rw-r--r-- | Patches/vsig~.dll | bin | 0 -> 49152 bytes | |||
-rw-r--r-- | Patches/vsig~.exp | bin | 0 -> 583 bytes | |||
-rw-r--r-- | Patches/vsig~.lib | bin | 0 -> 1942 bytes | |||
-rw-r--r-- | Patches/vsig~.obj | bin | 0 -> 3346 bytes | |||
-rw-r--r-- | Patches/vsnapshot~.c | 139 | ||||
-rw-r--r-- | Patches/vsnapshot~.dll | bin | 0 -> 49152 bytes | |||
-rw-r--r-- | Patches/vsnapshot~.exp | bin | 0 -> 623 bytes | |||
-rw-r--r-- | Patches/vsnapshot~.lib | bin | 0 -> 2028 bytes | |||
-rw-r--r-- | Patches/vsnapshot~.obj | bin | 0 -> 4210 bytes | |||
-rw-r--r-- | Patches/vsnap~.pd | 18 | ||||
-rw-r--r-- | PeRColate Framestein.pdf | bin | 0 -> 7998 bytes | |||
-rw-r--r-- | Plugins/2colors.cpp | 21 | ||||
-rw-r--r-- | Plugins/2colors.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/2colors.exp | bin | 0 -> 627 bytes | |||
-rw-r--r-- | Plugins/2colors.lib | bin | 0 -> 2066 bytes | |||
-rw-r--r-- | Plugins/2colors.obj | bin | 0 -> 1133 bytes | |||
-rw-r--r-- | Plugins/README.txt | 12 | ||||
-rw-r--r-- | Plugins/bend.c | 86 | ||||
-rw-r--r-- | Plugins/bend.dll | bin | 0 -> 49152 bytes | |||
-rw-r--r-- | Plugins/bend.exp | bin | 0 -> 697 bytes | |||
-rw-r--r-- | Plugins/bend.lib | bin | 0 -> 2110 bytes | |||
-rw-r--r-- | Plugins/bend.obj | bin | 0 -> 1726 bytes | |||
-rw-r--r-- | Plugins/black.c | 13 | ||||
-rw-r--r-- | Plugins/black.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/black.exp | bin | 0 -> 700 bytes | |||
-rw-r--r-- | Plugins/black.lib | bin | 0 -> 2120 bytes | |||
-rw-r--r-- | Plugins/black.obj | bin | 0 -> 560 bytes | |||
-rw-r--r-- | Plugins/colortv.c | 69 | ||||
-rw-r--r-- | Plugins/colortv.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/colortv.exp | bin | 0 -> 708 bytes | |||
-rw-r--r-- | Plugins/colortv.lib | bin | 0 -> 2146 bytes | |||
-rw-r--r-- | Plugins/colortv.obj | bin | 0 -> 864 bytes | |||
-rw-r--r-- | Plugins/copy_vert.c | 30 | ||||
-rw-r--r-- | Plugins/copy_vert.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/copy_vert.exp | bin | 0 -> 583 bytes | |||
-rw-r--r-- | Plugins/copy_vert.lib | bin | 0 -> 1970 bytes | |||
-rw-r--r-- | Plugins/copy_vert.obj | bin | 0 -> 816 bytes | |||
-rw-r--r-- | Plugins/fs2vf.c | 49 | ||||
-rw-r--r-- | Plugins/fs2vf.dll | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | Plugins/fs2vf.exp | bin | 0 -> 575 bytes | |||
-rw-r--r-- | Plugins/fs2vf.lib | bin | 0 -> 1932 bytes | |||
-rw-r--r-- | Plugins/fs2vf.obj | bin | 0 -> 1894 bytes | |||
-rw-r--r-- | Plugins/gol.c | 89 | ||||
-rw-r--r-- | Plugins/gol.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/gol.exp | bin | 0 -> 567 bytes | |||
-rw-r--r-- | Plugins/gol.lib | bin | 0 -> 1908 bytes | |||
-rw-r--r-- | Plugins/gol.obj | bin | 0 -> 1878 bytes | |||
-rw-r--r-- | Plugins/green.cpp | 14 | ||||
-rw-r--r-- | Plugins/green.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/green.exp | bin | 0 -> 619 bytes | |||
-rw-r--r-- | Plugins/green.lib | bin | 0 -> 2042 bytes | |||
-rw-r--r-- | Plugins/green.obj | bin | 0 -> 849 bytes | |||
-rw-r--r-- | Plugins/hist.cpp | 54 | ||||
-rw-r--r-- | Plugins/hist.dll | bin | 0 -> 45056 bytes | |||
-rw-r--r-- | Plugins/hist.exp | bin | 0 -> 614 bytes | |||
-rw-r--r-- | Plugins/hist.lib | bin | 0 -> 2032 bytes | |||
-rw-r--r-- | Plugins/hist.obj | bin | 0 -> 1986 bytes | |||
-rw-r--r-- | Plugins/makefile | 82 | ||||
-rw-r--r-- | Plugins/makesliders.c | 40 | ||||
-rw-r--r-- | Plugins/makesliders.dll | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | Plugins/makesliders.exp | bin | 0 -> 599 bytes | |||
-rw-r--r-- | Plugins/makesliders.lib | bin | 0 -> 2004 bytes | |||
-rw-r--r-- | Plugins/makesliders.obj | bin | 0 -> 940 bytes | |||
-rw-r--r-- | Plugins/ms.dll | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | Plugins/noize.c | 21 | ||||
-rw-r--r-- | Plugins/noize.dll | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | Plugins/noize.exp | bin | 0 -> 700 bytes | |||
-rw-r--r-- | Plugins/noize.lib | bin | 0 -> 2120 bytes | |||
-rw-r--r-- | Plugins/noize.obj | bin | 0 -> 865 bytes | |||
-rw-r--r-- | Plugins/pixels.h | 117 | ||||
-rw-r--r-- | Plugins/plot.cpp | 25 | ||||
-rw-r--r-- | Plugins/plot.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/plot.exp | bin | 0 -> 614 bytes | |||
-rw-r--r-- | Plugins/plot.lib | bin | 0 -> 2032 bytes | |||
-rw-r--r-- | Plugins/plot.obj | bin | 0 -> 1011 bytes | |||
-rw-r--r-- | Plugins/plugin.h | 119 | ||||
-rw-r--r-- | Plugins/rgb.c | 62 | ||||
-rw-r--r-- | Plugins/rgb.dll | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | Plugins/rgb.exp | bin | 0 -> 567 bytes | |||
-rw-r--r-- | Plugins/rgb.lib | bin | 0 -> 1908 bytes | |||
-rw-r--r-- | Plugins/rgb.obj | bin | 0 -> 1180 bytes | |||
-rw-r--r-- | Plugins/rgbcopy.cpp | 28 | ||||
-rw-r--r-- | Plugins/rgbcopy.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/rgbcopy.exp | bin | 0 -> 621 bytes | |||
-rw-r--r-- | Plugins/rgbcopy.lib | bin | 0 -> 2062 bytes | |||
-rw-r--r-- | Plugins/rgbcopy.obj | bin | 0 -> 1884 bytes | |||
-rw-r--r-- | Plugins/setbits.c | 11 | ||||
-rw-r--r-- | Plugins/setbits.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/setbits.exp | bin | 0 -> 583 bytes | |||
-rw-r--r-- | Plugins/setbits.lib | bin | 0 -> 1956 bytes | |||
-rw-r--r-- | Plugins/setbits.obj | bin | 0 -> 514 bytes | |||
-rw-r--r-- | Plugins/sharemem.h | 61 | ||||
-rw-r--r-- | Plugins/shuffle.c | 42 | ||||
-rw-r--r-- | Plugins/shuffle.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/shuffle.exp | bin | 0 -> 583 bytes | |||
-rw-r--r-- | Plugins/shuffle.lib | bin | 0 -> 1956 bytes | |||
-rw-r--r-- | Plugins/shuffle.obj | bin | 0 -> 1020 bytes | |||
-rw-r--r-- | Plugins/sonogram.cpp | 82 | ||||
-rw-r--r-- | Plugins/sonogram.dll | bin | 0 -> 45056 bytes | |||
-rw-r--r-- | Plugins/sonogram.exp | bin | 0 -> 630 bytes | |||
-rw-r--r-- | Plugins/sonogram.lib | bin | 0 -> 2080 bytes | |||
-rw-r--r-- | Plugins/sonogram.obj | bin | 0 -> 2306 bytes | |||
-rw-r--r-- | Plugins/subtract.cpp | 38 | ||||
-rw-r--r-- | Plugins/subtract.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/subtract.exp | bin | 0 -> 630 bytes | |||
-rw-r--r-- | Plugins/subtract.lib | bin | 0 -> 2080 bytes | |||
-rw-r--r-- | Plugins/subtract.obj | bin | 0 -> 1409 bytes | |||
-rw-r--r-- | Plugins/swap.cpp | 62 | ||||
-rw-r--r-- | Plugins/swap.dll | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | Plugins/swap.exp | bin | 0 -> 608 bytes | |||
-rw-r--r-- | Plugins/swap.lib | bin | 0 -> 2026 bytes | |||
-rw-r--r-- | Plugins/swap.obj | bin | 0 -> 1893 bytes | |||
-rw-r--r-- | Plugins/tile.cpp | 59 | ||||
-rw-r--r-- | Plugins/tile.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/tile.exp | bin | 0 -> 608 bytes | |||
-rw-r--r-- | Plugins/tile.lib | bin | 0 -> 2026 bytes | |||
-rw-r--r-- | Plugins/tile.obj | bin | 0 -> 1312 bytes | |||
-rw-r--r-- | Plugins/vf2fs.c | 49 | ||||
-rw-r--r-- | Plugins/vf2fs.dll | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | Plugins/vf2fs.exp | bin | 0 -> 575 bytes | |||
-rw-r--r-- | Plugins/vf2fs.lib | bin | 0 -> 1932 bytes | |||
-rw-r--r-- | Plugins/vf2fs.obj | bin | 0 -> 1894 bytes | |||
-rw-r--r-- | Plugins/xbend.c | 99 | ||||
-rw-r--r-- | Plugins/xbend.dll | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | Plugins/xbend.exp | bin | 0 -> 700 bytes | |||
-rw-r--r-- | Plugins/xbend.lib | bin | 0 -> 2120 bytes | |||
-rw-r--r-- | Plugins/xbend.obj | bin | 0 -> 1832 bytes | |||
-rw-r--r-- | Plugins/xshred.c | 20 | ||||
-rw-r--r-- | Plugins/xshred.dll | bin | 0 -> 28672 bytes | |||
-rw-r--r-- | Plugins/xshred.exp | bin | 0 -> 570 bytes | |||
-rw-r--r-- | Plugins/xshred.lib | bin | 0 -> 1936 bytes | |||
-rw-r--r-- | Plugins/xshred.obj | bin | 0 -> 640 bytes | |||
-rw-r--r-- | README.txt | 75 | ||||
-rw-r--r-- | Reija/01.jpg | bin | 0 -> 37151 bytes | |||
-rw-r--r-- | Reija/02.jpg | bin | 0 -> 24320 bytes | |||
-rw-r--r-- | Reija/03.jpg | bin | 0 -> 30982 bytes | |||
-rw-r--r-- | Reija/04.jpg | bin | 0 -> 31003 bytes | |||
-rw-r--r-- | Reija/05.jpg | bin | 0 -> 26077 bytes | |||
-rw-r--r-- | Reija/06.jpg | bin | 0 -> 37365 bytes | |||
-rw-r--r-- | Reija/07.jpg | bin | 0 -> 35830 bytes | |||
-rw-r--r-- | Reija/08.jpg | bin | 0 -> 36637 bytes | |||
-rw-r--r-- | Source/Filez.pas | 87 | ||||
-rw-r--r-- | Source/Framestein.cfg | 39 | ||||
-rw-r--r-- | Source/Framestein.dof | 91 | ||||
-rw-r--r-- | Source/Framestein.dpr | 46 | ||||
-rw-r--r-- | Source/Framestein.dsk | 222 | ||||
-rw-r--r-- | Source/Framestein.res | bin | 0 -> 4056 bytes | |||
-rw-r--r-- | Source/FsAviWriter.pas | 888 | ||||
-rw-r--r-- | Source/GPL.txt | 340 | ||||
-rw-r--r-- | Source/README.txt | 36 | ||||
-rw-r--r-- | Source/Strz.pas | 182 | ||||
-rw-r--r-- | Source/configureunit.dfm | 157 | ||||
-rw-r--r-- | Source/configureunit.pas | 120 | ||||
-rw-r--r-- | Source/dc.inc | 42 | ||||
-rw-r--r-- | Source/effectsunit.pas | 109 | ||||
-rw-r--r-- | Source/fsDcAvi.pas | 1615 | ||||
-rw-r--r-- | Source/fsaviunit.dfm | 23 | ||||
-rw-r--r-- | Source/fsaviunit.pas | 103 | ||||
-rw-r--r-- | Source/fsbrowserunit.dfm | 35 | ||||
-rw-r--r-- | Source/fsbrowserunit.pas | 113 | ||||
-rw-r--r-- | Source/fscopyunit.dfm | 26 | ||||
-rw-r--r-- | Source/fscopyunit.pas | 349 | ||||
-rw-r--r-- | Source/fsdrawunit.dfm | 17 | ||||
-rw-r--r-- | Source/fsdrawunit.pas | 101 | ||||
-rw-r--r-- | Source/fsformunit.pas | 18 | ||||
-rw-r--r-- | Source/fsframeunit.dfm | 146 | ||||
-rw-r--r-- | Source/fsframeunit.pas | 1098 | ||||
-rw-r--r-- | Source/fsinfounit.dfm | 16 | ||||
-rw-r--r-- | Source/fsinfounit.pas | 53 | ||||
-rw-r--r-- | Source/fsspeedbutton.pas | 48 | ||||
-rw-r--r-- | Source/fstextunit.dfm | 18 | ||||
-rw-r--r-- | Source/fstextunit.pas | 148 | ||||
-rw-r--r-- | Source/logunit.dfm | 100 | ||||
-rw-r--r-- | Source/logunit.pas | 60 | ||||
-rw-r--r-- | Source/mainunit.dfm | 3547 | ||||
-rw-r--r-- | Source/mainunit.pas | 903 | ||||
-rw-r--r-- | Source/pluginunit.pas | 227 | ||||
-rw-r--r-- | Source/pshostunit.pas | 145 | ||||
-rw-r--r-- | extract.wav | bin | 0 -> 229580 bytes | |||
-rw-r--r-- | head.avi | bin | 0 -> 82944 bytes | |||
-rw-r--r-- | ijl15.dll | bin | 0 -> 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 Binary files differnew file mode 100644 index 0000000..9d1845a --- /dev/null +++ b/Filters/BossTota.8bf diff --git a/Filters/BubbSpac.8bf b/Filters/BubbSpac.8bf Binary files differnew file mode 100644 index 0000000..f2d39f8 --- /dev/null +++ b/Filters/BubbSpac.8bf diff --git a/Filters/ChloeMag.8bf b/Filters/ChloeMag.8bf Binary files differnew file mode 100644 index 0000000..4c4c056 --- /dev/null +++ b/Filters/ChloeMag.8bf diff --git a/Filters/ColSteps.8bf b/Filters/ColSteps.8bf Binary files differnew file mode 100644 index 0000000..3354df5 --- /dev/null +++ b/Filters/ColSteps.8bf 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 Binary files differnew file mode 100755 index 0000000..4879d1f --- /dev/null +++ b/Framestein.exe diff --git a/HARMON.jpg b/HARMON.jpg Binary files differnew file mode 100644 index 0000000..b84472c --- /dev/null +++ b/HARMON.jpg 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 Binary files differnew file mode 100644 index 0000000..ffa3c8f --- /dev/null +++ b/Patches/arraysize.dll diff --git a/Patches/arraysize.exp b/Patches/arraysize.exp Binary files differnew file mode 100644 index 0000000..6292542 --- /dev/null +++ b/Patches/arraysize.exp diff --git a/Patches/arraysize.lib b/Patches/arraysize.lib Binary files differnew file mode 100644 index 0000000..c0342cf --- /dev/null +++ b/Patches/arraysize.lib diff --git a/Patches/arraysize.obj b/Patches/arraysize.obj Binary files differnew file mode 100644 index 0000000..8c664e8 --- /dev/null +++ b/Patches/arraysize.obj 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 Binary files differnew file mode 100644 index 0000000..92de6a3 --- /dev/null +++ b/Patches/buildstr.dll diff --git a/Patches/buildstr.exp b/Patches/buildstr.exp Binary files differnew file mode 100644 index 0000000..38c60e9 --- /dev/null +++ b/Patches/buildstr.exp diff --git a/Patches/buildstr.lib b/Patches/buildstr.lib Binary files differnew file mode 100644 index 0000000..d1aa14c --- /dev/null +++ b/Patches/buildstr.lib diff --git a/Patches/buildstr.obj b/Patches/buildstr.obj Binary files differnew file mode 100644 index 0000000..a916941 --- /dev/null +++ b/Patches/buildstr.obj 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 Binary files differnew file mode 100644 index 0000000..c46d150 --- /dev/null +++ b/Patches/l2s.dll diff --git a/Patches/l2s.exp b/Patches/l2s.exp Binary files differnew file mode 100644 index 0000000..18ec776 --- /dev/null +++ b/Patches/l2s.exp diff --git a/Patches/l2s.lib b/Patches/l2s.lib Binary files differnew file mode 100644 index 0000000..b875e0b --- /dev/null +++ b/Patches/l2s.lib diff --git a/Patches/l2s.obj b/Patches/l2s.obj Binary files differnew file mode 100644 index 0000000..c4e67b2 --- /dev/null +++ b/Patches/l2s.obj 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 Binary files differnew file mode 100644 index 0000000..cdd4326 --- /dev/null +++ b/Patches/noize.dll 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 Binary files differnew file mode 100644 index 0000000..ba9ff30 --- /dev/null +++ b/Patches/vcolor~.dll diff --git a/Patches/vcolor~.exp b/Patches/vcolor~.exp Binary files differnew file mode 100644 index 0000000..f07ba8c --- /dev/null +++ b/Patches/vcolor~.exp diff --git a/Patches/vcolor~.lib b/Patches/vcolor~.lib Binary files differnew file mode 100644 index 0000000..6092fa3 --- /dev/null +++ b/Patches/vcolor~.lib diff --git a/Patches/vcolor~.obj b/Patches/vcolor~.obj Binary files differnew file mode 100644 index 0000000..80e68ad --- /dev/null +++ b/Patches/vcolor~.obj 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 Binary files differnew file mode 100644 index 0000000..f14883b --- /dev/null +++ b/Patches/vdrawarray.dll diff --git a/Patches/vdrawarray.exp b/Patches/vdrawarray.exp Binary files differnew file mode 100644 index 0000000..00b8adf --- /dev/null +++ b/Patches/vdrawarray.exp diff --git a/Patches/vdrawarray.lib b/Patches/vdrawarray.lib Binary files differnew file mode 100644 index 0000000..53139da --- /dev/null +++ b/Patches/vdrawarray.lib diff --git a/Patches/vdrawarray.obj b/Patches/vdrawarray.obj Binary files differnew file mode 100644 index 0000000..bf12d3c --- /dev/null +++ b/Patches/vdrawarray.obj 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 Binary files differnew file mode 100644 index 0000000..677c448 --- /dev/null +++ b/Patches/vframe.dll diff --git a/Patches/vframe.exp b/Patches/vframe.exp Binary files differnew file mode 100644 index 0000000..de5412f --- /dev/null +++ b/Patches/vframe.exp 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 Binary files differnew file mode 100644 index 0000000..f03cc5a --- /dev/null +++ b/Patches/vframe.lib diff --git a/Patches/vframe.obj b/Patches/vframe.obj Binary files differnew file mode 100644 index 0000000..9f6f8cc --- /dev/null +++ b/Patches/vframe.obj 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 Binary files differnew file mode 100644 index 0000000..c433e65 --- /dev/null +++ b/Patches/vframeread~.dll diff --git a/Patches/vframeread~.exp b/Patches/vframeread~.exp Binary files differnew file mode 100644 index 0000000..ca173e8 --- /dev/null +++ b/Patches/vframeread~.exp diff --git a/Patches/vframeread~.lib b/Patches/vframeread~.lib Binary files differnew file mode 100644 index 0000000..c5e2974 --- /dev/null +++ b/Patches/vframeread~.lib diff --git a/Patches/vframeread~.obj b/Patches/vframeread~.obj Binary files differnew file mode 100644 index 0000000..72813aa --- /dev/null +++ b/Patches/vframeread~.obj 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 Binary files differnew file mode 100644 index 0000000..dba660b --- /dev/null +++ b/Patches/vrgb~.dll diff --git a/Patches/vrgb~.exp b/Patches/vrgb~.exp Binary files differnew file mode 100644 index 0000000..431dc6d --- /dev/null +++ b/Patches/vrgb~.exp diff --git a/Patches/vrgb~.lib b/Patches/vrgb~.lib Binary files differnew file mode 100644 index 0000000..49d8fdb --- /dev/null +++ b/Patches/vrgb~.lib diff --git a/Patches/vrgb~.obj b/Patches/vrgb~.obj Binary files differnew file mode 100644 index 0000000..a49f96d --- /dev/null +++ b/Patches/vrgb~.obj 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 Binary files differnew file mode 100644 index 0000000..554cdfe --- /dev/null +++ b/Patches/vsig~.dll diff --git a/Patches/vsig~.exp b/Patches/vsig~.exp Binary files differnew file mode 100644 index 0000000..26db989 --- /dev/null +++ b/Patches/vsig~.exp diff --git a/Patches/vsig~.lib b/Patches/vsig~.lib Binary files differnew file mode 100644 index 0000000..fa4c919 --- /dev/null +++ b/Patches/vsig~.lib diff --git a/Patches/vsig~.obj b/Patches/vsig~.obj Binary files differnew file mode 100644 index 0000000..ba38233 --- /dev/null +++ b/Patches/vsig~.obj 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 Binary files differnew file mode 100644 index 0000000..bc3187a --- /dev/null +++ b/Patches/vsnapshot~.dll diff --git a/Patches/vsnapshot~.exp b/Patches/vsnapshot~.exp Binary files differnew file mode 100644 index 0000000..2d397e5 --- /dev/null +++ b/Patches/vsnapshot~.exp diff --git a/Patches/vsnapshot~.lib b/Patches/vsnapshot~.lib Binary files differnew file mode 100644 index 0000000..b6ac3d4 --- /dev/null +++ b/Patches/vsnapshot~.lib diff --git a/Patches/vsnapshot~.obj b/Patches/vsnapshot~.obj Binary files differnew file mode 100644 index 0000000..a199364 --- /dev/null +++ b/Patches/vsnapshot~.obj 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 Binary files differnew file mode 100644 index 0000000..e8d027e --- /dev/null +++ b/PeRColate Framestein.pdf 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 Binary files differnew file mode 100644 index 0000000..ba62b0f --- /dev/null +++ b/Plugins/2colors.dll diff --git a/Plugins/2colors.exp b/Plugins/2colors.exp Binary files differnew file mode 100644 index 0000000..a0e870b --- /dev/null +++ b/Plugins/2colors.exp diff --git a/Plugins/2colors.lib b/Plugins/2colors.lib Binary files differnew file mode 100644 index 0000000..38cf84a --- /dev/null +++ b/Plugins/2colors.lib diff --git a/Plugins/2colors.obj b/Plugins/2colors.obj Binary files differnew file mode 100644 index 0000000..2013b69 --- /dev/null +++ b/Plugins/2colors.obj 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 Binary files differnew file mode 100644 index 0000000..220d616 --- /dev/null +++ b/Plugins/bend.dll diff --git a/Plugins/bend.exp b/Plugins/bend.exp Binary files differnew file mode 100644 index 0000000..6f7f43a --- /dev/null +++ b/Plugins/bend.exp diff --git a/Plugins/bend.lib b/Plugins/bend.lib Binary files differnew file mode 100644 index 0000000..ebb3f95 --- /dev/null +++ b/Plugins/bend.lib diff --git a/Plugins/bend.obj b/Plugins/bend.obj Binary files differnew file mode 100644 index 0000000..3ac109f --- /dev/null +++ b/Plugins/bend.obj 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 Binary files differnew file mode 100644 index 0000000..cb8b57a --- /dev/null +++ b/Plugins/black.dll diff --git a/Plugins/black.exp b/Plugins/black.exp Binary files differnew file mode 100644 index 0000000..4399f54 --- /dev/null +++ b/Plugins/black.exp diff --git a/Plugins/black.lib b/Plugins/black.lib Binary files differnew file mode 100644 index 0000000..a21da90 --- /dev/null +++ b/Plugins/black.lib diff --git a/Plugins/black.obj b/Plugins/black.obj Binary files differnew file mode 100644 index 0000000..45e140d --- /dev/null +++ b/Plugins/black.obj 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 Binary files differnew file mode 100644 index 0000000..cf5dacf --- /dev/null +++ b/Plugins/colortv.dll diff --git a/Plugins/colortv.exp b/Plugins/colortv.exp Binary files differnew file mode 100644 index 0000000..53c82e7 --- /dev/null +++ b/Plugins/colortv.exp diff --git a/Plugins/colortv.lib b/Plugins/colortv.lib Binary files differnew file mode 100644 index 0000000..f08d5a3 --- /dev/null +++ b/Plugins/colortv.lib diff --git a/Plugins/colortv.obj b/Plugins/colortv.obj Binary files differnew file mode 100644 index 0000000..dcb2aa3 --- /dev/null +++ b/Plugins/colortv.obj 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 Binary files differnew file mode 100644 index 0000000..95aab74 --- /dev/null +++ b/Plugins/copy_vert.dll diff --git a/Plugins/copy_vert.exp b/Plugins/copy_vert.exp Binary files differnew file mode 100644 index 0000000..d7f0589 --- /dev/null +++ b/Plugins/copy_vert.exp diff --git a/Plugins/copy_vert.lib b/Plugins/copy_vert.lib Binary files differnew file mode 100644 index 0000000..790bae5 --- /dev/null +++ b/Plugins/copy_vert.lib diff --git a/Plugins/copy_vert.obj b/Plugins/copy_vert.obj Binary files differnew file mode 100644 index 0000000..543c39f --- /dev/null +++ b/Plugins/copy_vert.obj 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 Binary files differnew file mode 100644 index 0000000..974de86 --- /dev/null +++ b/Plugins/fs2vf.dll diff --git a/Plugins/fs2vf.exp b/Plugins/fs2vf.exp Binary files differnew file mode 100644 index 0000000..f3d5fba --- /dev/null +++ b/Plugins/fs2vf.exp diff --git a/Plugins/fs2vf.lib b/Plugins/fs2vf.lib Binary files differnew file mode 100644 index 0000000..038bb12 --- /dev/null +++ b/Plugins/fs2vf.lib diff --git a/Plugins/fs2vf.obj b/Plugins/fs2vf.obj Binary files differnew file mode 100644 index 0000000..4996274 --- /dev/null +++ b/Plugins/fs2vf.obj 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 Binary files differnew file mode 100644 index 0000000..dfd2fd6 --- /dev/null +++ b/Plugins/gol.dll diff --git a/Plugins/gol.exp b/Plugins/gol.exp Binary files differnew file mode 100644 index 0000000..2dcf523 --- /dev/null +++ b/Plugins/gol.exp diff --git a/Plugins/gol.lib b/Plugins/gol.lib Binary files differnew file mode 100644 index 0000000..c38fb4e --- /dev/null +++ b/Plugins/gol.lib diff --git a/Plugins/gol.obj b/Plugins/gol.obj Binary files differnew file mode 100644 index 0000000..e571ee0 --- /dev/null +++ b/Plugins/gol.obj 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 Binary files differnew file mode 100644 index 0000000..3dc1016 --- /dev/null +++ b/Plugins/green.dll diff --git a/Plugins/green.exp b/Plugins/green.exp Binary files differnew file mode 100644 index 0000000..bba3425 --- /dev/null +++ b/Plugins/green.exp diff --git a/Plugins/green.lib b/Plugins/green.lib Binary files differnew file mode 100644 index 0000000..f79b6b6 --- /dev/null +++ b/Plugins/green.lib diff --git a/Plugins/green.obj b/Plugins/green.obj Binary files differnew file mode 100644 index 0000000..d32d5ab --- /dev/null +++ b/Plugins/green.obj 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 Binary files differnew file mode 100644 index 0000000..7c0bc44 --- /dev/null +++ b/Plugins/hist.dll diff --git a/Plugins/hist.exp b/Plugins/hist.exp Binary files differnew file mode 100644 index 0000000..238ffc2 --- /dev/null +++ b/Plugins/hist.exp diff --git a/Plugins/hist.lib b/Plugins/hist.lib Binary files differnew file mode 100644 index 0000000..d8d0ddc --- /dev/null +++ b/Plugins/hist.lib diff --git a/Plugins/hist.obj b/Plugins/hist.obj Binary files differnew file mode 100644 index 0000000..760936d --- /dev/null +++ b/Plugins/hist.obj 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 Binary files differnew file mode 100644 index 0000000..5491ab8 --- /dev/null +++ b/Plugins/makesliders.dll diff --git a/Plugins/makesliders.exp b/Plugins/makesliders.exp Binary files differnew file mode 100644 index 0000000..307b3d6 --- /dev/null +++ b/Plugins/makesliders.exp diff --git a/Plugins/makesliders.lib b/Plugins/makesliders.lib Binary files differnew file mode 100644 index 0000000..40bd42c --- /dev/null +++ b/Plugins/makesliders.lib diff --git a/Plugins/makesliders.obj b/Plugins/makesliders.obj Binary files differnew file mode 100644 index 0000000..c7326db --- /dev/null +++ b/Plugins/makesliders.obj diff --git a/Plugins/ms.dll b/Plugins/ms.dll Binary files differnew file mode 100644 index 0000000..5491ab8 --- /dev/null +++ b/Plugins/ms.dll 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 Binary files differnew file mode 100644 index 0000000..b761095 --- /dev/null +++ b/Plugins/noize.dll diff --git a/Plugins/noize.exp b/Plugins/noize.exp Binary files differnew file mode 100644 index 0000000..489c203 --- /dev/null +++ b/Plugins/noize.exp diff --git a/Plugins/noize.lib b/Plugins/noize.lib Binary files differnew file mode 100644 index 0000000..cbdfba5 --- /dev/null +++ b/Plugins/noize.lib diff --git a/Plugins/noize.obj b/Plugins/noize.obj Binary files differnew file mode 100644 index 0000000..302298a --- /dev/null +++ b/Plugins/noize.obj 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 Binary files differnew file mode 100644 index 0000000..93cff6a --- /dev/null +++ b/Plugins/plot.dll diff --git a/Plugins/plot.exp b/Plugins/plot.exp Binary files differnew file mode 100644 index 0000000..1d5ce2f --- /dev/null +++ b/Plugins/plot.exp diff --git a/Plugins/plot.lib b/Plugins/plot.lib Binary files differnew file mode 100644 index 0000000..afdc085 --- /dev/null +++ b/Plugins/plot.lib diff --git a/Plugins/plot.obj b/Plugins/plot.obj Binary files differnew file mode 100644 index 0000000..c48c30f --- /dev/null +++ b/Plugins/plot.obj 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 Binary files differnew file mode 100644 index 0000000..ba7dfd2 --- /dev/null +++ b/Plugins/rgb.dll diff --git a/Plugins/rgb.exp b/Plugins/rgb.exp Binary files differnew file mode 100644 index 0000000..cc7feab --- /dev/null +++ b/Plugins/rgb.exp diff --git a/Plugins/rgb.lib b/Plugins/rgb.lib Binary files differnew file mode 100644 index 0000000..8e364a1 --- /dev/null +++ b/Plugins/rgb.lib diff --git a/Plugins/rgb.obj b/Plugins/rgb.obj Binary files differnew file mode 100644 index 0000000..69b7892 --- /dev/null +++ b/Plugins/rgb.obj 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 Binary files differnew file mode 100644 index 0000000..1a995d3 --- /dev/null +++ b/Plugins/rgbcopy.dll diff --git a/Plugins/rgbcopy.exp b/Plugins/rgbcopy.exp Binary files differnew file mode 100644 index 0000000..b85e71e --- /dev/null +++ b/Plugins/rgbcopy.exp diff --git a/Plugins/rgbcopy.lib b/Plugins/rgbcopy.lib Binary files differnew file mode 100644 index 0000000..09edbd5 --- /dev/null +++ b/Plugins/rgbcopy.lib diff --git a/Plugins/rgbcopy.obj b/Plugins/rgbcopy.obj Binary files differnew file mode 100644 index 0000000..5d7194c --- /dev/null +++ b/Plugins/rgbcopy.obj 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 Binary files differnew file mode 100644 index 0000000..9a772ab --- /dev/null +++ b/Plugins/setbits.dll diff --git a/Plugins/setbits.exp b/Plugins/setbits.exp Binary files differnew file mode 100644 index 0000000..484fe3b --- /dev/null +++ b/Plugins/setbits.exp diff --git a/Plugins/setbits.lib b/Plugins/setbits.lib Binary files differnew file mode 100644 index 0000000..1e1db08 --- /dev/null +++ b/Plugins/setbits.lib diff --git a/Plugins/setbits.obj b/Plugins/setbits.obj Binary files differnew file mode 100644 index 0000000..09a9196 --- /dev/null +++ b/Plugins/setbits.obj 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 Binary files differnew file mode 100644 index 0000000..bd5d552 --- /dev/null +++ b/Plugins/shuffle.dll diff --git a/Plugins/shuffle.exp b/Plugins/shuffle.exp Binary files differnew file mode 100644 index 0000000..2802b94 --- /dev/null +++ b/Plugins/shuffle.exp diff --git a/Plugins/shuffle.lib b/Plugins/shuffle.lib Binary files differnew file mode 100644 index 0000000..d1bc16f --- /dev/null +++ b/Plugins/shuffle.lib diff --git a/Plugins/shuffle.obj b/Plugins/shuffle.obj Binary files differnew file mode 100644 index 0000000..5c70ab2 --- /dev/null +++ b/Plugins/shuffle.obj 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 Binary files differnew file mode 100644 index 0000000..db6e132 --- /dev/null +++ b/Plugins/sonogram.dll diff --git a/Plugins/sonogram.exp b/Plugins/sonogram.exp Binary files differnew file mode 100644 index 0000000..40a6fae --- /dev/null +++ b/Plugins/sonogram.exp diff --git a/Plugins/sonogram.lib b/Plugins/sonogram.lib Binary files differnew file mode 100644 index 0000000..484c38d --- /dev/null +++ b/Plugins/sonogram.lib diff --git a/Plugins/sonogram.obj b/Plugins/sonogram.obj Binary files differnew file mode 100644 index 0000000..7dd6ee5 --- /dev/null +++ b/Plugins/sonogram.obj 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 Binary files differnew file mode 100644 index 0000000..883c541 --- /dev/null +++ b/Plugins/subtract.dll diff --git a/Plugins/subtract.exp b/Plugins/subtract.exp Binary files differnew file mode 100644 index 0000000..9a066ba --- /dev/null +++ b/Plugins/subtract.exp diff --git a/Plugins/subtract.lib b/Plugins/subtract.lib Binary files differnew file mode 100644 index 0000000..5132561 --- /dev/null +++ b/Plugins/subtract.lib diff --git a/Plugins/subtract.obj b/Plugins/subtract.obj Binary files differnew file mode 100644 index 0000000..8405ccc --- /dev/null +++ b/Plugins/subtract.obj 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 Binary files differnew file mode 100644 index 0000000..ee04f4c --- /dev/null +++ b/Plugins/swap.dll diff --git a/Plugins/swap.exp b/Plugins/swap.exp Binary files differnew file mode 100644 index 0000000..8015b40 --- /dev/null +++ b/Plugins/swap.exp diff --git a/Plugins/swap.lib b/Plugins/swap.lib Binary files differnew file mode 100644 index 0000000..bda1a31 --- /dev/null +++ b/Plugins/swap.lib diff --git a/Plugins/swap.obj b/Plugins/swap.obj Binary files differnew file mode 100644 index 0000000..cca03a8 --- /dev/null +++ b/Plugins/swap.obj 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 Binary files differnew file mode 100644 index 0000000..58a8886 --- /dev/null +++ b/Plugins/tile.dll diff --git a/Plugins/tile.exp b/Plugins/tile.exp Binary files differnew file mode 100644 index 0000000..69d5907 --- /dev/null +++ b/Plugins/tile.exp diff --git a/Plugins/tile.lib b/Plugins/tile.lib Binary files differnew file mode 100644 index 0000000..1f0732e --- /dev/null +++ b/Plugins/tile.lib diff --git a/Plugins/tile.obj b/Plugins/tile.obj Binary files differnew file mode 100644 index 0000000..8409075 --- /dev/null +++ b/Plugins/tile.obj 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 Binary files differnew file mode 100644 index 0000000..d51abad --- /dev/null +++ b/Plugins/vf2fs.dll diff --git a/Plugins/vf2fs.exp b/Plugins/vf2fs.exp Binary files differnew file mode 100644 index 0000000..c9ce25b --- /dev/null +++ b/Plugins/vf2fs.exp diff --git a/Plugins/vf2fs.lib b/Plugins/vf2fs.lib Binary files differnew file mode 100644 index 0000000..0c52583 --- /dev/null +++ b/Plugins/vf2fs.lib diff --git a/Plugins/vf2fs.obj b/Plugins/vf2fs.obj Binary files differnew file mode 100644 index 0000000..4c0a7bd --- /dev/null +++ b/Plugins/vf2fs.obj 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 Binary files differnew file mode 100644 index 0000000..fb6f033 --- /dev/null +++ b/Plugins/xbend.dll diff --git a/Plugins/xbend.exp b/Plugins/xbend.exp Binary files differnew file mode 100644 index 0000000..99b93f3 --- /dev/null +++ b/Plugins/xbend.exp diff --git a/Plugins/xbend.lib b/Plugins/xbend.lib Binary files differnew file mode 100644 index 0000000..b54972e --- /dev/null +++ b/Plugins/xbend.lib diff --git a/Plugins/xbend.obj b/Plugins/xbend.obj Binary files differnew file mode 100644 index 0000000..4854676 --- /dev/null +++ b/Plugins/xbend.obj 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 Binary files differnew file mode 100644 index 0000000..9ddf030 --- /dev/null +++ b/Plugins/xshred.dll diff --git a/Plugins/xshred.exp b/Plugins/xshred.exp Binary files differnew file mode 100644 index 0000000..881e90e --- /dev/null +++ b/Plugins/xshred.exp diff --git a/Plugins/xshred.lib b/Plugins/xshred.lib Binary files differnew file mode 100644 index 0000000..c90c4df --- /dev/null +++ b/Plugins/xshred.lib diff --git a/Plugins/xshred.obj b/Plugins/xshred.obj Binary files differnew file mode 100644 index 0000000..484ad30 --- /dev/null +++ b/Plugins/xshred.obj 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 Binary files differnew file mode 100644 index 0000000..ac17dd9 --- /dev/null +++ b/Reija/01.jpg diff --git a/Reija/02.jpg b/Reija/02.jpg Binary files differnew file mode 100644 index 0000000..681558a --- /dev/null +++ b/Reija/02.jpg diff --git a/Reija/03.jpg b/Reija/03.jpg Binary files differnew file mode 100644 index 0000000..55dc52b --- /dev/null +++ b/Reija/03.jpg diff --git a/Reija/04.jpg b/Reija/04.jpg Binary files differnew file mode 100644 index 0000000..d6f834a --- /dev/null +++ b/Reija/04.jpg diff --git a/Reija/05.jpg b/Reija/05.jpg Binary files differnew file mode 100644 index 0000000..2716db4 --- /dev/null +++ b/Reija/05.jpg diff --git a/Reija/06.jpg b/Reija/06.jpg Binary files differnew file mode 100644 index 0000000..c2c8480 --- /dev/null +++ b/Reija/06.jpg diff --git a/Reija/07.jpg b/Reija/07.jpg Binary files differnew file mode 100644 index 0000000..14e045c --- /dev/null +++ b/Reija/07.jpg diff --git a/Reija/08.jpg b/Reija/08.jpg Binary files differnew file mode 100644 index 0000000..77bde9c --- /dev/null +++ b/Reija/08.jpg 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 Binary files differnew file mode 100644 index 0000000..ee5ac49 --- /dev/null +++ b/Source/Framestein.res 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 Binary files differnew file mode 100644 index 0000000..11c1b7b --- /dev/null +++ b/extract.wav diff --git a/head.avi b/head.avi Binary files differnew file mode 100644 index 0000000..dcae3c1 --- /dev/null +++ b/head.avi diff --git a/ijl15.dll b/ijl15.dll Binary files differnew file mode 100644 index 0000000..0ea9873 --- /dev/null +++ b/ijl15.dll |