aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFathi Boudra <fathi.boudra@linaro.org>2013-03-30 17:38:14 +0200
committerFathi Boudra <fathi.boudra@linaro.org>2013-03-30 17:38:14 +0200
commit341f04dca0008c290cf065c4b36348fd80fe9700 (patch)
treeab372775bee83fd6c6500c75fd066315f725981d
Imported Upstream version 2012.12HEADupstream/2012.12upstreammaster
-rw-r--r--COPYING674
-rw-r--r--COPYING.SGI40
-rw-r--r--INSTALL13
-rw-r--r--INSTALL.android35
-rw-r--r--NEWS208
-rw-r--r--README24
-rw-r--r--README.android50
-rw-r--r--android/Android.mk14
-rw-r--r--android/AndroidManifest.xml54
-rw-r--r--android/CleanSpec.mk6
l---------android/assets1
-rw-r--r--android/build.xml92
-rw-r--r--android/jni/Android.mk76
-rw-r--r--android/jni/Android.ndk.mk65
-rw-r--r--android/jni/Application.mk3
l---------android/jni/src1
-rw-r--r--android/project.properties14
-rw-r--r--android/res/drawable/menu_about.pngbin0 -> 1983 bytes
-rw-r--r--android/res/drawable/menu_delete.pngbin0 -> 1413 bytes
-rw-r--r--android/res/drawable/menu_load.pngbin0 -> 1094 bytes
-rw-r--r--android/res/drawable/menu_results.pngbin0 -> 1369 bytes
-rw-r--r--android/res/drawable/menu_save.pngbin0 -> 1248 bytes
-rw-r--r--android/res/drawable/menu_settings.pngbin0 -> 1851 bytes
-rw-r--r--android/res/layout/activity_about.xml43
-rw-r--r--android/res/layout/activity_editor.xml34
-rw-r--r--android/res/layout/activity_main.xml20
-rw-r--r--android/res/layout/activity_results.xml15
-rw-r--r--android/res/layout/list_header.xml5
-rw-r--r--android/res/layout/list_item.xml32
-rw-r--r--android/res/layout/save_dialog.xml28
-rw-r--r--android/res/menu/main_options_menu.xml26
-rw-r--r--android/res/values/strings.xml46
-rw-r--r--android/res/xml/preferences.xml15
-rw-r--r--android/src/org/linaro/glmark2/AboutActivity.java52
-rw-r--r--android/src/org/linaro/glmark2/BenchmarkListManager.java189
-rw-r--r--android/src/org/linaro/glmark2/EditorActivity.java548
-rw-r--r--android/src/org/linaro/glmark2/GLVisualConfig.java46
-rw-r--r--android/src/org/linaro/glmark2/Glmark2Activity.java88
-rw-r--r--android/src/org/linaro/glmark2/Glmark2Native.java34
-rw-r--r--android/src/org/linaro/glmark2/Glmark2SurfaceView.java218
-rw-r--r--android/src/org/linaro/glmark2/MainActivity.java482
-rw-r--r--android/src/org/linaro/glmark2/MainPreferencesActivity.java33
-rw-r--r--android/src/org/linaro/glmark2/ResultsActivity.java58
-rw-r--r--android/src/org/linaro/glmark2/SceneInfo.java96
-rw-r--r--data/models/asteroid-high.3dsbin0 -> 672087 bytes
-rw-r--r--data/models/asteroid-low.3dsbin0 -> 10183 bytes
-rw-r--r--data/models/bunny.obj104501
-rw-r--r--data/models/cat.3dsbin0 -> 231714 bytes
-rw-r--r--data/models/cube.3dsbin0 -> 699 bytes
-rw-r--r--data/models/horse.3dsbin0 -> 143522 bytes
-rw-r--r--data/models/jellyfish.jobj24432
-rw-r--r--data/shaders/README.shaders5
-rw-r--r--data/shaders/buffer-wireframe.frag17
-rw-r--r--data/shaders/buffer-wireframe.vert57
-rw-r--r--data/shaders/bump-height.frag56
-rw-r--r--data/shaders/bump-height.vert28
-rw-r--r--data/shaders/bump-normals-tangent.frag49
-rw-r--r--data/shaders/bump-normals-tangent.vert39
-rw-r--r--data/shaders/bump-normals.frag44
-rw-r--r--data/shaders/bump-normals.vert14
-rw-r--r--data/shaders/bump-poly.frag33
-rw-r--r--data/shaders/bump-poly.vert16
-rw-r--r--data/shaders/conditionals-step-conditional.all4
-rw-r--r--data/shaders/conditionals-step-simple.all1
-rw-r--r--data/shaders/conditionals.frag11
-rw-r--r--data/shaders/conditionals.vert25
-rw-r--r--data/shaders/depth.frag6
-rw-r--r--data/shaders/depth.vert12
-rw-r--r--data/shaders/desktop-blur.frag13
-rw-r--r--data/shaders/desktop.frag10
-rw-r--r--data/shaders/desktop.vert11
-rw-r--r--data/shaders/effect-2d-convolution.frag12
-rw-r--r--data/shaders/effect-2d.vert10
-rw-r--r--data/shaders/function-call.all1
-rw-r--r--data/shaders/function-step-low.all1
-rw-r--r--data/shaders/function-step-medium.all2
-rw-r--r--data/shaders/function.frag16
-rw-r--r--data/shaders/function.vert30
-rw-r--r--data/shaders/gradient.frag10
-rw-r--r--data/shaders/gradient.vert10
-rw-r--r--data/shaders/ideas-lamp-lit.frag68
-rw-r--r--data/shaders/ideas-lamp-lit.vert28
-rw-r--r--data/shaders/ideas-lamp-unlit.frag6
-rw-r--r--data/shaders/ideas-lamp-unlit.vert11
-rw-r--r--data/shaders/ideas-logo-flat.frag6
-rw-r--r--data/shaders/ideas-logo-flat.vert9
-rw-r--r--data/shaders/ideas-logo-shadow.frag10
-rw-r--r--data/shaders/ideas-logo-shadow.vert9
-rw-r--r--data/shaders/ideas-logo.frag35
-rw-r--r--data/shaders/ideas-logo.vert28
-rw-r--r--data/shaders/ideas-paper.frag6
-rw-r--r--data/shaders/ideas-paper.vert22
-rw-r--r--data/shaders/ideas-table.frag6
-rw-r--r--data/shaders/ideas-table.vert22
-rw-r--r--data/shaders/ideas-text.frag6
-rw-r--r--data/shaders/ideas-text.vert18
-rw-r--r--data/shaders/ideas-under-table.frag6
-rw-r--r--data/shaders/ideas-under-table.vert11
-rw-r--r--data/shaders/jellyfish.frag21
-rw-r--r--data/shaders/jellyfish.vert56
-rw-r--r--data/shaders/light-advanced.frag33
-rw-r--r--data/shaders/light-advanced.vert16
-rw-r--r--data/shaders/light-basic-tex-bilinear.frag31
-rw-r--r--data/shaders/light-basic-tex.frag11
-rw-r--r--data/shaders/light-basic-texgen.vert30
-rw-r--r--data/shaders/light-basic.frag7
-rw-r--r--data/shaders/light-basic.vert29
-rw-r--r--data/shaders/light-phong.frag29
-rw-r--r--data/shaders/light-phong.vert23
-rw-r--r--data/shaders/light-refract.frag45
-rw-r--r--data/shaders/light-refract.vert28
-rw-r--r--data/shaders/loop-step-loop.all2
-rw-r--r--data/shaders/loop-step-simple.all1
-rw-r--r--data/shaders/loop.frag12
-rw-r--r--data/shaders/loop.vert26
-rw-r--r--data/shaders/pulsar-light.vert31
-rw-r--r--data/shaders/pulsar.vert19
-rw-r--r--data/shaders/shadow.frag17
-rw-r--r--data/shaders/shadow.vert16
-rw-r--r--data/shaders/terrain-blur.frag14
-rw-r--r--data/shaders/terrain-luminance.frag15
-rw-r--r--data/shaders/terrain-noise.frag124
-rw-r--r--data/shaders/terrain-normalmap.frag15
-rw-r--r--data/shaders/terrain-overlay.frag10
-rw-r--r--data/shaders/terrain-texture.vert18
-rw-r--r--data/shaders/terrain.frag112
-rw-r--r--data/shaders/terrain.vert48
-rw-r--r--data/shaders/text-renderer.frag10
-rw-r--r--data/shaders/text-renderer.vert10
-rw-r--r--data/textures/asteroid-height-map.pngbin0 -> 210524 bytes
-rw-r--r--data/textures/asteroid-normal-map-tangent.pngbin0 -> 453013 bytes
-rw-r--r--data/textures/asteroid-normal-map.pngbin0 -> 531099 bytes
-rw-r--r--data/textures/crate-base.pngbin0 -> 500819 bytes
-rw-r--r--data/textures/desktop-shadow-corner.pngbin0 -> 1200 bytes
-rw-r--r--data/textures/desktop-shadow.pngbin0 -> 259 bytes
-rw-r--r--data/textures/desktop-window.pngbin0 -> 45536 bytes
-rw-r--r--data/textures/effect-2d.pngbin0 -> 15354 bytes
-rw-r--r--data/textures/glyph-atlas.pngbin0 -> 27829 bytes
-rw-r--r--data/textures/jellyfish-caustics-01.pngbin0 -> 47113 bytes
-rw-r--r--data/textures/jellyfish-caustics-02.pngbin0 -> 47495 bytes
-rw-r--r--data/textures/jellyfish-caustics-03.pngbin0 -> 47491 bytes
-rw-r--r--data/textures/jellyfish-caustics-04.pngbin0 -> 47595 bytes
-rw-r--r--data/textures/jellyfish-caustics-05.pngbin0 -> 47630 bytes
-rw-r--r--data/textures/jellyfish-caustics-06.pngbin0 -> 47480 bytes
-rw-r--r--data/textures/jellyfish-caustics-07.pngbin0 -> 47113 bytes
-rw-r--r--data/textures/jellyfish-caustics-08.pngbin0 -> 47496 bytes
-rw-r--r--data/textures/jellyfish-caustics-09.pngbin0 -> 47323 bytes
-rw-r--r--data/textures/jellyfish-caustics-10.pngbin0 -> 47593 bytes
-rw-r--r--data/textures/jellyfish-caustics-11.pngbin0 -> 47184 bytes
-rw-r--r--data/textures/jellyfish-caustics-12.pngbin0 -> 47485 bytes
-rw-r--r--data/textures/jellyfish-caustics-13.pngbin0 -> 47249 bytes
-rw-r--r--data/textures/jellyfish-caustics-14.pngbin0 -> 47546 bytes
-rw-r--r--data/textures/jellyfish-caustics-15.pngbin0 -> 47426 bytes
-rw-r--r--data/textures/jellyfish-caustics-16.pngbin0 -> 47710 bytes
-rw-r--r--data/textures/jellyfish-caustics-17.pngbin0 -> 47378 bytes
-rw-r--r--data/textures/jellyfish-caustics-18.pngbin0 -> 47731 bytes
-rw-r--r--data/textures/jellyfish-caustics-19.pngbin0 -> 47619 bytes
-rw-r--r--data/textures/jellyfish-caustics-20.pngbin0 -> 47470 bytes
-rw-r--r--data/textures/jellyfish-caustics-21.pngbin0 -> 47768 bytes
-rw-r--r--data/textures/jellyfish-caustics-22.pngbin0 -> 47256 bytes
-rw-r--r--data/textures/jellyfish-caustics-23.pngbin0 -> 47139 bytes
-rw-r--r--data/textures/jellyfish-caustics-24.pngbin0 -> 47310 bytes
-rw-r--r--data/textures/jellyfish-caustics-25.pngbin0 -> 47605 bytes
-rw-r--r--data/textures/jellyfish-caustics-26.pngbin0 -> 47689 bytes
-rw-r--r--data/textures/jellyfish-caustics-27.pngbin0 -> 46790 bytes
-rw-r--r--data/textures/jellyfish-caustics-28.pngbin0 -> 47518 bytes
-rw-r--r--data/textures/jellyfish-caustics-29.pngbin0 -> 47425 bytes
-rw-r--r--data/textures/jellyfish-caustics-30.pngbin0 -> 47381 bytes
-rw-r--r--data/textures/jellyfish-caustics-31.pngbin0 -> 47188 bytes
-rw-r--r--data/textures/jellyfish-caustics-32.pngbin0 -> 47416 bytes
-rw-r--r--data/textures/jellyfish256.pngbin0 -> 154259 bytes
-rw-r--r--data/textures/nasa1.pngbin0 -> 418040 bytes
-rw-r--r--data/textures/nasa2.pngbin0 -> 425190 bytes
-rw-r--r--data/textures/nasa3.pngbin0 -> 615684 bytes
-rw-r--r--data/textures/terrain-backgrounddetailed6.jpgbin0 -> 79044 bytes
-rw-r--r--data/textures/terrain-grasslight-512-nm.jpgbin0 -> 146828 bytes
-rw-r--r--data/textures/terrain-grasslight-512.jpgbin0 -> 137557 bytes
-rw-r--r--data/wscript_build8
-rw-r--r--debian/bzr-builder.manifest3
-rw-r--r--debian/changelog158
-rw-r--r--debian/compat1
-rw-r--r--debian/control45
-rw-r--r--debian/copyright102
-rw-r--r--debian/glmark2-data.install1
-rw-r--r--debian/glmark2-es2.install1
-rw-r--r--debian/glmark2-es2.manpages1
-rw-r--r--debian/glmark2.install1
-rw-r--r--debian/glmark2.manpages1
-rwxr-xr-xdebian/rules27
-rw-r--r--debian/source/format1
-rw-r--r--debian/watch2
-rw-r--r--doc/glmark2.1.in115
-rw-r--r--doc/wscript_build21
-rw-r--r--src/android.cpp532
-rw-r--r--src/benchmark-collection.cpp119
-rw-r--r--src/benchmark-collection.h59
-rw-r--r--src/benchmark.cpp161
-rw-r--r--src/benchmark.h126
-rw-r--r--src/canvas-android.cpp191
-rw-r--r--src/canvas-android.h57
-rw-r--r--src/canvas-drm.cpp587
-rw-r--r--src/canvas-drm.h132
-rw-r--r--src/canvas-x11-egl.cpp117
-rw-r--r--src/canvas-x11-egl.h52
-rw-r--r--src/canvas-x11-glx.cpp308
-rw-r--r--src/canvas-x11-glx.h65
-rw-r--r--src/canvas-x11.cpp526
-rw-r--r--src/canvas-x11.h141
-rw-r--r--src/canvas.h261
-rw-r--r--src/default-benchmarks.h79
-rw-r--r--src/egl-state.cpp578
-rw-r--r--src/egl-state.h151
-rw-r--r--src/gl-headers.cpp46
-rw-r--r--src/gl-headers.h71
-rw-r--r--src/gl-visual-config.cpp123
-rw-r--r--src/gl-visual-config.h65
-rw-r--r--src/image-reader.cpp386
-rw-r--r--src/image-reader.h77
-rw-r--r--src/libjpeg-turbo/README290
-rwxr-xr-xsrc/libjpeg-turbo/README-turbo.txt361
-rw-r--r--src/libjpeg-turbo/config.h137
-rw-r--r--src/libjpeg-turbo/jaricom.c153
-rw-r--r--src/libjpeg-turbo/jcapimin.c292
-rw-r--r--src/libjpeg-turbo/jcapistd.c161
-rw-r--r--src/libjpeg-turbo/jcarith.c925
-rw-r--r--src/libjpeg-turbo/jccoefct.c449
-rw-r--r--src/libjpeg-turbo/jccolext.c.inc114
-rw-r--r--src/libjpeg-turbo/jccolor.c599
-rw-r--r--src/libjpeg-turbo/jcdctmgr.c642
-rw-r--r--src/libjpeg-turbo/jchuff.c1026
-rw-r--r--src/libjpeg-turbo/jchuff.h47
-rw-r--r--src/libjpeg-turbo/jcinit.c76
-rw-r--r--src/libjpeg-turbo/jcmainct.c293
-rw-r--r--src/libjpeg-turbo/jcmarker.c666
-rw-r--r--src/libjpeg-turbo/jcmaster.c624
-rw-r--r--src/libjpeg-turbo/jcomapi.c106
-rw-r--r--src/libjpeg-turbo/jconfig.h58
-rw-r--r--src/libjpeg-turbo/jcparam.c649
-rw-r--r--src/libjpeg-turbo/jcphuff.c831
-rw-r--r--src/libjpeg-turbo/jcprepct.c354
-rw-r--r--src/libjpeg-turbo/jcsample.c527
-rw-r--r--src/libjpeg-turbo/jctrans.c399
-rw-r--r--src/libjpeg-turbo/jdapimin.c395
-rw-r--r--src/libjpeg-turbo/jdapistd.c277
-rw-r--r--src/libjpeg-turbo/jdarith.c761
-rw-r--r--src/libjpeg-turbo/jdatadst-tj.c188
-rw-r--r--src/libjpeg-turbo/jdatasrc-tj.c182
-rw-r--r--src/libjpeg-turbo/jdcoefct.c749
-rw-r--r--src/libjpeg-turbo/jdcolext.c.inc104
-rw-r--r--src/libjpeg-turbo/jdcolor.c529
-rw-r--r--src/libjpeg-turbo/jdct.h184
-rw-r--r--src/libjpeg-turbo/jddctmgr.c288
-rw-r--r--src/libjpeg-turbo/jdhuff.c808
-rw-r--r--src/libjpeg-turbo/jdhuff.h234
-rw-r--r--src/libjpeg-turbo/jdinput.c471
-rw-r--r--src/libjpeg-turbo/jdmainct.c514
-rw-r--r--src/libjpeg-turbo/jdmarker.c1364
-rw-r--r--src/libjpeg-turbo/jdmaster.c601
-rw-r--r--src/libjpeg-turbo/jdmerge.c455
-rw-r--r--src/libjpeg-turbo/jdmrgext.c.inc156
-rw-r--r--src/libjpeg-turbo/jdphuff.c668
-rw-r--r--src/libjpeg-turbo/jdpostct.c290
-rw-r--r--src/libjpeg-turbo/jdsample.c496
-rw-r--r--src/libjpeg-turbo/jdtrans.c152
-rw-r--r--src/libjpeg-turbo/jerror.c252
-rw-r--r--src/libjpeg-turbo/jerror.h314
-rw-r--r--src/libjpeg-turbo/jfdctflt.c168
-rw-r--r--src/libjpeg-turbo/jfdctfst.c224
-rw-r--r--src/libjpeg-turbo/jfdctint.c283
-rw-r--r--src/libjpeg-turbo/jidctflt.c242
-rw-r--r--src/libjpeg-turbo/jidctfst.c368
-rw-r--r--src/libjpeg-turbo/jidctint.c389
-rw-r--r--src/libjpeg-turbo/jidctred.c398
-rw-r--r--src/libjpeg-turbo/jinclude.h91
-rw-r--r--src/libjpeg-turbo/jmemmgr.c1151
-rw-r--r--src/libjpeg-turbo/jmemnobs.c109
-rw-r--r--src/libjpeg-turbo/jmemsys.h198
-rw-r--r--src/libjpeg-turbo/jmorecfg.h404
-rw-r--r--src/libjpeg-turbo/jpegcomp.h26
-rw-r--r--src/libjpeg-turbo/jpegint.h401
-rw-r--r--src/libjpeg-turbo/jpeglib.h1213
-rw-r--r--src/libjpeg-turbo/jquant1.c860
-rw-r--r--src/libjpeg-turbo/jquant2.c1293
-rw-r--r--src/libjpeg-turbo/jsimd.h98
-rw-r--r--src/libjpeg-turbo/jsimddct.h102
-rw-r--r--src/libjpeg-turbo/jutils.c179
-rw-r--r--src/libjpeg-turbo/jversion.h31
-rw-r--r--src/libjpeg-turbo/simd/jsimd.h666
-rw-r--r--src/libjpeg-turbo/simd/jsimd_arm.c670
-rw-r--r--src/libjpeg-turbo/simd/jsimd_arm_neon.S2159
-rw-r--r--src/libmatrix/COPYING21
-rw-r--r--src/libmatrix/Makefile42
-rw-r--r--src/libmatrix/README11
-rw-r--r--src/libmatrix/gl-if.h18
-rw-r--r--src/libmatrix/log.cc173
-rw-r--r--src/libmatrix/log.h51
-rw-r--r--src/libmatrix/mat.cc173
-rw-r--r--src/libmatrix/mat.h1221
-rw-r--r--src/libmatrix/program.cc360
-rw-r--r--src/libmatrix/program.h165
-rw-r--r--src/libmatrix/shader-source.cc615
-rw-r--r--src/libmatrix/shader-source.h103
-rw-r--r--src/libmatrix/stack.h106
-rw-r--r--src/libmatrix/test/basic-global-const.vert15
-rw-r--r--src/libmatrix/test/basic.frag7
-rw-r--r--src/libmatrix/test/basic.vert14
-rw-r--r--src/libmatrix/test/const_vec_test.cc60
-rw-r--r--src/libmatrix/test/const_vec_test.h39
-rw-r--r--src/libmatrix/test/inverse_test.cc172
-rw-r--r--src/libmatrix/test/inverse_test.h39
-rw-r--r--src/libmatrix/test/libmatrix_test.cc72
-rw-r--r--src/libmatrix/test/libmatrix_test.h51
-rw-r--r--src/libmatrix/test/options.cc76
-rw-r--r--src/libmatrix/test/shader_source_test.cc49
-rw-r--r--src/libmatrix/test/shader_source_test.h32
-rw-r--r--src/libmatrix/test/transpose_test.cc297
-rw-r--r--src/libmatrix/test/transpose_test.h38
-rw-r--r--src/libmatrix/test/util_split_test.cc180
-rw-r--r--src/libmatrix/test/util_split_test.h31
-rw-r--r--src/libmatrix/util.cc343
-rw-r--r--src/libmatrix/util.h142
-rw-r--r--src/libmatrix/vec.h716
-rw-r--r--src/libpng/ANNOUNCE65
-rw-r--r--src/libpng/CMakeLists.txt284
-rw-r--r--src/libpng/INSTALL143
-rw-r--r--src/libpng/KNOWNBUG22
-rw-r--r--src/libpng/LICENSE111
-rw-r--r--src/libpng/README275
-rw-r--r--src/libpng/TODO25
-rw-r--r--src/libpng/Y2KINFO55
-rw-r--r--src/libpng/png.c1100
-rw-r--r--src/libpng/png.h3796
-rw-r--r--src/libpng/pngconf.h1665
-rw-r--r--src/libpng/pngerror.c396
-rw-r--r--src/libpng/pnggccrd.c103
-rw-r--r--src/libpng/pngget.c944
-rw-r--r--src/libpng/pngmem.c641
-rw-r--r--src/libpng/pngpread.c1774
-rw-r--r--src/libpng/pngread.c1528
-rw-r--r--src/libpng/pngrio.c180
-rw-r--r--src/libpng/pngrtran.c4467
-rw-r--r--src/libpng/pngrutil.c3390
-rw-r--r--src/libpng/pngset.c1226
-rw-r--r--src/libpng/pngtrans.c699
-rw-r--r--src/libpng/pngvcrd.c1
-rw-r--r--src/libpng/pngwio.c260
-rw-r--r--src/libpng/pngwrite.c1593
-rw-r--r--src/libpng/pngwtran.c582
-rw-r--r--src/libpng/pngwutil.c2832
-rw-r--r--src/main-loop.cpp333
-rw-r--r--src/main-loop.h141
-rw-r--r--src/main.cpp228
-rw-r--r--src/mesh.cpp639
-rw-r--r--src/mesh.h117
-rw-r--r--src/model.cpp807
-rw-r--r--src/model.h131
-rw-r--r--src/options.cpp201
-rw-r--r--src/options.h59
-rw-r--r--src/scene-buffer.cpp472
-rw-r--r--src/scene-build.cpp268
-rw-r--r--src/scene-bump.cpp414
-rw-r--r--src/scene-conditionals.cpp156
-rw-r--r--src/scene-default-options.cpp62
-rw-r--r--src/scene-desktop.cpp1017
-rw-r--r--src/scene-effect-2d.cpp444
-rw-r--r--src/scene-function.cpp182
-rw-r--r--src/scene-grid.cpp126
-rw-r--r--src/scene-ideas.cpp414
-rw-r--r--src/scene-ideas/a.cc179
-rw-r--r--src/scene-ideas/characters.h157
-rw-r--r--src/scene-ideas/d.cc142
-rw-r--r--src/scene-ideas/e.cc139
-rw-r--r--src/scene-ideas/i.cc116
-rw-r--r--src/scene-ideas/lamp.cc258
-rw-r--r--src/scene-ideas/lamp.h64
-rw-r--r--src/scene-ideas/logo.cc788
-rw-r--r--src/scene-ideas/logo.h126
-rw-r--r--src/scene-ideas/m.cc210
-rw-r--r--src/scene-ideas/n.cc146
-rw-r--r--src/scene-ideas/o.cc139
-rw-r--r--src/scene-ideas/s.cc130
-rw-r--r--src/scene-ideas/splines.cc200
-rw-r--r--src/scene-ideas/splines.h83
-rw-r--r--src/scene-ideas/t.cc147
-rw-r--r--src/scene-ideas/table.cc353
-rw-r--r--src/scene-ideas/table.h94
-rw-r--r--src/scene-jellyfish.cpp631
-rw-r--r--src/scene-jellyfish.h124
-rw-r--r--src/scene-loop.cpp179
-rw-r--r--src/scene-pulsar.cpp331
-rw-r--r--src/scene-refract.cpp469
-rw-r--r--src/scene-refract.h106
-rw-r--r--src/scene-shading.cpp346
-rw-r--r--src/scene-shadow.cpp546
-rw-r--r--src/scene-terrain.cpp362
-rw-r--r--src/scene-terrain/base-renderer.cpp144
-rw-r--r--src/scene-terrain/blur-renderer.cpp161
-rw-r--r--src/scene-terrain/copy-renderer.cpp55
-rw-r--r--src/scene-terrain/luminance-renderer.cpp57
-rw-r--r--src/scene-terrain/normal-from-height-renderer.cpp59
-rw-r--r--src/scene-terrain/overlay-renderer.cpp122
-rw-r--r--src/scene-terrain/renderer-chain.cpp115
-rw-r--r--src/scene-terrain/renderer.h348
-rw-r--r--src/scene-terrain/simplex-noise-renderer.cpp56
-rw-r--r--src/scene-terrain/terrain-renderer.cpp246
-rw-r--r--src/scene-terrain/texture-renderer.cpp69
-rw-r--r--src/scene-texture.cpp346
-rw-r--r--src/scene.cpp288
-rw-r--r--src/scene.h592
-rw-r--r--src/text-renderer.cpp292
-rw-r--r--src/text-renderer.h60
-rw-r--r--src/texture.cpp212
-rw-r--r--src/texture.h87
-rw-r--r--src/wscript_build92
-rwxr-xr-xwaf162
-rw-r--r--waflib/Build.py731
-rw-r--r--waflib/ConfigSet.py151
-rw-r--r--waflib/Configure.py315
-rw-r--r--waflib/Context.py299
-rw-r--r--waflib/Errors.py37
-rw-r--r--waflib/Logs.py149
-rw-r--r--waflib/Node.py506
-rw-r--r--waflib/Options.py134
-rw-r--r--waflib/Runner.py197
-rw-r--r--waflib/Scripting.py367
-rw-r--r--waflib/Task.py672
-rw-r--r--waflib/TaskGen.py353
-rw-r--r--waflib/Tools/__init__.py4
-rw-r--r--waflib/Tools/ar.py12
-rw-r--r--waflib/Tools/asm.py25
-rw-r--r--waflib/Tools/bison.py29
-rw-r--r--waflib/Tools/c.py27
-rw-r--r--waflib/Tools/c_aliases.py56
-rw-r--r--waflib/Tools/c_config.py713
-rw-r--r--waflib/Tools/c_osx.py121
-rw-r--r--waflib/Tools/c_preproc.py606
-rw-r--r--waflib/Tools/c_tests.py146
-rw-r--r--waflib/Tools/ccroot.py375
-rw-r--r--waflib/Tools/compiler_c.py39
-rw-r--r--waflib/Tools/compiler_cxx.py39
-rw-r--r--waflib/Tools/compiler_d.py30
-rw-r--r--waflib/Tools/compiler_fc.py43
-rw-r--r--waflib/Tools/cs.py98
-rw-r--r--waflib/Tools/cxx.py27
-rw-r--r--waflib/Tools/d.py56
-rw-r--r--waflib/Tools/d_config.py47
-rw-r--r--waflib/Tools/d_scan.py133
-rw-r--r--waflib/Tools/dbus.py30
-rw-r--r--waflib/Tools/dmd.py47
-rw-r--r--waflib/Tools/errcheck.py161
-rw-r--r--waflib/Tools/fc.py123
-rw-r--r--waflib/Tools/fc_config.py283
-rw-r--r--waflib/Tools/fc_scan.py68
-rw-r--r--waflib/Tools/flex.py27
-rw-r--r--waflib/Tools/g95.py55
-rw-r--r--waflib/Tools/gas.py11
-rw-r--r--waflib/Tools/gcc.py98
-rw-r--r--waflib/Tools/gdc.py34
-rw-r--r--waflib/Tools/gfortran.py69
-rw-r--r--waflib/Tools/glib2.py174
-rw-r--r--waflib/Tools/gnu_dirs.py65
-rw-r--r--waflib/Tools/gxx.py98
-rw-r--r--waflib/Tools/icc.py31
-rw-r--r--waflib/Tools/icpc.py30
-rw-r--r--waflib/Tools/ifort.py49
-rw-r--r--waflib/Tools/intltool.py78
-rw-r--r--waflib/Tools/irixcc.py49
-rw-r--r--waflib/Tools/javaw.py275
-rw-r--r--waflib/Tools/kde4.py49
-rw-r--r--waflib/Tools/lua.py19
-rw-r--r--waflib/Tools/msvc.py654
-rw-r--r--waflib/Tools/nasm.py14
-rw-r--r--waflib/Tools/perl.py81
-rw-r--r--waflib/Tools/python.py336
-rw-r--r--waflib/Tools/qt4.py434
-rw-r--r--waflib/Tools/ruby.py104
-rw-r--r--waflib/Tools/suncc.py54
-rw-r--r--waflib/Tools/suncxx.py55
-rw-r--r--waflib/Tools/tex.py242
-rw-r--r--waflib/Tools/vala.py216
-rw-r--r--waflib/Tools/waf_unit_test.py79
-rw-r--r--waflib/Tools/winres.py34
-rw-r--r--waflib/Tools/xlc.py46
-rw-r--r--waflib/Tools/xlcxx.py46
-rw-r--r--waflib/Utils.py336
-rw-r--r--waflib/__init__.py4
-rw-r--r--waflib/ansiterm.py177
-rw-r--r--waflib/extras/__init__.py4
-rw-r--r--waflib/extras/compat15.py223
-rw-r--r--waflib/fixpy2.py50
-rw-r--r--wscript172
491 files changed, 233301 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. 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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. 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.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ 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
+state 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 3 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, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program 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, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU 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 Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/COPYING.SGI b/COPYING.SGI
new file mode 100644
index 0000000..94ab8db
--- /dev/null
+++ b/COPYING.SGI
@@ -0,0 +1,40 @@
+The data and some of the control logic for the "ideas" scene was adapted from
+the "Ideas in Motion" GLUT demo. Per the rights granted by the source for that
+demo, the following notice is reproduced here:
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States. Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..4f65d23
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,13 @@
+glmark2 uses the WAF build system.
+
+To configure glmark2 use:
+
+$ ./waf configure [--enable-gl --enable-glesv2 --enable-gl-drm --enable-glesv2-drm --data-path=DATA_PATH --prefix=PREFIX]
+
+To build use:
+
+$ ./waf
+
+To install use:
+
+$ ./waf install --destdir=DESTDIR
diff --git a/INSTALL.android b/INSTALL.android
new file mode 100644
index 0000000..c4ca070
--- /dev/null
+++ b/INSTALL.android
@@ -0,0 +1,35 @@
+The minimum Android API level for glmark2 is 9 (>= Android 2.3).
+
+Building using the SDK and NDK
+------------------------------
+
+To build and install glmark2 you need the Android SDK and NDK. The 'android',
+'adb' and 'ndk-build' tools used below are included there.
+
+To build glmark2 for Android we start by building the native part:
+
+$ cd android
+$ ndk-build
+
+To continue building the package from the command line:
+
+$ android update project -p . -s
+$ ant debug {or release}
+
+To install to a device, you need to have set up an ADB connection
+to the device. Then do:
+
+$ adb install bin/Glmark2Activity-debug.apk
+
+Alternatively you can load the project (in the android/ directory) in Eclipse
+using the ADT plugin and manage the build and install process from there. Keep
+in mind that when updating the native build (ndk-build etc) you need to refresh
+the Eclipse project, otherwise it won't notice that something has changed.
+
+Building using the Android build system
+---------------------------------------
+
+Copy the glmark2 source tree to somewhere the Android build system can access
+it (eg external/glmark2) and build the GLMark2 module:
+
+$ make GLMark2
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..9fcd54e
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,208 @@
+glmark2 2012.12 (20121218)
+==========================
+
+* Add a refraction (2 interface) and reflection benchmark (scene 'reflect').
+* Add a new canvas object which allows rendering to GBM managed surfaces
+ and page flipping to DRM managed framebuffer from a console.
+* Enhancements to visual config mechanism to consider stencil size in the
+ selection criteria and to query all config attribs.
+
+glmark2 2012.11 (20121126)
+==========================
+
+* Add a shadow mapping benchmark (scene 'shadow').
+* Consolidate EGL interactions into a separate state object.
+
+glmark2 2012.08 (20120817)
+==========================
+
+* Display benchmark results in the Android GUI.
+* Add an Android option menu offering load/save/delete benchmark list
+ functionality, access to last benchmark results, settings and
+ information about glmark2.
+* Properly handle spaces in scene options on Android.
+* Exclude from score calculation benchmarks whose set up wasn't successful.
+* Display an appropriate message (instead of a 0 FPS value) if benchmark
+ set up isn't successful.
+* Add support for standard GNU installation directories.
+
+glmark2 2012.07 (20120719)
+==========================
+
+* Add Android GUI for defining and running benchmarks.
+* Add benchmark based on the WebGL jellyfish demo (scene 'jellyfish').
+* Add benchmark based on the WebGL dynamic terrain demo (scene 'terrain').
+* Extend texture scene with the option to compute texture coordinates
+ in the shader (option 'texgen').
+* Add support for reading texture data from JPEG files.
+* Properly support options that have a finite set of acceptable values.
+
+glmark2 2012.06 (20120621)
+==========================
+
+* Add command-line option to render in fullscreen mode (--fullscreen).
+* Display the frame time in addition to the FPS for each benchmark.
+
+glmark2 2012.05 (20120524)
+==========================
+
+* Add benchmark based on the SGI "Ideas in Motion" demo.
+* Ensure that the framebuffer is drawn opaquely.
+* Add command-line option to configure the visual used for rendering
+ (--visual-config).
+* Add support for additional models and textures in the 'texture' scene.
+
+glmark2 2012.03 (20120322)
+==========================
+
+* X11:
+ - Support rendering to an off-screen surface (--off-screen).
+ - Add command-line option to select which method to use to "end"
+ a frame (--frame-end).
+
+glmark2 2012.02 (20120216)
+==========================
+
+* Consolidate X11 and Android main loops.
+* Accept command-line options on Android through either a file
+ ('/data/glmark2/args') or an extra intent key ('args').
+* Support per-scene options for displaying an FPS count on screen
+ (show-fps, fps-pos, fps-size), and remove --show-fps command-line option.
+* Support per-scene options for displaying a benchmark title on screen
+ (title, title-pos, title-size).
+* Add command-line option to run benchmarks indefinitely (--run-forever).
+* Add command-line option to annotate the benchmarks with on-screen
+ information (--annotate == -b :show-fps=true:title=#info#).
+* Move various utility classes to libmatrix.
+* Fix build issues on Android ICS.
+
+glmark2 2012.01 (20120119)
+==========================
+
+* X11:
+ - Run each benchmark in a fresh GL context. Use --reuse-context
+ to revert to the old default behavior of using the same context
+ for all benchmarks.
+ - Add option for showing a live FPS counter on screen (--show-fps).
+ - If the list of benchmarks to run contains only option-setting
+ descriptions, run the default benchmarks.
+* Android:
+ - Fix crash on platforms not supporting glMapBufferOES.
+ - Log the glmark2 score when finishing.
+ - Log an error message if we fail to find a suitable EGLContext.
+ - Implement various stability improvements.
+
+glmark2 2011.12 (20111215)
+==========================
+
+* Add benchmark for bilinear filtering implemented in the fragment
+ shader (not included in the default benchmarks).
+* Ensure we don't call any GL functions before binding a GL context.
+* Fix bug in the ShaderSource object that could lead to shader
+ compilation errors in strict OpenGL ES 2.0 implementations.
+* Refactor scene update code to reduce duplication.
+
+glmark2 2011.11 (20111116)
+==========================
+
+* Add benchmark for bump mapping using a height map.
+* Add benchmark for bump mapping using a tangent space normal map
+ (not included in the default benchmarks).
+* Implement validation support for all default benchmarks.
+* Add a colored prefix to log messages in debug mode.
+* Clean up and refactor code.
+
+glmark2 2011.10 (20111018)
+==========================
+
+* Add benchmark for buffer (VBO) updates.
+* Add benchmark for drop-shadow desktop effect.
+* Add support for glmark2 extra large models.
+* Enable the selection of additional models in the shading benchmark.
+* Gracefully handle unsupported OpenGL versions, on both X11 and Android.
+* Disable screen dimming and screen rotation on Android.
+
+glmark2 2011.09 (20110921)
+==========================
+
+* Add benchmark for blur desktop effect.
+* Add support for multiple lights in the phong shading benchmark.
+* Add support for loading models from OBJ geometry files.
+* Add Stanford Bunny model and make it available in the build benchmark.
+* Add per-scene options to set shader precision at runtime.
+* Add command-line option to specify the benchmarks to run using a text file.
+
+glmark2 2011.08 (20110818)
+==========================
+
+* Port to Android (see INSTALL.android).
+* Add benchmark based on pulsar X11 GL screensaver.
+* Add benchmark for 2D image processing using the GPU.
+* Add command line option to set the size of the output window (-s, --size).
+* Implement ShaderSource object to simplify complex shader creation.
+* Implement utility functions to access resources in an abstract way.
+
+glmark2 2011.07 (20110719)
+==========================
+
+* Replace SDL with custom window handling code.
+* Add benchmark for shader conditionals.
+* Add benchmark for shader function calls.
+* Add benchmark for shader loops.
+* Add benchmark for real phong (vs blinn-phong) lighting model.
+* Add benchmark for normal mapping.
+* Refactor Mesh class to increase flexibility in vertex attribute
+ handling.
+
+glmark2 2011.06 (20110624)
+==========================
+
+* Improve benchmark versatility by allowing runtime-configurable,
+ per-scene options.
+* Add command line option to list avalaible scenes and their
+ supported options (-l,--list-scenes).
+* Allow specifying the scenes to run and their options from the
+ command line (-b,--benchmark).
+* Add basic output validation functionality (--validate).
+* Add command line option to call glFinish() instead of swapping
+ the front and back buffers (--no-swap-buffers).
+* Manually disable VSync for GL/GLX (work around an SDL bug).
+* Replace custom math and shader infrastructure with functionality
+ provided by LibMatrix (lp:libmatrix).
+* Improve user documentation (--help and man page).
+
+glmark2 11.05 (20110530)
+==========================
+
+* Don't use the SDL_OPENGL flag for GLESv2 (LP: #761848).
+* Ensure our screen updates are not synchronized with the vertical
+ retrace (LP: 761855).
+* Use the correct GL headers depending on the flavor (desktop vs ES2).
+* Query the correct GL object for shader linking status.
+
+glmark2 11.01 (20110125)
+==========================
+
+* Fix visual corruption in glmark2-es2 due to missing depth buffer.
+* Fix linking issues with gcc 4.5.
+* Use correct GL functions to manipulate shaders vs programs.
+* Make result reporting more parser-friendly.
+* Upgrade build system to waf 1.6.2.
+
+glmark2 10.07.1 (20100728)
+==========================
+
+* Define the precision of fragment shader variables for OpenGL ES 2.0.
+
+glmark2 10.07 (20100715)
+========================
+
+* First release.
+* Included benchmarks:
+ - Rendering using vertex arrays
+ - Rendering using VBOs
+ - Texturing using nearest filtering
+ - Texturing using linear filtering
+ - Texturing using trilinear mipmapped filtering
+ - Lighting per vertex using simple GLSL shaders
+ - Lighting per pixel using elaborate GLSL shaders
diff --git a/README b/README
new file mode 100644
index 0000000..e9b340a
--- /dev/null
+++ b/README
@@ -0,0 +1,24 @@
+glmark2 is an OpenGL 2.0 and ES 2.0 benchmark.
+
+glmark2 was developed by Alexandros Frantzis based on the original glmark
+benchmark by Ben Smith.
+
+It is licensed under the GPLv3 (see COPYING).
+
+To build glmark2 for X11/GL(ES2) you need:
+
+ * python 2.x (>= 2.4) for the build system (waf)
+ * libpng 1.2
+
+and for OpenGL 2.0:
+
+ * libGL
+
+or for OpenGL ES 2.0:
+
+ * libEGL
+ * libGLESv2
+
+Read the INSTALL file for building/installation instructions,
+
+Read the INSTALL.android file for instructions for Android.
diff --git a/README.android b/README.android
new file mode 100644
index 0000000..7c372f9
--- /dev/null
+++ b/README.android
@@ -0,0 +1,50 @@
+Command-line arguments
+======================
+
+The Android version of glmark2 can accept command-line arguments from either
+an extra intent key or a file. If arguments are specified in an intent key, the
+file is disregarded.
+
+Arguments from an extra intent key
+----------------------------------
+
+The 'args' extra intent key is used to specify arguments. For example:
+
+am start -a android.intent.action.MAIN \
+ -n org.linaro.glmark2/org.linaro.glmark2.Glmark2Activity \
+ -e args '-b :duration=2 -b texture -f /path/file --debug'
+
+Arguments from a file
+---------------------
+
+If the 'args' intent key is not defined, the contents of the file
+'/data/glmark2/args' (if present) are used as command line arguments. The
+arguments can be placed in either a single or multiple lines. For example:
+
+-b :duration -b texture
+-f /path/file
+--debug
+
+Android limitations and peculiarities
+=====================================
+
+The Android version of glmark2 doesn't accept all of the command-line arguments
+that the X11 version accepts. In particular, the Android version currently
+ignores the following:
+
+--validate
+--frame-end
+--off-screen
+--reuse-context
+--fullscreen
+-l,--list-scenes
+
+The default visual config used on Android is:
+
+'red=5:green=6:blue=5:alpha=0:depth=16:buffer=1'
+
+Of course, you can change it using the '--visual-config' option.
+
+The Android system is free to resize the application at will, so although the
+'-s,--size' option is initially taken into account, it usually doesn't have any
+lasting effect.
diff --git a/android/Android.mk b/android/Android.mk
new file mode 100644
index 0000000..644bedd
--- /dev/null
+++ b/android/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_PACKAGE_NAME := GLMark2
+
+LOCAL_JNI_SHARED_LIBRARIES := libglmark2-android
+
+include $(BUILD_PACKAGE)
+
+include $(LOCAL_PATH)/jni/Android.mk
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
new file mode 100644
index 0000000..71fde82
--- /dev/null
+++ b/android/AndroidManifest.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ android:versionCode="1"
+ android:versionName="2012.12" package="org.linaro.glmark2">
+ <application android:label="@string/app_name">
+ <activity android:name="org.linaro.glmark2.MainActivity"
+ android:label="@string/title_activity_main">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name="org.linaro.glmark2.EditorActivity"
+ android:label="@string/title_activity_editor" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+ <activity android:label="@string/title_activity_glmark2"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+ android:screenOrientation="nosensor"
+ android:process=":glmark2"
+ android:name="org.linaro.glmark2.Glmark2Activity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+ <activity android:label="@string/title_activity_preferences"
+ android:name="org.linaro.glmark2.MainPreferencesActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+ <activity android:label="@string/title_activity_about"
+ android:name="org.linaro.glmark2.AboutActivity"
+ android:theme="@android:style/Theme.Dialog">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+ <activity android:label="@string/title_activity_results"
+ android:name="org.linaro.glmark2.ResultsActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+ </application>
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-feature android:glEsVersion="0x00020000"/>
+ <uses-sdk android:minSdkVersion="9"/>
+</manifest>
diff --git a/android/CleanSpec.mk b/android/CleanSpec.mk
new file mode 100644
index 0000000..c23b5f7
--- /dev/null
+++ b/android/CleanSpec.mk
@@ -0,0 +1,6 @@
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/GLMark2*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/GLMark2.apk)
+
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libglmark2-android_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libglmark2-matrix_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libglmark2-png_intermediates)
diff --git a/android/assets b/android/assets
new file mode 120000
index 0000000..eed2d0b
--- /dev/null
+++ b/android/assets
@@ -0,0 +1 @@
+../data/ \ No newline at end of file
diff --git a/android/build.xml b/android/build.xml
new file mode 100644
index 0000000..8d11dd3
--- /dev/null
+++ b/android/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="Glmark2" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- if sdk.dir was not set from one of the property file, then
+ get it from the ANDROID_HOME env var.
+ This must be done before we load project.properties since
+ the proguard config can use sdk.dir -->
+ <property environment="env" />
+ <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+ <isset property="env.ANDROID_HOME" />
+ </condition>
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+ unless="sdk.dir"
+ />
+
+ <!--
+ Import per project custom build rules if present at the root of the project.
+ This is the place to put custom intermediary targets such as:
+ -pre-build
+ -pre-compile
+ -post-compile (This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir})
+ -post-package
+ -post-build
+ -pre-clean
+ -->
+ <import file="custom_rules.xml" optional="true" />
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
new file mode 100644
index 0000000..6887d78
--- /dev/null
+++ b/android/jni/Android.mk
@@ -0,0 +1,76 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_MODULE := libglmark2-matrix
+LOCAL_CFLAGS := -DUSE_GLESv2 -Werror -Wall -Wextra -Wnon-virtual-dtor \
+ -Wno-error=unused-parameter
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src
+LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libmatrix/*.cc))
+LOCAL_SHARED_LIBRARIES := libdl libstlport
+
+include external/stlport/libstlport.mk
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libglmark2-png
+LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libpng/*.c))
+LOCAL_C_INCLUDES := external/zlib
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libglmark2-jpeg
+LOCAL_CFLAGS := -Werror -Wall -Wextra -Wno-error=attributes \
+ -Wno-error=unused-parameter -Wno-error=unused-function -Wno-error=unused-variable
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src/libjpeg-turbo/
+LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libjpeg-turbo/simd/*.c)) \
+ $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libjpeg-turbo/simd/*.S)) \
+ $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libjpeg-turbo/*.c))
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_MODULE := libglmark2-ideas
+LOCAL_CFLAGS := -DGLMARK_DATA_PATH="" -DUSE_GLESv2 -Werror -Wall -Wextra\
+ -Wnon-virtual-dtor -Wno-error=unused-parameter
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/src/libmatrix
+LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/scene-ideas/*.cc))
+LOCAL_SHARED_LIBRARIES := libdl libstlport
+
+include external/stlport/libstlport.mk
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libglmark2-android
+LOCAL_STATIC_LIBRARIES := libglmark2-matrix libglmark2-png libglmark2-ideas libglmark2-jpeg
+LOCAL_CFLAGS := -DGLMARK_DATA_PATH="" -DGLMARK_VERSION="\"2012.12\"" \
+ -DUSE_GLESv2 -Werror -Wall -Wextra -Wnon-virtual-dtor \
+ -Wno-error=unused-parameter
+LOCAL_SHARED_LIBRARIES := liblog libz libEGL libGLESv2 libandroid libdl libstlport
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/src/libmatrix \
+ $(LOCAL_PATH)/src/scene-ideas \
+ $(LOCAL_PATH)/src/scene-terrain \
+ $(LOCAL_PATH)/src/libjpeg-turbo \
+ $(LOCAL_PATH)/src/libpng \
+ external/zlib
+LOCAL_SRC_FILES := $(filter-out src/canvas% src/main.cpp, \
+ $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/*.cpp))) \
+ $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/scene-terrain/*.cpp)) \
+ src/canvas-android.cpp
+LOCAL_PRELINK_MODULE := false
+
+include external/stlport/libstlport.mk
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/android/jni/Android.ndk.mk b/android/jni/Android.ndk.mk
new file mode 100644
index 0000000..0279799
--- /dev/null
+++ b/android/jni/Android.ndk.mk
@@ -0,0 +1,65 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_MODULE := libglmark2-matrix
+LOCAL_CFLAGS := -DUSE_GLESv2 -Werror -Wall -Wextra -Wnon-virtual-dtor \
+ -Wno-error=unused-parameter
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src
+LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libmatrix/*.cc))
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libglmark2-png
+LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libpng/*.c))
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libglmark2-jpeg
+LOCAL_CFLAGS := -Werror -Wall -Wextra -Wno-error=attributes \
+ -Wno-error=unused-parameter -Wno-error=unused-function -Wno-error=unused-variable
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src/libjpeg-turbo/
+LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libjpeg-turbo/simd/*.c)) \
+ $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libjpeg-turbo/simd/*.S)) \
+ $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libjpeg-turbo/*.c))
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_MODULE := libglmark2-ideas
+LOCAL_CFLAGS := -DGLMARK_DATA_PATH="" -DUSE_GLESv2 -Werror -Wall -Wextra\
+ -Wnon-virtual-dtor -Wno-error=unused-parameter
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/src/libmatrix
+LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/scene-ideas/*.cc))
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libglmark2-android
+LOCAL_STATIC_LIBRARIES := libglmark2-matrix libglmark2-png libglmark2-ideas libglmark2-jpeg
+LOCAL_CFLAGS := -DGLMARK_DATA_PATH="" -DGLMARK_VERSION="\"2012.12\"" \
+ -DUSE_GLESv2 -Werror -Wall -Wextra -Wnon-virtual-dtor \
+ -Wno-error=unused-parameter
+LOCAL_LDLIBS := -landroid -llog -lGLESv2 -lEGL -lz
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/src/libmatrix \
+ $(LOCAL_PATH)/src/scene-ideas \
+ $(LOCAL_PATH)/src/scene-terrain \
+ $(LOCAL_PATH)/src/libjpeg-turbo \
+ $(LOCAL_PATH)/src/libpng
+LOCAL_SRC_FILES := $(filter-out src/canvas% src/main.cpp, \
+ $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/*.cpp))) \
+ $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/scene-terrain/*.cpp)) \
+ src/canvas-android.cpp
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/android/jni/Application.mk b/android/jni/Application.mk
new file mode 100644
index 0000000..69d78d9
--- /dev/null
+++ b/android/jni/Application.mk
@@ -0,0 +1,3 @@
+APP_STL := stlport_static
+APP_PLATFORM := android-9
+APP_BUILD_SCRIPT := jni/Android.ndk.mk
diff --git a/android/jni/src b/android/jni/src
new file mode 120000
index 0000000..a8d2a67
--- /dev/null
+++ b/android/jni/src
@@ -0,0 +1 @@
+../../src/ \ No newline at end of file
diff --git a/android/project.properties b/android/project.properties
new file mode 100644
index 0000000..b7c2081
--- /dev/null
+++ b/android/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-10
diff --git a/android/res/drawable/menu_about.png b/android/res/drawable/menu_about.png
new file mode 100644
index 0000000..6a7a1e9
--- /dev/null
+++ b/android/res/drawable/menu_about.png
Binary files differ
diff --git a/android/res/drawable/menu_delete.png b/android/res/drawable/menu_delete.png
new file mode 100644
index 0000000..24d8f6a
--- /dev/null
+++ b/android/res/drawable/menu_delete.png
Binary files differ
diff --git a/android/res/drawable/menu_load.png b/android/res/drawable/menu_load.png
new file mode 100644
index 0000000..e2d9bc1
--- /dev/null
+++ b/android/res/drawable/menu_load.png
Binary files differ
diff --git a/android/res/drawable/menu_results.png b/android/res/drawable/menu_results.png
new file mode 100644
index 0000000..95a3217
--- /dev/null
+++ b/android/res/drawable/menu_results.png
Binary files differ
diff --git a/android/res/drawable/menu_save.png b/android/res/drawable/menu_save.png
new file mode 100644
index 0000000..36fc7f4
--- /dev/null
+++ b/android/res/drawable/menu_save.png
Binary files differ
diff --git a/android/res/drawable/menu_settings.png b/android/res/drawable/menu_settings.png
new file mode 100644
index 0000000..5321f82
--- /dev/null
+++ b/android/res/drawable/menu_settings.png
Binary files differ
diff --git a/android/res/layout/activity_about.xml b/android/res/layout/activity_about.xml
new file mode 100644
index 0000000..6402727
--- /dev/null
+++ b/android/res/layout/activity_about.xml
@@ -0,0 +1,43 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp">
+
+ <TextView android:id="@+id/name_version"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/about_name_version_format" />
+
+ <TextView android:id="@+id/description"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/about_description" />
+
+ <TextView android:id="@+id/copyright"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/about_copyright" />
+
+ <TextView android:id="@+id/url"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/about_url" />
+
+ <TextView android:id="@+id/license1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/about_license_1" />
+
+ <TextView android:id="@+id/license2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/about_license_2" />
+</LinearLayout>
+
diff --git a/android/res/layout/activity_editor.xml b/android/res/layout/activity_editor.xml
new file mode 100644
index 0000000..c59f7c2
--- /dev/null
+++ b/android/res/layout/activity_editor.xml
@@ -0,0 +1,34 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout android:id="@+id/buttonLinearLayout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true">
+
+ <Button android:id="@+id/runButton"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0"
+ android:layout_alignParentBottom="true"
+ android:text="@string/runButtonText" />
+
+ <Button android:id="@+id/saveButton"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0"
+ android:layout_alignParentBottom="true"
+ android:text="@string/saveButtonText" />
+
+ </LinearLayout>
+
+
+ <ListView android:id="@+id/editorListView"
+ android:layout_above="@id/buttonLinearLayout"
+ android:layout_weight="1.0"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentTop="true" />
+</RelativeLayout>
diff --git a/android/res/layout/activity_main.xml b/android/res/layout/activity_main.xml
new file mode 100644
index 0000000..c9342be
--- /dev/null
+++ b/android/res/layout/activity_main.xml
@@ -0,0 +1,20 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <Button android:id="@+id/runButton"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:text="@string/runButtonText" />
+
+ <ListView android:id="@+id/benchmarkListView"
+ android:layout_above="@id/runButton"
+ android:layout_weight="1.0"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentTop="true" />
+
+
+</RelativeLayout>
diff --git a/android/res/layout/activity_results.xml b/android/res/layout/activity_results.xml
new file mode 100644
index 0000000..46c8f66
--- /dev/null
+++ b/android/res/layout/activity_results.xml
@@ -0,0 +1,15 @@
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <HorizontalScrollView android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView android:id="@+id/results"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:typeface="monospace" />
+
+ </HorizontalScrollView>
+
+</ScrollView>
diff --git a/android/res/layout/list_header.xml b/android/res/layout/list_header.xml
new file mode 100644
index 0000000..9c5bd8f
--- /dev/null
+++ b/android/res/layout/list_header.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:id="@+id/listHeader" />
diff --git a/android/res/layout/list_item.xml b/android/res/layout/list_item.xml
new file mode 100644
index 0000000..7b3233d
--- /dev/null
+++ b/android/res/layout/list_item.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingRight="?android:attr/scrollbarSize" >
+
+ <RelativeLayout android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="15dip"
+ android:layout_marginRight="6dip"
+ android:layout_marginTop="6dip"
+ android:layout_marginBottom="6dip"
+ android:layout_weight="1">
+
+ <TextView android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <TextView android:id="@+id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignLeft="@id/title"
+ android:layout_below="@id/title"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:attr/textColorSecondary" />
+
+ </RelativeLayout>
+
+</LinearLayout>
diff --git a/android/res/layout/save_dialog.xml b/android/res/layout/save_dialog.xml
new file mode 100644
index 0000000..1074b52
--- /dev/null
+++ b/android/res/layout/save_dialog.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical" >
+
+ <RelativeLayout android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="15dip"
+ android:layout_marginRight="15dip"
+ android:layout_marginTop="6dip"
+ android:layout_marginBottom="6dip"
+ android:layout_weight="1">
+
+ <EditText android:id="@+id/listName"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <CheckBox android:id="@+id/external"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignLeft="@id/listName"
+ android:layout_below="@id/listName"
+ android:text="@string/externalSaveDialogText"/>
+
+ </RelativeLayout>
+
+</LinearLayout>
diff --git a/android/res/menu/main_options_menu.xml b/android/res/menu/main_options_menu.xml
new file mode 100644
index 0000000..e833173
--- /dev/null
+++ b/android/res/menu/main_options_menu.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/save_benchmark_list"
+ android:title="@string/saveMainOptionsText"
+ android:icon="@drawable/menu_save" />
+
+ <item android:id="@+id/load_benchmark_list"
+ android:title="@string/loadMainOptionsText"
+ android:icon="@drawable/menu_load" />
+
+ <item android:id="@+id/delete_benchmark_list"
+ android:title="@string/deleteMainOptionsText"
+ android:icon="@drawable/menu_delete" />
+
+ <item android:id="@+id/settings"
+ android:title="@string/settingsMainOptionsText"
+ android:icon="@drawable/menu_settings" />
+
+ <item android:id="@+id/results"
+ android:title="@string/resultsMainOptionsText"
+ android:icon="@drawable/menu_results" />
+
+ <item android:id="@+id/about"
+ android:title="@string/aboutMainOptionsText"
+ android:icon="@drawable/menu_about" />
+</menu>
diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml
new file mode 100644
index 0000000..571541c
--- /dev/null
+++ b/android/res/values/strings.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">GLMark2</string>
+ <string name="title_activity_main">GLMark2</string>
+ <string name="title_activity_editor">GLMark2 Benchmark Editor</string>
+ <string name="title_activity_preferences">GLMark2 Settings</string>
+ <string name="title_activity_about">About GLMark2</string>
+ <string name="title_activity_results">GLMark2 Results</string>
+ <string name="title_activity_glmark2">GLMark2</string>
+ <string name="runButtonText">Run</string>
+ <string name="saveButtonText">Save</string>
+
+ <string name="saveMainOptionsText">Save list</string>
+ <string name="loadMainOptionsText">Load list</string>
+ <string name="deleteMainOptionsText">Delete list</string>
+ <string name="settingsMainOptionsText">Settings</string>
+ <string name="resultsMainOptionsText">Last results</string>
+ <string name="aboutMainOptionsText">About</string>
+
+ <string name="externalSaveDialogText">Save to external storage</string>
+
+ <string name="runForeverPreferenceTitle">Run forever</string>
+ <string name="runForeverPreferenceSummary">Run indefinitely, looping from the last benchmark back to the first</string>
+ <string name="logDebugPreferenceTitle">Log debug messages</string>
+ <string name="logDebugPreferenceSummary">Display debug messages in the log</string>
+ <string name="showResultsPreferenceTitle">Show benchmark results</string>
+ <string name="showResultsPreferenceSummary">Show results after running benchmarks</string>
+
+ <string name="about_name_version_format">GLMark2 %1$s</string>
+ <string name="about_description">OpenGL (ES) 2.0 benchmark suite</string>
+ <string name="about_copyright">Copyright © 2010-2012 Linaro Limited</string>
+ <string name="about_url">http://launchpad.net/glmark2</string>
+ <string name="about_license_1">
+ glmark2 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 3 of the License, or (at your
+ option) any later version
+ </string>
+ <string name="about_license_2">
+ glmark2 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.
+ </string>
+
+</resources>
diff --git a/android/res/xml/preferences.xml b/android/res/xml/preferences.xml
new file mode 100644
index 0000000..be88f2a
--- /dev/null
+++ b/android/res/xml/preferences.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ <CheckBoxPreference android:key="run_forever"
+ android:title="@string/runForeverPreferenceTitle"
+ android:summary="@string/runForeverPreferenceSummary"
+ android:defaultValue="false" />
+ <CheckBoxPreference android:key="log_debug"
+ android:title="@string/logDebugPreferenceTitle"
+ android:summary="@string/logDebugPreferenceSummary"
+ android:defaultValue="false" />
+ <CheckBoxPreference android:key="show_results"
+ android:title="@string/showResultsPreferenceTitle"
+ android:summary="@string/showResultsPreferenceSummary"
+ android:defaultValue="true" />
+</PreferenceScreen>
diff --git a/android/src/org/linaro/glmark2/AboutActivity.java b/android/src/org/linaro/glmark2/AboutActivity.java
new file mode 100644
index 0000000..0c88cdb
--- /dev/null
+++ b/android/src/org/linaro/glmark2/AboutActivity.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import android.app.Activity;
+import android.content.pm.PackageInfo;
+import android.os.Bundle;
+import android.view.Window;
+import android.widget.TextView;
+
+public class AboutActivity extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.activity_about);
+
+ /* Get the application version */
+ String versionName = "?";
+
+ try {
+ PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0);
+ versionName = info.versionName;
+ }
+ catch (Exception e) {
+ }
+
+ /* Display the application version */
+ TextView tv = (TextView) findViewById(R.id.name_version);
+ String formatString = getString(R.string.about_name_version_format);
+ tv.setText(String.format(formatString, versionName));
+ }
+}
diff --git a/android/src/org/linaro/glmark2/BenchmarkListManager.java b/android/src/org/linaro/glmark2/BenchmarkListManager.java
new file mode 100644
index 0000000..3757307
--- /dev/null
+++ b/android/src/org/linaro/glmark2/BenchmarkListManager.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.io.*;
+
+import android.app.Activity;
+import android.os.Environment;
+
+class BenchmarkListManager {
+
+ private ArrayList<String> benchmarks;
+ private Activity activity;
+
+ BenchmarkListManager(Activity activity, ArrayList<String> benchmarks)
+ {
+ this.activity = activity;
+ if (benchmarks == null) {
+ this.benchmarks = new ArrayList<String>();
+ this.benchmarks.add("Add benchmark...");
+ }
+ else {
+ this.benchmarks = benchmarks;
+ }
+ }
+
+ /**
+ * Gets the list holding the benchmarks.
+ *
+ * The reference to this list is constant for the life of
+ * the BenchmarkListManager,
+ *
+ * @return the operation error code
+ */
+ ArrayList<String> getBenchmarkList() {
+ return benchmarks;
+ }
+
+ /**
+ * Gets the saved benchmark lists.
+ *
+ * Each list name is prefixed with either "internal/" or "external/"
+ * to denote in which storage area it is saved in.
+ *
+ * @return an array containing the saved list names
+ */
+ String[] getSavedLists() {
+ File externalPath = getSavedListPath(true);
+ File internalPath = getSavedListPath(false);
+ ArrayList<String> lists = new ArrayList<String>();
+
+ if (externalPath != null && externalPath.isDirectory()) {
+ for (File f: externalPath.listFiles())
+ lists.add("external/" + f.getName());
+ }
+
+ if (internalPath != null && internalPath.isDirectory()) {
+ for (File f: internalPath.listFiles())
+ lists.add("internal/" + f.getName());
+ }
+
+ Collections.sort(lists);
+
+ String[] a = new String[0];
+ return lists.toArray(a);
+ }
+
+ /**
+ * Saves the current benchmark list to a file.
+ *
+ * @param listName the list filename
+ * @param external whether the file is to be stored in external storage
+ */
+ void saveBenchmarkList(String listName, boolean external) throws Exception {
+ File listPath = getSavedListPath(external);
+ if (listPath == null)
+ throw new Exception("External storage not present");
+
+ listPath.mkdirs();
+
+ File f = new File(listPath, listName);
+
+ BufferedWriter out = new BufferedWriter(new FileWriter(f));
+ try {
+ for (int i = 0; i < benchmarks.size() - 1; i++) {
+ out.write(benchmarks.get(i));
+ out.newLine();
+ }
+ }
+ catch (Exception ex) {
+ throw ex;
+ }
+ finally {
+ out.close();
+ }
+ }
+
+ /**
+ * Loads a benchmark list from a file.
+ *
+ * @param listName the list filename
+ * @param external whether the file is stored in external storage
+ */
+ void loadBenchmarkList(String listName, boolean external) throws Exception {
+ /* Get the list file path */
+ File listPath = getSavedListPath(external);
+ if (listPath == null)
+ throw new Exception("External storage not present");
+
+ File f = new File(listPath, listName);
+
+ ArrayList<String> newBenchmarks = new ArrayList<String>();
+
+ /* Read benchmarks from file */
+ BufferedReader reader = new BufferedReader(new FileReader(f));
+ String line = null;
+
+ while ((line = reader.readLine()) != null)
+ newBenchmarks.add(line);
+
+ /* If everything went well, replace current benchmarks */
+ benchmarks.clear();
+ benchmarks.addAll(newBenchmarks);
+ benchmarks.add("Add benchmark...");
+ }
+
+ /**
+ * Delete a benchmark list file.
+ *
+ * @param listName the list filename
+ * @param external whether the file is stored in external storage
+ */
+ void deleteBenchmarkList(String listName, boolean external) throws Exception {
+ /* Get the list file path */
+ File listPath = getSavedListPath(external);
+ if (listPath == null)
+ throw new Exception("External storage not present");
+
+ File f = new File(listPath, listName);
+ f.delete();
+ }
+
+ /**
+ * Gets the path where benchmark lists are saved in.
+ *
+ * @param external whether to get the path for external storage
+ *
+ * @return the saved list path
+ */
+ private File getSavedListPath(boolean external) {
+ File f = null;
+
+ if (external) {
+ String state = Environment.getExternalStorageState();
+ if (!Environment.MEDIA_MOUNTED.equals(state))
+ return null;
+ f = activity.getExternalFilesDir(null);
+ }
+ else {
+ f = activity.getFilesDir();
+ }
+
+ if (f != null)
+ f = new File(f, "lists");
+
+ return f;
+ }
+}
diff --git a/android/src/org/linaro/glmark2/EditorActivity.java b/android/src/org/linaro/glmark2/EditorActivity.java
new file mode 100644
index 0000000..47e88c8
--- /dev/null
+++ b/android/src/org/linaro/glmark2/EditorActivity.java
@@ -0,0 +1,548 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.text.SpannableString;
+import android.text.style.ForegroundColorSpan;
+import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+public class EditorActivity extends Activity {
+ public static final int DIALOG_SCENE_NAME_ID = 0;
+ public static final int DIALOG_SCENE_OPTION_TEXT_ID = 1;
+ public static final int DIALOG_SCENE_OPTION_LIST_ID = 2;
+
+ public static final int ITEM_POSITION_SCENE_NAME_HEADER = 0;
+ public static final int ITEM_POSITION_SCENE_NAME = 1;
+ public static final int ITEM_POSITION_SCENE_OPTION_HEADER = 2;
+ public static final int ITEM_POSITION_SCENE_OPTION = 3;
+
+ private EditorItemAdapter adapter;
+ private ArrayList<SceneInfo> sceneInfoList;
+ private String[] sceneNames;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_editor);
+
+ /* Get information about the available scenes */
+ sceneInfoList = getSceneInfoList();
+ sceneNames = getSceneNames();
+
+ /* Read information sent by the main activity */
+ final int benchmarkPos = this.getIntent().getIntExtra("benchmark-pos", 0);
+ String benchmarkText = getIntent().getStringExtra("benchmark-text");
+ if (benchmarkText.isEmpty())
+ benchmarkText = sceneNames[0];
+
+ /* Set up the run button */
+ Button runButton = (Button) findViewById(R.id.runButton);
+ runButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ Intent intent = new Intent(EditorActivity.this, Glmark2Activity.class);
+ String args = "-b \"" + getBenchmarkDescriptionText() + "\"";
+ intent.putExtra("args", args);
+ startActivity(intent);
+ }
+ });
+
+ /* Set up the save button */
+ Button button = (Button) findViewById(R.id.saveButton);
+ button.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ String newBenchmarkText = getBenchmarkDescriptionText();
+ Intent intent = new Intent();
+ intent.putExtra("benchmark-text", newBenchmarkText);
+ intent.putExtra("benchmark-pos", benchmarkPos);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+ });
+
+ /* Set up list view */
+ ListView lv = (ListView) findViewById(R.id.editorListView);
+ adapter = new EditorItemAdapter(this, R.layout.list_item,
+ getEditorItemList(benchmarkText));
+ lv.setAdapter(adapter);
+
+ lv.setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView<?> parentView, View childView, int position, long id) {
+ Bundle bundle = new Bundle();
+ bundle.putInt("item-pos", position);
+ /* Show the right dialog, depending on the clicked list position */
+ if (position == ITEM_POSITION_SCENE_NAME) {
+ showDialog(DIALOG_SCENE_NAME_ID, bundle);
+ }
+ else if (position >= ITEM_POSITION_SCENE_OPTION) {
+ String[] values = adapter.getItem(position).option.acceptableValues;
+ if (values.length == 0)
+ showDialog(DIALOG_SCENE_OPTION_TEXT_ID, bundle);
+ else
+ showDialog(DIALOG_SCENE_OPTION_LIST_ID, bundle);
+ }
+ }
+ });
+
+ lv.setOnItemLongClickListener(new OnItemLongClickListener() {
+ public boolean onItemLongClick(AdapterView<?> parentView, View childView, int position, long id) {
+ /* Reset the value of the long-clicked option */
+ if (position >= ITEM_POSITION_SCENE_OPTION) {
+ EditorItem item = adapter.getItem(position);
+ item.value = null;
+ adapter.notifyDataSetChanged();
+ }
+ return true;
+ }
+ });
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id, Bundle bundle) {
+ final int itemPos = bundle.getInt("item-pos");
+ Dialog dialog;
+ final int finalId = id;
+
+ switch (id) {
+ case DIALOG_SCENE_NAME_ID:
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("Pick a scene");
+ builder.setItems(sceneNames, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int item) {
+ adapter.clear();
+ for (EditorItem ei: getEditorItemList(sceneNames[item]))
+ adapter.add(ei);
+ adapter.notifyDataSetChanged();
+ dismissDialog(DIALOG_SCENE_NAME_ID);
+ }
+ });
+ dialog = builder.create();
+ }
+ break;
+
+ case DIALOG_SCENE_OPTION_TEXT_ID:
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ final EditorItem item = adapter.getItem(itemPos);
+ final EditText input = new EditText(this);
+ if (item.value != null)
+ input.setText(item.value);
+
+ input.setOnEditorActionListener(new OnEditorActionListener() {
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE ||
+ (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER &&
+ event.getAction() == KeyEvent.ACTION_UP))
+ {
+ item.value = v.getText().toString();
+ adapter.notifyDataSetChanged();
+ dismissDialog(DIALOG_SCENE_OPTION_TEXT_ID);
+ }
+ return true;
+ }
+ });
+ builder.setTitle(item.option.name + ": " + item.option.description);
+ dialog = builder.create();
+ ((AlertDialog)dialog).setView(input, 15, 6, 15, 6);
+ dialog.getWindow().setSoftInputMode(
+ WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN |
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
+ );
+
+ }
+ break;
+
+ case DIALOG_SCENE_OPTION_LIST_ID:
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ final EditorItem item = adapter.getItem(itemPos);
+ builder.setTitle(item.option.name + ": " + item.option.description);
+
+ builder.setItems(item.option.acceptableValues, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int index) {
+ item.value = item.option.acceptableValues[index];
+ adapter.notifyDataSetChanged();
+ dismissDialog(DIALOG_SCENE_OPTION_LIST_ID);
+ }
+ });
+
+ dialog = builder.create();
+ }
+ break;
+
+ default:
+ dialog = null;
+ break;
+ }
+
+ if (dialog != null) {
+ dialog.setOnDismissListener(new OnDismissListener() {
+ public void onDismiss(DialogInterface dialog) {
+ removeDialog(finalId);
+ }
+ });
+ }
+
+ return dialog;
+ }
+
+ /**
+ * Gets the value of an option.
+ *
+ * @param benchArray an array of option strings ("opt=val")
+ * @param opt the options to get the value of
+ *
+ * @return the value or null
+ */
+ private String getOptionValue(String[] benchArray, String opt) {
+ String ret = null;
+
+ /* Search from the end to the beginning */
+ for (int n = benchArray.length - 1; n >= 0; n--) {
+ String s = benchArray[n].trim();
+ if (s.startsWith(opt + "=")) {
+ int i = s.indexOf('=');
+ if (i >= 0 && i + 1 < s.length()) {
+ ret = s.substring(i + 1).trim();
+ break;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+ /**
+ * Gets the benchmark description string of the current editing state.
+ *
+ * @return the string
+ */
+ private String getBenchmarkDescriptionText() {
+ String ret = "";
+
+ for (int i = 0; i < adapter.getCount(); i++) {
+ /* Convert each list item to a proper string representation */
+ EditorItem item = adapter.getItem(i);
+ if (item == null)
+ continue;
+
+ String s = "";
+
+ /*
+ * Append "opt=" if this is an option item, except the
+ * "__custom__" item.
+ */
+ if (item.option != null && item.value != null &&
+ !item.option.name.equals("__custom__"))
+ {
+ s += item.option.name + "=";
+ }
+
+ /*
+ * Append the item value if this is not "__custom__".
+ */
+ if (item.value != null && !item.value.equals("__custom__"))
+ s += item.value;
+
+ /*
+ * Append ":" to the description string if needed.
+ */
+ if (!s.isEmpty() && !ret.isEmpty())
+ ret += ":";
+
+ /* Append the item representation */
+ ret += s;
+ }
+
+ return ret;
+ }
+
+ /**
+ * Creates an EditorItem list from a benchmark description string.
+ *
+ * @param benchDesc the benchmark description string
+ *
+ * @return the list
+ */
+ private ArrayList<EditorItem> getEditorItemList(String benchDesc) {
+ String[] benchArray = benchDesc.split(":");
+ String benchName = benchArray[0].trim();
+
+ if (benchName.isEmpty())
+ benchName = "__custom__";
+
+ /* Find SceneInfo from name */
+ SceneInfo sceneInfo = null;
+ for (SceneInfo si: sceneInfoList) {
+ if (si.name.equals(benchName)) {
+ sceneInfo = si;
+ break;
+ }
+ }
+
+ /* If we couldn't find a matching SceneInfo, use __custom__ */
+ if (sceneInfo == null) {
+ for (SceneInfo si: sceneInfoList) {
+ if (si.name.equals("__custom__")) {
+ sceneInfo = si;
+ break;
+ }
+ }
+ }
+
+ ArrayList<EditorItem> l = new ArrayList<EditorItem>();
+
+ /* Append null item for Scene header */
+ l.add(null);
+
+ /* Append scene name item */
+ l.add(new EditorItem(null, sceneInfo.name));
+
+ /* Append null item for Options header */
+ l.add(null);
+
+ /* Append items to the list */
+ if (!sceneInfo.name.equals("__custom__")) {
+ /* Append scene option items */
+ for (SceneInfo.Option opt: sceneInfo.options)
+ l.add(new EditorItem(opt, getOptionValue(benchArray, opt.name)));
+ }
+ else {
+ String desc = new String(benchDesc);
+ if (desc.startsWith("__custom__"))
+ desc = "";
+
+ /* Append scene option items (only one for __custom__) */
+ for (SceneInfo.Option opt: sceneInfo.options)
+ l.add(new EditorItem(opt, desc));
+ }
+
+ return l;
+ }
+
+ /**
+ * Gets a list of information about the available scenes.
+ *
+ * @return the list
+ */
+ private ArrayList<SceneInfo> getSceneInfoList() {
+ ArrayList<SceneInfo> l = new ArrayList<SceneInfo>();
+ SceneInfo customSceneInfo = new SceneInfo("__custom__");
+ customSceneInfo.addOption("__custom__", "Custom benchmark string", "", new String[0]);
+
+ for (Parcelable p: getIntent().getParcelableArrayExtra("scene-info"))
+ l.add((SceneInfo)p);
+
+ /* Sort SceneInfo list by name */
+ Collections.sort(l, new Comparator<SceneInfo>() {
+ public int compare(SceneInfo s1, SceneInfo s2) {
+ return s1.name.compareTo(s2.name);
+ }
+ });
+
+ /* Add the "__custom__" SceneInfo */
+ l.add(customSceneInfo);
+
+ return l;
+ }
+
+ /**
+ * Gets the array of scene names.
+ *
+ * @return the array
+ */
+ private String[] getSceneNames() {
+ ArrayList<String> l = new ArrayList<String>();
+
+ for (SceneInfo si: sceneInfoList) {
+ if (!si.name.isEmpty())
+ l.add(si.name);
+ }
+
+ String[] a = new String[0];
+ return l.toArray(a);
+ }
+
+
+ static private class EditorItem {
+ SceneInfo.Option option;
+
+ public EditorItem(SceneInfo.Option o, String value) {
+ this.option = o;
+ this.value = value;
+ }
+
+ public String value;
+ }
+
+ /**
+ * A ListView adapter that creates list item views from EditorItems
+ */
+ private class EditorItemAdapter extends ArrayAdapter<EditorItem> {
+ static final int VIEW_TYPE_HEADER = 0;
+ static final int VIEW_TYPE_SCENE_NAME = 1;
+ static final int VIEW_TYPE_SCENE_OPTION = 2;
+ static final int VIEW_TYPE_COUNT = 3;
+
+ public ArrayList<EditorItem> items;
+
+ public EditorItemAdapter(Context context, int textViewResourceId,
+ ArrayList<EditorItem> items)
+ {
+ super(context, textViewResourceId, items);
+ this.items = items;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return position == ITEM_POSITION_SCENE_NAME ||
+ position >= ITEM_POSITION_SCENE_OPTION;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position == ITEM_POSITION_SCENE_NAME)
+ return VIEW_TYPE_SCENE_NAME;
+ else if (position >= ITEM_POSITION_SCENE_OPTION)
+ return VIEW_TYPE_SCENE_OPTION;
+ else
+ return VIEW_TYPE_HEADER;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return VIEW_TYPE_COUNT;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ int viewType = getItemViewType(position);
+ View v = null;
+
+ if (viewType == VIEW_TYPE_HEADER)
+ v = getViewHeader(position, convertView);
+ else if (viewType == VIEW_TYPE_SCENE_NAME)
+ v = getViewScene(position, convertView);
+ else if (viewType == VIEW_TYPE_SCENE_OPTION)
+ v = getViewOption(position, convertView);
+
+ return v;
+ }
+
+ private View getViewHeader(int position, View convertView) {
+ /* Get the view/widget to use */
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = vi.inflate(R.layout.list_header, null);
+ }
+
+ TextView tv = (TextView) v;
+
+ if (position == ITEM_POSITION_SCENE_NAME_HEADER)
+ tv.setText("Scene");
+ else if (position == ITEM_POSITION_SCENE_OPTION_HEADER)
+ tv.setText("Options");
+
+ return tv;
+ }
+
+ private View getViewScene(int position, View convertView) {
+ /* Get the view/widget to use */
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = vi.inflate(R.layout.list_item, null);
+ }
+
+ EditorItem item = items.get(position);
+
+ TextView title = (TextView) v.findViewById(R.id.title);
+ TextView summary = (TextView) v.findViewById(R.id.summary);
+
+ if (title != null)
+ title.setText(item.value);
+ if (summary != null)
+ summary.setText("The scene to use");
+
+ return v;
+ }
+
+ private View getViewOption(int position, View convertView) {
+ /* Get the view/widget to use */
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = vi.inflate(R.layout.list_item, null);
+ }
+
+ EditorItem item = items.get(position);
+
+ TextView title = (TextView) v.findViewById(R.id.title);
+ TextView summary = (TextView) v.findViewById(R.id.summary);
+ boolean hasUserSetValue = item.value != null;
+ String value = hasUserSetValue ? item.value : item.option.defaultValue;
+
+ if (title != null) {
+ /* If the option has been edited by the user show it with emphasis */
+ SpannableString titleText = new SpannableString(item.option.name + " = " + value);
+ ForegroundColorSpan span = new ForegroundColorSpan(hasUserSetValue ? Color.CYAN : Color.LTGRAY);
+ titleText.setSpan(span, item.option.name.length() + " = ".length(), titleText.length(), 0);
+ title.setText(titleText);
+ }
+
+ if (summary != null)
+ summary.setText(item.option.description);
+
+ return v;
+ }
+ }
+}
diff --git a/android/src/org/linaro/glmark2/GLVisualConfig.java b/android/src/org/linaro/glmark2/GLVisualConfig.java
new file mode 100644
index 0000000..ca4d218
--- /dev/null
+++ b/android/src/org/linaro/glmark2/GLVisualConfig.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+/**
+ * Class that holds a configuration of a GL visual.
+ */
+class GLVisualConfig {
+ public GLVisualConfig() {}
+ public GLVisualConfig(int r, int g, int b, int a, int d, int s, int buf) {
+ red = r;
+ green = g;
+ blue = b;
+ alpha = a;
+ depth = d;
+ stencil = s;
+ buffer = buf;
+ }
+
+ public int red;
+ public int green;
+ public int blue;
+ public int alpha;
+ public int depth;
+ public int stencil;
+ public int buffer;
+}
diff --git a/android/src/org/linaro/glmark2/Glmark2Activity.java b/android/src/org/linaro/glmark2/Glmark2Activity.java
new file mode 100644
index 0000000..bc0dde4
--- /dev/null
+++ b/android/src/org/linaro/glmark2/Glmark2Activity.java
@@ -0,0 +1,88 @@
+package org.linaro.glmark2;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.opengl.GLSurfaceView;
+import android.app.Dialog;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Context;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+
+public class Glmark2Activity extends Activity {
+ public static final int DIALOG_EGLCONFIG_FAIL_ID = 0;
+ public static final String TAG = "GLMark2";
+ private WakeLock mWakeLock;
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mWakeLock.release();
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, TAG);
+ mWakeLock.acquire();
+
+ mGLView = new Glmark2SurfaceView(this);
+ setContentView(mGLView);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mGLView.onPause();
+ Glmark2Activity.this.finish();
+ android.os.Process.killProcess(android.os.Process.myPid());
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mGLView.onResume();
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ Dialog dialog;
+ switch (id) {
+ case DIALOG_EGLCONFIG_FAIL_ID:
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage("Glmark2 cannot run because it couldn't find a suitable EGLConfig for GLES2.0. Please check that proper GLES2.0 drivers are installed.");
+ builder.setCancelable(false);
+ builder.setPositiveButton("Quit",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ Glmark2Activity.this.finish();
+ /*
+ * Force process shutdown. There is no safer way to
+ * do this, as we have open threads we can't close
+ * when we fail to get an EGLConfig
+ */
+ android.os.Process.killProcess(android.os.Process.myPid());
+ }
+ });
+
+ dialog = builder.create();
+ break;
+ default:
+ dialog = null;
+ break;
+ }
+
+ return dialog;
+ }
+
+
+ private GLSurfaceView mGLView;
+
+ static {
+ System.loadLibrary("glmark2-android");
+ }
+}
+
diff --git a/android/src/org/linaro/glmark2/Glmark2Native.java b/android/src/org/linaro/glmark2/Glmark2Native.java
new file mode 100644
index 0000000..c805385
--- /dev/null
+++ b/android/src/org/linaro/glmark2/Glmark2Native.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import android.content.res.AssetManager;
+
+class Glmark2Native {
+ public static native void init(AssetManager assetManager, String args,
+ String logFilePath);
+ public static native void resize(int w, int h);
+ public static native boolean render();
+ public static native void done();
+ public static native int scoreConfig(GLVisualConfig vc, GLVisualConfig target);
+ public static native SceneInfo[] getSceneInfo(AssetManager assetManager);
+}
diff --git a/android/src/org/linaro/glmark2/Glmark2SurfaceView.java b/android/src/org/linaro/glmark2/Glmark2SurfaceView.java
new file mode 100644
index 0000000..35c6c26
--- /dev/null
+++ b/android/src/org/linaro/glmark2/Glmark2SurfaceView.java
@@ -0,0 +1,218 @@
+package org.linaro.glmark2;
+
+import java.io.File;
+
+import android.graphics.PixelFormat;
+import android.opengl.GLSurfaceView;
+import android.app.Activity;
+import android.util.Log;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+class Glmark2SurfaceView extends GLSurfaceView {
+
+ public static final String LOG_TAG = "glmark2";
+
+ public Glmark2SurfaceView(Activity activity) {
+ super(activity);
+ mActivity = activity;
+
+ setEGLContextClientVersion(2);
+
+ setEGLConfigChooser(getConfigChooser());
+
+ setRenderer(new Glmark2Renderer(this));
+ }
+
+ private EGLConfigChooser getConfigChooser() {
+ String args = mActivity.getIntent().getStringExtra("args");
+
+ if (args == null)
+ args = "";
+
+ String[] argv = args.split(" ");
+
+ /* Find the visual-config option argument */
+ String configString = new String();
+ boolean keepNext = false;
+ for (String arg : argv) {
+ if (keepNext) {
+ configString = arg;
+ break;
+ }
+
+ if (arg.equals("--visual-config"))
+ keepNext = true;
+ }
+
+ /* Parse the config string parameters */
+ String[] configParams = configString.split(":");
+ GLVisualConfig targetConfig = new GLVisualConfig(5, 6, 5, 0, 16, 0, 1);
+
+ for (String param : configParams) {
+ String[] paramKeyValue = param.split("=");
+ if (paramKeyValue.length < 2)
+ continue;
+
+ if (paramKeyValue[0].equals("red") || paramKeyValue[0].equals("r"))
+ targetConfig.red = Integer.parseInt(paramKeyValue[1]);
+ else if (paramKeyValue[0].equals("green") || paramKeyValue[0].equals("g"))
+ targetConfig.green = Integer.parseInt(paramKeyValue[1]);
+ else if (paramKeyValue[0].equals("blue") || paramKeyValue[0].equals("b"))
+ targetConfig.blue = Integer.parseInt(paramKeyValue[1]);
+ else if (paramKeyValue[0].equals("alpha") || paramKeyValue[0].equals("a"))
+ targetConfig.alpha = Integer.parseInt(paramKeyValue[1]);
+ else if (paramKeyValue[0].equals("depth") || paramKeyValue[0].equals("d"))
+ targetConfig.depth = Integer.parseInt(paramKeyValue[1]);
+ else if (paramKeyValue[0].equals("stencil") || paramKeyValue[0].equals("s"))
+ targetConfig.stencil = Integer.parseInt(paramKeyValue[1]);
+ else if (paramKeyValue[0].equals("buffer") || paramKeyValue[0].equals("buf"))
+ targetConfig.buffer = Integer.parseInt(paramKeyValue[1]);
+ }
+
+ return new Glmark2ConfigChooser(targetConfig);
+ }
+
+ /**
+ * EGLConfigChooser that quits with an error dialog when a suitable config
+ * cannot be found.
+ */
+ private class Glmark2ConfigChooser implements EGLConfigChooser {
+ private int[] mAttribList;
+
+ public Glmark2ConfigChooser(GLVisualConfig targetConfig)
+ {
+ mAttribList = new int[] {
+ EGL10.EGL_RED_SIZE, targetConfig.red,
+ EGL10.EGL_GREEN_SIZE, targetConfig.green,
+ EGL10.EGL_BLUE_SIZE, targetConfig.blue,
+ EGL10.EGL_ALPHA_SIZE, targetConfig.alpha,
+ EGL10.EGL_DEPTH_SIZE, targetConfig.depth,
+ EGL10.EGL_STENCIL_SIZE, targetConfig.stencil,
+ EGL10.EGL_BUFFER_SIZE, targetConfig.buffer,
+ EGL10.EGL_RENDERABLE_TYPE, 4, /* 4 = EGL_OPENGL_ES2_BIT */
+ EGL10.EGL_NONE };
+
+ mTargetConfig = targetConfig;
+ }
+
+ @Override
+ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+ try {
+ return chooseConfigInternal(egl, display);
+ }
+ catch (Exception e) {
+ /* Log an error message */
+ Log.e(LOG_TAG, "No suitable EGLConfig for GLES2.0 found. Please check that proper GLES2.0 drivers are installed.");
+ /* Display an informative (and lethal for the app) dialog */
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.showDialog(Glmark2Activity.DIALOG_EGLCONFIG_FAIL_ID);
+ }
+ });
+
+ /* Wait here until the app process gets killed... */
+ synchronized (this) {
+ try { this.wait(); } catch (Exception ex) { }
+ }
+ }
+ return null;
+ }
+
+ private EGLConfig chooseConfigInternal(EGL10 egl, EGLDisplay display) {
+ /* Get the number of available configs matching the attributes */
+ int[] num_config = new int[1];
+ if (!egl.eglChooseConfig(display, mAttribList, null, 0, num_config)) {
+ throw new IllegalArgumentException("eglChooseConfig failed");
+ }
+
+ int numConfigs = num_config[0];
+
+ if (numConfigs <= 0) {
+ throw new IllegalArgumentException("No matching configs found");
+ }
+
+ /* Get the matching configs */
+ EGLConfig[] configs = new EGLConfig[numConfigs];
+ if (!egl.eglChooseConfig(display, mAttribList, configs, numConfigs,
+ num_config))
+ {
+ throw new IllegalArgumentException("eglChooseConfig#2 failed");
+ }
+
+ /* Find the best matching config. */
+ int bestScore = Integer.MIN_VALUE;
+ EGLConfig bestConfig = configs[0];
+
+ for (EGLConfig config : configs) {
+ GLVisualConfig vc = new GLVisualConfig();
+ vc.red = findConfigAttrib(egl, display, config,
+ EGL10.EGL_RED_SIZE, 0);
+ vc.green = findConfigAttrib(egl, display, config,
+ EGL10.EGL_GREEN_SIZE, 0);
+ vc.blue = findConfigAttrib(egl, display, config,
+ EGL10.EGL_BLUE_SIZE, 0);
+ vc.alpha = findConfigAttrib(egl, display, config,
+ EGL10.EGL_ALPHA_SIZE, 0);
+ vc.depth = findConfigAttrib(egl, display, config,
+ EGL10.EGL_DEPTH_SIZE, 0);
+ vc.stencil = findConfigAttrib(egl, display, config,
+ EGL10.EGL_STENCIL_SIZE, 0);
+ vc.buffer = findConfigAttrib(egl, display, config,
+ EGL10.EGL_BUFFER_SIZE, 0);
+
+ int score = Glmark2Native.scoreConfig(vc, mTargetConfig);
+
+ if (score > bestScore) {
+ bestScore = score;
+ bestConfig = config;
+ }
+ }
+
+ return bestConfig;
+ }
+
+ private int findConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config,
+ int attribute, int defaultValue)
+ {
+ int[] value = new int[] { defaultValue };
+ egl.eglGetConfigAttrib(display, config, attribute, value);
+ return value[0];
+ }
+
+ protected GLVisualConfig mTargetConfig;
+ }
+
+ public Activity getActivity() {
+ return mActivity;
+ }
+
+ private Activity mActivity;
+
+}
+
+class Glmark2Renderer implements GLSurfaceView.Renderer {
+ public Glmark2Renderer(Glmark2SurfaceView view) {
+ mView = view;
+ }
+
+ public void onDrawFrame(GL10 gl) {
+ if (!Glmark2Native.render())
+ mView.getActivity().finish();
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ Glmark2Native.resize(width, height);
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ String args = mView.getActivity().getIntent().getStringExtra("args");
+ File f = new File(mView.getActivity().getFilesDir(), "last_run.log");
+ Glmark2Native.init(mView.getActivity().getAssets(), args, f.getAbsolutePath());
+ }
+
+ private Glmark2SurfaceView mView;
+}
diff --git a/android/src/org/linaro/glmark2/MainActivity.java b/android/src/org/linaro/glmark2/MainActivity.java
new file mode 100644
index 0000000..8e284b2
--- /dev/null
+++ b/android/src/org/linaro/glmark2/MainActivity.java
@@ -0,0 +1,482 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import java.util.ArrayList;
+
+import android.os.Bundle;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.widget.BaseAdapter;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.CheckBox;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.inputmethod.EditorInfo;
+import android.util.Log;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.AdapterView;
+import android.widget.TextView.OnEditorActionListener;
+
+public class MainActivity extends Activity {
+ public static final int DIALOG_ERROR_ID = 0;
+ public static final int DIALOG_BENCHMARK_ACTIONS_ID = 1;
+ public static final int DIALOG_SAVE_LIST_ID = 2;
+ public static final int DIALOG_LOAD_LIST_ID = 3;
+ public static final int DIALOG_DELETE_LIST_ID = 4;
+
+ public static final int ACTIVITY_GLMARK2_REQUEST_CODE = 1;
+ public static final int ACTIVITY_EDITOR_REQUEST_CODE = 2;
+
+ /**
+ * The supported benchmark item actions.
+ */
+ public enum BenchmarkItemAction {
+ EDIT, DELETE, CLONE, MOVEUP, MOVEDOWN
+ }
+
+ BaseAdapter adapter;
+ SceneInfo[] sceneInfoList;
+ BenchmarkListManager benchmarkListManager;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ ArrayList<String> savedBenchmarks = null;
+
+ if (savedInstanceState != null)
+ savedBenchmarks = savedInstanceState.getStringArrayList("benchmarks");
+
+ init(savedBenchmarks);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putStringArrayList("benchmarks", benchmarkListManager.getBenchmarkList());
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id, Bundle bundle) {
+ final CharSequence[] benchmarkActions = {"Delete", "Clone", "Move Up", "Move Down"};
+ final BenchmarkItemAction[] benchmarkActionsId = {
+ BenchmarkItemAction.DELETE, BenchmarkItemAction.CLONE,
+ BenchmarkItemAction.MOVEUP, BenchmarkItemAction.MOVEDOWN
+ };
+ final int finalId = id;
+
+ Dialog dialog;
+
+ switch (id) {
+ case DIALOG_ERROR_ID:
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage(bundle.getString("message") + ": " +
+ bundle.getString("detail"));
+ builder.setCancelable(false);
+ builder.setPositiveButton("OK", null);
+ dialog = builder.create();
+ }
+ break;
+
+ case DIALOG_BENCHMARK_ACTIONS_ID:
+ {
+ final int benchmarkPos = bundle.getInt("benchmark-pos");
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("Pick an action");
+ builder.setItems(benchmarkActions, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int item) {
+ doBenchmarkItemAction(benchmarkPos, benchmarkActionsId[item], null);
+ dismissDialog(DIALOG_BENCHMARK_ACTIONS_ID);
+ }
+ });
+ dialog = builder.create();
+ }
+ break;
+
+ case DIALOG_SAVE_LIST_ID:
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ View layout = getLayoutInflater().inflate(R.layout.save_dialog, null);
+ final EditText input = (EditText) layout.findViewById(R.id.listName);
+ final CheckBox checkBox = (CheckBox) layout.findViewById(R.id.external);
+
+ input.setOnEditorActionListener(new OnEditorActionListener() {
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE ||
+ (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER &&
+ event.getAction() == KeyEvent.ACTION_UP))
+ {
+ String listName = v.getText().toString();
+ try {
+ benchmarkListManager.saveBenchmarkList(listName,
+ checkBox.isChecked());
+ }
+ catch (Exception ex) {
+ Bundle bundle = new Bundle();
+ bundle.putString("message", "Cannot save list to file " + listName);
+ bundle.putString("detail", ex.getMessage());
+ showDialog(DIALOG_ERROR_ID, bundle);
+ }
+ dismissDialog(DIALOG_SAVE_LIST_ID);
+ }
+ return true;
+ }
+ });
+
+ builder.setTitle("Save list as");
+ builder.setView(layout);
+
+ dialog = builder.create();
+ dialog.getWindow().setSoftInputMode(
+ WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN |
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
+ );
+ }
+ break;
+
+ case DIALOG_LOAD_LIST_ID:
+ case DIALOG_DELETE_LIST_ID:
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ if (id == DIALOG_LOAD_LIST_ID)
+ builder.setTitle("Load list");
+ else
+ builder.setTitle("Delete list");
+ final String[] savedLists = benchmarkListManager.getSavedLists();
+
+ builder.setItems(savedLists, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int index) {
+ String desc = savedLists[index];
+ String filename = "";
+ boolean external = false;
+
+ if (desc.startsWith("internal/")) {
+ filename = desc.replace("internal/", "");
+ external = false;
+ }
+ else if (desc.startsWith("external/")) {
+ filename = desc.replace("external/", "");
+ external = true;
+ }
+
+ try {
+ if (finalId == DIALOG_LOAD_LIST_ID) {
+ benchmarkListManager.loadBenchmarkList(filename, external);
+ adapter.notifyDataSetChanged();
+ }
+ else {
+ benchmarkListManager.deleteBenchmarkList(filename, external);
+ }
+
+ }
+ catch (Exception ex) {
+ Bundle bundle = new Bundle();
+ if (finalId == DIALOG_LOAD_LIST_ID)
+ bundle.putString("message", "Cannot load list " + desc);
+ else
+ bundle.putString("message", "Cannot delete list " + desc);
+ bundle.putString("detail", ex.getMessage());
+ showDialog(DIALOG_ERROR_ID, bundle);
+ }
+ dismissDialog(finalId);
+ }
+ });
+
+ dialog = builder.create();
+ }
+ break;
+
+ default:
+ dialog = null;
+ break;
+ }
+
+ if (dialog != null) {
+ dialog.setOnDismissListener(new OnDismissListener() {
+ public void onDismiss(DialogInterface dialog) {
+ removeDialog(finalId);
+ }
+ });
+ }
+
+ return dialog;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.main_options_menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ boolean ret = true;
+
+ switch (item.getItemId()) {
+ case R.id.save_benchmark_list:
+ showDialog(DIALOG_SAVE_LIST_ID);
+ ret = true;
+ break;
+ case R.id.load_benchmark_list:
+ showDialog(DIALOG_LOAD_LIST_ID);
+ ret = true;
+ break;
+ case R.id.delete_benchmark_list:
+ showDialog(DIALOG_DELETE_LIST_ID);
+ ret = true;
+ break;
+ case R.id.settings:
+ startActivity(new Intent(MainActivity.this, MainPreferencesActivity.class));
+ ret = true;
+ break;
+ case R.id.results:
+ startActivity(new Intent(MainActivity.this, ResultsActivity.class));
+ ret = true;
+ break;
+ case R.id.about:
+ startActivity(new Intent(MainActivity.this, AboutActivity.class));
+ ret = true;
+ break;
+ default:
+ ret = super.onOptionsItemSelected(item);
+ break;
+ }
+
+ return ret;
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == ACTIVITY_GLMARK2_REQUEST_CODE)
+ {
+ startActivity(new Intent(this, ResultsActivity.class));
+ return;
+ }
+ else if (requestCode == ACTIVITY_EDITOR_REQUEST_CODE &&
+ resultCode == RESULT_OK)
+ {
+ String benchmarkText = data.getStringExtra("benchmark-text");
+ int benchmarkPos = data.getIntExtra("benchmark-pos", 0);
+ doBenchmarkItemAction(benchmarkPos, BenchmarkItemAction.EDIT, benchmarkText);
+ }
+ }
+
+ /**
+ * Initialize the activity.
+ *
+ * @param savedBenchmarks a list of benchmarks to load the list with (or null)
+ */
+ private void init(ArrayList<String> savedBenchmarks)
+ {
+ /* Initialize benchmark list manager */
+ benchmarkListManager = new BenchmarkListManager(this, savedBenchmarks);
+ final ArrayList<String> benchmarks = benchmarkListManager.getBenchmarkList();
+
+ /* Get Scene information */
+ sceneInfoList = Glmark2Native.getSceneInfo(getAssets());
+
+ /* Set up the run button */
+ Button button = (Button) findViewById(R.id.runButton);
+ button.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
+ Intent intent = new Intent(MainActivity.this, Glmark2Activity.class);
+ String args = "";
+ for (int i = 0; i < benchmarks.size() - 1; i++)
+ args += "-b \"" + benchmarks.get(i) + "\" ";
+ if (prefs.getBoolean("run_forever", false))
+ args += "--run-forever ";
+ if (prefs.getBoolean("log_debug", false))
+ args += "--debug ";
+ if (!args.isEmpty())
+ intent.putExtra("args", args);
+
+ if (prefs.getBoolean("show_results", true))
+ startActivityForResult(intent, ACTIVITY_GLMARK2_REQUEST_CODE);
+ else
+ startActivity(intent);
+ }
+ });
+
+ /* Set up the benchmark list view */
+ ListView lv = (ListView) findViewById(R.id.benchmarkListView);
+ adapter = new BenchmarkAdapter(this, R.layout.list_item, benchmarks);
+ lv.setAdapter(adapter);
+
+ lv.setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView<?> parentView, View childView, int position, long id) {
+ Intent intent = new Intent(MainActivity.this, EditorActivity.class);
+ String t = benchmarks.get(position);
+ if (position == benchmarks.size() - 1)
+ t = "";
+ intent.putExtra("benchmark-text", t);
+ intent.putExtra("benchmark-pos", position);
+ intent.putExtra("scene-info", sceneInfoList);
+ startActivityForResult(intent, ACTIVITY_EDITOR_REQUEST_CODE);
+ }
+ });
+
+ lv.setOnItemLongClickListener(new OnItemLongClickListener() {
+ public boolean onItemLongClick(AdapterView<?> parentView, View childView, int position, long id) {
+ if (position < benchmarks.size() - 1) {
+ Bundle bundle = new Bundle();
+ bundle.putInt("benchmark-pos", position);
+ showDialog(DIALOG_BENCHMARK_ACTIONS_ID, bundle);
+ }
+ return true;
+ }
+ });
+
+ }
+
+ /**
+ * Perform an action on an listview benchmark item.
+ *
+ * @param position the position of the item in the listview
+ * @param action the action to perform
+ * @param data extra data needed by some actions
+ */
+ private void doBenchmarkItemAction(int position, BenchmarkItemAction action, String data)
+ {
+ int scrollPosition = position;
+ final ArrayList<String> benchmarks = benchmarkListManager.getBenchmarkList();
+
+ switch(action) {
+ case EDIT:
+ if (position == benchmarks.size() - 1) {
+ benchmarks.add(position, data);
+ scrollPosition = position + 1;
+ }
+ else {
+ benchmarks.set(position, data);
+ }
+ break;
+ case DELETE:
+ benchmarks.remove(position);
+ break;
+ case CLONE:
+ {
+ String s = benchmarks.get(position);
+ benchmarks.add(position, s);
+ scrollPosition = position + 1;
+ }
+ break;
+ case MOVEUP:
+ if (position > 0) {
+ String up = benchmarks.get(position - 1);
+ String s = benchmarks.get(position);
+ benchmarks.set(position - 1, s);
+ benchmarks.set(position, up);
+ scrollPosition = position - 1;
+ }
+ break;
+ case MOVEDOWN:
+ if (position < benchmarks.size() - 2) {
+ String down = benchmarks.get(position + 1);
+ String s = benchmarks.get(position);
+ benchmarks.set(position + 1, s);
+ benchmarks.set(position, down);
+ scrollPosition = position + 1;
+ }
+ break;
+ default:
+ break;
+ }
+
+
+ adapter.notifyDataSetChanged();
+
+ /* Scroll the list view so that the item of interest remains visible */
+ final int finalScrollPosition = scrollPosition;
+ final ListView lv = (ListView) findViewById(R.id.benchmarkListView);
+ lv.post(new Runnable() {
+ @Override
+ public void run() {
+ lv.smoothScrollToPosition(finalScrollPosition);
+ }
+ });
+ }
+
+ /**
+ * A ListView adapter that creates item views from benchmark strings.
+ */
+ private class BenchmarkAdapter extends ArrayAdapter<String> {
+ private ArrayList<String> items;
+
+ public BenchmarkAdapter(Context context, int textViewResourceId, ArrayList<String> items) {
+ super(context, textViewResourceId, items);
+ this.items = items;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ /* Get the view/widget to use */
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = vi.inflate(R.layout.list_item, null);
+ }
+
+ /* Split the benchmark into its scene name and its options */
+ String benchmark = items.get(position);
+ String[] ba = benchmark.split(":", 2);
+
+ if (ba != null) {
+ TextView title = (TextView) v.findViewById(R.id.title);
+ TextView summary = (TextView) v.findViewById(R.id.summary);
+ title.setText("");
+ summary.setText("");
+
+ if (title != null && ba.length > 0)
+ title.setText(ba[0]);
+ if (summary != null && ba.length > 1)
+ summary.setText(ba[1]);
+ }
+ return v;
+ }
+ }
+
+ static {
+ System.loadLibrary("glmark2-android");
+ }
+}
diff --git a/android/src/org/linaro/glmark2/MainPreferencesActivity.java b/android/src/org/linaro/glmark2/MainPreferencesActivity.java
new file mode 100644
index 0000000..76447ec
--- /dev/null
+++ b/android/src/org/linaro/glmark2/MainPreferencesActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class MainPreferencesActivity extends PreferenceActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.preferences);
+ }
+}
diff --git a/android/src/org/linaro/glmark2/ResultsActivity.java b/android/src/org/linaro/glmark2/ResultsActivity.java
new file mode 100644
index 0000000..d0e8756
--- /dev/null
+++ b/android/src/org/linaro/glmark2/ResultsActivity.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import java.io.*;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class ResultsActivity extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_results);
+ TextView tv = (TextView) findViewById(R.id.results);
+
+ File f = new File(getFilesDir(), "last_run.log");
+
+ try {
+ /* Read log from file */
+ BufferedReader reader = new BufferedReader(new FileReader(f));
+ String line = null;
+ StringBuffer sb = new StringBuffer();
+
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ sb.append('\n');
+ }
+
+ reader.close();
+ tv.setText(sb.toString());
+ }
+ catch (Exception ex) {
+ }
+ }
+}
+
diff --git a/android/src/org/linaro/glmark2/SceneInfo.java b/android/src/org/linaro/glmark2/SceneInfo.java
new file mode 100644
index 0000000..5b4ae5f
--- /dev/null
+++ b/android/src/org/linaro/glmark2/SceneInfo.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+package org.linaro.glmark2;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+import java.util.ArrayList;
+
+class SceneInfo implements Parcelable {
+ static class Option {
+ String name;
+ String description;
+ String defaultValue;
+ String[] acceptableValues;
+ }
+
+ public SceneInfo(String name) {
+ this.name = name;
+ this.options = new ArrayList<Option>();
+ }
+
+ public void addOption(String name, String description, String defaultValue,
+ String[] acceptableValues)
+ {
+ Option opt = new Option();
+ opt.name = name;
+ opt.description = description;
+ opt.defaultValue = defaultValue;
+ opt.acceptableValues = acceptableValues;
+ this.options.add(opt);
+ }
+
+ public String name;
+ public ArrayList<Option> options;
+
+ /* Parcelable interface */
+ public static final Parcelable.Creator<SceneInfo> CREATOR =
+ new Parcelable.Creator<SceneInfo>() {
+ public SceneInfo createFromParcel(Parcel in) {
+ return new SceneInfo(in);
+ }
+
+ public SceneInfo[] newArray(int size) {
+ return new SceneInfo[size];
+ }
+ };
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(name);
+ out.writeInt(options.size());
+ for (Option opt: options) {
+ out.writeString(opt.name);
+ out.writeString(opt.description);
+ out.writeString(opt.defaultValue);
+ out.writeStringArray(opt.acceptableValues);
+ }
+ }
+
+ private SceneInfo(Parcel in) {
+ name = in.readString();
+ options = new ArrayList<Option>();
+
+ int size = in.readInt();
+ for (int i = 0; i < size; i++) {
+ Option opt = new Option();
+ opt.name = in.readString();
+ opt.description = in.readString();
+ opt.defaultValue = in.readString();
+ opt.acceptableValues = in.createStringArray();
+ options.add(opt);
+ }
+ }
+}
diff --git a/data/models/asteroid-high.3ds b/data/models/asteroid-high.3ds
new file mode 100644
index 0000000..369b9fe
--- /dev/null
+++ b/data/models/asteroid-high.3ds
Binary files differ
diff --git a/data/models/asteroid-low.3ds b/data/models/asteroid-low.3ds
new file mode 100644
index 0000000..903bd2e
--- /dev/null
+++ b/data/models/asteroid-low.3ds
Binary files differ
diff --git a/data/models/bunny.obj b/data/models/bunny.obj
new file mode 100644
index 0000000..d9f8c97
--- /dev/null
+++ b/data/models/bunny.obj
@@ -0,0 +1,104501 @@
+v 0.296502 -0.907931 0.450151
+v 0.315114 -0.913622 0.435867
+v 0.324517 -0.920404 0.443869
+v 0.325879 -0.966814 0.485578
+v 0.302693 -0.969589 0.506426
+v 0.29049 -0.968073 0.502572
+v 0.278223 -0.96657 0.498757
+v 0.256232 -0.967238 0.517897
+v 0.242885 -0.967829 0.515687
+v 0.220907 -0.96851 0.534853
+v 0.208062 -0.96806 0.53186
+v 0.197002 -0.964438 0.526298
+v 0.173341 -0.968279 0.547929
+v 0.161099 -0.966776 0.544075
+v 0.126289 -0.967007 0.560171
+v 0.112326 -0.968664 0.558732
+v 0.11889 -0.907418 0.505655
+v 0.10178 -0.963988 0.552425
+v 0.07826 -0.967765 0.573838
+v 0.0649908 -0.96824 0.571474
+v 0.0538154 -0.964656 0.566002
+v 0.0307452 -0.967842 0.586503
+v 0.0174889 -0.968317 0.584114
+v 0.00474634 -0.967778 0.58089
+v -0.0167567 -0.96797 0.599079
+v -0.0294992 -0.967431 0.595893
+v -0.00351319 -0.909242 0.528122
+v 0.0103597 -0.907585 0.529509
+v -0.0427042 -0.967906 0.593491
+v -0.0436933 -0.911066 0.521442
+v -0.13451 -0.969229 0.575058
+v -0.166648 -0.971927 0.547929
+v -0.124323 -0.915574 0.508661
+v -0.147766 -0.969704 0.572605
+v -0.160496 -0.969178 0.569458
+v -0.179365 -0.971374 0.544808
+v -0.192622 -0.97185 0.54238
+v -0.198222 -0.973596 0.520093
+v -0.210425 -0.972042 0.516175
+v -0.216 -0.973802 0.493915
+v -0.228165 -0.972248 0.49001
+v -0.231145 -0.968959 0.463908
+v -0.201472 -0.937116 0.442687
+v -0.18169 -0.924373 0.435802
+v -0.176295 -0.922665 0.458282
+v -0.162975 -0.92219 0.460709
+v -0.156937 -0.919364 0.482264
+v -0.144169 -0.91989 0.485462
+v -0.12923 -0.916255 0.485449
+v -0.121806 -0.969769 0.57818
+v -0.11054 -0.914084 0.510318
+v -0.0936743 -0.965761 0.580762
+v -0.107483 -0.967251 0.579092
+v -0.097104 -0.91348 0.512553
+v -0.0814841 -0.967315 0.584692
+v -0.0704243 -0.912273 0.516998
+v -0.0303213 -0.910462 0.523664
+v -0.0169494 -0.909858 0.525886
+v -0.0687031 -0.967855 0.587878
+v -0.0570524 -0.911669 0.51922
+v 0.0237188 -0.906981 0.531731
+v 0.0440016 -0.90946 0.515084
+v 0.0712978 -0.907199 0.518706
+v 0.0921457 -0.908625 0.501211
+v 0.105518 -0.908021 0.503433
+v 0.139738 -0.908856 0.488147
+v 0.152596 -0.909306 0.491191
+v 0.166481 -0.907649 0.492579
+v 0.187355 -0.909087 0.475058
+v 0.200714 -0.908497 0.477254
+v 0.214651 -0.906827 0.478641
+v 0.235512 -0.908278 0.461095
+v 0.248884 -0.907674 0.463304
+v 0.262256 -0.907084 0.465514
+v 0.283759 -0.907482 0.447119
+v 0.331685 -0.931477 0.455212
+v 0.148858 -0.96526 0.540209
+v 0.0579259 -0.907803 0.516484
+v -0.0559734 -0.968394 0.591102
+v -0.0832311 -0.911811 0.51394
+v -0.407922 -0.953686 0.138626
+v -0.458918 -0.98404 0.178575
+v -0.428115 -0.966955 0.146449
+v -0.46719 -0.983552 0.19941
+v -0.475205 -0.991233 0.250329
+v -0.477569 -0.987084 0.223315
+v -0.463028 -0.985555 0.293451
+v -0.469117 -0.988381 0.271896
+v -0.457453 -0.983731 0.315763
+v -0.439149 -0.982485 0.341261
+v -0.452379 -0.982948 0.338833
+v -0.420266 -0.98025 0.365924
+v -0.433021 -0.979698 0.362751
+v -0.407523 -0.980803 0.369084
+v -0.381576 -0.980918 0.374595
+v -0.346791 -0.980366 0.358731
+v -0.368281 -0.980443 0.377048
+v -0.333509 -0.979916 0.36112
+v -0.306418 -0.978015 0.365115
+v -0.321845 -0.982485 0.365796
+v -0.275397 -0.959865 0.332924
+v -0.247163 -0.963513 0.295866
+v -0.254652 -0.961471 0.315596
+v -0.243309 -0.963963 0.250869
+v -0.257696 -0.949781 0.188877
+v -0.24241 -0.953917 0.218884
+v -0.24715 -0.954457 0.195236
+v -0.276386 -0.951965 0.163867
+v -0.265814 -0.956654 0.170264
+v -0.287497 -0.948343 0.158344
+v -0.310169 -0.957925 0.139166
+v -0.297863 -0.959428 0.143071
+v -0.334652 -0.954881 0.131459
+v -0.322411 -0.956409 0.135312
+v -0.360844 -0.955022 0.126244
+v -0.346894 -0.953365 0.127592
+v -0.388744 -0.958323 0.123533
+v -0.374228 -0.955613 0.12406
+v -0.394254 -0.980366 0.37146
+v -0.24855 -0.957681 0.267259
+v 0.367279 -0.961702 0.0687223
+v 0.33744 -0.952145 0.0779067
+v 0.353329 -0.963333 0.0673993
+v 0.317568 -0.94833 0.0942716
+v 0.279482 -0.978259 0.137496
+v 0.296206 -0.963654 0.103867
+v 0.282475 -0.980841 0.163803
+v 0.292455 -0.978619 0.210509
+v 0.31225 -0.97429 0.233951
+v 0.300008 -0.972787 0.230136
+v 0.333252 -0.967855 0.255737
+v 0.32042 -0.967392 0.252693
+v 0.345995 -0.968317 0.25873
+v 0.36358 -0.968214 0.285525
+v 0.351274 -0.966686 0.281646
+v 0.37577 -0.96973 0.289417
+v 0.400304 -0.972749 0.297112
+v 0.386894 -0.97334 0.294941
+v 0.427074 -0.971567 0.301505
+v 0.459868 -0.950912 0.266193
+v 0.440985 -0.969923 0.302866
+v 0.491801 -0.948214 0.223482
+v 0.481936 -0.950308 0.246758
+v 0.502771 -0.951965 0.158858
+v 0.484762 -0.953339 0.132589
+v 0.494769 -0.959068 0.13986
+v 0.467896 -0.95262 0.104625
+v 0.479033 -0.956255 0.1102
+v 0.45735 -0.947944 0.0982537
+v 0.437068 -0.953545 0.0753377
+v 0.447639 -0.958208 0.0817603
+v 0.425391 -0.950976 0.0706491
+v 0.381807 -0.959017 0.0692105
+v 0.286033 -0.98237 0.18925
+v 0.413651 -0.972171 0.29927
+v 0.502168 -0.945041 0.19932
+v 0.506895 -0.952415 0.183572
+v 0.396335 -0.956332 0.0696857
+v 0.41315 -0.949447 0.0667955
+v -0.31681 -0.977553 -0.0308544
+v -0.32146 -0.978195 -0.054798
+v -0.293252 -0.950295 -0.0745413
+v -0.272661 -0.920173 -0.0741302
+v -0.262115 -0.924849 -0.0677333
+v -0.256334 -0.922074 -0.0454467
+v -0.243502 -0.922536 -0.0424152
+v -0.239443 -0.922922 -0.0176237
+v -0.226572 -0.923384 -0.0145794
+v -0.221922 -0.922806 0.00914585
+v -0.209667 -0.924335 0.0129994
+v -0.195679 -0.922691 0.0143354
+v -0.192146 -0.924219 0.0397562
+v -0.179288 -0.924682 0.0428134
+v -0.175178 -0.92517 0.0673607
+v -0.161767 -0.924579 0.0695444
+v -0.158222 -0.926133 0.0949396
+v -0.145351 -0.926583 0.0979582
+v -0.140662 -0.92603 0.121709
+v -0.128716 -0.928587 0.196122
+v -0.172981 -0.978285 0.208646
+v -0.176604 -0.976718 0.183277
+v -0.125107 -0.930141 0.221479
+v -0.15442 -0.960276 0.242609
+v -0.166507 -0.974534 0.229802
+v -0.181909 -0.978324 0.160438
+v -0.196385 -0.981021 0.159962
+v -0.201138 -0.981573 0.136301
+v -0.213958 -0.981111 0.133283
+v -0.218132 -0.98061 0.108697
+v -0.232082 -0.982254 0.1074
+v -0.236244 -0.981753 0.082865
+v -0.249642 -0.982344 0.0806428
+v -0.262988 -0.982935 0.0784719
+v -0.267176 -0.982434 0.0539246
+v -0.280522 -0.983025 0.0517794
+v -0.282436 -0.978324 0.0238409
+v -0.296347 -0.979955 0.0225178
+v -0.297067 -0.973198 -0.00728328
+v -0.313817 -0.980083 -0.00440594
+v -0.132904 -0.928086 0.171626
+v -0.137066 -0.927585 0.147092
+v -0.96948 0.285294 0.25381
+v -0.967758 0.285089 0.240991
+v -0.975298 0.26767 0.241081
+v -0.903378 0.00303149 0.255609
+v -0.926409 0.0219269 0.255275
+v -0.90691 0.00385359 0.242494
+v -0.91201 -0.0659092 0.204292
+v -0.904264 -0.0487993 0.204189
+v -0.904444 -0.048825 0.191408
+v -0.912074 -0.0659478 0.191485
+v -0.19004 -0.758386 -0.151934
+v -0.196514 -0.75768 -0.139847
+v -0.193457 -0.739902 -0.140258
+v -0.922646 0.408288 0.176417
+v -0.930533 0.40848 0.189853
+v -0.923802 0.425912 0.175814
+v -0.231684 -0.0572772 -0.242892
+v -0.231697 -0.0388442 -0.239963
+v -0.218826 -0.0571744 -0.244433
+v -0.205416 -0.220759 -0.289559
+v -0.218248 -0.220926 -0.288043
+v -0.205531 -0.202455 -0.286669
+v -0.888901 -0.0132307 0.152808
+v -0.887899 -0.0147336 0.139898
+v -0.890712 -0.0321132 0.140014
+v -0.898419 -0.0492489 0.152936
+v -0.896724 -0.0494544 0.140129
+v -0.9042 -0.0666157 0.140283
+v -0.900783 0.495828 0.125704
+v -0.89034 0.49588 0.112358
+v -0.890507 0.478397 0.112409
+v -0.903802 0.478423 0.125845
+v -0.00767507 0.22514 0.0800262
+v 0.00830448 0.230368 0.0858965
+v 0.0138408 0.229109 0.0692875
+v 0.0307581 0.234748 0.0755946
+v 0.0244767 0.228094 0.0534236
+v -0.0131985 0.226463 0.0966095
+v 0.00366733 0.232474 0.102788
+v 0.0451576 0.245217 0.136597
+v 0.0382083 0.244086 0.152666
+v 0.0544191 0.248634 0.158537
+v 0.0320169 0.243971 0.168941
+v 0.0259282 0.24347 0.185293
+v 0.0412784 0.247156 0.190894
+v 0.0605078 0.249006 0.142223
+v 0.066635 0.249237 0.125948
+v 0.0512463 0.245538 0.120296
+v 0.0490883 0.249135 0.17512
+v -0.019467 0.226642 0.112962
+v -0.00338474 0.231575 0.118845
+v 0.0728264 0.249327 0.109686
+v -0.0256199 0.226283 0.129352
+v -0.00948625 0.231203 0.135235
+v -0.0325821 0.225101 0.14546
+v -0.0155621 0.230573 0.151587
+v -0.0378872 0.22573 0.162121
+v -0.0224728 0.229327 0.167721
+v -0.0447851 0.224292 0.178254
+v -0.0286001 0.228852 0.184124
+v -0.0524666 0.221543 0.194311
+v -0.036243 0.226052 0.200117
+v 0.0933018 0.242018 0.0430189
+v 0.0892299 0.245705 0.060116
+v 0.109397 0.246758 0.0490177
+v 0.0684719 0.24302 0.0709831
+v 0.0628842 0.244613 0.0874508
+v 0.0844899 0.248081 0.0769048
+v -0.66416 0.775509 -0.402854
+v -0.670338 0.774854 -0.386926
+v -0.65405 0.768226 -0.399219
+v -0.824764 0.572194 0.30487
+v -0.834668 0.565848 0.320709
+v -0.818689 0.570973 0.326129
+v -0.647885 0.768573 -0.415327
+v -0.657865 0.775933 -0.419039
+v -0.402488 0.326412 0.254491
+v -0.397517 0.32392 0.237278
+v -0.399893 0.326142 0.243084
+v -0.660447 0.767596 -0.383175
+v 0.0566285 0.24478 0.1037
+v -0.794244 0.584281 0.24013
+v -0.801206 0.582791 0.256546
+v -0.785625 0.58599 0.261864
+v 0.0790307 0.249186 0.0934495
+v -0.0606362 0.216854 0.210188
+v -0.0445796 0.221825 0.215981
+v -0.966898 0.0749523 0.152281
+v -0.972986 0.092332 0.152165
+v -0.968632 0.0921779 0.139282
+v -0.0696665 0.211318 0.225769
+v -0.0526978 0.217073 0.231703
+v -0.0785426 0.205345 0.241312
+v -0.0623318 0.209982 0.247028
+v -0.0891399 0.197612 0.256623
+v -0.0728007 0.201838 0.26225
+v -0.099429 0.188929 0.271755
+v -0.0848625 0.191382 0.277266
+v -0.109782 0.180451 0.286938
+v -0.0957296 0.181337 0.292051
+v -0.121639 0.169532 0.301762
+v -0.107534 0.172782 0.306579
+v -0.915838 -0.134824 0.307067
+v -0.910455 -0.117586 0.307195
+v -0.915735 -0.117624 0.294119
+v -0.235114 -0.303098 -0.294697
+v -0.243309 -0.294864 -0.289816
+v -0.231016 -0.294427 -0.29575
+v -0.763698 0.583575 0.157124
+v -0.769992 0.583755 0.17363
+v -0.748939 0.585951 0.162287
+v -0.677095 0.773197 -0.371036
+v -0.667165 0.766042 -0.367311
+v -0.0664551 -0.915356 0.711617
+v -0.0798271 -0.915895 0.714173
+v -0.0795317 -0.933956 0.715393
+v -0.691636 0.58369 0.089095
+v -0.67829 0.582765 0.0939248
+v -0.672766 0.581532 0.0771874
+v 0.176475 0.259192 0.0555559
+v 0.191915 0.262314 0.0613363
+v 0.196488 0.258486 0.0436997
+v -0.842196 -0.453092 0.129301
+v -0.844084 -0.453259 0.116455
+v -0.83427 -0.471063 0.116558
+v -0.919588 -0.291383 0.128646
+v -0.919563 -0.291473 0.115813
+v -0.912164 -0.309032 0.115813
+v 0.478584 -0.226565 -0.287863
+v 0.490055 -0.23056 -0.283419
+v 0.476952 -0.242815 -0.296508
+v -0.562695 -0.856653 0.573799
+v -0.551494 -0.85664 0.58089
+v -0.555977 -0.840211 0.566542
+v -0.924816 -0.204626 0.14099
+v -0.925228 -0.204574 0.15372
+v -0.928053 -0.187105 0.14081
+v -0.794128 0.582316 0.277869
+v -0.80971 0.578783 0.272513
+v -0.801746 0.57922 0.29408
+v -0.465122 0.537357 0.245756
+v -0.469708 0.540068 0.262622
+v -0.463028 0.526863 0.265435
+v 0.986243 -0.525899 0.188659
+v 0.985125 -0.525771 0.175711
+v 0.978304 -0.513388 0.180528
+v -0.702619 0.863165 -0.583189
+v -0.692728 0.855664 -0.579593
+v -0.68416 0.860802 -0.595187
+v -0.96271 0.0746954 0.139397
+v -0.758945 0.581481 0.140065
+v -0.743338 0.584358 0.145576
+v -0.131979 0.160913 0.316996
+v -0.116603 0.164779 0.322571
+v -0.868092 -0.415879 0.180528
+v -0.884996 -0.397318 0.180425
+v -0.883557 -0.397575 0.167593
+v -0.14449 0.148838 0.331756
+v -0.127637 0.154786 0.337562
+v -0.153508 0.143058 0.34744
+v -0.1402 0.142583 0.352308
+v -0.163912 0.135633 0.363252
+v -0.150695 0.134567 0.367838
+v -0.847308 -0.435481 0.167747
+v -0.846691 -0.434993 0.180605
+v -0.868015 -0.415918 0.167644
+v -0.31803 0.767892 0.0363393
+v -0.332571 0.766286 0.0310471
+v -0.331903 0.7524 0.0499168
+v -0.925626 0.337061 0.12519
+v -0.922864 0.336984 0.112332
+v -0.935632 0.319308 0.112473
+v 0.0731861 0.240721 0.0541558
+v -0.933898 -0.256032 0.205332
+v -0.934707 -0.25593 0.192512
+v -0.929916 -0.273232 0.192628
+v -0.174484 0.127374 0.378795
+v -0.161061 0.125987 0.38315
+v -0.0610987 0.180566 0.323355
+v -0.0724025 0.171266 0.338422
+v -0.0568597 0.174465 0.343881
+v -0.660036 0.420157 -0.131973
+v -0.644802 0.428994 -0.151703
+v -0.634461 0.427954 -0.144214
+v -0.173623 0.114567 0.398667
+v -0.710608 0.473709 -0.286861
+v -0.698354 0.468365 -0.288929
+v -0.713242 0.474814 -0.273926
+v -0.0109635 0.671565 -0.179282
+v 0.000982665 0.668778 -0.174388
+v -0.0100001 0.656806 -0.160785
+v -0.491146 0.566118 0.234504
+v -0.501487 0.573684 0.23196
+v -0.496529 0.56807 0.252307
+v -0.877083 -0.0157612 0.0886326
+v -0.870815 -0.0158254 0.0758515
+v -0.876518 -0.0332308 0.0760185
+v -0.635579 0.513979 -0.438384
+v -0.642528 0.512065 -0.450806
+v -0.626228 0.527274 -0.450433
+v -0.545726 -0.840224 0.574403
+v -0.53405 -0.824334 0.562277
+v -0.545276 -0.824154 0.555418
+v -0.679214 0.584063 0.056044
+v -0.667268 0.580376 0.0604243
+v -0.661681 0.579618 0.0437511
+v -0.929055 -0.204227 0.179449
+v -0.930712 -0.204099 0.192281
+v -0.931149 -0.186758 0.17932
+v -0.919537 -0.13458 0.294491
+v -0.444081 0.314774 0.390754
+v -0.449618 0.30514 0.408802
+v -0.441743 0.304973 0.397549
+v 0.0323766 0.234851 0.281042
+v 0.0235647 0.228813 0.296508
+v 0.0389148 0.232474 0.302109
+v -0.950623 0.355828 0.266296
+v -0.950379 0.355802 0.253515
+v -0.95043 0.338075 0.253566
+v -0.878278 -0.379733 0.282776
+v -0.88339 -0.362302 0.282841
+v -0.883044 -0.379553 0.26997
+v -0.9042 -0.100566 0.307054
+v -0.908644 -0.100463 0.294183
+v 0.147188 0.262596 0.266424
+v 0.132403 0.260695 0.261094
+v 0.139596 0.259873 0.282314
+v -0.439084 -0.751668 0.284716
+v -0.439406 -0.733685 0.284536
+v -0.436002 -0.734057 0.271781
+v -0.479663 0.541249 0.333528
+v -0.487498 0.552785 0.330432
+v -0.484801 0.543523 0.350291
+v -0.493073 0.553928 0.347054
+v -0.498571 0.55502 0.363715
+v -0.490568 0.543574 0.366875
+v -0.533857 0.563819 0.388185
+v -0.541449 0.560903 0.404216
+v -0.529258 0.557255 0.40902
+v -0.883159 0.425141 0.112114
+v -0.891483 0.425385 0.124561
+v -0.883493 0.442932 0.111883
+v -0.526985 0.565386 0.371961
+v -0.522219 0.559477 0.392501
+v -0.867835 -0.415854 0.154812
+v -0.881798 -0.397639 0.154747
+v -0.897186 0.44324 0.124908
+v -0.903956 0.461108 0.125704
+v -0.887783 0.460748 0.112139
+v 0.413972 -0.964348 0.0566735
+v -0.899537 0.00380221 0.140065
+v 0.0233078 0.970334 -0.277805
+v 0.0153437 0.984297 -0.280451
+v 0.0174503 0.970437 -0.261787
+v -0.81522 -0.491089 0.2446
+v -0.819113 -0.489226 0.232333
+v -0.810981 -0.502033 0.230188
+v -0.463311 -0.696048 0.181864
+v -0.474114 -0.695136 0.169006
+v -0.471198 -0.700711 0.170277
+v -0.540061 -0.813159 0.413773
+v -0.506111 -0.798528 0.413657
+v -0.5308 -0.814135 0.400953
+v -0.896313 -0.0836614 0.306861
+v -0.900796 -0.08361 0.294003
+v -0.606549 0.769947 -0.567364
+v -0.613446 0.783949 -0.569638
+v -0.611764 0.772131 -0.550408
+v -0.393805 0.66942 0.102917
+v -0.39374 0.688431 0.0894675
+v -0.408641 0.675727 0.0968022
+v -0.608629 0.842061 -0.660505
+v -0.602271 0.827944 -0.658296
+v -0.595437 0.829575 -0.674417
+v -0.71933 0.590331 0.172679
+v -0.724867 0.59141 0.18943
+v -0.7052 0.590755 0.177702
+v -0.716427 0.773878 -0.348609
+v -0.726755 0.765618 -0.333926
+v -0.712676 0.766582 -0.328583
+v -0.73802 0.840031 -0.52256
+v -0.748168 0.831849 -0.508044
+v -0.735618 0.829999 -0.50315
+v -0.727012 0.836871 -0.51764
+v -0.928156 0.0228775 0.165653
+v -0.948991 0.04027 0.165435
+v -0.943648 0.0396277 0.152435
+v -0.755002 0.800506 -0.45534
+v -0.766228 0.788766 -0.441583
+v -0.750596 0.794289 -0.435199
+v -0.630428 0.629265 -0.13187
+v -0.6373 0.627634 -0.115826
+v -0.621989 0.618951 -0.128736
+v -0.64407 0.626157 -0.0996795
+v -0.636221 0.614583 -0.0967379
+v -0.628681 0.617538 -0.112602
+v -0.734976 0.747519 -0.299604
+v -0.746254 0.735535 -0.285872
+v -0.730352 0.741071 -0.279488
+v -0.718521 0.751912 -0.293785
+v -0.691803 0.767738 -0.339681
+v -0.70371 0.771283 -0.344061
+v -0.699895 0.764437 -0.323894
+v -0.466381 0.656228 0.0952222
+v -0.481769 0.652965 0.085524
+v -0.48263 0.63782 0.108902
+v 0.0860314 0.256521 0.170085
+v 0.0798913 0.256277 0.18636
+v 0.0945992 0.258332 0.191716
+v -0.722503 0.759504 -0.313644
+v -0.708746 0.758142 -0.309006
+v -0.149847 0.0833274 0.43579
+v -0.162243 0.094824 0.421788
+v -0.162628 0.0830448 0.435494
+v 0.100714 0.258781 0.175467
+v -0.044464 0.186963 0.329392
+v 0.00704565 0.192268 0.366605
+v -0.00908805 0.187477 0.360799
+v -0.00523446 0.179526 0.380889
+v -0.021792 0.17548 0.375442
+v -0.0835522 0.161825 0.353593
+v -0.0679709 0.164959 0.359
+v -0.742246 0.727789 -0.265846
+v -0.121716 0.188479 0.0380735
+v -0.136411 0.186218 0.0327041
+v -0.141998 0.188492 0.0492103
+v -0.654898 0.525835 -0.541172
+v -0.665303 0.527055 -0.548597
+v -0.642464 0.536599 -0.556934
+v -0.727423 0.581134 0.0573928
+v -0.735194 0.578604 0.0735393
+v -0.719073 0.583305 0.0792426
+v -0.936891 -0.238499 0.205281
+v -0.740808 0.580004 0.0902896
+v -0.747115 0.580158 0.106783
+v -0.732355 0.582611 0.111998
+v -0.953205 0.373503 0.253412
+v -0.95946 0.391114 0.253296
+v -0.959203 0.391075 0.240528
+v -0.951201 0.373027 0.239899
+v -0.9163 0.537011 0.198588
+v -0.924071 0.530755 0.188774
+v -0.929698 0.530549 0.201607
+v -0.164709 0.899428 -0.0916512
+v -0.183001 0.88955 -0.0986005
+v -0.176244 0.88946 -0.0773158
+v -0.886114 -0.0664744 0.306926
+v -0.890866 -0.0662817 0.294183
+v -0.639137 0.907559 -0.72775
+v -0.644776 0.908728 -0.711
+v -0.627936 0.902999 -0.723537
+v -0.886871 -0.344858 0.282841
+v -0.887591 -0.361955 0.26988
+v 0.968568 -0.525437 0.27146
+v 0.964264 -0.53281 0.287696
+v 0.975735 -0.54992 0.281787
+v -0.141677 -0.0918567 -0.280246
+v -0.14169 -0.0736935 -0.275249
+v -0.128909 -0.0734879 -0.277035
+v -0.128755 -0.11011 -0.283534
+v -0.141549 -0.110315 -0.281466
+v -0.128845 -0.0916897 -0.282006
+v -0.898137 -0.0314324 0.204137
+v -0.89725 -0.0315609 0.191279
+v -0.93323 0.426233 0.189044
+v -0.937084 0.443651 0.188518
+v -0.93377 0.443651 0.175891
+v -0.986487 0.179346 0.190187
+v -0.984932 0.196918 0.19011
+v -0.983661 0.17923 0.177316
+v -0.205467 -0.184381 -0.282725
+v -0.218312 -0.184523 -0.281235
+v -0.205557 -0.166167 -0.278178
+v -0.218338 -0.202635 -0.284947
+v -0.907167 -0.0664487 0.153077
+v -0.911894 -0.0836614 0.140348
+v -0.894758 0.513067 0.125267
+v -0.885831 0.513195 0.112139
+v -0.507601 0.576613 0.2111
+v -0.518802 0.581404 0.207002
+v -0.513497 0.577011 0.227619
+v -0.250901 0.846723 -0.0680672
+v -0.270824 0.834932 -0.0752734
+v -0.260149 0.840095 -0.0529098
+v 0.0130829 0.220836 0.311691
+v 0.0292937 0.225461 0.317356
+v 0.0479451 0.238088 0.286591
+v 0.122974 0.251858 0.313631
+v 0.109089 0.250239 0.308467
+v 0.114188 0.245474 0.329019
+v 0.124773 0.257998 0.27697
+v 0.117207 0.255133 0.29286
+v 0.131285 0.256007 0.297921
+v -0.842838 -0.453632 0.103546
+v -0.857546 -0.434479 0.10343
+v -0.855927 -0.434556 0.129211
+v -0.858779 -0.4343 0.116391
+v -0.726562 0.733197 -0.259616
+v -0.73933 0.719054 -0.246142
+v -0.722503 0.724937 -0.240027
+v -0.87779 -0.0491718 0.307157
+v -0.883378 -0.0490947 0.294119
+v -0.743197 0.894174 -0.635457
+v -0.752612 0.886762 -0.62071
+v -0.737481 0.891284 -0.614069
+v -0.693087 0.7468 -0.284819
+v -0.704956 0.750461 -0.289135
+v -0.701848 0.741443 -0.269494
+v -0.727526 0.898747 -0.628739
+v -0.60466 0.647326 -0.215159
+v -0.61116 0.646838 -0.199038
+v -0.59712 0.635547 -0.21241
+v -0.624982 0.643562 -0.167079
+v -0.617043 0.631334 -0.16406
+v -0.610492 0.632657 -0.180194
+v -0.96578 0.284562 0.189712
+v -0.954695 0.302301 0.189558
+v -0.962261 0.284793 0.176764
+v -0.743081 0.564744 0.408814
+v -0.757378 0.564923 0.404229
+v -0.753075 0.558616 0.425
+v -0.752625 0.581147 0.123559
+v -0.737879 0.583536 0.128787
+v -0.959062 0.302725 0.253733
+v -0.950995 0.32049 0.253618
+v -0.950918 0.3204 0.240772
+v -0.754475 0.586992 0.179063
+v -0.619728 0.782818 -0.553273
+v -0.625816 0.783422 -0.536728
+v -0.617621 0.772169 -0.533851
+v -0.165659 0.897026 -0.134734
+v -0.154831 0.907276 -0.106462
+v -0.144837 0.915138 -0.121157
+v -0.624789 0.539618 -0.472617
+v -0.630788 0.536933 -0.486349
+v -0.616491 0.553748 -0.482379
+v -0.345866 0.752246 0.0449457
+v -0.360497 0.735535 0.0584846
+v -0.346341 0.735072 0.0626851
+v -0.422501 -0.959261 -0.142364
+v -0.404698 -0.979544 -0.164818
+v -0.427395 -0.981047 -0.144304
+v -0.704738 0.889216 -0.621109
+v -0.694834 0.881855 -0.617461
+v -0.685457 0.888265 -0.632772
+v -0.0233078 0.955973 -0.192101
+v -0.0174375 0.974136 -0.203791
+v -0.0248749 0.975369 -0.193861
+v -0.0791848 -0.91813 -0.132332
+v -0.092621 -0.918696 -0.134503
+v -0.0832568 -0.917886 -0.157304
+v -0.613536 0.59317 -0.106937
+v -0.606998 0.578873 -0.104471
+v -0.600537 0.579272 -0.120784
+v -0.00460504 0.221954 0.0624025
+v 0.00934495 0.22496 0.057046
+v -0.891303 -0.345372 0.115967
+v -0.892331 -0.345038 0.128838
+v -0.900783 -0.327491 0.115813
+v -0.0285358 0.222853 0.0909704
+v -0.0237445 0.220284 0.0741174
+v -0.0356393 0.222082 0.107053
+v -0.624352 0.566195 -0.0362623
+v -0.62967 0.568058 -0.0193836
+v -0.621051 0.557974 -0.0160566
+v 0.0730576 0.254684 0.202378
+v 0.0877655 0.256944 0.207747
+v -0.0324536 0.164908 0.390163
+v -0.0177586 0.167246 0.39552
+v -0.443811 -0.751116 0.29751
+v -0.0489984 -0.428134 0.720775
+v -0.0576561 -0.409136 0.728521
+v -0.0602766 -0.428237 0.713826
+v -0.0409829 0.222712 0.123713
+v -0.947026 0.514506 0.214067
+v -0.93937 0.524037 0.209725
+v -0.94524 0.514249 0.201337
+v 0.143899 0.265589 0.154336
+v 0.137027 0.264446 0.170277
+v 0.152557 0.267234 0.175955
+v 0.00283239 0.212127 0.326669
+v 0.0173219 0.214928 0.332218
+v -0.51238 0.58229 0.190637
+v -0.524493 0.5845 0.18618
+v -0.684365 0.770718 -0.355288
+v -0.673306 0.765567 -0.351203
+v -0.680602 0.762934 -0.335506
+v -0.890969 -0.379733 0.15467
+v -0.892472 -0.379527 0.167554
+v -0.894951 -0.36198 0.154645
+v -0.688617 0.758977 -0.319976
+v -0.299867 0.812311 -0.0305461
+v -0.294215 0.806659 -0.0104047
+v -0.282462 0.818875 -0.0242905
+v -0.926062 -0.221928 0.153938
+v -0.923558 -0.222121 0.141041
+v -0.926641 -0.239424 0.141067
+v -0.562887 0.576291 0.359065
+v -0.574885 0.579785 0.354749
+v -0.569862 0.573928 0.375237
+v -0.861733 -0.41859 0.261004
+v -0.865137 -0.408493 0.274221
+v -0.870815 -0.410767 0.252346
+v -0.740885 0.783024 -0.394659
+v -0.756183 0.779388 -0.400542
+v -0.751906 0.77348 -0.380247
+v -0.474203 0.5436 0.279642
+v -0.467781 0.529406 0.282327
+v -0.1988 0.211845 0.197702
+v -0.187843 0.20609 0.201735
+v -0.182512 0.205191 0.184767
+v -0.634179 0.902665 -0.707082
+v -0.597313 0.579606 -0.129185
+v -0.601089 0.593633 -0.13959
+v -0.607101 0.593543 -0.123186
+v -0.582605 0.57597 0.370677
+v -0.760923 0.817873 -0.494711
+v -0.744892 0.822317 -0.488738
+v -0.18828 0.208556 0.163739
+v -0.193791 0.209944 0.180618
+v -0.177027 0.204035 0.167939
+v -0.0479194 0.221427 0.139872
+v -0.0540594 0.221132 0.15625
+v -0.060238 0.220836 0.172679
+v -0.589323 0.540055 -0.11616
+v -0.593819 0.559682 -0.116353
+v -0.594744 0.549034 -0.0998979
+v -0.0253502 0.182891 0.35516
+v -0.0370009 0.171857 0.369996
+v -0.636696 0.767237 -0.448044
+v -0.64633 0.775034 -0.451641
+v -0.642117 0.76838 -0.431615
+v -0.651931 0.775933 -0.43525
+v 0.10011 0.244767 0.323958
+v 0.104439 0.238845 0.344421
+v 0.0896794 0.236713 0.339077
+v 0.226842 0.264639 0.0560569
+v 0.240766 0.266155 0.0611436
+v 0.244851 0.262147 0.0442521
+v -0.834642 -0.471204 0.129365
+v -0.67608 0.625926 -0.0557357
+v -0.685213 0.6208 -0.0400388
+v -0.666754 0.617319 -0.0522033
+v -0.663325 0.758386 -0.347491
+v -0.656632 0.759787 -0.363406
+v -0.714822 0.74409 -0.273798
+v -0.711482 0.734828 -0.254414
+v 0.249244 0.275493 0.13801
+v 0.263284 0.276071 0.143161
+v 0.268692 0.274915 0.126847
+v -0.631764 0.641995 -0.150984
+v -0.623646 0.63073 -0.147978
+v -0.491211 0.560556 0.310265
+v -0.501346 0.56721 0.306335
+v -0.49667 0.561751 0.326926
+v -0.762953 0.87867 -0.605951
+v -0.749054 0.882035 -0.599965
+v -0.355307 0.707262 0.0818117
+v -0.374845 0.718155 0.0712786
+v -0.367934 0.707082 0.0816062
+v -0.927964 -0.117367 0.204626
+v -0.924149 -0.100078 0.20451
+v -0.926563 -0.117483 0.191767
+v -0.517505 0.587223 0.170097
+v -0.874604 -0.0319591 0.307003
+v -0.879871 -0.0317407 0.293862
+v -0.935041 -0.151716 0.204793
+v -0.932074 -0.134529 0.204741
+v -0.934913 -0.151819 0.192012
+v -0.978664 0.0757487 0.254953
+v -0.985677 0.0933211 0.254864
+v -0.984663 0.0930899 0.242005
+v -0.00838156 0.138254 0.446554
+v 0.00466927 0.155184 0.429906
+v -0.0083944 0.155223 0.420414
+v -0.978561 0.075723 0.242134
+v -0.890006 -0.344755 0.269995
+v -0.686305 0.464936 -0.287259
+v -0.980385 0.092743 0.203482
+v -0.985922 0.110251 0.203457
+v -0.982993 0.110097 0.190611
+v -0.919087 -0.291241 0.205512
+v -0.923339 -0.291036 0.192692
+v -0.912459 -0.30866 0.192718
+v -0.97219 0.267272 0.189751
+v -0.970366 0.267028 0.176957
+v -0.973783 0.249636 0.176944
+v -0.976442 0.249674 0.189841
+v 0.115293 0.255056 0.0882986
+v 0.109859 0.256238 0.104792
+v 0.13072 0.258486 0.0940276
+v -0.896929 -0.344562 0.167361
+v -0.902299 -0.327131 0.167169
+v -0.900513 -0.327208 0.154362
+v -0.876146 -0.0144895 0.306861
+v -0.880641 -0.0143225 0.29399
+v 0.103668 0.25611 0.121028
+v 0.119943 0.26013 0.127027
+v 0.124503 0.258499 0.110225
+v -0.154189 -0.183521 -0.291229
+v -0.16706 -0.183752 -0.288056
+v -0.154137 -0.165499 -0.28609
+v -0.651661 0.623177 -0.0839055
+v -0.643286 0.612849 -0.0808098
+v -0.65572 0.45665 -0.264485
+v -0.672535 0.449329 -0.242339
+v -0.664404 0.456304 -0.274427
+v -0.248974 0.139744 0.390086
+v -0.259032 0.146758 0.385937
+v -0.252506 0.135621 0.395789
+v 0.0654661 0.252076 0.218177
+v 0.0809703 0.255249 0.223752
+v 0.140881 0.255069 0.0607326
+v 0.157104 0.259051 0.0668726
+v 0.161061 0.255724 0.0497755
+v -0.896416 -0.361762 0.167503
+v -0.895696 -0.344806 0.154503
+v 0.161164 0.26907 0.197548
+v 0.154381 0.267375 0.213502
+v 0.168357 0.268428 0.218601
+v 0.171722 0.261556 0.0723062
+v 0.167047 0.263547 0.0890308
+v 0.187175 0.264639 0.0780866
+v -0.41324 0.463869 0.143366
+v -0.408872 0.482855 0.15011
+v -0.420664 0.464255 0.155711
+v -0.0678424 0.21792 0.188762
+v -0.0761277 0.213553 0.204613
+v -0.0851194 0.207875 0.220245
+v -0.148511 0.124497 0.388031
+v -0.161086 0.112409 0.403124
+v -0.541911 0.583922 0.273117
+v -0.529901 0.580633 0.277497
+v -0.524377 0.579631 0.260875
+v -0.687782 0.532283 -0.559259
+v -0.672368 0.539875 -0.580286
+v -0.676555 0.529239 -0.554609
+v -0.0112717 0.197561 0.340914
+v 0.00478487 0.202596 0.346733
+v -0.970456 0.0588315 0.254979
+v -0.704211 0.453362 -0.235814
+v -0.720936 0.475006 -0.248235
+v -0.705547 0.461287 -0.254632
+v -0.603812 0.634108 -0.196315
+v -0.688887 0.912838 -0.671013
+v -0.69766 0.907353 -0.655406
+v -0.686446 0.90147 -0.651578
+v -0.67748 0.907418 -0.666787
+v 0.125466 0.251588 0.0550164
+v 0.145698 0.252256 0.0440465
+v 0.116244 0.261646 0.181119
+v 0.109384 0.260348 0.197085
+v -0.930507 -0.23909 0.153977
+v 0.165916 0.25277 0.0331794
+v -0.433137 -0.878105 -0.118511
+v -0.433137 -0.860185 -0.110508
+v -0.420202 -0.859813 -0.115042
+v -0.937071 0.319385 0.125319
+v 0.120804 0.25372 0.0718566
+v 0.136128 0.257445 0.0775214
+v 0.0503343 0.246167 0.250072
+v 0.0413554 0.240464 0.265577
+v 0.0568469 0.243855 0.2711
+v -0.615797 0.556073 -0.0330124
+v 0.0658 0.249481 0.255609
+v -0.694115 -0.970141 0.00688508
+v -0.691636 -0.948201 0.00484268
+v -0.676979 -0.962511 -0.0340786
+v -0.261408 0.839145 -0.090341
+v -0.290567 0.821714 -0.0701353
+v -0.0940468 0.201979 0.235763
+v -0.10449 0.194298 0.251228
+v -0.113225 0.186861 0.267388
+v -0.125248 0.177137 0.281505
+v 0.260984 -0.175634 0.696549
+v 0.245146 -0.163238 0.686735
+v 0.248088 -0.175595 0.700891
+v -0.458789 0.523099 0.24839
+v -0.0481121 0.161954 0.384909
+v 0.424068 0.2381 0.110482
+v 0.419881 0.241492 0.127297
+v 0.435655 0.233797 0.114953
+v -0.192763 -0.184035 -0.283701
+v -0.192776 -0.166013 -0.27846
+v -0.179931 -0.165871 -0.280079
+v 0.078671 0.226822 0.353849
+v 0.0942652 0.230008 0.359283
+v 0.432045 0.230188 0.0769819
+v 0.428102 0.234234 0.0937193
+v 0.443362 0.225538 0.0811309
+v -0.966718 0.0937578 0.421981
+v -0.970263 0.110971 0.421724
+v -0.966936 0.110958 0.409046
+v 0.415655 0.244973 0.144124
+v 0.426907 0.240079 0.14826
+v 0.431069 0.23661 0.131459
+v 0.243874 0.276315 0.154362
+v -0.874065 -0.397562 0.270162
+v 0.254677 0.274337 0.121619
+v 0.257889 0.277137 0.159526
+v 0.237054 0.275352 0.170175
+v 0.251787 0.276983 0.175659
+v 0.0430767 0.173861 0.429996
+v 0.0448365 0.182429 0.417703
+v 0.0303213 0.173463 0.423407
+v -0.507306 0.567981 0.323008
+v -0.504107 0.584705 0.174079
+v 0.0840275 0.207503 0.39349
+v 0.0698977 0.206848 0.388467
+v 0.0714777 0.195428 0.408146
+v -0.767282 0.558013 0.420144
+v -0.777892 0.549779 0.435892
+v -0.765342 0.550305 0.440144
+v -0.683762 0.584307 0.110598
+v -0.689298 0.585579 0.127335
+v -0.67039 0.58378 0.115441
+v -0.609773 0.760583 -0.531089
+v -0.692496 0.593594 0.275583
+v -0.70592 0.593992 0.270856
+v -0.698739 0.593607 0.292076
+v -0.60466 0.759208 -0.547942
+v -0.850905 0.547325 0.373374
+v -0.868824 0.541172 0.366361
+v -0.863069 0.536343 0.38893
+v -0.0421133 0.688906 -0.192859
+v -0.0414197 0.69678 -0.199141
+v -0.0373092 0.679144 -0.185486
+v -0.567486 0.546118 0.45209
+v -0.578096 0.537756 0.467684
+v -0.55694 0.539772 0.455777
+v 0.0663524 0.693196 -0.206334
+v 0.0777076 0.70495 -0.227477
+v 0.0785811 0.705862 -0.22189
+v -0.127111 0.200399 0.110983
+v -0.132531 0.201222 0.127734
+v -0.112454 0.202686 0.11634
+v -0.573883 0.526477 0.476406
+v -0.586792 0.526336 0.480979
+v 0.134625 0.262545 0.132448
+v 0.140778 0.26234 0.116263
+v 0.409527 0.133771 0.459541
+v 0.415462 0.120887 0.467749
+v 0.421294 0.134349 0.454017
+v 0.0983372 0.256778 0.137599
+v 0.091375 0.255853 0.15354
+v 0.106828 0.259115 0.159205
+v 0.151632 0.260451 0.0832761
+v 0.112904 0.259501 0.142968
+v 0.0586195 0.250342 0.234337
+v 0.0733531 0.252474 0.23968
+v -0.973025 0.180566 0.459939
+v -0.969171 0.198177 0.459797
+v -0.971779 0.180515 0.447093
+v -0.970751 0.0585232 0.242198
+v 0.222102 0.267105 0.0727172
+v 0.236784 0.269289 0.0781893
+v 0.182024 0.271293 0.186758
+v 0.167291 0.269507 0.181363
+v 0.175203 0.26988 0.202673
+v -0.388859 0.306823 0.15336
+v -0.397928 0.326399 0.153347
+v -0.391403 0.314491 0.164112
+v -0.575835 0.740634 -0.681482
+v -0.576079 0.76084 -0.68152
+v -0.578186 0.760814 -0.668713
+v -0.135691 0.168672 0.296675
+v -0.112955 0.157214 0.342944
+v -0.125531 0.144946 0.357652
+v -0.146725 0.158896 0.311768
+v -0.29076 0.782998 0.0274632
+v -0.30426 0.76576 0.0424794
+v -0.291081 0.765015 0.0441236
+v -0.810391 0.575893 0.310163
+v -0.884045 0.00315994 0.306848
+v -0.887732 0.00287735 0.294183
+v -0.927398 -0.135055 0.153514
+v -0.925009 -0.135171 0.140617
+v -0.927886 -0.152384 0.140707
+v -0.154304 -0.128928 -0.279848
+v -0.167137 -0.129198 -0.276508
+v -0.154368 -0.110585 -0.278165
+v -0.929492 -0.15223 0.153514
+v -0.283926 -0.801675 -0.168389
+v -0.28778 -0.796306 -0.147169
+v -0.272841 -0.794276 -0.149519
+v 0.102525 0.25891 0.213091
+v 0.122345 0.262121 0.164869
+v -0.706421 0.901868 -0.63994
+v -0.6959 0.894791 -0.63642
+v 0.128421 0.262622 0.148633
+v -0.976789 0.0755817 0.203649
+v -0.978651 0.0927045 0.190688
+v -0.506753 0.575264 0.248621
+v -0.741527 0.588019 0.314658
+v -0.749889 0.583755 0.330625
+v -0.735079 0.585784 0.33575
+v -0.101767 0.166655 0.327761
+v -0.157181 0.150765 0.327144
+v -0.165518 0.146526 0.343136
+v -0.0913493 0.17494 0.312488
+v -0.776338 0.583947 0.190162
+v -0.760743 0.587133 0.195583
+v -0.409656 0.292295 0.346951
+v -0.403413 0.277959 0.349572
+v -0.396399 0.278525 0.333168
+v -0.598584 0.647506 -0.231472
+v -0.594179 0.640826 -0.231511
+v -0.592521 0.64766 -0.247747
+v -0.602078 0.730615 -0.472514
+v -0.609593 0.742445 -0.475237
+v -0.606317 0.73434 -0.45552
+v -0.509168 0.525398 0.414171
+v -0.509348 0.506953 0.41331
+v -0.502412 0.52518 0.401454
+v 0.388911 0.244176 0.299141
+v 0.377209 0.248287 0.294877
+v 0.381615 0.241646 0.314838
+v 0.438815 0.219834 0.0430831
+v 0.435552 0.225332 0.059949
+v 0.450568 0.216148 0.0475276
+v -0.61414 0.745901 -0.458307
+v -0.610993 0.736883 -0.43877
+v -0.160123 0.191665 0.0612849
+v -0.146109 0.192191 0.0665001
+v -0.932485 -0.186578 0.204998
+v -0.93508 -0.169057 0.204908
+v -0.935118 -0.169121 0.192101
+v -0.619227 0.747327 -0.441814
+v -0.624159 0.749639 -0.425102
+v -0.615887 0.738476 -0.422238
+v -0.933461 -0.203868 0.205139
+v -0.93237 -0.186642 0.192166
+v 0.230952 0.275108 0.186321
+v 0.245698 0.27679 0.191742
+v 0.239584 0.276662 0.20785
+v 0.224851 0.274722 0.202468
+v 0.0574249 0.194516 0.402983
+v 0.0590177 0.182968 0.422649
+v 0.218762 0.274543 0.218576
+v 0.232815 0.275275 0.223739
+v -0.99255 0.21503 0.254208
+v -0.990944 0.214928 0.241376
+v -0.993937 0.197355 0.241427
+v 0.108164 0.231254 0.364562
+v 0.0964489 0.219976 0.379078
+v -0.245968 -0.972453 0.463818
+v -0.236116 -0.969704 0.440889
+v -0.934617 0.0224664 0.191087
+v -0.935953 0.022749 0.203932
+v -0.954656 0.0406168 0.191087
+v -0.642965 0.0822099 -0.098729
+v -0.655669 0.0818245 -0.0933853
+v -0.642836 0.100592 -0.0944772
+v -0.99833 0.179886 0.254363
+v -0.99571 0.197509 0.254273
+v -0.995517 0.179783 0.241492
+v -0.919216 -0.0830834 0.204407
+v -0.919177 -0.0831091 0.191613
+v -0.934695 0.355275 0.189263
+v -0.933975 0.372848 0.189468
+v -0.929595 0.35507 0.176661
+v -0.93052 0.390677 0.189828
+v -0.925407 0.390202 0.176469
+v -0.928696 0.372873 0.176456
+v -0.838034 -0.453478 0.167837
+v -0.838213 -0.453632 0.155017
+v 0.191055 0.268903 0.116417
+v 0.205801 0.270779 0.121889
+v 0.211209 0.26979 0.105447
+v -0.832973 -0.471024 0.167939
+v 0.146186 0.261582 0.0997566
+v 0.197259 0.268582 0.100296
+v -0.931702 -0.256341 0.154105
+v -0.929004 -0.256585 0.141221
+v -0.979293 0.232102 0.189931
+v -0.977649 0.231999 0.177124
+v 0.181305 0.256097 0.0389855
+v -0.975298 0.0754918 0.190855
+v -0.890353 0.510947 0.405321
+v -0.870083 0.52667 0.402662
+v -0.876544 0.528378 0.391011
+v 0.161562 0.266797 0.234581
+v 0.753563 -0.0941047 0.0605913
+v 0.744777 -0.0760827 0.0604628
+v 0.746768 -0.0757487 0.073231
+v -0.113636 -0.92594 0.335853
+v -0.12169 -0.924951 0.356406
+v -0.126982 -0.926531 0.333644
+v -0.175242 0.139834 0.358846
+v -0.185698 0.131626 0.374363
+v -0.136629 0.135158 0.372822
+v 0.222603 -0.174863 0.707352
+v 0.235563 -0.174747 0.7031
+v 0.22241 -0.158704 0.691424
+v -0.883686 0.528507 0.379951
+v -0.885047 0.534865 0.362045
+v -0.892138 0.527377 0.370471
+v -0.353329 0.470151 0.0226463
+v -0.361011 0.468648 0.0114323
+v -0.338878 0.479541 0.00423895
+v -0.934784 0.374479 0.45886
+v -0.931663 0.392051 0.458718
+v -0.9321 0.39209 0.445925
+v 0.137888 0.253168 0.318872
+v 0.259571 0.263765 0.0498654
+v 0.145351 0.256649 0.303085
+v 0.153649 0.260605 0.287414
+v 0.175602 0.267927 0.239706
+v 0.168074 0.265076 0.255442
+v 0.160508 0.262185 0.271267
+v -0.870969 -0.415854 0.129147
+v -0.871136 -0.416034 0.116301
+v 0.211389 0.261633 0.0502251
+v 0.230901 0.260849 0.0391396
+v 0.0975921 0.757706 -0.293965
+v 0.103051 0.764077 -0.272474
+v 0.099095 0.744693 -0.272654
+v 0.206623 0.26451 0.0668341
+v 0.202667 0.267452 0.0838926
+v 0.217336 0.269815 0.0893262
+v -0.626292 0.763961 -0.481133
+v -0.634962 0.774045 -0.484242
+v -0.631224 0.766209 -0.464473
+v -0.640524 0.774944 -0.467864
+v -0.650107 0.578411 0.0104818
+v -0.655656 0.579297 0.0272192
+v -0.645136 0.573003 0.0311627
+v -0.0810988 0.183662 0.297433
+v -0.610852 0.602265 -0.572489
+v -0.603453 0.618527 -0.578822
+v -0.601475 0.618578 -0.566041
+v -0.444145 -0.609021 0.44017
+v -0.435937 -0.627069 0.440684
+v -0.431891 -0.608546 0.454813
+v -0.263695 0.81217 0.00043674
+v -0.265249 0.802818 0.0123315
+v -0.249745 0.812671 0.00575469
+v 0.537274 0.101259 0.41814
+v 0.536567 0.112833 0.408994
+v 0.522219 0.118408 0.418898
+v -0.0679709 0.197458 0.283149
+v -0.996506 0.145229 0.241749
+v -0.99693 0.162544 0.241569
+v -0.994823 0.16239 0.228852
+v -0.6968 0.754648 -0.304588
+v -0.402732 0.29381 0.33051
+v -0.389823 0.279886 0.316598
+v -0.816531 0.576882 0.288942
+v 0.374293 0.239102 0.330587
+v 0.363092 0.244176 0.32654
+v 0.366444 0.236662 0.346656
+v 0.446881 0.220721 0.0640723
+v 0.370966 0.247567 0.310856
+v 0.401705 0.24591 0.267182
+v 0.390465 0.250715 0.263033
+v 0.395102 0.244754 0.283123
+v 0.355744 0.241504 0.342366
+v -0.304787 0.782202 0.0226591
+v -0.277735 0.797205 0.0143354
+v -0.67125 0.498192 0.531988
+v -0.663697 0.491166 0.536869
+v -0.650929 0.491101 0.531962
+v -0.956377 0.058703 0.300452
+v -0.96298 0.0572386 0.279295
+v -0.952447 0.0492489 0.285795
+v 0.152429 0.206809 0.417896
+v 0.139005 0.20758 0.413169
+v 0.138492 0.19223 0.432283
+v -0.988388 0.232628 0.254093
+v -0.984033 0.250201 0.254003
+v -0.986769 0.232513 0.24126
+v -0.993898 0.127836 0.241787
+v -0.994245 0.127824 0.254619
+v -0.326071 0.489945 -0.0118562
+v -0.317324 0.490331 -0.0019011
+v -0.141446 -0.128684 -0.283098
+v -0.456503 0.360465 0.0186514
+v -0.442463 0.344601 0.0253823
+v -0.453767 0.343599 0.0116892
+v -0.154214 -0.147271 -0.282815
+v -0.167175 -0.147451 -0.27855
+v 0.225994 0.273913 0.239655
+v -0.620884 0.762831 -0.497601
+v -0.61775 0.753736 -0.478102
+v 0.211222 0.272051 0.234285
+v 0.204439 0.270188 0.250188
+v 0.218505 0.271087 0.255313
+v 0.0810217 0.216559 0.373605
+v 0.118491 0.239655 0.349521
+v 0.128973 0.247529 0.334299
+v 0.196026 0.272359 0.191896
+v 0.189218 0.270946 0.207824
+v 0.184889 0.269237 0.132551
+v 0.1802 0.270689 0.149224
+v 0.200406 0.271819 0.138292
+v 0.188139 0.271562 0.170573
+v 0.173392 0.2697 0.165165
+v 0.194279 0.271832 0.154413
+v 0.14679 0.264998 0.229199
+v 0.154754 0.265281 0.250522
+v 0.139969 0.263406 0.245191
+v 0.231337 0.270702 0.0945157
+v 0.800924 -0.415905 0.04799
+v 0.803711 -0.415622 0.0609124
+v 0.802799 -0.433709 0.0608225
+v -0.451198 0.364383 0.0250869
+v -0.440009 0.364742 0.0377652
+v -0.73337 0.867764 -0.576356
+v -0.742953 0.861264 -0.561018
+v -0.73021 0.857295 -0.557229
+v -0.596414 0.621301 -0.193347
+v -0.554923 0.582791 0.305834
+v -0.561115 0.582419 0.322237
+v -0.549117 0.579027 0.326553
+v -0.0865195 0.953751 -0.13905
+v -0.0721842 0.938632 -0.128132
+v -0.0735329 0.957925 -0.138254
+v -0.164285 0.195287 0.0786004
+v -0.169076 0.19792 0.0956076
+v -0.150926 0.194902 0.0834687
+v -0.929531 -0.169648 0.140733
+v 0.0669047 0.215827 0.368532
+v 0.146751 0.240528 0.359437
+v 0.13573 0.230984 0.374312
+v 0.149089 0.230342 0.379155
+v -0.931149 -0.169532 0.153553
+v 0.178697 0.252551 0.333682
+v 0.164657 0.251871 0.32857
+v 0.169089 0.245756 0.348878
+v 0.156411 0.247593 0.344228
+v 0.159468 0.238717 0.364113
+v 0.18241 0.269404 0.223752
+v 0.0423445 0.192859 0.397896
+v 0.103578 0.764205 -0.285307
+v 0.0996089 0.764372 -0.298191
+v -0.460536 0.534737 0.228878
+v -0.0566927 0.206681 0.268056
+v -0.0470202 0.213669 0.25268
+v -0.740615 0.850898 -0.541532
+v -0.600999 0.860095 -0.695033
+v -0.608385 0.857424 -0.67908
+v -0.594474 0.846223 -0.692683
+v -0.421974 0.676947 0.0922035
+v -0.424531 0.656318 0.10984
+v -0.601487 0.84463 -0.676613
+v -0.036577 0.22189 0.237535
+v 0.308486 0.192487 0.436522
+v 0.297247 0.19724 0.432347
+v 0.296206 0.180297 0.450896
+v -0.757545 0.580852 0.346785
+v -0.743428 0.581532 0.351666
+v 0.348178 0.238306 0.357973
+v 0.359495 0.233502 0.362147
+v -0.158556 0.195428 0.231498
+v -0.171157 0.197895 0.226938
+v -0.166199 0.192397 0.247632
+v 0.33884 0.231626 0.373092
+v 0.350195 0.227285 0.377446
+v 0.33049 0.211626 0.406939
+v 0.318557 0.215261 0.402816
+v 0.319559 0.202121 0.421801
+v 0.307561 0.205717 0.417601
+v 0.284877 0.184703 0.446464
+v -0.933872 -0.256148 0.17968
+v -0.872819 0.545874 0.346618
+v -0.456002 0.483458 0.268878
+v -0.454409 0.50324 0.255994
+v -0.45735 0.503292 0.268993
+v -0.867411 -0.0549393 0.345179
+v -0.872549 -0.0721135 0.350844
+v -0.865664 -0.0716639 0.362096
+v -0.705663 -0.972338 0.0254465
+v -0.702631 -0.949717 0.0179577
+v -0.0517087 0.683717 -0.18713
+v -0.0549201 0.689099 -0.190868
+v 0.597043 0.0588572 0.412989
+v 0.604943 0.0475533 0.416034
+v 0.608604 0.0500067 0.40848
+v -0.471133 0.555508 0.206064
+v -0.476503 0.556728 0.22266
+v -0.46814 0.546413 0.225859
+v 0.965022 -0.503664 0.232449
+v 0.972074 -0.50938 0.22731
+v 0.970854 -0.503921 0.215711
+v -0.736286 0.582971 0.0360182
+v -0.743852 0.577101 0.0516895
+v -0.612817 0.752233 -0.494621
+v -0.136256 0.196841 0.0888766
+v -0.131452 0.194285 0.0718823
+v -0.607769 0.749883 -0.511641
+v -0.615527 0.761533 -0.514377
+v -0.622502 0.756241 -0.461365
+v 0.196244 0.266232 0.265628
+v 0.189385 0.264498 0.281685
+v 0.202024 0.263007 0.286399
+v -0.713858 0.599079 0.0050482
+v -0.725278 0.593016 0.021426
+v -0.709773 0.593581 0.0263457
+v 0.210258 0.267105 0.270805
+v 0.181125 0.26076 0.297369
+v 0.194459 0.260143 0.30225
+v 0.172904 0.256148 0.312937
+v 0.186944 0.256855 0.318011
+v 0.202127 0.272629 0.175737
+v 0.208961 0.273913 0.15986
+v 0.215127 0.273772 0.143713
+v 0.220522 0.272719 0.12731
+v 0.22593 0.271896 0.110906
+v -0.638572 0.640454 -0.13494
+v 0.763325 -0.129725 0.047823
+v 0.761476 -0.129892 0.0351062
+v 0.757596 -0.111664 0.0476432
+v 0.755207 -0.112127 0.0350291
+v 0.747539 -0.0943102 0.0349264
+v 0.750865 -0.0940533 0.0476946
+v -0.17099 -0.95149 0.323843
+v -0.193996 -0.970051 0.335763
+v -0.18539 -0.970013 0.314324
+v 0.757545 -0.0935523 0.124612
+v 0.749452 -0.07589 0.124625
+v 0.749581 -0.0758001 0.137432
+v 0.865099 -0.54351 0.360426
+v 0.873744 -0.532142 0.349508
+v 0.852138 -0.543523 0.360362
+v -0.0276367 0.227747 0.221941
+v -0.191106 0.179719 0.295609
+v -0.202384 0.184548 0.291498
+v -0.200098 0.174015 0.311357
+v -0.766241 0.588019 0.212371
+v -0.781848 0.584949 0.206963
+v -0.772484 0.587852 0.228929
+v -0.779498 0.586581 0.245307
+v -0.619111 0.558244 0.0222737
+v -0.610055 0.551115 0.0157869
+v -0.615964 0.55281 0.00480414
+v -0.634872 0.652708 -0.71845
+v -0.616619 0.638052 -0.709536
+v -0.635014 0.634057 -0.706157
+v -0.823326 -0.489033 0.155171
+v -0.823904 -0.48929 0.167991
+v -0.833114 -0.47114 0.155081
+v 0.0558963 0.206 0.383355
+v -0.670557 0.755907 -0.331691
+v -0.849928 -0.435006 0.154914
+v -0.217066 -0.958131 0.434916
+v -0.226842 -0.968034 0.41868
+v -0.888066 -0.380208 0.11616
+v -0.889659 -0.380041 0.12898
+v -0.890301 -0.362982 0.115929
+v -0.996802 0.14528 0.254555
+v -0.998484 0.162596 0.254465
+v 0.209886 0.140027 0.495019
+v 0.222744 0.140219 0.492116
+v 0.221498 0.151343 0.481403
+v 0.0972967 -0.129493 0.633543
+v 0.0949203 -0.127541 0.624872
+v 0.0825375 -0.132011 0.628276
+v 0.138838 0.22144 0.393863
+v 0.124721 0.220978 0.388956
+v 0.124863 0.20713 0.408288
+v -0.621937 0.550524 -0.497229
+v -0.615155 0.565977 -0.504615
+v -0.609041 0.568584 -0.490909
+v -0.522258 -0.86648 0.602547
+v -0.538173 -0.856871 0.586015
+v -0.53396 -0.873956 0.600042
+v 0.111542 0.207426 0.403252
+v -0.527511 0.546118 0.428378
+v -0.520742 0.534005 0.430754
+v -0.512097 0.538462 0.415186
+v -0.6503 0.5752 0.0478873
+v -0.633806 0.568263 0.0353888
+v -0.660396 0.633093 -0.0872324
+v -0.505135 0.553684 0.380092
+v -0.496837 0.543343 0.383329
+v -0.566163 0.766106 -0.76215
+v -0.564763 0.781174 -0.760454
+v -0.567011 0.78102 -0.747134
+v -0.597364 0.63994 -0.219128
+v 0.0114773 0.185974 0.386977
+v 0.0239629 0.198434 0.372488
+v -0.0200194 0.230586 0.205949
+v -0.0131729 0.23232 0.189725
+v -0.167381 -0.110816 -0.273887
+v -0.600601 0.701019 -0.360221
+v -0.588321 0.68048 -0.360349
+v -0.597839 0.70039 -0.373246
+v -0.209025 0.16898 0.327465
+v -0.198479 0.162853 0.331319
+v -0.118658 0.202673 0.13282
+v -0.124053 0.203341 0.149558
+v -0.109474 0.20582 0.154914
+v -0.919563 -0.291563 0.102968
+v -0.913795 -0.309058 0.102994
+v -0.396515 0.29304 0.313849
+v -0.380317 0.289199 0.263046
+v -0.387729 0.300991 0.260079
+v -0.38534 0.291652 0.280117
+v 0.383901 0.249687 0.278974
+v 0.340664 0.219911 0.392167
+v 0.329501 0.224651 0.388056
+v 0.274164 0.175146 0.454505
+v 0.274151 0.157291 0.467569
+v 0.287022 0.174863 0.455764
+v -0.890751 -0.345911 0.102942
+v -0.902543 -0.327555 0.102955
+v -0.496606 -0.711283 0.131099
+v -0.500523 -0.693042 0.13056
+v -0.501924 -0.710974 0.118459
+v -0.230464 0.180695 0.319308
+v -0.241742 0.185435 0.315172
+v -0.239507 0.175158 0.335185
+v -0.620332 0.607184 -0.109519
+v -0.62773 0.604346 -0.0936422
+v 0.127509 0.181928 0.446734
+v 0.107406 0.174324 0.45394
+v 0.120213 0.174491 0.45561
+v -0.167034 -0.165717 -0.283046
+v 0.177117 0.201414 0.426862
+v 0.165107 0.204767 0.422482
+v 0.163964 0.188068 0.441352
+v 0.151928 0.191241 0.436817
+v 0.1402 0.180168 0.451512
+v 0.152904 0.178139 0.456059
+v 0.190322 0.214234 0.412103
+v 0.177593 0.216829 0.40789
+v 0.199931 0.22207 0.397434
+v 0.188819 0.22573 0.394094
+v 0.210939 0.231588 0.382546
+v 0.198222 0.233861 0.37805
+v -0.716157 0.587762 0.0417472
+v -0.602464 0.747738 -0.528597
+v -0.75725 0.576073 0.0844578
+v -0.762645 0.576818 0.101311
+v 0.274087 0.273772 0.110482
+v -0.690493 0.603446 -0.00438025
+v -0.70371 0.608006 -0.00923577
+v -0.700062 0.599683 0.0102505
+v 0.259379 0.272449 0.10492
+v 0.278814 0.271395 0.0938606
+v 0.264799 0.270984 0.0886069
+v 0.282847 0.268043 0.0769048
+v -0.17564 -0.967829 0.291267
+v -0.19293 -0.975793 0.294941
+v 0.269539 0.268004 0.0720493
+v -0.919409 -0.100617 0.153219
+v -0.913564 -0.0834687 0.153167
+v -0.917649 -0.100836 0.140528
+v -0.462822 0.545103 0.209186
+v -0.456785 0.545219 0.192641
+v -0.650402 0.760313 -0.379476
+v -0.644249 0.76066 -0.395609
+v -0.464569 0.556702 0.189622
+v -0.659278 0.620107 -0.0681186
+v -0.486419 0.561429 0.256212
+v -0.491018 0.564153 0.273104
+v -0.482026 0.555097 0.276572
+v -0.693999 0.614776 -0.024663
+v -0.740461 -0.562958 0.0931156
+v -0.745136 -0.561314 0.1037
+v -0.748695 -0.553542 0.0825053
+v -0.481294 0.559259 0.239462
+v -0.472829 0.549008 0.242712
+v 0.802529 -0.361891 0.0608096
+v 0.80023 -0.362173 0.0481827
+v 0.799408 -0.3441 0.0607839
+v 0.487177 -0.324703 0.661263
+v 0.466483 -0.321158 0.665297
+v 0.477479 -0.341993 0.669561
+v -0.237349 0.558899 -0.0807841
+v -0.226353 0.57114 -0.0941946
+v -0.226109 0.557049 -0.0745027
+v -0.728373 0.845131 -0.537267
+v -0.717481 0.842202 -0.533067
+v 0.00666029 0.235853 0.141131
+v -0.000301864 0.234568 0.157201
+v -0.00633915 0.233964 0.173591
+v -0.72529 0.583202 0.0957617
+v -0.514717 -0.808778 0.542894
+v -0.525893 -0.808483 0.537563
+v -0.195769 0.610743 -0.131973
+v -0.186417 0.623164 -0.141915
+v -0.183797 0.606799 -0.126102
+v 0.0797886 0.826775 -0.348609
+v 0.0733531 0.841842 -0.352835
+v 0.0882536 0.842973 -0.355429
+v -0.83928 0.556381 0.357587
+v -0.855478 0.551513 0.352064
+v -0.938343 0.337677 0.189622
+v -0.934348 0.337664 0.1767
+v -0.67748 0.753942 -0.315892
+v -0.63852 0.759941 -0.411962
+v -0.980488 0.0932183 0.306283
+v -0.982261 0.0930642 0.293438
+v -0.972742 0.0758772 0.293451
+v -0.876865 0.424794 0.0992042
+v -0.8698 0.424897 0.0861149
+v -0.880706 0.407337 0.086102
+v -0.819087 -0.489855 0.116597
+v -0.833088 -0.471512 0.103636
+v -0.884983 0.407363 0.0990758
+v -0.934335 0.301582 0.0868856
+v -0.92691 0.319103 0.0868599
+v -0.928477 0.301518 0.0740917
+v 0.286893 0.264279 0.0600004
+v 0.383028 -0.161709 -0.279552
+v 0.383606 -0.175171 -0.291062
+v 0.370568 -0.172358 -0.293952
+v -0.859408 -0.363715 0.372938
+v -0.859948 -0.349469 0.383227
+v -0.864431 -0.346104 0.37295
+v 0.273534 0.264549 0.0550806
+v -0.682824 0.609599 -0.0207066
+v -0.891072 0.389624 0.0863461
+v -0.645829 0.637897 -0.118947
+v -0.65292 0.635894 -0.103109
+v -0.502347 0.562688 0.343535
+v -0.513394 0.567955 0.339424
+v -0.50877 0.562213 0.359887
+v -0.548706 0.558693 0.420671
+v -0.557801 0.553016 0.436355
+v -0.5471 0.546837 0.440285
+v -0.667692 0.899453 -0.663357
+v -0.676594 0.893853 -0.648071
+v -0.658444 0.890616 -0.660017
+v 0.0543806 0.235865 0.307606
+v 0.0447209 0.228955 0.322918
+v 0.059493 0.230997 0.32821
+v 0.0697307 0.239693 0.313207
+v 0.0136224 0.236919 0.125049
+v 0.712201 -0.0225949 0.266065
+v 0.704353 -0.0107901 0.26952
+v 0.710197 -0.022916 0.278859
+v -0.615078 0.620582 -0.144792
+v -0.0612656 0.615328 -0.0958516
+v -0.0715419 0.615752 -0.103803
+v -0.048536 0.624949 -0.112345
+v -0.154664 0.189211 0.0448044
+v -0.314382 -0.97176 0.493837
+v -0.327626 -0.972222 0.491435
+v -0.318942 -0.971464 0.470074
+v -0.631623 0.847751 -0.631578
+v -0.623864 0.835368 -0.628764
+v -0.616247 0.839158 -0.644667
+v -0.647705 0.839492 -0.600222
+v -0.656247 0.834765 -0.584911
+v -0.639368 0.829074 -0.597306
+v 0.804405 -0.455546 0.28031
+v 0.802812 -0.477909 0.285551
+v 0.807269 -0.456304 0.26839
+v -0.0469945 -0.127361 0.590344
+v -0.0598398 -0.127271 0.590614
+v -0.0598141 -0.145229 0.591282
+v -0.735939 0.90341 -0.669677
+v -0.734167 0.899762 -0.65073
+v -0.728014 0.905542 -0.668675
+v -0.939961 0.301672 0.0997437
+v -0.938445 0.283984 0.0870397
+v -0.66809 0.782728 -0.422816
+v -0.678623 0.788894 -0.426746
+v -0.674719 0.781457 -0.406849
+v -0.831187 0.184163 0.682689
+v -0.83603 0.201234 0.68671
+v -0.84244 0.183585 0.67529
+v -0.675091 0.613003 -0.0364806
+v -0.818123 0.166141 0.673787
+v -0.818098 0.184754 0.687673
+v -0.610454 0.556445 -0.468674
+v -0.817956 0.203418 0.695085
+v -0.830815 0.203341 0.690332
+v -0.830609 0.221774 0.692965
+v -0.817725 0.221967 0.699067
+v -0.830275 0.239963 0.693852
+v -0.839524 0.236572 0.689035
+v -0.59238 0.558976 -0.411897
+v -0.585135 0.579246 -0.411872
+v -0.588783 0.559156 -0.399001
+v -0.639638 0.52315 -0.475456
+v -0.645932 0.520723 -0.489046
+v -0.830082 0.275866 0.684205
+v -0.841489 0.28916 0.671475
+v -0.834912 0.271665 0.683434
+v -0.830134 0.257934 0.690383
+v -0.817301 0.275956 0.690191
+v -0.824366 0.306926 0.672182
+v -0.829954 0.293721 0.676292
+v -0.817584 0.294247 0.681636
+v -0.817147 0.311781 0.673119
+v -0.80461 0.330073 0.667365
+v -0.818188 0.324254 0.665399
+v 0.213701 0.255544 0.327735
+v 0.205493 0.251254 0.343355
+v 0.218171 0.249263 0.347941
+v 0.227086 0.255043 0.332642
+v 0.195846 0.24442 0.358628
+v 0.208537 0.242506 0.363265
+v 0.18548 0.236135 0.373644
+v 0.17537 0.228813 0.38848
+v -0.891509 -0.3627 0.128838
+v -0.196103 0.669047 -0.166501
+v -0.196128 0.688367 -0.174169
+v -0.183309 0.669137 -0.168132
+v -0.610839 -0.877449 0.388044
+v -0.597724 -0.86093 0.387992
+v -0.605829 -0.878143 0.375173
+v -0.945806 0.319861 0.18952
+v -0.944444 0.319809 0.176649
+v -0.888952 0.407312 0.112242
+v -0.957212 0.0410921 0.203932
+v -0.969415 0.0581764 0.203752
+v -0.967912 0.0580864 0.190971
+v -0.928863 -0.186938 0.153733
+v -0.604365 -0.0980867 -0.206514
+v -0.604301 -0.0797436 -0.201427
+v -0.591687 -0.0792298 -0.206874
+v -0.896942 -0.0137316 0.204099
+v -0.89734 -0.0140784 0.191189
+v -0.711585 0.361647 0.64089
+v -0.715412 0.383573 0.630691
+v -0.728014 0.366027 0.644012
+v 0.666999 -0.324729 -0.209982
+v 0.684211 -0.335314 -0.19512
+v 0.669914 -0.335057 -0.208723
+v 0.795451 -0.344472 0.048157
+v 0.793743 -0.32663 0.0485038
+v 0.797173 -0.326283 0.0608996
+v 0.765573 -0.147515 0.0348878
+v 0.768117 -0.147541 0.0478744
+v -0.969107 0.0755946 0.306681
+v -0.434576 -0.770166 0.271961
+v -0.440536 -0.76951 0.284793
+v -0.434434 -0.752221 0.271884
+v -0.759151 0.871027 -0.585835
+v -0.599561 0.666029 -0.729407
+v -0.591096 0.6803 -0.738887
+v -0.583594 0.681482 -0.728046
+v -0.774115 0.867032 -0.592001
+v -0.737596 0.577961 0.372539
+v -0.747526 0.571834 0.38839
+v -0.733203 0.571693 0.392976
+v 0.83928 -0.543947 0.3599
+v 0.839267 -0.527261 0.341878
+v 0.822658 -0.539669 0.349803
+v -0.0034875 0.17047 0.40139
+v -0.679137 0.825259 -0.53755
+v -0.686459 0.822818 -0.521416
+v -0.669182 0.81795 -0.533838
+v -0.170631 0.20162 0.189198
+v -0.164465 0.201594 0.172525
+v 0.03018 0.179963 0.412218
+v -0.987836 0.110701 0.306181
+v -0.989326 0.110675 0.29331
+v -0.632791 0.759697 -0.428224
+v -0.51229 -0.870629 0.285628
+v -0.504544 -0.871476 0.272757
+v -0.527678 -0.887096 0.272873
+v 0.171388 -0.174349 0.707981
+v 0.175974 -0.166257 0.700647
+v 0.164645 -0.161864 0.696177
+v -0.70872 0.910025 -0.658977
+v -0.718071 0.904489 -0.643575
+v -0.590351 -0.84779 -0.0220682
+v -0.552752 -0.83181 -0.0231087
+v -0.573215 -0.851117 -0.0378294
+v 0.164876 0.218897 0.40333
+v -0.655219 0.577268 0.0648302
+v -0.445109 0.575752 0.162326
+v -0.457916 0.59493 0.156379
+v -0.463105 0.574326 0.171626
+v -0.977392 0.163392 0.472887
+v -0.974425 0.180618 0.472823
+v -0.976005 0.163289 0.460003
+v -0.893988 0.389675 0.0992428
+v -0.668399 0.62915 -0.0714455
+v -0.699664 0.589612 0.161003
+v -0.685534 0.589818 0.166025
+v -0.68073 0.58757 0.14907
+v -0.661796 0.58608 0.137098
+v -0.666626 0.58757 0.154144
+v -0.647731 0.585168 0.142326
+v 0.0723254 0.247144 0.276623
+v 0.0633466 0.241492 0.292128
+v 0.0788252 0.244921 0.297626
+v 0.0869049 0.24988 0.282019
+v -0.992524 0.12808 0.306103
+v -0.993847 0.128055 0.293258
+v 0.0252217 0.236045 0.0921522
+v -0.536966 0.584204 0.219102
+v -0.542926 0.5845 0.23557
+v -0.52493 0.581301 0.223444
+v -0.996737 0.145537 0.305988
+v -0.997058 0.145434 0.29313
+v -0.792394 0.184959 0.691064
+v -0.792394 0.166591 0.682972
+v -0.780448 0.16677 0.689266
+v -0.241575 -0.673428 -0.121722
+v -0.254433 -0.673325 -0.123315
+v -0.241691 -0.654558 -0.128247
+v 0.0514647 0.237664 0.0646118
+v 0.0355365 0.232204 0.0587672
+v 0.0843486 -0.304716 -0.468173
+v 0.0966159 -0.306938 -0.464923
+v 0.103128 -0.316701 -0.467607
+v -0.605071 0.739799 -0.492013
+v -0.399945 0.326258 0.140566
+v -0.391852 0.307105 0.140463
+v -0.393073 0.306348 0.127836
+v -0.210849 0.18004 0.307388
+v -0.221973 0.184985 0.303316
+v -0.21916 0.175788 0.323393
+v -0.475539 0.538321 0.316572
+v -0.482746 0.550254 0.313579
+v -0.908233 0.0038279 0.203945
+v -0.908208 0.00380221 0.191099
+v 0.728078 -0.0410022 0.0862048
+v 0.719253 -0.0318563 0.0714969
+v 0.725008 -0.0354916 0.0922035
+v -0.924675 -0.117868 0.153437
+v -0.921978 -0.11801 0.140605
+v -0.804816 0.14844 0.671347
+v -0.805163 0.166437 0.67818
+v -0.180277 -0.0743614 -0.265538
+v -0.192981 -0.0747725 -0.261877
+v -0.180213 -0.0565065 -0.257137
+v -0.805291 0.18478 0.68951
+v -0.805008 0.203572 0.698065
+v -0.804931 0.222031 0.702355
+v -0.804931 0.240271 0.702355
+v -0.817751 0.240194 0.699118
+v -0.776492 0.619156 -0.158845
+v -0.773191 0.62721 -0.148337
+v -0.775837 0.627107 -0.163829
+v -0.804996 0.258447 0.699259
+v -0.804739 0.276302 0.693813
+v -0.81734 0.258113 0.696498
+v -0.804854 0.294466 0.686504
+v -0.804777 0.312385 0.677114
+v 0.620396 -0.928291 0.0189083
+v 0.632702 -0.922601 0.0134619
+v 0.638842 -0.924823 0.0194349
+v -0.685509 -0.907764 0.0158639
+v -0.693961 -0.921201 0.0253566
+v -0.691944 -0.906428 0.0280027
+v -0.383503 0.485963 -0.021336
+v -0.37067 0.482302 -0.017855
+v -0.381807 0.470433 -0.00385359
+v 0.458391 -0.186873 -0.278871
+v 0.445713 -0.184972 -0.280875
+v 0.462656 -0.181877 -0.276225
+v -0.599201 -0.938477 -0.0827109
+v -0.582053 -0.936975 -0.0870783
+v -0.584288 -0.9579 -0.0917283
+v -0.803724 0.401724 0.615547
+v -0.810365 0.393593 0.619118
+v -0.791611 0.401403 0.621122
+v 0.814013 -0.437986 0.15512
+v 0.814051 -0.432809 0.163418
+v 0.815798 -0.446053 0.177034
+v 0.236013 0.260541 0.317266
+v 0.221935 0.259873 0.312166
+v -0.998626 0.162878 0.305936
+v -0.999024 0.162776 0.293078
+v -0.698932 0.840031 -0.544936
+v -0.709439 0.846004 -0.548931
+v -0.706806 0.836499 -0.528969
+v -0.379701 0.519014 -0.0429675
+v -0.389296 0.505167 -0.0322674
+v -0.388024 0.514416 -0.0374954
+v -0.451865 0.340747 0.368313
+v -0.444274 0.3283 0.371499
+v -0.43762 0.329585 0.354851
+v -0.463298 0.341235 0.388557
+v -0.470979 0.341004 0.400722
+v -0.455783 0.322751 0.400234
+v -0.890674 -0.0322289 0.127194
+v -0.887527 -0.0323958 0.1144
+v -0.892536 -0.0497241 0.114336
+v -0.716954 0.909177 -0.682586
+v -0.934874 -0.169198 0.179282
+v -0.933526 -0.151934 0.179179
+v -0.702863 0.911078 -0.676472
+v -0.817687 0.508712 0.485167
+v -0.812407 0.495469 0.508892
+v -0.80172 0.501159 0.507004
+v 0.795811 -0.308249 0.0479387
+v 0.798444 -0.308094 0.0609124
+v 0.770121 -0.16546 0.0349649
+v 0.773537 -0.165178 0.0477588
+v -0.962877 0.426451 0.265923
+v -0.960347 0.444152 0.265833
+v -0.96131 0.444036 0.252975
+v -0.958612 0.443985 0.240104
+v -0.96271 0.426297 0.240246
+v -0.592008 0.65872 -0.668649
+v -0.591314 0.660158 -0.679426
+v -0.585572 0.679542 -0.668572
+v -0.971162 0.0581892 0.229391
+v -0.962273 0.0472964 0.23828
+v 0.0189661 0.236212 0.10844
+v -0.913667 0.0377395 0.100527
+v -0.921862 0.0373927 0.112923
+v -0.936621 0.0563909 0.1009
+v 0.0218306 0.208338 0.352526
+v -0.705188 0.716395 -0.215274
+v -0.719356 0.716151 -0.220207
+v -0.715785 0.706735 -0.199192
+v -0.397979 0.4906 -0.0228389
+v -0.393753 0.472977 -0.00896602
+v -0.432341 0.631578 0.129172
+v -0.419418 0.650242 0.115813
+v -0.432366 0.650781 0.11327
+v -0.495116 0.592502 0.159641
+v -0.507691 0.594121 0.15476
+v -0.790776 0.537691 0.451358
+v -0.80357 0.525296 0.466541
+v -0.788746 0.527672 0.471769
+v -0.496207 0.60572 0.140592
+v 0.273393 0.274697 0.238601
+v 0.260175 0.275172 0.233772
+v 0.266033 0.272102 0.254286
+v 0.266906 0.276392 0.217869
+v 0.252673 0.272924 0.24943
+v 0.245185 0.270239 0.265153
+v 0.258582 0.269533 0.270034
+v 0.221228 0.2404 0.367812
+v 0.295846 0.274658 0.136802
+v 0.309039 0.274131 0.141581
+v 0.313843 0.271858 0.124998
+v 0.301254 0.273232 0.120515
+v -0.935709 -0.221196 0.205152
+v -0.935041 -0.221273 0.192358
+v -0.455295 0.562637 0.174439
+v -0.442745 0.557679 0.169802
+v -0.51974 0.549188 0.412411
+v 0.255525 0.267722 0.066757
+v -0.087637 0.170123 -0.0392424
+v -0.0848881 0.16275 -0.0572772
+v -0.0996089 0.160836 -0.0549522
+v -0.486484 0.557961 0.293451
+v -0.496246 0.565668 0.289726
+v -0.597904 0.761058 -0.578694
+v -0.593177 0.760699 -0.591744
+v -0.600755 0.769934 -0.583909
+v -0.652548 0.587698 0.15923
+v -0.928465 -0.273207 0.205435
+v -0.475218 -0.783627 0.41358
+v -0.473651 -0.78382 0.400748
+v -0.501538 -0.799067 0.400825
+v -0.891072 -0.0320233 0.152795
+v -0.218595 -0.968381 0.397973
+v -0.233996 -0.972903 0.398628
+v -0.225775 -0.973301 0.377922
+v -0.982273 0.214542 0.189982
+v -0.980437 0.214388 0.177214
+v -0.982132 0.196841 0.177252
+v -0.689786 -0.119243 0.532489
+v -0.67626 -0.130367 0.542277
+v -0.676337 -0.112653 0.534274
+v -0.461037 -0.485334 -0.186912
+v -0.473792 -0.485539 -0.189096
+v -0.461011 -0.466862 -0.197753
+v -0.629426 -0.20943 -0.210496
+v -0.642438 -0.209969 -0.202622
+v -0.629606 -0.190933 -0.207567
+v -0.656542 0.25101 -0.0959544
+v -0.643813 0.251048 -0.0958131
+v -0.643736 0.232282 -0.0953121
+v -0.0204947 -0.920995 0.0012203
+v -0.0338666 -0.921573 -0.000963397
+v -0.0245666 -0.920674 -0.0236353
+v -0.503966 0.541635 0.399425
+v -0.342218 0.243752 0.0879903
+v -0.329964 0.241492 0.0927559
+v -0.325249 0.23882 0.075646
+v -0.46755 -0.839068 0.28541
+v -0.462951 -0.839633 0.272564
+v -0.47992 -0.855985 0.27268
+v -0.512148 0.552065 0.396329
+v -0.640332 -0.469547 -0.167695
+v -0.640807 -0.45078 -0.181273
+v -0.627628 -0.46902 -0.175981
+v -0.997714 0.180207 0.305885
+v -0.998998 0.18013 0.292988
+v -0.653652 0.586285 -0.00968535
+v -0.644558 0.577281 -0.00625566
+v -0.638418 0.577448 -0.0227876
+v -0.196257 0.707403 -0.181003
+v -0.184208 0.707609 -0.183803
+v -0.183347 0.688328 -0.176083
+v -0.377684 -0.624513 0.50983
+v -0.378943 -0.606722 0.510549
+v -0.387356 -0.62459 0.501211
+v -0.79102 0.131883 0.680171
+v -0.791919 0.1488 0.682021
+v -0.800975 0.131677 0.671886
+v -0.470504 -0.783486 0.499798
+v -0.478943 -0.783756 0.494544
+v -0.4792 -0.79515 0.524024
+v -0.79215 0.203585 0.699979
+v -0.792073 0.222082 0.704166
+v -0.792073 0.240336 0.704051
+v -0.792035 0.258563 0.700981
+v -0.791842 0.276187 0.696434
+v -0.791906 0.294299 0.689099
+v -0.791752 0.311948 0.680762
+v -0.791816 0.330086 0.670293
+v -0.791791 0.347928 0.659323
+v -0.803814 0.347876 0.656587
+v -0.791572 0.365462 0.647904
+v -0.804405 0.365718 0.643806
+v -0.791701 0.383792 0.634455
+v -0.804122 0.383227 0.63064
+v -0.813088 0.410304 0.602958
+v -0.791752 0.419694 0.60545
+v -0.134959 -0.470549 0.571898
+v -0.13546 -0.489316 0.55493
+v -0.129333 -0.489098 0.566812
+v 0.24354 0.263547 0.301466
+v 0.230168 0.264035 0.296547
+v -0.791251 0.43647 0.589753
+v -0.791932 0.445218 0.580607
+v -0.803069 0.427851 0.592425
+v 0.251761 0.26758 0.285834
+v 0.237683 0.267195 0.280785
+v -0.792009 0.491358 0.527595
+v -0.804944 0.491345 0.519567
+v -0.803672 0.478975 0.536946
+v 0.812292 -0.414852 0.201877
+v 0.812831 -0.4148 0.189057
+v 0.811084 -0.396971 0.201864
+v 0.995645 -0.560787 0.175775
+v 0.991278 -0.54324 0.175724
+v 0.992486 -0.54324 0.188685
+v 0.797905 -0.290137 0.0477845
+v 0.799742 -0.289995 0.0606041
+v 0.776286 -0.183277 0.0350934
+v 0.779857 -0.18293 0.0477845
+v -0.962736 0.408673 0.240297
+v -0.963892 0.408763 0.253168
+v -0.898304 -0.361608 0.205872
+v -0.898098 -0.344215 0.205769
+v -0.898162 -0.344524 0.192962
+v -0.218454 -0.166257 -0.276765
+v -0.202731 -0.764128 -0.12826
+v -0.202782 -0.74671 -0.118511
+v -0.616799 -0.117085 -0.202532
+v -0.617146 -0.0985491 -0.199796
+v 0.0335455 0.219513 0.337857
+v 0.0491782 0.222532 0.343226
+v 0.0373991 0.211536 0.357909
+v -0.53816 0.552438 0.424524
+v -0.629554 0.750795 -0.40866
+v -0.620781 0.741559 -0.405398
+v -0.807911 -0.507659 0.155312
+v -0.809581 -0.507608 0.168106
+v -0.735824 0.711809 -0.225987
+v -0.627576 0.758374 -0.444691
+v -0.439033 0.476175 -0.00903024
+v -0.429579 0.466811 -0.00380221
+v -0.444081 0.471268 -0.00516381
+v -0.482001 0.60599 0.14528
+v 0.285031 0.276906 0.169494
+v 0.298274 0.276007 0.174311
+v 0.303669 0.275339 0.157933
+v -0.808605 0.544756 0.425847
+v -0.825034 0.540209 0.420517
+v -0.822324 0.531487 0.441133
+v 0.272956 0.276701 0.201723
+v 0.280034 0.275814 0.222673
+v 0.286148 0.276148 0.20654
+v -0.66696 0.747699 -0.312115
+v -0.996185 0.197882 0.305769
+v -0.997495 0.197792 0.292898
+v -0.660139 0.749459 -0.327889
+v 0.318595 0.269687 0.108389
+v 0.305969 0.270663 0.10397
+v -0.83278 -0.470844 0.180798
+v -0.592971 0.458975 -0.132628
+v -0.587178 0.480196 -0.128903
+v -0.59256 0.459232 -0.129147
+v -0.470851 -0.800609 0.53394
+v -0.167689 -0.853647 0.67082
+v -0.160971 -0.871631 0.682188
+v -0.149975 -0.858297 0.678913
+v 0.250747 0.270496 0.0833274
+v 0.341601 0.176854 0.448506
+v 0.331055 0.182904 0.444601
+v 0.332777 0.166989 0.4613
+v -0.656979 0.583279 0.120219
+v -0.642914 0.583061 0.125383
+v -0.638097 0.580492 0.108414
+v 0.411082 0.155595 0.436419
+v 0.392739 0.158126 0.448686
+v 0.402064 0.151446 0.448699
+v 0.102884 0.256649 0.250368
+v 0.0881123 0.254542 0.244998
+v 0.09528 0.253836 0.266283
+v 0.0805593 0.251601 0.260965
+v -0.894502 -0.379527 0.180322
+v -0.94569 0.3018 0.125421
+v -0.942864 0.301736 0.112602
+v -0.912215 -0.308839 0.141517
+v -0.915465 -0.308621 0.154323
+v -0.921875 -0.291396 0.141465
+v -0.731443 -0.305102 -0.178203
+v -0.731328 -0.286527 -0.177933
+v -0.718829 -0.304665 -0.183546
+v 0.508513 -0.533619 0.622175
+v 0.49992 -0.533709 0.632104
+v 0.49694 -0.550948 0.628071
+v -0.261164 0.706967 -0.155891
+v -0.261395 0.726158 -0.154426
+v -0.248101 0.726183 -0.163546
+v -0.473921 -0.466323 -0.202288
+v -0.473921 -0.447453 -0.215994
+v -0.461204 -0.446939 -0.215069
+v -0.605932 0.325821 -0.0794225
+v -0.593164 0.325744 -0.0759671
+v -0.593189 0.30681 -0.0786004
+v -0.643864 0.269674 -0.0928073
+v -0.53387 -0.88639 0.285731
+v -0.526214 -0.280207 -0.254016
+v -0.526587 -0.261607 -0.254786
+v -0.513407 -0.279938 -0.257561
+v 0.278981 0.276803 0.185602
+v 0.292198 0.276225 0.190406
+v -0.207702 0.203701 0.251331
+v -0.215884 0.200181 0.267555
+v -0.203951 0.196405 0.271871
+v -0.837366 -0.453054 0.180682
+v -0.779459 0.185165 0.692374
+v -0.779356 0.203547 0.698746
+v -0.779176 0.22207 0.704218
+v -0.779151 0.240297 0.704783
+v -0.779151 0.258512 0.702124
+v -0.779138 0.276456 0.697076
+v -0.779164 0.294594 0.689754
+v -0.779112 0.312243 0.681302
+v -0.779074 0.33006 0.671758
+v -0.779074 0.348018 0.660942
+v -0.779022 0.366091 0.648739
+v -0.778855 0.383573 0.637217
+v -0.778868 0.401531 0.624359
+v -0.778997 0.419836 0.608752
+v -0.778791 0.437113 0.593478
+v -0.774886 0.591359 -0.127502
+v -0.772934 0.609291 -0.130097
+v -0.777558 0.601147 -0.146
+v -0.779112 0.455777 0.574814
+v -0.65346 0.750949 -0.34383
+v -0.218788 0.600209 -0.122416
+v -0.20941 0.612965 -0.131908
+v -0.206006 0.596497 -0.118973
+v -0.629336 -0.283136 -0.217304
+v -0.641873 -0.28365 -0.211588
+v -0.629143 -0.26478 -0.215043
+v -0.768027 0.577332 0.118215
+v 0.97675 -0.705117 0.201838
+v 0.977868 -0.704821 0.188967
+v 0.983956 -0.686427 0.201774
+v 0.758341 -0.220926 -0.0418885
+v 0.753897 -0.22108 -0.0549136
+v 0.752034 -0.203084 -0.0420041
+v 0.797982 -0.272063 0.0477203
+v 0.799896 -0.271909 0.0605399
+v 0.798098 -0.253939 0.0605399
+v 0.79603 -0.254131 0.0478102
+v 0.79567 -0.236161 0.0606683
+v 0.787179 -0.218871 0.0351833
+v 0.781784 -0.200862 0.0349135
+v 0.78488 -0.200669 0.0477845
+v 0.789222 -0.218601 0.0478873
+v -0.897533 -0.361929 0.193065
+v -0.897122 -0.361942 0.180271
+v -0.883596 0.529843 0.125588
+v -0.87594 0.529753 0.112229
+v -0.910674 -0.309006 0.128646
+v -0.0453889 0.216752 0.0848047
+v -0.0386322 0.214838 0.068337
+v -0.0214324 0.218152 0.0652413
+v -0.0324408 0.210971 0.0472835
+v -0.0509123 0.218075 0.101426
+v -0.0579516 0.217137 0.117522
+v -0.587114 0.700403 -0.463176
+v -0.596003 0.720685 -0.475995
+v -0.597544 0.72084 -0.463112
+v -0.0640659 0.216739 0.133976
+v -0.070206 0.216366 0.150418
+v -0.712856 0.583755 0.0626851
+v -0.897225 -0.344614 0.180142
+v -0.901952 -0.326926 0.180027
+v -0.0772067 0.21512 0.166591
+v -0.993295 0.21548 0.305705
+v -0.994528 0.215377 0.292783
+v -0.99088 0.11047 0.254774
+v -0.991381 0.110675 0.241967
+v -0.912485 -0.142673 0.320041
+v -0.909107 -0.125344 0.315725
+v -0.906795 -0.309251 0.205602
+v -0.520048 0.56694 0.355738
+v -0.515668 0.560659 0.376097
+v -0.602078 -0.842382 0.452463
+v -0.600473 -0.842549 0.465347
+v -0.58475 -0.826441 0.45236
+v -0.618096 0.645181 -0.183071
+v -0.750955 0.576112 0.0679516
+v -0.881965 -0.397896 0.129082
+v 0.290451 0.275943 0.153142
+v -0.936853 0.356688 0.446156
+v -0.935902 0.35674 0.45895
+v -0.935863 0.374363 0.446014
+v -0.93052 -0.273476 0.179757
+v -0.931355 -0.273361 0.166989
+v -0.926024 -0.290959 0.166989
+v -0.948991 0.338011 0.240747
+v -0.948747 0.355596 0.240657
+v -0.848387 -0.434865 0.206283
+v -0.846935 -0.435109 0.193437
+v -0.837751 -0.453169 0.193527
+v -0.274523 0.512746 -0.0139243
+v -0.286071 0.505527 -0.00149005
+v -0.295885 0.50148 -0.00789986
+v 0.317786 -0.130585 -0.261325
+v 0.304594 -0.12984 -0.262134
+v 0.307253 -0.111767 -0.253566
+v -0.607769 0.670961 -0.733852
+v -0.622066 0.68978 -0.740275
+v -0.60371 0.684076 -0.741533
+v -0.9586 0.24916 0.125755
+v -0.956031 0.266733 0.125563
+v -0.952948 0.248993 0.112897
+v -0.921952 -0.222288 0.128247
+v -0.919344 -0.222506 0.115351
+v -0.921605 -0.23977 0.115608
+v 0.323284 0.266681 0.0918953
+v 0.310105 0.267773 0.0870783
+v -0.482643 -0.69434 0.155608
+v -0.477967 -0.712837 0.156944
+v -0.738406 0.887353 -0.67371
+v -0.749491 0.887289 -0.661173
+v 0.150155 0.219488 0.398744
+v -0.445931 0.400927 0.0310599
+v -0.442899 0.420234 0.0296598
+v -0.437761 0.401942 0.0420427
+v 0.245364 0.271742 0.0997052
+v -0.638469 0.417382 -0.118177
+v -0.624879 0.427607 -0.135441
+v -0.615373 0.427247 -0.126706
+v -0.445302 0.651013 0.110277
+v -0.43726 0.658514 0.105319
+v -0.593665 0.55204 -0.404524
+v -0.599496 0.549342 -0.41823
+v -0.988927 0.233078 0.30559
+v -0.990109 0.232949 0.29268
+v 0.110476 0.259334 0.234478
+v 0.0957039 0.257394 0.229122
+v 0.104606 0.249263 0.0658193
+v 0.0998529 0.251691 0.0825824
+v -0.978253 0.267747 0.253913
+v -0.982415 0.250072 0.241196
+v -0.083989 0.213155 0.18293
+v -0.641912 -0.26532 -0.208338
+v -0.628989 -0.246437 -0.213026
+v -0.893808 -0.37918 0.206
+v -0.895555 -0.379167 0.193193
+v -0.885202 -0.397382 0.193283
+v -0.643903 0.288313 -0.0891849
+v -0.656645 0.288338 -0.0896345
+v -0.644044 0.307093 -0.087515
+v -0.247433 0.707095 -0.165743
+v -0.641334 -0.375776 -0.209443
+v -0.641706 -0.357356 -0.213412
+v -0.628694 -0.375571 -0.213283
+v -0.715335 -0.257073 0.551423
+v -0.720718 -0.239642 0.548469
+v -0.720538 -0.257009 0.548854
+v -0.644481 -0.398371 0.550382
+v -0.656864 -0.398346 0.544628
+v -0.648116 -0.406438 0.544165
+v -0.848438 0.134683 -0.0296469
+v -0.835285 0.135248 -0.0359155
+v -0.835375 0.116032 -0.0293772
+v -0.62046 0.591539 -0.0908419
+v -0.613421 0.578578 -0.0881958
+v -0.856736 0.5264 0.41868
+v -0.858625 0.529624 0.409637
+v -0.947565 0.268518 0.459463
+v -0.947232 0.26848 0.472283
+v -0.940436 0.286116 0.459348
+v 0.0555623 -0.658 0.706389
+v 0.0650165 -0.666555 0.704924
+v 0.0688829 -0.657101 0.710191
+v -0.974553 0.163212 0.447209
+v -0.976249 0.145923 0.447248
+v -0.766305 0.16731 0.697538
+v -0.76637 0.185435 0.696151
+v -0.766434 0.203662 0.698836
+v -0.766318 0.22207 0.703319
+v -0.766344 0.240271 0.703396
+v -0.766305 0.258409 0.700454
+v -0.766293 0.276534 0.695971
+v -0.766318 0.294491 0.68951
+v -0.766331 0.312372 0.681482
+v -0.766318 0.33015 0.671873
+v -0.766331 0.348056 0.66098
+v -0.766318 0.365911 0.649934
+v -0.766228 0.383856 0.637551
+v -0.7661 0.401351 0.625682
+v -0.766151 0.419592 0.611565
+v -0.766177 0.437691 0.595624
+v -0.766139 0.455404 0.579194
+v -0.766023 0.472887 0.561018
+v -0.779125 0.473658 0.555277
+v -0.753268 0.490793 0.541545
+v -0.766151 0.491089 0.538552
+v 0.796697 -0.235814 0.201645
+v 0.795233 -0.235878 0.214516
+v 0.797854 -0.253759 0.214491
+v 0.984367 -0.686568 0.188929
+v 0.792754 -0.236353 0.047823
+v 0.791315 -0.218319 0.060617
+v 0.793358 -0.254324 0.0348493
+v 0.790879 -0.236559 0.0350548
+v -0.436978 -0.788252 0.220991
+v -0.429951 -0.788714 0.233939
+v -0.430517 -0.770705 0.22135
+v -0.0915549 0.210021 0.198987
+v -0.688206 0.778297 -0.375083
+v -0.695605 0.775381 -0.359514
+v -0.255615 -0.446104 -0.221324
+v -0.255679 -0.42753 -0.226231
+v -0.242783 -0.445693 -0.226257
+v -0.915311 0.354659 0.125113
+v -0.912318 0.354569 0.112229
+v -0.943866 0.46139 0.188672
+v -0.939627 0.461313 0.175788
+v -0.812549 0.0332179 -0.00611436
+v -0.825034 0.0169301 0.0114452
+v -0.834219 0.0400645 0.00123315
+v -0.101343 0.203508 0.214452
+v -0.202153 -0.976936 0.317176
+v -0.209642 -0.974907 0.336894
+v -0.216103 -0.978593 0.315789
+v -0.564467 0.78513 -0.762754
+v -0.435963 -0.788046 0.272076
+v -0.44209 -0.78725 0.28478
+v 0.795606 -0.272218 0.0347851
+v -0.983198 0.250702 0.305461
+v -0.984444 0.250548 0.29259
+v -0.109538 0.198845 0.230329
+v -0.265326 0.135839 0.3976
+v -0.278223 0.136173 0.39638
+v -0.278236 0.118626 0.409714
+v 0.0943937 0.252911 0.0991015
+v 0.117271 0.260939 0.218473
+v 0.124118 0.262494 0.20248
+v 0.122332 0.231575 0.369444
+v 0.110579 0.220605 0.384087
+v -0.937058 0.33909 0.459052
+v -0.937032 0.339129 0.471898
+v 0.182448 0.245165 0.353785
+v -0.829748 -0.471615 0.0908419
+v -0.826255 -0.471589 0.0781508
+v -0.815195 -0.481866 0.0739632
+v -0.192801 -0.147939 -0.273386
+v -0.192827 -0.129622 -0.271562
+v -0.180059 -0.129404 -0.273502
+v -0.907899 0.372359 0.124998
+v -0.97043 0.126783 0.139025
+v -0.975954 0.127027 0.151998
+v -0.973346 0.144188 0.138948
+v 0.189115 0.198126 0.431268
+v 0.176681 0.185422 0.445449
+v -0.938766 0.0399103 0.139885
+v -0.95499 0.0573928 0.139667
+v 0.891162 -0.543574 0.356072
+v 0.87797 -0.544037 0.359874
+v -0.774398 0.577769 0.134644
+v -0.780037 0.579297 0.151408
+v 0.331723 0.267927 0.113321
+v 0.326996 0.270599 0.129866
+v 0.344286 0.265898 0.117907
+v 0.165544 0.268775 0.143842
+v 0.149282 0.264934 0.137856
+v 0.158633 0.267709 0.159744
+v -0.00378294 0.708213 -0.215878
+v 0.0085357 0.712053 -0.222198
+v -0.00247272 0.700107 -0.208582
+v -0.924727 -0.239578 0.128363
+v -0.924328 -0.257022 0.115672
+v -0.656761 0.325937 -0.0877334
+v -0.64407 0.326026 -0.0865902
+v 0.318865 0.260914 0.0538218
+v 0.314819 0.264857 0.0705978
+v 0.331569 0.259706 0.058292
+v 0.327433 0.263354 0.0750679
+v -0.95806 0.057457 0.152435
+v -0.902723 0.00400773 0.152846
+v -0.925343 0.0225435 0.152846
+v -0.920128 0.0216829 0.139808
+v 0.161613 0.229687 0.383702
+v 0.24065 0.273669 0.11643
+v 0.0848239 0.194902 0.413028
+v 0.0973609 0.207118 0.398461
+v -0.617377 0.0104304 -0.151112
+v -0.617673 0.0289405 -0.143431
+v -0.60475 0.0293387 -0.151497
+v -0.975761 0.268223 0.305371
+v -0.978099 0.267902 0.292475
+v -0.243772 -0.276392 -0.29083
+v -0.243849 -0.257985 -0.289379
+v -0.231042 -0.257702 -0.291203
+v -0.78655 -0.125845 -0.103867
+v -0.781424 -0.108723 -0.103289
+v -0.771623 -0.124856 -0.11598
+v -0.720846 0.306784 -0.0792298
+v -0.733499 0.30654 -0.0771232
+v -0.720885 0.325487 -0.07589
+v -0.731752 -0.268081 -0.17539
+v -0.718727 -0.267593 -0.181581
+v -0.745316 -0.0487094 -0.104561
+v -0.745483 -0.030392 -0.0966095
+v -0.732651 -0.0299039 -0.10483
+v -0.733845 0.325397 -0.0714327
+v -0.733653 0.344036 -0.0690692
+v -0.720897 0.344254 -0.0724475
+v -0.605598 0.269648 -0.0878233
+v -0.605701 0.288261 -0.0844707
+v -0.59292 0.269571 -0.085691
+v -0.653164 -0.450382 -0.177021
+v -0.653806 -0.432296 -0.186257
+v -0.84822 0.115698 -0.0224407
+v -0.591712 -0.0610665 -0.198601
+v -0.604699 -0.0614391 -0.190586
+v -0.591609 -0.043173 -0.188556
+v -0.655939 -0.045254 -0.152872
+v -0.65599 -0.0270779 -0.144831
+v -0.643145 -0.0267439 -0.151318
+v -0.848849 0.191575 -0.0370458
+v -0.836004 0.191819 -0.042184
+v -0.835747 0.172898 -0.0400516
+v -0.848567 0.153681 -0.0332822
+v -0.835619 0.153951 -0.0382276
+v -0.753589 0.0950038 0.693171
+v -0.753781 0.113116 0.698296
+v -0.766588 0.113951 0.693145
+v -0.624442 0.596112 -0.661314
+v -0.638289 0.583588 -0.65249
+v -0.632727 0.596433 -0.667133
+v -0.75373 0.13133 0.701276
+v -0.767667 0.131754 0.695444
+v -0.061985 0.670473 -0.175223
+v -0.0484075 0.666607 -0.172448
+v -0.0585938 0.653749 -0.160078
+v -0.0713621 0.657011 -0.163983
+v -0.0696151 0.64161 -0.146552
+v -0.848503 0.529535 0.0740275
+v -0.824713 0.544474 0.0745798
+v -0.837224 0.528648 0.0618116
+v -0.75355 0.149429 0.702355
+v -0.753473 0.167438 0.702188
+v -0.521795 -0.901213 0.619387
+v -0.509104 -0.883589 0.616073
+v -0.528308 -0.89068 0.613479
+v -0.753422 0.185602 0.700338
+v -0.75364 0.203688 0.699568
+v -0.753422 0.222057 0.701058
+v -0.753396 0.240271 0.700891
+v -0.753332 0.25846 0.697988
+v -0.753524 0.276367 0.694044
+v -0.753614 0.294209 0.68739
+v -0.753473 0.312475 0.678797
+v -0.753627 0.330021 0.670126
+v -0.753563 0.34812 0.659529
+v -0.75355 0.365988 0.648521
+v -0.753524 0.383907 0.637602
+v -0.753447 0.40166 0.626003
+v -0.753435 0.41981 0.611796
+v -0.753383 0.437601 0.597075
+v -0.753357 0.455494 0.58089
+v -0.753319 0.473234 0.562868
+v -0.740486 0.490639 0.544615
+v -0.744456 0.50324 0.525925
+v 0.768155 -0.292539 -0.0547723
+v 0.772895 -0.292192 -0.0418371
+v 0.773229 -0.31015 -0.0419656
+v -0.422989 0.385243 0.217548
+v -0.425224 0.385012 0.230303
+v -0.418005 0.365384 0.230303
+v 0.787629 -0.200605 0.0607326
+v 0.796119 -0.290201 0.0349264
+v 0.101947 0.0550293 -0.201581
+v 0.116128 0.0559798 -0.202737
+v 0.103231 0.0446888 -0.216353
+v -0.150952 -0.779299 -0.28225
+v -0.155036 -0.761867 -0.26821
+v -0.146584 -0.762921 -0.280901
+v -0.596491 0.468314 -0.169841
+v -0.591301 0.485051 -0.175955
+v -0.592123 0.478924 -0.167862
+v -0.118569 0.19336 0.246
+v -0.127457 0.187028 0.261479
+v -0.139224 0.176571 0.276546
+v -0.14837 0.169879 0.291742
+v -0.159417 0.161144 0.307247
+v -0.650248 0.611038 -0.0648174
+v 0.0515032 -0.298512 -0.474942
+v 0.062229 -0.28162 -0.465565
+v 0.0644513 -0.316277 -0.476856
+v -0.755053 0.726723 -0.280554
+v -0.644404 0.382918 -0.0818374
+v -0.636542 0.387671 -0.0818117
+v -0.631623 0.38279 -0.0804501
+v -0.622811 0.383984 -0.0792426
+v 0.0291396 0.751938 -0.265846
+v 0.0210342 0.765271 -0.270368
+v 0.0338666 0.765361 -0.278473
+v 0.794231 -0.308339 0.0350163
+v 0.790789 -0.344896 0.0352475
+v 0.791367 -0.326682 0.0350163
+v -0.24855 0.524897 0.0119847
+v -0.24548 0.52536 -0.00124599
+v -0.22038 0.544808 0.0123829
+v -0.213701 0.544564 -0.000745027
+v -0.182384 0.564898 -0.000488121
+v -0.196424 0.565039 0.0124728
+v -0.168485 0.155608 0.323046
+v -0.238685 0.838747 -0.0268724
+v -0.251903 0.82445 -0.0132435
+v -0.237863 0.825375 -0.00748881
+v -0.224645 0.839273 -0.0214131
+v 0.0882536 0.252718 0.115351
+v 0.0828843 0.253489 0.131896
+v 0.130964 0.263919 0.186527
+v -0.930661 -0.13467 0.191883
+v -0.594089 0.659747 -0.268698
+v -0.599792 0.660492 -0.250368
+v 0.133353 0.241479 0.35471
+v 0.229154 0.274414 0.148916
+v 0.223784 0.275275 0.165293
+v -0.880911 -0.398256 0.116134
+v 0.20855 0.26049 0.307298
+v 0.200342 0.256187 0.322918
+v 0.191401 0.25056 0.338255
+v 0.304928 0.260451 0.0485295
+v 0.321627 0.254992 0.0362751
+v -0.951676 0.284305 0.125473
+v -0.94718 0.284215 0.112679
+v -0.951522 0.266617 0.112769
+v 0.33645 0.265666 0.0967122
+v 0.201549 0.210355 0.416791
+v -0.966744 0.285654 0.305243
+v -0.9693 0.285397 0.292359
+v -0.959113 0.250766 0.421017
+v -0.957546 0.250804 0.433811
+v -0.953089 0.268248 0.420876
+v -0.144593 0.650434 -0.161093
+v -0.142101 0.643639 -0.15616
+v -0.156565 0.648957 -0.160001
+v -0.973937 0.162763 0.552335
+v -0.979833 0.145781 0.538693
+v -0.975658 0.145576 0.554609
+v -0.475886 0.38216 0.00409765
+v -0.477813 0.399925 0.00250483
+v -0.474653 0.402777 0.00512527
+v -0.196899 0.783743 -0.18469
+v -0.196809 0.802715 -0.181144
+v -0.183913 0.80278 -0.189224
+v 0.867167 -0.834675 0.265564
+v 0.882466 -0.82224 0.266514
+v 0.877931 -0.821881 0.279886
+v -0.659176 0.904335 -0.678668
+v 0.676157 -0.929332 0.267349
+v 0.659946 -0.935202 0.269327
+v 0.668656 -0.935215 0.247644
+v -0.901245 0.389791 0.125306
+v -0.897263 0.389829 0.11205
+v -0.904752 0.372167 0.112139
+v 0.33496 0.254722 0.0411949
+v 0.347587 0.247311 0.0275018
+v 0.335307 0.249237 0.0247914
+v 0.235307 0.274209 0.132808
+v -0.466727 0.640467 0.113976
+v -0.458108 0.632079 0.124972
+v -0.445276 0.632297 0.126873
+v -0.617647 0.0471422 -0.13363
+v -0.607294 0.0624153 -0.127014
+v -0.607358 0.048658 -0.138549
+v -0.66407 0.831296 -0.569304
+v -0.654654 0.822818 -0.565797
+v -0.646523 0.827096 -0.581404
+v -0.241459 -0.710602 -0.115184
+v -0.254253 -0.710358 -0.118408
+v -0.241537 -0.692169 -0.116815
+v -0.25433 -0.691771 -0.121671
+v 0.0698078 -0.916268 -0.0802831
+v 0.057001 -0.915793 -0.0832632
+v 0.0663395 -0.914996 -0.106089
+v -0.330233 -0.970308 0.534146
+v -0.343515 -0.970796 0.531693
+v -0.33532 -0.970989 0.51123
+v -0.266867 -0.782253 -0.133026
+v -0.266906 -0.765104 -0.120014
+v -0.254074 -0.765233 -0.118421
+v -0.629105 -0.301543 -0.220117
+v -0.641757 -0.302006 -0.214709
+v -0.230939 -0.276058 -0.29408
+v -0.306251 -0.597101 -0.15467
+v -0.319122 -0.597139 -0.156494
+v -0.30638 -0.577961 -0.164368
+v -0.641526 -0.338769 -0.216007
+v -0.628681 -0.356855 -0.217933
+v -0.218197 -0.257497 -0.292886
+v -0.218132 -0.275673 -0.297459
+v -0.612779 0.590665 -0.549021
+v -0.617685 0.58667 -0.565052
+v -0.610017 0.59782 -0.553273
+v -0.84867 0.172641 -0.0350548
+v -0.740705 0.0951451 0.696202
+v -0.740769 0.113206 0.699593
+v -0.740615 0.131562 0.705207
+v -0.740846 0.149481 0.704642
+v -0.740615 0.167528 0.70513
+v -0.740615 0.185666 0.703575
+v -0.740576 0.203791 0.700441
+v -0.740576 0.221992 0.697859
+v -0.740525 0.240181 0.696215
+v -0.727654 0.222031 0.695277
+v -0.727782 0.239976 0.691347
+v -0.737545 0.252102 0.692837
+v -0.271595 0.551166 -0.0786004
+v -0.26223 0.564268 -0.0901997
+v -0.259559 0.548494 -0.0736036
+v -0.739587 0.270342 0.690037
+v -0.74082 0.276212 0.689202
+v -0.740769 0.294234 0.683074
+v -0.740756 0.312231 0.67529
+v -0.740898 0.330021 0.667121
+v -0.740705 0.3483 0.656819
+v -0.740833 0.365834 0.646786
+v -0.740769 0.383959 0.636048
+v -0.740705 0.401891 0.624693
+v -0.740666 0.419283 0.612669
+v -0.740589 0.437125 0.598064
+v -0.740564 0.455263 0.582187
+v -0.740551 0.473182 0.564384
+v -0.731623 0.48685 0.550241
+v -0.727757 0.473478 0.564654
+v -0.727821 0.455147 0.58202
+v 0.756967 -0.0938092 0.111844
+v 0.74908 -0.0760827 0.111793
+v 0.783094 -0.182712 0.0606298
+v 0.765111 -0.129532 0.060617
+v 0.798804 -0.398076 0.0352475
+v 0.79874 -0.380221 0.035286
+v 0.801129 -0.397909 0.0479515
+v 0.795323 -0.362379 0.0348878
+v 0.967244 -0.634468 0.314016
+v 0.973924 -0.616844 0.30311
+v 0.967823 -0.617101 0.315018
+v -0.711302 0.504833 -0.475751
+v -0.708836 0.505963 -0.482739
+v -0.697853 0.502559 -0.482559
+v -0.253996 -0.781572 -0.139526
+v -0.898304 -0.0843936 0.101812
+v -0.894669 -0.0847147 0.0891592
+v -0.897623 -0.102197 0.0894161
+v 0.797956 -0.416162 0.0350805
+v -0.176732 0.151562 0.339154
+v -0.681437 0.779979 -0.390985
+v -0.742169 0.708007 -0.226411
+v -0.728232 0.706774 -0.207978
+v 0.797314 -0.434133 0.0352989
+v 0.79969 -0.43403 0.0479515
+v 0.799279 -0.451975 0.0480928
+v 0.794578 -0.452437 0.0351833
+v -0.581642 0.559618 -0.347465
+v -0.578096 0.579747 -0.347478
+v -0.580511 0.559849 -0.334543
+v -0.590107 0.680492 -0.347517
+v -0.592265 0.680274 -0.33471
+v -0.582399 0.660518 -0.33462
+v -0.1388 -0.931836 0.2897
+v -0.146841 -0.930834 0.310317
+v -0.151003 -0.930321 0.285821
+v -0.173238 -0.932106 0.375301
+v -0.198479 -0.954855 0.390407
+v -0.190476 -0.955883 0.369932
+v 0.703197 -0.133553 -0.0932569
+v 0.699497 -0.119551 -0.0925761
+v 0.711276 -0.133039 -0.0803859
+v 0.475282 -0.956101 -0.0403471
+v 0.480215 -0.955562 -0.027566
+v 0.47527 -0.965465 -0.0262558
+v 0.770455 -0.147156 0.060527
+v 0.799151 -0.470035 0.0481956
+v -0.154895 -0.929858 0.330856
+v -0.180175 -0.952646 0.346052
+v -0.588283 0.539143 -0.347619
+v -0.58624 0.539374 -0.33462
+v -0.577955 0.579798 -0.334607
+v -0.187072 0.143932 0.354903
+v -0.226097 0.851579 -0.0408224
+v 0.0767442 0.253271 0.148171
+v -0.959345 0.302777 0.240875
+v 0.143 0.248235 0.339373
+v 0.216154 0.273553 0.1809
+v 0.322231 0.250702 0.023751
+v -0.968632 0.128183 0.395982
+v -0.971972 0.14555 0.395905
+v -0.969403 0.127965 0.383239
+v 0.300895 0.2646 0.0653183
+v -0.924251 -0.274183 0.11571
+v 0.21189 0.218999 0.401942
+v -0.977367 0.144368 0.151908
+v 0.201806 0.195467 0.435353
+v -0.955504 0.231305 0.113129
+v -0.972318 0.215531 0.395571
+v -0.969557 0.215595 0.408429
+v -0.968555 0.233283 0.395597
+v 0.213547 0.207066 0.421184
+v -0.836081 -0.453169 0.206373
+v -0.831675 -0.471114 0.193643
+v -0.830262 -0.471204 0.206514
+v -0.676954 0.590832 0.187811
+v -0.682477 0.591796 0.20451
+v -0.662875 0.591141 0.192782
+v -0.931406 0.266244 0.0741944
+v -0.938818 0.266399 0.0869498
+v -0.932485 0.283855 0.0743229
+v -0.925908 -0.274054 0.128504
+v -0.875606 0.46053 0.0991272
+v -0.878573 0.478282 0.0991914
+v -0.868361 0.478128 0.085935
+v 0.173572 0.239167 0.369058
+v -0.565097 0.788136 -0.764976
+v -0.568013 0.801534 -0.758797
+v 0.531699 -0.0527428 0.522778
+v 0.51843 -0.0400902 0.523831
+v 0.519136 -0.0572515 0.528327
+v -0.183707 0.829896 -0.180759
+v -0.183784 0.821688 -0.184086
+v -0.196796 0.821714 -0.174503
+v -0.605701 0.546246 -0.432694
+v -0.600511 0.558 -0.437973
+v -0.595836 0.558693 -0.42491
+v -0.668874 0.492155 -0.42139
+v -0.683685 0.490164 -0.422315
+v -0.6689 0.498976 -0.45245
+v -0.631456 0.344768 -0.0829806
+v -0.631533 0.363689 -0.080039
+v -0.6187 0.344793 -0.0815034
+v -0.266957 -0.747147 -0.116764
+v -0.254099 -0.747262 -0.115158
+v -0.267009 -0.728829 -0.116777
+v -0.254202 -0.728919 -0.115171
+v -0.764584 -0.0216186 -0.0778682
+v -0.77391 -0.0386772 -0.0779324
+v -0.776916 -0.0210278 -0.0651
+v -0.247702 0.687879 -0.161594
+v -0.641616 -0.320516 -0.216071
+v -0.628835 -0.320066 -0.221106
+v -0.628925 -0.338499 -0.220053
+v -0.74479 -0.213155 -0.162557
+v -0.744905 -0.194722 -0.159474
+v -0.731842 -0.194208 -0.167233
+v -0.229462 -0.321646 -0.295969
+v -0.237477 -0.321274 -0.285345
+v -0.24223 -0.313361 -0.28487
+v -0.71039 0.454467 -0.223071
+v -0.708746 0.450741 -0.21426
+v -0.715412 0.454184 -0.210355
+v -0.593549 0.363368 -0.0727172
+v -0.597621 0.378705 -0.0710345
+v -0.584236 0.374813 -0.0675791
+v -0.727821 0.0951194 0.697949
+v -0.727898 0.113257 0.70301
+v -0.727924 0.13151 0.70775
+v -0.727898 0.149609 0.707802
+v -0.72768 0.167657 0.707506
+v -0.727782 0.185756 0.704128
+v -0.72777 0.203906 0.700827
+v -0.714834 0.221915 0.693222
+v -0.715194 0.23959 0.687378
+v 0.3127 -0.730846 0.690448
+v 0.299854 -0.730114 0.698142
+v 0.300073 -0.748752 0.694147
+v 0.312597 -0.712439 0.694571
+v 0.312764 -0.749176 0.687467
+v 0.299867 -0.712066 0.69985
+v 0.312725 -0.69434 0.698373
+v 0.299983 -0.694301 0.700454
+v 0.274382 -0.565411 0.739799
+v 0.287189 -0.565733 0.736588
+v 0.274266 -0.547942 0.73637
+v 0.287086 -0.530459 0.733274
+v 0.274189 -0.530151 0.735547
+v -0.728078 0.311999 0.670396
+v -0.734655 0.306823 0.67493
+v -0.664596 0.483394 -0.380362
+v -0.668861 0.485706 -0.390279
+v -0.650004 0.491076 -0.399168
+v -0.728052 0.330047 0.662689
+v -0.727924 0.34821 0.653697
+v -0.727962 0.384087 0.633093
+v -0.728027 0.401762 0.622804
+v -0.727962 0.419425 0.611218
+v -0.727847 0.437537 0.596934
+v -0.719433 0.48306 0.554236
+v -0.715014 0.473054 0.564204
+v -0.414267 0.385333 0.153283
+v -0.415333 0.385436 0.140425
+v -0.418159 0.404961 0.153244
+v 0.735811 -0.0580479 0.214555
+v 0.727281 -0.0405655 0.214504
+v 0.734526 -0.0579837 0.227413
+v 0.74014 -0.0580479 0.11178
+v 0.740268 -0.0579837 0.124625
+v 0.73468 -0.058703 0.0605399
+v 0.731379 -0.0589342 0.0477588
+v 0.722298 -0.0408352 0.0604114
+v -0.932344 -0.186488 0.217818
+v -0.934951 -0.16898 0.217702
+v -0.923378 -0.204805 0.128183
+v -0.901669 0.372077 0.0992942
+v -0.740756 0.0710602 0.684821
+v -0.727359 0.0747083 0.686954
+v -0.170335 0.669497 -0.170727
+v -0.157515 0.669548 -0.172461
+v 0.801065 -0.379964 0.0479387
+v 0.776941 -0.164908 0.0605399
+v -0.741437 0.687622 -0.185229
+v -0.74646 0.699401 -0.214131
+v 0.6596 0.0150932 0.368891
+v 0.66484 0.0107772 0.365115
+v 0.657904 0.0237638 0.362571
+v -0.728592 0.688071 -0.172911
+v -0.98298 0.0929743 0.216392
+v -0.911355 -0.308685 0.244138
+v -0.921798 -0.290792 0.244074
+v -0.921811 -0.29083 0.231228
+v -0.792677 0.833018 -0.571218
+v -0.784918 0.843063 -0.56116
+v -0.789902 0.843075 -0.573376
+v -0.148575 0.59994 -0.109558
+v -0.1374 0.598116 -0.103238
+v -0.14846 0.586247 -0.0897501
+v 0.772214 -0.12889 0.124612
+v 0.765098 -0.111471 0.124625
+v 0.772266 -0.128864 0.137458
+v -0.32882 0.483638 0.037945
+v -0.328499 0.483613 0.05115
+v -0.345802 0.47236 0.0369174
+v -0.574846 0.599914 -0.334633
+v -0.575052 0.640325 -0.347491
+v -0.576645 0.640389 -0.334607
+v -0.574949 0.62012 -0.334607
+v -0.916685 0.425745 0.162763
+v -0.909184 0.425578 0.149738
+v -0.907989 0.408018 0.150585
+v -0.572675 0.797243 -0.774623
+v -0.569695 0.81515 -0.77032
+v -0.207484 -0.978529 0.294376
+v 0.488359 -0.164034 -0.26496
+v 0.475642 -0.163752 -0.268711
+v 0.477826 -0.149314 -0.266835
+v 0.325866 -0.584371 0.72847
+v 0.312789 -0.58396 0.732567
+v 0.313111 -0.602149 0.731784
+v -0.451891 0.47606 -0.00733466
+v -0.196886 0.136597 0.370343
+v -0.206623 0.129853 0.386284
+v -0.196039 0.123726 0.390176
+v -0.198428 0.867533 -0.0491204
+v -0.214985 0.862408 -0.0549907
+v -0.211466 0.853634 -0.0350034
+v 0.0706042 0.252962 0.16442
+v -0.923712 -0.100232 0.191678
+v 0.151273 0.252513 0.32374
+v 0.210811 0.274119 0.197329
+v 0.22435 0.267735 0.275878
+v 0.216116 0.26356 0.291511
+v 0.296823 0.268377 0.0822228
+v -0.573986 -0.827661 0.426708
+v -0.544711 -0.812658 0.426579
+v -0.567807 -0.828355 0.413863
+v 0.322205 0.272654 0.146462
+v 0.222898 0.228325 0.386965
+v -0.920462 -0.204985 0.115389
+v -0.960128 0.231485 0.125833
+v 0.234934 0.225114 0.39146
+v 0.224594 0.216841 0.406477
+v -0.177439 0.197407 0.243547
+v -0.680139 0.804655 -0.482508
+v -0.690762 0.810808 -0.486439
+v -0.687333 0.802703 -0.466772
+v -0.586587 0.500581 -0.167297
+v -0.589631 0.479592 -0.154747
+v 0.982736 -0.5264 0.227298
+v 0.975581 -0.508879 0.214311
+v -0.916159 -0.308814 0.179937
+v -0.925818 -0.290792 0.179821
+v -0.917084 -0.308531 0.167104
+v 0.187278 0.180053 0.449919
+v -0.481859 0.576497 0.183444
+v -0.489258 0.573787 0.199282
+v -0.47288 0.567056 0.186347
+v -0.931059 0.409457 0.432822
+v -0.926229 0.427337 0.432861
+v -0.92921 0.427312 0.420041
+v -0.594577 0.689446 -0.744886
+v -0.608707 0.708405 -0.750666
+v -0.595527 0.708084 -0.753518
+v 0.345249 0.25909 0.0635457
+v 0.348178 0.253746 0.0461018
+v -0.589888 0.499528 -0.206064
+v -0.589696 0.497614 -0.198331
+v -0.593639 0.493529 -0.214516
+v 0.556298 -0.92296 -0.0127939
+v 0.56949 -0.925542 -0.00557486
+v 0.530492 -0.943628 0.00879903
+v -0.170335 0.650023 -0.161491
+v -0.183116 0.650075 -0.15959
+v -0.760448 -0.547068 0.103996
+v -0.757763 -0.547646 0.0909961
+v -0.715117 -0.0779966 0.503857
+v -0.728027 -0.0783049 0.499066
+v -0.728014 -0.096314 0.502174
+v -0.71504 -0.0959415 0.508584
+v 0.759176 -0.904412 0.142968
+v 0.747307 -0.910616 0.170367
+v 0.741887 -0.913635 0.14749
+v -0.715181 -0.0599747 0.501069
+v -0.132069 0.72707 -0.203482
+v -0.119301 0.727095 -0.205306
+v -0.119224 0.707827 -0.194157
+v -0.621398 0.671372 -0.731964
+v -0.267086 -0.710435 -0.118395
+v -0.267176 -0.691822 -0.121658
+v -0.721719 0.400735 -0.0741045
+v -0.708938 0.400773 -0.080707
+v -0.708412 0.382199 -0.0747468
+v -0.218813 -0.0392938 -0.237368
+v -0.196527 -0.0488892 -0.244998
+v -0.260329 0.687891 -0.157792
+v -0.473407 -0.565116 -0.11819
+v -0.47324 -0.543459 -0.146565
+v -0.460523 -0.564422 -0.124651
+v -0.71373 0.0760955 0.687686
+v -0.71495 0.0951066 0.699658
+v -0.234292 0.630922 -0.142557
+v -0.221434 0.611359 -0.130097
+v -0.234202 0.61168 -0.129519
+v -0.714976 0.113373 0.706119
+v -0.714963 0.131497 0.708058
+v -0.714937 0.149686 0.709138
+v -0.714924 0.167644 0.707108
+v -0.714744 0.185807 0.703254
+v -0.714886 0.203829 0.699285
+v -0.309565 0.747442 -0.1195
+v -0.325827 0.725798 -0.113591
+v -0.324247 0.747558 -0.106911
+v 0.248486 -0.747738 0.701084
+v 0.248679 -0.729536 0.706723
+v 0.235615 -0.729009 0.707069
+v -0.422411 0.404665 0.0889152
+v -0.415719 0.423548 0.089095
+v -0.420279 0.404948 0.101966
+v 0.773255 -0.201581 0.0094156
+v 0.768322 -0.201967 -0.00342969
+v 0.766935 -0.183791 0.00933853
+v 0.235576 -0.747853 0.699401
+v 0.312802 -0.676241 0.701816
+v 0.299918 -0.67592 0.704732
+v 0.274279 -0.582945 0.743756
+v 0.28706 -0.583266 0.740313
+v 0.287227 -0.548224 0.734006
+v 0.273894 0.0513298 0.543266
+v 0.274048 0.0692747 0.534107
+v 0.261126 0.0691719 0.536933
+v 0.2611 0.0337318 0.551641
+v 0.273842 0.0335648 0.549625
+v 0.261126 0.0515225 0.545052
+v 0.261331 -0.729215 0.707558
+v 0.24846 -0.711141 0.708958
+v 0.261498 -0.693749 0.706813
+v 0.248756 -0.693556 0.709741
+v -0.685663 0.473092 -0.3227
+v -0.679754 0.474981 -0.334235
+v -0.679381 0.471268 -0.31706
+v -0.00848432 -0.127348 0.582598
+v 0.0047078 -0.115145 0.584423
+v -0.00843294 -0.109583 0.581532
+v -0.263759 -0.945568 0.593761
+v -0.267625 -0.92752 0.590537
+v -0.274767 -0.946056 0.580518
+v -0.714565 0.325179 0.65881
+v -0.706935 0.34338 0.647326
+v -0.71522 0.401634 0.619593
+v -0.715156 0.419643 0.60834
+v -0.715117 0.43737 0.595161
+v -0.715053 0.455173 0.58044
+v -0.618957 0.593414 -0.605861
+v -0.622708 0.589047 -0.621867
+v -0.611956 0.608739 -0.613235
+v -0.409103 0.365616 0.153347
+v -0.410863 0.365564 0.140528
+v -0.419816 0.424768 0.141863
+v -0.421294 0.424922 0.153411
+v -0.715412 0.508969 -0.477922
+v 0.73048 -0.0403856 0.124625
+v 0.7424 -0.076635 0.047823
+v -0.928259 -0.117252 0.217432
+v -0.924983 -0.100103 0.217317
+v -0.918098 -0.0829421 0.217227
+v 0.29067 -0.91059 0.428185
+v 0.278454 -0.909087 0.42428
+v 0.285943 -0.911143 0.404524
+v 0.226482 -0.903435 0.617512
+v 0.240406 -0.902601 0.614956
+v 0.235345 -0.883166 0.615714
+v -0.578546 0.699658 -0.707301
+v -0.57518 0.720184 -0.707211
+v -0.575977 0.720377 -0.694353
+v 0.093289 0.881971 -0.349392
+v 0.0971683 0.861919 -0.349932
+v 0.0872517 0.874251 -0.360349
+v -0.889736 -0.37945 0.244497
+v -0.893654 -0.361685 0.244279
+v -0.892472 -0.37918 0.231614
+v -0.927321 0.443818 0.163354
+v -0.920385 0.443612 0.15038
+v 0.76014 -0.111741 0.0605913
+v -0.715117 0.68748 -0.161067
+v -0.728425 0.668662 -0.136597
+v -0.741488 0.668431 -0.150483
+v 0.713717 -0.0225307 0.253181
+v 0.72145 -0.040604 0.265988
+v 0.931907 -0.623151 0.0244446
+v 0.939486 -0.619285 0.0341428
+v 0.945176 -0.636729 0.0345153
+v -0.916801 0.408249 0.163611
+v 0.317516 -0.144034 -0.272706
+v 0.304389 -0.143199 -0.273656
+v 0.318262 -0.155698 -0.286129
+v 0.30566 -0.153321 -0.288467
+v -0.597891 0.489265 -0.231729
+v -0.591468 0.505411 -0.238023
+v -0.593459 0.49922 -0.231768
+v 0.0794161 0.709883 -0.234735
+v 0.0638861 0.708701 -0.233669
+v 0.854232 -0.770243 -0.0149776
+v 0.868092 -0.768791 -0.00224793
+v 0.852202 -0.787802 -0.00159282
+v 0.763441 -0.561275 0.370741
+v 0.759575 -0.554955 0.374774
+v 0.759626 -0.572322 0.374723
+v -0.667474 0.467119 -0.312333
+v -0.653395 0.474929 -0.3311
+v -0.643877 0.474467 -0.322353
+v -0.575245 0.599888 -0.360285
+v -0.573305 0.62012 -0.360323
+v -0.573356 0.620107 -0.347465
+v 0.671687 -0.054554 -0.0850102
+v 0.678868 -0.0621456 -0.0805143
+v 0.681668 -0.0752734 -0.088427
+v 0.273675 -0.159603 0.674789
+v 0.286328 -0.160284 0.671257
+v 0.266289 -0.146257 0.655714
+v -0.159712 0.601789 -0.115877
+v -0.160341 0.588482 -0.0949011
+v -0.392739 0.303457 0.277137
+v -0.390709 0.292937 0.297048
+v -0.53834 -0.795574 0.0931156
+v -0.534294 -0.795663 0.106321
+v -0.527524 -0.779555 0.0928587
+v -0.398159 0.304729 0.294055
+v -0.403708 0.305911 0.310946
+v -0.40954 0.306861 0.327696
+v -0.202795 0.873544 -0.0692618
+v 0.0645027 0.252667 0.18072
+v 0.159494 0.25679 0.308094
+v 0.203977 0.272873 0.213206
+v 0.292802 0.271768 0.0991272
+v 0.316849 0.274029 0.162763
+v 0.233919 0.238036 0.37227
+v -0.926371 -0.256855 0.12835
+v -0.255204 -0.521596 -0.190226
+v -0.255345 -0.50238 -0.201671
+v -0.24241 -0.521095 -0.195159
+v -0.715323 -0.238833 0.55141
+v -0.702182 -0.256662 0.555777
+v -0.702374 -0.238473 0.55624
+v -0.610543 0.381659 -0.0747339
+v -0.607101 0.40017 -0.0760442
+v -0.610595 0.45114 -0.174709
+v -0.601809 0.465192 -0.184715
+v -0.634949 0.474325 -0.312539
+v -0.622438 0.48527 -0.328416
+v -0.615669 0.487261 -0.31602
+v -0.58362 0.539759 -0.295981
+v -0.590505 0.519335 -0.295994
+v -0.589541 0.523163 -0.304703
+v -0.0507325 -0.947623 -0.219346
+v -0.0373349 -0.947058 -0.217201
+v -0.0509766 -0.931682 -0.210072
+v -0.933243 0.409585 0.42008
+v -0.913127 -0.0831605 0.25557
+v -0.908965 -0.0831219 0.268467
+v -0.903198 -0.0658964 0.255634
+v -0.977816 0.178986 0.151626
+v -0.973462 0.178845 0.138806
+v -0.974926 0.161581 0.138832
+v 0.0381698 0.687891 -0.200823
+v 0.0498847 0.685451 -0.194606
+v 0.0377844 0.674378 -0.17995
+v 0.164876 0.174889 0.460542
+v 0.340638 0.262275 0.0799106
+v -0.767269 -0.52956 0.0908291
+v -0.205377 -0.257214 -0.295994
+v -0.205531 -0.238935 -0.291678
+v -0.724391 -0.119538 0.512553
+v -0.715374 -0.113565 0.515559
+v -0.728373 -0.114041 0.50762
+v -0.874232 0.442739 0.0990244
+v -0.702246 -0.0777654 0.507145
+v -0.702503 -0.0953763 0.514159
+v -0.702233 -0.0598591 0.502341
+v -0.702323 -0.0420041 0.498693
+v -0.715271 -0.042017 0.500157
+v -0.0757423 0.602958 -0.0639567
+v -0.068292 0.607223 -0.0633787
+v -0.0608418 0.616677 -0.0448943
+v -0.13275 0.803101 -0.218974
+v -0.132994 0.82215 -0.215917
+v -0.119866 0.82215 -0.225255
+v -0.234099 0.593055 -0.116083
+v -0.233264 0.604435 -0.124381
+v -0.229012 0.586979 -0.110559
+v -0.267304 -0.673248 -0.124921
+v 0.569837 -0.273939 -0.263187
+v 0.580177 -0.280747 -0.256199
+v 0.566214 -0.293194 -0.266167
+v 0.171478 0.0340657 0.558154
+v 0.158594 0.0340529 0.556715
+v 0.158916 0.0156584 0.564435
+v -0.231402 -0.148093 -0.272076
+v -0.231479 -0.12984 -0.268736
+v -0.218582 -0.129738 -0.270175
+v -0.218543 -0.2962 -0.299514
+v -0.486907 -0.428005 -0.228377
+v -0.499727 -0.428198 -0.228736
+v -0.486997 -0.409482 -0.233605
+v -0.47351 -0.524281 -0.161491
+v -0.460639 -0.524307 -0.161491
+v -0.702002 0.0764038 0.689125
+v -0.702028 0.0950295 0.699863
+v -0.702066 0.113488 0.705528
+v -0.70204 0.131574 0.707365
+v -0.702028 0.149622 0.707249
+v -0.702053 0.16776 0.705849
+v -0.702015 0.18564 0.702201
+v -0.70204 0.203791 0.697769
+v -0.701976 0.221838 0.690101
+v 0.158376 -0.402674 0.766466
+v 0.158466 -0.385397 0.761212
+v 0.145582 -0.402944 0.764565
+v -0.692445 0.216713 0.690242
+v -0.689169 0.203701 0.694622
+v 0.338763 -0.829703 0.612978
+v 0.350747 -0.843602 0.594609
+v 0.357029 -0.824167 0.603202
+v 0.235692 -0.244369 0.734815
+v 0.248576 -0.24451 0.731899
+v 0.235705 -0.226642 0.730268
+v 0.29979 -0.0387928 0.552104
+v 0.31261 -0.0390882 0.55001
+v 0.299803 -0.020591 0.550665
+v 0.235615 -0.767044 0.690627
+v 0.24846 -0.766466 0.691462
+v 0.312661 -0.657641 0.707339
+v 0.322205 -0.640479 0.713197
+v 0.309951 -0.640608 0.717898
+v 0.287279 -0.601083 0.740942
+v 0.274292 -0.60071 0.745143
+v 0.274074 0.0869113 0.522868
+v 0.261151 0.0868471 0.527248
+v 0.261241 -0.747352 0.703768
+v 0.261357 -0.711334 0.70775
+v 0.31997 -0.165216 -0.301839
+v 0.307883 -0.161889 -0.305153
+v 0.685213 -0.75619 0.425899
+v 0.685419 -0.738271 0.424499
+v 0.672869 -0.756511 0.425449
+v 0.235859 -0.421416 0.757744
+v 0.223181 -0.420876 0.764411
+v 0.222949 -0.43868 0.765901
+v 0.158492 -0.314684 0.755483
+v 0.158543 -0.296958 0.753557
+v 0.145659 -0.296996 0.753646
+v -0.702477 0.383766 0.62635
+v 0.825869 -0.810153 -0.00143867
+v 0.838547 -0.789459 -0.014451
+v 0.843968 -0.805631 0.0117663
+v -0.702554 0.401505 0.616176
+v -0.7024 0.419579 0.605103
+v -0.702529 0.436881 0.5929
+v -0.702259 0.455366 0.577448
+v -0.602181 0.485347 -0.247863
+v -0.59518 0.498988 -0.244652
+v -0.406496 0.346142 0.140425
+v -0.417594 0.405025 0.140438
+v 0.993603 -0.650126 0.1502
+v 0.997983 -0.631835 0.1502
+v 0.995376 -0.649998 0.163097
+v 0.998715 -0.61398 0.150097
+v 1 -0.614545 0.16239
+v 0.998677 -0.631847 0.163033
+v 0.718598 -0.0413362 0.0476946
+v 0.794719 -0.199924 0.111805
+v 0.794539 -0.199963 0.124625
+v 0.798213 -0.217664 0.124651
+v 0.800101 -0.253759 0.0733338
+v 0.802234 -0.253618 0.0863076
+v 0.802671 -0.271652 0.0862562
+v 0.801579 -0.271742 0.0733852
+v 0.75987 -0.23828 0.36857
+v 0.757596 -0.243161 0.374466
+v 0.761681 -0.256302 0.368673
+v -0.348307 0.479489 -0.00461146
+v -0.200868 -0.981586 0.205936
+v -0.208935 -0.980584 0.226565
+v -0.213649 -0.981124 0.202891
+v 0.901091 -0.678347 -0.0140656
+v 0.90122 -0.659773 -0.017688
+v 0.918805 -0.64721 -0.00259475
+v 0.877533 -0.732619 -0.0166989
+v 0.895645 -0.730165 -0.00240207
+v 0.881798 -0.749382 -0.0021837
+v -0.935863 0.356778 0.471769
+v -0.933654 0.374299 0.471564
+v -0.224478 -0.977553 0.266887
+v -0.212198 -0.979056 0.270792
+v -0.231402 -0.974457 0.285834
+v -0.10404 0.606683 -0.104111
+v -0.0923127 0.618154 -0.118613
+v -0.0936743 0.60563 -0.0965966
+v 0.764045 -0.11133 0.111793
+v -0.415822 0.306681 0.34437
+v -0.2011 0.117701 0.399335
+v 0.946474 -0.654468 0.0347594
+v 0.955388 -0.653569 0.0478616
+v 0.955375 -0.618026 0.0478616
+v -0.194908 -0.685579 -0.13941
+v -0.203116 -0.672156 -0.134811
+v -0.194985 -0.667532 -0.152345
+v 0.889017 -0.71398 -0.0155043
+v 0.902312 -0.711963 -0.00289019
+v -0.442553 0.324665 0.0126526
+v -0.585958 0.67976 -0.655727
+v -0.582643 0.700146 -0.655778
+v 0.171427 0.0163135 0.564731
+v 0.300599 -0.10889 0.612708
+v 0.301062 -0.0926403 0.597345
+v 0.287998 -0.109892 0.605579
+v 0.723621 -0.73732 0.431897
+v 0.723621 -0.719465 0.428802
+v 0.710827 -0.737641 0.428712
+v 0.72371 -0.701623 0.42577
+v 0.711263 -0.702073 0.422675
+v 0.710852 -0.719799 0.425809
+v 0.312918 -0.476214 0.742728
+v 0.325763 -0.476445 0.73926
+v 0.325493 -0.458295 0.741546
+v 0.171363 -0.385385 0.762291
+v 0.17135 -0.367902 0.757962
+v 0.913795 -0.670319 -0.00445732
+v 0.665187 -0.00223508 0.377536
+v 0.672894 -0.00217086 0.365551
+v -0.187034 0.87822 -0.0631218
+v -0.279738 0.830025 -0.060116
+v -0.319366 0.780634 0.0173925
+v -0.62231 0.582483 -0.58116
+v 0.0222545 0.956101 -0.262699
+v -0.712869 0.592823 0.287169
+v -0.720037 0.85217 -0.55281
+v -0.530389 0.582509 0.240091
+v -0.51834 0.579336 0.244459
+v -0.14774 0.111664 0.407877
+v 0.0575919 0.251331 0.196751
+v 0.0507325 0.249803 0.212821
+v 0.155486 0.26469 0.121671
+v -0.895234 0.407581 0.1251
+v -0.267394 -0.654532 -0.129815
+v -0.254549 -0.654622 -0.128209
+v 0.167715 0.261325 0.292475
+v 0.197169 0.271087 0.229134
+v 0.231106 0.269661 0.260027
+v 0.287381 0.273258 0.115441
+v -0.823878 -0.489226 0.180849
+v 0.310863 0.274427 0.178871
+v 0.244273 0.24645 0.357382
+v 0.231556 0.248634 0.352847
+v -0.464865 0.348609 0.0045087
+v -0.466137 0.360786 0.00990372
+v -0.23469 0.688071 -0.16609
+v -0.221935 0.688097 -0.169596
+v -0.221716 0.669022 -0.162814
+v -0.689324 -0.274735 0.557396
+v -0.689324 -0.256533 0.55737
+v -0.144644 0.669728 -0.173874
+v -0.132737 0.657345 -0.166706
+v -0.689683 -0.23846 0.558411
+v -0.689439 -0.220027 0.559426
+v -0.702259 -0.220207 0.555983
+v -0.276052 -0.927687 0.581378
+v -0.671173 0.421917 -0.138267
+v -0.674166 0.412 -0.112563
+v -0.589297 0.479746 -0.141876
+v -0.591571 0.471692 -0.154876
+v -0.780808 0.83303 -0.539888
+v -0.769016 0.847802 -0.552707
+v -0.706061 -0.274568 0.553363
+v -0.691173 -0.292128 0.557152
+v -0.689311 -0.183803 0.557447
+v -0.68967 -0.165769 0.551718
+v -0.702452 -0.184086 0.551461
+v 0.0596214 0.784616 -0.311126
+v 0.0672516 0.782908 -0.314235
+v 0.0710923 0.765387 -0.30076
+v -0.862119 0.442495 0.0731797
+v -0.867103 0.442636 0.0858965
+v -0.861746 0.460221 0.0733723
+v -0.470324 -0.611706 0.411281
+v -0.460857 -0.629638 0.393143
+v -0.45446 -0.629253 0.404717
+v -0.867154 0.460414 0.0857167
+v -0.689208 -0.0775856 0.511564
+v -0.689362 -0.0951708 0.520029
+v -0.689375 -0.0597178 0.50396
+v -0.691302 -0.0420555 0.499412
+v -0.689324 -0.0238923 0.498577
+v -0.70213 -0.0241235 0.500684
+v -0.629991 0.555032 -0.550524
+v -0.62398 0.570845 -0.557756
+v -0.619201 0.574878 -0.541725
+v 0.287458 -0.126526 0.61949
+v 0.33821 -0.160374 0.649805
+v 0.338429 -0.142454 0.63949
+v 0.325622 -0.14302 0.638732
+v -0.64177 -0.247079 -0.204716
+v -0.64204 -0.228685 -0.201928
+v -0.628964 -0.227927 -0.211357
+v 0.145788 -0.787019 0.665361
+v 0.158582 -0.787237 0.667288
+v 0.145711 -0.767789 0.682856
+v -0.499855 -0.409701 -0.234067
+v -0.5001 -0.390947 -0.244562
+v -0.509181 -0.626517 -0.0392295
+v -0.496875 -0.643511 -0.0514197
+v -0.503979 -0.640916 -0.0375597
+v -0.689182 0.095158 0.697795
+v -0.71319 0.0578938 0.678514
+v -0.698791 0.0604628 0.679979
+v -0.689131 0.113308 0.702663
+v -0.689067 0.131459 0.704744
+v -0.688938 0.149622 0.704976
+v -0.688964 0.167593 0.70513
+v -0.689247 0.185576 0.700583
+v 0.363824 -0.212037 0.685772
+v 0.363657 -0.195403 0.671334
+v 0.350901 -0.19494 0.674776
+v -0.676838 0.199141 0.690486
+v -0.680807 0.217021 0.684654
+v 0.351043 -0.211755 0.688983
+v 0.363888 -0.177638 0.656613
+v 0.35085 -0.177984 0.660557
+v 0.349578 -0.822857 0.615097
+v 0.350375 -0.808098 0.630614
+v 0.0720685 0.813724 -0.338178
+v 0.0734045 0.822459 -0.34356
+v 0.29988 -0.0569175 0.558102
+v 0.312725 -0.0566349 0.560196
+v 0.325404 -0.0212975 0.541994
+v 0.312635 -0.00715483 0.544114
+v 0.312622 -0.0209507 0.545591
+v 0.222718 0.0519207 0.551783
+v 0.222731 0.0696087 0.54211
+v 0.209924 0.0695701 0.5436
+v 0.209911 0.0340529 0.560774
+v 0.222718 0.0342841 0.560029
+v 0.209911 0.0518565 0.55308
+v 0.287317 -0.619053 0.73854
+v 0.274279 -0.618925 0.742009
+v 0.274074 0.104278 0.509611
+v 0.26119 0.104484 0.514428
+v 0.261267 -0.766106 0.694442
+v 0.895825 -0.694661 -0.0152602
+v 0.887912 -0.695753 -0.0220554
+v 0.864649 -0.786595 0.0109442
+v 0.862889 -0.732079 -0.0278229
+v 0.875259 -0.713775 -0.0256135
+v 0.865163 -0.560723 0.373451
+v 0.878072 -0.560903 0.371781
+v 0.802683 -0.289777 0.0862947
+v 0.803852 -0.289661 0.0991657
+v -0.451737 0.456894 0.00473991
+v -0.464762 0.475816 -0.00439309
+v -0.118119 0.709086 -0.082865
+v -0.125852 0.727519 -0.0940918
+v -0.130386 0.709215 -0.0778939
+v -0.571558 0.785631 -0.773248
+v -0.584686 0.798387 -0.775047
+v -0.689606 0.41954 0.600299
+v -0.692355 0.379913 0.623421
+v 0.844302 -0.861033 0.163906
+v 0.825073 -0.872427 0.173206
+v 0.842581 -0.861007 0.151151
+v -0.614513 0.622201 -0.693184
+v -0.606112 0.636176 -0.702895
+v -0.600216 0.638925 -0.690165
+v -0.404646 0.346206 0.153283
+v 0.890943 -0.527004 0.342289
+v 0.90682 -0.532836 0.343265
+v 0.789915 -0.182133 0.111793
+v 0.789748 -0.182159 0.124612
+v -0.267458 -0.972633 0.482045
+v -0.280162 -0.972094 0.478821
+v -0.271954 -0.972376 0.458217
+v 0.799022 -0.217753 0.111844
+v 0.797892 -0.235878 0.073398
+v 0.799613 -0.235737 0.0862176
+v -0.136603 -0.0111497 -0.233528
+v -0.136064 -0.0242648 -0.245538
+v -0.150566 -0.0267311 -0.243226
+v -0.455141 0.329045 0
+v -0.909132 0.336547 0.0738862
+v -0.901541 0.336444 0.0610409
+v -0.908657 0.318653 0.0614647
+v 0.0541622 -0.190894 -0.404293
+v 0.0549843 -0.20257 -0.418089
+v 0.0412398 -0.202583 -0.418153
+v 0.941657 -0.672695 0.0349264
+v 0.949428 -0.671963 0.0477074
+v 0.956865 -0.635637 0.0479001
+v 0.707513 -0.0235326 0.047579
+v 0.69739 -0.00610152 0.0477074
+v 0.699844 -0.00542072 0.0603087
+v 0.711161 -0.0230702 0.0603344
+v 0.778778 -0.146591 0.11178
+v 0.771868 -0.129057 0.111818
+v 0.805946 -0.289469 0.124728
+v 0.805291 -0.289533 0.111985
+v 0.805021 -0.271434 0.124689
+v 0.778894 -0.146526 0.124612
+v 0.805407 -0.361634 0.0736678
+v 0.807372 -0.361415 0.086436
+v 0.808875 -0.379257 0.086436
+v 0.73021 -0.872864 -0.00161851
+v 0.718393 -0.891155 0.0118562
+v 0.704237 -0.893172 0.00491975
+v -0.244452 -0.0575598 -0.242327
+v -0.257323 -0.0576754 -0.240824
+v -0.244517 -0.039191 -0.240605
+v 0.555989 -0.790834 -0.214889
+v 0.550582 -0.781611 -0.232898
+v 0.562168 -0.780634 -0.220361
+v -0.546959 -0.90341 0.271819
+v 0.338596 -0.124972 0.632515
+v 0.338814 -0.107836 0.624114
+v 0.326007 -0.125344 0.630293
+v 0.338827 -0.0908419 0.609689
+v 0.338737 -0.0736549 0.592245
+v 0.325982 -0.0908805 0.605155
+v 0.723967 -0.684025 0.419746
+v 0.711662 -0.684218 0.420491
+v -0.553947 -0.811592 0.452296
+v -0.581706 -0.826852 0.439515
+v -0.605225 0.618411 -0.591616
+v -0.615116 0.59773 -0.589779
+v 0.46737 -0.120527 0.61046
+v 0.466612 -0.143598 0.618463
+v 0.483324 -0.137046 0.611205
+v -0.608822 0.621725 -0.161067
+v -0.28945 0.821842 -0.045087
+v -0.134548 0.125396 0.393156
+v -0.109371 0.149802 0.363368
+v -0.122551 0.13661 0.378371
+v -0.724199 0.577306 0.377202
+v -0.530787 0.584307 0.202635
+v -0.883801 -0.380696 0.103263
+v -0.882376 -0.0327298 0.0884142
+v -0.714205 0.88251 -0.605926
+v -0.703582 0.876499 -0.601969
+v -0.20566 0.210766 0.214221
+v -0.194394 0.20591 0.21837
+v -0.0967315 0.161774 0.348544
+v 0.160868 0.263842 0.105229
+v 0.174625 0.262802 0.276405
+v 0.190412 0.269379 0.245037
+v 0.246855 0.27593 0.228878
+v 0.238582 0.272526 0.24433
+v 0.282642 0.275172 0.132037
+v -0.180008 -0.147721 -0.275377
+v 0.306033 0.276007 0.195493
+v 0.240509 0.254106 0.33742
+v 0.253162 0.252384 0.342122
+v 0.378853 0.236572 0.0208479
+v 0.360266 0.245332 0.0295185
+v 0.376207 0.243508 0.0378808
+v -0.760859 -0.547274 0.116789
+v -0.771803 -0.529034 0.10379
+v 0.245942 0.234607 0.376598
+v 0.265878 0.250149 0.346669
+v 0.256257 0.243277 0.361852
+v -0.67924 -0.274838 0.563074
+v 0.305635 0.268801 0.268647
+v 0.293085 0.271216 0.264112
+v 0.298184 0.266219 0.284292
+v -0.676363 -0.256264 0.562136
+v -0.676427 -0.238126 0.560556
+v -0.676311 -0.219873 0.56184
+v -0.676196 -0.20162 0.563022
+v -0.689169 -0.201812 0.560273
+v -0.676376 -0.183636 0.560389
+v -0.675592 -0.16564 0.555752
+v -0.676324 -0.148119 0.548854
+v -0.689555 -0.148042 0.54491
+v -0.621102 0.70802 -0.745284
+v -0.342167 -0.600864 0.540016
+v -0.348949 -0.606093 0.535302
+v -0.342372 -0.619233 0.537113
+v -0.604725 0.558154 -0.450664
+v -0.593703 0.578681 -0.450587
+v -0.676286 -0.0773672 0.516317
+v -0.67653 -0.0948625 0.524974
+v -0.676298 -0.0596536 0.50807
+v -0.676491 -0.0416316 0.502174
+v -0.676632 -0.0237766 0.499284
+v -0.681694 0.507338 -0.50649
+v -0.667538 0.515353 -0.525257
+v -0.6596 0.516458 -0.514069
+v -0.688746 -0.00813107 0.508674
+v 0.326084 -0.108042 0.620916
+v 0.710737 -0.773903 0.432064
+v 0.723556 -0.773826 0.434261
+v 0.710724 -0.755599 0.430587
+v 0.326046 -0.0742587 0.587081
+v -0.228755 -0.673235 -0.123366
+v -0.228845 -0.654404 -0.129892
+v -0.215923 -0.673068 -0.125023
+v 0.723544 -0.755291 0.433876
+v -0.67635 0.0951323 0.694545
+v -0.689092 0.0765194 0.688906
+v -0.585379 0.746119 -0.76635
+v -0.569374 0.747661 -0.759799
+v -0.584943 0.731964 -0.761444
+v -0.676209 0.113206 0.699748
+v -0.696324 0.400401 -0.0847019
+v -0.682657 0.382546 -0.0794353
+v -0.695656 0.382238 -0.0767507
+v -0.676247 0.131446 0.702586
+v -0.676183 0.149519 0.703049
+v -0.676157 0.167554 0.70134
+v 0.738624 -0.595135 0.401865
+v 0.735194 -0.60581 0.407016
+v 0.737789 -0.61317 0.401647
+v 0.145723 -0.24365 0.748239
+v 0.158633 -0.243675 0.745798
+v 0.145723 -0.225923 0.742445
+v -0.11212 -0.956898 0.702329
+v -0.100675 -0.943783 0.715033
+v -0.118324 -0.942922 0.714044
+v 0.158684 0.0518308 0.548687
+v 0.145723 0.0517794 0.54563
+v 0.145826 0.0336161 0.554429
+v 0.364004 -0.228967 0.697114
+v 0.351107 -0.229057 0.69976
+v 0.158517 -0.767404 0.687557
+v 0.171414 -0.766787 0.691989
+v 0.158325 -0.747956 0.703023
+v 0.222808 -0.244305 0.737436
+v 0.222821 -0.226578 0.732978
+v 0.209989 -0.226437 0.7347
+v 0.313098 -0.0743871 0.580685
+v 0.30015 -0.0745284 0.575816
+v 0.210014 -0.368095 0.756472
+v 0.222885 -0.368133 0.756383
+v 0.209937 -0.350189 0.75786
+v 0.287369 -0.639105 0.731488
+v 0.274074 -0.637114 0.734944
+v 0.274009 0.121953 0.495135
+v 0.261164 0.121722 0.499489
+v 0.248524 -0.805529 0.660788
+v 0.261305 -0.80558 0.662509
+v 0.248486 -0.785695 0.679272
+v 0.24864 -0.825285 0.637037
+v 0.261434 -0.824899 0.640171
+v 0.261318 -0.786107 0.679747
+v 0.24846 -0.847327 0.610075
+v 0.261318 -0.847648 0.60897
+v 0.261216 -0.865914 0.606555
+v 0.24837 -0.865503 0.60933
+v 0.248216 -0.8835 0.612695
+v 0.261126 -0.883628 0.610884
+v -0.477941 0.418898 0.00459862
+v -0.465045 0.418885 0.0129866
+v -0.715207 0.442276 -0.184536
+v -0.69346 0.445488 -0.214067
+v -0.700114 0.441583 -0.180798
+v -0.676594 0.45543 0.569586
+v -0.676825 0.473555 0.555559
+v -0.689491 0.47299 0.559284
+v -0.672894 0.18117 0.696151
+v 0.814347 -0.432745 0.176237
+v 0.784918 -0.16442 0.111831
+v 0.78497 -0.164368 0.124625
+v 0.828066 -0.844553 0.0490433
+v 0.837879 -0.843898 0.0615932
+v 0.805407 -0.864861 0.06194
+v -0.422411 0.345269 0.0637255
+v -0.427549 0.365038 0.0635842
+v -0.422501 0.365128 0.0765066
+v 0.922607 -0.727879 0.0353117
+v 0.928799 -0.70942 0.0352603
+v 0.930327 -0.72707 0.0481185
+v 0.935221 -0.691051 0.0350677
+v 0.943044 -0.690319 0.0478873
+v 0.935761 -0.709048 0.0476304
+v 0.794514 -0.380516 0.0222994
+v 0.79048 -0.38094 0.00972389
+v 0.791277 -0.362803 0.0222994
+v -0.220817 -0.979133 0.292141
+v -0.237747 -0.970308 0.303881
+v -0.815041 -0.0696472 0.420272
+v -0.812934 -0.0523317 0.417665
+v -0.821515 -0.0526914 0.408185
+v -0.385712 -0.0763139 -0.247105
+v -0.398635 -0.0762625 -0.24442
+v -0.385866 -0.0581378 -0.237818
+v 0.743505 -0.889691 0.0365706
+v 0.77373 -0.867122 0.0373284
+v 0.75689 -0.888805 0.0490048
+v 0.819023 -0.843846 0.0372771
+v 0.79531 -0.865323 0.04957
+v -0.614358 0.578578 -0.526696
+v -0.603658 0.598514 -0.527531
+v 0.806113 -0.307478 0.111947
+v 0.807398 -0.307388 0.124754
+v 0.804392 -0.271473 0.111921
+v 0.813551 -0.414775 0.176186
+v 0.812086 -0.39692 0.18898
+v 0.80303 -0.343766 0.0735265
+v 0.805214 -0.343535 0.0862562
+v 0.338698 -0.0566221 0.574236
+v 0.338416 -0.0392038 0.550203
+v 0.325635 -0.0565322 0.566542
+v 0.351107 0.0142583 0.525771
+v 0.337941 0.0324215 0.528276
+v 0.338377 0.0146179 0.529612
+v 0.422501 -0.446348 0.702265
+v 0.410812 -0.446387 0.707699
+v 0.408641 -0.464036 0.704526
+v 0.325519 -0.0389855 0.548905
+v 0.286958 -0.22767 0.717166
+v 0.299803 -0.22794 0.711257
+v 0.286932 -0.210278 0.707981
+v 0.710724 -0.792593 0.430741
+v 0.723633 -0.792568 0.432694
+v 0.299867 -0.280143 0.737526
+v 0.299996 -0.262584 0.728714
+v 0.28706 -0.262558 0.73145
+v 0.915182 -0.746736 0.035209
+v 0.92411 -0.745644 0.0482341
+v -0.814642 -0.472026 0.27083
+v -0.821527 -0.454505 0.283714
+v -0.825509 -0.453824 0.270715
+v -0.446792 -0.732773 0.310355
+v -0.448269 -0.714725 0.310355
+v -0.445096 -0.715111 0.297497
+v -0.955029 0.303098 0.305127
+v -0.956609 0.303072 0.292282
+v -0.643286 0.0462174 -0.118845
+v -0.656054 0.0457806 -0.112255
+v -0.64326 0.0642907 -0.107502
+v 0.234741 -0.156045 0.682573
+v 0.224902 -0.149635 0.679002
+v -0.94059 0.286116 0.446503
+v -0.087059 0.16907 0.333181
+v 0.0423702 0.24591 0.228531
+v 0.0341235 0.241633 0.24424
+v 0.182821 0.266656 0.260721
+v 0.228537 0.254196 0.0211562
+v 0.215486 0.257779 0.033295
+v -0.943943 0.320747 0.305127
+v -0.946602 0.320657 0.292205
+v 0.277259 0.276611 0.14835
+v 0.299366 0.275365 0.211357
+v -0.936441 -0.23855 0.192423
+v 0.262063 0.258075 0.326797
+v 0.248704 0.25864 0.321916
+v -0.934091 0.374261 0.42035
+v -0.933461 0.391923 0.420221
+v -0.935067 0.391846 0.407427
+v 0.357786 0.256957 0.0680929
+v 0.360779 0.251781 0.0506233
+v 0.285069 0.267632 0.279616
+v 0.277722 0.265011 0.295352
+v 0.29094 0.263508 0.300079
+v -0.663839 -0.237792 0.56441
+v -0.663774 -0.219732 0.562894
+v -0.663505 -0.201581 0.563549
+v -0.66353 -0.183508 0.561995
+v -0.663633 -0.165576 0.557576
+v -0.663556 -0.147772 0.552412
+v -0.663697 -0.129892 0.546233
+v -0.663607 -0.112204 0.539451
+v -0.66353 -0.0945928 0.531127
+v -0.66344 -0.0769819 0.522778
+v -0.663659 -0.0591141 0.513594
+v -0.663582 -0.0413619 0.506927
+v -0.663787 -0.0234555 0.501917
+v -0.963943 0.0764552 0.447697
+v -0.952922 0.0649972 0.435417
+v -0.951907 0.0591654 0.447903
+v 0.505276 -0.0049069 0.509766
+v 0.513035 0.0152217 0.495995
+v 0.492508 0.0130123 0.501814
+v 0.299816 -0.210586 0.701893
+v 0.299649 -0.193347 0.6938
+v 0.286906 -0.192885 0.698681
+v 0.736479 -0.701302 0.428815
+v -0.628283 0.566735 -0.573877
+v 0.325326 -0.730615 0.689574
+v 0.325596 -0.712721 0.693826
+v 0.389836 0.0677076 0.497357
+v 0.389848 0.0857424 0.491012
+v 0.376875 0.0854341 0.491949
+v 0.248499 -0.332385 0.75768
+v 0.261395 -0.332488 0.756241
+v 0.248486 -0.314607 0.756126
+v 0.261395 -0.530164 0.736113
+v 0.261421 -0.547788 0.737834
+v 0.104606 0.803499 -0.311396
+v 0.103732 0.789292 -0.31805
+v 0.105775 0.802703 -0.324806
+v 0.235653 -0.565142 0.743332
+v 0.235705 -0.547569 0.740647
+v 0.222808 -0.547325 0.74355
+v -0.058992 0.626324 -0.119513
+v -0.046455 0.637088 -0.135274
+v -0.492534 0.386746 -0.0118562
+v -0.485006 0.382713 -0.00515096
+v -0.475167 0.360323 0.00021837
+v -0.416515 0.424165 0.102056
+v -0.403323 0.443394 0.10248
+v -0.406239 0.444422 0.11494
+v 0.534486 -0.0700583 0.526837
+v 0.762156 -0.665476 0.42243
+v 0.749388 -0.665746 0.419489
+v 0.749208 -0.68319 0.426335
+v -0.417312 0.424627 0.114798
+v 0.196835 -0.674802 0.716331
+v 0.184015 -0.67511 0.713428
+v 0.184144 -0.692541 0.717166
+v 0.797584 -0.217831 0.137419
+v 0.171465 -0.806646 0.649959
+v 0.171543 -0.786325 0.669792
+v 0.171401 -0.82829 0.623292
+v 0.158594 -0.828188 0.624204
+v 0.364081 -0.246232 0.706594
+v 0.351171 -0.24618 0.709407
+v 0.209963 -0.296958 0.75082
+v 0.209937 -0.279642 0.746569
+v 0.197143 -0.279462 0.747339
+v 0.376643 -0.195171 0.667313
+v 0.313393 -0.0915099 0.601571
+v 0.222834 -0.350201 0.757924
+v 0.222795 -0.332295 0.758553
+v 0.209924 -0.332269 0.758463
+v 0.209963 -0.261916 0.742343
+v 0.209976 -0.244176 0.739221
+v 0.197105 -0.244061 0.740698
+v -0.597287 0.644166 -0.672079
+v 0.274125 0.139333 0.480273
+v 0.261203 0.139192 0.483266
+v 0.775721 -0.146706 0.0861277
+v 0.768913 -0.129121 0.0861534
+v 0.770544 -0.129031 0.098973
+v 0.261254 0.157882 0.46676
+v 0.877186 -0.785503 0.0234555
+v 0.889492 -0.784231 0.036198
+v 0.866833 -0.804771 0.0360182
+v -0.579895 0.740647 -0.65583
+v -0.577904 0.740647 -0.668675
+v -0.579933 0.76084 -0.655868
+v 0.796543 -0.2539 0.227362
+v 0.798033 -0.271922 0.227362
+v -0.400548 0.442521 0.0897629
+v -0.640537 0.465334 -0.284138
+v -0.627833 0.476124 -0.30013
+v -0.62073 0.477884 -0.287683
+v -0.992408 0.17968 0.228685
+v -1 0.180065 0.280079
+v -0.999859 0.162763 0.280156
+v -0.701925 0.476946 -0.315301
+v -0.427832 0.450934 0.013115
+v -0.417697 0.463895 0.000770718
+v -0.41595 0.44875 0.0185358
+v -0.663826 0.455314 0.564705
+v -0.66371 0.473311 0.550061
+v -0.304646 0.501108 -0.0179192
+v -0.283322 0.512502 -0.023828
+v -0.374061 0.499733 -0.0322674
+v -0.650955 0.473182 0.545154
+v 0.806139 -0.343406 0.201761
+v 0.804803 -0.3255 0.201774
+v 0.804263 -0.325564 0.214581
+v -0.591211 0.659208 -0.65574
+v 0.904046 -0.765528 0.0355943
+v 0.91332 -0.764591 0.0483369
+v -0.997598 0.197728 0.279963
+v -0.998073 0.145422 0.280272
+v -0.0214709 -0.916923 -0.169815
+v -0.0308223 -0.917707 -0.146976
+v -0.0348686 -0.917488 -0.171999
+v 0.773717 -0.526298 0.00946698
+v 0.76646 -0.545655 -0.0032884
+v 0.768489 -0.526734 -0.00324986
+v 0.899049 -0.783499 0.0487222
+v -0.877289 -0.345205 0.308428
+v -0.881977 -0.344986 0.295596
+v -0.87648 -0.36234 0.295403
+v 0.788425 -0.182185 0.150277
+v 0.784045 -0.164227 0.150303
+v 0.783621 -0.164356 0.16311
+v 0.322218 -0.173489 -0.318718
+v 0.309617 -0.17142 -0.320811
+v -0.575694 0.781161 -0.694275
+v -0.576401 0.78102 -0.681584
+v 0.73644 -0.719157 0.432
+v 0.738084 -0.0765708 0.0348493
+v 0.736492 -0.755008 0.436779
+v 0.73635 -0.737063 0.434184
+v 0.73653 -0.773467 0.436881
+v 0.736581 -0.792272 0.433632
+v -0.607563 0.428391 -0.115454
+v -0.598572 0.442315 -0.126488
+v 0.802041 -0.235596 0.124651
+v -0.93237 -0.134426 0.217535
+v 0.688412 0.0129481 0.0604243
+v 0.26083 -0.159282 0.677911
+v 0.273932 -0.175659 0.692156
+v 0.878972 -0.803319 0.0488635
+v 0.768682 -0.508712 -0.0161851
+v 0.771868 -0.50843 -0.00330124
+v 0.763826 -0.527197 -0.0161722
+v -0.924945 -0.291241 0.154169
+v -0.930083 -0.273553 0.154195
+v -0.927617 -0.2739 0.141273
+v -0.0766928 0.177355 0.317908
+v -0.0641173 0.189494 0.303355
+v -0.040559 0.211459 0.27381
+v -0.0509123 0.203213 0.288994
+v -0.228576 0.858605 -0.108594
+v -0.251389 0.840095 -0.108299
+v -0.23302 0.858657 -0.0983051
+v -0.594821 0.599066 -0.488931
+v -0.603055 0.584769 -0.497062
+v -0.599432 0.598501 -0.50193
+v -0.898651 -0.32726 0.12871
+v 0.0146244 0.691668 -0.11616
+v 0.00352603 0.690692 -0.109827
+v 0.0131729 0.673184 -0.0954149
+v -0.0622547 0.210933 0.0785747
+v -0.0300901 0.219629 0.258602
+v 0.0259025 0.23715 0.259976
+v 0.259674 0.277356 0.19688
+v 0.252917 0.276238 0.212757
+v 0.271864 0.277446 0.164702
+v -0.709349 0.724989 -0.234671
+v 0.286598 0.273605 0.243367
+v 0.293303 0.274902 0.227465
+v 0.265146 0.267015 0.29074
+v 0.270297 0.26234 0.311229
+v 0.257619 0.263984 0.306489
+v 0.353124 0.259848 0.0845349
+v 0.282847 0.260169 0.315789
+v 0.274151 0.256084 0.331627
+v 0.334819 0.270817 0.151035
+v 0.329437 0.272102 0.167349
+v 0.347318 0.268351 0.155608
+v -0.577801 0.775047 -0.773184
+v -0.816543 -0.490883 0.10483
+v -0.650685 -0.219475 0.566979
+v -0.651841 -0.238845 0.572014
+v -0.650634 -0.201607 0.563498
+v -0.650569 -0.183611 0.561571
+v -0.650736 -0.165512 0.55895
+v -0.650608 -0.147631 0.555328
+v -0.650634 -0.129789 0.550511
+v -0.650325 -0.112062 0.544345
+v -0.650608 -0.0942588 0.537499
+v -0.650839 -0.0764167 0.52825
+v -0.650646 -0.05887 0.519669
+v -0.650634 -0.0411949 0.51141
+v -0.650903 -0.0232243 0.504769
+v -0.0206617 -0.916075 0.461596
+v -0.0281505 -0.914046 0.481288
+v -0.0340465 -0.916679 0.459374
+v -0.300342 -0.975176 0.386682
+v -0.313599 -0.975626 0.384318
+v -0.64475 0.571333 -0.6366
+v -0.634089 0.569573 -0.629599
+v -0.645007 0.557653 -0.61615
+v 0.235615 -0.234285 -0.409431
+v 0.244311 -0.247246 -0.411011
+v 0.231414 -0.247002 -0.415789
+v 0.932228 -0.744989 0.0608225
+v 0.762118 -0.700955 0.432308
+v 0.74935 -0.701096 0.431602
+v 0.749273 -0.718964 0.433876
+v 0.286919 0.0691591 0.530973
+v 0.286893 0.0867186 0.519515
+v 0.222744 -0.565077 0.744321
+v 0.235885 -0.529946 0.739966
+v 0.222872 -0.529547 0.743756
+v 0.996622 -0.614172 0.137278
+v 0.993282 -0.614481 0.124497
+v 0.994862 -0.596548 0.137316
+v -0.408988 0.34586 0.127695
+v -0.409964 0.345564 0.114927
+v -0.412418 0.365603 0.127631
+v -0.107239 0.596304 -0.0790628
+v -0.0842844 0.605823 -0.0874765
+v 0.749478 -0.773608 0.437331
+v 0.762311 -0.773454 0.436419
+v 0.749388 -0.754905 0.438487
+v 0.184234 -0.40279 0.768213
+v 0.17135 -0.402687 0.767481
+v 0.171337 -0.420195 0.772092
+v 0.184247 -0.38541 0.761289
+v 0.184221 -0.367876 0.758296
+v 0.197272 -0.636446 0.737256
+v 0.19713 -0.618475 0.744372
+v 0.184298 -0.618835 0.739542
+v 0.184863 -0.636716 0.730923
+v 0.158697 0.104574 0.520569
+v 0.145852 0.104651 0.517576
+v 0.145839 0.0867058 0.52676
+v 0.17153 0.13968 0.494428
+v 0.158607 0.13995 0.491757
+v 0.158633 0.122351 0.506285
+v -0.38525 0.446143 0.0727815
+v -0.396387 0.442662 0.0756588
+v -0.383567 0.446952 0.0641237
+v 0.351171 -0.263598 0.71723
+v 0.343258 -0.276033 0.723499
+v 0.355217 -0.274376 0.71917
+v 0.376489 -0.17819 0.654378
+v 0.376579 -0.160451 0.643537
+v 0.363798 -0.160656 0.646375
+v 0.338596 -0.767519 0.667699
+v 0.33839 -0.750011 0.67967
+v 0.325134 -0.768033 0.67416
+v 0.313393 -0.108453 0.617525
+v -0.360394 0.462033 0.0535392
+v -0.366688 0.459541 0.039859
+v -0.35848 0.463946 0.0505719
+v 0.299983 -0.583677 0.735843
+v 0.300111 -0.601584 0.7361
+v 0.287022 -0.675727 0.706106
+v 0.286778 -0.655984 0.72057
+v 0.274151 -0.67538 0.709009
+v 0.274099 -0.656086 0.722676
+v 0.286906 -0.786055 0.676164
+v 0.287125 -0.767442 0.68951
+v 0.274151 -0.786184 0.678116
+v 0.286893 -0.805182 0.662072
+v 0.274125 -0.805105 0.663665
+v 0.287047 -0.747892 0.701443
+v 0.274099 -0.747429 0.704025
+v 0.274151 -0.766607 0.693505
+v 0.274151 -0.824784 0.641713
+v 0.286842 -0.824655 0.643241
+v 0.287047 -0.847995 0.607878
+v 0.274125 -0.847404 0.61037
+v 0.287227 -0.866223 0.60459
+v 0.274125 -0.865966 0.60572
+v 0.282397 -0.900198 0.607428
+v 0.274151 -0.883975 0.608893
+v 0.267613 -0.901188 0.609291
+v 0.286919 -0.884116 0.606825
+v -0.650903 0.45525 0.556741
+v -0.614474 0.460491 -0.210971
+v -0.604904 0.473927 -0.223149
+v -0.600177 0.477678 -0.207079
+v -0.595707 0.481609 -0.190945
+v 0.803197 -0.253502 0.111844
+v 0.804071 -0.253451 0.124689
+v 0.802632 -0.307683 0.214555
+v 0.802889 -0.325641 0.227452
+v 0.99729 -0.596279 0.15002
+v 0.994014 -0.578758 0.15002
+v 0.996904 -0.578527 0.162943
+v 0.765188 -0.256559 -0.054888
+v 0.760268 -0.23882 -0.0548751
+v 0.763634 -0.238511 -0.0420555
+v 0.847655 -0.823692 0.036699
+v 0.857327 -0.823281 0.049069
+v 0.772022 -0.490459 -0.0162236
+v 0.775015 -0.490125 -0.00331409
+v 0.774886 -0.47209 -0.0161208
+v 0.77892 -0.471474 -0.00296726
+v 0.776916 -0.453991 -0.0162621
+v 0.783159 -0.453426 -0.00333978
+v 0.801168 -0.544371 0.346309
+v 0.813602 -0.544345 0.350638
+v 0.796993 -0.535649 0.338885
+v -0.593806 0.655007 -0.696459
+v -0.59775 0.650563 -0.712516
+v -0.587589 0.670897 -0.703845
+v 0.762156 -0.718797 0.43561
+v 0.749363 -0.736858 0.436933
+v 0.736594 -0.811322 0.425038
+v 0.222757 -0.747352 0.705798
+v 0.222885 -0.767789 0.693325
+v 0.210117 -0.403034 0.764192
+v 0.223052 -0.403355 0.761007
+v 0.210053 -0.385616 0.759504
+v 0.158543 -0.191536 0.72319
+v 0.158582 -0.17467 0.709099
+v 0.145736 -0.174478 0.709304
+v 0.209834 -0.00166989 0.567492
+v 0.209899 0.0163906 0.564769
+v 0.197079 0.0163007 0.564525
+v 0.755336 -0.0939377 0.0733723
+v 0.740384 -0.0579066 0.137458
+v 0.730608 -0.0402957 0.13747
+v 0.755824 -0.0937064 0.098973
+v 0.748245 -0.0757616 0.0989345
+v 0.802131 -0.235608 0.11187
+v 0.951136 -0.689677 0.0605142
+v 0.958124 -0.670961 0.060861
+v 0.958214 -0.688713 0.0736164
+v 0.969865 -0.723332 0.163328
+v 0.976146 -0.704963 0.163277
+v 0.971406 -0.723177 0.176148
+v 0.795644 -0.39841 0.0224279
+v 0.792125 -0.398667 0.0096982
+v 0.779562 -0.435674 -0.0160309
+v 0.78592 -0.435109 -0.00317279
+v -0.0678039 0.212281 0.0952479
+v -0.0740467 0.212217 0.111664
+v -0.0211369 0.225795 0.2432
+v -0.0801996 0.211999 0.128093
+v -0.0129288 0.230008 0.22731
+v -0.0863525 0.211524 0.144548
+v -0.0924926 0.211215 0.161041
+v -0.100251 0.208916 0.177124
+v 0.0177586 0.232397 0.27566
+v -0.462912 -0.784462 0.464987
+v -0.496798 -0.7947 0.517203
+v 0.265801 0.277613 0.18081
+v -0.942273 0.338319 0.304986
+v -0.94533 0.338268 0.292153
+v -0.710082 0.509085 -0.49782
+v -0.713563 0.526143 -0.510601
+v -0.702362 0.513606 -0.516535
+v 0.348987 0.263329 0.101349
+v -0.65098 -0.291023 0.582149
+v -0.657763 -0.274684 0.577794
+v -0.65784 -0.291974 0.578681
+v -0.637917 -0.272359 0.588315
+v -0.637994 -0.254427 0.585283
+v -0.644558 -0.257523 0.582239
+v -0.655785 -0.257612 0.5752
+v -0.650646 -0.272886 0.581532
+v 0.373252 0.24916 0.0553119
+v -0.000892748 -0.927161 -0.331434
+v 0.0158832 -0.910603 -0.329931
+v 0.0104753 -0.932337 -0.32717
+v 0.369823 0.254131 0.0723447
+v -0.638032 -0.219012 0.572361
+v -0.124465 -0.602727 0.521352
+v -0.12494 -0.621314 0.517036
+v -0.119776 -0.617949 0.525077
+v -0.63802 -0.201299 0.565912
+v -0.637878 -0.183457 0.562252
+v -0.637968 -0.165422 0.559323
+v -0.638071 -0.1474 0.556368
+v -0.638187 -0.129275 0.553337
+v -0.637891 -0.1116 0.549214
+v -0.637865 -0.0938349 0.542611
+v -0.637955 -0.0761084 0.533131
+v -0.637994 -0.0584333 0.523459
+v -0.637955 -0.040771 0.515251
+v -0.637853 -0.0230573 0.508417
+v -0.655129 0.430061 -0.15923
+v -0.639985 0.438834 -0.178948
+v -0.62958 0.437806 -0.17142
+v -0.458031 -0.801238 0.530536
+v -0.445212 -0.801868 0.528571
+v -0.4471 -0.796755 0.519091
+v 0.248524 -0.226835 0.728393
+v 0.261344 -0.440196 0.743897
+v 0.261537 -0.422649 0.741341
+v 0.248807 -0.440298 0.744372
+v 0.389823 0.121337 0.474441
+v 0.402514 0.120977 0.472399
+v 0.397453 0.133964 0.464948
+v 0.261537 -0.404871 0.741366
+v 0.248499 -0.422276 0.746517
+v 0.145775 -0.158138 0.691899
+v 0.13293 -0.174696 0.70906
+v 0.222757 -0.674121 0.720955
+v 0.22277 -0.655919 0.725952
+v 0.209899 -0.656163 0.724732
+v 0.460331 -0.0704179 0.577666
+v 0.466586 -0.056712 0.563292
+v 0.453741 -0.056545 0.56807
+v 0.42823 -0.142904 0.625527
+v 0.428179 -0.125152 0.622085
+v 0.41491 -0.123816 0.625476
+v 0.286649 0.0334363 0.546529
+v 0.30006 -0.297471 0.744295
+v 0.286983 -0.280053 0.74039
+v 0.235769 -0.511744 0.743768
+v 0.222949 -0.511564 0.746903
+v 0.261087 -0.0199102 0.562907
+v 0.2611 -0.00174696 0.563074
+v 0.248409 -0.0197175 0.56527
+v 0.235885 -0.439386 0.756228
+v 0.261036 0.0160309 0.559477
+v 0.248255 0.0161979 0.562727
+v 0.132878 -0.261273 0.751861
+v 0.145749 -0.261389 0.750435
+v 0.132878 -0.243457 0.748868
+v 0.197079 -0.314568 0.756113
+v 0.19713 -0.297035 0.750679
+v 0.184234 -0.29706 0.751655
+v 0.184195 -0.314568 0.755548
+v 0.184157 -0.332115 0.758862
+v 0.183784 -0.864116 0.625219
+v 0.184002 -0.846377 0.619015
+v 0.171157 -0.846133 0.622445
+v 0.184298 -0.727917 0.719504
+v 0.184401 -0.709921 0.720557
+v 0.171517 -0.710383 0.716228
+v 0.158427 -0.529689 0.745747
+v 0.171324 -0.529496 0.747301
+v 0.158479 -0.511012 0.756383
+v 0.171414 -0.692811 0.713518
+v 0.158492 -0.693029 0.712567
+v 0.158594 -0.710679 0.713454
+v 0.357234 -0.746723 0.672451
+v 0.351441 -0.729729 0.686504
+v 0.34584 -0.74707 0.678579
+v 0.760474 -0.201864 0.355956
+v 0.753691 -0.202378 0.368699
+v 0.754424 -0.208685 0.37024
+v 0.313303 -0.125666 0.62703
+v 0.300291 -0.12564 0.622766
+v 0.29997 -0.566092 0.732799
+v 0.312725 -0.566362 0.729369
+v 0.28706 -0.693954 0.703152
+v 0.274292 -0.693852 0.705001
+v 0.274202 -0.711488 0.706106
+v 0.286932 -0.711552 0.703935
+v 0.287022 -0.72951 0.704398
+v 0.274138 -0.729176 0.707146
+v 0.298326 -0.640634 0.723447
+v 0.299739 -0.656896 0.713287
+v 0.223026 -0.38586 0.756665
+v -0.292648 0.512181 -0.0328968
+v -0.281537 0.524011 -0.0466413
+v -0.271171 0.52315 -0.0389213
+v 0.301164 -0.621391 0.730345
+v -0.573279 0.729639 -0.756794
+v -0.569528 0.733107 -0.741636
+v -0.252031 0.57737 -0.102236
+v -0.239186 0.574095 -0.0983821
+v -0.249385 0.561173 -0.0861149
+v -0.630762 0.470523 0.531847
+v -0.637878 0.473195 0.535765
+v -0.637287 0.453734 0.546516
+v 0.88506 -0.633016 0.398615
+v 0.883737 -0.616022 0.396611
+v 0.878394 -0.631282 0.401493
+v 0.76741 -0.129185 0.214439
+v 0.758855 -0.111086 0.214594
+v 0.764905 -0.129057 0.227375
+v 0.793268 -0.434569 0.0222352
+v 0.795683 -0.416316 0.0224279
+v -0.408872 0.365667 0.166154
+v -0.414319 0.385295 0.166103
+v -0.409091 0.365564 0.178948
+v -0.448282 0.382456 0.0325114
+v -0.439406 0.381993 0.04185
+v 0.781142 -0.417588 -0.0160309
+v 0.787166 -0.417023 -0.00303149
+v 0.781219 -0.399592 -0.0160823
+v 0.787539 -0.399091 -0.00318563
+v 0.779485 -0.381737 -0.0160823
+v 0.784751 -0.381313 -0.00337831
+v 0.777622 -0.363406 -0.0160309
+v 0.781514 -0.363548 -0.003404
+v -0.964162 0.4264 0.253078
+v 0.0311434 -0.974123 -0.226758
+v 0.0292295 -0.961291 -0.21494
+v 0.0158318 -0.961856 -0.217086
+v 0.0452989 -0.981098 -0.265769
+v 0.0370908 -0.979685 -0.244536
+v 0.032505 -0.980597 -0.268788
+v 0.77847 -0.345783 -0.0163521
+v 0.780744 -0.345577 -0.00363522
+v 0.784803 -0.236944 0.00935138
+v 0.779729 -0.219282 0.0094156
+v 0.783621 -0.21882 0.0220168
+v 0.812998 -0.432848 0.150585
+v 0.812805 -0.414852 0.15056
+v 0.736993 -0.0581635 0.073231
+v 0.725496 -0.0406682 0.0732439
+v 0.761039 -0.111382 0.0732567
+v 0.781604 -0.327478 -0.0163264
+v 0.784302 -0.327157 -0.00344254
+v 0.739934 -0.0581507 0.0989602
+v 0.93833 -0.726402 0.0607711
+v 0.944585 -0.707994 0.0607197
+v 0.944984 -0.725901 0.0734109
+v 0.964213 -0.652657 0.0608739
+v 0.971098 -0.652117 0.0733338
+v 0.96483 -0.670473 0.073398
+v 0.729067 -0.131343 0.36857
+v 0.727962 -0.139449 0.376817
+v 0.735849 -0.149057 0.368699
+v 0.786318 -0.363201 0.00946698
+v 0.312931 -0.369829 0.733428
+v 0.312905 -0.387671 0.731938
+v 0.325904 -0.37015 0.729086
+v -0.10774 0.205602 0.193219
+v -0.116038 0.201286 0.209134
+v -0.124323 0.196995 0.225024
+v 0.015819 0.239179 0.163084
+v 0.00980738 0.23864 0.179462
+v 0.0219976 0.239552 0.146745
+v -0.132596 0.192834 0.240914
+v -0.141549 0.187079 0.256662
+v -0.151285 0.180078 0.272166
+v 0.0467505 0.239835 0.0814906
+v 0.0289212 0.240785 0.130688
+v -0.014239 0.206488 0.320876
+v -0.0273155 0.192551 0.335108
+v 0.00719979 0.224677 0.290895
+v 0.200778 0.25295 0.0228389
+v 0.186597 0.252076 0.0241749
+v 0.18178 0.265795 0.09449
+v 0.439328 0.229378 0.0978812
+v -0.97472 0.231883 0.164291
+v -0.97025 0.231755 0.151485
+v -0.973102 0.214144 0.151613
+v 0.0973995 0.861881 -0.33647
+v -0.59125 -0.843101 0.511307
+v -0.575553 -0.826454 0.513465
+v -0.57897 -0.826402 0.503895
+v -0.625187 -0.382482 0.567248
+v -0.624956 -0.363406 0.576484
+v -0.637917 -0.364036 0.570216
+v -0.637634 -0.345166 0.577781
+v -0.64475 -0.362494 0.567685
+v -0.625046 -0.344973 0.583279
+v 0.0602894 0.803037 -0.324292
+v 0.0594031 0.822754 -0.335622
+v -0.62484 -0.326425 0.587595
+v -0.639266 -0.327054 0.581956
+v -0.375243 -0.677628 0.509085
+v -0.384774 -0.677898 0.500337
+v -0.384363 -0.695573 0.500568
+v -0.624763 -0.308172 0.590717
+v -0.637775 -0.308634 0.586362
+v -0.624956 -0.290137 0.592926
+v -0.63757 -0.290381 0.589175
+v -0.624917 -0.272012 0.592875
+v -0.465893 0.334119 -0.0055877
+v -0.625059 -0.254093 0.589946
+v -0.111067 -0.182095 0.582791
+v -0.103668 -0.184047 0.586465
+v -0.111144 -0.163675 0.586324
+v -0.624943 -0.236353 0.584821
+v -0.625071 -0.218601 0.578616
+v -0.637814 -0.236726 0.580017
+v -0.624853 -0.20108 0.571564
+v -0.625059 -0.183212 0.565617
+v -0.625187 -0.165268 0.561211
+v -0.625161 -0.14722 0.55949
+v -0.62502 -0.129198 0.558835
+v -0.624866 -0.11133 0.555161
+v -0.62493 -0.0936422 0.547274
+v -0.624982 -0.0759928 0.53764
+v -0.624994 -0.0583562 0.527916
+v -0.625084 -0.0405526 0.518475
+v -0.625084 -0.0227747 0.510549
+v -0.613703 -0.00503536 0.505026
+v -0.630633 -0.00950552 0.505257
+v 0.274215 -0.512437 0.736421
+v 0.261357 -0.512232 0.737564
+v 0.145068 -0.863088 0.637769
+v 0.132441 -0.845118 0.634712
+v 0.132223 -0.862613 0.642406
+v 0.505045 -0.232937 0.634262
+v 0.505199 -0.250702 0.637962
+v 0.513934 -0.238871 0.632734
+v 0.261485 -0.386952 0.744025
+v 0.248756 -0.404306 0.748881
+v 0.235602 -0.655637 0.727224
+v 0.222834 -0.636587 0.73935
+v 0.736838 -0.666273 0.414749
+v 0.724584 -0.666427 0.414094
+v 0.42805 -0.107669 0.616754
+v 0.415064 -0.107682 0.620955
+v 0.235628 -0.636741 0.739735
+v 0.235628 -0.618591 0.746941
+v 0.222757 -0.618463 0.746402
+v 0.312417 -0.211035 0.696896
+v 0.325262 -0.211575 0.693415
+v 0.312584 -0.193527 0.687891
+v -0.487074 -0.390317 -0.246899
+v 0.74759 -0.908381 0.100091
+v 0.74407 -0.908214 0.0873609
+v 0.781566 -0.886326 0.0872196
+v 0.325416 -0.228711 0.703087
+v 0.791457 -0.416727 0.0094156
+v 0.235923 -0.49376 0.747262
+v 0.222937 -0.493195 0.752863
+v 0.261434 -0.675444 0.711116
+v 0.261344 -0.656009 0.726145
+v 0.171414 -0.261684 0.74671
+v 0.17144 -0.243842 0.743987
+v 0.158505 -0.547364 0.743396
+v 0.17135 -0.547248 0.745143
+v 0.197079 0.139924 0.496394
+v 0.184298 0.140142 0.495032
+v 0.184285 0.122339 0.507852
+v 0.197118 0.122506 0.509599
+v 0.184272 -0.656909 0.715059
+v 0.171478 -0.637448 0.722625
+v 0.171376 -0.675252 0.71064
+v 0.171311 -0.657628 0.713621
+v 0.158492 -0.49218 0.766967
+v 0.17144 -0.492232 0.767044
+v 0.15853 -0.473722 0.772747
+v 0.171401 -0.473786 0.773107
+v 0.171363 -0.45579 0.77497
+v 0.158505 -0.455764 0.774443
+v 0.349887 -0.766235 0.661623
+v 0.351145 -0.69443 0.696421
+v 0.338506 -0.694545 0.697243
+v 0.33839 -0.712516 0.69511
+v 0.312751 -0.143264 0.637397
+v 0.29988 -0.143276 0.637653
+v 0.30006 -0.548417 0.730011
+v 0.312738 -0.548661 0.727956
+v 0.312764 -0.405179 0.736061
+v 0.300073 -0.387594 0.733967
+v 0.312764 -0.422649 0.740698
+v 0.299944 -0.405128 0.736537
+v 0.312751 -0.440311 0.74364
+v 0.299931 -0.42252 0.741354
+v 0.312674 -0.45805 0.744796
+v 0.299893 -0.440157 0.745323
+v 0.299906 -0.475931 0.745246
+v 0.299893 -0.494017 0.74197
+v 0.29988 -0.457922 0.746582
+v 0.312789 -0.530601 0.731411
+v 0.312751 -0.512386 0.735881
+v 0.299867 -0.530434 0.732593
+v 0.312674 -0.494082 0.740043
+v 0.299906 -0.51227 0.737526
+v 0.389643 0.0496085 0.507852
+v 0.376913 0.0676819 0.500247
+v 0.312661 -0.263046 0.726427
+v 0.299816 -0.245448 0.720274
+v -0.670634 0.551885 -0.603318
+v -0.671944 0.542123 -0.584936
+v 0.19713 -0.385513 0.760776
+v 0.197092 -0.367941 0.757693
+v -0.419842 0.404935 0.166077
+v -0.421756 0.404858 0.178884
+v -0.416001 0.385308 0.178986
+v -0.423452 0.44446 0.153193
+v -0.423272 0.424691 0.166103
+v 0.784315 -0.309225 -0.0161851
+v 0.787821 -0.308929 -0.003404
+v 0.784019 -0.291306 -0.0160695
+v 0.788143 -0.290985 -0.00351961
+v 0.781514 -0.273412 -0.0163135
+v 0.787642 -0.27295 -0.00336547
+v -0.130553 0.746569 -0.100784
+v -0.141279 0.746466 -0.0936808
+v -0.137246 0.727635 -0.0879389
+v -0.133726 0.765477 -0.105203
+v -0.144336 0.765464 -0.0979711
+v -0.134844 0.784539 -0.10668
+v -0.14512 0.784552 -0.098973
+v 0.730249 -0.0400259 0.112371
+v 0.701925 -0.514506 -0.144895
+v 0.688617 -0.515662 -0.157548
+v 0.698354 -0.496753 -0.144651
+v 0.951201 -0.707519 0.0733338
+v 0.78953 -0.182236 0.0990116
+v 0.605354 -0.486734 -0.247426
+v 0.616504 -0.485706 -0.234337
+v 0.610543 -0.504486 -0.234851
+v -0.160316 0.174157 0.287773
+v -0.170001 0.167259 0.303329
+v -0.0053886 0.233001 0.211305
+v 0.00297369 0.23697 0.195557
+v -0.17907 0.161645 0.319077
+v -0.18801 0.156314 0.335018
+v 0.0350998 0.241081 0.114375
+v -0.197105 0.150573 0.350779
+v -0.206867 0.143662 0.366463
+v -0.216514 0.136777 0.382173
+v -0.193559 0.566285 -0.0742844
+v -0.182525 0.578193 -0.0877462
+v -0.183142 0.565167 -0.0667699
+v -0.227792 0.12722 0.3976
+v 0.0413297 0.240991 0.0980867
+v -0.0406618 0.179166 0.349572
+v -0.820834 -0.48983 0.129429
+v -0.960398 0.233386 0.472476
+v -0.960154 0.233361 0.485308
+v -0.954399 0.250882 0.472373
+v 0.176347 0.266835 0.110932
+v -0.621436 0.745618 -0.748907
+v -0.630582 0.74337 -0.7389
+v -0.631674 0.761649 -0.738502
+v -0.60055 0.7361 -0.509342
+v -0.598212 0.726646 -0.489573
+v 0.178941 -0.930783 0.167631
+v 0.187188 -0.939659 0.177342
+v 0.173122 -0.925529 0.185011
+v -0.0138665 -0.919299 -0.190136
+v -0.0272641 -0.919865 -0.192281
+v -0.611995 -0.381454 0.572656
+v -0.612278 -0.363355 0.580338
+v -0.63626 -0.392308 0.55764
+v -0.638392 -0.381505 0.562123
+v -0.612072 -0.344575 0.586041
+v -0.612149 -0.326386 0.589586
+v -0.612123 -0.30812 0.592862
+v -0.612098 -0.289867 0.596099
+v -0.6122 -0.271768 0.596484
+v -0.612111 -0.253746 0.594557
+v -0.612008 -0.236058 0.589496
+v -0.611995 -0.218344 0.584577
+v -0.612393 -0.200399 0.577383
+v -0.611944 -0.182994 0.571307
+v -0.612046 -0.165178 0.564988
+v -0.612008 -0.147143 0.563176
+v -0.612175 -0.128941 0.56229
+v -0.612008 -0.111138 0.558385
+v -0.612072 -0.0935138 0.550344
+v -0.612098 -0.0758515 0.540774
+v -0.612111 -0.0582277 0.531037
+v -0.612111 -0.040604 0.521262
+v -0.612123 -0.0228518 0.513067
+v -0.0376046 -0.931156 -0.207978
+v 0.810712 -0.433079 0.099307
+v 0.811983 -0.433002 0.112152
+v 0.813011 -0.450883 0.112088
+v 0.492392 -0.250637 0.639349
+v 0.49229 -0.232898 0.635585
+v 0.492315 -0.214966 0.632631
+v 0.505019 -0.215223 0.629471
+v 0.492302 -0.197175 0.628058
+v 0.749414 -0.0759157 0.150264
+v 0.756569 -0.0933468 0.150303
+v 0.389579 -0.107245 0.626144
+v 0.389669 -0.0900841 0.613453
+v 0.376913 -0.0900712 0.61502
+v 0.184311 -0.243958 0.742304
+v 0.184285 -0.226116 0.738065
+v 0.273894 -0.192821 0.704385
+v 0.37672 0.103109 0.484833
+v -0.637377 0.540145 -0.542046
+v 0.284787 -0.914572 -0.0868856
+v 0.275435 -0.915305 -0.0640338
+v 0.272006 -0.914084 -0.0898657
+v 0.287137 -0.315031 0.750191
+v 0.299893 -0.315301 0.746697
+v 0.287099 -0.297343 0.747044
+v -0.509926 -0.916782 -0.108453
+v -0.509811 -0.934804 -0.11485
+v -0.520935 -0.937745 -0.112217
+v 0.543234 -0.880661 -0.05264
+v 0.526664 -0.877771 -0.0673607
+v 0.553138 -0.85524 -0.0660891
+v 0.222834 -0.785862 0.677769
+v 0.235679 -0.785503 0.679054
+v 0.778033 -0.146899 0.0990501
+v 0.287035 0.157265 0.469072
+v -0.241806 0.59046 -0.114195
+v 0.325301 -0.749241 0.683678
+v 0.197053 -0.332256 0.758386
+v 0.158594 -0.279282 0.750743
+v 0.171504 -0.279282 0.749395
+v 0.158684 -0.261415 0.748084
+v 0.35699 -0.69195 0.695149
+v 0.354794 -0.709985 0.691899
+v 0.351351 -0.676729 0.695457
+v 0.338634 -0.676665 0.697551
+v 0.299559 -0.159847 0.661135
+v 0.312468 -0.160207 0.654802
+v 0.29952 -0.824578 0.641468
+v 0.299751 -0.86621 0.603382
+v 0.299893 -0.767712 0.684539
+v 0.319007 -0.362674 0.733043
+v 0.171414 -0.61931 0.735034
+v 0.158543 -0.638 0.727725
+v 0.171401 -0.600877 0.743088
+v 0.158569 -0.600929 0.741122
+v 0.158582 -0.619028 0.736151
+v 0.14589 0.121966 0.505822
+v 0.171401 -0.510652 0.757372
+v 0.338403 -0.245936 0.711257
+v 0.778136 -0.255596 -0.0162621
+v 0.784661 -0.255108 -0.00341685
+v 0.338236 -0.228929 0.70134
+v 0.338249 -0.211511 0.69073
+v 0.338159 -0.194362 0.678283
+v -0.51405 -0.6924 0.0921779
+v -0.528539 -0.674031 0.104869
+v -0.530196 -0.6738 0.0919466
+v 0.15862 -0.675496 0.711989
+v 0.17144 0.12257 0.506606
+v 0.184298 0.104856 0.520954
+v 0.171478 0.10483 0.520915
+v 0.338519 -0.73118 0.689356
+v 0.209924 -0.564898 0.746774
+v 0.209937 -0.547094 0.746158
+v 0.197079 -0.564769 0.74838
+v 0.793024 -0.200014 0.150264
+v 0.792728 -0.200091 0.163071
+v 0.796325 -0.217818 0.163097
+v 0.323541 -0.183521 -0.333592
+v 0.31085 -0.181774 -0.335455
+v 0.25681 -0.104021 -0.264151
+v 0.243849 -0.0910603 -0.264793
+v 0.25681 -0.0909961 -0.262275
+v -0.867758 -0.363792 0.308904
+v 0.774424 -0.237895 -0.0160695
+v 0.779806 -0.237368 -0.00342969
+v -0.134805 0.80364 -0.106475
+v -0.144144 0.80355 -0.0975472
+v -0.132724 0.822587 -0.10352
+v -0.140778 0.823011 -0.0918439
+v -0.128639 0.841804 -0.0972261
+v -0.136308 0.841765 -0.0858323
+v -0.631623 0.561879 -0.591153
+v -0.637082 0.558809 -0.605014
+v -0.625611 0.577653 -0.59845
+v -0.443066 -0.717988 0.196995
+v -0.446329 -0.697474 0.207554
+v -0.454049 -0.696832 0.194709
+v -0.059827 0.136982 0.420478
+v -0.0465963 0.153514 0.402045
+v -0.0595572 0.153476 0.394081
+v 0.0698848 0.237009 0.0427492
+v 0.0552797 0.234812 0.0452668
+v -0.378223 0.278769 0.282969
+v -0.383708 0.278974 0.299861
+v -0.373291 0.276264 0.265859
+v -0.422463 0.305371 0.360966
+v -0.416143 0.291961 0.363535
+v -0.361846 0.463728 0.0637512
+v -0.363143 0.461891 0.0641751
+v -0.697172 0.584744 0.105807
+v -0.291543 0.796524 0.00899171
+v -0.306688 0.793544 0.00345539
+v -0.0694096 0.62775 -0.126873
+v -0.0576561 0.639182 -0.141375
+v -0.723158 0.591269 0.22749
+v -0.736581 0.59195 0.222725
+v -0.72863 0.591821 0.244253
+v -0.710994 0.858323 -0.567903
+v -0.0517087 0.169365 0.364524
+v -0.063565 0.158511 0.379412
+v 0.307587 -0.266591 -0.401762
+v 0.318891 -0.270689 -0.396817
+v 0.308859 -0.284228 -0.40315
+v -0.618007 0.213399 -0.0926917
+v -0.618212 0.232217 -0.0923834
+v -0.60529 0.21336 -0.092165
+v -0.771097 0.155595 -0.0715355
+v -0.758573 0.155762 -0.0753891
+v -0.758187 0.137072 -0.0762625
+v -0.822054 0.135531 -0.0424409
+v -0.822491 0.116455 -0.0361081
+v 0.294369 -0.967469 0.317343
+v 0.282731 -0.964875 0.312706
+v 0.28855 -0.970154 0.295301
+v -0.191144 -0.964952 0.648032
+v -0.202834 -0.96237 0.64337
+v -0.196771 -0.966313 0.62608
+v -0.145479 0.803037 -0.212179
+v -0.599304 -0.419232 0.555277
+v -0.599201 -0.400272 0.564756
+v -0.612136 -0.400683 0.561853
+v -0.624082 -0.393863 0.561725
+v -0.599304 -0.381557 0.574827
+v -0.825163 0.0952736 0.644962
+v -0.830249 0.113385 0.648482
+v -0.832883 0.0941689 0.644924
+v -0.599252 -0.362777 0.58265
+v -0.59924 -0.344331 0.5873
+v -0.599329 -0.32645 0.589882
+v -0.59924 -0.307889 0.594018
+v -0.599137 -0.289546 0.598475
+v -0.599137 -0.271421 0.600531
+v -0.599162 -0.253463 0.599066
+v -0.599381 -0.235583 0.59493
+v -0.599355 -0.217818 0.589972
+v -0.599381 -0.200104 0.583485
+v -0.599407 -0.182467 0.575431
+v -0.599342 -0.164959 0.567146
+v -0.599471 -0.147053 0.562675
+v -0.599432 -0.128915 0.562521
+v -0.599214 -0.111138 0.559914
+v -0.599291 -0.0932569 0.552271
+v -0.599265 -0.0756973 0.543986
+v -0.599188 -0.0581635 0.534133
+v -0.599227 -0.0406682 0.524114
+v -0.599342 -0.0226334 0.513529
+v -0.586458 -0.0227619 0.514775
+v -0.599317 -0.00822099 0.505707
+v -0.500177 -0.372 -0.252577
+v 0.222731 -0.600492 0.748457
+v 0.505019 -0.197471 0.624693
+v 0.197079 -0.191742 0.721418
+v 0.209899 -0.191703 0.720056
+v 0.197053 -0.174439 0.709304
+v 0.22232 -0.055633 0.575277
+v 0.222513 -0.0375597 0.572733
+v 0.209744 -0.0373541 0.576266
+v 0.80777 -0.415288 0.0864232
+v 0.808978 -0.397202 0.086436
+v 0.809568 -0.415186 0.0992428
+v 0.775272 -0.755175 0.437254
+v 0.782054 -0.77655 0.428982
+v 0.785715 -0.758142 0.434145
+v 0.4922 -0.179539 0.622997
+v 0.0210984 0.784578 -0.284729
+v 0.672278 -0.831682 0.409521
+v 0.672316 -0.812221 0.417228
+v 0.659535 -0.812709 0.414338
+v 0.654962 -0.847032 0.399142
+v 0.65951 -0.831617 0.407466
+v 0.646741 -0.831926 0.406078
+v 0.222782 -0.297035 0.751604
+v 0.209937 -0.314594 0.756216
+v 0.380523 -0.224253 0.687737
+v 0.37672 -0.21214 0.681392
+v 0.222615 -0.192063 0.719517
+v 0.20986 -0.17467 0.709073
+v 0.2225 -0.0735393 0.580453
+v 0.235448 -0.0738219 0.576047
+v 0.286996 -0.440157 0.74549
+v 0.286983 -0.422636 0.741713
+v 0.287047 -0.405102 0.737474
+v 0.209873 -0.209147 0.729112
+v 0.222718 -0.209173 0.727712
+v 0.184349 -0.828573 0.622984
+v 0.153919 -0.0817989 0.584615
+v 0.158607 -0.0729228 0.585437
+v 0.145788 -0.0729356 0.585193
+v 0.235641 -0.332282 0.7589
+v 0.235743 -0.350343 0.756768
+v -0.628707 0.457023 -0.235814
+v -0.617801 0.469444 -0.249327
+v -0.610954 0.471358 -0.236842
+v 0.299417 -0.17652 0.682625
+v 0.312468 -0.176559 0.675316
+v 0.299636 -0.805567 0.658977
+v 0.299854 -0.847815 0.607313
+v 0.299739 -0.786453 0.673184
+v 0.158338 -0.420208 0.771129
+v 0.17135 -0.350137 0.757654
+v 0.171337 -0.332346 0.757847
+v 0.158415 -0.332436 0.755599
+v -0.287099 0.504795 0.0249456
+v 0.158427 -0.350278 0.75547
+v 0.325506 -0.787841 0.662792
+v 0.338249 -0.788509 0.654892
+v 0.325404 -0.80734 0.64721
+v 0.376708 -0.14239 0.637769
+v 0.363952 -0.142416 0.639195
+v -0.701064 0.851027 -0.564191
+v 0.453946 0.0311627 0.501724
+v 0.454101 0.0494544 0.495906
+v 0.441217 0.0495572 0.499001
+v 0.441024 -0.178794 0.630332
+v 0.440896 -0.161131 0.626337
+v 0.427883 -0.160926 0.629317
+v 0.428179 -0.178575 0.633697
+v 0.209796 -0.0552733 0.579593
+v 0.197028 -0.261954 0.744359
+v 0.402578 0.0143354 0.526169
+v 0.389746 0.0141812 0.525848
+v 0.389823 -0.00376367 0.533696
+v 0.222834 -0.279552 0.745657
+v 0.222847 -0.261916 0.741071
+v -0.590608 0.666029 -0.720557
+v -0.124644 0.861046 -0.0909832
+v -0.132621 0.861085 -0.0798464
+v 0.906974 -0.782857 0.0612849
+v 0.748142 -0.0758001 0.0860892
+v 0.738688 -0.0580222 0.0860635
+v -0.94456 0.35602 0.304703
+v -0.94781 0.355956 0.291974
+v 0.768746 -0.219937 -0.0164163
+v 0.773974 -0.219462 -0.00371229
+v -0.121728 0.880018 -0.0867828
+v -0.129911 0.87998 -0.0759799
+v -0.542245 0.58044 0.310317
+v -0.255795 -0.408879 -0.231177
+v -0.242962 -0.408853 -0.231177
+v -0.242872 -0.427337 -0.227888
+v -0.00326913 0.216469 0.306052
+v -0.196527 0.726479 -0.186218
+v -0.183681 0.72653 -0.189507
+v -0.602823 0.621828 -0.177419
+v -0.126584 0.19169 0.0549265
+v -0.171543 0.202545 0.151022
+v -0.159571 0.199783 0.155402
+v -0.61527 0.609445 -0.672233
+v 0.679099 -0.00118177 0.352205
+v 0.686061 -0.0141941 0.3548
+v -0.638752 0.483279 -0.349752
+v -0.630158 0.483985 -0.339681
+v -0.614795 0.79601 -0.5887
+v -0.621051 0.795728 -0.572258
+v -0.878445 -0.397189 0.257291
+v -0.627769 0.79425 -0.556073
+v -0.953346 0.302276 0.176674
+v -0.528578 0.21268 -0.0715226
+v -0.528899 0.231395 -0.0676305
+v -0.515797 0.212474 -0.068003
+v 0.0508096 0.698681 -0.216546
+v -0.771045 0.13679 -0.0715868
+v -0.617608 0.157085 -0.0944643
+v -0.617711 0.175891 -0.0943102
+v -0.604904 0.175904 -0.0942331
+v -0.599111 -0.437562 0.548237
+v -0.611507 -0.427042 0.547505
+v -0.586484 -0.437575 0.552104
+v -0.58642 -0.418924 0.558411
+v -0.586484 -0.400452 0.56518
+v -0.586394 -0.381428 0.574403
+v -0.58651 -0.363214 0.581956
+v -0.586471 -0.344691 0.586452
+v -0.586484 -0.32636 0.589586
+v -0.586458 -0.307915 0.594159
+v -0.586471 -0.28961 0.599657
+v -0.586446 -0.271267 0.602663
+v -0.586446 -0.253258 0.601263
+v -0.58651 -0.235339 0.598193
+v -0.586163 -0.217676 0.595354
+v -0.586266 -0.199911 0.589329
+v -0.586202 -0.182493 0.580864
+v -0.586548 -0.164638 0.570601
+v -0.586471 -0.146937 0.565373
+v -0.586407 -0.128928 0.563382
+v -0.586407 -0.110919 0.560633
+v -0.586471 -0.0931541 0.553992
+v -0.586497 -0.0754276 0.545899
+v -0.586458 -0.0578681 0.536073
+v -0.586381 -0.0405269 0.525848
+v 0.41017 -0.292346 0.685091
+v 0.410401 -0.275044 0.685579
+v 0.399752 -0.292372 0.692644
+v 0.672304 -0.793557 0.420773
+v 0.659574 -0.793685 0.418872
+v 0.672406 -0.774867 0.424229
+v 0.659779 -0.775021 0.424293
+v 0.515784 -0.255917 0.635303
+v 0.145711 -0.674866 0.71547
+v 0.145621 -0.693068 0.712542
+v 0.757596 -0.0935395 0.137458
+v -0.0169108 0.704577 -0.210393
+v -0.0293065 0.708521 -0.210419
+v -0.0164612 0.708547 -0.213759
+v 0.775207 -0.736948 0.437858
+v 0.787693 -0.738669 0.436689
+v 0.775117 -0.718733 0.437113
+v 0.878342 -0.822163 0.0996024
+v 0.881554 -0.821906 0.112409
+v 0.860808 -0.841072 0.112628
+v 0.222628 0.0162878 0.565578
+v 0.20959 -0.864835 0.617127
+v 0.196963 -0.846839 0.615534
+v 0.19853 -0.869293 0.621738
+v 0.248576 -0.582611 0.747327
+v 0.261383 -0.582676 0.746736
+v 0.248576 -0.565142 0.742818
+v 0.145582 -0.420517 0.76874
+v 0.235474 -0.0917283 0.583806
+v 0.325519 -0.694301 0.698193
+v 0.287022 -0.475918 0.74531
+v 0.286996 -0.457909 0.746864
+v 0.222949 -0.109082 0.590113
+v 0.222705 -0.0915356 0.585579
+v 0.211145 -0.0928972 0.58721
+v -0.629143 0.57326 -0.614583
+v 0.158646 0.0871553 0.530652
+v 0.171517 0.0695059 0.54193
+v 0.171517 0.0870397 0.532039
+v 0.15853 0.0698399 0.539618
+v 0.78804 -0.885516 0.100013
+v -0.896069 -0.344537 0.231485
+v -0.897289 -0.344408 0.21864
+v -0.897135 -0.361711 0.218704
+v 0.248319 0.069249 0.538501
+v 0.248383 0.0870911 0.529098
+v 0.171388 -0.0728971 0.586144
+v 0.158582 -0.0549008 0.58536
+v 0.171401 -0.564936 0.746196
+v 0.145685 -0.314864 0.753094
+v 0.197143 0.0340529 0.560749
+v 0.184336 0.0339758 0.559194
+v 0.184272 0.0163392 0.564718
+v -0.10616 0.669818 -0.174221
+v -0.111337 0.668277 -0.173078
+v -0.103488 0.683434 -0.181671
+v 0.223258 -0.475135 0.758181
+v 0.2104 -0.493311 0.756909
+v 0.801103 -0.235608 0.0990372
+v 0.938754 -0.744526 0.0735136
+v 0.944829 -0.743807 0.0863718
+v 0.935028 -0.762381 0.086603
+v 0.803082 -0.271601 0.0990501
+v 0.802735 -0.253553 0.0990372
+v 0.236052 -0.403818 0.755368
+v 0.470954 -0.920186 -0.143289
+v 0.482052 -0.90025 -0.143302
+v 0.473844 -0.919569 -0.130418
+v 0.389694 0.0318692 0.517511
+v 0.402488 0.031805 0.517447
+v 0.402565 0.0496599 0.506516
+v 0.158556 -0.20871 0.734083
+v 0.145711 -0.191292 0.723524
+v 0.402578 -0.00390497 0.535045
+v -0.368127 0.134657 0.373079
+v -0.368076 0.117624 0.393015
+v -0.355243 0.117393 0.397523
+v 0.201356 -0.937951 0.248608
+v 0.210759 -0.944746 0.256623
+v 0.197811 -0.928497 0.262635
+v 0.107676 -0.12749 0.631218
+v 0.110656 -0.12984 0.638411
+v 0.124131 -0.130662 0.643087
+v -0.0390818 -0.922986 0.046333
+v -0.0483047 -0.924052 0.0687737
+v -0.0518757 -0.922524 0.0433657
+v 0.761771 -0.202416 -0.0162493
+v -0.943673 0.373631 0.304755
+v -0.947707 0.373657 0.291845
+v -0.970122 0.109545 0.139217
+v -0.974271 0.109725 0.152127
+v -0.638122 0.783024 -0.503767
+v -0.644185 0.782831 -0.487595
+v -0.788078 0.584705 0.223534
+v -0.930366 0.338769 0.407646
+v -0.930584 0.356457 0.407581
+v -0.928747 0.356431 0.394749
+v -0.957032 0.233476 0.52378
+v -0.954117 0.233502 0.536587
+v -0.949903 0.251074 0.52369
+v -0.455244 -0.822253 0.28532
+v -0.93192 0.374106 0.39462
+v -0.936634 0.391756 0.394595
+v -0.933012 0.374119 0.381749
+v -0.450632 -0.822767 0.272513
+v -0.946486 0.355596 0.227747
+v -0.948349 0.373194 0.227567
+v -0.929454 -0.13476 0.179089
+v -0.578918 -0.810564 0.0926917
+v -0.540729 -0.796408 0.0797565
+v -0.529297 -0.779311 0.0798849
+v -0.947424 0.39146 0.304511
+v -0.953397 0.391358 0.291704
+v -0.120521 0.126 0.398114
+v -0.124028 0.118035 0.410587
+v -0.111349 0.118691 0.415815
+v -0.64967 0.510395 -0.463201
+v -0.63283 0.525206 -0.462906
+v -0.170656 0.707532 -0.186013
+v -0.157939 0.707403 -0.188171
+v -0.15776 0.688238 -0.179988
+v 0.543337 -0.921856 -0.0192808
+v -0.617852 0.194658 -0.0942203
+v -0.605046 0.194696 -0.0933082
+v -0.771919 0.212333 -0.0776884
+v -0.772163 0.231151 -0.0764937
+v -0.759228 0.231331 -0.0812208
+v 0.450697 -0.964322 -0.105126
+v 0.455539 -0.958234 -0.104522
+v 0.458815 -0.957925 -0.091664
+v -0.601179 -0.609458 -0.0275532
+v -0.587101 -0.625579 -0.00796408
+v -0.599843 -0.625283 -0.0049069
+v -0.516542 0.0408095 -0.183405
+v -0.527409 0.031137 -0.185435
+v -0.527601 0.0494159 -0.174426
+v -0.573433 -0.436958 0.556394
+v -0.573446 -0.418564 0.561275
+v -0.573754 -0.400619 0.565707
+v -0.573716 -0.382045 0.572297
+v -0.573665 -0.363162 0.579773
+v -0.573652 -0.344665 0.584178
+v -0.573639 -0.32654 0.588212
+v -0.573639 -0.30794 0.594313
+v -0.573626 -0.28943 0.600762
+v -0.573549 -0.271074 0.603626
+v -0.573626 -0.253142 0.602933
+v -0.573523 -0.235249 0.600569
+v -0.573523 -0.21742 0.597499
+v -0.573472 -0.19977 0.592412
+v -0.573587 -0.182108 0.583138
+v -0.573613 -0.164561 0.573504
+v -0.573626 -0.146668 0.568687
+v -0.5736 -0.128659 0.566902
+v -0.573639 -0.110791 0.562149
+v -0.573613 -0.093077 0.555495
+v -0.573613 -0.0754147 0.547415
+v -0.573613 -0.0578681 0.53755
+v -0.573613 -0.0403085 0.526169
+v -0.573639 -0.0225949 0.515007
+v -0.220483 -0.919068 -0.369212
+v -0.215396 -0.907751 -0.367658
+v -0.206803 -0.918413 -0.370664
+v 0.365905 -0.258447 0.711373
+v 0.377568 -0.258062 0.705926
+v 0.197079 -0.350111 0.758284
+v 0.38936 -0.212628 0.676498
+v 0.376926 -0.00344254 0.531359
+v 0.377029 -0.0219012 0.541545
+v -0.834039 -0.453901 0.219295
+v -0.833692 -0.453696 0.232179
+v -0.849813 -0.434621 0.219128
+v 0.274241 -0.440234 0.744411
+v 0.261395 -0.458192 0.743884
+v 0.736517 -0.683563 0.423124
+v 0.222757 -0.827545 0.626735
+v 0.222834 -0.805824 0.657782
+v 0.210078 -0.805567 0.655855
+v 0.286572 -0.17625 0.688624
+v 0.90447 -0.578796 0.372758
+v 0.891059 -0.561083 0.368737
+v 0.891175 -0.578514 0.378615
+v 0.248293 0.104445 0.517434
+v 0.248409 0.122313 0.501737
+v 0.27451 -0.0921907 0.585257
+v 0.274189 -0.0746697 0.570627
+v 0.26137 -0.0918824 0.581006
+v 0.235371 -0.055877 0.57114
+v 0.235358 -0.0377523 0.569304
+v -0.522399 -0.762497 0.0796408
+v 0.145723 -0.637448 0.733929
+v 0.145736 -0.656215 0.724847
+v 0.235923 -0.475674 0.750165
+v 0.171324 -0.0192551 0.577614
+v 0.171363 -0.00175981 0.571911
+v 0.15853 -0.0194092 0.578539
+v 0.171337 -0.0369688 0.582573
+v 0.171401 -0.296932 0.752503
+v 0.248601 -0.547762 0.737975
+v 0.312841 -0.297844 0.740775
+v 0.312828 -0.280233 0.734777
+v 0.184298 -0.805991 0.651205
+v 0.184247 -0.787134 0.668906
+v 0.171453 -0.747198 0.707326
+v 0.171465 -0.72838 0.714918
+v 0.158376 -0.729009 0.710987
+v -0.768733 -0.411268 0.454852
+v -0.762824 -0.399617 0.468918
+v -0.772638 -0.399502 0.460607
+v -0.974836 0.128492 0.434467
+v -0.975774 0.145833 0.434441
+v -0.973629 0.145717 0.421531
+v 0.287022 -0.494017 0.741932
+v -0.952228 0.409033 0.304523
+v -0.957418 0.409084 0.291563
+v 0.345378 -0.51746 0.725194
+v 0.338621 -0.513028 0.728393
+v 0.338364 -0.530909 0.726158
+v 0.158556 -0.00157997 0.571025
+v 0.878291 -0.613312 0.398153
+v 0.312545 -0.767853 0.679362
+v 0.312507 -0.786903 0.668495
+v 0.20968 -0.0194992 0.572348
+v 0.197028 -0.00157997 0.569265
+v 0.402617 0.067592 0.497126
+v 0.415359 0.0672194 0.496419
+v 0.402527 0.0852542 0.490074
+v 0.415423 0.08519 0.487029
+v 0.415398 0.103019 0.478898
+v 0.402552 0.103225 0.482187
+v 0.196925 -0.0193836 0.574262
+v 0.389784 0.10352 0.484216
+v -0.193174 0.593478 -0.114901
+v 0.197195 -0.43805 0.773133
+v 0.197156 -0.420362 0.771386
+v 0.184272 -0.420221 0.771925
+v 0.158582 -0.226 0.74093
+v 0.145685 -0.208543 0.73443
+v -0.575322 0.489881 0.495931
+v -0.586266 0.509162 0.492245
+v -0.586099 0.490922 0.499091
+v -0.472379 0.522816 0.333117
+v -0.479175 0.529008 0.352745
+v -0.0669433 0.688688 -0.188993
+v -0.0755368 0.674738 -0.177599
+v -0.080662 0.688636 -0.186372
+v -0.608373 0.581597 -0.511872
+v -0.601603 0.598565 -0.514724
+v 0.0183367 -0.973622 -0.229725
+v 0.0242455 -0.979197 -0.247542
+v 0.756774 -0.184613 -0.0161979
+v 0.762015 -0.184137 -0.00349392
+v -0.632021 0.783178 -0.52026
+v -0.6294 0.773017 -0.500633
+v -0.657801 0.608109 -0.0489663
+v -0.711713 0.823435 -0.494082
+v -0.722978 0.827995 -0.498398
+v -0.72082 0.817616 -0.479168
+v 0.117592 0.258743 0.255711
+v -0.980308 0.128928 0.485899
+v -0.980244 0.146218 0.485809
+v -0.979293 0.146141 0.472938
+v -0.965998 0.215852 0.485424
+v -0.965652 0.21566 0.472604
+v -0.970404 0.198229 0.472681
+v -0.96727 0.0766736 0.511847
+v -0.959704 0.0665643 0.524371
+v -0.965562 0.0768406 0.524692
+v -0.165351 -0.92305 0.0441621
+v -0.078337 0.205949 0.0727172
+v -0.0573864 0.208145 0.0616831
+v -0.0475854 0.208081 0.0508417
+v -0.0838477 0.20722 0.0893519
+v -0.166854 -0.219834 -0.297934
+v -0.179853 -0.220258 -0.294491
+v -0.166995 -0.201915 -0.292757
+v -0.288383 -0.971824 0.499399
+v -0.30164 -0.972299 0.497023
+v -0.293444 -0.972556 0.476458
+v -0.17099 0.745708 -0.197753
+v -0.158068 0.745798 -0.20248
+v -0.157772 0.726851 -0.197047
+v -0.758431 -0.049159 -0.0950809
+v -0.770878 -0.049904 -0.0863718
+v -0.75856 -0.0308416 -0.0870783
+v -0.315423 -0.016108 -0.227799
+v -0.308833 -0.0214131 -0.23101
+v -0.32173 -0.0212718 -0.229828
+v -0.144966 0.707635 -0.19101
+v 0.00849716 0.765541 -0.263419
+v -0.387279 0.447633 0.0446888
+v -0.373766 0.457781 0.0274632
+v -0.771855 0.193412 -0.0760827
+v -0.758855 0.193656 -0.0806042
+v -0.560511 -0.455032 0.552823
+v -0.560794 -0.436907 0.560222
+v -0.573498 -0.455687 0.54843
+v -0.586433 -0.456226 0.543767
+v -0.560434 -0.418025 0.565656
+v -0.560639 -0.3999 0.569445
+v -0.560742 -0.381711 0.573183
+v -0.560704 -0.363188 0.577448
+v -0.560794 -0.345076 0.581545
+v -0.560794 -0.326605 0.586259
+v -0.560768 -0.308184 0.593299
+v -0.560768 -0.289674 0.59985
+v -0.560768 -0.27119 0.601956
+v -0.560781 -0.253258 0.601288
+v -0.560781 -0.235133 0.601237
+v -0.560755 -0.217227 0.599246
+v -0.560639 -0.199744 0.593812
+v -0.560704 -0.182056 0.584641
+v -0.560755 -0.164497 0.574968
+v -0.560652 -0.14677 0.569522
+v -0.560742 -0.128671 0.56685
+v -0.560729 -0.110881 0.563151
+v -0.560729 -0.0929871 0.557062
+v -0.560755 -0.0753505 0.548905
+v -0.560794 -0.0576882 0.537807
+v -0.560729 -0.0404242 0.527518
+v -0.560742 -0.0228903 0.516086
+v -0.560794 -0.00482983 0.503934
+v -0.573626 -0.0051895 0.50473
+v 0.789954 -0.434878 0.00937707
+v -0.574577 0.0116635 0.495417
+v -0.560845 0.0124985 0.493388
+v -0.573472 0.030559 0.489419
+v 0.752715 -0.166488 -0.0165191
+v 0.758457 -0.166282 -0.003404
+v -0.0824219 0.6445 -0.15074
+v -0.080585 0.629651 -0.133103
+v 0.158453 -0.583061 0.743833
+v 0.171388 -0.58274 0.746196
+v 0.15844 -0.565193 0.743756
+v 0.197105 -0.765593 0.699388
+v 0.209924 -0.766042 0.699748
+v 0.197053 -0.74662 0.715509
+v 0.210078 -0.529496 0.745695
+v 0.197105 -0.547133 0.747506
+v 0.17144 -0.0913044 0.584114
+v 0.312481 0.0862305 0.514184
+v 0.312687 0.104278 0.503497
+v 0.299662 0.103854 0.505861
+v 0.299649 0.0863975 0.517499
+v 0.274061 -0.0564808 0.561622
+v 0.274228 -0.0383561 0.557537
+v 0.261113 -0.0381248 0.562971
+v 0.28155 -0.110251 -0.257574
+v 0.28241 -0.0913301 -0.258319
+v 0.295191 -0.0915613 -0.254735
+v 0.235332 -0.191305 0.716485
+v 0.248383 -0.191999 0.71398
+v 0.145723 0.0694545 0.535996
+v 0.145736 -0.827931 0.625476
+v 0.145723 -0.80743 0.643948
+v 0.402437 -0.14257 0.631796
+v 0.402308 -0.124843 0.629484
+v 0.389463 -0.124741 0.632181
+v 0.158517 -0.0370073 0.583767
+v 0.145698 -0.00154144 0.571192
+v 0.158646 0.157329 0.48008
+v 0.145801 0.139744 0.49001
+v 0.235602 -0.847404 0.610267
+v 0.235384 -0.865285 0.611475
+v 0.222603 -0.0195891 0.569394
+v 0.22259 -0.00166989 0.567274
+v 0.312545 -0.228544 0.706042
+v 0.184182 -0.58265 0.748174
+v -0.296026 -0.963577 0.558141
+v -0.30927 -0.964065 0.555713
+v -0.303733 -0.969345 0.539002
+v 0.762131 -0.111523 0.0861919
+v 0.76258 -0.111343 0.0989602
+v 0.63721 -0.804231 0.421441
+v 0.646729 -0.812529 0.41385
+v 0.647114 -0.793878 0.421146
+v 0.957174 -0.706813 0.0863204
+v 0.951059 -0.725271 0.086269
+v 0.778162 -0.489804 0.00960828
+v 0.776235 -0.507954 0.00976243
+v -0.618456 0.542072 -0.458975
+v 0.466304 -0.30383 0.65854
+v 0.479573 -0.303586 0.655341
+v 0.466522 -0.28609 0.651642
+v -0.644224 0.36374 -0.0818374
+v -0.654962 0.37358 -0.0814007
+v 0.479586 -0.286078 0.650396
+v 0.479663 -0.268569 0.644847
+v 0.466586 -0.268467 0.644012
+v 0.479509 -0.250766 0.639079
+v 0.466715 -0.250625 0.638283
+v 0.479624 -0.232885 0.635264
+v 0.466753 -0.23286 0.63353
+v 0.197323 -0.805413 0.65398
+v 0.197233 -0.786286 0.671475
+v 0.197118 -0.692079 0.721199
+v -0.126456 -0.965555 0.662471
+v -0.134086 -0.964643 0.682034
+v -0.140213 -0.967058 0.660801
+v 0.197092 -0.828175 0.623845
+v 0.325609 -0.405321 0.734366
+v 0.338441 -0.405565 0.731257
+v 0.32566 -0.387825 0.729844
+v 0.26074 -0.143521 0.653222
+v 0.27392 -0.143508 0.645451
+v 0.26146 -0.126167 0.613915
+v 0.184349 -0.109647 0.585373
+v 0.167227 -0.0987675 0.582932
+v 0.170104 -0.116211 0.58563
+v 0.235718 -0.805464 0.660736
+v 0.209822 -0.847006 0.61317
+v 0.209796 -0.674661 0.719517
+v 0.196963 -0.656883 0.719183
+v 0.87937 -0.76802 0.0100322
+v 0.748887 -0.148723 -0.0163007
+v 0.753807 -0.148363 -0.00349392
+v -0.0790564 0.155287 0.374106
+v 0.125248 0.261427 0.239835
+v 0.145749 0.265692 0.191922
+v 0.138851 0.264485 0.207875
+v -0.662271 0.782703 -0.438924
+v -0.0901162 0.207297 0.105794
+v -0.0962305 0.206925 0.122249
+v -0.102448 0.206809 0.138704
+v -0.15853 0.822022 -0.201029
+v -0.171209 0.821932 -0.192641
+v -0.158492 0.84102 -0.195916
+v -0.639895 -0.571641 -0.0431345
+v -0.639959 -0.551423 -0.0634943
+v -0.626883 -0.570228 -0.0550036
+v -0.635142 0.799414 -0.739671
+v -0.633601 0.781161 -0.7389
+v -0.641192 0.779825 -0.725721
+v 0.230708 -0.0184202 -0.242185
+v 0.243528 -0.018433 -0.240618
+v 0.242371 -0.0272963 -0.242429
+v -0.307099 -0.428005 -0.220824
+v -0.319906 -0.427992 -0.222673
+v -0.30715 -0.409225 -0.22722
+v -0.14521 0.726633 -0.199565
+v -0.145325 0.745785 -0.206103
+v -0.759343 0.250034 -0.077971
+v -0.633832 0.690653 -0.731668
+v -0.54791 -0.455173 0.556831
+v -0.547884 -0.436432 0.564949
+v -0.562913 -0.466194 0.545437
+v -0.547653 -0.417691 0.570691
+v -0.547717 -0.399476 0.574121
+v -0.547794 -0.38139 0.575983
+v -0.547846 -0.363278 0.577794
+v -0.547884 -0.344986 0.581006
+v -0.547974 -0.327054 0.583986
+v -0.547935 -0.308249 0.591372
+v -0.548013 -0.28934 0.598039
+v -0.548077 -0.271678 0.598218
+v -0.547948 -0.253258 0.600158
+v -0.547923 -0.235018 0.602727
+v -0.547961 -0.217047 0.600017
+v -0.547935 -0.199385 0.59466
+v -0.54791 -0.182005 0.586157
+v -0.54791 -0.16451 0.574994
+v -0.548 -0.146552 0.569214
+v -0.547935 -0.128517 0.568764
+v -0.547935 -0.110611 0.565334
+v -0.547948 -0.0927944 0.55895
+v -0.547935 -0.0752734 0.550575
+v -0.547974 -0.0575341 0.539541
+v -0.547871 -0.0403342 0.529136
+v -0.547923 -0.0225307 0.516599
+v -0.547948 -0.00499682 0.505141
+v -0.547948 0.0126269 0.492335
+v -0.547884 0.0303663 0.484358
+v -0.560704 0.0304177 0.485899
+v 0.145788 -0.0548237 0.585502
+v 0.132904 -0.0548109 0.585964
+v -0.225621 0.537884 -0.0121902
+v 0.222705 -0.728277 0.714879
+v 0.209924 -0.727648 0.722831
+v 0.209937 -0.746569 0.715342
+v 0.990803 -0.59687 0.124304
+v 0.275345 -0.109712 0.597974
+v 0.261627 -0.10975 0.593607
+v 0.0713364 0.928548 -0.346322
+v 0.0596343 0.931194 -0.348609
+v 0.0605848 0.937835 -0.343573
+v 0.325378 -0.848316 0.600222
+v 0.312892 -0.848637 0.603511
+v 0.312494 -0.866351 0.60134
+v -0.638276 0.502624 -0.413837
+v -0.645971 0.501249 -0.425128
+v -0.628013 0.515392 -0.427042
+v 0.26146 -0.209276 0.719452
+v 0.26101 -0.192577 0.710383
+v 0.274151 -0.457922 0.746492
+v 0.184259 -0.279449 0.748547
+v 0.209924 -0.786762 0.673607
+v 0.209924 0.104933 0.522598
+v 0.222667 0.104496 0.52202
+v 0.209899 0.122685 0.509856
+v 0.248306 0.0339501 0.554968
+v 0.402373 -0.107322 0.623125
+v 0.389412 -0.142557 0.63565
+v 0.184272 0.156995 0.481365
+v 0.171491 0.157162 0.481493
+v 0.743479 -0.13115 -0.0160566
+v 0.747539 -0.130585 -0.00357099
+v 0.222795 -0.314504 0.756794
+v 0.312558 -0.245846 0.71687
+v 0.31031 -0.327876 0.7431
+v 0.312931 -0.31557 0.742587
+v 0.913243 -0.79971 0.138048
+v 0.915285 -0.800031 0.150829
+v 0.892395 -0.82066 0.150881
+v 0.184208 -0.564795 0.748187
+v 0.184285 -0.766158 0.696472
+v -0.74303 0.511191 -0.357947
+v -0.740666 0.528353 -0.364049
+v -0.724918 0.495328 -0.37051
+v 0.928799 -0.763036 0.0738733
+v 0.762234 -0.647943 0.413259
+v 0.762323 -0.630845 0.401544
+v 0.749542 -0.648469 0.409598
+v 0.749902 -0.631089 0.398936
+v 0.749709 -0.613915 0.392694
+v 0.789427 -0.182262 0.137419
+v 0.793435 -0.199899 0.137445
+v 0.737185 -0.64879 0.406965
+v 0.287125 -0.0745413 0.571038
+v 0.287677 -0.092165 0.591513
+v 0.0590434 0.754533 -0.28532
+v 0.0742266 0.748662 -0.286026
+v 0.0622547 0.737783 -0.270483
+v 0.801476 -0.289854 0.073398
+v 0.158594 -0.806929 0.648521
+v 0.822876 -0.862189 0.0875407
+v 0.827025 -0.863307 0.099885
+v 0.171273 -0.0548366 0.586581
+v 0.223129 -0.456817 0.762548
+v 0.21022 -0.474595 0.764038
+v 0.338416 -0.423201 0.734109
+v 0.338416 -0.440941 0.735625
+v 0.34832 -0.430716 0.729896
+v 0.389797 -0.02167 0.543407
+v 0.776466 -0.886544 0.0745541
+v -0.39401 0.593851 0.137278
+v -0.388011 0.576638 0.136237
+v -0.380073 0.595251 0.12501
+v 0.762311 -0.754957 0.438693
+v 0.762234 -0.736755 0.438693
+v 0.29654 -0.899389 0.605848
+v 0.311415 -0.898413 0.604243
+v 0.29961 -0.884155 0.605296
+v 0.034496 0.245319 0.206963
+v 0.132043 0.263072 0.223842
+v -0.193803 0.880776 -0.0840596
+v 0.105209 0.783435 -0.298473
+v 0.0939569 0.76635 -0.309096
+v 0.0969242 0.772465 -0.312282
+v -0.673293 0.601918 -0.0172127
+v -0.680563 0.598873 -0.00114323
+v -0.116372 0.204369 0.171266
+v -0.123257 0.202506 0.187657
+v -0.130746 0.199436 0.203842
+v -0.696299 0.592477 0.0310214
+v -0.138427 0.196751 0.219989
+v -0.145968 0.193412 0.236122
+v -0.746472 0.268955 -0.0778168
+v -0.746537 0.287658 -0.0745798
+v -0.733434 0.287709 -0.0786903
+v -0.141343 -0.727057 0.495353
+v -0.139506 -0.709407 0.493041
+v -0.149821 -0.714083 0.487004
+v -0.63748 -0.922087 -0.0635585
+v -0.650325 -0.923076 -0.0540145
+v -0.63766 -0.904309 -0.0558642
+v -0.626703 -0.58983 -0.0373027
+v -0.758496 0.118151 -0.0737962
+v -0.770699 -0.104651 -0.110572
+v -0.770866 -0.0863589 -0.10266
+v -0.758072 -0.0858194 -0.110868
+v -0.823326 0.248441 -0.0437511
+v -0.836184 0.248325 -0.0387286
+v -0.823801 0.267336 -0.0360054
+v 0.130643 -0.25354 -0.442289
+v 0.118016 -0.251575 -0.444576
+v 0.120251 -0.233939 -0.436894
+v -0.15826 0.783936 -0.205692
+v -0.145518 0.784 -0.212461
+v -0.145428 0.764925 -0.210945
+v -0.158183 0.764873 -0.205782
+v -0.550273 -0.466875 0.549021
+v -0.759022 0.212551 -0.082287
+v -0.534987 -0.454672 0.559682
+v -0.53509 -0.436213 0.568315
+v -0.534949 -0.417536 0.574455
+v -0.53518 -0.399437 0.578501
+v -0.534897 -0.381017 0.580941
+v -0.535026 -0.363047 0.581301
+v -0.534949 -0.344858 0.582547
+v -0.535052 -0.326746 0.584538
+v -0.535077 -0.308339 0.589432
+v -0.53509 -0.290137 0.593003
+v -0.534923 -0.272128 0.59362
+v -0.53509 -0.253245 0.600762
+v -0.53509 -0.235005 0.602907
+v -0.535077 -0.217008 0.60125
+v -0.535077 -0.199552 0.595559
+v -0.535103 -0.182056 0.586015
+v -0.535154 -0.164214 0.574544
+v -0.535129 -0.146488 0.570755
+v -0.535116 -0.128363 0.570575
+v -0.53509 -0.110405 0.5673
+v -0.53509 -0.0927174 0.560492
+v -0.535077 -0.0751578 0.552207
+v -0.535103 -0.0573543 0.541327
+v -0.535129 -0.0398461 0.529881
+v -0.535103 -0.0225563 0.518102
+v -0.53509 -0.00498398 0.50518
+v -0.53509 0.0126012 0.49227
+v -0.534962 0.0303277 0.483202
+v -0.534962 0.0484782 0.484563
+v -0.549425 0.048157 0.486079
+v 0.145634 -0.565322 0.74197
+v 0.145711 -0.547479 0.741598
+v 0.0868278 0.744565 -0.283586
+v 0.261472 -0.226886 0.725657
+v 0.248434 -0.209263 0.723473
+v 0.274202 -0.422675 0.740775
+v 0.274292 -0.405051 0.738194
+v 0.286983 -0.0386001 0.553941
+v 0.286803 -0.0203855 0.555032
+v -0.046622 0.650948 -0.155235
+v 0.248601 -0.35051 0.755059
+v 0.274305 -0.125935 0.615611
+v 0.222654 0.122005 0.509059
+v 0.740371 -0.0579451 0.150316
+v 0.145621 -0.71109 0.710859
+v 0.402308 -0.090585 0.612734
+v 0.402475 -0.0733595 0.595431
+v 0.389694 -0.0734494 0.596908
+v 0.342321 -0.569676 0.720184
+v 0.342603 -0.586927 0.720506
+v 0.184285 -0.455803 0.77452
+v 0.248512 -0.530023 0.737282
+v 0.184311 -0.473953 0.771681
+v 0.734937 -0.113051 -0.0165833
+v 0.740782 -0.112923 -0.00346823
+v 0.209937 -0.618385 0.746004
+v 0.209873 -0.600505 0.748483
+v 0.145865 -0.747725 0.699221
+v 0.145736 -0.72915 0.707288
+v 0.184234 -0.746826 0.712156
+v 0.248165 -0.00168273 0.565733
+v 0.235551 0.122429 0.504936
+v 0.324928 -0.827032 0.622457
+v 0.312301 -0.825811 0.63389
+v 0.261357 -0.494287 0.738951
+v 0.248781 -0.494313 0.741456
+v 0.248614 -0.512168 0.739619
+v 0.749568 -0.908753 0.112859
+v 0.76962 -0.899004 0.114683
+v 0.753691 -0.907289 0.120116
+v 0.286983 -0.142775 0.63976
+v 0.145736 -0.0369174 0.58405
+v 0.145711 -0.0192166 0.579092
+v 0.299803 0.121825 0.493337
+v 0.274189 -0.297214 0.74987
+v 0.274176 -0.279861 0.742214
+v 0.261331 -0.279745 0.743756
+v 0.210104 -0.51132 0.749973
+v -0.419868 0.404961 0.114734
+v 0.787976 -0.700762 0.435289
+v 0.77504 -0.700852 0.433876
+v 0.222731 -0.91921 0.618797
+v 0.213213 -0.904052 0.620582
+v 0.20968 -0.918824 0.621314
+v -0.149205 -0.808329 0.646697
+v -0.136334 -0.791579 0.635817
+v -0.152814 -0.804103 0.635881
+v 0.0269687 0.242224 0.222956
+v 0.0522097 0.213515 0.363149
+v 0.0404049 0.202532 0.377832
+v 0.17013 0.267079 0.127091
+v 0.0270329 0.18925 0.392372
+v 0.0146115 0.176661 0.406836
+v -0.373419 -0.570884 0.522367
+v -0.370979 -0.588674 0.520312
+v -0.360818 -0.58852 0.528533
+v -0.367999 -0.565887 0.527299
+v -0.532585 -0.840262 0.579606
+v -0.521949 -0.833223 0.578938
+v -0.521757 -0.824386 0.568276
+v -0.688026 0.596561 0.0151703
+v -0.664918 0.60617 -0.0329097
+v -0.154201 0.189173 0.252025
+v -0.162564 0.184523 0.267914
+v -0.704558 0.588096 0.0468596
+v -0.171453 0.179346 0.283843
+v -0.247034 0.61159 -0.127811
+v -0.247253 0.630422 -0.139937
+v 0.0255943 0.677088 -0.185037
+v 0.0250162 0.663524 -0.164446
+v -0.667448 -0.284626 -0.199988
+v -0.667397 -0.266322 -0.196495
+v -0.654821 -0.265821 -0.20189
+v -0.639073 -0.590306 -0.0284395
+v -0.732587 -0.0117149 -0.0965966
+v -0.745496 -0.0121773 -0.0884784
+v -0.732754 0.00661533 -0.0886582
+v -0.654744 -0.247529 -0.198447
+v -0.522849 -0.899325 -0.0971361
+v -0.535488 -0.899967 -0.0933211
+v -0.52272 -0.881765 -0.0885812
+v -0.192956 -0.91813 -0.370253
+v -0.180213 -0.919942 -0.368108
+v -0.184747 -0.943076 -0.371332
+v -0.823763 0.286039 -0.0307516
+v -0.836775 0.285834 -0.0239436
+v -0.823724 0.304729 -0.0269751
+v -0.770994 0.0800519 -0.056879
+v -0.7582 0.0804244 -0.0619657
+v -0.757892 0.0610023 -0.0514711
+v -0.835966 0.210817 -0.0454724
+v -0.836184 0.229674 -0.0440851
+v -0.82321 0.229879 -0.048992
+v -0.158376 0.80296 -0.204163
+v -0.145723 0.822086 -0.209199
+v -0.522206 -0.473709 0.54843
+v -0.522219 -0.454801 0.559965
+v -0.535142 -0.474184 0.547312
+v -0.522258 -0.436072 0.569984
+v -0.522258 -0.417536 0.576587
+v -0.521937 -0.398577 0.583588
+v -0.522116 -0.380658 0.586028
+v -0.521949 -0.362469 0.587107
+v -0.522065 -0.344524 0.587493
+v -0.522155 -0.326515 0.587621
+v -0.522091 -0.308184 0.590306
+v -0.522193 -0.290201 0.590717
+v -0.522271 -0.272063 0.59353
+v -0.522232 -0.253245 0.60134
+v -0.522258 -0.235005 0.602907
+v -0.522219 -0.216944 0.600261
+v -0.522232 -0.199308 0.594879
+v -0.522258 -0.182095 0.584512
+v -0.522245 -0.164446 0.573761
+v -0.522258 -0.146462 0.571924
+v -0.522245 -0.128273 0.572155
+v -0.522245 -0.110392 0.568623
+v -0.522193 -0.0929357 0.561429
+v -0.522245 -0.0748495 0.552733
+v -0.522271 -0.0571744 0.543112
+v -0.522271 -0.0398461 0.531371
+v -0.522232 -0.0225692 0.519567
+v -0.522283 -0.0047913 0.505424
+v -0.522232 0.0124214 0.491949
+v -0.522206 0.0302892 0.482457
+v -0.522052 0.0483497 0.481557
+v -0.0739183 0.604692 -0.0783435
+v 0.0587608 -0.874765 0.667814
+v 0.055254 -0.859941 0.667634
+v 0.0462495 -0.875304 0.672053
+v 0.1732 -0.87014 0.630563
+v 0.170823 -0.863782 0.629766
+v 0.160765 -0.870654 0.634789
+v 0.287009 -0.512219 0.737256
+v 0.248255 -0.0742715 0.572386
+v 0.261293 -0.0741431 0.569959
+v 0.248242 -0.0560826 0.567788
+v 0.145634 -0.438179 0.771373
+v 0.261151 -0.0563909 0.564551
+v 0.248434 -0.0379065 0.565399
+v 0.299983 -0.351357 0.742253
+v 0.299918 -0.369456 0.737474
+v 0.306058 -0.363085 0.737025
+v 0.286829 0.103713 0.505732
+v 0.209924 -0.582611 0.74811
+v 0.197002 -0.58265 0.748624
+v -0.580537 0.460761 -0.0523189
+v -0.575797 0.440607 -0.0474505
+v -0.583594 0.438731 -0.0593967
+v 0.197285 -0.492566 0.762278
+v 0.197182 -0.511102 0.753043
+v 0.402514 -0.0561468 0.577743
+v 0.402565 -0.0390882 0.561262
+v 0.389797 -0.0391011 0.561237
+v 0.184221 -0.350073 0.758977
+v -0.302899 0.512951 -0.0405655
+v -0.292802 0.526002 -0.0529612
+v -0.349771 0.552862 -0.0701096
+v -0.362629 0.552746 -0.0668726
+v -0.36286 0.571731 -0.0769176
+v 0.171363 -0.314517 0.755689
+v 0.762709 -0.165743 0.00906878
+v 0.197079 -0.727712 0.722998
+v -0.926307 -0.117599 0.179025
+v -0.928143 -0.134888 0.166205
+v -0.108279 0.597037 -0.0235326
+v -0.128562 0.580787 -0.0415545
+v -0.124567 0.581519 -0.0452797
+v 0.248691 -0.476252 0.742677
+v 0.274138 -0.209789 0.714327
+v 0.209911 0.0872966 0.533928
+v 0.222731 0.0872581 0.532361
+v 0.145634 -0.583151 0.742214
+v 0.145569 -0.529727 0.743871
+v 0.389746 -0.0563009 0.579156
+v 0.377042 -0.0392681 0.561134
+v 0.312622 0.121876 0.493375
+v 0.865189 -0.630807 0.407286
+v 0.852536 -0.630319 0.411191
+v 0.863686 -0.649754 0.409701
+v 0.453869 -0.303265 0.660068
+v 0.726061 -0.0955048 -0.0156713
+v 0.72687 -0.10695 -0.0282725
+v 0.716337 -0.087849 -0.0229674
+v 0.321897 0.0803473 0.513298
+v 0.325211 0.085935 0.509085
+v 0.732227 -0.0957103 -0.00323702
+v -0.515514 -0.692195 0.0792426
+v -0.526754 -0.673929 0.0789472
+v -0.267446 -0.635585 -0.137946
+v -0.2546 -0.635637 -0.136379
+v 0.788065 -0.718797 0.437061
+v 0.787924 -0.682895 0.432052
+v 0.775002 -0.682984 0.430484
+v 0.018722 0.237921 0.238653
+v -0.686138 0.540903 -0.575945
+v -0.683209 0.558835 -0.609407
+v -0.140084 -0.44649 -0.438282
+v -0.127483 -0.445796 -0.446759
+v -0.127355 -0.464101 -0.443304
+v -0.621629 0.45877 -0.223354
+v -0.50931 -0.849254 0.595649
+v -0.522232 -0.849524 0.591051
+v -0.509284 -0.866287 0.60694
+v -0.508937 -0.833878 0.581365
+v -0.271312 0.829536 -0.038523
+v -0.496516 -0.800981 0.532206
+v -0.509361 -0.816473 0.559914
+v -0.180509 0.173617 0.299539
+v -0.189731 0.167477 0.315044
+v -0.175473 0.083032 0.433927
+v 0.0173733 0.740763 -0.251087
+v 0.0329803 0.733929 -0.25277
+v -0.207625 0.157008 0.347067
+v -0.217323 0.150341 0.36288
+v -0.227188 0.142955 0.378333
+v -0.180123 -0.111022 -0.271896
+v -0.193033 -0.111202 -0.268942
+v -0.180072 -0.092743 -0.269918
+v -0.305814 -0.691424 -0.125653
+v -0.318634 -0.691347 -0.127374
+v -0.305943 -0.672772 -0.128697
+v -0.0146115 0.633479 -0.113771
+v -0.0254016 0.624526 -0.101337
+v -0.0249777 0.634519 -0.121272
+v -0.192904 -0.0929743 -0.266591
+v -0.18679 -0.288415 -0.321389
+v -0.192416 -0.275133 -0.303663
+v -0.177644 -0.270355 -0.321903
+v -0.721103 0.363124 -0.06966
+v -0.733691 0.362957 -0.0673479
+v -0.72127 0.381942 -0.0700197
+v -0.836865 0.304536 -0.0169815
+v -0.837353 0.323393 -0.0105203
+v -0.824019 0.323599 -0.022171
+v -0.822992 0.211048 -0.0504049
+v -0.19636 -0.0350548 -0.233951
+v -0.210335 -0.0351576 -0.23363
+v -0.509412 -0.45516 0.558719
+v -0.509412 -0.473953 0.546966
+v -0.5094 -0.435995 0.569779
+v -0.509412 -0.417408 0.578205
+v -0.509245 -0.398358 0.58721
+v -0.509412 -0.380336 0.591359
+v -0.509181 -0.361968 0.593787
+v -0.509168 -0.343984 0.5938
+v -0.509066 -0.325988 0.593299
+v -0.509348 -0.308146 0.592798
+v -0.509335 -0.290111 0.592528
+v -0.509425 -0.271922 0.595469
+v -0.509412 -0.253271 0.601186
+v -0.509412 -0.23503 0.60274
+v -0.509425 -0.217163 0.599426
+v -0.509464 -0.199526 0.594313
+v -0.509412 -0.182082 0.583125
+v -0.509412 -0.164407 0.574082
+v -0.5094 -0.146231 0.574198
+v -0.5094 -0.128158 0.573774
+v -0.509412 -0.110367 0.568751
+v -0.509374 -0.0924733 0.559708
+v -0.509374 -0.0749009 0.552695
+v -0.5094 -0.057457 0.544127
+v -0.509438 -0.039692 0.53159
+v -0.509412 -0.022338 0.519862
+v -0.509412 -0.00503536 0.506619
+v -0.5094 0.0124471 0.491975
+v -0.509374 0.0302378 0.480915
+v -0.509194 0.0482983 0.47841
+v 0.248627 -0.458217 0.743794
+v 0.235949 -0.457511 0.75321
+v -0.496567 0.0487351 0.474531
+v -0.496516 0.0303021 0.481018
+v 0.248242 0.0514326 0.546426
+v 0.48096 -0.427915 0.673941
+v 0.491622 -0.427903 0.666735
+v 0.481577 -0.410561 0.674969
+v 0.809003 -0.433246 0.0865645
+v 0.210181 -0.43832 0.770127
+v 0.210245 -0.456329 0.76874
+v 0.19704 -0.22645 0.737179
+v 0.197053 -0.208954 0.730859
+v 0.210001 -0.636664 0.739607
+v 0.19713 -0.402906 0.766697
+v 0.14589 0.15697 0.478218
+v 0.132955 0.157368 0.475469
+v 0.132865 0.140142 0.487351
+v 0.197092 -0.529149 0.747828
+v 0.184234 -0.191703 0.721508
+v 0.184234 -0.208736 0.73136
+v 0.714192 -0.0667955 0.00637127
+v 0.71495 -0.0781893 -0.00728328
+v 0.704815 -0.0607454 -0.00333978
+v 0.235705 -0.826274 0.632477
+v 0.998253 -0.596214 0.214504
+v 0.997457 -0.578488 0.214516
+v 0.996981 -0.578514 0.227362
+v 0.197079 -0.709728 0.724359
+v 0.376977 -0.0735265 0.598398
+v 0.377016 -0.0566221 0.58044
+v 0.338326 0.103996 0.49692
+v 0.338364 0.121902 0.488918
+v 0.325493 0.121992 0.492039
+v 0.325519 0.139808 0.482328
+v 0.325326 -0.194054 0.682946
+v -0.231851 -0.429727 -0.243534
+v 0.338313 0.139616 0.480478
+v 0.346907 0.132409 0.481493
+v -0.228666 -0.691925 -0.118485
+v -0.215872 -0.691899 -0.118498
+v -0.732317 -0.157381 -0.158177
+v -0.744995 -0.157971 -0.151343
+v -0.732638 -0.139076 -0.150534
+v 0.762645 -0.613787 0.38911
+v 0.750917 -0.595919 0.387645
+v 0.963481 -0.688418 0.0862048
+v 0.184362 -0.26162 0.744758
+v 0.171376 -0.191947 0.722574
+v 0.345622 -0.396496 0.726376
+v 0.338583 -0.387979 0.727095
+v 0.145428 -0.456021 0.772195
+v 0.621115 -0.850269 0.403985
+v 0.633909 -0.831361 0.408866
+v 0.616028 -0.84233 0.412848
+v 0.912446 -0.607428 0.00806685
+v 0.911278 -0.622496 -0.00236353
+v 0.900847 -0.617178 -0.0083366
+v 0.700319 -0.0607454 -0.0164034
+v 0.69274 -0.0426335 -0.0166218
+v 0.697724 -0.0423253 -0.00380221
+v 0.684301 -0.0250355 -0.0164805
+v 0.689401 -0.0246244 -0.00372514
+v 0.673819 -0.00685939 -0.0168402
+v 0.678251 -0.0068337 -0.00380221
+v 0.787911 -0.66504 0.428609
+v 0.77495 -0.665181 0.425719
+v 0.0111947 0.234735 0.254632
+v 0.453612 -0.320876 0.668534
+v -0.496464 -0.883191 0.617242
+v -0.509322 -0.900815 0.621892
+v -0.496426 -0.900725 0.6231
+v -0.496529 -0.866094 0.608649
+v -0.496349 -0.849524 0.598193
+v -0.496336 -0.833403 0.581841
+v -0.496593 -0.815972 0.561751
+v -0.522849 -0.873878 0.607249
+v -0.237811 0.13431 0.39358
+v -0.60624 0.363522 -0.0761726
+v -0.619008 0.363625 -0.0791656
+v 0.0465963 0.744115 -0.269366
+v -0.132917 0.113398 0.412861
+v -0.714899 0.832298 -0.513632
+v -0.420138 0.480453 -0.0148749
+v -0.406573 0.476252 -0.0126912
+v -0.617762 0.449431 -0.186218
+v -0.63775 -0.94007 -0.0687095
+v -0.624789 -0.921419 -0.0682085
+v -0.192712 -0.202288 -0.288223
+v 0.453818 -0.965761 -0.0785361
+v 0.462116 -0.957501 -0.0788701
+v 0.462167 -0.957501 -0.0660377
+v -0.758406 -0.122069 -0.125961
+v -0.758303 -0.103931 -0.117701
+v -0.171273 0.802908 -0.196058
+v -0.73355 0.269045 -0.0808868
+v -0.836659 0.267208 -0.0308673
+v -0.14896 -0.925054 0.0726016
+v -0.152493 -0.923513 0.0471808
+v -0.522733 -0.480003 0.543485
+v -0.508462 -0.492579 0.533375
+v -0.313894 -0.956628 0.570537
+v -0.323079 -0.965555 0.554056
+v -0.496593 -0.455417 0.557319
+v -0.495193 -0.474261 0.545296
+v -0.49658 -0.436342 0.568636
+v -0.496554 -0.417395 0.578231
+v -0.496541 -0.398513 0.587762
+v -0.496387 -0.379668 0.594994
+v -0.496297 -0.361518 0.59827
+v -0.496413 -0.343625 0.598861
+v -0.496336 -0.325628 0.598578
+v -0.496374 -0.307773 0.597306
+v -0.496451 -0.28988 0.595739
+v -0.496567 -0.271755 0.59642
+v -0.496541 -0.253361 0.599952
+v -0.496631 -0.235159 0.601006
+v -0.496503 -0.217291 0.596728
+v -0.49667 -0.199796 0.590884
+v -0.496541 -0.182082 0.580582
+v -0.496567 -0.164446 0.575161
+v -0.496618 -0.146218 0.575726
+v -0.496516 -0.128068 0.57299
+v -0.496541 -0.110392 0.5673
+v -0.496529 -0.0926917 0.559169
+v -0.496516 -0.0748495 0.551372
+v -0.496554 -0.0573414 0.542868
+v -0.496567 -0.0398333 0.532874
+v -0.496593 -0.0219783 0.52035
+v -0.496567 -0.00498398 0.506683
+v -0.496541 0.0129609 0.491243
+v -0.506073 0.0680929 0.483433
+v 0.248473 -0.65583 0.727635
+v 0.158556 -0.65705 0.717538
+v 0.794231 -0.236058 0.227259
+v 0.235602 -0.674442 0.718104
+v 0.809838 -0.397164 0.0991785
+v 0.364222 -0.0903538 0.616163
+v 0.145711 -0.619246 0.738939
+v 0.402578 -0.0214003 0.54378
+v 0.441127 0.067258 0.492091
+v 0.702567 -0.0420555 0.00905593
+v 0.248062 -0.159153 0.680981
+v 0.13284 -0.226013 0.743473
+v 0.132852 -0.208428 0.734584
+v 0.325763 -0.494544 0.73619
+v 0.248473 -0.674956 0.713659
+v 0.23582 -0.71109 0.711026
+v 0.325365 -0.160129 0.651809
+v -0.603389 0.578501 -0.489072
+v -0.604121 0.572078 -0.475957
+v 0.878124 -0.578244 0.381685
+v 0.20995 -0.709651 0.724629
+v 0.209937 -0.691976 0.723229
+v -0.561217 0.411011 -0.03878
+v -0.576632 0.420979 -0.0529483
+v -0.566702 0.420979 -0.0391011
+v 0.453612 -0.143405 0.621096
+v 0.453638 -0.125794 0.616459
+v 0.453805 -0.16126 0.624564
+v 0.466548 -0.161453 0.622714
+v 0.453908 -0.178999 0.627095
+v 0.466586 -0.179256 0.62599
+v 0.865535 -0.612759 0.401981
+v 0.567936 -0.671591 -0.246912
+v 0.577724 -0.652464 -0.247144
+v 0.578726 -0.67028 -0.233707
+v 0.4536 -0.214902 0.631578
+v 0.466663 -0.214992 0.631423
+v 0.453818 -0.196957 0.630088
+v -0.26751 -0.616035 -0.146886
+v -0.254729 -0.616382 -0.147785
+v -0.621912 -0.824655 0.0927174
+v -0.583273 -0.810975 0.0797308
+v -0.0925825 0.632181 -0.138164
+v 0.799087 -0.271845 0.214491
+v -0.89815 -0.327247 0.231408
+v -0.898818 -0.326977 0.218537
+v 0.995594 -0.632066 0.214581
+v 0.997251 -0.614159 0.214568
+v 0.995825 -0.614262 0.227465
+v -0.954913 0.426708 0.304408
+v -0.958253 0.426592 0.291601
+v -0.410645 0.365616 0.191806
+v -0.412649 0.365487 0.204613
+v -0.404865 0.346091 0.204677
+v 0.787783 -0.647454 0.420696
+v 0.775002 -0.647853 0.417318
+v 0.466727 -0.197047 0.628392
+v -0.483439 -0.884052 0.617974
+v -0.483709 -0.865991 0.608777
+v -0.483683 -0.849614 0.598167
+v 0.86867 -0.842151 0.202365
+v 0.868426 -0.841727 0.215172
+v 0.837083 -0.862279 0.215236
+v 0.704121 -0.934418 0.15977
+v 0.693049 -0.938413 0.185152
+v 0.687667 -0.941894 0.162647
+v -0.605187 0.44035 -0.138973
+v -0.613305 0.439553 -0.150059
+v -0.603157 0.452527 -0.162403
+v -0.597326 0.45516 -0.14871
+v 0.663659 0.0106873 -0.0166732
+v 0.664661 0.015029 -0.00342969
+v -0.689825 0.793531 -0.430947
+v -0.701617 0.797295 -0.435353
+v -0.697146 0.791001 -0.415263
+v -0.709067 0.794379 -0.419784
+v -0.717134 0.790204 -0.404383
+v -0.704545 0.788175 -0.399669
+v -0.107226 0.139513 0.383381
+v -0.0946377 0.151934 0.368622
+v -0.368769 0.273566 0.248749
+v -0.375834 0.285512 0.245782
+v -0.639574 -0.529034 -0.0957232
+v -0.627332 -0.550203 -0.0766864
+v -0.624982 -0.903577 -0.0622355
+v -0.170964 0.783833 -0.198987
+v -0.639985 -0.509804 -0.120373
+v -0.627384 -0.509072 -0.132024
+v -0.626587 -0.527929 -0.10975
+v 0.421473 -0.310432 -0.355314
+v 0.432739 -0.314389 -0.3506
+v 0.424826 -0.323894 -0.354119
+v -0.772176 0.287208 -0.0647018
+v -0.772394 0.305898 -0.0600646
+v -0.759343 0.306206 -0.0679131
+v -0.630287 -0.0446374 -0.162776
+v -0.642785 -0.0451512 -0.158883
+v -0.630466 -0.02632 -0.156417
+v -0.772304 0.249815 -0.0716511
+v -0.13212 0.707699 -0.192615
+v -0.119159 0.688611 -0.184536
+v -0.151234 -0.889884 -0.360516
+v -0.151285 -0.871656 -0.359052
+v -0.138415 -0.871733 -0.357485
+v -0.633922 0.545116 -0.525694
+v -0.626099 0.559438 -0.534364
+v -0.153251 -0.854264 -0.352835
+v -0.138376 -0.889897 -0.358936
+v -0.483696 -0.473991 0.545193
+v -0.483722 -0.455237 0.556972
+v -0.597261 -0.627377 0.0131793
+v -0.606728 -0.621301 0.00497113
+v -0.483735 -0.436547 0.567133
+v -0.483735 -0.417935 0.575559
+v -0.483709 -0.398602 0.586028
+v -0.483709 -0.379771 0.595636
+v -0.483632 -0.36139 0.600274
+v -0.483658 -0.343483 0.600864
+v -0.483696 -0.325526 0.601044
+v -0.483619 -0.307542 0.600659
+v -0.483645 -0.289649 0.599079
+v -0.483709 -0.271781 0.596266
+v -0.483837 -0.25354 0.597525
+v -0.483799 -0.235544 0.596266
+v -0.483683 -0.217625 0.591834
+v -0.483747 -0.200014 0.586336
+v -0.483709 -0.182288 0.579914
+v -0.483722 -0.164343 0.575418
+v -0.483426 -0.146269 0.5715
+v -0.483709 -0.128427 0.568995
+v -0.483632 -0.110431 0.564448
+v -0.483837 -0.0931541 0.556844
+v -0.483735 -0.0752606 0.549124
+v -0.483709 -0.0574699 0.541185
+v -0.483683 -0.0395121 0.531975
+v -0.483709 -0.0219269 0.521943
+v -0.483696 -0.00531795 0.506246
+v -0.483722 0.0129095 0.491217
+v -0.48367 0.0305975 0.479939
+v -0.483825 0.0488635 0.470909
+v -0.470838 0.0306489 0.479939
+v -0.470787 0.0480029 0.469701
+v 0.158363 -0.437973 0.773737
+v 0.402154 -0.178421 0.644025
+v 0.402193 -0.160682 0.635906
+v 0.389489 -0.160412 0.639452
+v 0.392058 -0.191022 0.659015
+v 0.389257 -0.178344 0.649767
+v 0.158453 -0.367915 0.757012
+v 0.145634 -0.385539 0.759774
+v -0.260432 0.649355 -0.147117
+v -0.247407 0.649587 -0.149969
+v 0.235551 -0.00151575 0.566722
+v -0.229603 -0.520132 -0.206578
+v -0.229706 -0.501057 -0.216418
+v -0.219841 -0.521879 -0.218113
+v 0.325622 -0.676343 0.700107
+v 0.132955 0.0335134 0.552862
+v 0.646921 -0.773942 0.433426
+v 0.648013 -0.766505 0.437575
+v 0.415423 0.0496599 0.505013
+v 0.479483 -0.215017 0.632374
+v 0.261293 -0.476137 0.741687
+v 0.761835 -0.589175 0.377857
+v 0.762889 -0.596433 0.380606
+v 0.775349 -0.596163 0.380773
+v 0.335988 -0.482791 0.734481
+v 0.440985 -0.0391268 0.553517
+v 0.453587 -0.0398204 0.551256
+v 0.441075 -0.0216829 0.535803
+v 0.453535 -0.24135 0.635264
+v 0.453754 -0.232885 0.633376
+v 0.441499 -0.224407 0.640325
+v 0.145762 0.0160695 0.562919
+v 0.132878 0.0162365 0.561802
+v 0.13293 -0.00168273 0.572335
+v 0.453959 -0.268171 0.644962
+v 0.453844 -0.250573 0.63854
+v 0.446586 -0.258152 0.647634
+v 0.787847 -0.630229 0.410703
+v 0.775027 -0.630537 0.407491
+v 0.787744 -0.612952 0.398076
+v 0.774693 -0.613055 0.393413
+v 0.78786 -0.595868 0.385243
+v 0.787988 -0.578925 0.373516
+v 0.77549 -0.579182 0.370548
+v 0.788322 -0.561802 0.35927
+v 0.775439 -0.561982 0.360465
+v 0.752253 -0.130328 0.00931284
+v 0.788836 -0.544461 0.346553
+v 0.776106 -0.544294 0.355802
+v -0.418018 0.385192 0.191793
+v -0.791611 0.47922 0.542932
+v -0.609477 0.48983 -0.302353
+v 0.750788 -0.112217 0.0220811
+v 0.745856 -0.112589 0.00928715
+v 0.742953 -0.0944258 0.0220168
+v -0.589053 0.499412 -0.193309
+v -0.585431 0.520055 -0.193155
+v -0.588064 0.499721 -0.180399
+v 0.925484 -0.780737 0.0995511
+v 0.939589 -0.76188 0.0994611
+v 0.927861 -0.781328 0.112204
+v 0.949171 -0.743216 0.0993198
+v 0.952575 -0.743023 0.112037
+v 0.94316 -0.761816 0.112139
+v 0.699279 -0.0233014 0.330432
+v 0.702426 -0.0231729 0.317497
+v 0.690184 -0.00236353 0.319604
+v 0.453677 -0.108157 0.6087
+v 0.462116 -0.103957 0.602714
+v 0.44087 -0.0906621 0.602136
+v -0.470851 -0.883268 0.615611
+v -0.483735 -0.900725 0.623035
+v -0.470054 -0.898991 0.62089
+v -0.470889 -0.865966 0.60879
+v -0.470941 -0.849318 0.597024
+v -0.10458 0.634635 -0.143328
+v -0.103527 0.619953 -0.124882
+v -0.293534 -0.82305 -0.254003
+v -0.276527 -0.827918 -0.275352
+v -0.304902 -0.840147 -0.266797
+v 0.153944 -0.143957 0.672901
+v 0.152647 -0.158203 0.692079
+v -0.470876 -0.816665 0.559772
+v -0.483388 -0.799992 0.536355
+v 0.788605 -0.526734 0.336393
+v -0.267677 -0.597088 -0.156957
+v -0.254844 -0.597319 -0.157548
+v -0.429643 0.303689 0.377356
+v -0.422899 0.290561 0.380092
+v -0.70267 0.585758 0.122583
+v -0.651636 0.907533 -0.694417
+v -0.641205 0.900571 -0.690859
+v 0.0113874 -0.0551063 -0.264433
+v -1.92679e-05 -0.0359668 -0.259
+v 0.0126205 -0.0379964 -0.256752
+v -0.730377 0.592361 0.20618
+v -0.693845 0.868663 -0.598565
+v 0.0942138 -0.656074 0.724205
+v 0.0815741 -0.637846 0.727275
+v 0.0812658 -0.657191 0.715753
+v -0.5364 0.582971 0.256533
+v -0.171042 -0.923898 0.694096
+v -0.179352 -0.942819 0.684834
+v -0.159404 -0.942228 0.701315
+v -0.162011 -0.923628 0.703434
+v -0.168884 -0.92481 0.438847
+v -0.173688 -0.925337 0.41525
+v 0.439778 -0.973776 0.0224793
+v 0.430992 -0.973481 0.0444833
+v 0.426406 -0.974354 0.0203084
+v -0.535925 0.187207 -0.0797051
+v -0.541526 0.193874 -0.0803345
+v -0.528321 0.193951 -0.0750936
+v -0.772497 0.324588 -0.0532951
+v -0.759497 0.324909 -0.0615161
+v -0.835208 0.0586902 -0.00856781
+v -0.821913 0.0594866 -0.0165576
+v -0.821694 0.0409123 -0.00707776
+v -0.759369 0.343702 -0.0593838
+v -0.834912 0.0781251 -0.0167246
+v -0.821913 0.0786132 -0.0251768
+v -0.20634 0.556214 -0.0578809
+v -0.479149 -0.487094 0.53651
+v -0.470864 -0.473991 0.547004
+v -0.470812 -0.454698 0.559811
+v -0.470889 -0.43647 0.566979
+v -0.470876 -0.41796 0.573735
+v -0.470864 -0.399013 0.583189
+v -0.470954 -0.380067 0.592913
+v -0.470902 -0.361467 0.598552
+v -0.470889 -0.343843 0.598411
+v -0.470812 -0.325371 0.602226
+v -0.470761 -0.30726 0.603652
+v -0.470864 -0.289494 0.601327
+v -0.470851 -0.271665 0.597743
+v -0.470864 -0.253772 0.594647
+v -0.470941 -0.235968 0.591051
+v -0.470851 -0.217998 0.586876
+v -0.470864 -0.200232 0.583048
+v -0.470851 -0.182275 0.579978
+v -0.470864 -0.164446 0.575123
+v -0.470902 -0.146629 0.56897
+v -0.470876 -0.128697 0.564281
+v -0.470787 -0.110945 0.559181
+v -0.470774 -0.093077 0.551346
+v -0.470787 -0.0752991 0.544808
+v -0.470838 -0.0576369 0.538051
+v -0.470851 -0.0398461 0.53141
+v -0.470851 -0.0219783 0.520414
+v -0.470889 -0.00452154 0.505796
+v -0.470915 0.0131407 0.491435
+v -0.474692 0.0677846 0.461313
+v -0.48561 0.0678232 0.468095
+v 0.145762 -0.279218 0.752426
+v 0.184298 -0.437909 0.774931
+v 0.17135 -0.437871 0.775047
+v 0.184195 -0.547158 0.747108
+v 0.21022 -0.420517 0.768907
+v 0.312366 -0.805953 0.65425
+v 0.13293 -0.0730384 0.583986
+v 0.132942 0.0869627 0.524358
+v 0.132968 0.0690949 0.535315
+v 0.184324 -0.492347 0.765297
+v -0.425931 0.424447 0.178742
+v -0.429425 0.424344 0.191613
+v -0.424723 0.404974 0.191857
+v 0.13284 0.105036 0.513722
+v -0.422296 0.385012 0.0892234
+v 0.983841 -0.686453 0.1632
+v 0.990469 -0.668174 0.163122
+v 0.984265 -0.686581 0.176058
+v 0.415488 0.0318692 0.514814
+v 0.145711 -0.60098 0.741469
+v 0.479444 -0.197137 0.629098
+v 0.322732 -0.310394 0.739195
+v 0.184259 -0.529265 0.748495
+v 0.336939 -0.465462 0.736344
+v 0.427948 -0.0907135 0.606478
+v 0.427948 -0.0739375 0.591706
+v 0.454101 -0.021426 0.531603
+v 0.453959 -0.00402058 0.523009
+v 0.44105 -0.00402058 0.525976
+v 0.813384 -0.432887 0.137792
+v 0.814347 -0.447671 0.13819
+v 0.758971 -0.147952 0.00923577
+v 0.783685 -0.507312 0.335237
+v 0.79838 -0.518051 0.321171
+v 0.0122095 0.652939 -0.148389
+v 0.0345089 0.663755 -0.15521
+v 0.235448 0.139474 0.489817
+v 0.235615 -0.600299 0.749253
+v 0.588334 -0.542406 -0.24663
+v 0.597557 -0.541879 -0.23503
+v 0.588642 -0.560877 -0.236199
+v 0.851752 -0.842395 0.0870269
+v 0.858869 -0.840802 0.0999364
+v 0.578841 -0.561442 -0.246848
+v 0.596619 -0.523613 -0.24681
+v 0.605534 -0.523009 -0.234748
+v -0.580588 0.540132 -0.206064
+v -0.578507 0.560132 -0.206116
+v -0.580306 0.560119 -0.193258
+v 0.730827 -0.131793 -0.0418885
+v 0.724558 -0.132114 -0.0548623
+v 0.724571 -0.113976 -0.0420298
+v -0.333612 0.483317 0.0643935
+v -0.30909 0.504987 0.0637127
+v -0.988568 0.110457 0.216328
+v 0.415077 -0.178562 0.637975
+v 0.364235 -0.0562239 0.580839
+v 0.364196 -0.0731026 0.597319
+v 0.223463 -0.865208 0.613363
+v 0.99413 -0.650101 0.201774
+v 0.995427 -0.649934 0.188839
+v 0.996763 -0.631924 0.201723
+v 0.28697 -0.0566478 0.558462
+v -0.447267 -0.880519 0.608572
+v -0.45202 -0.86314 0.602008
+v -0.458314 -0.866557 0.60626
+v 0.0801225 0.793467 -0.329636
+v -0.45807 -0.816717 0.559747
+v -0.458314 -0.785387 0.507505
+v -0.568 0.581031 0.338486
+v -0.555977 0.577602 0.342802
+v 0.69486 -0.00581892 0.302841
+v 0.00325628 0.234619 0.233116
+v -0.00501609 0.230265 0.24889
+v -0.457569 -0.589895 0.451795
+v -0.444415 -0.588739 0.461108
+v -0.623903 -0.409701 0.552618
+v -0.14476 0.688688 -0.182467
+v -0.618251 0.250997 -0.0927045
+v -0.60547 0.23214 -0.0905208
+v -0.772407 0.362443 -0.0545154
+v -0.75951 0.360092 -0.0593324
+v -0.771701 0.174401 -0.072653
+v -0.758573 0.174825 -0.0783949
+v -0.772368 0.343509 -0.0528327
+v -0.77224 0.268467 -0.0665772
+v -0.759343 0.268762 -0.0730127
+v -0.262397 -0.971901 0.505013
+v -0.275153 -0.971361 0.501814
+v -0.420266 -0.914071 -0.130226
+v -0.432765 -0.914637 -0.128774
+v -0.420227 -0.895908 -0.126655
+v -0.458725 -0.788984 -0.0698913
+v -0.471544 -0.789819 -0.0618501
+v -0.458802 -0.770705 -0.0683241
+v -0.0757423 -0.919428 -0.106513
+v -0.0896666 -0.921046 -0.107836
+v -0.457993 -0.454544 0.563228
+v -0.457954 -0.435892 0.569509
+v -0.45798 -0.417485 0.574365
+v -0.458018 -0.399078 0.581288
+v -0.45807 -0.380247 0.588931
+v -0.458198 -0.361929 0.594108
+v -0.458018 -0.343933 0.596484
+v -0.458006 -0.325346 0.602534
+v -0.458031 -0.30726 0.604705
+v -0.458006 -0.289417 0.602611
+v -0.458006 -0.271575 0.59922
+v -0.458044 -0.253913 0.593967
+v -0.458031 -0.236135 0.586966
+v -0.458031 -0.21819 0.584063
+v -0.458018 -0.200143 0.583292
+v -0.45789 -0.182326 0.580839
+v -0.457928 -0.164458 0.576279
+v -0.457967 -0.146693 0.571269
+v -0.458044 -0.1288 0.563896
+v -0.458044 -0.111138 0.555777
+v -0.458044 -0.0935138 0.548969
+v -0.45807 -0.0758129 0.54229
+v -0.457916 -0.0575598 0.536779
+v -0.457954 -0.0396663 0.530254
+v -0.458018 -0.0221196 0.51877
+v -0.458044 -0.00457293 0.505707
+v -0.458018 0.0128196 0.494004
+v -0.458121 0.0304434 0.481069
+v -0.457941 0.0481056 0.468314
+v 0.812613 -0.432925 0.124946
+v 0.811187 -0.414993 0.124869
+v 0.261357 -0.618591 0.74486
+v 0.274138 -0.494133 0.7403
+v -0.228486 -0.729099 -0.11196
+v -0.228576 -0.710679 -0.113591
+v -0.215653 -0.729073 -0.111985
+v 0.364158 -0.1074 0.628893
+v 0.376759 -0.107451 0.628649
+v 0.246431 0.157021 0.46956
+v 0.415025 -0.160862 0.632567
+v 0.24855 -0.600415 0.74856
+v 0.415411 0.0141812 0.524461
+v -0.289527 0.505732 0.0374184
+v -0.325827 0.484255 0.0244574
+v 0.415449 -0.00332693 0.533016
+v 0.415346 -0.0731154 0.592592
+v 0.415128 -0.0905593 0.609715
+v 0.415346 -0.0561982 0.576124
+v 0.415359 -0.039024 0.559772
+v 0.479483 -0.179333 0.624718
+v 0.479342 -0.16162 0.62107
+v 0.479406 -0.00470138 0.518976
+v 0.492521 -0.00452154 0.513298
+v 0.479855 0.0134747 0.504062
+v 0.235718 -0.692773 0.715522
+v 0.223206 -0.710191 0.719915
+v 0.772279 -0.128877 0.150277
+v 0.771816 -0.129082 0.163071
+v 0.777789 -0.146436 0.163135
+v 0.748797 -0.868175 0.0131407
+v 0.752368 -0.871926 0.0229417
+v 0.732831 -0.88946 0.0246116
+v 0.428115 -0.0564165 0.57439
+v 0.440729 -0.0739118 0.588636
+v -0.132326 0.745978 -0.210612
+v -0.127123 -0.919852 0.443021
+v -0.134548 -0.917822 0.462675
+v -0.139905 -0.919389 0.439951
+v 0.22268 -0.847083 0.611346
+v 0.209911 -0.828188 0.623973
+v 0.947912 -0.761328 0.137792
+v 0.957662 -0.742677 0.137637
+v 0.949595 -0.761225 0.150611
+v 0.261447 -0.368776 0.748521
+v 0.248627 -0.368557 0.751835
+v 0.248781 -0.386592 0.749086
+v 0.261447 -0.350587 0.753235
+v 0.235602 -0.582598 0.747648
+v 0.222782 -0.582714 0.746813
+v -0.578225 0.579773 -0.360311
+v -0.577595 0.801264 -0.694288
+v -0.581153 0.821046 -0.694751
+v -0.580126 0.801213 -0.681571
+v -0.400767 0.33602 0.207207
+v -0.40692 0.34595 0.217497
+v -0.579766 0.78111 -0.668649
+v -0.592881 -0.843422 0.413798
+v -0.584789 -0.844668 0.401107
+v -0.090296 -0.0734237 -0.278306
+v -0.0775535 -0.0550293 -0.269456
+v -0.0774764 -0.0734366 -0.278114
+v 0.771534 -0.274221 -0.0419271
+v 0.767179 -0.274504 -0.0549779
+v 0.768374 -0.255878 -0.0416958
+v -0.298043 0.505167 0.0508288
+v -0.125672 -0.819453 -0.328146
+v -0.138543 -0.81962 -0.326617
+v -0.125043 -0.80242 -0.312667
+v 0.325493 0.104047 0.500055
+v 0.364081 -0.0214003 0.537704
+v 0.364286 -0.0396021 0.559207
+v 0.261357 -0.29706 0.751566
+v 0.248524 -0.279565 0.744257
+v 0.261408 -0.26225 0.734905
+v 0.261241 -0.244806 0.729523
+v 0.717391 -0.059281 0.0218113
+v 0.724712 -0.0726915 0.0127425
+v -0.458262 -0.833904 0.579939
+v -0.468128 -0.831335 0.57773
+v 0.505597 -0.0532181 0.530318
+v 0.505225 -0.0403599 0.527569
+v 0.492572 -0.039769 0.531423
+v -0.445379 -0.833352 0.57737
+v -0.445212 -0.81691 0.556561
+v 0.376733 0.121028 0.476907
+v -0.432302 -0.801842 0.529984
+v -0.433073 -0.784424 0.499001
+v -0.63423 0.793724 -0.539721
+v -0.640678 0.793159 -0.523394
+v -0.646986 0.792786 -0.506978
+v -0.653498 0.791502 -0.491012
+v -0.885137 -0.0141941 0.281132
+v -0.958111 0.444306 0.304318
+v -0.958535 0.444229 0.291498
+v -0.0136867 0.224561 0.265165
+v 0.49351 0.132178 0.429983
+v 0.49202 0.118459 0.443355
+v 0.502527 0.118254 0.435815
+v -0.960937 0.461943 0.304241
+v -0.960282 0.461917 0.29146
+v -0.430606 -0.589445 0.468905
+v -0.30805 -0.973828 0.406579
+v -0.315744 -0.972492 0.426515
+v -0.320754 -0.973275 0.403407
+v -0.822645 0.0972004 -0.0296341
+v -0.835221 0.096982 -0.0223123
+v -0.593947 0.849151 -0.76847
+v -0.609426 0.837642 -0.766659
+v -0.621089 0.852555 -0.761855
+v -0.898304 0.176687 -0.00263329
+v -0.885754 0.17625 -0.0152088
+v -0.887116 0.158858 -0.0149519
+v 0.205274 -0.0543099 -0.26189
+v 0.214908 -0.0407196 -0.254119
+v 0.218043 -0.0545283 -0.258357
+v -0.420343 -0.932273 -0.133887
+v -0.431197 -0.920096 -0.129827
+v 0.00633915 0.640197 -0.111844
+v 0.00329482 0.639105 -0.106462
+v 0.359225 -0.0186899 -0.227721
+v 0.3462 -0.000205525 -0.229045
+v 0.366663 0.00240207 -0.223033
+v 0.524262 -0.618848 -0.296714
+v 0.513883 -0.612862 -0.303226
+v 0.515732 -0.600132 -0.300837
+v -0.0379129 -0.921252 -0.0258062
+v -0.0280477 -0.919312 -0.049403
+v -0.311505 0.610473 -0.112512
+v -0.311749 0.629715 -0.119243
+v -0.298377 0.61091 -0.118357
+v -0.445045 -0.453683 0.567184
+v -0.445109 -0.435661 0.572862
+v -0.445173 -0.417357 0.578051
+v -0.445173 -0.398834 0.58247
+v -0.445109 -0.38103 0.585694
+v -0.445147 -0.362648 0.58843
+v -0.445147 -0.3441 0.594904
+v -0.445186 -0.325359 0.602791
+v -0.445173 -0.307131 0.605656
+v -0.44516 -0.289276 0.604333
+v -0.445173 -0.271473 0.600839
+v -0.445199 -0.253926 0.593954
+v -0.445186 -0.236161 0.586876
+v -0.445186 -0.218139 0.585245
+v -0.44516 -0.199937 0.586362
+v -0.445135 -0.181928 0.584731
+v -0.445135 -0.16406 0.581417
+v -0.445045 -0.146424 0.576099
+v -0.445212 -0.128414 0.567531
+v -0.445173 -0.110726 0.558025
+v -0.445186 -0.0933082 0.549381
+v -0.445083 -0.0754404 0.540235
+v -0.445327 -0.0580993 0.534197
+v -0.445109 -0.0397819 0.525822
+v -0.445186 -0.022171 0.515739
+v -0.445199 -0.00476561 0.505604
+v -0.445224 0.0130894 0.494364
+v -0.445199 0.0304819 0.481133
+v -0.445109 0.0482983 0.466965
+v -0.450619 -0.781572 0.474351
+v 0.0203405 0.723357 -0.236893
+v 0.145415 -0.474146 0.770846
+v 0.261472 -0.600556 0.74716
+v -0.287099 0.520671 0.0556844
+v 0.325442 -0.884643 0.601841
+v 0.339405 -0.879055 0.600184
+v 0.325352 -0.866569 0.59967
+v 0.355821 0.0979069 0.494249
+v 0.360368 0.0806042 0.500902
+v 0.415423 -0.0211947 0.542457
+v 0.762169 -0.683164 0.428635
+v -0.614757 0.519746 -0.401017
+v -0.606754 0.53412 -0.410677
+v -0.600601 0.536587 -0.397074
+v -0.360458 0.495636 -0.029891
+v -0.357838 0.479515 -0.0135903
+v 0.235499 0.0692875 0.540081
+v 0.235538 0.0870911 0.530626
+v 0.479663 -0.0219012 0.528006
+v 0.492508 -0.0221196 0.524692
+v 0.222782 -0.692092 0.721302
+v 0.248447 -0.262301 0.737346
+v 0.274151 -0.476072 0.743961
+v 0.248499 -0.126154 0.61398
+v 0.248563 -0.10966 0.590575
+v 0.235602 -0.109647 0.588995
+v 0.338197 -0.177419 0.662753
+v 0.325198 -0.177214 0.668765
+v 0.273958 0.0158896 0.555071
+v 0.286726 0.015697 0.55159
+v 0.325583 -0.422816 0.738849
+v 0.235499 0.0163392 0.564499
+v 0.235525 0.0341428 0.558244
+v 0.364055 0.0141555 0.524217
+v 0.35121 0.0324729 0.523086
+v -0.458044 0.613209 0.141337
+v -0.44516 0.612721 0.142326
+v 0.805843 -0.433503 0.0736935
+v -0.445122 0.594455 0.154259
+v -0.468307 0.6217 0.131985
+v 0.805766 -0.415494 0.0736678
+v -0.697313 0.416342 -0.105216
+v -0.687564 0.416059 -0.115042
+v -0.364106 0.463869 0.0792683
+v -0.382154 0.448095 0.056211
+v -0.580177 0.580081 -0.206103
+v -0.580704 0.579991 -0.193322
+v 0.347382 -0.413567 0.728662
+v 0.698585 -0.702137 0.423471
+v 0.69829 -0.720146 0.423509
+v -0.433098 -0.850885 0.586632
+v -0.432495 -0.83375 0.571063
+v -0.445546 -0.850333 0.591577
+v -0.432328 -0.817038 0.551911
+v 0.973449 -0.583241 0.301209
+v 0.980026 -0.583767 0.288043
+v 0.971805 -0.566272 0.298743
+v 0.376708 -0.124895 0.634956
+v 0.364055 -0.124702 0.635521
+v -0.703119 -0.170547 0.54721
+v -0.431827 -0.769305 0.48604
+v -0.445314 -0.785079 0.503292
+v -0.716517 0.419977 -0.0948368
+v -0.70705 0.421518 -0.106911
+v -0.625906 0.5078 0.507531
+v -0.624583 0.489894 0.518359
+v -0.612457 0.489804 0.511975
+v 0.0107708 0.237689 0.217137
+v -0.047367 0.195775 0.309289
+v -0.0354209 0.206514 0.294453
+v -0.0243226 0.216122 0.279527
+v -0.232648 0.536034 -0.0245474
+v -0.240483 0.534763 -0.0358512
+v -0.218158 0.544833 -0.0431217
+v -0.77278 0.3813 -0.0534107
+v -0.773075 0.400157 -0.0503022
+v -0.760024 0.400311 -0.0569175
+v -0.855927 0.0521134 0.0096982
+v -0.847603 0.0586516 -0.00111754
+v -0.460176 -0.583613 -0.111279
+v -0.125544 -0.890012 -0.357292
+v -0.125595 -0.871913 -0.355635
+v -0.213662 -0.594789 -0.179847
+v -0.216385 -0.596137 -0.169044
+v -0.229256 -0.577859 -0.170688
+v -0.433728 -0.940931 -0.134054
+v -0.444955 -0.920777 -0.129044
+v -0.449117 -0.26076 -0.262892
+v -0.449168 -0.242172 -0.26356
+v -0.436233 -0.242352 -0.261158
+v -0.423721 -0.00219655 -0.218884
+v -0.410722 -0.00251768 -0.217882
+v -0.411595 -0.0219012 -0.224985
+v -0.299045 0.629702 -0.124497
+v -0.299173 0.649034 -0.130971
+v -0.285686 0.630255 -0.131484
+v -0.432315 -0.473079 0.556677
+v -0.432315 -0.454235 0.568289
+v -0.323965 -0.972196 0.447093
+v -0.336707 -0.971657 0.443895
+v -0.328512 -0.971952 0.423291
+v -0.432366 -0.435777 0.575187
+v -0.432353 -0.417215 0.581802
+v -0.432353 -0.398885 0.584923
+v -0.432456 -0.380683 0.58572
+v -0.432315 -0.362751 0.586709
+v -0.432328 -0.344036 0.594724
+v -0.432328 -0.325384 0.602856
+v -0.432315 -0.307272 0.605129
+v -0.432315 -0.28925 0.60459
+v -0.432341 -0.27146 0.600993
+v -0.432328 -0.253797 0.593427
+v -0.432353 -0.236045 0.587981
+v -0.432366 -0.217908 0.588623
+v -0.432225 -0.199526 0.591821
+v -0.432302 -0.181581 0.589715
+v -0.432302 -0.163739 0.585013
+v -0.432328 -0.146 0.578642
+v -0.432366 -0.128273 0.570588
+v -0.432353 -0.110701 0.560903
+v -0.432341 -0.0934367 0.549175
+v -0.432341 -0.0756973 0.538282
+v -0.432353 -0.0580351 0.52861
+v -0.432392 -0.039692 0.521648
+v -0.432366 -0.0225692 0.515135
+v -0.432379 -0.00468853 0.50712
+v -0.432353 0.0128453 0.495546
+v -0.432341 0.0300708 0.480633
+v -0.432032 0.0485295 0.465886
+v -0.41947 0.0654083 0.453156
+v -0.421024 0.0698142 0.44938
+v -0.432238 0.0656266 0.453529
+v -0.663659 0.409919 -0.1065
+v 0.286726 0.0512014 0.540016
+v 0.415256 -0.142853 0.628379
+v 0.202281 -0.0797179 0.587159
+v 0.200727 -0.0971105 0.585913
+v 0.251916 -0.132808 0.631077
+v -0.60755 0.462418 -0.198511
+v 0.235705 -0.279437 0.744693
+v 0.235666 -0.296803 0.751039
+v 0.248499 -0.296983 0.751745
+v 0.235692 -0.262031 0.739427
+v -0.619805 0.417151 -0.100168
+v -0.600858 0.430317 -0.102814
+v 0.184195 -0.00160566 0.570768
+v 0.793178 -0.21801 0.214439
+v 0.698046 -0.738001 0.425732
+v 0.184324 0.0872324 0.532271
+v 0.145826 0.174593 0.460453
+v 0.274305 -0.3148 0.753544
+v 0.261408 -0.314658 0.755021
+v 0.69793 -0.774212 0.428776
+v 0.697956 -0.755959 0.42744
+v 0.171388 -0.208839 0.73249
+v 0.132917 -0.0190624 0.579554
+v 0.132994 0.0511757 0.544628
+v 0.80127 -0.72048 0.435635
+v 0.800898 -0.700839 0.435032
+v 0.800153 -0.739825 0.432591
+v 0.800872 -0.682869 0.432347
+v 0.800795 -0.664975 0.429996
+v 0.800782 -0.647467 0.423432
+v 0.347305 0.0805143 0.504512
+v 0.351248 0.0683755 0.510292
+v 0.363721 0.0676562 0.507556
+v 0.274292 -0.368994 0.745567
+v 0.351081 0.050238 0.51782
+v 0.364183 0.0503793 0.513799
+v -0.432302 0.575649 0.157419
+v -0.432353 0.594198 0.150662
+v 0.491545 -0.967148 0.00264613
+v 0.486779 -0.954868 -0.0019011
+v 0.504762 -0.941792 -0.00851643
+v -0.432315 0.612862 0.140951
+v -0.399508 0.105203 0.412501
+v -0.380844 0.100386 0.411281
+v -0.380587 0.118061 0.392013
+v 0.619856 -0.921509 0.00513812
+v 0.803865 -0.451654 0.0610023
+v -0.420382 0.325551 0.0508288
+v -0.425751 0.32541 0.0379964
+v -0.427459 0.345217 0.0507646
+v 0.800744 -0.629972 0.414004
+v 0.697917 -0.792825 0.427158
+v 0.273778 -0.00193964 0.559413
+v 0.9958 -0.560774 0.214504
+v 0.994181 -0.56089 0.227413
+v -0.674924 -0.380362 0.543947
+v -0.6824 -0.3985 0.53159
+v -0.669246 -0.398333 0.538835
+v -0.419534 -0.850474 0.58274
+v -0.419752 -0.834533 0.567351
+v -0.439662 -0.863011 0.597024
+v -0.427331 -0.862767 0.592181
+v -0.419534 -0.81786 0.548224
+v -0.419495 -0.801341 0.527299
+v -0.267741 -0.577961 -0.164677
+v -0.254921 -0.578334 -0.16573
+v -0.419611 -0.784976 0.504795
+v -0.419701 -0.768046 0.490215
+v 0.0183624 0.240682 0.201132
+v -0.418275 -0.751797 0.47728
+v -0.405751 -0.732824 0.482457
+v -0.411865 -0.731604 0.474377
+v -0.161266 0.19837 0.117213
+v -0.166687 0.200066 0.133925
+v -0.14792 0.198241 0.122082
+v -0.65256 0.518295 -0.501635
+v -0.643003 0.531641 -0.513722
+v -0.637172 0.534454 -0.500029
+v -0.716093 0.582136 0.361223
+v -0.729285 0.582213 0.356598
+v -0.77513 0.541095 0.456509
+v -0.720512 0.590254 0.303303
+v -0.706395 0.591012 0.308184
+v -0.624789 0.467556 -0.261736
+v -0.607011 0.481776 -0.262789
+v -0.973629 0.163161 0.4343
+v -0.973397 0.163058 0.421467
+v -0.623504 0.772979 -0.517203
+v -0.423028 -0.608546 0.463587
+v -0.00996153 -0.919621 0.397678
+v -0.0180027 -0.918644 0.418269
+v -0.0227554 -0.919171 0.394659
+v 0.190374 -0.91849 0.321903
+v 0.176938 -0.919094 0.319655
+v 0.185017 -0.920109 0.299026
+v -0.419161 -0.588957 0.477845
+v -0.472444 -0.583844 -0.104021
+v -0.572457 -0.876062 -0.0669368
+v -0.586805 -0.884206 -0.0673351
+v -0.587216 -0.879299 -0.0636356
+v -0.512238 -0.485116 -0.19548
+v -0.525032 -0.485064 -0.195326
+v -0.512393 -0.46658 -0.206
+v -0.449964 0.438256 0.0166604
+v -0.439868 0.453478 0.00809254
+v -0.437671 0.437601 0.0249199
+v -0.14151 -0.165139 -0.288428
+v -0.141574 -0.146912 -0.285268
+v -0.128652 -0.146783 -0.288261
+v 0.510581 -0.632798 -0.308827
+v -0.229513 -0.539156 -0.196777
+v -0.221459 -0.540273 -0.20618
+v -0.128703 -0.128492 -0.285024
+v -0.419508 -0.454736 0.567467
+v -0.719587 -0.95894 0.102634
+v -0.71626 -0.945003 0.0951451
+v -0.71292 -0.962421 0.0841239
+v -0.419495 -0.435533 0.576497
+v -0.419482 -0.41701 0.583228
+v -0.419521 -0.398641 0.585951
+v -0.419431 -0.380966 0.585437
+v -0.419457 -0.362764 0.586812
+v -0.419418 -0.344331 0.593671
+v -0.419585 -0.325204 0.601905
+v -0.419547 -0.307118 0.605489
+v -0.419521 -0.289289 0.60423
+v -0.419457 -0.271421 0.599888
+v -0.419495 -0.253836 0.593273
+v -0.419418 -0.236071 0.587595
+v -0.419482 -0.217728 0.591385
+v -0.419482 -0.199359 0.59448
+v -0.419495 -0.181504 0.591128
+v -0.41947 -0.163585 0.585463
+v -0.41947 -0.145807 0.579079
+v -0.41947 -0.128273 0.57204
+v -0.419482 -0.110855 0.562046
+v -0.419495 -0.0933725 0.547826
+v -0.419495 -0.0758772 0.536484
+v -0.419495 -0.0582534 0.529599
+v -0.419611 -0.039936 0.524127
+v -0.419521 -0.0223637 0.518385
+v -0.419547 -0.00440594 0.509008
+v -0.419521 0.0130251 0.49579
+v -0.419508 0.0309572 0.478539
+v -0.41947 0.0480414 0.46649
+v 0.78664 -0.453131 0.0094156
+v 0.79084 -0.452655 0.022505
+v -0.0340978 0.154709 0.409046
+v -0.0340465 0.137535 0.436663
+v 0.466702 0.0131664 0.50798
+v 0.466907 -0.00400773 0.521468
+v 0.235538 0.0517922 0.548725
+v 0.376875 -0.246553 0.701893
+v 0.988272 -0.650486 0.124638
+v 0.991471 -0.650178 0.137458
+v 0.985421 -0.668585 0.137458
+v 0.71021 -0.841829 0.40613
+v 0.698033 -0.831001 0.413965
+v 0.695733 -0.844219 0.405154
+v 0.235422 -0.0196405 0.567801
+v 0.800628 -0.612605 0.402816
+v 0.710801 -0.81181 0.424242
+v 0.800525 -0.595457 0.389996
+v 0.80068 -0.578539 0.378178
+v 0.710904 -0.830551 0.415096
+v 0.697891 -0.811926 0.422687
+v 0.80041 -0.561262 0.362404
+v -0.580652 0.726491 -0.758926
+v -0.595527 0.726748 -0.758579
+v 0.351505 -0.107605 0.627313
+v 0.351621 -0.0908805 0.614172
+v 0.184375 0.0693389 0.543099
+v 0.171465 0.051895 0.550293
+v -0.827873 -0.470806 0.232102
+v -0.821951 -0.488905 0.219411
+v 0.49351 0.0316765 0.492013
+v 0.480832 0.0312526 0.496458
+v -0.419572 0.557871 0.158318
+v -0.419418 0.575534 0.152576
+v -0.431197 0.557756 0.163906
+v -0.419341 0.594352 0.146346
+v -0.419393 0.61299 0.138151
+v -0.41947 0.631989 0.128158
+v -0.406663 0.650422 0.115929
+v 0.446381 -0.965016 -0.129943
+v 0.452225 -0.958645 -0.117342
+v 0.801283 -0.289777 0.201697
+v 0.79978 -0.271768 0.201697
+v -0.434756 0.345025 0.0379322
+v -0.432842 0.364922 0.0506875
+v -0.202012 -0.969075 0.35629
+v 0.788207 -0.182236 0.163084
+v -0.556221 -0.904386 0.261158
+v -0.552316 -0.920391 0.276469
+v 0.119648 -0.844848 0.638257
+v 0.119468 -0.862215 0.645887
+v 0.325468 -0.245898 0.714019
+v 0.756081 -0.093578 0.16311
+v 0.234549 0.164073 0.466169
+v 0.413188 -0.428815 0.711591
+v 0.426098 -0.428442 0.707506
+v 0.414447 -0.411358 0.713235
+v 0.607178 -0.921894 0.00120746
+v -0.406907 -0.851309 0.578796
+v -0.406714 -0.834199 0.564731
+v -0.406637 -0.817796 0.545309
+v -0.406586 -0.801457 0.527197
+v -0.40674 -0.784514 0.509689
+v -0.406778 -0.767404 0.498269
+v -0.406303 -0.750217 0.48947
+v -0.12986 -0.758155 0.557499
+v -0.110592 -0.744167 0.537897
+v -0.118813 -0.743422 0.5278
+v -0.347574 0.492373 -0.0260631
+v -0.336399 0.490652 -0.0196148
+v -0.959486 0.479489 0.304087
+v -0.960321 0.479579 0.291357
+v -0.151581 0.57579 -0.0647531
+v -0.138543 0.585437 -0.0812979
+v -0.12923 0.584975 -0.0725888
+v -0.966641 0.215634 0.421249
+v -0.966011 0.215595 0.43403
+v -0.964598 0.233116 0.421082
+v -0.685547 0.749908 -0.3004
+v -0.674346 0.745002 -0.296354
+v -0.140662 -0.391615 -0.447081
+v -0.127702 -0.39087 -0.454801
+v -0.128036 -0.409431 -0.450741
+v -0.419572 -0.474004 0.554429
+v -0.140675 -0.373567 -0.447042
+v -0.406599 -0.455109 0.564589
+v -0.406689 -0.473696 0.554005
+v -0.406663 -0.435674 0.574891
+v -0.406586 -0.417215 0.581841
+v -0.406509 -0.399129 0.583999
+v -0.40665 -0.38085 0.584885
+v -0.40665 -0.362687 0.586401
+v -0.40656 -0.344447 0.59195
+v -0.406663 -0.325641 0.599464
+v -0.406611 -0.307388 0.603074
+v -0.406727 -0.28943 0.602586
+v -0.40665 -0.271627 0.598039
+v -0.406611 -0.253939 0.591757
+v -0.406342 -0.236212 0.585309
+v -0.406509 -0.21801 0.587762
+v -0.406689 -0.199449 0.592849
+v -0.406522 -0.181414 0.590691
+v -0.406637 -0.163752 0.584962
+v -0.406624 -0.145935 0.578706
+v -0.40665 -0.128402 0.570383
+v -0.40665 -0.111073 0.558719
+v -0.406701 -0.0933982 0.546336
+v -0.406701 -0.075723 0.539682
+v -0.406676 -0.0578681 0.534608
+v -0.406611 -0.0400645 0.529509
+v -0.40674 -0.0219655 0.52202
+v -0.406689 -0.00431602 0.510613
+v -0.406676 0.0132692 0.496034
+v -0.406714 0.0310599 0.478641
+v -0.406624 0.0483112 0.465218
+v -0.40656 0.0658193 0.449033
+v -0.406367 0.083199 0.431217
+v -0.419264 0.0830705 0.43579
+v -0.610312 0.416599 -0.0913686
+v 0.403619 -0.190586 0.653338
+v -0.543144 0.0673864 0.497537
+v -0.555566 0.0670396 0.502238
+v -0.952511 0.497139 0.30401
+v -0.955619 0.49719 0.29119
+v 0.466753 0.0310342 0.500003
+v 0.492071 -0.161889 0.617923
+v -0.337337 0.505437 -0.0382405
+v -0.325301 0.502855 -0.0332179
+v 0.748296 -0.0757359 0.163122
+v 0.235538 0.104728 0.519284
+v -0.573729 0.74075 -0.694044
+v -0.574063 0.760878 -0.694327
+v 0.443722 -0.241376 0.643485
+v 0.712548 -0.041349 0.0346695
+v 0.703929 -0.0239179 0.0348621
+v 0.343875 -0.379437 0.724115
+v 0.351338 -0.124895 0.635341
+v 0.784803 -0.164433 0.137406
+v 0.778997 -0.146488 0.137445
+v 0.222577 -0.883011 0.618064
+v 0.274369 -0.38726 0.739774
+v 0.145685 -0.33277 0.75163
+v 0.76276 -0.147554 0.0219012
+v -0.406611 0.594121 0.142775
+v -0.406676 0.612721 0.135929
+v -0.40647 0.632027 0.126719
+v 0.291299 -0.919081 -0.105511
+v 0.302385 -0.922691 -0.100013
+v -0.406586 0.669124 0.102621
+v 0.99061 -0.668174 0.18889
+v -0.940796 0.514595 0.303804
+v -0.943982 0.514775 0.291074
+v -0.577839 0.6989 -0.721174
+v -0.58782 0.821264 -0.681661
+v -0.584455 0.800969 -0.668932
+v -0.414755 -0.862099 0.588032
+v -0.393843 -0.868432 0.58441
+v -0.393985 -0.851605 0.575444
+v -0.406663 -0.868034 0.587827
+v -0.393818 -0.834598 0.561365
+v -0.393805 -0.817809 0.543844
+v -0.393792 -0.801046 0.529098
+v -0.393997 -0.783884 0.514955
+v -0.393946 -0.766749 0.504884
+v -0.393586 -0.749176 0.499335
+v -0.394267 -0.731206 0.4943
+v -0.393689 -0.713351 0.492129
+v -0.402103 -0.71371 0.482302
+v 0.722298 -0.0288891 0.109802
+v -0.657365 0.509021 -0.474441
+v -0.665136 0.507646 -0.485719
+v -0.594602 0.4464 -0.110251
+v 0.0903089 0.725901 -0.247105
+v 0.0923898 0.725271 -0.234118
+v 0.0768085 0.718771 -0.249636
+v -0.682413 0.74084 -0.280837
+v 0.279867 0.272115 0.259308
+v -0.708129 0.363304 -0.0741045
+v 0.29979 0.272474 0.248184
+v -0.393818 -0.492142 0.547171
+v -0.393933 -0.473786 0.55439
+v -0.0270072 0.692207 -0.197548
+v -0.0245409 0.67556 -0.181992
+v -0.393805 -0.455032 0.562573
+v -0.393792 -0.436162 0.57037
+v -0.393805 -0.417536 0.576484
+v -0.394074 -0.398975 0.580518
+v -0.39374 -0.381146 0.581802
+v -0.393625 -0.363098 0.583806
+v -0.393805 -0.344434 0.589818
+v -0.39383 -0.325744 0.597743
+v -0.393792 -0.307619 0.599618
+v -0.393997 -0.289713 0.59904
+v -0.393792 -0.271896 0.594699
+v -0.393933 -0.254324 0.587749
+v -0.393561 -0.236443 0.582611
+v -0.393638 -0.218396 0.582444
+v -0.393509 -0.200155 0.585758
+v -0.393394 -0.181774 0.584859
+v -0.393869 -0.164189 0.580068
+v -0.393818 -0.146244 0.573812
+v -0.393792 -0.128684 0.565566
+v -0.393792 -0.111459 0.556497
+v -0.393818 -0.0933853 0.549316
+v -0.393818 -0.0755175 0.544319
+v -0.393792 -0.0576754 0.539271
+v -0.393818 -0.0397562 0.533028
+v -0.393818 -0.0218884 0.5236
+v -0.39383 -0.0043674 0.512001
+v -0.393805 0.0128967 0.497126
+v -0.393805 0.0306489 0.479682
+v -0.393869 0.047913 0.464756
+v -0.39374 0.0659991 0.446079
+v -0.393753 0.082621 0.430459
+v -0.591943 0.499477 -0.218922
+v 0.659291 -0.299462 -0.210419
+v 0.643967 -0.314851 -0.221106
+v 0.648566 -0.294453 -0.216289
+v -0.959627 0.46175 0.265744
+v -0.958548 0.461673 0.25286
+v 0.248563 -0.0922421 0.581712
+v 0.235653 -0.314504 0.756832
+v -0.307009 -0.465038 -0.212307
+v -0.307048 -0.446541 -0.21557
+v -0.294241 -0.446528 -0.213604
+v 0.40936 -0.163328 -0.277831
+v 0.395757 -0.163251 -0.278114
+v 0.398223 -0.144933 -0.27539
+v -0.202487 -0.907585 -0.369097
+v -0.2025 -0.889627 -0.366566
+v -0.189731 -0.889473 -0.366913
+v 0.17144 -0.226129 0.739337
+v 0.0638861 -0.978593 -0.240271
+v 0.0579644 -0.973018 -0.222481
+v 0.0504628 -0.979146 -0.242429
+v 0.531699 -0.0012203 0.50053
+v 0.525341 0.0154015 0.491256
+v 0.518725 -0.00332693 0.505809
+v 0.684969 -0.812388 0.419836
+v 0.685085 -0.793184 0.423946
+v 0.453561 0.0131279 0.513876
+v 0.274241 -0.244883 0.72689
+v 0.235756 -0.368275 0.754777
+v 0.805753 -0.343458 0.214619
+v -0.934784 0.374312 0.433208
+v -0.398673 0.576574 0.143418
+v -0.392764 0.613376 0.131228
+v -0.393972 0.631501 0.124098
+v -0.393895 0.650434 0.114297
+v -0.599586 0.638373 -0.655817
+v -0.603967 0.628739 -0.664718
+v -0.395988 0.709767 0.0710345
+v -0.391287 0.697191 0.0835972
+v -0.429039 0.384845 0.0634301
+v 0.990225 -0.668058 0.201748
+v -0.630813 0.213463 -0.0939505
+v -0.415077 0.325615 0.0637127
+v -0.417877 0.424794 0.127554
+v -0.0422418 0.708161 -0.207503
+v -0.0423574 0.727288 -0.220554
+v -0.393997 -0.886056 0.590473
+v -0.410902 -0.879415 0.593517
+v -0.381062 -0.86874 0.582419
+v -0.381152 -0.851823 0.573645
+v -0.380959 -0.834739 0.558321
+v -0.380934 -0.817963 0.543639
+v -0.380959 -0.801033 0.529111
+v -0.381126 -0.783692 0.518089
+v -0.381255 -0.766209 0.5101
+v -0.381165 -0.748508 0.504987
+v -0.380908 -0.730692 0.502881
+v -0.372058 -0.731231 0.5078
+v -0.242115 -0.57827 -0.165769
+v 0.272519 0.269636 0.275044
+v -0.689889 0.737795 -0.265178
+v -0.781501 0.149327 0.688636
+v 0.339508 0.268171 0.134465
+v -0.380805 -0.491384 0.553144
+v -0.380908 -0.473195 0.556767
+v -0.380947 -0.454929 0.560209
+v -0.380934 -0.436676 0.563767
+v -0.381101 -0.417986 0.569342
+v -0.381435 -0.39954 0.573954
+v -0.381281 -0.381184 0.577152
+v -0.380972 -0.363175 0.579811
+v -0.380934 -0.344562 0.588148
+v -0.380998 -0.326193 0.593055
+v -0.380677 -0.308172 0.593671
+v -0.380869 -0.290098 0.593324
+v -0.381088 -0.27232 0.589522
+v -0.380651 -0.254607 0.580954
+v -0.380715 -0.236816 0.577563
+v -0.380792 -0.218614 0.578963
+v -0.380369 -0.200348 0.580248
+v -0.38033 -0.182159 0.578449
+v -0.380882 -0.164433 0.573915
+v -0.380908 -0.146629 0.568944
+v -0.380908 -0.128825 0.562508
+v -0.380959 -0.110791 0.558115
+v -0.380934 -0.0931413 0.553992
+v -0.380985 -0.0751835 0.549316
+v -0.380934 -0.0575084 0.542547
+v -0.380947 -0.0397819 0.534429
+v -0.380947 -0.0221196 0.524692
+v -0.380985 -0.0042261 0.512168
+v -0.380998 0.0136032 0.496317
+v -0.380985 0.0309572 0.478462
+v -0.380947 0.0475019 0.462778
+v -0.380972 0.0653697 0.446939
+v -0.380921 0.0830448 0.429303
+v -0.487421 0.482855 0.371537
+v -0.482938 0.48297 0.358975
+v -0.479945 0.502868 0.358705
+v 0.0789922 0.913378 -0.348519
+v 0.0824989 0.897103 -0.359514
+v 0.0706556 0.914842 -0.356226
+v -0.182217 0.559721 -0.0258062
+v -0.188871 0.556985 -0.0379193
+v -0.165852 0.566593 -0.0463587
+v 0.453625 -0.0738733 0.584089
+v 0.440947 -0.0563138 0.571385
+v -0.308332 0.545257 -0.073154
+v -0.298056 0.558334 -0.0851643
+v -0.294626 0.541288 -0.0704436
+v 0.685098 -0.831502 0.411114
+v 0.0843358 0.775728 -0.316534
+v 0.0848496 0.760031 -0.300426
+v -0.189667 -0.907585 -0.369701
+v -0.496503 0.487852 0.387581
+v -0.486471 0.463137 0.384755
+v -0.946409 0.496484 0.188723
+v -0.941734 0.496394 0.176045
+v -0.943519 0.478937 0.175916
+v -0.621423 0.438898 -0.161144
+v -0.657943 0.560941 -0.621122
+v 0.184157 -0.0192936 0.576112
+v 0.120123 -0.0731797 0.582277
+v 0.118723 -0.0832504 0.58044
+v 0.184426 0.0516124 0.552592
+v 0.26146 -0.565167 0.742638
+v 0.454113 0.0673479 0.489342
+v 0.441063 0.0849588 0.483677
+v -0.0489727 -0.912633 0.498744
+v 0.975735 -0.687146 0.124754
+v 0.982196 -0.668431 0.124766
+v 0.978908 -0.686825 0.137573
+v -0.380882 0.631719 0.119872
+v -0.381088 0.650486 0.111099
+v -0.381024 0.669266 0.102595
+v -0.380959 0.688688 0.0897758
+v -0.412983 0.306078 0.0507646
+v -0.408821 0.306463 0.0634429
+v -0.411403 0.325744 0.0765194
+v -0.403901 0.306206 0.0764937
+v -0.899742 -0.326694 0.205679
+v -0.900038 -0.326849 0.192859
+v -0.932832 0.496278 0.163405
+v -0.937405 0.478924 0.163315
+v -0.852253 -0.432797 0.229918
+v -0.848618 -0.434839 0.244857
+v -0.380908 -0.88612 0.588096
+v -0.368127 -0.868702 0.58125
+v -0.368165 -0.851528 0.572759
+v -0.368114 -0.834585 0.559875
+v -0.36814 -0.817796 0.543844
+v -0.368178 -0.800891 0.529355
+v -0.36805 -0.783653 0.520748
+v -0.368332 -0.765811 0.514917
+v -0.296103 -0.00296726 -0.223367
+v -0.313727 0.000423895 -0.219488
+v -0.368243 -0.747956 0.51132
+v -0.698739 0.732323 -0.24988
+v -0.367793 -0.546991 0.535032
+v -0.368011 -0.528378 0.543574
+v -0.380998 -0.529046 0.53737
+v -0.0415353 -0.914662 0.479027
+v -0.0549072 -0.915253 0.476856
+v -0.0468532 -0.916229 0.456316
+v -0.808631 0.0405398 -0.0126398
+v -0.796441 0.0330253 -0.0166732
+v 0.641706 -0.392873 -0.220605
+v 0.630544 -0.387093 -0.229533
+v 0.643299 -0.369315 -0.223046
+v -0.442206 -0.95149 0.614429
+v -0.44227 -0.957052 0.609137
+v -0.427113 -0.953866 0.61037
+v -0.367921 -0.509419 0.553016
+v -0.368024 -0.491063 0.558218
+v 0.652766 -0.392257 -0.209121
+v 0.662695 -0.372886 -0.207477
+v -0.368101 -0.472964 0.560171
+v -0.36805 -0.454762 0.561365
+v -0.368101 -0.436727 0.561609
+v -0.368101 -0.418757 0.561943
+v -0.367973 -0.400671 0.564243
+v -0.368127 -0.382006 0.567916
+v -0.368088 -0.363843 0.573388
+v -0.368191 -0.34496 0.581211
+v -0.367626 -0.32699 0.586131
+v -0.367909 -0.308647 0.58694
+v -0.367909 -0.290586 0.586992
+v -0.368345 -0.272847 0.58274
+v -0.367575 -0.255056 0.575084
+v -0.367793 -0.237034 0.574493
+v -0.367947 -0.218743 0.577268
+v -0.368076 -0.200592 0.576959
+v -0.367909 -0.18257 0.574326
+v -0.368165 -0.164677 0.571693
+v -0.368024 -0.146642 0.567634
+v -0.367986 -0.128633 0.563305
+v -0.368114 -0.110791 0.559631
+v -0.36814 -0.0927687 0.55651
+v -0.368178 -0.0748624 0.551693
+v -0.368114 -0.0572772 0.544435
+v -0.368127 -0.0394608 0.535007
+v -0.368114 -0.022004 0.524859
+v -0.368101 -0.00431602 0.512078
+v -0.368101 0.0133591 0.496098
+v -0.368127 0.0308801 0.478385
+v -0.36814 0.0480157 0.46333
+v -0.368165 0.065344 0.448481
+v -0.368153 0.0830705 0.430857
+v -0.368153 0.100502 0.412874
+v -0.380792 0.135081 0.376701
+v 0.577737 -0.839427 0.470575
+v 0.563645 -0.857758 0.472694
+v 0.570492 -0.858246 0.460196
+v 0.428179 -0.0389341 0.556779
+v 0.668964 -0.84576 0.401159
+v 0.682361 -0.845079 0.403252
+v 0.24846 -0.618231 0.747571
+v 0.248486 -0.636896 0.740159
+v 0.33839 -0.0213232 0.537807
+v 0.261267 -0.636883 0.738232
+v 0.197156 0.104882 0.522508
+v 0.0237702 0.706735 -0.221787
+v 0.0119525 0.695521 -0.207053
+v -0.628668 0.54834 -0.510845
+v -0.127008 0.596882 -0.0958259
+v 0.685123 -0.77461 0.425847
+v 0.287214 -0.33295 0.750409
+v 0.28697 0.121812 0.491859
+v 0.499778 -0.15381 0.612348
+v 0.495514 -0.136892 0.606195
+v 0.492033 -0.144304 0.611526
+v 0.0468661 0.765631 -0.288056
+v 0.059904 0.765837 -0.296058
+v 0.466869 -0.0217214 0.52974
+v -0.370683 0.6138 0.11616
+v -0.368191 0.631488 0.113064
+v -0.380523 0.614044 0.124856
+v -0.368076 0.650614 0.106744
+v -0.368204 0.669497 0.0996795
+v -0.36814 0.688444 0.0910732
+v 0.961066 -0.706735 0.0988831
+v 0.968131 -0.688007 0.0989987
+v 0.965433 -0.706196 0.111793
+v -0.932472 0.513298 0.176327
+v -0.924906 0.513015 0.163919
+v 0.0220618 0.652837 -0.137817
+v -0.935247 0.461275 0.162955
+v 0.814424 -0.684757 0.431795
+v 0.428102 -0.0219911 0.539978
+v 0.337362 -0.44807 0.736858
+v 0.325725 -0.440504 0.74075
+v 0.248293 0.139346 0.486554
+v -0.367947 -0.886287 0.585476
+v -0.67671 0.432848 -0.173039
+v -0.659022 0.43954 -0.196392
+v -0.64949 0.439194 -0.187683
+v -0.355397 -0.869049 0.577781
+v -0.355359 -0.85172 0.571051
+v -0.355243 -0.834431 0.558732
+v -0.355282 -0.817642 0.545488
+v -0.35532 -0.80057 0.532643
+v -0.355384 -0.783126 0.524628
+v -0.355474 -0.765361 0.519772
+v -0.355217 -0.747404 0.51746
+v -0.342462 -0.728868 0.522598
+v -0.355667 -0.711334 0.518333
+v -0.355539 -0.729484 0.516561
+v -0.404826 0.460684 0.00466284
+v 0.476182 -0.0533851 0.555533
+v 0.479611 -0.0395892 0.539194
+v 0.46656 -0.0397048 0.54518
+v -0.919421 0.318897 0.074233
+v -0.329026 0.23408 0.0366348
+v -0.333753 0.237073 0.0536291
+v -0.315628 0.233553 0.041516
+v -0.589117 0.519657 -0.283123
+v -0.595925 0.507415 -0.297343
+v -0.378082 -0.552926 0.526734
+v -0.621706 0.517832 -0.413439
+v -0.61292 0.53168 -0.42428
+v -0.033918 -0.44175 0.722831
+v -0.0430125 -0.4464 0.715188
+v -0.0393516 -0.464537 0.712053
+v -0.355166 -0.527955 0.54843
+v -0.355115 -0.509008 0.557923
+v -0.355295 -0.490896 0.561969
+v -0.35514 -0.47245 0.564448
+v -0.355256 -0.454518 0.565065
+v -0.355217 -0.436496 0.564769
+v -0.355102 -0.418461 0.563665
+v -0.355269 -0.400722 0.561481
+v -0.355153 -0.382661 0.562097
+v -0.35523 -0.364408 0.565296
+v -0.35541 -0.345628 0.5729
+v -0.355089 -0.327311 0.577486
+v -0.355205 -0.309032 0.581789
+v -0.355038 -0.291074 0.580569
+v -0.354922 -0.273361 0.574442
+v -0.354794 -0.255429 0.570164
+v -0.355115 -0.237201 0.572464
+v -0.355307 -0.218987 0.573491
+v -0.354845 -0.201016 0.571449
+v -0.354883 -0.182814 0.570087
+v -0.35505 -0.164677 0.569689
+v -0.355217 -0.146732 0.567364
+v -0.355256 -0.128813 0.563986
+v -0.355166 -0.110726 0.559991
+v -0.355243 -0.0927559 0.556612
+v -0.35523 -0.0748367 0.553016
+v -0.355217 -0.0569946 0.545052
+v -0.355217 -0.0393837 0.535135
+v -0.355205 -0.0215929 0.523908
+v -0.355205 -0.00400773 0.51087
+v -0.355243 0.0130894 0.49579
+v -0.355269 0.0309957 0.478552
+v -0.355295 0.0479515 0.464846
+v -0.355333 0.0657165 0.448866
+v -0.355295 0.0828265 0.433696
+v -0.355295 0.100245 0.415738
+v -0.652098 0.407748 -0.100386
+v -0.64028 0.405295 -0.0950424
+v -0.418134 0.444589 0.140271
+v 0.0815998 0.191716 0.416868
+v 0.834321 -0.861187 0.112923
+v 0.839588 -0.861547 0.138344
+v 0.867385 -0.84084 0.138203
+v 0.350901 0.0856011 0.501134
+v 0.35049 -0.787905 0.645412
+v 0.337889 -0.807468 0.640569
+v 0.81373 -0.665142 0.428558
+v 0.813679 -0.647454 0.423484
+v 0.81364 -0.629869 0.415674
+v 0.813512 -0.612412 0.404704
+v 0.428127 -0.00390497 0.530575
+v 0.492328 -0.268492 0.644898
+v 0.184221 -0.174722 0.709022
+v -0.355718 0.65037 0.10257
+v -0.355397 0.669523 0.0965067
+v -0.35532 0.688495 0.0894033
+v 0.0151253 0.95596 -0.249623
+v 0.0244253 0.937064 -0.259231
+v -0.355153 0.726556 0.068504
+v -0.961271 0.479387 0.265641
+v -0.961002 0.479297 0.252847
+v -0.929171 -0.273194 0.243945
+v -0.934129 -0.255853 0.243881
+v -0.929402 -0.273348 0.231113
+v -0.883403 -0.397267 0.206103
+v 0.813538 -0.595302 0.394479
+v 0.184259 -0.091253 0.584512
+v 0.184182 -0.0728971 0.587248
+v -0.512585 -0.710011 0.0795638
+v -0.404466 0.12257 0.405141
+v -0.396207 0.122763 0.394428
+v -0.342501 -0.852029 0.565244
+v -0.342346 -0.834431 0.55475
+v -0.347986 -0.859235 0.571513
+v -0.342488 -0.817578 0.542919
+v -0.342475 -0.800416 0.534313
+v -0.342501 -0.782857 0.527826
+v -0.342809 -0.764976 0.523549
+v -0.342706 -0.747044 0.521737
+v -0.342488 -0.710679 0.524294
+v -0.361846 -0.713209 0.514994
+v -0.363413 -0.695419 0.516137
+v -0.342719 -0.692541 0.526554
+v -0.329707 -0.69204 0.531012
+v -0.342539 -0.67416 0.52929
+v -0.342385 -0.546336 0.545296
+v -0.342167 -0.527377 0.552682
+v -0.0281119 -0.464512 0.719041
+v -0.0211755 -0.459566 0.724526
+v -0.342372 -0.508969 0.559914
+v -0.342411 -0.490729 0.563523
+v -0.342372 -0.472347 0.566221
+v -0.342359 -0.45421 0.567788
+v -0.342231 -0.436072 0.56888
+v -0.342269 -0.418114 0.568854
+v -0.342359 -0.400349 0.565951
+v -0.342424 -0.382674 0.562496
+v -0.342385 -0.364704 0.562663
+v -0.342488 -0.346052 0.567929
+v -0.342616 -0.327542 0.574313
+v -0.342475 -0.309546 0.574917
+v -0.34286 -0.292012 0.572142
+v -0.342064 -0.273836 0.56825
+v -0.342218 -0.255686 0.567981
+v -0.342192 -0.236842 0.570665
+v -0.342372 -0.219346 0.568738
+v -0.342257 -0.201247 0.567582
+v -0.342282 -0.183071 0.567698
+v -0.342565 -0.165101 0.56676
+v -0.342244 -0.146822 0.564821
+v -0.342179 -0.128761 0.561956
+v -0.342334 -0.110829 0.559541
+v -0.342282 -0.09291 0.554776
+v -0.342334 -0.0750037 0.551192
+v -0.342359 -0.0571744 0.544692
+v -0.342372 -0.0395121 0.534904
+v -0.342192 -0.0214516 0.522727
+v -0.342257 -0.0036866 0.50983
+v -0.342385 0.0131279 0.49588
+v -0.342436 0.0311242 0.478706
+v -0.342475 0.0482084 0.465154
+v -0.342462 0.0655496 0.450279
+v -0.342513 0.0831733 0.435597
+v -0.342462 0.10036 0.417382
+v -0.342411 0.117496 0.399168
+v -0.327857 0.135351 0.380606
+v -0.340921 0.135454 0.377228
+v 0.810994 -0.361056 0.124805
+v 0.810532 -0.361146 0.112037
+v 0.80971 -0.343162 0.124779
+v 0.808978 -0.343278 0.112024
+v 0.807462 -0.325384 0.112011
+v 0.80813 -0.325281 0.124779
+v 0.98411 -0.650987 0.111651
+v 0.988388 -0.632721 0.111716
+v -0.661295 0.447594 -0.236045
+v -0.646138 0.456316 -0.255737
+v -0.637416 0.456663 -0.245743
+v 0.810789 -0.361068 0.163277
+v 0.811187 -0.36103 0.150457
+v 0.809042 -0.343214 0.163238
+v 0.813435 -0.578026 0.381749
+v 0.813512 -0.561198 0.368403
+v -0.631802 0.465706 -0.274196
+v 0.428333 0.0674892 0.494004
+v 0.428294 0.0852029 0.485591
+v -0.20074 0.842176 -0.0177394
+v -0.201177 0.860006 -0.0372128
+v 0.492135 -0.286283 0.64951
+v -0.350709 0.632721 0.100013
+v -0.341704 0.650987 0.0933468
+v -0.342873 0.669433 0.0924733
+v -0.342745 0.688405 0.0870911
+v -0.342552 0.707429 0.0801675
+v -0.32954 0.745849 0.0564679
+v -0.329591 0.726864 0.0687609
+v -0.342398 0.726543 0.0700454
+v -0.140842 -0.946377 0.708637
+v -0.133944 -0.942228 0.711629
+v -0.152865 -0.944784 0.704526
+v 0.812356 -0.396881 0.176186
+v 0.810725 -0.379039 0.188967
+v -0.439149 -0.805708 0.234118
+v -0.437736 0.463972 0.191845
+v -0.432289 0.483497 0.18469
+v -0.438763 0.483741 0.197509
+v -0.426817 -0.771052 0.233784
+v -0.42728 -0.752953 0.220297
+v -0.606471 0.500941 -0.327016
+v 0.942504 -0.741932 0.299514
+v 0.93508 -0.741418 0.311524
+v 0.931881 -0.763139 0.292038
+v 0.428307 0.103032 0.475944
+v 0.42814 0.0492874 0.502855
+v -0.337529 -0.92901 0.586375
+v -0.349244 -0.929293 0.591539
+v -0.334061 -0.941547 0.585296
+v -0.581898 0.687365 -0.709844
+v -0.395205 0.446554 0.0334877
+v -0.329488 -0.869896 0.568777
+v -0.329604 -0.852709 0.559939
+v -0.329527 -0.835214 0.550742
+v -0.329553 -0.818258 0.541648
+v -0.329668 -0.800185 0.53493
+v -0.32963 -0.782703 0.529445
+v -0.32963 -0.764835 0.526079
+v -0.32972 -0.746749 0.524769
+v -0.329848 -0.728778 0.525231
+v -0.329694 -0.710409 0.527813
+v -0.329655 -0.67371 0.534185
+v -0.600203 0.489855 0.505989
+v -0.603787 0.512181 0.496805
+v -0.329681 -0.655521 0.535829
+v -0.342758 -0.655958 0.531333
+v -0.342501 -0.637589 0.534095
+v -0.32963 -0.637152 0.538963
+v 0.531147 -0.893198 -0.0518436
+v -0.32954 -0.618668 0.543664
+v -0.329231 -0.600235 0.546156
+v -0.34209 -0.582663 0.541519
+v -0.329424 -0.582252 0.546683
+v -0.342398 -0.564679 0.542123
+v -0.351017 -0.570794 0.536831
+v -0.329642 -0.564268 0.547235
+v -0.353984 -0.552605 0.538757
+v -0.329527 -0.545899 0.550203
+v -0.329514 -0.527415 0.554904
+v -0.329668 -0.509355 0.559438
+v -0.32963 -0.49096 0.562354
+v -0.329553 -0.472347 0.566246
+v -0.329527 -0.454043 0.569394
+v -0.329411 -0.435802 0.572001
+v -0.329411 -0.417845 0.572284
+v -0.329527 -0.40008 0.569727
+v -0.329617 -0.38252 0.563793
+v -0.329578 -0.364781 0.560363
+v -0.329488 -0.346502 0.562958
+v -0.32945 -0.328249 0.567338
+v -0.329475 -0.31006 0.568109
+v -0.329565 -0.292269 0.565411
+v -0.329617 -0.274157 0.565142
+v -0.329514 -0.255737 0.567582
+v -0.329527 -0.237561 0.567724
+v -0.329707 -0.21995 0.56554
+v -0.329424 -0.201466 0.563395
+v -0.329334 -0.183431 0.563408
+v -0.32954 -0.16528 0.562393
+v -0.32963 -0.147207 0.561699
+v -0.329514 -0.129095 0.559259
+v -0.329308 -0.110971 0.555277
+v -0.329591 -0.0933468 0.550883
+v -0.329321 -0.0751707 0.545244
+v -0.329398 -0.0573543 0.540003
+v -0.329424 -0.0396406 0.531808
+v -0.329193 -0.021426 0.519759
+v -0.32945 -0.00431602 0.509072
+v -0.32945 0.0134362 0.493247
+v -0.329553 0.0305204 0.478089
+v -0.329591 0.0481956 0.46518
+v -0.329604 0.0656652 0.451949
+v -0.329642 0.0833146 0.437331
+v -0.329655 0.100553 0.420722
+v -0.32972 0.118344 0.401467
+v -0.32471 0.152217 0.362083
+v -0.33884 0.15169 0.357228
+v 0.811187 -0.379026 0.124831
+v 0.810699 -0.379052 0.112062
+v 0.0174246 -0.916473 -0.090585
+v 0.00403985 -0.917039 -0.0927559
+v 0.0133527 -0.916229 -0.115556
+v -0.972306 0.180309 0.408583
+v -0.971766 0.180374 0.42139
+v -0.970597 0.197946 0.408468
+v 0.581834 -0.634018 -0.248068
+v 0.582669 -0.615534 -0.247413
+v 0.59247 -0.632952 -0.234529
+v 0.92772 -0.656215 0.00924861
+v 0.936814 -0.655341 0.0222224
+v 0.932318 -0.673607 0.0221324
+v 0.738701 -0.0952993 0.00960828
+v -0.38909 0.286925 0.0892748
+v -0.397838 0.306707 0.102017
+v -0.385391 0.287067 0.10212
+v -0.441987 -0.805439 0.272218
+v 0.428397 0.0143225 0.520312
+v 0.428179 0.0314838 0.51105
+v -0.585739 0.676896 -0.684577
+v 0.813807 -0.468442 0.0976885
+v 0.812163 -0.451037 0.0993712
+v -0.509618 -0.710345 0.0924605
+v -0.097772 0.664307 -0.170431
+v -0.0899492 0.679144 -0.1795
+v -0.0849781 0.660813 -0.166873
+v -0.246803 -0.90323 -0.358898
+v -0.266829 -0.909486 -0.352783
+v -0.253855 -0.891155 -0.352629
+v -0.330632 0.65168 0.0839312
+v -0.341589 0.632708 0.090585
+v -0.464736 0.437922 0.0108029
+v -0.452354 0.420555 0.0208222
+v -0.329617 0.688662 0.0828136
+v -0.329565 0.707737 0.0775342
+v 0.809671 -0.361146 0.176135
+v 0.807963 -0.343265 0.176109
+v 0.807256 -0.343355 0.18889
+v -0.316746 0.745695 0.0578038
+v -0.919666 0.390471 0.163675
+v -0.912035 0.390202 0.150842
+v -0.915337 0.372591 0.15074
+v -0.233238 0.539554 0.0207965
+v -0.625123 -0.88621 -0.049403
+v -0.619509 -0.880404 -0.047412
+v -0.60389 -0.883679 -0.0593581
+v -0.595797 0.398487 -0.0700069
+v -0.327883 -0.911207 0.578013
+v -0.298827 -0.92743 0.569008
+v -0.316836 -0.905966 0.572849
+v -0.347395 -0.95587 0.584936
+v -0.331184 -0.949036 0.582213
+v -0.316682 -0.887983 0.57019
+v -0.329424 -0.887597 0.573851
+v -0.31672 -0.870128 0.566863
+v -0.316617 -0.852427 0.560774
+v -0.31672 -0.835227 0.552052
+v -0.316707 -0.817744 0.544024
+v -0.316759 -0.800236 0.535058
+v -0.316771 -0.782728 0.529457
+v -0.316771 -0.764848 0.526208
+v -0.3169 -0.746761 0.525732
+v -0.316836 -0.728637 0.526786
+v -0.31681 -0.710294 0.529624
+v -0.31681 -0.691938 0.532746
+v -0.316836 -0.673607 0.536086
+v -0.316849 -0.655444 0.537678
+v -0.316849 -0.636921 0.542547
+v -0.316836 -0.618475 0.547325
+v -0.316515 -0.599965 0.549573
+v -0.31672 -0.58202 0.550215
+v -0.316656 -0.563793 0.551641
+v -0.316771 -0.545694 0.553825
+v -0.316759 -0.527505 0.555559
+v -0.316707 -0.509111 0.558064
+v -0.316733 -0.491037 0.560569
+v -0.316759 -0.472489 0.564577
+v -0.316733 -0.45403 0.569214
+v -0.316707 -0.43579 0.572605
+v -0.316682 -0.417691 0.574313
+v -0.316643 -0.399836 0.572695
+v -0.316797 -0.382263 0.567158
+v -0.316527 -0.364383 0.564178
+v -0.316643 -0.346219 0.566336
+v -0.316759 -0.32821 0.567069
+v -0.316733 -0.310188 0.566927
+v -0.316746 -0.292243 0.56563
+v -0.316771 -0.27399 0.566863
+v -0.316707 -0.255865 0.566555
+v -0.31672 -0.237754 0.565411
+v -0.316759 -0.219693 0.563857
+v -0.316759 -0.201684 0.561147
+v -0.31672 -0.183546 0.560967
+v -0.316759 -0.165486 0.560106
+v -0.31672 -0.147438 0.557409
+v -0.316527 -0.129378 0.553324
+v -0.31636 -0.111317 0.548957
+v -0.31645 -0.0934752 0.54369
+v -0.316335 -0.0754147 0.539014
+v -0.316476 -0.0576882 0.533581
+v -0.316219 -0.0395764 0.524628
+v -0.316193 -0.0216957 0.515045
+v -0.31645 -0.00420041 0.504807
+v -0.316489 0.0136032 0.490536
+v -0.316682 0.030469 0.478076
+v -0.316733 0.0481956 0.465231
+v -0.316733 0.0656523 0.453478
+v -0.316797 0.0837642 0.437845
+v -0.316759 0.100592 0.423882
+v -0.316823 0.11828 0.40455
+v -0.309899 0.154259 0.367247
+v -0.303939 0.135646 0.389611
+v -0.296681 0.154465 0.372668
+v -0.316746 0.135287 0.384588
+v 0.756877 -0.111382 0.227387
+v 0.559663 -0.744783 -0.246887
+v 0.574345 -0.743357 -0.234003
+v 0.565675 -0.76215 -0.233502
+v -0.582181 0.700043 -0.668521
+v -0.580999 0.720441 -0.655778
+v -0.415834 0.38532 0.127605
+v -0.418198 0.385192 0.114786
+v -0.419315 0.404987 0.127605
+v -0.581642 -0.826595 0.490896
+v -0.559085 -0.810089 0.491012
+v 0.923917 -0.674263 0.00980096
+v -0.580331 0.819736 -0.77461
+v -0.569875 0.821804 -0.760249
+v -0.331878 0.48139 0.016609
+v -0.450041 -0.707519 0.31322
+v 0.963314 -0.53403 0.0885812
+v 0.966153 -0.54536 0.085524
+v 0.960796 -0.546118 0.0730127
+v -0.886178 0.533696 0.134465
+v -0.904213 0.51326 0.138036
+v -0.896634 0.531795 0.149327
+v 0.132955 -0.0369174 0.585103
+v 0.325763 -0.512694 0.733068
+v 0.184169 -0.600826 0.745233
+v 0.209642 -0.0732182 0.584962
+v 0.338223 0.0859993 0.504795
+v 0.33487 0.080129 0.508931
+v -0.317208 0.688598 0.0768663
+v -0.316874 0.70775 0.0738348
+v -0.330169 0.669446 0.0854341
+v -0.320175 0.670666 0.0766222
+v -0.316733 0.72698 0.0672066
+v -0.455475 -0.767224 0.4264
+v -0.450902 -0.767725 0.43972
+v -0.443529 -0.75109 0.433542
+v -0.315025 0.515482 -0.0457421
+v -0.314061 0.500954 -0.0269366
+v -0.903172 -0.291306 0.32076
+v -0.895735 -0.309212 0.321004
+v -0.896749 -0.299938 0.327324
+v -0.899023 -0.326874 0.244215
+v -0.577043 -0.917642 0.324395
+v -0.580113 -0.899389 0.324267
+v -0.567807 -0.900725 0.311473
+v 0.452482 0.208235 0.0295827
+v -0.863711 0.424781 0.0732439
+v -0.303695 -0.870873 0.559169
+v -0.3039 -0.852966 0.556908
+v -0.303849 -0.835111 0.552361
+v -0.303862 -0.81777 0.544011
+v -0.303862 -0.800403 0.534493
+v -0.303875 -0.782754 0.528378
+v -0.303875 -0.764912 0.525488
+v -0.303888 -0.746749 0.525848
+v -0.303875 -0.728662 0.526811
+v -0.303888 -0.710268 0.529239
+v -0.303926 -0.692028 0.533234
+v -0.303862 -0.673363 0.537165
+v -0.303913 -0.655213 0.538989
+v -0.30399 -0.636844 0.544409
+v -0.303811 -0.618 0.549792
+v -0.303875 -0.599875 0.551821
+v -0.303811 -0.581699 0.553221
+v -0.303836 -0.563523 0.554878
+v -0.303785 -0.545334 0.556047
+v -0.303926 -0.527505 0.555585
+v -0.303875 -0.50929 0.556946
+v -0.303875 -0.491153 0.558642
+v -0.303849 -0.4729 0.562316
+v -0.303849 -0.454441 0.567081
+v -0.303952 -0.4357 0.572027
+v -0.303888 -0.417652 0.574365
+v -0.303785 -0.399643 0.573992
+v -0.304016 -0.382148 0.569227
+v -0.303708 -0.363856 0.570961
+v -0.303644 -0.345551 0.574185
+v -0.303733 -0.327555 0.574532
+v -0.303926 -0.309662 0.573478
+v -0.303785 -0.291819 0.571346
+v -0.303759 -0.273798 0.569599
+v -0.30399 -0.255776 0.567544
+v -0.303875 -0.237677 0.566902
+v -0.303913 -0.21959 0.565566
+v -0.303965 -0.201568 0.562688
+v -0.303823 -0.183534 0.561712
+v -0.303875 -0.165473 0.559117
+v -0.303888 -0.147567 0.555662
+v -0.303875 -0.129789 0.550537
+v -0.303798 -0.111626 0.545103
+v -0.303644 -0.0938092 0.538668
+v -0.303528 -0.0757487 0.532579
+v -0.303322 -0.0577011 0.524962
+v -0.303155 -0.0398718 0.516908
+v -0.303579 -0.022415 0.509509
+v -0.303541 -0.0043674 0.500183
+v -0.303695 0.0130765 0.488404
+v -0.303746 0.0307388 0.477023
+v -0.303798 0.0484268 0.465552
+v -0.303811 0.0662304 0.452694
+v -0.303888 0.0838669 0.438063
+v -0.303926 0.100823 0.424126
+v -0.303862 0.11783 0.407234
+v -0.291196 0.136366 0.393439
+v 0.810981 -0.397022 0.112062
+v 0.811932 -0.396894 0.124908
+v 0.773948 -0.146886 0.214439
+v 0.772458 -0.146937 0.227298
+v 0.809491 -0.343162 0.150431
+v 0.807744 -0.325333 0.150406
+v 0.807346 -0.325371 0.163212
+v -0.404197 0.346386 0.166141
+v -0.464724 0.401634 0.0132692
+v -0.466972 0.382494 0.0138858
+v -0.656953 0.363727 -0.0820172
+v 0.322077 0.0280284 0.535546
+v 0.325108 0.0147336 0.535019
+v 0.614834 -0.948188 0.0580607
+v 0.630466 -0.942241 0.0565964
+v -0.867796 -0.415584 0.193386
+v -0.854591 -0.428699 0.203264
+v -0.86989 -0.416162 0.211691
+v -0.17379 0.565476 -0.0575084
+v 0.184349 -0.510922 0.756087
+v 0.287163 0.010045 0.552862
+v 0.376875 0.0140913 0.524165
+v 0.364094 -0.00348108 0.529869
+v -0.290503 -0.968869 0.541429
+v -0.304183 0.707725 0.0684654
+v -0.303965 0.726838 0.0652156
+v -0.303913 0.746004 0.0565707
+v -0.396926 0.326913 0.166128
+v -0.403015 0.346168 0.178999
+v 0.779009 -0.146475 0.15029
+v 0.0909768 0.730525 -0.267683
+v -0.210451 0.544641 -0.0139243
+v -0.179455 0.562611 -0.0121517
+v -0.486111 -0.855278 0.285538
+v 0.272866 0.188518 0.442508
+v 0.261305 0.174953 0.454325
+v -0.920141 -0.247914 0.312667
+v -0.921502 -0.230303 0.313464
+v -0.923044 -0.23855 0.307722
+v 0.0640274 0.224382 0.348454
+v -0.290952 -0.871605 0.55448
+v -0.291029 -0.853634 0.550421
+v -0.291094 -0.836203 0.547788
+v -0.290991 -0.817963 0.539926
+v -0.29094 -0.80057 0.531911
+v -0.290991 -0.78287 0.527826
+v -0.29094 -0.764925 0.525167
+v -0.290927 -0.746787 0.525296
+v -0.290965 -0.728791 0.525553
+v -0.290991 -0.710525 0.52834
+v -0.291017 -0.691989 0.5329
+v -0.291029 -0.673633 0.536163
+v -0.291029 -0.654995 0.540196
+v -0.291029 -0.636356 0.546747
+v -0.291055 -0.618154 0.550639
+v -0.291017 -0.599708 0.553183
+v -0.291029 -0.581558 0.554853
+v -0.291029 -0.563369 0.556407
+v -0.291004 -0.545334 0.556253
+v -0.291042 -0.527492 0.555662
+v -0.291029 -0.509303 0.556856
+v -0.291042 -0.491114 0.558334
+v -0.291094 -0.472758 0.561121
+v -0.290965 -0.454724 0.56396
+v -0.291068 -0.436213 0.568122
+v -0.291132 -0.417691 0.57204
+v -0.291428 -0.399759 0.571641
+v -0.290914 -0.381852 0.570896
+v -0.29076 -0.363239 0.577024
+v -0.290785 -0.345166 0.579066
+v -0.290927 -0.327195 0.579541
+v -0.290696 -0.309238 0.578963
+v -0.29094 -0.29146 0.576291
+v -0.290978 -0.273399 0.574814
+v -0.291029 -0.255339 0.57353
+v -0.291055 -0.237304 0.571937
+v -0.291184 -0.219218 0.570627
+v -0.290952 -0.201222 0.568366
+v -0.290914 -0.183367 0.564962
+v -0.291145 -0.165255 0.561134
+v -0.291184 -0.147361 0.556343
+v -0.291068 -0.129558 0.551153
+v -0.29162 -0.111099 0.545476
+v -0.290978 -0.0938477 0.536959
+v -0.290965 -0.0763396 0.52843
+v -0.290798 -0.0583947 0.519245
+v -0.290708 -0.0403471 0.511731
+v -0.290631 -0.0222481 0.504101
+v -0.290811 -0.00468853 0.496792
+v -0.290901 0.0128325 0.486606
+v -0.29085 0.0309829 0.47579
+v -0.290862 0.0485167 0.464139
+v -0.290901 0.0661661 0.451114
+v -0.290991 0.0835972 0.437793
+v -0.291042 0.101234 0.423086
+v -0.291132 0.118575 0.408057
+v -0.282397 0.15449 0.377112
+v -0.901644 0.549625 0.260657
+v -0.912318 0.543472 0.238088
+v -0.922068 0.538475 0.253913
+v 0.802735 -0.883731 0.138434
+v 0.991548 -0.667891 0.176032
+v -0.579856 0.720416 -0.668662
+v 0.955709 -0.724141 0.293721
+v 0.948246 -0.722998 0.308621
+v -0.647987 0.527967 -0.528674
+v 0.428179 0.120463 0.464126
+v 0.351274 -0.0390369 0.552065
+v 0.351711 -0.0566735 0.580428
+v -0.0242969 -0.934508 0.699876
+v -0.0395442 -0.932145 0.705644
+v -0.0415096 -0.95 0.701636
+v 0.157927 -0.863332 0.634699
+v 0.158248 -0.84567 0.626979
+v 0.145415 -0.845452 0.630447
+v 0.197143 -0.455918 0.772863
+v -0.382462 0.457447 0.0174439
+v -0.370478 0.468494 0.00229931
+v 0.376849 0.0320362 0.517794
+v 0.364016 0.0321775 0.519554
+v -0.309039 0.68978 0.0703665
+v -0.291235 0.72689 0.059949
+v -0.290747 0.746081 0.0553889
+v 0.76452 -0.111099 0.150277
+v 0.764019 -0.111317 0.163097
+v -0.278223 0.783666 0.0295956
+v -0.438917 0.502405 0.197419
+v -0.441422 0.483677 0.204664
+v -0.117258 0.597435 -0.0137445
+v -0.108935 0.61633 -0.00151575
+v -0.127586 0.59687 -0.00622997
+v 0.197066 0.157959 0.479155
+v -0.973731 0.162891 0.395854
+v -0.974862 0.180297 0.395699
+v -0.976686 0.162878 0.383047
+v -0.722105 0.453773 -0.185255
+v 0.088138 0.807237 -0.338885
+v -0.278081 -0.854251 0.546349
+v -0.278171 -0.836332 0.541879
+v -0.278146 -0.818361 0.536381
+v -0.27812 -0.800724 0.531384
+v -0.278043 -0.782921 0.52694
+v -0.278081 -0.76495 0.525064
+v -0.278043 -0.746928 0.523394
+v -0.277902 -0.729138 0.522598
+v -0.278043 -0.710653 0.526721
+v -0.278133 -0.692066 0.530948
+v -0.278158 -0.673762 0.534223
+v -0.278107 -0.655431 0.539734
+v -0.278133 -0.636729 0.546118
+v -0.278184 -0.618129 0.550472
+v -0.278197 -0.59967 0.552913
+v -0.278197 -0.581789 0.554442
+v -0.278184 -0.563408 0.556754
+v -0.278197 -0.54554 0.555726
+v -0.27821 -0.527299 0.556394
+v -0.278184 -0.509136 0.558064
+v -0.278171 -0.491153 0.558912
+v -0.27821 -0.472925 0.55976
+v -0.27821 -0.454929 0.560248
+v -0.278428 -0.436316 0.5636
+v -0.278351 -0.417909 0.568893
+v -0.278197 -0.400041 0.569984
+v -0.278158 -0.381518 0.574185
+v -0.27803 -0.362931 0.580325
+v -0.278017 -0.344883 0.582162
+v -0.278043 -0.326939 0.582316
+v -0.278056 -0.308981 0.582252
+v -0.27812 -0.291062 0.581224
+v -0.278313 -0.273078 0.579156
+v -0.27812 -0.254953 0.578051
+v -0.277914 -0.236829 0.57764
+v -0.277799 -0.218755 0.577422
+v -0.277953 -0.200862 0.574532
+v -0.278004 -0.18302 0.56983
+v -0.278364 -0.164972 0.564525
+v -0.2783 -0.147271 0.559079
+v -0.278197 -0.129609 0.553722
+v -0.278184 -0.11187 0.547223
+v -0.278197 -0.0940147 0.537948
+v -0.278184 -0.0763268 0.526914
+v -0.278133 -0.0584461 0.516227
+v -0.277979 -0.0407067 0.508366
+v -0.278069 -0.0227105 0.501904
+v -0.278017 -0.00477845 0.493786
+v -0.27812 0.0125499 0.484717
+v -0.278056 0.0306103 0.473812
+v -0.278094 0.0480286 0.462007
+v -0.278043 0.0659092 0.4478
+v -0.277953 0.0838156 0.433606
+v -0.278171 0.10117 0.421634
+v -0.270387 0.151228 0.381582
+v 0.810635 -0.415057 0.112101
+v 0.779331 -0.164471 0.214504
+v 0.778598 -0.164728 0.227259
+v 0.989146 -0.614879 0.111459
+v 0.991779 -0.632464 0.124484
+v 0.839023 -0.860866 0.12564
+v 0.186238 -0.115916 0.587197
+v 0.176963 -0.118588 0.60396
+v 0.190387 -0.119269 0.608726
+v -0.140174 0.583742 -0.0127682
+v -0.139224 0.579027 -0.0239051
+v -0.130707 0.584294 -0.0264742
+v -0.0790564 -0.924682 0.109712
+v -0.0924026 -0.925272 0.107528
+v -0.0826274 -0.92314 0.0843422
+v 0.32557 -0.280593 0.731296
+v 0.351197 -0.0220554 0.537987
+v 0.235615 -0.209121 0.726479
+v -0.633113 0.551307 -0.567981
+v -0.639188 0.547158 -0.581635
+v 0.376746 0.0497627 0.511024
+v -0.270528 0.536317 -0.0601288
+v -0.259353 0.534763 -0.0536548
+v -0.277529 0.727365 0.0504949
+v -0.278069 0.746209 0.0501737
+v -0.278197 0.765323 0.0428904
+v -0.265454 0.784257 0.0302507
+v 0.803852 -0.289649 0.163122
+v 0.802889 -0.289674 0.176045
+v 0.80452 -0.307568 0.176045
+v -0.42105 0.38532 0.204728
+v -0.575013 0.599888 -0.347491
+v -0.58028 0.699825 -0.694263
+v -0.288987 0.5036 0.00448301
+v -0.566266 -0.882857 0.324228
+v -0.55545 -0.884052 0.311344
+v -0.844867 0.55967 0.33647
+v -0.828592 0.564474 0.341955
+v -0.615951 0.854623 -0.663164
+v -0.623928 0.850693 -0.647403
+v -0.21618 0.583819 -0.106629
+v -0.204144 0.581301 -0.101504
+v 0.0430382 -0.192525 0.706363
+v 0.0555238 -0.1916 0.708649
+v 0.0558963 -0.175557 0.69091
+v -0.265377 -0.818464 0.534788
+v -0.265288 -0.800763 0.529946
+v -0.265198 -0.782985 0.525604
+v -0.265249 -0.765092 0.523125
+v -0.265198 -0.747224 0.520145
+v -0.265249 -0.729035 0.521249
+v -0.265121 -0.710974 0.52351
+v -0.265249 -0.6924 0.527813
+v -0.26521 -0.674134 0.531282
+v -0.265326 -0.655367 0.53719
+v -0.265288 -0.636793 0.544024
+v -0.265288 -0.618308 0.548995
+v -0.26539 -0.599863 0.551551
+v -0.265442 -0.581519 0.55448
+v -0.265352 -0.563523 0.555238
+v -0.265326 -0.545501 0.555161
+v -0.265377 -0.527287 0.556381
+v -0.265339 -0.509162 0.558398
+v -0.265352 -0.491012 0.560132
+v -0.2653 -0.472977 0.559849
+v -0.265365 -0.45507 0.558449
+v -0.26539 -0.43674 0.561622
+v -0.265467 -0.418371 0.564448
+v -0.265493 -0.399977 0.56739
+v -0.265403 -0.381338 0.575726
+v -0.265365 -0.362918 0.580492
+v -0.265352 -0.344896 0.582688
+v -0.265365 -0.326836 0.584101
+v -0.265352 -0.308852 0.583896
+v -0.265442 -0.29119 0.5808
+v -0.265352 -0.273245 0.576895
+v -0.265146 -0.254774 0.579066
+v -0.265249 -0.236559 0.581442
+v -0.265198 -0.218332 0.582958
+v -0.264889 -0.200489 0.580479
+v -0.26521 -0.182673 0.574801
+v -0.265236 -0.164959 0.568315
+v -0.265416 -0.14686 0.564153
+v -0.265185 -0.129429 0.558257
+v -0.265365 -0.111613 0.549136
+v -0.265416 -0.0938092 0.538295
+v -0.265403 -0.0762754 0.52694
+v -0.26539 -0.0586388 0.51728
+v -0.26539 -0.0407838 0.509367
+v -0.265365 -0.0228004 0.501699
+v -0.2653 -0.00509958 0.493234
+v -0.265249 0.012871 0.482135
+v -0.265236 0.0305076 0.470613
+v -0.265133 0.0480286 0.457383
+v -0.26521 0.0655239 0.442752
+v -0.265288 0.0830063 0.43105
+v -0.265326 0.100977 0.421441
+v -0.265326 0.118562 0.411178
+v 0.803698 -0.325795 0.0864874
+v 0.805676 -0.325564 0.0992171
+v 0.8075 -0.343393 0.0992042
+v 0.788772 -0.200143 0.214504
+v 0.790917 -0.217985 0.2274
+v 0.48412 -0.900314 -0.130572
+v 0.601899 -0.505128 -0.247208
+v 0.185634 -0.869742 0.626183
+v -0.573921 0.74057 -0.707146
+v -0.679022 0.416188 0.597602
+v -0.689876 0.401364 0.611243
+v 0.274254 -0.262352 0.733287
+v 0.210721 0.158113 0.477383
+v 0.200252 0.163135 0.473182
+v 0.351107 -0.00389213 0.530292
+v 0.295975 -0.345718 0.745002
+v 0.300034 -0.333284 0.745605
+v 0.197259 -0.474197 0.768547
+v -0.105081 0.879967 -0.108029
+v -0.0938156 0.899081 -0.114143
+v -0.0985427 0.900764 -0.106809
+v 0.826717 -0.684834 0.426836
+v 0.338274 -0.00357099 0.532425
+v 0.33839 -0.26338 0.720454
+v 0.325596 -0.263085 0.723717
+v 0.312622 0.139346 0.483163
+v 0.312648 0.157355 0.47069
+v -0.265814 0.746029 0.042261
+v -0.265133 0.765503 0.0399232
+v -0.252481 0.80355 0.0147978
+v 0.770455 -0.129044 0.175916
+v 0.769196 -0.129018 0.188774
+v 0.775862 -0.146655 0.188787
+v 0.478185 -0.967713 0.000513812
+v 0.48674 -0.954855 -0.0147079
+v -0.231838 0.821585 -0.146244
+v -0.238107 0.803563 -0.150393
+v -0.246135 0.821148 -0.133064
+v -0.978022 0.180271 0.382944
+v -0.252622 -0.818387 0.536137
+v -0.252584 -0.800853 0.528276
+v -0.0584268 0.200194 0.0330638
+v -0.0734687 0.203315 0.0557743
+v -0.25225 -0.783332 0.522251
+v -0.252327 -0.76549 0.518565
+v -0.252262 -0.747494 0.516818
+v -0.252224 -0.729523 0.516895
+v -0.252352 -0.711206 0.519682
+v -0.252481 -0.692644 0.524204
+v -0.252494 -0.674263 0.527441
+v -0.252506 -0.655752 0.532245
+v -0.252494 -0.636998 0.540479
+v -0.252352 -0.618604 0.545848
+v -0.252404 -0.600248 0.549059
+v -0.252404 -0.581918 0.552322
+v -0.252417 -0.563831 0.552245
+v -0.252532 -0.545643 0.553337
+v -0.252584 -0.527274 0.556047
+v -0.252519 -0.509175 0.558321
+v -0.252532 -0.490986 0.559798
+v -0.252519 -0.472951 0.559978
+v -0.252468 -0.455083 0.558886
+v -0.252571 -0.436894 0.559721
+v -0.252699 -0.41859 0.560928
+v -0.252532 -0.400272 0.566709
+v -0.252712 -0.38139 0.573838
+v -0.252571 -0.363278 0.577961
+v -0.252596 -0.34505 0.581096
+v -0.252699 -0.326926 0.582187
+v -0.252686 -0.309058 0.580158
+v -0.252532 -0.291563 0.573324
+v -0.252442 -0.273309 0.574313
+v -0.252494 -0.254851 0.580004
+v -0.252224 -0.236148 0.585424
+v -0.252288 -0.217998 0.587505
+v -0.252262 -0.200207 0.584204
+v -0.252198 -0.182532 0.579053
+v -0.252211 -0.164857 0.572682
+v -0.252468 -0.146706 0.568636
+v -0.252378 -0.129211 0.561648
+v -0.252558 -0.111369 0.551063
+v -0.252494 -0.0939377 0.540967
+v -0.252596 -0.0760955 0.530164
+v -0.252571 -0.0586131 0.520209
+v -0.252622 -0.0407196 0.510896
+v -0.252648 -0.0227233 0.503215
+v -0.252571 -0.00516381 0.494493
+v -0.252506 0.0120617 0.482469
+v -0.252468 0.030225 0.468661
+v -0.252417 0.0479772 0.454287
+v -0.252455 0.0651257 0.440722
+v -0.252481 0.0831733 0.429791
+v -0.252506 0.100373 0.422135
+v -0.252506 0.118228 0.41078
+v -0.23961 0.118369 0.409392
+v 0.809607 -0.379193 0.0991785
+v 0.796363 -0.217882 0.0862305
+v 0.792638 -0.200155 0.0862819
+v 0.789748 -0.200297 0.0734237
+v 0.78786 -0.182378 0.086269
+v -0.580601 0.660505 -0.347465
+v -0.509592 -0.831746 -0.0576625
+v -0.51062 -0.846813 -0.0693389
+v -0.526497 -0.836049 -0.0502251
+v 0.69942 -0.0239179 0.0218627
+v 0.6945 -0.0242262 0.00903024
+v 0.688643 -0.0061529 0.0228646
+v -0.571956 0.760878 -0.707172
+v 0.312687 0.175236 0.456137
+v 0.751636 -0.589265 0.385731
+v 0.737121 -0.631115 0.403008
+v 0.228537 -0.124651 0.622676
+v 0.23988 -0.129275 0.626812
+v -0.376939 0.278576 0.112538
+v -0.382115 0.286861 0.115042
+v -0.378853 0.286707 0.130611
+v 0.188909 0.167426 0.468674
+v -0.252596 0.765284 0.0323445
+v -0.279186 0.708701 0.0457421
+v -0.287831 0.708804 0.0559156
+v -0.251954 0.784629 0.0280027
+v -0.239224 0.803653 0.0153373
+v 0.683042 -0.00664102 0.00908163
+v -0.770236 0.149596 0.695509
+v 0.545456 -0.94779 0.0197561
+v 0.528089 -0.95569 0.0235197
+v 0.528192 0.101067 0.427697
+v 0.0175659 0.172885 0.415134
+v 0.130361 0.248454 0.0383817
+v -0.429399 0.0867828 0.43692
+v -0.44042 0.0864232 0.443253
+v 0.110026 0.255968 0.271588
+v -0.477299 0.552528 0.259719
+v -0.240046 -0.800313 0.528931
+v -0.239661 -0.783615 0.519631
+v -0.239584 -0.765862 0.514801
+v -0.239353 -0.747943 0.512014
+v -0.239635 -0.72978 0.512617
+v -0.239289 -0.711976 0.513696
+v -0.239456 -0.693325 0.518154
+v -0.239558 -0.674815 0.522624
+v -0.239456 -0.656356 0.52789
+v -0.239687 -0.637409 0.53552
+v -0.239674 -0.618938 0.540389
+v -0.239648 -0.600453 0.545334
+v -0.239584 -0.582329 0.547223
+v -0.239777 -0.564076 0.548224
+v -0.239802 -0.545732 0.55132
+v -0.239635 -0.527595 0.553594
+v -0.239764 -0.509278 0.55642
+v -0.239571 -0.491307 0.557319
+v -0.239623 -0.473105 0.558783
+v -0.239674 -0.45507 0.558539
+v -0.239751 -0.437036 0.558013
+v -0.239815 -0.418937 0.557961
+v -0.239828 -0.400478 0.562958
+v -0.23988 -0.382006 0.567685
+v -0.240021 -0.363458 0.573928
+v -0.240046 -0.345397 0.575611
+v -0.240046 -0.327285 0.576934
+v -0.239224 -0.309726 0.573877
+v -0.239314 -0.291601 0.571693
+v -0.239571 -0.272898 0.574968
+v -0.23952 -0.254414 0.582213
+v -0.239597 -0.23593 0.589445
+v -0.239404 -0.217779 0.590306
+v -0.239468 -0.199924 0.587493
+v -0.239314 -0.182326 0.582239
+v -0.239289 -0.164677 0.575765
+v -0.239494 -0.146809 0.569805
+v -0.239854 -0.12889 0.561545
+v -0.23961 -0.111536 0.552168
+v -0.239751 -0.0936808 0.542932
+v -0.239777 -0.0759286 0.533337
+v -0.239815 -0.0583947 0.522046
+v -0.239905 -0.0405269 0.512694
+v -0.239751 -0.0229674 0.505642
+v -0.239725 -0.00525373 0.495867
+v -0.239687 0.0122544 0.482688
+v -0.2397 0.0301608 0.468545
+v -0.239674 0.0474505 0.455135
+v -0.239661 0.065267 0.440915
+v -0.239661 0.0832632 0.429894
+v -0.239623 0.101003 0.421429
+v 0.944907 -0.761739 0.124933
+v 0.955581 -0.742651 0.124895
+v -0.226777 0.100874 0.421223
+v -0.226829 0.117933 0.40735
+v 0.80908 -0.361248 0.0992171
+v 0.794321 -0.2181 0.0734623
+v 0.785252 -0.182416 0.0733466
+v 0.780114 -0.164728 0.0733852
+v 0.781977 -0.164523 0.0861663
+v -0.516619 -0.74513 0.0796537
+v -0.513972 -0.745233 0.0926788
+v -0.512765 -0.727622 0.0797308
+v 0.783261 -0.345384 0.00938991
+v 0.786241 -0.34541 0.0224536
+v 0.801026 -0.325949 0.0736036
+v 0.325596 -0.530716 0.729536
+v 0.35112 -0.160129 0.647146
+v 0.132994 0.122069 0.504422
+v 0.982993 -0.686671 0.214683
+v 0.197092 0.0520491 0.553465
+v 0.371659 0.132949 0.472309
+v 0.384941 0.133386 0.469097
+v 0.343875 0.0457293 0.521879
+v 0.325455 0.157201 0.47051
+v 0.518186 -0.18758 0.616305
+v 0.505918 -0.187811 0.621224
+v -0.239687 0.784539 0.0219783
+v -0.213855 0.803859 -0.000333978
+v -0.2104 0.784745 -0.012537
+v -0.199031 0.803846 -0.018433
+v -0.926358 -0.187233 0.128068
+v -0.901682 0.407813 0.137804
+v 0.171427 0.174491 0.460337
+v -0.478494 0.547325 0.296662
+v 0.102486 0.253194 0.287516
+v -0.945048 0.268544 0.523484
+v -0.940642 0.286193 0.523369
+v -0.941207 0.286283 0.510652
+v -0.961772 0.233258 0.446772
+v -0.956043 0.250817 0.446682
+v -0.238775 -0.807738 0.540235
+v -0.00842009 -0.513838 0.716973
+v -0.021381 -0.501095 0.713672
+v -0.0176045 -0.519245 0.710332
+v -0.226713 -0.765875 0.512193
+v -0.226623 -0.748149 0.508661
+v -0.226816 -0.730242 0.507813
+v -0.226739 -0.712066 0.509663
+v -0.226533 -0.693929 0.511744
+v -0.226597 -0.675457 0.516497
+v -0.226559 -0.656793 0.523073
+v -0.226636 -0.63827 0.527813
+v -0.22715 -0.619362 0.533157
+v -0.227111 -0.600929 0.538115
+v -0.226867 -0.582843 0.540337
+v -0.226713 -0.564718 0.542508
+v -0.226983 -0.546028 0.548237
+v -0.226893 -0.527736 0.55168
+v -0.226919 -0.509547 0.553286
+v -0.226764 -0.491551 0.553889
+v -0.226752 -0.473388 0.555456
+v -0.22688 -0.455199 0.556651
+v -0.226957 -0.437164 0.556304
+v -0.226957 -0.419219 0.554801
+v -0.226739 -0.401171 0.55719
+v -0.226752 -0.382854 0.560453
+v -0.227124 -0.364126 0.565977
+v -0.226944 -0.346194 0.566465
+v -0.227137 -0.327838 0.568944
+v -0.226829 -0.309944 0.567916
+v -0.22688 -0.29146 0.570306
+v -0.226777 -0.273001 0.577897
+v -0.226739 -0.254131 0.587749
+v -0.226687 -0.23566 0.592207
+v -0.226559 -0.217638 0.591513
+v -0.22679 -0.19968 0.589818
+v -0.226675 -0.181889 0.586092
+v -0.226508 -0.164304 0.580697
+v -0.226713 -0.146501 0.57326
+v -0.226662 -0.129031 0.564898
+v -0.226906 -0.110971 0.55606
+v -0.226842 -0.0935651 0.546002
+v -0.226957 -0.0757616 0.536587
+v -0.22706 -0.058125 0.523908
+v -0.226906 -0.0405783 0.516946
+v -0.227291 -0.0224279 0.508455
+v -0.22697 -0.00481699 0.497909
+v -0.226996 0.0128453 0.483458
+v -0.226983 0.0305461 0.468982
+v -0.226919 0.0477845 0.455558
+v -0.226854 0.0651128 0.442199
+v -0.226803 0.0829806 0.430985
+v -0.568218 0.739658 -0.748457
+v 0.930802 -0.780853 0.125049
+v 0.933526 -0.780121 0.13792
+v 0.99702 -0.596343 0.227387
+v 0.883313 -0.821958 0.125229
+v 0.908747 -0.800301 0.125267
+v 0.887732 -0.821187 0.138074
+v 0.804405 -0.307632 0.0991657
+v -0.0556651 0.955266 -0.148928
+v -0.0638732 0.93691 -0.138228
+v -0.0554981 0.936872 -0.148466
+v -0.0352282 0.635149 -0.129018
+v 0.340227 -0.65836 0.696716
+v 0.353201 -0.658142 0.693441
+v 0.342886 -0.640531 0.697962
+v 0.838072 -0.703537 0.42026
+v 0.838252 -0.686029 0.420838
+v 0.351479 -0.143212 0.640479
+v 0.13284 -0.191228 0.723576
+v 0.197066 -0.600453 0.747917
+v -0.283361 -0.971117 0.52238
+v -0.296617 -0.971593 0.519965
+v 0.325481 -0.897604 0.602046
+v 0.33961 -0.896794 0.600235
+v -0.226764 0.784745 0.00973674
+v -0.226212 0.804257 0.0093
+v -0.213572 0.823563 -0.00309572
+v -0.0298974 -0.982396 -0.255172
+v -0.0352154 -0.975819 -0.23828
+v -0.0426657 -0.981907 -0.258165
+v -0.90375 -0.101876 0.102287
+v -0.889376 0.0025819 0.114182
+v -0.906666 0.0208351 0.114015
+v -0.900719 0.020347 0.10108
+v -0.360407 0.177753 0.329533
+v -0.365442 0.194645 0.327067
+v -0.37234 0.194529 0.33787
+v -0.213958 0.117856 0.404164
+v -0.370606 0.211755 0.325192
+v 0.0936101 0.246989 0.302931
+v 0.308306 0.25548 0.0313425
+v 0.413265 -0.97027 -0.155724
+v 0.399752 -0.970925 -0.157612
+v 0.408346 -0.972042 -0.179629
+v -0.211029 0.546644 -0.0307003
+v -0.213855 -0.765772 0.510986
+v -0.213572 -0.730923 0.50238
+v -0.213457 -0.748329 0.504319
+v -0.213714 -0.71267 0.503638
+v -0.213804 -0.694314 0.50658
+v -0.213945 -0.675753 0.511127
+v -0.213624 -0.657448 0.516766
+v -0.213881 -0.638925 0.519412
+v -0.213996 -0.620364 0.524101
+v -0.213714 -0.602162 0.5278
+v -0.214112 -0.583536 0.532078
+v -0.214022 -0.565077 0.537088
+v -0.214112 -0.54658 0.541776
+v -0.213919 -0.52834 0.545553
+v -0.213983 -0.510138 0.546978
+v -0.213945 -0.491962 0.548802
+v -0.21451 -0.473568 0.550716
+v -0.214035 -0.455636 0.551795
+v -0.214073 -0.437447 0.553298
+v -0.214035 -0.419515 0.551744
+v -0.214048 -0.401338 0.553247
+v -0.213919 -0.383381 0.553902
+v -0.213919 -0.364922 0.558758
+v -0.213958 -0.346913 0.558693
+v -0.213971 -0.328544 0.561596
+v -0.213958 -0.310445 0.563626
+v -0.213945 -0.291447 0.572695
+v -0.213855 -0.272307 0.583755
+v -0.213881 -0.253733 0.590164
+v -0.213855 -0.235583 0.591577
+v -0.213881 -0.217702 0.590781
+v -0.213906 -0.199603 0.591179
+v -0.213881 -0.181594 0.589625
+v -0.21424 -0.163533 0.585617
+v -0.213765 -0.146205 0.579477
+v -0.213726 -0.128774 0.571051
+v -0.214163 -0.110559 0.559682
+v -0.213893 -0.0934238 0.550627
+v -0.214138 -0.0755432 0.539914
+v -0.214099 -0.0580479 0.528404
+v -0.214176 -0.0401159 0.52062
+v -0.214189 -0.0223637 0.51096
+v -0.21406 -0.00488121 0.500812
+v -0.214099 0.0127939 0.4864
+v -0.214163 0.0305975 0.470613
+v -0.214048 0.0475918 0.458333
+v -0.214215 0.0661404 0.443458
+v -0.213996 0.0830192 0.432527
+v -0.213919 0.101041 0.41981
+v -0.0151125 -0.913198 0.695496
+v -0.0274568 -0.913686 0.700493
+v 0.145672 -0.510755 0.755727
+v 0.145672 -0.492026 0.76653
+v -0.170772 0.58974 -0.102364
+v -0.171388 0.576715 -0.0812208
+v 0.82673 -0.665412 0.42559
+v 0.826614 -0.647544 0.422174
+v 0.82655 -0.629908 0.415674
+v 0.849928 -0.668187 0.414993
+v 0.852395 -0.648366 0.413927
+v 0.839113 -0.667172 0.420067
+v 0.235679 -0.386053 0.754327
+v -0.661706 0.537768 -0.5743
+v -0.646356 0.545668 -0.592939
+v 0.340818 0.150059 0.473118
+v -0.226109 0.822767 -0.000166989
+v -0.625585 0.448314 -0.197381
+v -0.214125 0.841637 -0.020758
+v -0.909274 0.35444 0.0993841
+v -0.649529 0.390895 -0.084946
+v 0.837134 -0.523138 0.336277
+v 0.0110919 0.986134 -0.264832
+v 0.0059281 0.985928 -0.248004
+v 0.0106038 0.969589 -0.246283
+v -0.584005 0.417305 -0.0616831
+v 0.0846184 0.24135 0.318409
+v -0.669953 0.382494 -0.0816062
+v -0.676645 0.399206 -0.0889023
+v -0.663158 0.394864 -0.0871682
+v -0.2011 -0.749035 0.499785
+v -0.200817 -0.731141 0.497627
+v -0.200791 -0.71312 0.499117
+v -0.200997 -0.694789 0.501635
+v -0.201318 -0.676112 0.505668
+v -0.201164 -0.657666 0.511012
+v -0.201189 -0.639298 0.51421
+v -0.201164 -0.621109 0.515906
+v -0.201254 -0.602611 0.520594
+v -0.201408 -0.584037 0.525154
+v -0.201125 -0.565823 0.529072
+v -0.201177 -0.5473 0.533838
+v -0.200997 -0.529034 0.537383
+v -0.201382 -0.510613 0.539888
+v -0.2011 -0.492527 0.542251
+v -0.201241 -0.474287 0.543549
+v -0.201048 -0.456188 0.545784
+v -0.201228 -0.437678 0.54992
+v -0.201061 -0.419836 0.549201
+v -0.201125 -0.401608 0.54992
+v -0.201035 -0.383137 0.552219
+v -0.201035 -0.365063 0.554634
+v -0.201112 -0.347157 0.555418
+v -0.201048 -0.32875 0.558154
+v -0.201112 -0.310445 0.563703
+v -0.201022 -0.291087 0.577627
+v -0.2011 -0.272564 0.584744
+v -0.201061 -0.253913 0.588507
+v -0.201112 -0.235853 0.588816
+v -0.201061 -0.217651 0.590485
+v -0.200958 -0.199475 0.591719
+v -0.201074 -0.181363 0.592888
+v -0.200971 -0.163598 0.589304
+v -0.201177 -0.145691 0.583408
+v -0.20101 -0.128325 0.574801
+v -0.201164 -0.110585 0.563934
+v -0.201164 -0.0929743 0.554275
+v -0.201177 -0.0753762 0.544551
+v -0.201331 -0.0575469 0.533709
+v -0.201202 -0.0401544 0.524987
+v -0.201241 -0.022415 0.513825
+v -0.201202 -0.00480414 0.50238
+v -0.201254 0.0127939 0.48789
+v -0.201344 0.0307003 0.473747
+v -0.201305 0.0481956 0.460594
+v -0.201369 0.0662175 0.446503
+v -0.201189 0.0833788 0.432874
+v -0.2011 0.100617 0.417678
+v -0.391647 0.316675 0.174054
+v -0.395911 0.326502 0.179025
+v 0.805972 -0.289494 0.137535
+v 0.8047 -0.271473 0.137509
+v 0.69337 -0.479104 -0.144548
+v 0.677904 -0.480311 -0.158151
+v 0.689568 -0.461416 -0.144034
+v 0.886859 -0.802651 0.0614391
+v 0.892061 -0.802703 0.0739504
+v 0.921579 -0.764128 0.0608225
+v 0.91454 -0.78188 0.0741302
+v 0.786511 -0.327003 0.00933853
+v 0.788643 -0.327028 0.0220554
+v 0.826499 -0.612387 0.406194
+v 0.382462 -0.604692 0.687879
+v 0.387035 -0.586542 0.694661
+v 0.373522 -0.587248 0.697795
+v 0.274022 -0.0201543 0.558552
+v 0.274164 -0.227272 0.722073
+v 0.287176 -0.387427 0.736704
+v -0.0353053 0.981304 -0.190046
+v -0.0431409 0.975742 -0.174696
+v 0.351467 -0.0733338 0.595572
+v -0.350156 0.508725 -0.0420298
+v -0.218415 0.784861 -0.00132307
+v -0.201112 0.823088 -0.010957
+v -0.187124 0.86183 -0.033963
+v -0.183951 0.870513 -0.0424666
+v 0.805188 -0.438102 0.281453
+v 0.799562 -0.454685 0.296418
+v -0.706935 0.523202 -0.530601
+v 0.248101 0.176327 0.453092
+v 0.074933 0.234388 0.333734
+v 0.181934 -0.933352 0.193925
+v 0.176655 -0.927045 0.21047
+v 0.166148 -0.922382 0.20406
+v -0.310837 0.554403 -0.0798592
+v -0.322912 0.549779 -0.0748239
+v -0.323567 0.5543 -0.0781379
+v -0.649645 0.419116 -0.124471
+v -0.188062 -0.713312 0.495315
+v -0.187972 -0.731732 0.49421
+v -0.188254 -0.695188 0.496496
+v -0.18819 -0.676857 0.499952
+v -0.188819 -0.658296 0.504884
+v -0.18828 -0.639901 0.507865
+v -0.188241 -0.621571 0.511204
+v -0.18837 -0.603164 0.514236
+v -0.188139 -0.584936 0.517974
+v -0.188203 -0.566426 0.522714
+v -0.188408 -0.547826 0.527094
+v -0.18837 -0.529535 0.530498
+v -0.188306 -0.511243 0.533928
+v -0.188344 -0.492887 0.536972
+v -0.188575 -0.474377 0.539091
+v -0.188267 -0.456406 0.542059
+v -0.188254 -0.438102 0.545232
+v -0.188049 -0.419592 0.547505
+v -0.188485 -0.402032 0.548057
+v -0.188614 -0.383907 0.550138
+v -0.188408 -0.365359 0.554146
+v -0.18855 -0.34726 0.556227
+v -0.188164 -0.328544 0.561686
+v -0.188357 -0.310265 0.567235
+v -0.1881 -0.290818 0.580749
+v -0.188074 -0.272385 0.583703
+v -0.188241 -0.254157 0.587454
+v -0.188254 -0.236032 0.587827
+v -0.188216 -0.217599 0.590447
+v -0.188229 -0.199449 0.592721
+v -0.18819 -0.181247 0.595328
+v -0.188229 -0.163379 0.591192
+v -0.188151 -0.145846 0.58581
+v -0.18837 -0.127682 0.577435
+v -0.188318 -0.110303 0.567402
+v -0.188267 -0.0928073 0.558912
+v -0.188254 -0.0753248 0.549034
+v -0.188434 -0.0573543 0.538346
+v -0.18828 -0.040103 0.527993
+v -0.18846 -0.0220297 0.515829
+v -0.18837 -0.00468853 0.504049
+v -0.188254 0.01237 0.490421
+v -0.188485 0.0307131 0.475302
+v -0.188408 0.0480286 0.463471
+v -0.188473 0.0660377 0.449316
+v -0.188293 0.0829164 0.433799
+v -0.13686 0.611577 -0.124021
+v -0.1267 0.624333 -0.136289
+v -0.125621 0.609638 -0.11783
+v 0.672265 -0.589586 -0.157316
+v 0.682567 -0.570164 -0.156481
+v 0.685123 -0.588302 -0.14433
+v 0.865137 -0.578115 0.384627
+v 0.86515 -0.595559 0.394248
+v 0.797301 -0.217895 0.150239
+v -0.0226398 0.64599 -0.144946
+v -0.0114516 0.64405 -0.138729
+v 0.803056 -0.253489 0.137483
+v 0.801309 -0.23557 0.13747
+v -0.40638 0.325898 0.102171
+v -0.404222 0.326052 0.114914
+v -0.582579 0.599875 -0.206244
+v 0.404505 -0.516522 0.698116
+v 0.416695 -0.516175 0.693132
+v 0.40665 -0.498886 0.701456
+v 0.826434 -0.595251 0.396046
+v 0.826396 -0.57809 0.38455
+v -0.372289 0.464062 0.090341
+v -0.306174 -0.972004 0.473259
+v -0.547743 -0.866788 0.324138
+v -0.535424 -0.868111 0.311306
+v -0.216077 -0.653749 -0.13643
+v -0.939923 0.513452 0.188916
+v -0.340715 0.522482 -0.0529483
+v -0.327125 0.518205 -0.0507132
+v -0.188036 0.823011 -0.0247144
+v -0.187907 0.84278 -0.0240592
+v -0.175126 0.862266 -0.0362109
+v -0.175884 0.879916 -0.0528841
+v -0.573767 0.781135 -0.707146
+v 0.497376 -0.934277 -0.0270394
+v 0.489977 -0.936037 -0.0147592
+v 0.00216443 0.229417 0.270201
+v -0.00821457 0.221068 0.285307
+v 0.93016 -0.506991 0.0859607
+v 0.935941 -0.498205 0.107412
+v 0.94158 -0.51123 0.0907263
+v -0.175422 -0.713839 0.489945
+v -0.582785 0.762972 -0.769934
+v -0.573703 0.766684 -0.770744
+v -0.175332 -0.695817 0.490511
+v -0.175306 -0.67732 0.495225
+v -0.175499 -0.65872 0.499502
+v -0.175447 -0.640351 0.502881
+v -0.175525 -0.621789 0.507569
+v -0.175447 -0.603626 0.509432
+v -0.175383 -0.585335 0.512913
+v -0.175473 -0.566773 0.517486
+v -0.17546 -0.548456 0.520877
+v -0.175499 -0.52992 0.525565
+v -0.175422 -0.511654 0.529175
+v -0.175422 -0.493388 0.532566
+v -0.17537 -0.474711 0.53651
+v -0.175203 -0.456098 0.540813
+v -0.175576 -0.438371 0.544384
+v -0.176244 -0.420555 0.547634
+v -0.176437 -0.401865 0.553876
+v -0.176732 -0.383445 0.558937
+v -0.177528 -0.365526 0.559875
+v -0.177105 -0.346951 0.564063
+v -0.176193 -0.328287 0.569471
+v -0.175139 -0.309302 0.576189
+v -0.175075 -0.290766 0.582598
+v -0.175537 -0.27259 0.582881
+v -0.175229 -0.254273 0.585437
+v -0.175422 -0.236212 0.586439
+v -0.175358 -0.217702 0.588854
+v -0.175396 -0.199205 0.595881
+v -0.175383 -0.181093 0.597191
+v -0.175409 -0.163405 0.592335
+v -0.175409 -0.145743 0.584667
+v -0.175473 -0.127785 0.577281
+v -0.175422 -0.110405 0.568597
+v -0.175447 -0.0927944 0.558989
+v -0.17537 -0.0752991 0.550498
+v -0.175499 -0.0574442 0.539708
+v -0.175627 -0.0394864 0.528957
+v -0.175486 -0.0222352 0.518513
+v -0.175563 -0.00423895 0.504628
+v -0.175537 0.0129994 0.491166
+v -0.175563 0.0305076 0.476586
+v -0.175589 0.0483112 0.465321
+v -0.175537 0.0657294 0.450485
+v -0.175435 0.0999364 0.415468
+v 0.198184 -0.117355 0.590588
+v 0.793807 -0.217882 0.201697
+v 0.998921 -0.596176 0.188762
+v 0.999936 -0.596086 0.175878
+v 0.998626 -0.578372 0.188723
+v -0.381666 0.482534 0.121671
+v -0.396207 0.463844 0.123212
+v -0.388191 0.463561 0.11205
+v 0.764571 -0.11106 0.137432
+v 0.97088 -0.598629 0.072653
+v 0.963995 -0.599323 0.0600646
+v 0.967938 -0.581006 0.0725246
+v -0.394999 0.306296 0.115017
+v 0.324299 -0.19494 -0.34717
+v 0.312121 -0.192076 -0.350176
+v 0.826344 -0.560787 0.371769
+v 0.04264 -0.859427 0.671462
+v 0.440806 -0.108016 0.613235
+v 0.132865 -0.297022 0.753043
+v 0.132878 -0.279218 0.753081
+v 0.0172577 0.156058 0.436766
+v -0.415834 0.365564 0.217535
+v -0.409103 0.345693 0.230265
+v 0.145698 -0.35051 0.752182
+v 0.145672 -0.368056 0.75619
+v -0.17758 0.578103 0.0115479
+v -0.175049 0.842587 -0.0346951
+v 0.063642 0.689959 -0.196713
+v 0.0645669 0.686427 -0.182712
+v 0.324543 -0.207272 -0.359745
+v 0.312481 -0.204279 -0.362918
+v -0.0192615 0.211318 0.30022
+v -0.805163 -0.508301 0.142364
+v -0.797609 -0.515443 0.153591
+v 0.306495 0.273733 0.232256
+v 0.324594 0.273836 0.183906
+v -0.180226 -0.743345 0.496368
+v -0.175293 -0.731514 0.491846
+v -0.162602 -0.6961 0.487582
+v -0.162679 -0.71416 0.485976
+v -0.162589 -0.677538 0.491448
+v -0.162589 -0.659349 0.493439
+v -0.162577 -0.640865 0.498372
+v -0.162551 -0.622368 0.503394
+v -0.162538 -0.604179 0.505051
+v -0.162564 -0.585835 0.508378
+v -0.162564 -0.567056 0.514172
+v -0.162589 -0.548571 0.51904
+v -0.162615 -0.530395 0.522971
+v -0.162615 -0.511859 0.527775
+v -0.162525 -0.493285 0.532219
+v -0.162345 -0.47457 0.538359
+v -0.163206 -0.457036 0.542239
+v -0.164221 -0.439014 0.548199
+v -0.647332 0.615637 -0.687134
+v -0.633601 0.614956 -0.689022
+v -0.624673 0.609908 -0.680762
+v 0.0471744 -0.162866 0.674751
+v 0.0345089 -0.175274 0.689947
+v 0.0254658 0.691372 -0.204536
+v 0.038067 0.702098 -0.22031
+v 0.393638 0.247246 0.0807584
+v 0.405481 0.24356 0.0854469
+v 0.409001 0.238807 0.0684141
+v -0.163219 -0.381351 0.580286
+v -0.163823 -0.400555 0.569471
+v -0.657108 0.7403 -0.308364
+v -0.163206 -0.362764 0.586786
+v -0.161883 -0.343586 0.594326
+v 0.355937 0.263431 0.250329
+v 0.367343 0.259154 0.254517
+v 0.373304 0.259038 0.238409
+v -0.162063 -0.325795 0.592566
+v -0.161652 -0.308017 0.591128
+v -0.720255 -0.222262 0.547839
+v -0.162538 -0.272372 0.588173
+v -0.161125 -0.290098 0.591128
+v -0.162512 -0.254337 0.586362
+v -0.162499 -0.236174 0.586144
+v -0.162525 -0.217792 0.589368
+v -0.162487 -0.198961 0.598475
+v -0.162564 -0.180965 0.59764
+v -0.162641 -0.163649 0.591462
+v -0.162718 -0.145987 0.581198
+v -0.162615 -0.128029 0.575405
+v -0.162461 -0.110688 0.567981
+v -0.162512 -0.0929357 0.560132
+v -0.162564 -0.0751707 0.550729
+v -0.162577 -0.0575212 0.541057
+v -0.162564 -0.0399874 0.531153
+v -0.162769 -0.0218113 0.519156
+v -0.162705 -0.00452154 0.505758
+v -0.162577 0.0125113 0.492103
+v -0.162679 0.0303663 0.477922
+v -0.162679 0.0481699 0.466683
+v -0.162679 0.065845 0.452116
+v -0.431287 0.44419 0.178729
+v -0.427331 0.444345 0.165948
+v -0.432893 0.464409 0.180656
+v 0.914643 -0.728521 0.0226848
+v 0.920064 -0.710512 0.0220939
+v 0.742837 -0.0763268 0.227259
+v 0.726164 -0.059448 0.0350677
+v -0.387138 0.296855 0.127348
+v 0.962325 -0.581661 0.0601545
+v 0.965857 -0.563395 0.07282
+v 0.959242 -0.564076 0.0601417
+v -0.936775 -0.238434 0.2181
+v -0.609233 0.782137 -0.763614
+v -0.596208 0.782035 -0.769613
+v -0.609516 0.762163 -0.760981
+v -0.267869 -0.55958 -0.172243
+v -0.255011 -0.559554 -0.172268
+v 0.306945 0.0452026 0.536304
+v 0.312455 0.0509445 0.532206
+v 0.29952 0.0510729 0.536766
+v -0.163129 -0.4162 0.561892
+v 0.299379 0.0332179 0.542971
+v 0.705778 -0.910475 0.0370715
+v -0.168254 0.841945 -0.0412206
+v -0.180033 0.822895 -0.0360054
+v -0.16232 0.861997 -0.0452411
+v -0.949415 0.33814 0.266373
+v -0.158325 -0.435045 0.557833
+v 0.715939 -0.0229931 0.24022
+v 0.71626 -0.0227876 0.2274
+v 0.704995 -0.00580607 0.233027
+v -0.16372 -0.820275 0.647403
+v -0.149384 -0.824514 0.662304
+v -0.162345 -0.841958 0.667133
+v -0.173225 -0.836923 0.657268
+v -0.136423 -0.807353 0.655881
+v -0.524621 -0.851168 0.324023
+v -0.51229 -0.852478 0.311203
+v 0.312558 0.274131 0.216161
+v 0.318595 0.274119 0.200027
+v -0.622772 -0.974367 0.204908
+v -0.626317 -0.965684 0.219051
+v -0.634449 -0.971785 0.200207
+v -0.149783 -0.677705 0.49001
+v -0.149937 -0.696087 0.487518
+v -0.149834 -0.659567 0.492026
+v -0.14968 -0.640916 0.49624
+v -0.149808 -0.622637 0.49999
+v -0.149757 -0.60423 0.502983
+v -0.149834 -0.585848 0.508455
+v -0.149616 -0.566979 0.513889
+v -0.149693 -0.548584 0.519168
+v -0.149641 -0.529946 0.525617
+v -0.149757 -0.511525 0.530793
+v -0.150104 -0.493311 0.53642
+v -0.150797 -0.47507 0.543767
+v -0.152737 -0.457742 0.549239
+v 0.389116 0.24153 0.0430317
+v 0.385674 0.246437 0.0600389
+v 0.401075 0.238216 0.0473349
+v -0.586882 0.519759 -0.231742
+v -0.594654 0.86165 -0.709266
+v 0.225133 0.187284 0.443754
+v 0.211286 0.172988 0.45841
+v 0.223309 0.169262 0.462456
+v 0.236424 0.182647 0.447941
+v 0.389553 0.250933 0.0978169
+v 0.401332 0.247015 0.102287
+v 0.39762 0.243136 0.0643421
+v 0.745599 -0.814597 0.420953
+v 0.753383 -0.794957 0.431435
+v -0.975851 0.0757744 0.280644
+v -0.841155 0.567891 0.299424
+v -0.850288 0.562457 0.315326
+v 0.361409 0.262571 0.234016
+v 0.372237 0.260348 0.201363
+v 0.366881 0.26171 0.217715
+v 0.383503 0.25566 0.205499
+v 0.397247 0.250766 0.119037
+v 0.392597 0.253489 0.135569
+v 0.40868 0.246309 0.123405
+v 0.404389 0.249558 0.139962
+v 0.00437382 -0.209674 0.715868
+v -0.0106809 -0.215762 0.712079
+v -0.00817603 -0.227554 0.722972
+v -0.93508 -0.238691 0.179616
+v -0.149063 -0.253926 0.595829
+v -0.0722355 -0.427864 0.707416
+v -0.080084 -0.409187 0.714597
+v -0.0826659 -0.428224 0.699658
+v -0.149641 -0.235955 0.589805
+v -0.149654 -0.217702 0.591166
+v -0.149718 -0.198987 0.599105
+v -0.14977 -0.181234 0.595341
+v -0.14977 -0.16388 0.585656
+v -0.149654 -0.146334 0.577383
+v -0.149628 -0.128427 0.574249
+v -0.149667 -0.11047 0.569817
+v -0.14959 -0.0927559 0.563433
+v -0.149718 -0.0750679 0.553825
+v -0.149706 -0.0575084 0.54256
+v -0.149847 -0.0396277 0.531693
+v -0.149744 -0.0222609 0.521481
+v -0.149821 -0.00453439 0.508764
+v -0.149937 0.013282 0.49457
+v -0.14995 0.03097 0.480144
+v -0.149795 0.0481442 0.468134
+v -0.149873 0.066179 0.452463
+v 0.0950488 0.744783 -0.233784
+v 0.0884206 0.765323 -0.234658
+v 0.08905 0.744693 -0.221235
+v -0.149834 0.100656 0.417665
+v -0.137104 0.100951 0.421107
+v -0.501474 -0.835484 0.323933
+v -0.487614 -0.836961 0.311075
+v 0.978895 -0.615816 0.0854212
+v 0.984598 -0.61529 0.098562
+v 0.984046 -0.632181 0.0984849
+v 0.979345 -0.633607 0.085935
+v -0.257234 -0.076057 -0.243829
+v -0.409193 0.325962 0.0892363
+v -0.41464 0.345628 0.0891977
+v -0.412559 0.34577 0.102005
+v -0.584146 0.620132 -0.231819
+v -0.587807 0.6403 -0.244677
+v -0.580742 0.700043 -0.681443
+v -0.899717 -0.0661533 0.268338
+v 0.869145 -0.840866 0.150996
+v 0.869466 -0.841264 0.163816
+v -0.00393708 0.727352 -0.232204
+v -0.00389855 0.746761 -0.246514
+v 0.0089339 0.727532 -0.236996
+v 0.440883 -0.143276 0.623061
+v 0.440883 -0.125421 0.619978
+v 0.440934 0.0312783 0.506336
+v 0.440985 0.0136289 0.517588
+v 0.267779 -0.918965 0.609137
+v 0.26101 -0.901856 0.610331
+v 0.253573 -0.901971 0.611565
+v -0.149924 0.899903 -0.0692618
+v -0.136154 0.901098 -0.0721906
+v -0.146263 0.910102 -0.0827623
+v -0.162371 0.896666 -0.0735522
+v 0.452122 -0.822061 -0.272128
+v 0.464711 -0.82287 -0.26207
+v 0.452456 -0.840622 -0.27241
+v 0.790442 -0.308801 0.00914585
+v 0.837083 -0.76847 -0.0290818
+v 0.850262 -0.751232 -0.0280413
+v -0.604095 0.780878 -0.591706
+v -0.577788 0.697949 -0.73389
+v 0.809093 -0.421608 0.26496
+v 0.80962 -0.405732 0.242301
+v 0.808734 -0.40419 0.264793
+v -0.625778 0.624924 -0.698502
+v -0.0135711 0.687634 -0.195518
+v 5.78038e-05 0.683884 -0.192628
+v -0.62344 0.505629 -0.390163
+v -0.607795 0.521506 -0.388609
+v -0.136436 -0.824231 0.66662
+v -0.149243 -0.841842 0.671154
+v -0.136668 -0.84147 0.67186
+v -0.124118 -0.774571 0.612143
+v -0.141549 -0.788534 0.624166
+v -0.499406 -0.682766 0.161774
+v -0.674757 0.457344 -0.281941
+v -0.635052 0.751835 -0.392257
+v -0.785509 0.580184 0.168248
+v -0.137079 -0.695329 0.495135
+v -0.137143 -0.677178 0.496933
+v -0.13713 -0.658964 0.498565
+v -0.136822 -0.640505 0.501224
+v -0.136693 -0.622098 0.504281
+v -0.136912 -0.603806 0.507877
+v -0.136745 -0.585116 0.514146
+v -0.137284 -0.567043 0.518372
+v -0.137798 -0.548802 0.52405
+v -0.137631 -0.52992 0.531757
+v -0.137824 -0.509856 0.538963
+v -0.791238 0.787648 -0.480286
+v -0.785522 0.788046 -0.467723
+v -0.779844 0.80391 -0.488134
+v -0.113559 -0.562239 0.553568
+v -0.117657 -0.544075 0.556844
+v -0.123694 -0.545643 0.544114
+v -0.1388 -0.493247 0.545848
+v 0.349553 0.266206 0.229687
+v 0.337619 0.269469 0.225319
+v 0.343541 0.266116 0.245795
+v -0.928696 0.248544 0.0740917
+v -0.937148 0.248698 0.0871425
+v -0.696311 0.722137 -0.230419
+v 0.307998 0.255339 0.324845
+v 0.29997 0.251537 0.340542
+v 0.311877 0.248056 0.344909
+v 0.320574 0.253104 0.329418
+v 0.360368 0.263958 0.196995
+v 0.355474 0.265923 0.213566
+v -0.989287 0.214799 0.228569
+v -0.991162 0.197278 0.228582
+v -0.958227 0.302802 0.227978
+v -0.679458 0.731475 -0.26135
+v -0.687551 0.727378 -0.245795
+v 0.2946 0.222082 0.394132
+v 0.282577 0.225486 0.389726
+v 0.283592 0.21259 0.40893
+v 0.270901 0.215005 0.404601
+v 0.378737 0.257959 0.22207
+v 0.38787 0.255955 0.15214
+v 0.399174 0.25137 0.15625
+v -0.949261 0.320349 0.227978
+v -0.861129 0.554904 0.331049
+v -0.658482 0.54852 -0.598835
+v -0.634962 0.569329 -0.0026076
+v -0.137323 -0.235287 0.596921
+v -0.136899 -0.217458 0.59475
+v -0.136757 -0.199089 0.599028
+v -0.136899 -0.181671 0.589085
+v -0.136873 -0.164189 0.579606
+v -0.136963 -0.145833 0.579272
+v -0.136873 -0.127939 0.578347
+v -0.136809 -0.110046 0.574956
+v -0.136873 -0.0923705 0.566812
+v -0.136989 -0.0746954 0.554454
+v -0.136719 -0.0576497 0.545321
+v -0.13704 -0.0393837 0.535032
+v -0.136796 -0.0223251 0.524422
+v -0.137181 -0.00395635 0.510986
+v -0.137104 0.013372 0.497691
+v -0.137027 0.0307516 0.482893
+v -0.136937 0.0480671 0.469598
+v -0.136963 0.0656009 0.4534
+v -0.137143 0.0835972 0.436072
+v -0.124452 0.101555 0.424884
+v 0.689786 -0.551706 -0.157072
+v 0.691533 -0.533517 -0.157201
+v 0.701578 -0.550768 -0.144574
+v 0.977148 -0.598077 0.085524
+v 0.981811 -0.597884 0.0985748
+v 0.927193 -0.691745 0.0224664
+v -0.418699 0.36523 0.089262
+v -0.416618 0.365397 0.101966
+v 0.976827 -0.70522 0.17607
+v 0.187625 0.101362 -0.174529
+v 0.187792 0.0892491 -0.187272
+v 0.1732 0.0870397 -0.18478
+v -0.179751 -0.00301864 -0.216251
+v -0.192943 -0.0024663 -0.216392
+v -0.190618 0.015607 -0.21056
+v 0.0883949 0.0429804 -0.214337
+v 0.0898207 0.0321518 -0.228711
+v 0.0349713 0.0699812 -0.191549
+v 0.0213039 0.0698527 -0.191318
+v 0.0225371 0.08519 -0.181954
+v 0.312481 -0.884424 0.603896
+v -0.618546 0.288184 -0.0870012
+v -0.61861 0.307028 -0.0839826
+v 0.196899 -0.0372128 0.579169
+v 0.184054 -0.0370715 0.582187
+v 0.197747 -0.0447916 0.581224
+v 0.455141 0.083944 0.481223
+v 0.441268 0.103186 0.473131
+v 0.797995 -0.757847 0.429508
+v 0.0753698 0.0696087 -0.191421
+v 0.0622162 0.0704436 -0.192268
+v 0.0635007 0.0854084 -0.182455
+v -0.586754 0.519824 -0.218858
+v 0.0732632 0.785541 -0.234542
+v 0.0865067 0.783191 -0.2474
+v 0.076179 0.804295 -0.252808
+v 0.700884 -0.693376 0.424254
+v -0.600665 0.532926 0.479065
+v -0.123976 -0.84075 0.676844
+v -0.136308 -0.858605 0.686555
+v -0.123398 -0.824206 0.669266
+v -0.123784 -0.806518 0.660891
+v -0.123745 -0.790423 0.643806
+v -0.371069 0.533375 -0.0528712
+v -0.356027 0.527621 -0.0533465
+v -0.364633 0.513362 -0.0433914
+v -0.145698 -0.773017 0.591616
+v -0.123835 -0.761097 0.571012
+v -0.647063 0.751617 -0.359835
+v -0.640974 0.751835 -0.37602
+v -0.797263 0.581147 0.20162
+v 0.341923 0.269738 0.171921
+v 0.336515 0.270753 0.188274
+v -0.132544 -0.672837 0.502765
+v -0.125608 -0.658077 0.511102
+v -0.0888959 0.59809 -0.0483882
+v -0.0905401 0.597859 -0.0579323
+v -0.0842202 0.600248 -0.0538475
+v -0.125184 -0.639529 0.515507
+v -0.118646 -0.636073 0.524448
+v -0.634346 0.447941 -0.207374
+v -0.642246 0.446901 -0.218588
+v -0.669401 0.440594 -0.203945
+v -0.125428 -0.566272 0.530421
+v -0.119699 -0.563009 0.541404
+v -0.700396 0.593067 0.254144
+v -0.237991 0.163315 0.354916
+v -0.247818 0.156173 0.370433
+v -0.227253 0.157599 0.359065
+v -0.595078 0.539682 -0.382289
+v -0.58845 0.555277 -0.389662
+v -0.584146 0.559002 -0.3734
+v 0.258274 0.217381 0.400208
+v 0.246893 0.221671 0.395789
+v 0.248589 0.209777 0.415057
+v 0.237285 0.214131 0.410638
+v 0.226251 0.204587 0.425462
+v 0.238261 0.200978 0.429637
+v 0.331595 0.26934 0.241427
+v 0.337478 0.265898 0.261916
+v 0.324928 0.26821 0.25733
+v -0.979011 0.129147 0.537306
+v -0.9814 0.129172 0.524371
+v -0.979075 0.111728 0.524551
+v -0.961284 0.161221 0.113424
+v -0.968889 0.161414 0.126089
+v -0.961515 0.178537 0.113218
+v -0.475334 -0.820082 0.323868
+v -0.467588 -0.820917 0.310998
+v 0.303759 0.243778 0.360401
+v 0.291261 0.246103 0.355905
+v 0.377594 0.259013 0.185024
+v 0.366252 0.263586 0.180913
+v -0.851701 -0.435109 0.142056
+v -0.839806 -0.453645 0.142172
+v -0.977508 0.163033 0.537473
+v -0.640293 0.570665 0.0141812
+v -0.630004 0.563857 0.0182275
+v -0.142461 0.197201 0.105344
+v 0.261575 0.193142 0.43832
+v 0.249552 0.1967 0.434094
+v 0.261267 0.207195 0.419296
+v 0.273239 0.203855 0.423625
+v 0.293624 0.235364 0.375185
+v 0.382938 0.257857 0.168697
+v 0.394319 0.253322 0.172821
+v -0.909685 0.529457 0.163816
+v -0.918008 0.530292 0.176237
+v -0.904726 0.533851 0.164934
+v 0.724674 -0.640415 0.414094
+v 0.714462 -0.657692 0.421878
+v -0.631738 0.743011 -0.372681
+v -0.643916 0.742625 -0.340323
+v -0.637788 0.742882 -0.35647
+v 0.788104 -0.470549 0.325076
+v 0.793576 -0.471307 0.31024
+v 0.793987 -0.453863 0.311242
+v -0.671584 0.828419 -0.553401
+v 0.379174 0.25539 0.258884
+v 0.384659 0.254568 0.242583
+v -0.124156 -0.198935 0.59344
+v -0.125723 -0.216957 0.600004
+v -0.124053 -0.182095 0.581956
+v -0.124002 -0.164022 0.581365
+v -0.124002 -0.145627 0.584769
+v -0.123951 -0.127554 0.584667
+v -0.123848 -0.110033 0.57773
+v -0.123938 -0.0923705 0.568392
+v -0.124053 -0.0745541 0.557653
+v -0.123861 -0.0573799 0.548623
+v -0.124439 -0.0383304 0.539503
+v -0.124118 -0.0216315 0.529907
+v -0.12431 -0.00390497 0.515662
+v -0.12431 0.0135775 0.500954
+v -0.124053 0.0303791 0.485552
+v -0.124053 0.0479772 0.471011
+v -0.124285 0.0659349 0.452193
+v -0.124246 0.0833018 0.437357
+v -0.317696 0.531731 -0.0619015
+v -0.304055 0.527993 -0.0590884
+v -0.463156 -0.803178 0.323727
+v -0.458455 -0.80373 0.310856
+v -0.687602 0.4357 -0.179063
+v -0.696851 0.428198 -0.145948
+v 0.332199 -0.640582 0.70513
+v 0.122268 -0.127541 -0.290689
+v 0.108626 -0.127502 -0.290805
+v 0.112852 -0.106333 -0.287157
+v 0.0771553 0.0854212 -0.182545
+v 0.197118 0.0698784 0.54414
+v 0.197118 0.0873352 0.533953
+v 0.287073 -0.24505 0.723807
+v 0.103462 0.00667955 -0.253091
+v 0.0887931 0.00172127 -0.250573
+v 0.0889986 0.0180733 -0.239436
+v -0.235075 0.72626 -0.171382
+v -0.234459 0.745194 -0.171883
+v -0.222281 0.726325 -0.176456
+v -0.612265 0.544628 -0.445321
+v -0.11239 0.932684 -0.115248
+v -0.12169 0.931348 -0.115877
+v -0.110296 0.920789 -0.0948754
+v -0.638302 0.571783 0.052229
+v -0.642528 0.575315 0.0694674
+v -0.625649 0.56992 0.0568019
+v -0.121883 -0.856293 0.696511
+v -0.139994 -0.871181 0.698001
+v -0.128536 -0.871399 0.704667
+v -0.110797 -0.823242 0.674648
+v -0.110926 -0.839915 0.687082
+v -0.110489 -0.806505 0.66608
+v -0.111157 -0.789485 0.648765
+v -0.111105 -0.774456 0.618373
+v -0.110836 -0.760634 0.577332
+v -0.620434 0.470382 0.524204
+v -0.636555 0.489688 0.525565
+v -0.115087 -0.871798 0.709947
+v -0.110977 -0.85628 0.702599
+v 0.331107 0.271768 0.204587
+v -0.255448 -0.48333 -0.211485
+v -0.242616 -0.483163 -0.213129
+v -0.242526 -0.502058 -0.20496
+v 0.687191 -0.171022 -0.119166
+v 0.675695 -0.171832 -0.131947
+v 0.674988 -0.154208 -0.132268
+v -0.979049 0.161709 0.15178
+v -0.267934 -0.540826 -0.178768
+v -0.255101 -0.540453 -0.182082
+v -0.949775 0.514647 0.26541
+v -0.934271 0.531012 0.265191
+v -0.951124 0.514506 0.252603
+v -0.477864 0.494814 -0.00818245
+v -0.465122 0.494749 -0.0119718
+v 0.199995 0.177329 0.453979
+v 0.278531 0.248158 0.351293
+v 0.268936 0.240862 0.366258
+v 0.25794 0.231511 0.381146
+v 0.303502 0.261312 0.304639
+v 0.318249 0.266938 0.273258
+v 0.310863 0.264151 0.288942
+v 0.822427 -0.524974 0.330959
+v -0.856017 -0.434492 0.0905465
+v -0.923532 -0.187451 0.115235
+v -0.522874 -0.674776 0.119217
+v -0.510992 -0.692593 0.10519
+v -0.507139 -0.692618 0.117868
+v -0.804353 0.580132 0.217946
+v -0.810596 0.579785 0.234607
+v -0.481885 0.622599 0.127297
+v 0.281614 0.238627 0.370741
+v 0.269938 0.227876 0.385333
+v 0.295448 0.257895 0.320323
+v 0.330182 0.263714 0.27769
+v -0.857597 0.299424 -0.00202956
+v -0.867771 0.281646 -0.00151575
+v -0.87129 0.299719 0.0108928
+v -0.97481 0.196584 0.151587
+v -0.971638 0.196405 0.138858
+v -0.595437 0.680531 -0.3218
+v -0.584288 0.66048 -0.321775
+v 0.371197 0.2618 0.164343
+v 0.375937 0.259359 0.147759
+v -0.174227 0.894688 -0.113732
+v -0.822247 -0.489534 0.1423
+v -0.832947 -0.471153 0.142236
+v -0.67197 0.734456 -0.276996
+v 0.120123 -0.158254 0.688906
+v 0.13293 -0.157959 0.690576
+v 0.127881 -0.152936 0.683139
+v 0.305583 0.231999 0.379604
+v 0.388898 0.254568 0.189173
+v -0.457376 -0.785657 0.323496
+v -0.452765 -0.786222 0.310664
+v -0.650839 0.740827 -0.324421
+v -0.741784 0.590293 0.277073
+v -0.756659 0.588469 0.271922
+v -0.748746 0.588854 0.293425
+v -0.550967 0.572117 0.363342
+v -0.557865 0.570562 0.379566
+v -0.545148 0.568546 0.384049
+v 0.361293 0.258987 0.270663
+v 0.372546 0.25426 0.274799
+v -0.119917 -0.218447 0.603716
+v -0.126623 -0.236148 0.61082
+v 0.39008 0.253386 0.226206
+v -0.663479 -0.255609 0.570061
+v -0.111015 -0.145293 0.590652
+v -0.111041 -0.127413 0.587582
+v -0.111105 -0.109853 0.579657
+v -0.111272 -0.0918696 0.572219
+v -0.111388 -0.0739889 0.564448
+v -0.1109 -0.0569175 0.553953
+v -0.111208 -0.0391525 0.544255
+v -0.111439 -0.0211048 0.535174
+v -0.111529 -0.00349392 0.522226
+v -0.111491 0.0138601 0.507441
+v -0.111337 0.0310085 0.49087
+v -0.111581 0.0489149 0.473516
+v -0.111491 0.0660248 0.455391
+v -0.111542 0.0838027 0.442508
+v -0.111478 0.101337 0.430754
+v 0.70461 -0.532373 -0.144394
+v -0.0823833 0.917886 -0.119885
+v -0.0976821 0.920777 -0.103713
+v 0.983571 -0.561763 0.124111
+v 0.979807 -0.562226 0.111433
+v 0.980218 -0.544217 0.124175
+v 0.975555 -0.544628 0.111292
+v 0.969916 -0.527646 0.111703
+v 0.973783 -0.52694 0.12424
+v -0.952023 0.373516 0.26618
+v 0.324761 -0.00515096 0.537704
+v -0.573446 0.719966 -0.720493
+v -0.594936 0.599888 -0.167567
+v -0.596272 0.606722 -0.175004
+v -0.601654 0.607955 -0.15837
+v 0.871008 -0.819324 0.299784
+v 0.882337 -0.818477 0.279103
+v 0.783659 -0.164394 0.0989859
+v 0.800692 -0.289841 0.214504
+v 0.799523 -0.289931 0.227387
+v 0.801373 -0.30776 0.227413
+v -0.110348 0.899942 -0.0920879
+v -0.123437 0.918619 -0.0898785
+v 0.311351 0.0102377 0.542226
+v -0.0990437 0.937617 -0.114156
+v -0.0969756 0.942382 -0.122236
+v -0.310683 0.801765 -0.0165062
+v -0.31708 0.801534 -0.0282083
+v -0.338621 0.782664 -0.00621712
+v -0.0981702 -0.838862 0.696459
+v -0.0982087 -0.822202 0.682689
+v -0.0979004 -0.805657 0.671321
+v -0.0981188 -0.7896 0.652926
+v -0.0983886 -0.773955 0.618681
+v -0.09835 -0.760249 0.574557
+v -0.0977334 -0.744603 0.551166
+v -0.0846312 -0.743306 0.563986
+v -0.0922228 -0.72468 0.555264
+v -0.0985427 -0.725965 0.545283
+v -0.791816 0.580338 0.184792
+v -0.536041 0.580595 0.293926
+v -0.548668 0.583035 0.289392
+v 0.325095 0.271884 0.220721
+v 0.351454 0.265024 0.138793
+v -0.823647 -0.488995 0.193746
+v -0.170476 0.688469 -0.17923
+v -0.708322 0.778155 -0.363946
+v -0.868914 -0.415545 0.142018
+v 0.287548 0.254119 0.336097
+v 0.323824 -0.221825 -0.370458
+v 0.312545 -0.217098 -0.375417
+v -0.840937 -0.453593 0.0907006
+v -0.968902 0.178742 0.126
+v -0.966076 0.19634 0.125922
+v -0.962941 0.213874 0.125948
+v -0.95711 0.213733 0.113141
+v -0.96018 0.196148 0.113077
+v 0.322796 0.260991 0.293412
+v -0.961348 0.479425 0.27846
+v -0.960514 0.461788 0.27855
+v 0.385314 0.254106 0.114657
+v -0.904572 0.354273 0.0865902
+v -0.218145 -0.239244 -0.29092
+v -0.664442 0.737628 -0.29259
+v 0.315692 0.240117 0.364729
+v 0.354588 0.257612 0.286579
+v 0.342706 0.261158 0.282211
+v 0.347857 0.256084 0.30243
+v -0.838355 0.00065511 0.397575
+v -0.834617 -0.0158254 0.384036
+v -0.827372 -0.0173668 0.396367
+v -0.234716 0.668816 -0.159937
+v -0.221575 0.650036 -0.154259
+v -0.173829 0.200708 0.112563
+v -0.178659 0.2032 0.129532
+v 0.365892 0.25295 0.29074
+v 0.416901 0.239102 0.0895446
+v 0.395231 0.251601 0.209892
+v -0.961952 0.0579066 0.165409
+v -0.111221 -0.200451 0.593132
+v -0.475347 0.354402 -0.00200387
+v -0.48543 0.363406 -0.0112396
+v -0.0982473 -0.127297 0.589291
+v -0.0981573 -0.145126 0.593787
+v -0.0982729 -0.109596 0.582958
+v -0.0982858 -0.0918439 0.576638
+v -0.0981445 -0.0743743 0.568096
+v -0.0983372 -0.0564679 0.55895
+v -0.0981573 -0.0392038 0.548584
+v -0.0985042 -0.0210534 0.538205
+v -0.0985042 -0.003404 0.528417
+v -0.0985812 0.0141812 0.515469
+v -0.0987868 0.031882 0.499477
+v -0.0990437 0.0495957 0.480376
+v -0.0992363 0.0672965 0.46446
+v -0.0990694 0.0845863 0.451127
+v -0.0988253 0.101838 0.437562
+v -0.0985812 0.11905 0.420812
+v -0.626664 0.584667 -0.637949
+v -0.618906 0.59922 -0.647557
+v -0.615232 0.603652 -0.631603
+v -0.981708 0.129082 0.511577
+v -0.981593 0.146359 0.511448
+v -0.45306 -0.76802 0.323342
+v -0.449874 -0.768431 0.310497
+v 0.771392 -0.311987 0.371576
+v 0.777378 -0.311062 0.356303
+v 0.769427 -0.294941 0.368866
+v 0.184041 -0.0548751 0.586696
+v 0.441101 0.120476 0.461082
+v 0.453998 0.102827 0.471076
+v 0.457016 0.117265 0.460298
+v -0.451429 -0.750217 0.323316
+v -0.448282 -0.750615 0.310458
+v 0.755104 -0.0933339 0.0860635
+v 0.232082 0.145023 0.485116
+v 0.990944 -0.579002 0.137124
+v 0.0458128 0.671064 -0.170586
+v -0.113161 0.880044 -0.0969563
+v -0.307626 -0.334761 -0.253194
+v -0.294729 -0.334209 -0.257407
+v -0.2946 -0.352912 -0.250766
+v -0.0853249 -0.838438 0.700917
+v -0.0984014 -0.855638 0.706157
+v -0.0853891 -0.82147 0.690293
+v -0.0854277 -0.804861 0.675046
+v -0.0853891 -0.789369 0.653132
+v -0.0855047 -0.774006 0.621738
+v -0.0853377 -0.759851 0.579272
+v 0.0302186 -0.109583 0.581455
+v 0.0296791 -0.126 0.590293
+v 0.0458898 -0.116211 0.581185
+v -0.58511 0.568122 0.407324
+v -0.597827 0.570139 0.402816
+v -0.593421 0.563844 0.423214
+v -0.213071 0.190496 0.287491
+v 0.319058 0.27155 0.236842
+v 0.345853 0.166796 0.45737
+v 0.351531 0.169558 0.45227
+v 0.356245 0.262725 0.122223
+v 0.383374 0.166578 0.444871
+v 0.378519 0.15011 0.459476
+v -0.823364 -0.488802 0.206565
+v -0.596131 0.74084 -0.540196
+v -0.593767 0.741045 -0.55299
+v 0.213829 0.191909 0.439553
+v -0.683004 0.847944 -0.576099
+v -0.690737 0.844565 -0.560646
+v -0.67328 0.840121 -0.572631
+v 0.354331 0.266951 0.176546
+v 0.363927 0.262532 0.143431
+v -0.595039 0.499682 -0.257009
+v -0.702079 0.592541 0.216174
+v -0.708296 0.592656 0.232693
+v -0.694192 0.593055 0.237625
+v -0.926589 -0.169879 0.127913
+v -0.923725 -0.170059 0.115094
+v 0.422694 -0.966416 -0.180142
+v 0.416746 -0.962755 -0.204459
+v 0.428384 -0.960147 -0.193977
+v -0.50683 -0.710576 0.105588
+v 0.316078 0.259244 0.309263
+v -0.121613 0.199333 0.0942459
+v -0.106198 0.202532 0.0999236
+v 0.399341 0.228788 0.0208993
+v 0.403426 0.231254 0.0297112
+v 0.411441 0.225756 0.0240079
+v -0.651302 0.536343 -0.566824
+v 0.380613 0.256752 0.131228
+v -0.868207 -0.416329 0.103456
+v -0.877931 -0.398577 0.103251
+v 0.795991 -0.480543 0.301954
+v -0.898548 0.37191 0.0865002
+v -0.12932 0.640312 -0.152422
+v -0.138697 0.626902 -0.141337
+v -0.66258 0.819235 -0.55019
+v -0.735541 0.590434 0.260567
+v -0.749735 0.590126 0.255634
+v 0.335924 0.259436 0.298062
+v 0.328628 0.256932 0.313772
+v 0.339919 0.252461 0.317985
+v 0.349386 0.262481 0.266283
+v -0.913949 0.336817 0.0866287
+v -0.742696 0.591089 0.239282
+v -0.684918 0.874379 -0.6138
+v -0.675207 0.866634 -0.610344
+v -0.597685 0.599349 -0.155004
+v -0.933025 0.391936 0.433054
+v 0.359161 0.251524 0.306669
+v 0.400176 0.249803 0.193771
+v -0.894142 -0.0318692 0.165627
+v -0.890956 -0.0144381 0.165576
+v -0.217593 0.164266 0.343226
+v -0.228177 0.170431 0.339321
+v -0.00163778 0.983783 -0.232885
+v 0.709465 -0.912774 0.0478744
+v 0.717378 -0.909062 0.0463844
+v 0.72777 -0.910038 0.0618244
+v -0.0855176 -0.144921 0.59493
+v -0.0854919 -0.127143 0.589818
+v -0.0855176 -0.109339 0.584923
+v -0.0854277 -0.0918182 0.577936
+v -0.0853891 -0.0741559 0.569907
+v -0.085569 -0.0561982 0.56089
+v -0.0854277 -0.0388185 0.552181
+v -0.0856332 -0.0209507 0.541365
+v -0.0855561 -0.00337831 0.531461
+v -0.0859286 0.0148235 0.520864
+v -0.0860442 0.0324472 0.507839
+v -0.0861341 0.0498654 0.489945
+v -0.086391 0.0675791 0.474043
+v -0.0862112 0.0849203 0.460697
+v -0.0859928 0.10221 0.445668
+v -0.086147 0.120039 0.426348
+v 0.531018 -0.913198 0.447697
+v 0.523671 -0.922691 0.440183
+v 0.542849 -0.908407 0.431975
+v -0.0854277 0.13607 0.405667
+v 0.0354594 0.717692 -0.236829
+v 0.0506297 0.712747 -0.236186
+v 0.683723 -0.497974 -0.157535
+v -0.699677 0.696588 -0.176327
+v -0.702426 0.705811 -0.195261
+v -0.412225 0.345847 0.243174
+v -0.0985812 0.616446 -0.00913301
+v -0.0865067 0.611526 -0.0238923
+v -0.0859286 0.629959 -0.00947983
+v -0.927 0.0777911 0.599387
+v -0.928156 0.0598719 0.582419
+v -0.919087 0.0684012 0.600286
+v -0.0737384 0.629715 -0.019101
+v -0.0831155 0.636305 -0.00903024
+v 0.325609 -0.54879 0.72635
+v 0.802696 -0.307709 0.0863332
+v -0.410439 0.576343 0.14889
+v 0.359469 -0.0735522 -0.237677
+v 0.380458 -0.0626337 -0.231087
+v 0.379033 -0.078382 -0.239462
+v -0.0382469 0.623768 -0.10492
+v -0.0525308 0.615726 -0.085858
+v -0.205891 -0.0930513 -0.263855
+v -0.218749 -0.0932697 -0.260618
+v -0.205891 -0.0749908 -0.257227
+v 0.286996 0.139757 0.479232
+v -0.072608 -0.855497 0.707802
+v -0.072608 -0.838271 0.701225
+v -0.0989281 -0.864 0.709703
+v -0.0853763 -0.855715 0.708277
+v -0.0725567 -0.821444 0.691604
+v -0.0725053 -0.805285 0.676048
+v -0.0725824 -0.789652 0.651578
+v -0.0726594 -0.774173 0.616998
+v -0.0715033 -0.759684 0.586208
+v -0.0721456 -0.7417 0.578912
+v -0.0716446 -0.722985 0.585168
+v -0.0591462 -0.721341 0.601648
+v -0.064143 -0.704513 0.599156
+v -0.0845413 -0.724539 0.565656
+v -0.649516 0.896204 -0.67529
+v -0.451031 -0.732195 0.323303
+v 0.312366 0.270278 0.252744
+v -0.714526 0.592554 0.249173
+v 0.360972 0.260207 0.105678
+v -0.934707 0.321351 0.433529
+v -0.936095 0.321351 0.44631
+v -0.934245 0.338949 0.4334
+v -0.933526 0.53186 0.252474
+v -0.93341 -0.256199 0.166899
+v 0.813987 -0.436753 0.195518
+v -0.134715 -0.193232 -0.299642
+v -0.135023 -0.20812 -0.310766
+v -0.154253 -0.201466 -0.29778
+v -0.796608 0.814931 -0.558205
+v -0.79689 0.805541 -0.529714
+v -0.789144 0.825041 -0.537653
+v 0.359148 0.264857 0.159962
+v 0.368718 0.260156 0.126873
+v 0.343066 0.268531 0.208993
+v 0.348487 0.267516 0.192654
+v -0.625752 0.560492 0.000976243
+v -0.585392 0.520016 -0.206026
+v -0.605084 0.553671 -0.0663331
+v -0.612522 0.565437 -0.0691848
+v -0.610261 0.554981 -0.0496599
+v -0.333458 0.738707 -0.102647
+v -0.160817 0.616523 -0.134323
+v -0.148819 0.613954 -0.129224
+v -0.940488 0.30347 0.395044
+v -0.938111 0.303663 0.407915
+v -0.932023 0.321094 0.394916
+v 0.987733 -0.543664 0.149995
+v 0.984431 -0.543998 0.137175
+v 0.981567 -0.526298 0.150007
+v -0.786216 0.56134 0.394017
+v -0.796967 0.553992 0.410176
+v -0.782195 0.55606 0.415199
+v -0.801476 0.560505 0.389328
+v -0.817867 0.555855 0.38392
+v -0.812793 0.550678 0.404807
+v 0.412816 0.242879 0.106346
+v -0.473587 -0.783782 0.426387
+v -0.457466 -0.76689 0.413631
+v -0.450568 -0.714558 0.323085
+v -0.492701 0.358576 -0.0200387
+v -0.0819594 0.937026 -0.119281
+v 0.351852 0.249019 0.322391
+v 0.405558 0.248672 0.176983
+v -0.196706 0.745592 -0.187978
+v -0.487614 -0.712105 0.144253
+v -0.492148 -0.693363 0.143109
+v -0.712676 0.783871 -0.384293
+v -0.726138 0.785297 -0.389046
+v -0.721026 0.780223 -0.368622
+v 0.708476 -0.0137059 0.252783
+v -0.453535 0.557486 0.176687
+v -0.072608 -0.145139 0.593954
+v -0.0726466 -0.127168 0.589779
+v -0.268036 -0.521853 -0.186976
+v -0.0726466 -0.109339 0.586208
+v -0.0726723 -0.0914328 0.580158
+v -0.072698 -0.073732 0.572219
+v -0.0726594 -0.056211 0.563729
+v -0.072775 -0.0383304 0.554544
+v -0.0727622 -0.0207323 0.544679
+v -0.0728264 -0.0030058 0.535058
+v -0.072775 0.0146436 0.525206
+v -0.0729549 0.0324601 0.514017
+v -0.0729549 0.0498911 0.499284
+v -0.0731475 0.0675534 0.483253
+v -0.0732888 0.0852157 0.468686
+v -0.0731347 0.102608 0.453786
+v -0.0733145 0.120373 0.432899
+v -0.0725567 0.136456 0.413824
+v -0.072197 0.152551 0.385654
+v 0.789517 -0.254748 0.00937707
+v -0.961593 0.426515 0.278781
+v -0.960077 0.444165 0.278679
+v -0.572984 0.401416 -0.0535392
+v -0.0689985 0.616818 -0.03404
+v -0.45595 0.340722 0.376997
+v 0.687487 -0.0613748 -0.0550421
+v 0.677763 -0.0436483 -0.0550549
+v 0.68285 -0.0432887 -0.0422739
+v 0.44087 -0.302892 0.666016
+v 0.107239 -0.0732439 0.58125
+v 0.50534 -0.0222994 0.521378
+v 0.704674 -0.114657 -0.0812979
+v 0.713113 -0.114696 -0.0676947
+v 0.410311 -0.309597 0.685194
+v 0.399328 -0.309687 0.691912
+v -0.136526 0.578732 -0.0411435
+v -0.405494 0.447273 0.0258062
+v -0.392816 0.458166 0.00976243
+v 0.255923 -0.154144 0.671501
+v -0.0598141 -0.821547 0.691475
+v -0.0597884 -0.805362 0.674584
+v -0.059827 -0.789857 0.649959
+v -0.0598141 -0.774186 0.61854
+v -0.0586966 -0.758553 0.595919
+v -0.0598141 -0.740197 0.594044
+v -0.056423 -0.704128 0.609535
+v -0.696581 0.591372 0.199513
+v 0.365622 0.25742 0.0891592
+v -0.116077 0.197856 0.0775342
+v -0.11126 0.19521 0.0605784
+v -0.919999 0.458526 0.418333
+v -0.929929 0.440671 0.410587
+v -0.924534 0.441146 0.422983
+v 0.373445 0.257741 0.110264
+v 0.0340336 0.784809 -0.294337
+v -0.139468 0.200361 0.143932
+v -0.958548 0.496997 0.265551
+v -0.145685 0.200014 0.160566
+v -0.131028 0.202044 0.165948
+v -0.687962 0.592823 0.221183
+v -0.073443 -0.92228 -0.00829806
+v -0.0827687 -0.923217 0.0143482
+v -0.0868278 -0.92287 -0.0104689
+v -0.626086 0.742124 -0.389046
+v 0.332533 0.249764 0.333824
+v 0.32444 0.245576 0.349379
+v 0.420741 0.234838 0.0728714
+v -0.916287 -0.083366 0.166
+v -0.909158 -0.0661661 0.165833
+v 0.420253 0.146501 0.440632
+v -0.607872 0.607698 -0.142082
+v 0.285262 0.200682 0.428121
+v 0.344453 0.246232 0.338152
+v 0.410966 0.247465 0.160656
+v -0.93332 0.321145 0.407761
+v 0.808708 -0.439206 0.263855
+v -0.0598141 -0.109057 0.587133
+v -0.0598013 -0.0916769 0.579618
+v -0.0598013 -0.0739247 0.571783
+v -0.0597756 -0.0561853 0.56518
+v -0.0597884 -0.0384588 0.557152
+v -0.0598912 -0.0205653 0.547916
+v -0.059904 -0.00290304 0.538205
+v -0.0599554 0.0147849 0.528404
+v -0.0598398 0.0322545 0.518321
+v -0.0599811 0.0499554 0.503947
+v -0.0600839 0.067592 0.489432
+v -0.0599297 0.0849203 0.476098
+v -0.0601481 0.102724 0.460119
+v -0.059994 0.119949 0.441904
+v 0.586291 -0.651873 -0.234658
+v 0.594577 -0.614596 -0.235236
+v 0.791392 -0.272616 0.00931284
+v -0.205608 -0.982126 0.182262
+v -0.218415 -0.981663 0.179218
+v -0.209205 -0.980571 0.156918
+v 0.760255 -0.527441 -0.0289276
+v 0.760679 -0.545501 -0.0161979
+v 0.839524 -0.64793 0.418513
+v 0.338608 -0.549239 0.722227
+v 0.325686 -0.566657 0.726569
+v -0.949865 0.46148 0.214337
+v -0.955144 0.479104 0.214401
+v -0.950995 0.479142 0.201466
+v 0.839472 -0.6301 0.413991
+v 0.756543 -0.545694 -0.0287092
+v 0.839421 -0.612489 0.406143
+v -0.04729 -0.838772 0.698771
+v -0.0471358 -0.821701 0.689882
+v 0.245262 -0.148325 0.667352
+v -0.0471101 -0.805554 0.672991
+v -0.0470459 -0.790063 0.648354
+v -0.0471101 -0.774353 0.615585
+v -0.0471487 -0.757205 0.60572
+v -0.0467633 -0.73863 0.610087
+v -0.0484589 -0.703704 0.619683
+v -0.0459027 -0.719658 0.617551
+v -0.0399425 -0.703524 0.62924
+v -0.61134 0.539104 0.475096
+v -0.623376 0.527672 0.490074
+v -0.806409 -0.0694288 0.429855
+v -0.804597 -0.0519978 0.427581
+v 0.37762 0.254324 0.0934752
+v -0.95869 0.49701 0.252693
+v -0.828746 -0.471294 0.219385
+v -0.727448 0.5887 0.319617
+v -0.72091 0.586478 0.340632
+v 0.382193 0.251267 0.0770333
+v -0.618238 0.566349 -0.0526529
+v -0.895311 0.37173 0.0737577
+v -0.90032 0.354325 0.0736421
+v -0.931984 -0.221504 0.179564
+v 0.412931 0.234529 0.051728
+v 0.424235 0.229982 0.0558385
+v 0.427177 0.224061 0.038523
+v 0.415744 0.228364 0.034541
+v -0.512341 -0.79786 0.426528
+v -0.803377 -0.508263 0.129558
+v -0.79048 -0.518051 0.134721
+v -0.901387 -0.0491204 0.165781
+v -0.499316 0.577191 0.195595
+v 0.336386 0.242108 0.353734
+v 0.327587 0.236495 0.369007
+v 0.317504 0.228299 0.383753
+v -0.931624 0.31936 0.0995511
+v 0.998651 -0.631822 0.175929
+v 0.99666 -0.649754 0.175993
+v -0.310387 0.492489 0.010546
+v -0.630723 0.504139 -0.402482
+v -0.0467633 -0.109236 0.583369
+v -0.0469431 -0.0917797 0.576561
+v -0.0469688 -0.0740275 0.571474
+v -0.046956 -0.0561725 0.565193
+v -0.0468789 -0.0385359 0.558449
+v -0.0468789 -0.0208351 0.550331
+v -0.046956 -0.00305718 0.540877
+v -0.0469945 0.0147978 0.531423
+v -0.047123 0.0326527 0.520376
+v -0.0471615 0.0502508 0.507376
+v -0.0470074 0.0675406 0.495405
+v -0.0470587 0.0852414 0.482624
+v -0.0472771 0.103109 0.466708
+v -0.0469431 0.119988 0.449765
+v -0.0469945 0.137393 0.42866
+v 0.0923898 0.788599 -0.328043
+v -0.485032 -0.719581 0.148543
+v -0.47649 -0.73723 0.158524
+v -0.476503 -0.719337 0.15801
+v -0.917803 -0.0832247 0.178781
+v -0.921078 -0.10045 0.166025
+v 0.791482 -0.290715 0.00928715
+v 0.765034 -0.509008 -0.0289148
+v 0.839357 -0.595367 0.397254
+v -0.266212 -0.892055 -0.346797
+v -0.775708 0.813724 -0.501031
+v -0.787308 0.806492 -0.503304
+v 0.966217 -0.616998 0.0606298
+v 0.95305 -0.600325 0.0472707
+v 0.768399 -0.490716 -0.0289918
+v 0.351479 0.115261 0.488198
+v 0.839331 -0.577974 0.386194
+v -0.298827 -0.952569 0.569355
+v -0.0346245 -0.822523 0.686003
+v -0.0343547 -0.805953 0.669869
+v -0.0339822 -0.78996 0.642766
+v -0.034085 -0.774173 0.618488
+v -0.034252 -0.756318 0.615431
+v -0.0333914 -0.736909 0.625797
+v -0.0334813 -0.718348 0.632502
+v -0.0210599 -0.717217 0.645476
+v -0.0312976 -0.702933 0.638887
+v -0.268126 -0.502855 -0.196764
+v -0.720743 0.592232 0.265692
+v -0.727667 0.591012 0.281993
+v -0.599946 0.551384 -0.0831348
+v -0.606947 0.564358 -0.0857552
+v -0.61626 -0.227477 -0.218152
+v -0.61694 -0.20889 -0.216225
+v -0.603979 -0.208543 -0.219629
+v -0.929017 -0.221697 0.166732
+v -0.932395 -0.238923 0.166745
+v -0.825163 0.575225 0.267221
+v -0.833512 0.57114 0.283239
+v -0.524095 0.577036 0.298216
+v -0.530864 0.57588 0.314491
+v -0.51861 0.572939 0.318885
+v 0.0879967 0.861714 -0.359373
+v -0.0340208 -0.423355 0.730769
+v -0.0339951 -0.404781 0.739928
+v -0.0466991 -0.405025 0.735136
+v -0.0343291 -0.386669 0.74838
+v -0.0468147 -0.386721 0.743011
+v -0.0811373 0.616343 -0.112294
+v -0.629567 -0.949974 0.518796
+v -0.635283 -0.947739 0.503382
+v -0.628141 -0.960404 0.506631
+v -0.0467376 -0.368609 0.747506
+v -0.0340722 -0.368223 0.754083
+v -0.0468018 -0.333079 0.747699
+v -0.0467633 -0.350767 0.749151
+v -0.034085 -0.332603 0.754096
+v 0.906229 -0.55317 0.0301222
+v 0.904559 -0.569689 0.0212847
+v 0.892832 -0.565964 0.0173668
+v -0.0469688 -0.315519 0.743447
+v -0.0340208 -0.315185 0.749292
+v -0.0341492 -0.350317 0.75565
+v -0.0421133 -0.860648 0.702368
+v -0.0316315 -0.842664 0.694918
+v 0.135627 -0.099975 0.581943
+v -0.0339694 -0.297818 0.7431
+v -0.0339951 -0.280464 0.735522
+v -0.029602 -0.267683 0.73231
+v -0.0411756 -0.267439 0.726145
+v -0.183476 0.205897 0.146642
+v 0.295577 0.20925 0.413336
+v 0.306534 0.218807 0.398487
+v -0.716941 0.591603 0.210945
+v -0.710762 0.59231 0.194414
+v 0.99991 -0.613877 0.175904
+v -0.336707 0.553414 -0.0743486
+v -0.332276 0.536163 -0.0636613
+v -0.842247 0.534634 0.41525
+v 0.0406104 -0.146077 0.633697
+v 0.0251061 -0.149661 0.628302
+v 0.0294093 -0.155929 0.649099
+v -0.82944 0.546876 0.399759
+v 0.213726 -0.955279 0.243393
+v -0.0341235 -0.109737 0.57967
+v -0.0341364 -0.0918824 0.576214
+v -0.0341364 -0.0738605 0.571873
+v -0.0341621 -0.0558128 0.566105
+v -0.0340978 -0.0383561 0.560145
+v -0.0342391 -0.0202956 0.551449
+v -0.0341878 -0.00269751 0.543048
+v -0.0340722 0.0148363 0.534403
+v -0.0340465 0.032383 0.524474
+v -0.0342905 0.0505462 0.51236
+v -0.0342648 0.0681571 0.499348
+v -0.0342135 0.0854983 0.487505
+v -0.0342006 0.103032 0.472835
+v -0.034252 0.12063 0.45656
+v -0.580614 0.363265 -0.0683755
+v -0.896839 -0.0316637 0.178511
+v -0.895375 -0.014361 0.178511
+v 0.770043 -0.472553 -0.0289533
+v 0.839292 -0.560916 0.374569
+v -0.215743 -0.710448 -0.115261
+v 0.440639 -0.196854 0.634481
+v 0.424903 -0.190329 0.639002
+v 0.429181 -0.207233 0.645181
+v 0.287304 -0.369405 0.741482
+v -0.0515418 -0.302031 0.7375
+v -0.0464293 -0.2846 0.732182
+v 0.734706 -0.640531 0.406014
+v -0.506651 0.360156 -0.0346309
+v -0.50448 0.37787 -0.0278743
+v -0.501487 0.358191 -0.0299295
+v 0.760165 -0.537473 0.375828
+v 0.767911 -0.537948 0.36401
+v 0.141883 -0.11643 0.591218
+v 0.125955 -0.116494 0.5915
+v 0.129025 -0.1195 0.606131
+v -0.00875407 0.991233 -0.235223
+v -0.0271742 0.988125 -0.231382
+v -0.0165383 0.990347 -0.222416
+v 0.771752 -0.454402 -0.0290175
+v 0.00934495 -0.916011 -0.14054
+v 0.00053308 -0.915754 -0.118524
+v -0.00409123 -0.916576 -0.142647
+v -0.0218948 -0.822985 0.681379
+v -0.0214838 -0.806274 0.665348
+v -0.0212654 -0.790461 0.639272
+v -0.0214581 -0.773903 0.620698
+v -0.0212654 -0.755239 0.626594
+v -0.0208543 -0.735676 0.639002
+v -0.00790628 -0.715701 0.658874
+v -0.0131857 -0.702368 0.65705
+v -0.817455 0.578103 0.250984
+v -0.382372 0.728174 0.056879
+v -0.367446 0.746312 0.0414518
+v -0.376695 0.74644 0.0325757
+v -0.978433 0.111561 0.473169
+v -0.979203 0.128787 0.473002
+v -0.978625 0.128748 0.460247
+v 0.962749 -0.510112 0.12433
+v 0.957546 -0.510935 0.111741
+v 0.947463 -0.502829 0.111574
+v -0.145056 0.577358 -0.0244574
+v -0.166713 0.56378 -0.0389598
+v -0.119969 0.653813 -0.163302
+v -0.116526 0.637114 -0.148415
+v -0.763569 0.586902 0.288274
+v 0.707538 -0.0221838 0.290252
+v 0.699767 -0.00732182 0.286373
+v 0.702195 -0.0186 0.305525
+v 0.719561 -0.0407967 0.278807
+v -0.946371 0.337896 0.227863
+v -0.976288 0.214311 0.16433
+v -0.0213425 -0.441441 0.729549
+v -0.0211498 -0.42297 0.735316
+v -0.021381 -0.404794 0.743666
+v -0.0211755 -0.385937 0.753672
+v -0.0211883 -0.367864 0.758399
+v -0.0211626 -0.349983 0.759812
+v -0.0212269 -0.332398 0.757076
+v -0.0211626 -0.314928 0.753672
+v -0.0212782 -0.297471 0.74653
+v -0.0214452 -0.279989 0.739324
+v -0.0211112 -0.262635 0.733839
+v -0.00826595 -0.244806 0.732323
+v -0.0245409 -0.250098 0.72698
+v -0.0213039 -0.127425 0.582624
+v -0.0212911 -0.109558 0.579259
+v -0.659587 -0.419656 0.530318
+v -0.659921 -0.403997 0.539708
+v -0.6717 -0.418037 0.526169
+v -0.0212782 -0.0917797 0.577743
+v -0.0212654 -0.0737834 0.573465
+v -0.0212782 -0.0560569 0.568122
+v -0.0211626 -0.038446 0.561275
+v -0.0212911 -0.0203726 0.554146
+v -0.0212654 -0.00271036 0.545899
+v -0.0212911 0.0150547 0.536291
+v -0.021381 0.032884 0.52676
+v -0.0214324 0.050649 0.51552
+v -0.0215737 0.068581 0.502983
+v -0.021381 0.0857424 0.49087
+v -0.021214 0.102839 0.4757
+v -0.0213296 0.120489 0.462533
+v -0.0214195 0.138344 0.440311
+v 0.581693 -0.488571 -0.272333
+v 0.566767 -0.49236 -0.283316
+v 0.566279 -0.473902 -0.286065
+v 0.987514 -0.579374 0.124342
+v 0.983841 -0.579785 0.111664
+v 0.773152 -0.436278 -0.0289148
+v 0.20959 -0.882742 0.620762
+v 0.199854 -0.886839 0.623832
+v -0.88971 -0.327067 0.308351
+v -0.900359 -0.308968 0.308184
+v -0.891663 -0.327221 0.295596
+v 0.287202 -0.351062 0.747198
+v 0.274446 -0.350882 0.750756
+v -0.292404 0.821855 -0.0575855
+v -0.929621 -0.186912 0.166462
+v -0.932588 -0.169365 0.166372
+v 0.774616 -0.418127 -0.0288377
+v 0.766768 -0.165704 0.0222095
+v -0.268242 -0.483959 -0.204934
+v -0.00903667 -0.823602 0.675354
+v -0.00892106 -0.807455 0.659953
+v -0.00843294 -0.790757 0.634802
+v -0.00847147 -0.773698 0.623549
+v -0.00816319 -0.754147 0.635894
+v -0.00807327 -0.734443 0.651347
+v 0.00446374 -0.7152 0.667236
+v 0.00459219 -0.733762 0.659246
+v -0.952562 0.250959 0.510806
+v -0.945677 0.268647 0.51078
+v -0.946885 0.268557 0.497922
+v -0.635283 0.601455 -0.0777783
+v -0.696401 0.912581 -0.693017
+v -0.68064 0.915099 -0.68581
+v -0.687461 0.914046 -0.70626
+v -0.805625 0.5357 0.446374
+v -0.819357 0.522007 0.461403
+v -0.294331 -0.409457 -0.22618
+v -0.691045 0.590524 0.182763
+v -0.00820172 -0.477087 0.727275
+v -0.00844578 -0.459117 0.730885
+v -0.612804 0.498667 -0.340555
+v -0.00849716 -0.441082 0.734199
+v -0.00847147 -0.422906 0.738784
+v -0.00838156 -0.404254 0.747699
+v -0.00831733 -0.385616 0.756267
+v -0.00840725 -0.367735 0.760018
+v -0.00848432 -0.34997 0.760711
+v -0.00848432 -0.332218 0.759298
+v -0.00833018 -0.314825 0.755162
+v -0.00852285 -0.297304 0.748457
+v -0.00826595 -0.28004 0.742882
+v -0.00845863 -0.262275 0.737474
+v -0.0181183 -0.232937 0.719979
+v 0.00496471 -0.226976 0.729613
+v 0.803082 -0.307632 0.201761
+v -0.00843294 -0.0914971 0.579965
+v -0.00843294 -0.0737192 0.573658
+v -0.00834302 -0.0561083 0.565167
+v -0.0082531 -0.038613 0.559361
+v -0.00835587 -0.0205011 0.553748
+v -0.00863846 -0.00235069 0.547659
+v -0.00838156 0.0150932 0.539246
+v -0.00840725 0.032717 0.528006
+v -0.00852285 0.0506362 0.517036
+v -0.00847147 0.0680801 0.506811
+v -0.00858708 0.0859479 0.492694
+v -0.00822741 0.10275 0.478629
+v -0.00848432 0.12081 0.467389
+v -0.666331 0.431795 -0.165525
+v 0.0191716 -0.165165 0.664423
+v 0.0172448 -0.159359 0.648302
+v -0.577981 0.720403 -0.68152
+v 0.774514 -0.400131 -0.0287863
+v 0.773011 -0.382263 -0.0288891
+v 0.338274 -0.866852 0.598154
+v 0.352379 -0.860776 0.596086
+v 0.338326 -0.848959 0.595803
+v -0.420125 0.385128 0.101979
+v -0.0348043 0.662792 -0.169596
+v 0.274395 -0.332732 0.753801
+v 0.132865 -0.314967 0.75136
+v 0.632303 -0.823114 0.414132
+v 0.00425822 -0.841123 0.679144
+v 0.00387286 -0.824103 0.669394
+v 0.00120104 0.654815 -0.154555
+v 0.00407838 -0.807532 0.655508
+v 0.00441236 -0.791013 0.631616
+v 0.00433529 -0.773236 0.628482
+v 0.00460504 -0.753377 0.643819
+v 0.00400131 -0.697076 0.672798
+v -0.00324344 -0.702342 0.665386
+v -0.838496 0.218897 0.688675
+v -0.00852285 -0.955292 -0.327696
+v 0.0162043 -0.967713 -0.313836
+v -0.613472 0.520055 0.493683
+v -0.00833018 -0.532052 0.712156
+v -0.0146244 -0.537062 0.707519
+v -0.472701 -0.950308 0.619041
+v -0.483002 -0.935664 0.622612
+v -0.487023 -0.95289 0.618064
+v 0.00479772 -0.53114 0.718861
+v 0.00441236 -0.513324 0.723113
+v -0.284453 0.554223 -0.082698
+v 0.00411692 -0.495353 0.726684
+v -0.00816319 -0.495328 0.722548
+v 0.77269 -0.363805 0.372372
+v 0.765458 -0.345911 0.38541
+v 0.765676 -0.363329 0.384768
+v 0.00455366 -0.476895 0.730512
+v 0.00446374 -0.458847 0.733865
+v 0.0044509 -0.440761 0.73696
+v 0.00424537 -0.422906 0.740904
+v 0.00448943 -0.404087 0.748958
+v 0.00436098 -0.386168 0.754738
+v 0.00442521 -0.367876 0.758541
+v 0.00439951 -0.350201 0.757243
+v 0.00483625 -0.332423 0.75488
+v 0.00437382 -0.314838 0.752966
+v 0.0045665 -0.29742 0.748868
+v 0.00441236 -0.279719 0.745079
+v 0.00447659 -0.262083 0.741713
+v 0.0045665 -0.244536 0.736883
+v 0.0101542 -0.198922 0.708726
+v 0.0174375 -0.209789 0.721456
+v -0.434614 0.384678 0.0506233
+v -0.430889 0.403715 0.054554
+v 0.00386001 -0.133219 0.585925
+v -0.0121838 -0.132743 0.583665
+v 0.00447659 -0.0916512 0.579336
+v -0.0159089 -0.980816 -0.253913
+v -0.0218563 -0.975279 -0.236148
+v 0.00418114 -0.0736935 0.568893
+v 0.00443805 -0.056211 0.56369
+v 0.00438667 -0.0380863 0.560839
+v 0.00425822 -0.02009 0.556317
+v 0.00443805 -0.00241492 0.550742
+v 0.00446374 0.0152345 0.542483
+v 0.00450228 0.0327555 0.531025
+v 0.00441236 0.0505077 0.519888
+v 0.00450228 0.0679516 0.508199
+v 0.00428391 0.0858837 0.494133
+v 0.00434813 0.103443 0.484049
+v 0.00492617 0.120694 0.473863
+v 0.00437382 0.138858 0.45182
+v -0.487909 0.342507 -0.0153887
+v 0.813435 -0.863833 0.0746569
+v 0.773114 -0.364203 -0.0289918
+v 0.626985 -0.804629 0.4292
+v 0.634063 -0.812195 0.418988
+v 0.455925 -0.0872838 0.5938
+v -0.375243 0.158755 0.356868
+v -0.36787 0.170547 0.34243
+v -0.377812 0.176661 0.352514
+v 0.0167053 -0.841264 0.675483
+v 0.0167695 -0.824527 0.664783
+v -0.00411692 0.637564 -0.0962627
+v 0.0171806 -0.807699 0.649497
+v 0.017232 -0.791001 0.631693
+v 0.017476 -0.772336 0.635881
+v 0.0172962 -0.753068 0.64879
+v 0.0173861 -0.733518 0.662393
+v 0.0175146 -0.714545 0.671308
+v 0.0173476 -0.696331 0.676356
+v -0.680589 0.442328 -0.210226
+v 0.0172705 -0.678193 0.679722
+v 0.00384717 -0.678476 0.67705
+v 0.00437382 -0.66012 0.681353
+v -0.0103983 -0.665643 0.671359
+v 0.0173347 -0.659824 0.684282
+v 0.0172448 -0.641057 0.693672
+v 0.00450228 -0.641443 0.688906
+v 0.0176816 -0.622111 0.702227
+v 0.0048491 -0.62283 0.694609
+v 0.00496471 -0.604654 0.697487
+v 0.0170393 -0.604346 0.704847
+v 0.017476 -0.586067 0.707172
+v 0.00468211 -0.586555 0.700981
+v -0.00437382 -0.574133 0.698643
+v -0.000289019 -0.592772 0.695457
+v 0.0172577 -0.567981 0.710743
+v 0.00479772 -0.568019 0.706825
+v 0.00468211 -0.54965 0.713145
+v 0.0174118 -0.549316 0.717924
+v -0.00917797 -0.555752 0.702933
+v 0.0173604 -0.531063 0.722599
+v 0.0173347 -0.51299 0.725836
+v 0.0172063 -0.495135 0.727956
+v 0.017309 -0.476959 0.730782
+v 0.0173347 -0.458539 0.736742
+v 0.0173733 -0.440388 0.741328
+v 0.0172962 -0.422366 0.74468
+v 0.0172063 -0.404383 0.748187
+v 0.0171934 -0.386361 0.751578
+v 0.017399 -0.36839 0.753428
+v 0.0174889 -0.350831 0.751835
+v 0.0171934 -0.332912 0.750024
+v 0.0171934 -0.315005 0.750397
+v 0.0172833 -0.297214 0.749831
+v 0.0173219 -0.279591 0.747789
+v 0.0171934 -0.261723 0.74531
+v 0.0172833 -0.244228 0.740262
+v 0.0172833 -0.226642 0.732734
+v -0.115948 0.595932 -0.0890436
+v 0.0106295 -0.181954 0.689818
+v 0.0189147 -0.17616 0.68477
+v 0.00495186 -0.177227 0.678245
+v -0.761334 0.735175 -0.309173
+v -0.755027 0.747956 -0.326245
+v -0.767924 0.734777 -0.32067
+v 0.39595 0.249803 0.246707
+v 0.0172833 -0.109403 0.584628
+v 0.0172063 -0.0917026 0.575675
+v -0.18688 -0.979929 0.207297
+v -0.191671 -0.980482 0.183636
+v 0.0172833 -0.0739504 0.570151
+v 0.0171035 -0.0557101 0.568045
+v 0.0171934 -0.0378166 0.565758
+v 0.0173861 -0.02009 0.561673
+v 0.017476 -0.00241492 0.554955
+v 0.0175403 0.0151575 0.546657
+v 0.0172191 0.0331666 0.534686
+v 0.017232 0.0508032 0.523305
+v 0.0170264 0.0687609 0.510857
+v 0.0167952 0.086025 0.498179
+v 0.0169879 0.104175 0.489637
+v 0.0171934 0.121581 0.479309
+v 0.0172063 0.138871 0.458115
+v 0.848387 -0.842395 0.0744128
+v 0.774848 -0.345924 -0.0290304
+v 0.29952 0.0686453 0.528533
+v 0.457851 -0.965889 -0.0534621
+v 0.979011 -0.669124 0.111805
+v 0.029769 -0.841662 0.669844
+v 0.0296534 -0.825015 0.660197
+v 0.030103 -0.808213 0.642059
+v 0.030103 -0.790692 0.634776
+v 0.0301415 -0.771489 0.645733
+v 0.0305397 -0.751951 0.655752
+v 0.0302828 -0.733325 0.663806
+v 0.0300002 -0.715008 0.670692
+v 0.0301672 -0.696344 0.676433
+v 0.0303984 -0.677769 0.680531
+v 0.0299488 -0.659799 0.686221
+v -0.114689 0.621841 -0.131189
+v -0.773165 0.734301 -0.333297
+v -0.60159 0.416817 -0.081452
+v 0.0299617 -0.56816 0.709587
+v 0.030347 -0.58608 0.707005
+v 0.0302057 -0.549432 0.716292
+v 0.030103 -0.53132 0.721597
+v 0.0301158 -0.513606 0.722869
+v 0.0302443 -0.495533 0.725271
+v 0.0299745 -0.477126 0.73145
+v 0.0302699 -0.45814 0.741045
+v 0.0302956 -0.439977 0.745605
+v 0.030103 -0.422276 0.746337
+v 0.030103 -0.404331 0.74793
+v 0.0302057 -0.386207 0.750268
+v 0.030103 -0.368442 0.751103
+v 0.030103 -0.350535 0.752375
+v 0.0300644 -0.332757 0.751694
+v 0.030103 -0.314864 0.752824
+v 0.0300644 -0.297112 0.751463
+v 0.0300773 -0.279424 0.749819
+v 0.0301415 -0.261646 0.747905
+v 0.0302699 -0.244061 0.743023
+v 0.0301286 -0.226797 0.734057
+v 0.0301672 -0.209545 0.721777
+v 0.0302443 -0.192667 0.707686
+v 0.0172063 -0.192204 0.70522
+v 0.863968 -0.840802 0.125447
+v 0.0203148 -0.150329 0.625142
+v 0.0185807 -0.13282 0.589612
+v 0.0311177 -0.133116 0.595855
+v 0.0301158 -0.0736421 0.575187
+v 0.0302828 -0.0556073 0.574416
+v 0.0302443 -0.0376624 0.571372
+v 0.0300901 -0.0196918 0.565553
+v 0.0302057 -0.00206809 0.558642
+v 0.0300901 0.0157483 0.549316
+v 0.0302057 0.0331794 0.53913
+v 0.0299873 0.0510986 0.526786
+v 0.0301286 0.068504 0.516561
+v 0.0298717 0.0866287 0.505861
+v 0.0297561 0.104702 0.496419
+v 0.0301286 0.121632 0.484011
+v 0.0302571 0.138819 0.46586
+v 0.0301415 0.15634 0.444884
+v 0.871663 -0.822292 0.0742201
+v 0.877469 -0.821226 0.087014
+v 0.781951 -0.471589 0.00940276
+v 0.777918 -0.327735 -0.0290432
+v 0.779318 -0.309649 -0.0289533
+v -0.608257 0.618925 -0.639041
+v -0.604583 0.623601 -0.621828
+v -0.687705 0.499965 -0.476715
+v -0.673074 0.507068 -0.496779
+v 0.531018 -0.0405526 0.521339
+v 0.518237 -0.0224407 0.518269
+v 0.53852 -0.0184202 0.509971
+v 0.00762368 0.956114 -0.238178
+v 0.852408 -0.612644 0.404627
+v 0.0422418 -0.842459 0.665682
+v 0.0198396 -0.858387 0.679259
+v 0.0296534 -0.859029 0.675778
+v 0.0425372 -0.825477 0.653774
+v 0.0429611 -0.808547 0.637525
+v 0.0428326 -0.790474 0.638681
+v 0.0429354 -0.770397 0.6566
+v 0.043719 -0.751026 0.664693
+v 0.0431152 -0.732863 0.668418
+v 0.0432052 -0.714404 0.672721
+v 0.0431795 -0.696061 0.677538
+v -0.41857 0.436419 0.0417215
+v -0.427536 0.43683 0.0326271
+v 0.0300644 0.668379 -0.112628
+v 0.0400324 0.667904 -0.132242
+v 0.0265833 0.691591 -0.121221
+v -0.281781 0.538308 -0.0662817
+v -0.134638 -0.922421 0.0031471
+v -0.147432 -0.921958 0.000102762
+v -0.138697 -0.922061 -0.0216829
+v -0.941554 0.28627 0.497871
+v 0.0434235 -0.585502 0.713107
+v 0.0429739 -0.567981 0.710653
+v 0.0427684 -0.550177 0.71154
+v 0.0428969 -0.531885 0.715663
+v 0.0429483 -0.513683 0.718463
+v 0.0416894 -0.494839 0.723717
+v 0.0431409 -0.476252 0.736203
+v 0.0429611 -0.458025 0.744719
+v 0.0429611 -0.439849 0.749356
+v 0.0429868 -0.421917 0.750859
+v 0.0429097 -0.4041 0.751219
+v 0.0429097 -0.386181 0.752799
+v 0.0429226 -0.368133 0.755792
+v 0.0428969 -0.350291 0.755971
+v 0.0428326 -0.332539 0.75488
+v 0.0429097 -0.314748 0.754469
+v 0.0428583 -0.296983 0.753287
+v 0.0429226 -0.279308 0.751488
+v 0.0429483 -0.261505 0.749664
+v 0.0429226 -0.243791 0.745258
+v 0.0429611 -0.226437 0.737282
+v 0.0423702 -0.209134 0.722972
+v 0.0606748 -0.163842 0.679259
+v -0.114497 0.607865 -0.111459
+v 0.793743 -0.199847 0.098973
+v 0.797982 -0.217741 0.0990116
+v 0.406008 0.246103 0.21381
+v 0.411518 0.245178 0.197471
+v 0.421666 0.241697 0.164561
+v 0.41735 0.244741 0.181324
+v 0.0431795 -0.0555688 0.575623
+v 0.0430125 -0.0375853 0.571654
+v 0.0431538 -0.019846 0.567736
+v 0.0431281 -0.00209378 0.561417
+v 0.0430382 0.0157483 0.552194
+v 0.0430896 0.0332308 0.542187
+v 0.043051 0.0509445 0.530986
+v 0.0429354 0.0687994 0.519965
+v 0.0427427 0.0868727 0.510716
+v 0.0427556 0.104612 0.500915
+v 0.0428583 0.122107 0.487633
+v 0.0430125 0.139179 0.470883
+v 0.0430125 0.15652 0.45132
+v 0.0558449 0.174285 0.435006
+v 0.895619 -0.802844 0.086603
+v 0.778264 -0.291781 -0.029146
+v 0.852279 -0.595251 0.396162
+v 0.299854 0.139898 0.481005
+v 0.299854 0.157637 0.469547
+v -0.634166 0.493234 -0.376778
+v -0.641513 0.491924 -0.389058
+v 0.299353 0.0101992 0.547839
+v 0.852215 -0.578026 0.386155
+v 0.852189 -0.560826 0.37471
+v 0.0551127 -0.84287 0.661045
+v 0.0339951 -0.875677 0.676896
+v 0.0553311 -0.826043 0.648893
+v 0.0557807 -0.80865 0.636073
+v 0.0557293 -0.789665 0.646157
+v 0.0553311 -0.769639 0.66459
+v 0.0560248 -0.750409 0.672978
+v 0.0560633 -0.731899 0.677435
+v 0.0562945 -0.713621 0.680274
+v 0.0558835 -0.695547 0.684282
+v -0.993976 0.127978 0.280374
+v -0.137502 0.880609 -0.0668469
+v -0.0934046 0.688958 -0.18582
+v -0.242179 -0.55904 -0.177188
+v 0.0478937 -0.610768 0.719979
+v 0.0427556 -0.621276 0.715676
+v 0.0558578 -0.620569 0.721366
+v -0.149603 -0.217394 -0.309019
+v 0.0514904 -0.575701 0.715624
+v 0.0559477 -0.567467 0.716446
+v 0.0557165 -0.549856 0.71407
+v 0.0556266 -0.531834 0.717615
+v 0.0559734 -0.513234 0.724436
+v 0.0562817 -0.494249 0.731475
+v 0.0557036 -0.476471 0.738887
+v 0.0557679 -0.457961 0.746466
+v 0.0556266 -0.439862 0.751655
+v 0.0556523 -0.421763 0.754584
+v 0.0557807 -0.403753 0.755689
+v 0.0558578 -0.385706 0.758386
+v 0.0556394 -0.367889 0.75953
+v 0.0558064 -0.350099 0.758785
+v 0.0557807 -0.332385 0.757307
+v 0.0557165 -0.314697 0.754957
+v 0.0558321 -0.297099 0.752362
+v 0.0556394 -0.279449 0.749266
+v 0.0556266 -0.261659 0.747776
+v 0.0559348 -0.244035 0.745849
+v 0.0558192 -0.226231 0.740313
+v 0.055755 -0.208852 0.728341
+v 0.0688701 -0.175223 0.695547
+v 0.401204 0.248428 0.230368
+v 0.0558835 -0.0735136 0.57773
+v 0.0558578 -0.0555174 0.574789
+v 0.0431024 -0.0734879 0.578925
+v 0.0559092 -0.0375853 0.572823
+v 0.0559734 -0.0197304 0.569406
+v 0.055922 -0.00184972 0.563292
+v 0.0559477 0.0157355 0.555032
+v 0.0557679 0.0337061 0.544474
+v 0.0559348 0.0510472 0.534197
+v 0.0557679 0.0689792 0.523279
+v 0.055922 0.0865259 0.514685
+v 0.0558963 0.104265 0.504961
+v 0.0558835 0.121838 0.491898
+v 0.0559092 0.139294 0.475661
+v 0.0557807 0.15697 0.456406
+v 0.068793 0.174105 0.439643
+v 0.919601 -0.781752 0.0867186
+v 0.779947 -0.521956 0.0226976
+v 0.78348 -0.489406 0.0222737
+v 0.776094 -0.2739 -0.0289661
+v 0.807822 -0.814906 0.375083
+v 0.817121 -0.794906 0.38902
+v 0.797918 -0.814585 0.383458
+v 0.367048 -0.913044 0.594326
+v 0.368589 -0.89497 0.596703
+v 0.354472 -0.895793 0.598784
+v 0.0818053 0.173784 0.444126
+v 0.107136 0.192705 0.423831
+v -0.903172 -0.0488892 0.178575
+v -0.910147 -0.309045 0.231331
+v -0.604468 0.512797 -0.350407
+v -0.610518 0.510254 -0.36401
+v -0.596632 0.527274 -0.360144
+v 0.464133 -0.145833 -0.269995
+v 0.0683691 -0.86034 0.662304
+v 0.0680223 -0.843307 0.656523
+v 0.0680993 -0.826274 0.644937
+v 0.0686132 -0.808778 0.634532
+v 0.0686132 -0.789575 0.649253
+v 0.0687545 -0.769151 0.667095
+v 0.0685232 -0.750435 0.676896
+v 0.0687159 -0.73154 0.682573
+v 0.0689214 -0.713094 0.686761
+v 0.0685232 -0.676215 0.701495
+v 0.0607005 -0.685297 0.691552
+v 0.0687288 -0.694879 0.691938
+v 0.0686902 -0.638681 0.719799
+v 0.0557807 -0.639143 0.715342
+v 0.0534942 -0.666851 0.698463
+v 0.0457871 -0.647737 0.705412
+v 0.0688187 -0.620158 0.725734
+v 0.0687673 -0.602072 0.728881
+v 0.056089 -0.602483 0.723858
+v 0.0487929 -0.593042 0.718245
+v 0.0686902 -0.566914 0.722882
+v 0.056256 -0.584885 0.72048
+v 0.0688444 -0.584474 0.727185
+v -0.241203 -0.765015 -0.120052
+v 0.0683691 -0.549355 0.720724
+v 0.0685361 -0.531102 0.724912
+v -0.268332 -0.465295 -0.209854
+v -0.255525 -0.464897 -0.214761
+v 0.0684719 -0.512836 0.731321
+v 0.0685232 -0.494467 0.737371
+v 0.0685618 -0.476188 0.74188
+v 0.0686902 -0.457781 0.747686
+v 0.0687031 -0.439463 0.753711
+v 0.0683563 -0.421274 0.757693
+v 0.0685875 -0.403432 0.760467
+v 0.0685104 -0.385487 0.76233
+v 0.0684847 -0.367658 0.762664
+v 0.0685489 -0.349919 0.760878
+v 0.0686517 -0.332295 0.758746
+v 0.0686132 -0.314697 0.755676
+v 0.0686388 -0.297266 0.749677
+v 0.068626 -0.279745 0.745002
+v 0.0686902 -0.261928 0.744424
+v 0.0687031 -0.244035 0.744359
+v 0.0686003 -0.22609 0.740647
+v 0.0686902 -0.20898 0.73231
+v 0.0687288 -0.192358 0.71696
+v 0.0739953 -0.164009 0.684346
+v 0.0817539 -0.175158 0.70292
+v 0.0888445 -0.161979 0.689471
+v -0.582142 0.780981 -0.655945
+v 0.0687416 -0.091587 0.580774
+v 0.0606362 -0.0988574 0.582817
+v 0.0686003 -0.109211 0.585257
+v 0.0444126 -0.0803345 0.579644
+v 0.0686902 -0.0734623 0.577923
+v 0.0686517 -0.0553889 0.576715
+v 0.0687416 -0.0374312 0.57448
+v 0.0687288 -0.0195505 0.56992
+v 0.0687673 -0.00192679 0.564487
+v 0.0689214 0.0156841 0.557794
+v 0.0688572 0.0333849 0.54834
+v 0.0688701 0.0510472 0.53859
+v 0.0685489 0.0693261 0.526799
+v 0.068626 0.0868727 0.516715
+v 0.0686902 0.104407 0.506696
+v 0.0687801 0.121748 0.494878
+v 0.0687031 0.139526 0.478988
+v 0.068626 0.157175 0.459682
+v 0.772702 -0.256097 -0.0289148
+v -0.241241 -0.747314 -0.113552
+v -0.241344 -0.729163 -0.111934
+v -0.619676 0.496702 -0.353002
+v 0.911958 -0.711154 0.00958259
+v 0.904174 -0.729741 0.00965966
+v 0.768412 -0.238203 -0.029146
+v 0.813653 -0.4148 0.163405
+v -0.0944065 0.647467 -0.155428
+v 0.893281 -0.74874 0.00986519
+v 0.763248 -0.220515 -0.0290304
+v 0.730814 -0.0401672 0.150303
+v 0.0809575 -0.860905 0.658386
+v 0.0809446 -0.843743 0.652014
+v 0.0810217 -0.826659 0.640839
+v 0.0815098 -0.809023 0.633633
+v 0.0815612 -0.78829 0.652888
+v 0.0815227 -0.769074 0.668803
+v 0.0814713 -0.750153 0.678116
+v 0.0813172 -0.731617 0.684693
+v 0.0814328 -0.713004 0.690627
+v 0.0810603 -0.694828 0.697358
+v 0.0817154 -0.675393 0.705515
+v -0.73459 0.601828 -0.0209507
+v -0.721976 0.615765 -0.03413
+v -0.739292 0.607557 -0.0407324
+v -0.454666 0.522881 0.230213
+v -0.452366 0.523138 0.217497
+v 0.0815741 -0.619631 0.732002
+v -0.764135 0.827096 -0.514172
+v 0.0812915 -0.601828 0.732747
+v 0.08133 -0.584063 0.731167
+v 0.0815741 -0.566388 0.728958
+v 0.0814071 -0.548802 0.726363
+v 0.0816768 -0.530588 0.728752
+v 0.081831 -0.511949 0.736203
+v 0.0814841 -0.493837 0.74319
+v 0.0815098 -0.475751 0.746248
+v 0.0813942 -0.457871 0.748136
+v 0.0814328 -0.439515 0.754173
+v 0.0814071 -0.421249 0.760519
+v 0.0811373 -0.403124 0.763794
+v 0.0815098 -0.385256 0.764822
+v 0.0814841 -0.367478 0.764912
+v 0.0814199 -0.349777 0.762754
+v 0.0814456 -0.332192 0.759491
+v 0.0814841 -0.314671 0.755715
+v 0.0814328 -0.297099 0.751681
+v 0.0813685 -0.279411 0.749189
+v 0.081497 -0.261646 0.747943
+v 0.0814585 -0.243804 0.745271
+v 0.0814585 -0.226129 0.740608
+v 0.081497 -0.208736 0.732709
+v 0.0815355 -0.191703 0.720159
+v 0.0816383 -0.109737 0.585489
+v 0.0678424 -0.124073 0.596266
+v 0.0810089 -0.124021 0.601096
+v 0.0814328 -0.0913943 0.580453
+v 0.0815612 -0.0734366 0.579194
+v 0.0815998 -0.0553632 0.57755
+v 0.0816126 -0.0374312 0.574557
+v 0.0816511 -0.0195762 0.57123
+v 0.0817411 -0.00191395 0.567261
+v 0.081998 0.0159667 0.560068
+v 0.0815998 0.0337061 0.550357
+v 0.0815355 0.0515482 0.540877
+v 0.0815741 0.0690949 0.530909
+v 0.0817154 0.0864617 0.520607
+v 0.0816511 0.104201 0.509432
+v 0.0815484 0.12212 0.496843
+v 0.0817025 0.139102 0.483176
+v 0.0815612 0.157047 0.464306
+v -0.426624 0.514197 -0.0288377
+v -0.413728 0.514351 -0.0322032
+v -0.412944 0.495328 -0.023584
+v 0.971085 -0.669895 0.0862176
+v -0.929993 0.392064 0.471538
+v 0.756556 -0.20284 -0.0289661
+v 0.531147 -0.873634 0.516034
+v 0.52236 -0.894881 0.51159
+v 0.530273 -0.89393 0.498654
+v 0.640884 -0.84865 0.397767
+v 0.78488 -0.182455 0.214414
+v 0.783454 -0.182493 0.227246
+v 0.994965 -0.632143 0.137329
+v 0.670647 -0.0960443 -0.117894
+v 0.669131 -0.111536 -0.127014
+v 0.659253 -0.104522 -0.134657
+v 0.0939826 -0.861264 0.654327
+v 0.0938413 -0.84409 0.647429
+v 0.0711051 -0.874289 0.663228
+v 0.0842459 -0.873711 0.659593
+v 0.0940212 -0.826788 0.636523
+v 0.0943294 -0.809048 0.633787
+v 0.0944707 -0.787661 0.657332
+v 0.0943551 -0.768727 0.671848
+v 0.0943038 -0.74987 0.681276
+v 0.0943551 -0.731 0.688765
+v 0.0943423 -0.712477 0.695021
+v 0.0945478 -0.693775 0.700711
+v 0.0941239 -0.675663 0.7096
+v 0.0942781 -0.637564 0.732426
+v -0.496593 -0.787083 0.485051
+v 0.0943808 -0.619195 0.736665
+v 0.094368 -0.601391 0.736768
+v 0.0941111 -0.583742 0.734533
+v 0.0942267 -0.566105 0.732632
+v 0.0944322 -0.548404 0.730538
+v 0.0939955 -0.530716 0.731745
+v 0.0945093 -0.511641 0.741122
+v 0.0946377 -0.493015 0.75014
+v 0.0943808 -0.47525 0.752285
+v 0.0940854 -0.457678 0.751707
+v 0.0942395 -0.43954 0.754391
+v 0.0942395 -0.421262 0.760673
+v 0.0943166 -0.40306 0.764886
+v 0.0942524 -0.385243 0.765824
+v 0.0943166 -0.367453 0.765169
+v 0.0943551 -0.349752 0.762767
+v 0.0943423 -0.332128 0.759709
+v 0.0943166 -0.314556 0.757436
+v 0.0942781 -0.296868 0.754892
+v 0.0942781 -0.279154 0.753338
+v 0.0943038 -0.261376 0.751347
+v 0.0943166 -0.243637 0.747198
+v 0.0942781 -0.226013 0.740853
+v 0.0943423 -0.208839 0.732567
+v 0.0944194 -0.191999 0.721263
+v 0.0944322 -0.174825 0.706093
+v 0.97314 -0.63416 0.0730384
+v 0.976044 -0.651706 0.0860506
+v 0.672098 0.0143097 0.0177265
+v 0.973115 -0.616356 0.0730641
+v 0.0943423 -0.109365 0.584911
+v 0.0943294 -0.0914585 0.580171
+v 0.0944194 -0.073321 0.580646
+v 0.0943038 -0.0551962 0.578796
+v 0.0944194 -0.0372128 0.578013
+v 0.0945607 -0.0194349 0.575623
+v 0.0943937 -0.00143867 0.569997
+v 0.0943551 0.0163906 0.562162
+v 0.0944451 0.0338217 0.553465
+v 0.0944194 0.0515482 0.54387
+v 0.0944065 0.0692747 0.534197
+v 0.0945863 0.0865773 0.523895
+v 0.0943423 0.104574 0.509984
+v 0.0944322 0.12194 0.498153
+v 0.0943937 0.139641 0.483767
+v 0.0943551 0.157368 0.46771
+v 0.0945735 0.174131 0.449059
+v -0.345712 0.540787 -0.0653312
+v 0.25311 0.261171 0.0387928
+v 0.242744 0.254735 0.0199744
+v -0.936339 -0.238293 0.24374
+v -0.93508 -0.255737 0.231036
+v -0.949518 0.390895 0.214709
+v -0.955645 0.39087 0.227452
+v -0.953526 0.408545 0.214838
+v 0.752111 -0.184844 -0.0291331
+v 0.106738 -0.861817 0.649343
+v 0.106674 -0.844578 0.642689
+v 0.107033 -0.827096 0.632451
+v 0.106892 -0.809652 0.631989
+v 0.107432 -0.786672 0.6631
+v 0.107188 -0.768483 0.67502
+v 0.107162 -0.749382 0.685875
+v 0.107188 -0.730563 0.693492
+v 0.107188 -0.712182 0.698129
+v 0.107059 -0.693993 0.703164
+v 0.107213 -0.674622 0.716601
+v 0.107226 -0.655688 0.727339
+v 0.106905 -0.637833 0.733287
+v 0.107085 -0.619156 0.738746
+v 0.107123 -0.601109 0.740108
+v 0.106944 -0.583498 0.737693
+v 0.107213 -0.565861 0.735265
+v 0.107213 -0.548147 0.733749
+v 0.107021 -0.530292 0.735946
+v 0.107188 -0.511423 0.746209
+v 0.107329 -0.492604 0.756691
+v 0.107175 -0.474788 0.758656
+v 0.1072 -0.456971 0.758566
+v 0.106931 -0.43945 0.756537
+v 0.107149 -0.42121 0.7603
+v 0.107136 -0.403175 0.763679
+v 0.107162 -0.385269 0.765027
+v 0.107175 -0.367491 0.764154
+v 0.107188 -0.349829 0.76215
+v 0.107213 -0.332179 0.758836
+v 0.107149 -0.314504 0.757757
+v 0.107111 -0.296855 0.755278
+v 0.107149 -0.279141 0.754481
+v 0.107175 -0.261312 0.752722
+v 0.107149 -0.243585 0.748418
+v 0.107213 -0.226103 0.74197
+v 0.107188 -0.208762 0.732657
+v 0.107162 -0.191421 0.720531
+v 0.1072 -0.174516 0.706376
+v 0.107316 -0.158138 0.689009
+v 0.115832 -0.149468 0.6789
+v -0.849813 0.304241 -0.00666671
+v -0.199391 0.838528 -0.164034
+v -0.602913 -0.35611 -0.225987
+v -0.589978 -0.355905 -0.22731
+v -0.589875 -0.374248 -0.225589
+v -0.184092 0.783833 -0.191305
+v 0.107111 -0.109069 0.585527
+v 0.107252 -0.0915484 0.581108
+v 0.71143 -0.0877591 0.375918
+v 0.723377 -0.0950424 0.356072
+v 0.718136 -0.0883114 0.363406
+v 0.107175 -0.0550678 0.581635
+v 0.107393 -0.0371101 0.581892
+v 0.10729 -0.0191909 0.57773
+v 0.107239 -0.00145152 0.571359
+v 0.107252 0.016275 0.563369
+v 0.107213 0.0340272 0.553851
+v 0.107213 0.0516895 0.545591
+v 0.107175 0.0695188 0.53606
+v 0.107213 0.0870526 0.524563
+v 0.107085 0.105152 0.510742
+v 0.107252 0.122172 0.49999
+v 0.107329 0.13941 0.486528
+v 0.107149 0.157689 0.469547
+v 0.973487 -0.580633 0.0857809
+v -0.32119 -0.167503 -0.263637
+v -0.333997 -0.167644 -0.263316
+v -0.32128 -0.149327 -0.257612
+v -0.924983 0.535071 0.214799
+v 0.747757 -0.166822 -0.0293515
+v 0.743736 -0.149147 -0.0290175
+v 0.873744 -0.667647 0.404486
+v 0.874283 -0.650357 0.405256
+v 0.786897 -0.471127 0.0222224
+v 0.725946 -0.0404884 0.2274
+v 0.0973738 -0.873121 0.656022
+v 0.119904 -0.827404 0.629355
+v 0.119917 -0.809768 0.634121
+v 0.120187 -0.786864 0.66513
+v 0.120071 -0.768136 0.678013
+v 0.120084 -0.748945 0.688688
+v 0.120059 -0.730217 0.696485
+v 0.120059 -0.711861 0.701058
+v 0.119892 -0.693787 0.706517
+v 0.12002 -0.674519 0.718258
+v 0.119969 -0.656151 0.726466
+v 0.120059 -0.63705 0.7347
+v 0.119956 -0.619028 0.740377
+v 0.119904 -0.601019 0.742214
+v 0.119982 -0.583331 0.740146
+v 0.119917 -0.565694 0.73741
+v 0.120097 -0.547852 0.736614
+v 0.119969 -0.529946 0.73872
+v 0.119853 -0.51141 0.749677
+v 0.119904 -0.492527 0.760429
+v 0.119776 -0.474492 0.763871
+v 0.119737 -0.456637 0.764154
+v 0.119827 -0.438911 0.762497
+v 0.119994 -0.421223 0.76039
+v 0.119956 -0.403368 0.761045
+v 0.120007 -0.385462 0.762356
+v 0.119994 -0.367709 0.761662
+v 0.119879 -0.350163 0.758361
+v 0.120071 -0.332501 0.755753
+v 0.120174 -0.314735 0.754725
+v 0.120123 -0.296932 0.753659
+v 0.119994 -0.279115 0.753672
+v 0.120007 -0.261273 0.752927
+v 0.120033 -0.243483 0.748765
+v 0.119994 -0.225885 0.742548
+v 0.120007 -0.208698 0.734186
+v 0.120046 -0.191652 0.723075
+v 0.120084 -0.174837 0.707506
+v -0.420767 0.104741 0.426862
+v 0.90718 -0.693736 -0.00313425
+v -0.477415 0.437871 0.00702638
+v 0.737198 -0.131459 -0.0289918
+v 0.120046 -0.109365 0.586388
+v -0.599458 0.49683 -0.271434
+v -0.603928 0.492874 -0.287529
+v -0.591995 0.511898 -0.280053
+v 0.120174 -0.0548751 0.584936
+v 0.120136 -0.0369174 0.583934
+v 0.120123 -0.0191652 0.579194
+v 0.120444 -0.00186257 0.572515
+v 0.120136 0.0159153 0.564101
+v 0.120059 0.0338345 0.553504
+v 0.120071 0.0516381 0.545488
+v 0.120071 0.0693389 0.537267
+v 0.120187 0.0864745 0.525141
+v 0.119982 0.10483 0.511847
+v 0.120033 0.12248 0.50193
+v 0.11993 0.140348 0.486092
+v 0.120071 0.157368 0.472322
+v -0.568167 0.441557 -0.0360696
+v 0.132981 0.174876 0.457498
+v 0.970482 -0.563086 0.0857424
+v 0.953449 -0.553928 0.0573029
+v 0.918008 -0.692683 0.00964682
+v 0.729722 -0.11354 -0.0293001
+v -0.881579 -0.397613 0.141915
+v 0.109847 -0.872722 0.651616
+v 0.122885 -0.872093 0.647698
+v 0.132852 -0.827725 0.626979
+v 0.132814 -0.808483 0.639966
+v 0.132878 -0.787686 0.664333
+v 0.132955 -0.767828 0.679413
+v 0.132763 -0.748881 0.692323
+v 0.132827 -0.729831 0.701328
+v 0.132788 -0.71154 0.706157
+v 0.132814 -0.693184 0.710743
+v 0.132891 -0.674327 0.717718
+v 0.132904 -0.656446 0.725361
+v 0.132878 -0.637384 0.735714
+v 0.132865 -0.619118 0.740686
+v 0.132788 -0.601044 0.742368
+v 0.132878 -0.583177 0.7417
+v 0.132814 -0.565463 0.74021
+v 0.13275 -0.547775 0.739016
+v 0.132557 -0.530138 0.741354
+v 0.132852 -0.510793 0.754019
+v 0.132942 -0.492039 0.764488
+v 0.132968 -0.473889 0.769048
+v 0.132634 -0.456252 0.768688
+v 0.13266 -0.438526 0.767134
+v 0.132698 -0.420902 0.76418
+v 0.132724 -0.40324 0.761572
+v 0.132852 -0.385564 0.759915
+v 0.132852 -0.368082 0.756087
+v 0.133585 -0.350689 0.753004
+v 0.132827 -0.332835 0.750756
+v 0.337298 -0.977527 0.0293258
+v 0.325005 -0.975999 0.0255108
+v 0.334357 -0.975202 0.00271036
+v -0.157721 0.578886 -0.00477845
+v -0.864945 -0.416791 0.0905722
+v -0.864367 -0.41719 0.0775342
+v -0.854848 -0.435212 0.0777141
+v 0.151427 -0.0993841 0.58247
+v 0.145698 -0.0913172 0.58211
+v 0.139018 -0.14275 0.667955
+v 0.0290111 -0.945375 -0.205692
+v 0.015652 -0.945876 -0.207798
+v 0.722233 -0.863628 -0.0167117
+v 0.735772 -0.866146 -0.00407196
+v 0.36647 -0.973108 -0.0408866
+v 0.356515 -0.974907 -0.0171356
+v 0.353072 -0.973674 -0.0430317
+v 0.800744 -0.307902 0.0736164
+v 0.135242 -0.871618 0.643138
+v 0.368448 -0.877244 0.597281
+v 0.354318 -0.878092 0.598886
+v -0.841181 -0.453812 0.0777526
+v 0.849415 -0.68581 0.414248
+v -0.595373 0.721019 -0.488776
+v -0.587422 0.700968 -0.488789
+v -0.593279 0.721161 -0.50157
+v 0.695708 -0.060861 -0.0293772
+v 0.687705 -0.0429932 -0.0294157
+v -0.19266 -0.220541 -0.291267
+v -0.361627 0.546978 -0.0639696
+v -0.381011 0.248595 0.327118
+v -0.383297 0.266694 0.319231
+v -0.390902 0.267362 0.334517
+v -0.597326 0.578539 -0.463445
+v -0.120637 0.586465 -0.06194
+v 0.00753377 0.784809 -0.194542
+v -0.00383432 0.784912 -0.188376
+v 0.00193322 0.766004 -0.180104
+v 0.814565 -0.702574 0.431975
+v 0.813923 -0.72179 0.430215
+v 0.516015 -0.854482 0.539824
+v 0.525495 -0.854521 0.531448
+v 0.514435 -0.837488 0.538038
+v 0.571635 -0.637037 0.57737
+v 0.560909 -0.637024 0.584435
+v 0.558327 -0.654532 0.580479
+v -0.163386 0.616086 0.0325114
+v -0.152056 0.616292 0.0262815
+v -0.162641 0.634905 0.0337189
+v -0.172172 0.65416 -0.00226077
+v -0.186456 0.653723 -0.000500967
+v 0.406753 -0.840249 0.584911
+v 0.391916 -0.841251 0.586311
+v 0.396245 -0.858027 0.59159
+v 0.525803 -0.534095 0.601956
+v 0.517068 -0.534005 0.611783
+v 0.514396 -0.551423 0.607968
+v 0.335012 -0.327401 0.73416
+v 0.334858 -0.310124 0.734134
+v 0.667063 -0.532694 0.512938
+v 0.666228 -0.515559 0.511821
+v 0.65653 -0.532746 0.520247
+v 0.333496 -0.344806 0.731732
+v 0.322809 -0.327645 0.739054
+v 0.665252 -0.204728 0.51308
+v 0.673755 -0.204818 0.502598
+v 0.661899 -0.187747 0.508237
+v 0.623389 -0.445436 0.56342
+v 0.613382 -0.445308 0.571603
+v 0.609387 -0.463086 0.565591
+v 0.321306 -0.345089 0.736665
+v 0.364415 0.115209 0.484062
+v 0.359238 0.132589 0.476728
+v 0.308294 -0.345474 0.740441
+v 0.469258 -0.70829 0.631912
+v 0.472701 -0.690319 0.637242
+v 0.460151 -0.690512 0.641674
+v 0.353137 0.150059 0.468185
+v -0.0742394 0.918053 -0.130675
+v -0.085569 0.899209 -0.124509
+v 0.200778 -0.0619015 0.585617
+v 0.422308 -0.377074 0.702368
+v 0.409296 -0.377356 0.706337
+v 0.412687 -0.394274 0.710974
+v 0.448937 -0.655598 0.647891
+v 0.44877 -0.63836 0.647827
+v 0.435783 -0.638822 0.651847
+v 0.656748 -0.515495 0.520646
+v 0.714577 -0.172474 0.426233
+v 0.721758 -0.172833 0.413953
+v 0.710583 -0.155672 0.420761
+v 0.333689 -0.29313 0.732272
+v -0.32972 0.783165 0.00294157
+v 0.71775 -0.156032 0.408519
+v 0.713717 -0.138922 0.402302
+v 0.706601 -0.138562 0.414621
+v -0.0715804 0.689959 -0.0834302
+v -0.0839504 0.690139 -0.0786774
+v -0.0707455 0.672143 -0.0593196
+v 0.337889 -0.622509 0.713556
+v 0.326855 -0.622368 0.720146
+v -0.153521 0.708868 -0.0663203
+v -0.159365 0.727558 -0.0747083
+v -0.165235 0.708559 -0.0607839
+v 0.592945 -0.136648 0.543793
+v 0.58845 -0.119975 0.537396
+v 0.581706 -0.136623 0.550126
+v 0.475115 -0.568777 0.641417
+v 0.465623 -0.568456 0.65037
+v 0.46263 -0.586144 0.645913
+v 0.377132 -0.344511 0.70477
+v 0.388898 -0.344215 0.699221
+v 0.378403 -0.327067 0.706658
+v 0.0250676 0.766261 -0.191742
+v 0.0190303 0.784809 -0.200528
+v 0.0134811 0.766119 -0.185974
+v 0.602785 -0.690486 0.531436
+v 0.606523 -0.672182 0.537049
+v 0.59527 -0.672438 0.543305
+v -0.187034 0.63389 0.0429932
+v -0.200277 0.633928 0.0465
+v -0.197875 0.615752 0.0504435
+v 0.925343 -0.54843 0.344305
+v 0.915825 -0.542072 0.346168
+v 0.914566 -0.548713 0.351165
+v -0.227728 0.689446 -0.015607
+v -0.239109 0.689471 -0.00951837
+v -0.233367 0.670769 -0.00123315
+v 0.445841 -0.551076 0.667172
+v 0.457016 -0.550819 0.660685
+v 0.448641 -0.533247 0.671359
+v -0.231029 -0.239411 -0.289417
+v -0.231042 -0.221093 -0.287555
+v -0.184465 0.671424 -0.0206295
+v -0.194292 0.689805 -0.0346052
+v -0.20548 0.689638 -0.0286579
+v -0.196976 0.671051 -0.0162878
+v 0.585174 -0.153527 0.555084
+v -0.268447 -0.446708 -0.214761
+v 0.619484 -0.463253 0.557576
+v -0.0590563 0.672837 -0.0647531
+v 0.99237 -0.54333 0.214953
+v 0.985896 -0.525989 0.214953
+v 0.99025 -0.543626 0.227233
+v -0.141125 0.61624 0.0196276
+v -0.150438 0.63484 0.0286707
+v 0.357786 -0.327041 0.72197
+v 0.357876 -0.309829 0.722368
+v 0.346791 -0.309906 0.728585
+v 0.680281 -0.394055 0.510588
+v 0.679137 -0.376971 0.508558
+v 0.671841 -0.376534 0.521185
+v 0.369373 -0.309649 0.716408
+v 0.346393 -0.327234 0.728033
+v 0.02869 -0.958144 0.667699
+v 0.0428326 -0.955253 0.668058
+v 0.0252089 -0.947187 0.678797
+v 0.511211 -0.153668 0.606285
+v 0.504929 -0.16221 0.613337
+v 0.420048 -0.20722 0.654635
+v 0.413612 -0.190252 0.645348
+v 0.367292 -0.859787 0.594994
+v -0.618341 0.401839 -0.082287
+v -0.697236 0.686221 -0.156854
+v 0.536028 0.0498783 0.461763
+v 0.52439 0.0494801 0.467415
+v 0.529811 0.03255 0.47525
+v 0.568616 -0.783576 0.503471
+v 0.571532 -0.764976 0.50771
+v 0.560691 -0.764899 0.514557
+v 0.731739 -0.569753 0.425436
+v 0.726781 -0.568918 0.44103
+v 0.725496 -0.586414 0.438847
+v 0.464325 -0.72635 0.624346
+v 0.456888 -0.70847 0.636459
+v 0.730775 -0.58712 0.424165
+v 0.745111 -0.191177 0.379758
+v 0.747667 -0.208274 0.383586
+v 0.564699 -0.0861919 0.52554
+v 0.575373 -0.0860378 0.518449
+v 0.559137 -0.0694931 0.517357
+v -0.231389 0.708405 -0.0209121
+v -0.240612 0.70847 -0.0118048
+v -0.477389 0.338679 -0.0104304
+v -0.00287092 0.747237 -0.164484
+v -0.0151639 0.747391 -0.15959
+v -0.00596664 0.728238 -0.146488
+v -0.214125 0.765708 -0.0179577
+v -0.221729 0.765644 -0.00647403
+v -0.225763 0.74644 -0.0127682
+v -0.26855 -0.427825 -0.222943
+v -0.229513 0.76576 0.00491975
+v -0.237786 0.765824 0.01553
+v 0.743749 -0.0758515 0.214516
+v 0.748746 -0.0936936 0.227375
+v -0.599484 0.526632 0.484576
+v 0.366611 -0.361839 0.711976
+v 0.367022 -0.344562 0.712657
+v 0.356502 -0.344524 0.719979
+v -0.053186 -0.91456 0.708238
+v -0.052017 -0.931708 0.70838
+v 0.61563 -0.375866 0.575392
+v 0.613896 -0.358833 0.573029
+v 0.604275 -0.376033 0.581558
+v 0.896441 -0.632824 0.392578
+v 0.907193 -0.632759 0.3855
+v 0.895285 -0.615752 0.390908
+v 0.413625 -0.551127 0.688225
+v 0.403336 -0.55123 0.696074
+v 0.402334 -0.568494 0.69434
+v 0.896711 -0.650088 0.392822
+v 0.907437 -0.650023 0.385731
+v 0.904007 -0.598732 0.381004
+v 0.892485 -0.599002 0.386862
+v 0.906448 -0.615675 0.384485
+v 0.412122 -0.568571 0.686042
+v 0.399277 -0.586247 0.689741
+v 0.410478 -0.586401 0.683267
+v 0.426149 -0.411165 0.707994
+v 0.425096 -0.393914 0.706517
+v 0.363939 -0.842973 0.591076
+v 0.906589 -0.667416 0.384344
+v 0.896223 -0.66748 0.392
+v 0.400882 -0.429097 0.716305
+v 0.401319 -0.411782 0.716626
+v 0.388243 -0.41218 0.720095
+v 0.970353 -0.72346 0.201877
+v 0.970687 -0.723627 0.189031
+v -0.00948625 0.89903 -0.218152
+v -0.0102313 0.918105 -0.219256
+v -0.0181954 0.918118 -0.208042
+v -0.0364357 0.880018 -0.189468
+v -0.0269302 0.879967 -0.198293
+v -0.03641 0.899081 -0.189378
+v 0.726241 -0.622727 0.416753
+v 0.72872 -0.604936 0.420517
+v 0.719227 -0.622098 0.429251
+v 0.723248 -0.604012 0.435404
+v -0.00998722 0.691591 -0.106757
+v -0.0205204 0.709292 -0.122429
+v -0.0223958 0.691539 -0.102094
+v 0.715862 -0.640043 0.424152
+v 0.504929 -0.746132 0.57001
+v 0.49518 -0.745965 0.578488
+v 0.485983 -0.765721 0.564821
+v 0.611083 -0.238255 0.569805
+v 0.60854 -0.22117 0.566195
+v 0.59843 -0.221286 0.574095
+v 0.253714 -0.9198 0.611256
+v 0.366534 -0.825002 0.594814
+v -0.256925 -0.203058 -0.28013
+v -0.256861 -0.184959 -0.27629
+v -0.24408 -0.184754 -0.278255
+v 0.376926 -0.80436 0.609766
+v 0.365725 -0.804886 0.616086
+v -0.584634 0.539438 -0.308891
+v -0.550993 -0.448108 -0.210868
+v -0.538173 -0.447684 -0.215827
+v -0.538224 -0.467325 -0.203508
+v 0.90393 -0.778939 0.310843
+v 0.896184 -0.777924 0.322687
+v 0.887424 -0.797911 0.309315
+v 0.895259 -0.68513 0.390407
+v 0.894938 -0.797886 0.297908
+v 0.911483 -0.759453 0.322443
+v 0.902851 -0.759504 0.332385
+v 0.918856 -0.740814 0.33331
+v 0.910455 -0.740313 0.343933
+v 0.885638 -0.758926 0.35286
+v 0.893243 -0.739709 0.364318
+v 0.876595 -0.758643 0.362443
+v 0.396143 -0.37787 0.709587
+v 0.38218 -0.37841 0.711758
+v 0.385609 -0.395301 0.716382
+v -0.0101414 0.936551 -0.217073
+v -0.0172063 0.93718 -0.206655
+v 0.794591 -0.290419 0.0221196
+v 0.793075 -0.308531 0.0221324
+v 0.769658 -0.886814 0.0620299
+v -0.0346759 0.841958 -0.1874
+v -0.0243354 0.841906 -0.19503
+v -0.0355237 0.860918 -0.188312
+v 0.988722 -0.668302 0.150303
+v 0.571096 -0.68924 -0.23408
+v 0.743043 -0.906339 0.0751578
+v -0.218865 -0.0751321 -0.252667
+v -0.206006 -0.0569432 -0.247657
+v 0.347703 -0.622547 0.705104
+v 0.352083 -0.604731 0.711745
+v -0.0308351 0.955973 -0.180643
+v -0.0324665 0.937219 -0.183071
+v -0.404441 0.510626 -0.032049
+v 0.666677 -0.170971 0.492579
+v 0.66267 -0.153938 0.486644
+v 0.653922 -0.154105 0.496895
+v 0.905215 -0.685232 0.382173
+v 0.518353 -0.892132 0.519721
+v 0.510247 -0.891515 0.530845
+v 0.50159 -0.897218 0.53755
+v 0.924213 -0.722214 0.341402
+v 0.916133 -0.721893 0.352308
+v 0.879126 -0.777423 0.343226
+v 0.870378 -0.777436 0.353079
+v 0.927951 -0.703961 0.347157
+v 0.920141 -0.703717 0.358217
+v 0.930443 -0.686029 0.350741
+v 0.922697 -0.685836 0.361942
+v 0.932061 -0.668264 0.353156
+v 0.924547 -0.667776 0.365063
+v 0.933782 -0.65082 0.355609
+v 0.926088 -0.650293 0.367376
+v 0.898522 -0.721739 0.371974
+v 0.889004 -0.721186 0.381017
+v 0.883532 -0.739696 0.372848
+v 0.935709 -0.63317 0.358808
+v 0.926872 -0.632926 0.368622
+v 0.309707 0.0278229 0.540222
+v 0.582374 -0.428159 0.594673
+v 0.583838 -0.410638 0.596882
+v 0.57193 -0.428249 0.602059
+v 0.362989 -0.785927 0.634956
+v 0.374074 -0.785284 0.628508
+v 0.37112 -0.766081 0.647095
+v -0.0172063 0.879954 -0.206822
+v -0.007431 0.879954 -0.215351
+v -0.0183238 0.899017 -0.208287
+v -0.0698206 -0.923603 0.087348
+v 0.0740724 0.879826 -0.300452
+v 0.0810217 0.879774 -0.313027
+v 0.0702959 0.898811 -0.305988
+v 0.383914 -0.785503 0.62012
+v -0.268614 -0.409059 -0.229507
+v 0.390658 -0.766402 0.630152
+v 0.380921 -0.766312 0.638681
+v -0.590839 0.801315 -0.655752
+v -0.594641 0.821534 -0.668572
+v -0.600152 0.821521 -0.65574
+v 0.396335 -0.747327 0.638655
+v 0.38674 -0.747327 0.647339
+v 0.379868 -0.30961 0.708958
+v 0.38069 -0.292192 0.710332
+v 0.369835 -0.292295 0.717153
+v -0.0248878 0.937231 -0.194555
+v -0.0349071 0.918195 -0.186886
+v 0.354729 -0.640081 0.692439
+v -0.144991 0.690409 -0.0538603
+v -0.156681 0.68987 -0.0484139
+v 0.360022 -0.60536 0.699786
+v 0.362013 -0.587248 0.703563
+v -0.317812 -0.944091 0.57791
+v 0.936095 -0.615752 0.35963
+v 0.926936 -0.615598 0.369033
+v 0.935337 -0.598591 0.358538
+v 0.925626 -0.59845 0.367093
+v 0.933282 -0.581648 0.355699
+v 0.923262 -0.581725 0.36383
+v 0.863583 -0.795676 0.343201
+v 0.930301 -0.564975 0.351537
+v 0.919537 -0.56527 0.358409
+v 0.902376 -0.703421 0.377832
+v 0.892857 -0.702972 0.386759
+v 0.871842 -0.796319 0.332411
+v -0.254202 -0.972158 0.484448
+v -0.259225 -0.972916 0.461377
+v -0.260034 0.630447 -0.138113
+v -0.231106 -0.202814 -0.284395
+v -0.231273 -0.18451 -0.280169
+v 0.573896 -0.410561 0.605091
+v 0.377016 -0.747211 0.655894
+v 0.614487 -0.550203 0.549676
+v 0.603735 -0.550267 0.556612
+v 0.603774 -0.567531 0.556535
+v 0.678623 -0.342404 0.508712
+v 0.678983 -0.325166 0.508969
+v 0.670338 -0.342212 0.518911
+v 0.978407 -0.580158 0.098562
+v 0.975221 -0.562598 0.0985748
+v 0.894463 -0.766235 0.0230573
+v 0.906769 -0.747147 0.022916
+v -0.268743 -0.390381 -0.236045
+v -0.255885 -0.389791 -0.242635
+v -0.261447 0.745323 -0.152641
+v -0.24855 0.7454 -0.16081
+v 0.400626 -0.728932 0.645078
+v 0.391531 -0.728495 0.654584
+v 0.357016 -0.804784 0.62608
+v -0.0964104 0.6724 -0.0511371
+v -0.10801 0.67204 -0.0454081
+v -0.0884591 0.653183 -0.0171742
+v -0.0267632 0.918118 -0.197946
+v -0.231594 -0.0934881 -0.257368
+v 0.679574 -0.0252153 -0.0294029
+v -0.605675 0.307105 -0.0801033
+v -0.433214 -0.824129 -0.0944772
+v -0.433227 -0.805811 -0.0895574
+v -0.420356 -0.805207 -0.0958773
+v -0.229141 -0.597062 -0.159256
+v -0.216257 -0.615701 -0.154349
+v -0.167342 -0.237728 -0.304331
+v -0.15555 -0.218267 -0.303945
+v -0.156501 -0.23503 -0.321967
+v 0.919794 -0.532605 0.336174
+v -0.0374376 0.619118 -0.0772388
+v -0.0309122 0.621353 -0.0888509
+v -0.0166411 0.636035 -0.0707391
+v 0.47455 -0.927328 0.546876
+v 0.482823 -0.916962 0.549329
+v 0.469322 -0.908805 0.562072
+v -0.268807 -0.371126 -0.249199
+v -0.256052 -0.370189 -0.260618
+v 0.404672 -0.710358 0.651154
+v 0.394897 -0.710204 0.659632
+v 0.0138151 0.665566 -0.170419
+v -0.630633 0.194645 -0.0940276
+v 0.59152 -0.690782 0.537704
+v 0.584378 -0.672361 0.550215
+v -0.107933 0.689959 -0.0682342
+v 0.0783884 0.860609 -0.293862
+v 0.0854277 0.861046 -0.307182
+v 0.626664 -0.410279 0.568571
+v 0.62678 -0.39304 0.568828
+v 0.61617 -0.393092 0.57606
+v -0.725856 0.252372 0.687378
+v 0.359456 -0.127194 -0.26979
+v 0.346624 -0.109686 -0.259347
+v 0.364466 -0.106166 -0.261286
+v -0.357286 -0.624294 0.526182
+v 0.987848 -0.561455 0.137111
+v -0.363978 0.482161 0.101927
+v 0.517672 -0.942511 -0.00156713
+v 0.0766928 0.89894 -0.319591
+v 0.0857359 0.880866 -0.323907
+v 0.806357 -0.307452 0.15038
+v 0.805522 -0.307529 0.163187
+v 0.407202 -0.692362 0.655072
+v 0.397825 -0.692053 0.664102
+v -0.268948 -0.351935 -0.26225
+v -0.256116 -0.351512 -0.267169
+v 0.776363 -0.794906 0.420311
+v 0.787064 -0.79497 0.413297
+v 0.793358 -0.776267 0.422636
+v 0.402026 -0.621867 0.670692
+v 0.4062 -0.60423 0.677063
+v 0.394781 -0.604423 0.683164
+v 0.429232 -0.74725 0.618604
+v 0.442437 -0.74671 0.615226
+v 0.436592 -0.727673 0.62933
+v -0.0307452 0.728367 -0.137059
+v -0.0383111 0.747095 -0.148004
+v -0.0424473 0.72784 -0.131587
+v 0.449964 -0.727622 0.626555
+v 0.409026 -0.674237 0.657705
+v 0.398236 -0.674404 0.664911
+v 0.411287 -0.326682 0.68662
+v 0.399341 -0.327041 0.691706
+v 0.401435 -0.34401 0.694699
+v 0.774013 -0.818708 0.398667
+v 0.767924 -0.814585 0.407979
+v 0.756787 -0.826749 0.40225
+v -0.708052 0.325628 -0.0791142
+v -0.708091 0.344395 -0.0758001
+v -0.603774 -0.116533 -0.208531
+v -0.59152 -0.0977013 -0.211626
+v -0.420793 -0.786479 -0.0932697
+v 0.621706 -0.823152 0.421339
+v 0.409759 -0.656857 0.658989
+v 0.397761 -0.65723 0.664346
+v -0.473741 -0.504127 -0.178678
+v -0.460896 -0.504114 -0.178537
+v -0.638765 -0.958465 -0.070328
+v -0.625277 -0.957463 -0.0772002
+v -0.626973 -0.978722 -0.0744899
+v 0.411017 -0.145088 -0.275108
+v 0.398057 -0.126989 -0.27286
+v 0.416335 -0.12352 -0.268852
+v -0.269334 -0.333682 -0.26469
+v -0.256399 -0.333374 -0.267568
+v 0.671096 -0.324909 0.520016
+v 0.662554 -0.324626 0.530601
+v 0.662618 -0.341865 0.530626
+v -0.714192 0.252628 0.681803
+v -0.728707 0.270535 0.683383
+v -0.707744 0.678566 -0.141722
+v 0.670094 -0.00795124 -0.0304048
+v 0.32963 -0.658103 0.701006
+v 0.75567 -0.0938092 0.175891
+v 0.754539 -0.0936422 0.188774
+v 0.761912 -0.110983 0.188852
+v -0.034496 0.635701 -0.0517537
+v -0.0327619 0.654609 -0.0491076
+v -0.0440273 0.635701 -0.0429932
+v 0.550376 -0.817616 -0.181427
+v 0.527961 -0.838682 -0.155993
+v 0.50597 -0.843602 -0.182789
+v 0.410696 -0.639619 0.660711
+v 0.398326 -0.63985 0.665284
+v 0.385674 -0.464319 0.716357
+v 0.398018 -0.464075 0.711758
+v 0.387292 -0.446901 0.719157
+v 0.612303 -0.341852 0.570485
+v 0.599843 -0.342224 0.575033
+v 0.602541 -0.358988 0.57913
+v 0.538057 -0.727776 0.550293
+v 0.54448 -0.709471 0.559747
+v 0.529027 -0.727378 0.559978
+v 0.367241 -0.551937 0.711617
+v 0.369116 -0.534236 0.71416
+v 0.35672 -0.534493 0.718643
+v 0.388872 -0.327067 0.699131
+v 0.3899 -0.309649 0.700865
+v -0.26909 -0.315403 -0.263958
+v -0.25627 -0.31498 -0.268903
+v 0.542142 -0.0352732 0.515263
+v 0.806421 -0.397434 0.0735136
+v -0.432752 -0.570061 0.483523
+v 0.413753 -0.621879 0.665322
+v -0.855311 0.460029 0.060694
+v 0.377799 -0.569072 0.703999
+v 0.372096 -0.728264 0.671642
+v 0.376078 -0.709921 0.677667
+v 0.362282 -0.72811 0.680017
+v 0.378403 -0.691938 0.681212
+v 0.368448 -0.691861 0.689343
+v 0.366187 -0.709818 0.685888
+v 0.0726466 -0.0142326 -0.256302
+v 0.0764873 -0.0362237 -0.266283
+v 0.0550357 -0.0343098 -0.260875
+v 0.315525 0.0625438 0.525976
+v -0.717198 0.270663 0.677371
+v -0.719561 0.288621 0.673864
+v -0.731572 0.288749 0.679375
+v -0.722953 0.307105 0.66942
+v -0.622066 0.892633 -0.754404
+v -0.622901 0.86928 -0.759954
+v -0.635142 0.874469 -0.753197
+v -0.635425 0.516214 0.504923
+v -0.0922614 0.860969 -0.134799
+v -0.100726 0.860892 -0.124561
+v -0.104002 0.841714 -0.129583
+v -0.829825 -0.0529997 0.398268
+v -0.827423 -0.0356329 0.395211
+v -0.838085 -0.0532823 0.388313
+v -0.310888 0.573234 -0.0931413
+v -0.311132 0.591873 -0.103533
+v -0.29812 0.573273 -0.0949396
+v 0.0747404 0.84224 -0.277638
+v 0.0660955 0.841804 -0.267079
+v 0.0710923 0.823024 -0.259989
+v 0.599766 -0.238383 0.576086
+v 0.600704 -0.255544 0.577358
+v 0.243643 -0.137021 0.647159
+v 0.599728 -0.290471 0.575855
+v 0.61256 -0.28997 0.571757
+v 0.6001 -0.272937 0.576446
+v 0.555758 -0.70915 0.553517
+v 0.560794 -0.691064 0.561031
+v 0.550492 -0.690627 0.568803
+v 0.804996 -0.38577 0.28207
+v 0.805766 -0.402996 0.283444
+v 0.359071 -0.465231 0.723267
+v 0.371236 -0.464987 0.718335
+v 0.359482 -0.447851 0.723884
+v 0.288807 -0.0075145 0.554827
+v 0.300535 -0.00727044 0.549548
+v 0.568604 -0.533619 0.573671
+v 0.557235 -0.533748 0.579862
+v 0.558815 -0.550845 0.581841
+v 0.3727 -0.412886 0.720043
+v 0.370889 -0.395879 0.717692
+v 0.358943 -0.413323 0.723139
+v 0.373239 -0.44735 0.721058
+v 0.373689 -0.429983 0.721456
+v 0.359867 -0.430459 0.724308
+v 0.0211369 0.747429 -0.174902
+v 0.0094991 0.74716 -0.169224
+v -0.113623 0.653492 -0.00828522
+v -0.125222 0.653171 -0.00264613
+v -0.115524 0.635495 0.0117791
+v 0.65802 -0.729086 0.452553
+v 0.649824 -0.72847 0.463445
+v 0.644571 -0.747057 0.45579
+v 0.653036 -0.747789 0.445077
+v 0.63861 -0.766607 0.446451
+v 0.103784 0.822895 -0.336033
+v 0.102216 0.842138 -0.337793
+v 0.105081 0.821983 -0.324922
+v 0.802696 -0.253515 0.15029
+v 0.800949 -0.235608 0.150264
+v 0.801553 -0.253579 0.163174
+v 0.417517 -0.603935 0.670833
+v 0.692895 -0.00608867 0.0347337
+v 0.420446 -0.586606 0.675239
+v 0.440857 -0.233232 -0.306617
+v 0.440446 -0.246977 -0.317626
+v 0.428731 -0.2432 -0.321659
+v -0.834797 0.478102 0.513709
+v -0.824752 0.47841 0.521789
+v -0.399521 -0.956898 -0.150752
+v -0.705123 0.270612 0.672105
+v -0.701976 0.252654 0.676677
+v -0.708515 0.288981 0.667403
+v -0.711495 0.307118 0.663241
+v -0.089384 0.879941 -0.130585
+v -0.0974123 0.880044 -0.119461
+v -0.0227683 0.659837 -0.164882
+v -0.0338409 0.647891 -0.151202
+v -0.37559 0.552489 -0.0620813
+v 0.633459 -0.785259 0.43886
+v 0.799947 -0.235621 0.163135
+v 0.39076 -0.292243 0.702291
+v 0.35297 -0.569586 0.71294
+v 0.364016 -0.569663 0.706607
+v 0.354575 -0.552142 0.715509
+v -0.642181 0.4343 0.560299
+v 0.680537 -0.255814 0.511834
+v 0.678713 -0.238756 0.509303
+v 0.670672 -0.238499 0.520247
+v 0.573228 -0.324292 0.604525
+v 0.581102 -0.324575 0.593427
+v 0.571905 -0.30717 0.602881
+v -0.983519 0.0928843 0.229134
+v -0.990173 0.110521 0.229134
+v 0.340124 0.0628649 0.516394
+v 0.477004 0.0491718 0.489406
+v 0.466689 0.0489149 0.493298
+v -0.0954984 0.822741 -0.139898
+v -0.105299 0.822741 -0.131407
+v -0.105209 0.803653 -0.131497
+v 0.542386 -0.768367 -0.250342
+v 0.552765 -0.763486 -0.246424
+v -0.591096 0.459785 -0.116121
+v -0.589747 0.459926 -0.103289
+v -0.66872 0.0713042 0.678501
+v -0.662875 0.0905208 0.687031
+v -0.686279 0.23503 0.676857
+v -0.697917 0.234838 0.682676
+v -0.690878 0.253078 0.670268
+v -0.694128 0.27092 0.665541
+v -0.697635 0.289148 0.660531
+v -0.700049 0.30717 0.657153
+v -0.703441 0.32559 0.652464
+v 0.735991 -0.588276 0.408313
+v -0.567987 0.362905 -0.0643421
+v -0.576966 0.375211 -0.0646247
+v -0.228935 -0.635123 -0.141311
+v -0.216167 -0.634815 -0.144561
+v 0.841939 -0.862356 0.176738
+v 0.870995 -0.840969 0.17661
+v -0.426984 0.464358 0.168684
+v -0.4248 0.483266 0.172371
+v 0.603414 -0.187387 0.55886
+v 0.613446 -0.187272 0.550781
+v 0.600023 -0.170393 0.554018
+v 0.579548 -0.307491 0.591552
+v 0.570299 -0.290124 0.600954
+v -0.368165 0.15223 0.355147
+v -0.380523 0.153206 0.367221
+v 0.357941 -0.3962 0.721752
+v -0.0430639 0.918259 -0.175839
+v -0.0450035 0.899068 -0.179282
+v 0.0421647 0.729292 -0.166745
+v 0.0333271 0.747172 -0.17986
+v 0.030681 0.729202 -0.160823
+v -0.269192 -0.296341 -0.272218
+v -0.256013 -0.295313 -0.282879
+v 0.076179 0.732914 -0.269237
+v -0.732959 -0.0479515 -0.111805
+v -0.164285 0.633273 -0.149237
+v -0.177015 0.63696 -0.152422
+v 0.486882 -0.0531538 0.548494
+v -0.2518 -0.927456 -0.361428
+v -0.0983243 -0.955408 0.704115
+v -0.71802 0.52658 -0.491692
+v -0.360535 0.632759 0.108491
+v -0.65942 0.108915 0.692246
+v -0.657801 0.127117 0.694648
+v -0.523144 -0.779864 0.105987
+v -0.515681 -0.762741 0.105884
+v -0.519958 -0.762574 0.0928073
+v -0.658405 0.145023 0.694224
+v -0.658906 0.16302 0.693441
+v -0.67012 0.16302 0.699915
+v -0.381602 -0.89569 0.590819
+v -0.395051 -0.896589 0.59335
+v -0.661642 0.181157 0.68969
+v -0.66556 0.199051 0.684063
+v -0.670043 0.217201 0.677692
+v -0.674886 0.235043 0.670704
+v -0.679857 0.252808 0.663472
+v -0.68398 0.271177 0.657487
+v -0.68696 0.289199 0.653286
+v -0.689259 0.307298 0.650075
+v -0.69215 0.325461 0.646016
+v -0.6959 0.343689 0.640736
+v -0.699831 0.361878 0.63529
+v -0.455102 0.401249 0.0219655
+v 0.694911 -0.569406 -0.144407
+v -0.619484 0.529419 -0.437832
+v 0.663029 -0.710383 0.460041
+v 0.65504 -0.709934 0.471127
+v 0.66353 -0.636934 0.50694
+v 0.654526 -0.636716 0.516548
+v 0.651777 -0.654584 0.512232
+v 0.566985 -0.801585 0.50089
+v 0.557865 -0.783576 0.510446
+v 0.556298 -0.801611 0.508006
+v 0.554769 -0.819646 0.505642
+v 0.625598 -0.427774 0.566799
+v 0.568886 -0.654969 0.573131
+v 0.616272 -0.41033 0.576073
+v 0.605277 -0.393143 0.582868
+v 0.671713 -0.0436869 -0.0695444
+v 0.682927 -0.0614519 -0.0680287
+v 0.391094 -0.823974 0.585373
+v 0.404274 -0.823242 0.581815
+v 0.398288 -0.804373 0.595444
+v -0.613074 0.479168 -0.276444
+v -0.26927 -0.277124 -0.282134
+v -0.256514 -0.276623 -0.287555
+v 0.348191 -0.465308 0.729883
+v 0.347536 -0.482649 0.728701
+v 0.346714 -0.499978 0.727224
+v 0.348178 -0.448005 0.730075
+v -0.269398 -0.258383 -0.285641
+v -0.256668 -0.25819 -0.287581
+v -0.120881 -0.964155 0.684462
+v -0.66669 0.0529997 0.65863
+v -0.658739 0.072075 0.670396
+v -0.117117 -0.922652 -0.0405012
+v -0.130463 -0.92323 -0.0426849
+v -0.121202 -0.922318 -0.0653826
+v -0.652342 0.090585 0.679914
+v -0.648527 0.108877 0.685554
+v -0.647024 0.127104 0.68793
+v -0.648026 0.145075 0.686594
+v -0.649066 0.163058 0.68522
+v -0.651237 0.181093 0.682214
+v -0.655553 0.199231 0.675945
+v -0.660062 0.217355 0.66942
+v -0.665136 0.235056 0.662137
+v -0.670158 0.252783 0.654943
+v -0.674346 0.271049 0.648739
+v -0.677211 0.28916 0.644628
+v -0.679446 0.30726 0.641546
+v -0.681745 0.325359 0.638411
+v -0.685149 0.34374 0.633569
+v -0.688399 0.361801 0.629034
+v -0.510825 -0.745361 0.10564
+v -0.506484 -0.728123 0.105627
+v -0.509605 -0.727917 0.0926146
+v 0.422013 -0.568674 0.677654
+v 0.46868 0.0832247 0.477241
+v 0.460819 0.065845 0.488314
+v 0.66818 -0.691771 0.467607
+v 0.660537 -0.690936 0.479515
+v 0.635091 -0.120142 0.492039
+v 0.6308 -0.103161 0.485835
+v 0.620036 -0.103366 0.492887
+v -0.259636 0.727571 0.0286579
+v -0.26769 0.727763 0.0398846
+v 0.540537 0.0670525 0.445693
+v 0.529631 0.06659 0.45245
+v 0.710069 -0.189186 0.442238
+v 0.717827 -0.189545 0.431191
+v 0.706652 -0.172448 0.437973
+v -0.677878 0.516381 -0.532733
+v 0.547563 0.0500967 0.455918
+v 0.442257 -0.709253 0.637897
+v 0.446136 -0.691013 0.643768
+v 0.431454 -0.691681 0.645052
+v -0.220997 0.708367 -0.0283881
+v -0.222025 0.727404 -0.0297754
+v -0.36778 -0.895073 0.587788
+v -0.19889 0.65353 0.00398204
+v -0.209321 0.671103 -0.0115736
+v -0.210567 0.652708 0.0094156
+v 0.330644 -0.6045 0.725734
+v 0.615373 -0.427646 0.574647
+v 0.605405 -0.410369 0.582945
+v -0.643286 0.00858066 0.5101
+v -0.650775 -0.00545925 0.50464
+v -0.210361 0.708431 -0.03562
+v 0.433612 -0.673659 0.648174
+v 0.448359 -0.672991 0.647056
+v 0.435077 -0.656138 0.650486
+v -0.108883 0.861007 -0.113514
+v -0.112531 0.841894 -0.118909
+v 0.915401 -0.598552 0.374941
+v -0.610556 -0.91104 0.532784
+v -0.622156 -0.928574 0.525886
+v -0.615373 -0.92779 0.537216
+v 0.352687 -0.58703 0.712593
+v 0.902183 -0.739889 0.354672
+v 0.691636 -0.0702766 0.392706
+v 0.700268 -0.0705464 0.382777
+v 0.687384 -0.0531538 0.386399
+v 0.46904 -0.533311 0.655688
+v 0.479907 -0.533362 0.64879
+v 0.471159 -0.515636 0.658951
+v 0.368011 -0.327144 0.714288
+v 0.531288 -0.746787 0.540196
+v 0.523337 -0.746389 0.551436
+v 0.517569 -0.765387 0.542752
+v 0.00667313 0.842009 -0.217959
+v 0.00434813 0.860918 -0.22108
+v -0.00578681 0.861059 -0.213283
+v -0.269539 -0.239989 -0.284254
+v -0.256681 -0.239796 -0.286026
+v -0.807577 -0.501391 0.116417
+v -0.791598 -0.51159 0.105383
+v -0.679792 0.0344768 0.639323
+v -0.657801 0.052563 0.649034
+v -0.677583 0.0429161 0.652965
+v -0.649208 0.0720364 0.661892
+v -0.643055 0.090752 0.671103
+v -0.638353 0.109005 0.677962
+v -0.636607 0.127181 0.680608
+v -0.637146 0.145152 0.679773
+v -0.638739 0.163045 0.677744
+v -0.641436 0.181106 0.673826
+v -0.645727 0.199256 0.667467
+v -0.649876 0.217073 0.661623
+v -0.655348 0.235069 0.653633
+v -0.66046 0.252757 0.646375
+v -0.664751 0.270946 0.639927
+v -0.667859 0.288968 0.635572
+v -0.670467 0.307195 0.631719
+v -0.672612 0.325384 0.628829
+v -0.674783 0.343586 0.625874
+v -0.67784 0.361749 0.621571
+v -0.680961 0.379874 0.617204
+v -0.510851 0.338846 -0.0396277
+v -0.274331 -0.975292 0.392205
+v -0.287099 -0.974727 0.389084
+v -0.279353 -0.976114 0.36911
+v 0.624956 -0.120399 0.500106
+v 0.802285 -0.27164 0.175955
+v 0.800988 -0.253643 0.175942
+v 0.801258 -0.271691 0.188839
+v 0.673678 -0.673042 0.475957
+v 0.665521 -0.672721 0.486773
+v 0.689195 -0.411486 0.500928
+v 0.680794 -0.411281 0.511012
+v 0.681 -0.428571 0.511179
+v 0.720525 -0.206565 0.43498
+v 0.713306 -0.206218 0.447068
+v 0.750801 -0.57204 0.384588
+v 0.765239 -0.328647 0.385243
+v 0.758136 -0.345564 0.396817
+v 0.664083 -0.376226 0.532373
+v 0.663145 -0.35909 0.531063
+v -0.19952 0.708624 -0.0424922
+v -0.202757 0.727365 -0.0470909
+v -0.213148 0.727404 -0.0395507
+v 0.386971 -0.657217 0.671218
+v 0.386778 -0.639978 0.671038
+v 0.323014 -0.236456 -0.381017
+v 0.311556 -0.232346 -0.385487
+v 0.806563 -0.379283 0.266026
+v 0.807436 -0.386977 0.263329
+v 0.38927 -0.62247 0.674982
+v -0.216874 0.689715 -0.0224921
+v 0.512868 0.117984 0.428198
+v 0.533587 0.0840853 0.435597
+v 0.523555 0.0837513 0.443677
+v 0.565212 -0.672451 0.567672
+v 0.516644 -0.602868 0.610897
+v 0.526355 -0.602945 0.602316
+v 0.515039 -0.585784 0.608739
+v -0.617454 0.00923577 0.502559
+v -0.218646 0.746363 -0.0251511
+v -0.230297 0.727378 -0.0193579
+v -0.221768 0.671013 -0.00696215
+v -0.107791 -0.92174 -0.0632502
+v 0.423567 -0.551205 0.68003
+v 0.613832 -0.515687 0.54879
+v 0.61283 -0.498513 0.547518
+v 0.600922 -0.49886 0.552939
+v 0.425918 -0.533619 0.683652
+v 0.41446 -0.533786 0.689703
+v 0.428063 -0.51597 0.686941
+v 0.42796 -0.498706 0.686928
+v 0.417556 -0.498899 0.694622
+v 0.427215 -0.481622 0.68608
+v 0.417569 -0.481326 0.69452
+v -0.269578 -0.221607 -0.282571
+v -0.25672 -0.221453 -0.284292
+v -0.649824 0.0521262 0.63791
+v -0.671559 0.0333079 0.628752
+v -0.687667 0.0308673 0.637204
+v -0.680704 0.0244574 0.618141
+v -0.641167 0.0715483 0.650974
+v -0.63477 0.0902896 0.660415
+v -0.630081 0.109005 0.667737
+v -0.627936 0.127001 0.670692
+v -0.628039 0.145036 0.670653
+v -0.629876 0.16293 0.667994
+v -0.632457 0.18108 0.664115
+v -0.636298 0.199051 0.658578
+v -0.640691 0.217201 0.652066
+v -0.645919 0.234825 0.644731
+v -0.651366 0.252808 0.636729
+v -0.656208 0.271087 0.629201
+v -0.659266 0.289032 0.624847
+v -0.661732 0.307028 0.621674
+v -0.663415 0.325153 0.619683
+v -0.665264 0.343458 0.616998
+v -0.667744 0.361544 0.61371
+v -0.670441 0.379848 0.609843
+v -0.674269 0.398037 0.604358
+v -0.598584 0.619002 -0.553119
+v -0.606549 0.598013 -0.540466
+v -0.23162 -0.0755304 -0.249122
+v -0.935774 0.0777012 0.59001
+v 0.689658 -0.428712 0.501313
+v 0.764083 -0.31155 0.383779
+v 0.756736 -0.311087 0.396008
+v 0.757571 -0.328287 0.396483
+v 0.725303 -0.257959 0.441544
+v 0.723762 -0.240901 0.439887
+v 0.717365 -0.240374 0.452437
+v -0.202847 0.746081 -0.0473221
+v -0.211157 0.746402 -0.0367504
+v 0.0127875 0.680338 -0.188967
+v -0.403285 0.346052 0.191845
+v 0.919832 -0.759928 0.311768
+v -0.459393 -0.882459 0.611873
+v -0.446432 0.34514 0.346117
+v -0.445571 0.340953 0.351704
+v -0.441345 0.344986 0.33313
+v 0.764456 -0.46753 0.381981
+v 0.764494 -0.450074 0.382777
+v 0.757648 -0.466824 0.395327
+v 0.672509 -0.255557 0.522778
+v 0.661681 -0.238319 0.529869
+v 0.722015 -0.223765 0.437395
+v 0.764032 -0.432912 0.381647
+v 0.756916 -0.432386 0.394004
+v 0.765008 -0.795201 0.426785
+v 0.683081 -0.0703408 0.403368
+v 0.678893 -0.0531795 0.397087
+v 0.751161 -0.554519 0.385577
+v 0.75233 -0.537088 0.387029
+v 0.763659 -0.484974 0.380799
+v 0.757224 -0.484293 0.394325
+v 0.756145 -0.501917 0.392128
+v 0.761347 -0.520055 0.377279
+v 0.75418 -0.51949 0.389585
+v 0.762709 -0.502405 0.379527
+v 0.757391 -0.449547 0.395134
+v -0.174625 0.634198 0.0384074
+v 0.659394 -0.221389 0.526876
+v 0.668078 -0.221633 0.516998
+v 0.656093 -0.204382 0.522084
+v -0.435693 0.443921 0.191331
+v 0.809299 -0.397074 0.240387
+v 0.927411 -0.740711 0.323329
+v 0.932614 -0.722638 0.330741
+v 0.936095 -0.704577 0.335673
+v 0.495912 -0.0531924 0.538732
+v -0.269642 -0.203277 -0.279488
+v -0.642438 0.0522932 0.626401
+v -0.664738 0.0335648 0.617897
+v -0.633331 0.0712657 0.639773
+v -0.626844 0.0898657 0.649214
+v -0.622091 0.108735 0.656767
+v -0.620049 0.126783 0.659555
+v -0.620023 0.144831 0.659593
+v -0.621796 0.162763 0.656947
+v -0.623903 0.180862 0.654005
+v -0.627525 0.198909 0.648636
+v -0.6317 0.216726 0.642843
+v -0.63712 0.234722 0.63484
+v -0.642849 0.252539 0.626568
+v -0.647731 0.270419 0.61958
+v -0.650903 0.288749 0.614519
+v -0.653241 0.30681 0.611436
+v -0.654962 0.325114 0.608841
+v -0.656478 0.343329 0.607043
+v -0.658482 0.361608 0.604243
+v -0.661025 0.380002 0.600556
+v -0.663736 0.397986 0.596985
+v -0.668116 0.416509 0.590819
+v -0.673293 0.434222 0.583266
+v -0.684982 0.43394 0.588906
+v -0.212635 -0.874932 -0.360182
+v -0.226764 -0.876704 -0.35823
+v -0.224992 -0.858991 -0.349392
+v 0.688078 -0.394415 0.498937
+v 0.430093 -0.463998 0.690383
+v 0.418365 -0.464165 0.696202
+v 0.722863 -0.343355 0.459463
+v 0.730698 -0.343625 0.448429
+v 0.721822 -0.326193 0.458089
+v 0.730018 -0.326463 0.447312
+v 0.729324 -0.309276 0.44613
+v 0.721052 -0.309032 0.45692
+v 0.762413 -0.294478 0.381236
+v 0.755361 -0.294003 0.39358
+v 0.758483 -0.2604 0.37665
+v 0.630004 -0.29584 -0.227837
+v 0.630094 -0.314389 -0.22785
+v 0.938214 -0.68662 0.339026
+v 0.939704 -0.66879 0.341377
+v 0.718277 -0.257523 0.454441
+v 0.759947 -0.277536 0.378281
+v 0.753345 -0.276996 0.390857
+v 0.715772 -0.223277 0.450754
+v 0.809556 -0.379116 0.201838
+v 0.809106 -0.379155 0.214658
+v 0.810493 -0.397022 0.214671
+v 0.67003 -0.0190753 0.384216
+v 0.678418 -0.0181504 0.371833
+v 0.213418 -0.159372 0.694353
+v 0.683004 -0.0360696 0.379938
+v 0.674552 -0.0360696 0.390728
+v 0.68705 -0.0872067 0.408814
+v 0.695464 -0.0872453 0.39805
+v 0.763441 -0.398179 0.382083
+v 0.757327 -0.397523 0.395789
+v 0.756916 -0.41498 0.394787
+v 0.699215 -0.104548 0.404049
+v 0.763313 -0.415468 0.382058
+v 0.764584 -0.380735 0.383432
+v 0.757776 -0.380272 0.395931
+v 0.758406 -0.362687 0.397845
+v 0.805676 -0.420581 0.282494
+v 0.42191 -0.656523 0.653877
+v 0.395243 -0.911425 0.59028
+v 0.409322 -0.910603 0.588032
+v 0.396721 -0.893352 0.592399
+v -0.269758 -0.185165 -0.273258
+v -0.635116 0.0525758 0.614892
+v -0.655335 0.0331152 0.607531
+v 0.863711 -0.815407 0.319103
+v 0.845124 -0.825657 0.324614
+v 0.850609 -0.8319 0.307671
+v -0.625881 0.0712786 0.628315
+v -0.619561 0.0898529 0.637666
+v -0.615232 0.10835 0.644166
+v -0.612624 0.126578 0.648109
+v -0.612393 0.144574 0.648199
+v -0.613768 0.162557 0.645797
+v -0.616028 0.180618 0.64274
+v -0.619381 0.19882 0.637576
+v -0.623042 0.216533 0.632849
+v -0.628771 0.234324 0.624577
+v -0.634872 0.252397 0.615354
+v -0.639522 0.270394 0.608572
+v -0.643016 0.288544 0.603228
+v -0.645817 0.306502 0.599837
+v -0.64723 0.324896 0.597396
+v -0.648373 0.343175 0.595906
+v -0.650261 0.36148 0.593209
+v -0.651648 0.37981 0.591564
+v -0.653986 0.397986 0.58843
+v -0.657596 0.416342 0.583254
+v -0.661835 0.434261 0.577255
+v -0.780859 0.708649 -0.313515
+v -0.785034 0.690371 -0.300696
+v -0.778881 0.697679 -0.289417
+v 0.731199 -0.360863 0.448828
+v 0.723222 -0.360478 0.460337
+v 0.75102 -0.242686 0.387915
+v 0.749812 -0.225358 0.385552
+v 0.610312 -0.637088 0.542791
+v 0.611866 -0.619683 0.54527
+v 0.600563 -0.619914 0.551487
+v 0.732368 -0.552284 0.426528
+v 0.727538 -0.551539 0.442135
+v -0.190926 0.803653 -0.0296084
+v -0.202538 0.784655 -0.023828
+v 0.941631 -0.65109 0.344524
+v 0.944046 -0.633492 0.348133
+v 0.944868 -0.616022 0.349354
+v -0.229834 -0.774148 -0.138395
+v -0.215538 -0.765027 -0.118472
+v 0.766768 -0.277998 0.364948
+v 0.719176 -0.274671 0.454993
+v 0.751932 -0.259886 0.389238
+v 0.67739 -0.655097 0.481699
+v 0.669311 -0.654789 0.492553
+v 0.680512 -0.637358 0.486349
+v 0.672342 -0.637075 0.497177
+v 0.686613 -0.584705 0.495584
+v 0.678174 -0.584345 0.50613
+v 0.676684 -0.601815 0.50387
+v 0.682631 -0.619734 0.489676
+v 0.674577 -0.619426 0.500581
+v 0.684789 -0.60211 0.493015
+v 0.687435 -0.567313 0.496779
+v 0.678572 -0.567133 0.50658
+v 0.687063 -0.550074 0.496509
+v 0.678148 -0.549907 0.506195
+v 0.676928 -0.532746 0.504602
+v 0.686254 -0.5329 0.495302
+v 0.691366 -0.10424 0.415199
+v 0.6852 -0.515764 0.493915
+v 0.6759 -0.51561 0.503202
+v 0.702773 -0.121619 0.409251
+v 0.695155 -0.121491 0.421249
+v 0.699022 -0.138382 0.426605
+v 0.702837 -0.155287 0.431962
+v 0.729632 -0.379334 0.448956
+v 0.722837 -0.377832 0.459502
+v 0.56475 -0.324035 0.615084
+v 0.563684 -0.306926 0.613684
+v 0.944508 -0.598706 0.349045
+v -0.269822 -0.167002 -0.26839
+v -0.257105 -0.166668 -0.270663
+v -0.629978 0.0518565 0.599696
+v -0.648887 0.0320233 0.593864
+v -0.619908 0.0716125 0.615328
+v -0.613318 0.08984 0.624782
+v -0.609015 0.108196 0.631295
+v -0.606137 0.126269 0.635328
+v -0.605765 0.144214 0.63547
+v -0.606972 0.162159 0.633877
+v -0.608758 0.180245 0.631128
+v -0.611571 0.198293 0.627005
+v -0.615142 0.216366 0.621622
+v -0.62082 0.234144 0.613363
+v -0.62687 0.252269 0.604153
+v -0.631738 0.270162 0.597191
+v -0.63581 0.288377 0.590742
+v -0.638302 0.306386 0.587582
+v -0.639818 0.324665 0.585026
+v -0.640678 0.342957 0.5845
+v -0.642284 0.361197 0.582637
+v -0.643132 0.379591 0.58134
+v -0.644712 0.398037 0.578899
+v -0.647833 0.416252 0.574634
+v -0.651777 0.434479 0.569098
+v -0.633305 0.434222 0.550447
+v 0.811071 -0.379013 0.176148
+v 0.80899 -0.36121 0.188916
+v 0.728245 -0.44771 0.443689
+v 0.720139 -0.44744 0.454595
+v 0.719973 -0.464691 0.454467
+v -0.00974316 0.635919 -0.0833788
+v -0.0554467 0.860943 -0.171986
+v -0.0554724 0.879993 -0.171921
+v -0.0651963 0.860918 -0.163431
+v 0.732921 -0.534904 0.427504
+v 0.942607 -0.581892 0.346797
+v 0.939473 -0.565 0.342173
+v 0.880308 -0.599285 0.391756
+v 0.435372 -0.44586 0.69818
+v 0.740602 -0.207863 0.395931
+v 0.738136 -0.190727 0.392141
+v 0.756093 -0.225923 0.372822
+v -0.457774 -0.846505 0.593311
+v 0.687641 -0.377176 0.498565
+v 0.726395 -0.275082 0.442919
+v 0.634616 -0.153848 0.513979
+v 0.644352 -0.153951 0.505488
+v 0.629709 -0.136944 0.506798
+v -0.976904 0.163533 0.485642
+v -0.974823 0.180733 0.485591
+v 0.639612 -0.13738 0.498873
+v -0.426766 0.404871 0.204664
+v -0.440767 0.443844 0.204304
+v -0.432533 0.424434 0.204626
+v 0.58746 0.0335262 0.445796
+v 0.597004 0.033295 0.437023
+v 0.581706 0.0500838 0.437511
+v 0.790789 -0.199924 0.188864
+v 0.78664 -0.182313 0.188774
+v 0.790031 -0.20013 0.201633
+v 0.592419 0.0161851 0.453041
+v 0.601616 0.0163392 0.443625
+v 0.597377 -0.00105331 0.460375
+v 0.606099 -0.000693646 0.450086
+v 0.591006 0.0504435 0.428237
+v 0.602091 -0.017855 0.467145
+v 0.611083 -0.0178807 0.457524
+v 0.60624 -0.0350163 0.473208
+v 0.615335 -0.0350034 0.463754
+v 0.687204 -0.480928 0.497152
+v 0.678945 -0.480633 0.507903
+v 0.676825 -0.498256 0.504576
+v 0.612123 -0.0691462 0.481403
+v 0.6224 -0.0693004 0.473837
+v 0.609272 -0.0519978 0.477421
+v 0.685444 -0.498552 0.494159
+v 0.688656 -0.463458 0.499399
+v 0.680448 -0.463163 0.510164
+v 0.689491 -0.446091 0.50062
+v 0.680833 -0.445809 0.511063
+v 0.729324 -0.413118 0.445
+v 0.729966 -0.395571 0.446734
+v 0.722182 -0.412591 0.457845
+v 0.722542 -0.395198 0.458693
+v 0.541513 0.0330638 0.469804
+v 0.935542 -0.548661 0.33665
+v -0.269899 -0.148723 -0.265281
+v -0.257092 -0.14853 -0.267041
+v -0.624275 0.0516381 0.585656
+v -0.642785 0.0314068 0.579978
+v -0.651815 0.0262429 0.580338
+v -0.614191 0.0713171 0.601327
+v -0.607525 0.0893904 0.611115
+v -0.602952 0.107746 0.617473
+v -0.599818 0.125974 0.622509
+v -0.599201 0.143932 0.622714
+v -0.600267 0.161851 0.621186
+v -0.601809 0.179963 0.618552
+v -0.604005 0.197972 0.615547
+v -0.607859 0.21584 0.609985
+v -0.613241 0.233784 0.601943
+v -0.619342 0.251858 0.592695
+v -0.624493 0.270034 0.584769
+v -0.628861 0.287837 0.578899
+v -0.631494 0.306065 0.574878
+v -0.632509 0.324357 0.573414
+v -0.633421 0.342725 0.57204
+v -0.634423 0.36103 0.571372
+v -0.635194 0.379501 0.569419
+v -0.636131 0.397832 0.568738
+v -0.638379 0.416085 0.565745
+v -0.648488 0.503279 0.520825
+v 0.727782 -0.482367 0.442803
+v 0.727949 -0.464961 0.443535
+v 0.719818 -0.482071 0.45376
+v 0.517723 -0.272911 0.638154
+v 0.505996 -0.273232 0.643485
+v 0.526291 -0.620248 0.602188
+v 0.517274 -0.620081 0.61177
+v 0.516786 -0.637435 0.610871
+v 0.885266 -0.66748 0.398667
+v 0.884084 -0.685374 0.396855
+v -0.461435 0.0680415 0.457883
+v 0.917893 -0.523163 0.328416
+v 0.812163 -0.378911 0.163289
+v 0.812446 -0.378885 0.150496
+v -0.426368 0.495302 -0.0214773
+v 0.728052 -0.292153 0.445334
+v 0.720191 -0.291858 0.455661
+v 0.475681 0.100553 0.464807
+v 0.469502 0.117753 0.455957
+v 0.463439 0.100579 0.46983
+v 0.687243 -0.359938 0.498256
+v 0.678495 -0.359745 0.508057
+v 0.639073 -0.170624 0.520299
+v 0.648707 -0.170765 0.511718
+v 0.0629484 0.785721 -0.227041
+v 0.0569496 0.804308 -0.235647
+v 0.0796601 0.766659 -0.225127
+v 0.0696536 0.767044 -0.217368
+v 0.0667891 0.804488 -0.244009
+v 0.0617795 0.823191 -0.251151
+v 0.0521455 0.823204 -0.242571
+v 0.0473157 0.842112 -0.249469
+v 0.0568083 0.842022 -0.258216
+v 0.0432565 0.860969 -0.255185
+v 0.0525052 0.860751 -0.264176
+v 0.0489855 0.879954 -0.269315
+v 0.0398268 0.880198 -0.260259
+v 0.0456843 0.898824 -0.273772
+v 0.0369495 0.898901 -0.263855
+v 0.042717 0.917835 -0.277869
+v 0.0346502 0.917797 -0.26681
+v -0.655656 0.483124 -0.370613
+v 0.618944 -0.0521005 0.468905
+v 0.0320683 0.936949 -0.270599
+v 0.61617 -0.0864617 0.487338
+v 0.626253 -0.0862562 0.479271
+v 0.664712 -0.289803 0.53394
+v 0.664494 -0.272539 0.533722
+v 0.656542 -0.289559 0.544769
+v 0.663428 -0.255403 0.532348
+v 0.65486 -0.255249 0.542778
+v 0.688103 -0.290702 0.500003
+v 0.688617 -0.273374 0.500967
+v 0.68064 -0.290329 0.511988
+v 0.688219 -0.256135 0.500671
+v 0.687024 -0.239077 0.499181
+v 0.728669 -0.430472 0.443959
+v 0.721013 -0.430073 0.455803
+v -0.192339 0.596703 0.0356971
+v -0.186405 0.615906 0.044419
+v -0.203836 0.596664 0.0416701
+v 0.885728 -0.650178 0.39936
+v -0.27004 -0.130316 -0.262365
+v -0.257092 -0.130238 -0.265076
+v -0.063231 0.63773 -0.0245602
+v -0.270027 -0.112217 -0.257137
+v -0.257105 -0.112101 -0.26004
+v -0.618392 0.0511885 0.571667
+v -0.636799 0.0308801 0.565977
+v -0.644095 0.0245987 0.560209
+v -0.608681 0.0704051 0.586272
+v -0.601886 0.0891207 0.596715
+v -0.598289 0.107348 0.601995
+v -0.594962 0.12555 0.607133
+v -0.593061 0.143533 0.608816
+v -0.593498 0.161542 0.607608
+v -0.595026 0.179616 0.605848
+v -0.596992 0.197715 0.602997
+v -0.600704 0.21566 0.597486
+v -0.605958 0.233682 0.589509
+v -0.611738 0.251498 0.581224
+v -0.616979 0.269661 0.573273
+v -0.622053 0.287799 0.565386
+v -0.624763 0.305744 0.562085
+v -0.625791 0.324087 0.560659
+v -0.626382 0.342456 0.560261
+v -0.627281 0.360799 0.55886
+v -0.627628 0.379245 0.557871
+v -0.628809 0.397639 0.556381
+v -0.630569 0.415879 0.554403
+v -0.624558 0.434094 0.540466
+v -0.626831 0.452321 0.537409
+v 0.492277 -0.915818 0.536638
+v 0.490119 -0.908985 0.547955
+v -0.101176 0.765413 -0.126038
+v -0.104079 0.784539 -0.130007
+v -0.112364 0.765567 -0.119551
+v -0.0336483 0.709844 -0.118575
+v -0.0348429 0.69136 -0.0976114
+v 0.873538 -0.739452 0.38103
+v 0.881785 -0.703331 0.393349
+v 0.437774 -0.428301 0.701996
+v 0.917084 -0.800185 0.163623
+v 0.894347 -0.820943 0.163688
+v 0.878471 -0.721263 0.388301
+v 0.38534 -0.710229 0.668354
+v -0.0275724 -0.0497627 -0.269995
+v -0.014406 -0.0504306 -0.269456
+v -0.0260824 -0.0732953 -0.273862
+v 0.727564 -0.499618 0.442675
+v 0.719806 -0.499335 0.453773
+v 0.686947 -0.342764 0.497473
+v 0.643235 -0.187554 0.526285
+v 0.652612 -0.187451 0.517087
+v 0.00337189 0.673017 -0.0870911
+v -0.00739247 0.672554 -0.0801803
+v 0.0522482 0.785554 -0.219937
+v 0.046455 0.804334 -0.228312
+v 0.0357164 0.804167 -0.221312
+v 0.439046 -0.410767 0.703845
+v 0.042139 0.82296 -0.234414
+v 0.0315288 0.822895 -0.227233
+v 0.380124 -0.275005 0.709549
+v 0.39076 -0.274954 0.702368
+v 0.43798 -0.39367 0.702342
+v 0.0161144 0.937154 -0.248968
+v 0.999666 -0.596086 0.163007
+v 0.0167952 0.918066 -0.247876
+v 0.0258769 0.918156 -0.257535
+v 0.018722 0.898991 -0.245204
+v 0.0278293 0.899068 -0.254812
+v 0.0272385 0.956332 -0.278383
+v 0.0211241 0.880057 -0.242018
+v 0.0306681 0.880044 -0.250715
+v 0.0275339 0.841855 -0.232821
+v 0.0378358 0.841701 -0.240425
+v 0.0243097 0.861174 -0.237587
+v -0.390658 0.482778 0.131382
+v -0.404852 0.463882 0.133244
+v 0.0379129 0.937154 -0.285512
+v 0.0464422 0.923834 -0.287683
+v 0.435282 -0.376804 0.698412
+v -0.432957 -0.896371 -0.124342
+v -0.420292 -0.877706 -0.121799
+v 0.656221 -0.272269 0.544486
+v 0.652612 -0.238203 0.5394
+v 0.681026 -0.273052 0.512219
+v 0.763647 -0.219809 0.35593
+v 0.400163 -0.446438 0.714584
+v 0.388525 -0.429367 0.720698
+v 0.438429 -0.25819 0.658527
+v 0.430452 -0.257857 0.669548
+v 0.431005 -0.274992 0.670178
+v -0.375539 0.571873 -0.0731925
+v -0.583311 0.84102 -0.707686
+v -0.632124 0.0296213 0.549509
+v -0.648977 0.0102762 0.523754
+v -0.625701 0.0298139 0.536702
+v -0.653935 0.0141812 0.543433
+v -0.612958 0.0503022 0.556253
+v -0.603491 0.0699041 0.570948
+v -0.596902 0.0881573 0.580376
+v -0.592586 0.106655 0.586914
+v -0.588809 0.125165 0.59317
+v -0.587692 0.143174 0.59448
+v -0.586959 0.161196 0.594724
+v -0.587704 0.179397 0.593414
+v -0.590081 0.197368 0.590306
+v -0.593305 0.215223 0.5859
+v -0.598392 0.233296 0.578051
+v -0.60389 0.251293 0.569933
+v -0.609195 0.269392 0.561956
+v -0.61432 0.287568 0.554082
+v -0.617994 0.305667 0.548636
+v -0.61879 0.323907 0.54721
+v -0.619497 0.342186 0.547621
+v -0.6201 0.360568 0.546375
+v -0.620293 0.378988 0.546208
+v -0.621102 0.397344 0.545668
+v -0.622798 0.4157 0.543048
+v 0.33121 -0.362417 0.728084
+v 0.472572 0.0663845 0.483112
+v 0.00653183 0.728483 -0.150894
+v 0.448834 -0.621301 0.64793
+v 0.460703 -0.6208 0.64265
+v 0.450388 -0.603639 0.650743
+v 0.388268 -0.674224 0.672978
+v 0.388166 -0.691989 0.67267
+v 0.867437 -0.758271 0.371871
+v 0.570248 -0.550678 0.575996
+v 0.593356 -0.567569 0.56414
+v 0.593652 -0.584808 0.56441
+v 0.672766 -0.290073 0.522996
+v 0.525019 -0.655033 0.600042
+v 0.516028 -0.654828 0.609651
+v 0.514114 -0.672554 0.606581
+v 0.519933 -0.690371 0.592554
+v 0.522707 -0.672644 0.596536
+v 0.511301 -0.690358 0.602547
+v 0.861772 -0.776691 0.363483
+v -0.58746 0.600017 -0.193193
+v 0.570029 -0.0691591 0.510678
+v 0.719908 -0.516625 0.453876
+v 0.727359 -0.517036 0.44193
+v 0.687101 -0.32541 0.498089
+v 0.66389 -0.307131 0.532733
+v 0.655823 -0.306887 0.543652
+v 0.687448 -0.308056 0.49895
+v 0.679574 -0.307786 0.509997
+v 0.0414967 0.78531 -0.213026
+v 0.0480864 0.76644 -0.203444
+v 0.368011 -0.67425 0.688726
+v 0.378249 -0.674301 0.681096
+v 0.366714 -0.65723 0.687172
+v 0.577724 -0.238614 0.589252
+v 0.577133 -0.221414 0.588456
+v 0.567473 -0.238678 0.597037
+v 0.568231 -0.255891 0.598039
+v 0.577749 -0.25593 0.58915
+v 0.574397 -0.204459 0.584602
+v 0.564031 -0.204369 0.592194
+v 0.566625 -0.221427 0.595881
+v 0.570158 -0.187606 0.578527
+v 0.560383 -0.187541 0.586992
+v 0.555925 -0.17083 0.580543
+v 0.565765 -0.170855 0.572155
+v 0.551506 -0.154067 0.574198
+v 0.561474 -0.153977 0.565964
+v 0.557711 -0.137291 0.560505
+v 0.547165 -0.137252 0.567916
+v 0.553844 -0.120014 0.554981
+v 0.543375 -0.120579 0.562457
+v 0.549194 -0.103469 0.548302
+v 0.539265 -0.103584 0.556587
+v 0.0341235 0.860815 -0.245653
+v 0.953795 -0.582637 0.0479643
+v 0.582887 -0.764681 0.501686
+v 0.59459 -0.764603 0.496098
+v 0.587049 -0.746106 0.507672
+v -0.329925 0.501468 0.0837899
+v -0.339649 0.48297 0.0698399
+v -0.321332 0.501506 0.0736678
+v 0.579959 -0.783281 0.497229
+v 0.590697 -0.783281 0.490215
+v 0.64985 -0.221222 0.535533
+v -0.630955 0.00895317 0.504897
+v -0.620421 0.0289533 0.521005
+v -0.606677 0.0486195 0.541532
+v -0.598083 0.0690178 0.5557
+v -0.591019 0.0878233 0.566246
+v -0.586677 0.106308 0.57281
+v -0.582926 0.124574 0.578077
+v -0.580819 0.142763 0.5808
+v -0.579676 0.1609 0.582252
+v -0.5801 0.179141 0.581879
+v -0.582361 0.197317 0.578167
+v -0.585906 0.21548 0.572862
+v -0.590813 0.233373 0.565861
+v -0.596285 0.251395 0.557781
+v -0.601128 0.269353 0.550858
+v -0.606176 0.287169 0.543741
+v -0.6108 0.305256 0.536972
+v -0.612342 0.323624 0.534364
+v -0.612766 0.341903 0.534043
+v -0.612984 0.360311 0.533812
+v -0.613177 0.378731 0.533684
+v -0.613459 0.397164 0.533529
+v -0.614461 0.415584 0.532168
+v -0.615964 0.433901 0.530369
+v -0.617891 0.452309 0.527711
+v 0.0765387 0.747956 -0.206938
+v 0.96316 -0.723871 0.124856
+v 0.968388 -0.705823 0.124702
+v 0.965061 -0.723794 0.13765
+v 0.406046 -0.747455 0.630126
+v 0.416849 -0.747622 0.623215
+v 0.411184 -0.728842 0.637743
+v 0.854874 -0.795728 0.353092
+v 0.672496 -0.411011 0.521725
+v 0.671893 -0.428378 0.520736
+v -0.927617 0.33873 0.394813
+v -0.231363 -0.16627 -0.27557
+v -0.218479 -0.148055 -0.273297
+v -0.114895 0.822754 -0.122673
+v -0.861887 -0.398384 0.295891
+v -0.858599 -0.404948 0.295236
+v -0.854591 -0.399065 0.308891
+v -0.181331 0.727558 -0.0612978
+v -0.192108 0.727404 -0.0543613
+v -0.188293 0.70847 -0.0489149
+v 0.291402 -0.960687 -0.163688
+v 0.303618 -0.962203 -0.159847
+v 0.290567 -0.945722 -0.153527
+v -0.176848 0.708392 -0.0550036
+v -0.18151 0.689844 -0.0391011
+v -0.244298 -0.130007 -0.26699
+v 0.525739 -0.585733 0.601597
+v 0.524814 -0.56861 0.600415
+v 0.514127 -0.568623 0.607557
+v 0.720319 -0.533863 0.454171
+v 0.399431 -0.275185 0.692246
+v 0.39848 -0.258126 0.691026
+v 0.685175 -0.221864 0.496008
+v 0.676517 -0.221761 0.506439
+v 0.37681 -0.657153 0.679067
+v 0.37541 -0.640171 0.677217
+v 0.365815 -0.640133 0.685977
+v 0.570094 -0.838451 0.482508
+v -0.082409 0.784771 -0.14388
+v -0.093289 0.784629 -0.137046
+v -0.0902061 0.765683 -0.132653
+v 0.0594288 0.766402 -0.209494
+v -0.0221389 0.654699 -0.0563523
+v 0.0182467 0.729048 -0.156276
+v 0.812741 -0.396868 0.150534
+v 0.028934 0.709934 -0.140707
+v 0.0404177 0.710204 -0.146475
+v 0.0462366 0.692284 -0.138395
+v -0.381435 0.295981 0.149417
+v -0.383978 0.301839 0.166886
+v -0.457569 0.382083 0.0228775
+v 0.789954 -0.488841 0.0351833
+v 0.783878 -0.499284 0.0255236
+v -0.434229 0.420619 0.0396534
+v -0.426766 0.421801 0.0509316
+v 0.960231 -0.742073 0.150573
+v 0.966281 -0.634776 0.0605913
+v -0.140675 -0.410227 -0.442187
+v -0.127702 -0.427748 -0.446991
+v 0.533202 -0.0869241 0.547736
+v 0.542425 -0.0866544 0.538475
+v 0.523298 -0.0698142 0.53344
+v 0.480729 -0.445359 0.673466
+v 0.47053 -0.445257 0.681366
+v 0.469258 -0.462803 0.679452
+v -0.980719 0.146424 0.524358
+v 0.481872 -0.393246 0.67547
+v 0.471275 -0.393323 0.682715
+v 0.599329 -0.745657 0.50297
+v 0.96858 -0.549432 0.293888
+v 0.97869 -0.566683 0.285679
+v 0.587255 -0.801585 0.485064
+v 0.577415 -0.801444 0.493401
+v 0.646741 -0.204433 0.531307
+v -0.611417 0.0284909 0.511243
+v -0.601243 0.0477331 0.5264
+v -0.591661 0.0683498 0.541879
+v -0.585238 0.087014 0.551127
+v -0.579702 0.105576 0.559143
+v -0.575784 0.124342 0.565309
+v -0.573716 0.142442 0.568135
+v -0.572136 0.160592 0.570036
+v -0.57238 0.178935 0.569817
+v -0.574217 0.197188 0.567133
+v -0.577248 0.215287 0.562842
+v -0.582271 0.233065 0.555713
+v -0.588 0.250946 0.547415
+v -0.592547 0.269122 0.540813
+v -0.596979 0.286835 0.534698
+v -0.602387 0.305346 0.526131
+v -0.605534 0.323355 0.521699
+v -0.606587 0.341608 0.520132
+v -0.60651 0.360028 0.520954
+v -0.606433 0.378474 0.520954
+v -0.606086 0.396997 0.521892
+v -0.606471 0.415378 0.521018
+v -0.607281 0.433811 0.520363
+v -0.608501 0.45218 0.51877
+v -0.610055 0.470305 0.516561
+v -0.590222 0.538976 -0.360465
+v -0.582887 0.55931 -0.360401
+v -0.599175 0.470523 0.50974
+v 0.736993 -0.0582149 0.201671
+v 0.72777 -0.04027 0.201723
+v -0.187484 0.784848 -0.0468725
+v -0.183399 0.803705 -0.041182
+v -0.195114 0.784783 -0.0354016
+v -0.0852864 0.746877 -0.125576
+v -0.0968471 0.746787 -0.119744
+v 0.431185 -0.359887 0.69285
+v 0.418082 -0.360323 0.696408
+v -0.270066 -0.094156 -0.249122
+v -0.257362 -0.0937578 -0.251318
+v -0.13853 0.652901 0.000552348
+v -0.15871 0.671385 -0.0286579
+v -0.156115 0.65493 -0.00137445
+v -0.169783 0.690319 -0.0445603
+v -0.171928 0.671822 -0.0249327
+v 0.934964 -0.637576 0.021259
+v 0.952704 -0.515585 0.0951708
+v -0.551237 0.525861 0.466464
+v -0.547524 0.531025 0.459515
+v -0.138736 0.635123 0.0232243
+v -0.651764 0.447248 -0.227323
+v -0.127021 0.635483 0.0176751
+v -0.130296 0.616279 0.0128068
+v 0.572842 -0.619452 0.579297
+v 0.562027 -0.61949 0.586157
+v 0.523003 -0.873069 0.526965
+v 0.514114 -0.872735 0.536792
+v -0.152416 0.74662 -0.0871553
+v -0.154612 0.765503 -0.0902511
+v -0.164503 0.765451 -0.0819273
+v 0.628103 -0.0520877 0.459412
+v 0.636324 -0.0522033 0.448571
+v 0.624044 -0.0352732 0.45385
+v 0.719613 -0.5687 0.452411
+v 0.72696 -0.534429 0.440992
+v 0.720486 -0.55114 0.454312
+v 0.682207 -0.205165 0.492604
+v 0.67039 -0.187824 0.49773
+v 0.653716 -0.341685 0.540312
+v 0.654089 -0.324472 0.540684
+v 0.5931 -0.727224 0.516805
+v 0.60448 -0.727057 0.510883
+v -0.0201093 0.985555 -0.210637
+v -0.0089596 0.979274 -0.219218
+v 0.50448 -0.872568 0.545681
+v 0.493959 -0.872658 0.5529
+v 0.493047 -0.890487 0.551564
+v 0.494499 -0.854713 0.553915
+v 0.505173 -0.854688 0.546683
+v 0.493561 -0.837179 0.552682
+v 0.503876 -0.837295 0.545
+v 0.49139 -0.819954 0.549535
+v 0.502039 -0.819915 0.542341
+v 0.501012 -0.784989 0.541121
+v 0.506895 -0.765374 0.549894
+v 0.495809 -0.765952 0.556394
+v 0.500189 -0.802651 0.539798
+v 0.488834 -0.802882 0.545989
+v 0.489721 -0.784745 0.547312
+v 0.513947 -0.746556 0.56035
+v -0.414614 0.365449 0.11485
+v 0.520344 -0.727249 0.570036
+v 0.511686 -0.727134 0.580068
+v -0.428667 0.404794 0.217522
+v -0.432007 0.404845 0.230445
+v -0.586458 -0.00512527 0.504859
+v 0.486586 0.10099 0.458128
+v 0.481217 0.118215 0.45042
+v 0.435141 -0.909678 0.58062
+v 0.43717 -0.891271 0.583356
+v 0.424017 -0.891913 0.586902
+v 0.967103 -0.72382 0.150406
+v 0.480164 0.0833917 0.471255
+v 0.491211 0.0839183 0.46482
+v 0.426984 -0.343124 0.686851
+v 0.41446 -0.34365 0.691051
+v 0.583221 -0.820211 0.478988
+v 0.574178 -0.8198 0.488597
+v 0.54028 -0.799723 -0.219282
+v 0.540125 -0.81777 -0.193707
+v 0.506766 -0.825721 -0.209532
+v -0.603209 0.00976243 0.500478
+v 0.235397 -0.919325 0.616176
+v -0.601539 0.0282725 0.502996
+v -0.593523 0.0476432 0.514994
+v -0.585392 0.0667442 0.527043
+v -0.577544 0.0861791 0.538886
+v -0.571635 0.104484 0.546567
+v -0.567486 0.124009 0.554198
+v -0.564403 0.142236 0.558565
+v -0.562528 0.160566 0.561327
+v -0.562849 0.178884 0.561006
+v -0.564634 0.197111 0.558436
+v -0.567576 0.215261 0.554275
+v -0.571866 0.232988 0.548199
+v -0.578083 0.251113 0.539117
+v -0.582836 0.269122 0.532219
+v -0.587037 0.286925 0.526285
+v -0.592573 0.304986 0.518256
+v -0.597891 0.323136 0.510331
+v -0.600152 0.3413 0.507274
+v -0.600396 0.35972 0.50703
+v -0.599676 0.37823 0.50825
+v -0.598687 0.396688 0.509676
+v -0.597608 0.415301 0.511744
+v -0.597711 0.43376 0.511667
+v -0.598019 0.45218 0.511384
+v -0.52281 -0.917283 -0.103636
+v -0.0909768 0.728149 -0.11124
+v -0.102024 0.727391 -0.104946
+v -0.0941625 0.709176 -0.0933596
+v 0.561847 -0.602226 0.586002
+v 0.573176 -0.602059 0.579862
+v 0.561346 -0.585039 0.585245
+v 0.558944 -0.49886 0.582598
+v 0.561924 -0.481236 0.586786
+v 0.54922 -0.498834 0.591153
+v 0.524647 -0.837308 0.529689
+v -0.148678 0.881175 -0.0566735
+v -0.000982665 0.642599 -0.131497
+v -0.124773 0.90183 -0.079294
+v -0.656093 0.0638283 -0.100964
+v -0.229038 -0.61615 -0.149468
+v -0.270104 -0.0761469 -0.241055
+v -0.601064 0.578385 -0.476291
+v -0.36295 0.158087 0.348197
+v -0.183527 0.74644 -0.0643421
+v -0.193585 0.746389 -0.0562239
+v 0.549143 -0.728097 0.543626
+v 0.557313 -0.516548 0.580042
+v 0.546689 -0.516676 0.587184
+v 0.546188 -0.534043 0.586182
+v 0.342192 -0.604307 0.719966
+v 0.38069 -0.534107 0.708508
+v 0.380548 -0.516856 0.70847
+v 0.369142 -0.517049 0.714571
+v 0.718007 -0.585938 0.45078
+v 0.716106 -0.603613 0.44753
+v -0.152724 0.803473 -0.0874508
+v 0.678739 -0.187952 0.487042
+v 0.67486 -0.171523 0.482367
+v 0.609529 -0.708675 0.518411
+v 0.598751 -0.708598 0.525373
+v -0.621218 0.563189 -0.5194
+v 0.505751 -0.0703537 0.553221
+v 0.515514 -0.0703665 0.544602
+v 0.865124 -0.822561 0.0616446
+v 0.540639 -0.498821 0.601224
+v 0.532932 -0.49868 0.6124
+v 0.529323 -0.516535 0.606876
+v -0.779215 0.491641 0.532617
+v 0.537646 -0.516497 0.596677
+v -0.0458641 0.879993 -0.180631
+v -0.04571 0.860956 -0.180554
+v -0.0451962 0.841945 -0.180027
+v -0.0300516 0.80373 -0.181016
+v -0.0329675 0.822831 -0.185062
+v -0.0414197 0.803756 -0.174889
+v -0.0439245 0.822973 -0.178318
+v -0.0261466 0.784681 -0.17557
+v -0.037489 0.784809 -0.169301
+v -0.0210727 0.765952 -0.168235
+v -0.0332372 0.766261 -0.163058
+v 0.524557 -0.709099 0.576253
+v -0.0183624 0.728251 -0.141812
+v 0.528719 -0.690422 0.582637
+v 0.516156 -0.708649 0.586863
+v 0.532226 -0.67258 0.587749
+v 0.53473 -0.655059 0.591513
+v -0.132724 0.764937 -0.216071
+v -0.132724 0.784077 -0.219089
+v -0.119648 0.765053 -0.22049
+v 0.0686132 0.693441 -0.173052
+v 0.0622547 0.692901 -0.159667
+v 0.0628713 0.686376 -0.168762
+v 0.49604 0.0662689 0.471551
+v 0.484582 0.0661276 0.477524
+v 0.423657 -0.326322 0.682008
+v -0.588938 0.010212 0.498565
+v -0.590068 0.0284266 0.497023
+v -0.585508 0.0471808 0.503921
+v -0.577672 0.0666671 0.51561
+v -0.568963 0.086269 0.528623
+v -0.562207 0.104753 0.538385
+v -0.557351 0.123854 0.545874
+v -0.553883 0.142364 0.55105
+v -0.552033 0.160605 0.553889
+v -0.552264 0.178922 0.553722
+v -0.554088 0.19715 0.551115
+v -0.556927 0.215339 0.547107
+v -0.560883 0.233271 0.541429
+v -0.567255 0.251344 0.532219
+v -0.571725 0.268826 0.525732
+v -0.576311 0.287041 0.519181
+v -0.58213 0.304896 0.51078
+v -0.588694 0.322879 0.501326
+v -0.59274 0.341222 0.495058
+v -0.593806 0.359437 0.493529
+v -0.592521 0.377934 0.495816
+v -0.590017 0.39656 0.499669
+v -0.588 0.41534 0.503048
+v -0.587062 0.43376 0.50455
+v -0.586677 0.452309 0.505231
+v -0.587435 0.470729 0.504281
+v 0.89883 -0.8026 0.0994098
+v 0.71224 -0.621507 0.441698
+v -0.564788 0.489303 0.491949
+v -0.575065 0.470883 0.499579
+v -0.144259 0.841842 -0.0746183
+v -0.148408 0.822998 -0.080373
+v 0.611468 -0.324639 0.569715
+v 0.599227 -0.32487 0.574532
+v 0.355192 -0.361993 0.718078
+v 0.378776 -0.361595 0.707005
+v 0.695913 -0.0534621 0.37638
+v 0.690839 -0.0363907 0.368776
+v -0.0942652 0.63624 -0.0025819
+v -0.497402 -0.918644 0.625322
+v -0.497993 -0.936653 0.623087
+v -0.48141 -0.917475 0.625887
+v -0.51843 -0.92612 0.622342
+v -0.5178 -0.908471 0.621777
+v -0.270194 -0.0577139 -0.239565
+v 0.658161 -0.170984 0.503022
+v 0.503105 -0.726479 0.590498
+v 0.380047 -0.551487 0.70748
+v 0.596555 -0.153463 0.549008
+v 0.352995 -0.913879 0.596677
+v -0.626536 0.494711 -0.3655
+v -0.616427 0.507466 -0.377755
+v 0.421666 -0.309418 0.67908
+v -0.0979004 -0.966866 0.625784
+v -0.106044 -0.966968 0.646131
+v -0.111157 -0.967354 0.623369
+v -0.981837 0.161812 0.164664
+v -0.980694 0.179115 0.164497
+v -0.874219 0.0880674 0.00982665
+v -0.888374 0.105845 0.0095569
+v -0.873705 0.0956718 0.0053308
+v 0.709003 -0.639439 0.436792
+v 0.671122 -0.154336 0.476612
+v 0.654731 -0.358833 0.541686
+v 0.613973 -0.690126 0.525
+v 0.81278 -0.396817 0.163366
+v 0.512932 -0.0868471 0.563639
+v 0.523799 -0.0864489 0.556818
+v 0.543388 -0.480966 0.605514
+v 0.536002 -0.480543 0.617551
+v 0.0137252 0.649471 -0.103315
+v 0.490337 -0.120129 0.598668
+v 0.478815 -0.12036 0.604538
+v 0.484968 -0.103662 0.590742
+v 0.473587 -0.103726 0.59687
+v 0.511313 -0.221813 0.629137
+v 0.52087 -0.204587 0.620235
+v 0.478815 -0.0869627 0.581879
+v 0.467383 -0.0870397 0.587916
+v 0.472521 -0.0704308 0.572695
+v 0.425815 -0.785837 0.590318
+v 0.433368 -0.766633 0.601777
+v 0.415706 -0.78531 0.598385
+v -0.0261723 0.746684 -0.153232
+v 0.00356457 0.70996 -0.132474
+v -0.00884399 0.709883 -0.127888
+v 0.535553 -0.533863 0.593658
+v 0.791829 -0.199988 0.175968
+v 0.794899 -0.217882 0.188813
+v 0.524313 -0.551449 0.599657
+v 0.535052 -0.551294 0.592733
+v 0.0767057 0.710756 -0.184214
+v 0.0733788 0.729279 -0.188813
+v 0.0638219 0.729125 -0.180297
+v 0.505276 0.0323702 0.485038
+v 0.0690627 0.710833 -0.172821
+v 0.550941 -0.874225 0.473491
+v 0.558777 -0.873339 0.460504
+v -0.395898 0.326502 0.19187
+v -0.390067 0.314697 0.202455
+v -0.568655 0.0662304 0.506002
+v -0.575925 0.0472322 0.495173
+v -0.558905 0.0858708 0.520427
+v -0.550826 0.10501 0.532399
+v -0.545944 0.124086 0.539721
+v -0.54299 0.142326 0.544165
+v -0.540704 0.160772 0.547544
+v -0.540652 0.179141 0.547749
+v -0.543234 0.197291 0.544371
+v -0.54561 0.215339 0.540864
+v -0.548719 0.233283 0.536381
+v -0.555232 0.251138 0.52694
+v -0.559984 0.269148 0.520119
+v -0.564711 0.287234 0.513362
+v -0.5708 0.304742 0.504525
+v -0.578289 0.322687 0.493812
+v -0.584133 0.34112 0.485051
+v -0.586831 0.359219 0.481056
+v -0.584686 0.377755 0.484537
+v -0.580473 0.396586 0.49096
+v -0.577544 0.415443 0.495636
+v -0.575823 0.433978 0.498192
+v -0.57441 0.452514 0.500311
+v -0.248717 0.746774 0.0222481
+v -0.771521 0.504923 0.516856
+v -0.270271 -0.0392424 -0.237998
+v -0.257388 -0.0391396 -0.239539
+v -0.759921 0.381467 -0.0586002
+v 0.81242 -0.739529 0.427941
+v -0.22232 -0.981188 0.22433
+v -0.498237 -0.945311 0.621006
+v -0.419958 0.69136 0.0772773
+v -0.434589 0.672721 0.0922292
+v -0.467961 -0.934765 0.62256
+v -0.467164 -0.916615 0.624384
+v 0.43604 -0.24117 0.655084
+v 0.836222 -0.823962 0.024663
+v 0.672496 -0.39376 0.521737
+v -0.745136 -0.176186 -0.156494
+v -0.73242 -0.175647 -0.163289
+v 0.421319 -0.292243 0.67863
+v 0.421345 -0.274966 0.678848
+v 0.613112 -0.602149 0.547158
+v 0.61378 -0.584834 0.548212
+v 0.603312 -0.584898 0.555765
+v 0.91201 -0.581802 0.370086
+v -0.229423 -0.559002 -0.177214
+v -0.219764 -0.557691 -0.192962
+v 0.705701 -0.657435 0.431808
+v 0.658444 -0.137393 0.480979
+v 0.667037 -0.137303 0.470587
+v 0.655643 -0.375956 0.542945
+v 0.617364 -0.672271 0.530138
+v 0.739921 -0.0582149 0.163122
+v 0.73057 -0.0403471 0.163161
+v -0.435886 0.42446 0.217548
+v -0.438648 0.424023 0.230111
+v 0.804109 -0.271511 0.150303
+v 0.51816 -0.103559 0.571218
+v 0.529053 -0.103161 0.564422
+v 0.545662 -0.463818 0.608559
+v 0.538558 -0.463047 0.621211
+v 0.462386 -0.672516 0.645052
+v 0.978227 -0.526644 0.137188
+v -0.0738155 0.746826 -0.131639
+v -0.0785811 0.728174 -0.115865
+v 0.00452797 0.654622 -0.0853056
+v -0.00352603 0.655868 -0.0746569
+v 0.804186 -0.397639 0.0607968
+v 0.857083 -0.80522 0.0236867
+v 0.462617 -0.637833 0.645412
+v 0.773589 -0.147002 0.0733852
+v 0.767063 -0.129301 0.0733466
+v 0.46191 -0.966031 -0.0283753
+v 0.421075 -0.257664 0.678489
+v 0.409977 -0.257844 0.685001
+v -0.0253887 0.636099 -0.0612078
+v 0.53721 -0.585579 0.595624
+v 0.536208 -0.56843 0.594236
+v 0.488513 0.0493259 0.483433
+v -0.329437 -0.905452 0.577139
+v 0.0558449 0.748059 -0.192114
+v 0.0665451 0.748239 -0.199205
+v -0.857674 -0.426849 0.24627
+v -0.844508 -0.435623 0.257844
+v -0.564313 0.0472964 0.489496
+v -0.546394 0.0860763 0.515919
+v -0.538802 0.105717 0.527107
+v -0.535129 0.124021 0.532707
+v -0.532097 0.142275 0.537357
+v -0.529194 0.160926 0.541648
+v -0.529079 0.179256 0.542059
+v -0.531121 0.197394 0.539156
+v -0.534063 0.21548 0.534994
+v -0.537287 0.233258 0.530241
+v -0.54353 0.251472 0.521365
+v -0.548257 0.269533 0.514621
+v -0.553125 0.287465 0.50762
+v -0.559162 0.304947 0.498732
+v -0.566651 0.322905 0.487993
+v -0.573279 0.340889 0.478436
+v -0.577364 0.359244 0.472399
+v -0.575527 0.377639 0.475019
+v -0.570402 0.396778 0.48324
+v -0.566715 0.415455 0.488597
+v -0.564596 0.434158 0.492013
+v -0.563453 0.452578 0.493645
+v -0.563427 0.47105 0.493927
+v -0.617698 -0.0619143 -0.180952
+v -0.617082 -0.0445346 -0.168633
+v -0.604519 -0.0437254 -0.178845
+v -0.456014 -0.898451 0.617923
+v -0.936724 0.339129 0.484679
+v -0.935285 0.339154 0.497473
+v -0.934412 0.356842 0.484589
+v -0.536349 -0.667313 0.0877719
+v -0.270259 -0.0211691 -0.234067
+v -0.257426 -0.021092 -0.235544
+v -0.45446 -0.934226 0.620402
+v -0.454589 -0.916101 0.620659
+v -0.00831733 -0.840969 0.684629
+v -0.247574 0.668765 -0.156636
+v -0.427845 0.404473 0.0631218
+v -0.423529 0.404858 0.0762625
+v -0.425558 0.384961 0.0763396
+v -0.475822 0.522829 0.346014
+v 0.913397 -0.783024 0.292102
+v -0.101137 0.6538 -0.012704
+v -0.104503 0.635881 0.00506105
+v -0.60696 0.623536 -0.681931
+v 0.940578 -0.722895 0.319745
+v -0.526599 -0.243226 -0.253027
+v -0.539406 -0.243855 -0.24469
+v -0.526651 -0.224806 -0.251395
+v 0.804045 -0.77628 0.415584
+v -0.0193514 -0.842163 0.690101
+v 0.703479 -0.675239 0.428262
+v 0.654063 -0.120515 0.474698
+v 0.662965 -0.12063 0.465141
+v 0.663428 -0.410831 0.531307
+v 0.664173 -0.393464 0.532476
+v 0.654603 -0.410677 0.541057
+v 0.655759 -0.393195 0.543035
+v 0.608578 -0.654494 0.540132
+v 0.620075 -0.654339 0.534197
+v 0.497877 0.100887 0.451795
+v 0.508076 0.101349 0.443882
+v 0.805663 -0.3255 0.188864
+v 0.533497 -0.119911 0.570832
+v 0.522861 -0.120014 0.578013
+v 0.549682 -0.445989 0.614326
+v 0.542027 -0.445488 0.626324
+v -0.0776691 0.899197 -0.135762
+v 0.454383 -0.5687 0.656677
+v -0.0840275 0.860853 -0.145679
+v -0.0948304 0.841829 -0.138729
+v -0.0646568 0.88007 -0.162377
+v -0.0747661 0.86093 -0.154734
+v -0.0732632 0.88007 -0.152281
+v -0.062229 0.899222 -0.158537
+v -0.0697564 0.899184 -0.146989
+v -0.600614 0.564628 -0.102043
+v 0.407523 -0.92937 0.586593
+v 0.408358 -0.804784 0.587647
+v 0.419842 -0.804552 0.581712
+v 0.422411 -0.766183 0.608366
+v -0.0585424 0.918246 -0.153129
+v -0.0662753 0.918182 -0.141799
+v 0.391082 0.15074 0.455289
+v 0.971573 -0.705502 0.137535
+v 0.935311 -0.780211 0.150688
+v -0.057746 0.709382 -0.108376
+v -0.0668662 0.728637 -0.121337
+v -0.0701546 0.709356 -0.103739
+v -0.908092 0.0040848 0.229623
+v -0.90912 0.00444447 0.216816
+v -0.895426 -0.0138986 0.21688
+v 0.537762 -0.620068 0.596253
+v -0.0830127 -0.862703 0.71073
+v 0.419059 -0.240682 0.675727
+v 0.408102 -0.240939 0.682432
+v 0.499855 0.0492489 0.477126
+v -0.532919 0.0876692 0.512502
+v -0.527152 0.105717 0.521493
+v -0.522849 0.124355 0.527993
+v -0.520369 0.14275 0.531757
+v -0.518211 0.160952 0.535071
+v -0.517531 0.179372 0.536201
+v -0.519534 0.197548 0.533414
+v -0.522656 0.215557 0.528931
+v -0.52642 0.233605 0.523523
+v -0.532033 0.251575 0.515443
+v -0.536824 0.269559 0.508545
+v -0.541616 0.287581 0.50166
+v -0.547383 0.305435 0.493337
+v -0.554345 0.322854 0.483163
+v -0.562374 0.341145 0.471602
+v -0.567139 0.35918 0.464666
+v -0.567024 0.3776 0.464871
+v -0.56132 0.396599 0.473555
+v -0.557235 0.415545 0.4799
+v -0.555039 0.433914 0.482919
+v -0.553485 0.452527 0.485398
+v -0.552881 0.47105 0.486464
+v -0.554114 0.489406 0.48482
+v -0.556953 0.507723 0.480748
+v -0.410003 0.437459 0.0521262
+v 0.710107 -0.121889 0.397087
+v -0.444364 -0.58283 0.46789
+v -0.270336 -0.00294157 -0.226308
+v -0.257529 -0.00273605 -0.226604
+v -0.440202 -0.932787 0.618013
+v -0.442167 -0.915677 0.616099
+v -0.443465 -0.897886 0.61398
+v -0.355641 -0.642059 0.525103
+v -0.279584 -0.910243 -0.346091
+v -0.295358 -0.921201 -0.340696
+v -0.292468 -0.911066 -0.338011
+v -0.0388378 0.955819 -0.169545
+v -0.0521455 0.968882 -0.159783
+v 0.557479 0.124921 -0.00516381
+v 0.559265 0.119333 -0.0151446
+v 0.548398 0.124831 -0.0212975
+v 0.687705 -0.079461 -0.080874
+v -0.249925 0.206527 -0.0100707
+v -0.246713 0.200284 -0.0273733
+v -0.260239 0.20555 -0.024162
+v -0.346084 0.482534 0.0828393
+v 0.94429 -0.704603 0.325474
+v 0.946204 -0.686889 0.328043
+v 0.797121 -0.795355 0.405218
+v -0.0547145 0.728187 -0.126565
+v -0.0454017 0.70924 -0.113193
+v 0.808721 -0.757834 0.422495
+v 0.658688 -0.10361 0.458795
+v 0.649824 -0.103507 0.468494
+v 0.621912 -0.637063 0.5371
+v 0.60466 -0.934328 0.0200387
+v 0.582078 -0.924939 -0.0012203
+v -0.837957 0.254208 0.687095
+v 0.565084 -0.46315 0.591654
+v 0.576632 -0.463304 0.58599
+v 0.56913 -0.445591 0.597846
+v 0.552329 -0.428121 0.618797
+v 0.544429 -0.427903 0.63001
+v 0.430684 -0.804501 0.574904
+v -0.0488828 0.784861 -0.163148
+v -0.052351 0.803615 -0.168094
+v -0.0602252 0.784925 -0.156918
+v -0.0317985 0.672426 -0.0705592
+v -0.0457999 0.672747 -0.0681957
+v -0.0815741 0.879941 -0.141915
+v 0.453458 -0.803807 0.562534
+v 0.456914 -0.78576 0.567724
+v 0.447048 -0.785618 0.576009
+v 0.442129 -0.804116 0.568841
+v 0.497107 -0.497575 0.651501
+v 0.498943 -0.480234 0.654301
+v 0.488988 -0.480106 0.662522
+v 0.494075 -0.515302 0.646941
+v 0.486252 -0.498012 0.65845
+v 0.492688 -0.393182 0.668598
+v 0.503606 -0.39313 0.661931
+v 0.492148 -0.375982 0.668007
+v 0.492418 -0.410549 0.668122
+v 0.503606 -0.410382 0.661726
+v -0.0672387 0.765695 -0.144651
+v -0.0787096 0.765695 -0.138639
+v 0.504159 -0.375725 0.66283
+v 0.500986 -0.445346 0.657538
+v 0.50227 -0.427851 0.659606
+v 0.491018 -0.445244 0.665785
+v -0.282192 -0.936397 -0.351743
+v -0.96894 0.198087 0.446965
+v -0.965909 0.21566 0.446888
+v 0.499457 -0.324447 0.656446
+v 0.495899 -0.307671 0.651295
+v -0.535835 -0.638116 0.321556
+v -0.532123 -0.647724 0.301428
+v -0.524891 -0.655457 0.298165
+v 0.809633 -0.397061 0.227567
+v 0.808772 -0.37918 0.227452
+v -0.0598912 0.690576 -0.0889152
+v -0.962389 0.40884 0.266013
+v 0.537621 -0.602817 0.596202
+v -0.140611 -0.337716 -0.443574
+v -0.140418 -0.320195 -0.438423
+v -0.128048 -0.319283 -0.447183
+v 0.537043 -0.637486 0.595058
+v 0.768104 -0.128864 0.201658
+v 0.77522 -0.146886 0.201594
+v -0.529849 0.0678489 0.49412
+v -0.521025 0.0871939 0.507441
+v -0.515719 0.105935 0.515482
+v -0.512071 0.124291 0.521031
+v -0.509579 0.142724 0.524872
+v -0.50701 0.161131 0.528764
+v -0.506908 0.179462 0.529034
+v -0.50886 0.197638 0.526259
+v -0.511943 0.215685 0.52193
+v -0.515899 0.23363 0.516214
+v -0.520755 0.251511 0.509239
+v -0.525443 0.269559 0.502431
+v -0.530222 0.287529 0.495533
+v -0.535899 0.3055 0.487325
+v -0.542823 0.322995 0.477306
+v -0.55035 0.340901 0.466361
+v -0.556542 0.359257 0.457498
+v -0.557942 0.377575 0.45561
+v -0.554063 0.396355 0.461236
+v -0.549914 0.41516 0.467569
+v -0.547948 0.433721 0.470356
+v -0.546278 0.452296 0.472912
+v -0.54484 0.470973 0.475841
+v -0.544737 0.489329 0.475905
+v -0.546587 0.507633 0.473195
+v -0.354293 -0.659966 0.524448
+v -0.231826 -0.982254 0.177034
+v -0.22259 -0.981162 0.154734
+v -0.430028 -0.91533 0.610704
+v -0.427472 -0.932813 0.613915
+v -0.431878 -0.897552 0.608366
+v -0.433921 -0.879916 0.60536
+v -0.58502 0.679028 -0.694507
+v 0.407177 -0.48148 0.702163
+v 0.947604 -0.669047 0.330227
+v -0.174895 0.615971 0.0384974
+v -0.0403792 0.937231 -0.171857
+v 0.645174 -0.0862176 0.46139
+v 0.654076 -0.08677 0.452257
+v 0.652663 -0.428378 0.53791
+v 0.662079 -0.428314 0.529136
+v 0.623967 -0.619349 0.540183
+v 0.513677 0.0835972 0.451962
+v 0.503105 0.08361 0.459271
+v -0.728515 -0.0603087 0.497113
+v 0.951766 -0.569792 0.0480157
+v 0.527743 -0.137046 0.585039
+v 0.537736 -0.136879 0.576908
+v -0.633164 0.670769 -0.727416
+v -0.646908 0.670422 -0.7124
+v 0.554345 -0.410446 0.621982
+v 0.54588 -0.410138 0.632502
+v 0.474756 -0.672233 0.640389
+v 0.476015 -0.654635 0.642226
+v 0.462964 -0.655084 0.645977
+v 0.418211 -0.822343 0.579284
+v 0.431326 -0.821701 0.575521
+v -0.26891 0.52098 0.0369174
+v -0.150566 -0.923718 0.710294
+v 0.468256 -0.765143 0.584384
+v 0.457427 -0.766325 0.591038
+v 0.48308 -0.515713 0.653684
+v 0.491056 -0.533041 0.642342
+v -0.062229 0.746967 -0.137458
+v -0.0736357 0.803615 -0.153668
+v -0.0845285 0.803743 -0.146809
+v -0.0709638 0.784783 -0.14993
+v -0.0852607 0.822754 -0.147618
+v -0.0750487 0.822793 -0.155582
+v 0.499894 -0.462945 0.655701
+v 0.490491 -0.462636 0.664847
+v 0.461448 -0.498487 0.66784
+v 0.474191 -0.498423 0.663781
+v 0.465584 -0.480748 0.67407
+v 0.502078 -0.341402 0.660094
+v 0.489952 -0.341556 0.665284
+v 0.460061 -0.515957 0.665425
+v 0.464441 -0.34234 0.673312
+v -0.048202 0.691218 -0.0943616
+v 0.526214 -0.637499 0.601956
+v -0.723942 0.45755 -0.171074
+v -0.468128 0.523099 0.307516
+v -0.215114 0.569162 -0.088016
+v -0.517402 0.0679645 0.48965
+v -0.510286 0.0870397 0.500517
+v -0.505006 0.10582 0.508481
+v -0.502347 0.12424 0.512527
+v -0.499984 0.142711 0.51624
+v -0.497518 0.161119 0.520042
+v -0.497274 0.179385 0.520376
+v -0.499444 0.197484 0.517357
+v -0.502309 0.215595 0.513221
+v -0.506098 0.233682 0.507787
+v -0.510581 0.251832 0.501249
+v -0.514782 0.269674 0.495315
+v -0.51956 0.287645 0.488391
+v -0.524608 0.305384 0.481133
+v -0.531853 0.323522 0.470639
+v -0.539599 0.34112 0.459374
+v -0.544942 0.359424 0.451628
+v -0.54597 0.377626 0.450266
+v -0.546099 0.396188 0.450099
+v -0.544249 0.414222 0.451692
+v -0.542438 0.433272 0.455083
+v -0.54105 0.451949 0.45755
+v -0.539393 0.470947 0.461904
+v -0.537441 0.489187 0.4636
+v -0.537595 0.507672 0.463535
+v -0.531622 0.525514 0.450035
+v -0.537107 0.539284 0.444049
+v 0.609657 -0.468121 -0.246912
+v -0.452456 -0.485578 0.540941
+v -0.439084 -0.485038 0.543485
+v -0.456181 -0.473516 0.552476
+v -0.420536 -0.823551 -0.0995767
+v -0.414537 -0.950462 0.610537
+v -0.415166 -0.932389 0.60906
+v -0.704956 -0.971978 0.0942716
+v -0.713331 -0.962203 0.110213
+v -0.417697 -0.914919 0.606015
+v -0.42033 -0.897321 0.602496
+v -0.422475 -0.879736 0.599285
+v -0.268358 0.51484 -0.00337831
+v -0.198787 0.577961 0.0260117
+v -0.188306 0.578205 0.0186257
+v -0.180958 0.59696 0.029557
+v 0.949852 -0.651385 0.333695
+v 0.9521 -0.633774 0.337163
+v -0.275037 0.567814 -0.093745
+v -0.264787 0.581057 -0.105537
+v -0.0275724 0.899068 -0.199243
+v 0.640781 -0.0692105 0.455006
+v 0.649362 -0.0695316 0.445
+v 0.649246 -0.463163 0.5329
+v 0.660268 -0.463189 0.526169
+v 0.650287 -0.445886 0.534429
+v 0.624211 -0.602149 0.540915
+v 0.518494 0.0668726 0.45904
+v 0.511532 0.0496471 0.471577
+v -0.944097 0.443908 0.201556
+v -0.950751 0.443882 0.214568
+v -0.946795 0.461442 0.201504
+v 0.54254 -0.153912 0.58387
+v 0.532303 -0.153655 0.591616
+v 0.554846 -0.393207 0.622547
+v 0.5466 -0.392796 0.633646
+v -0.100855 0.59624 -0.0326913
+v 0.478532 -0.745464 0.599606
+v 0.468667 -0.745451 0.608405
+v 0.485327 -0.727018 0.609638
+v 0.475321 -0.726761 0.61782
+v 0.485135 -0.568507 0.63335
+v 0.477749 -0.550973 0.645489
+v -0.649901 0.783499 -0.471268
+v -0.0753056 0.841842 -0.155724
+v -0.0850294 0.841829 -0.147233
+v 0.477685 -0.480337 0.668803
+v 0.503748 -0.358538 0.662252
+v 0.491853 -0.358628 0.667891
+v 0.460318 -0.837706 0.572091
+v 0.456593 -0.82075 0.566747
+v 0.448127 -0.838066 0.577114
+v -0.0122608 0.654789 -0.0647018
+v -0.0188633 0.672336 -0.0743357
+v 0.415244 -0.223983 0.670293
+v 0.404531 -0.224202 0.677294
+v -0.938766 0.304023 0.510626
+v -0.939833 0.303881 0.497768
+v -0.578379 0.712464 -0.751964
+v -0.573292 0.715213 -0.738489
+v 0.972306 -0.687378 0.111985
+v -0.868811 -0.315275 0.372616
+v -0.870853 -0.328493 0.360131
+v -0.86718 -0.332706 0.37173
+v -0.500498 0.0868342 0.492129
+v -0.495244 0.105691 0.500055
+v -0.492842 0.124253 0.50378
+v -0.491056 0.14293 0.507222
+v -0.488269 0.161106 0.51105
+v -0.488051 0.179282 0.511346
+v -0.490633 0.197381 0.507518
+v -0.493626 0.215441 0.503266
+v -0.497119 0.233656 0.498089
+v -0.500382 0.251601 0.493503
+v -0.504505 0.269481 0.487659
+v -0.509078 0.287619 0.481031
+v -0.514756 0.305564 0.472835
+v -0.521281 0.323483 0.463317
+v -0.528834 0.341325 0.45236
+v -0.533484 0.359527 0.445655
+v -0.534474 0.377934 0.444332
+v -0.536452 0.396226 0.44148
+v -0.536285 0.414633 0.441608
+v -0.535064 0.433195 0.443754
+v -0.534448 0.451756 0.444846
+v -0.533754 0.470279 0.445976
+v -0.531378 0.488943 0.449701
+v -0.530286 0.507402 0.45182
+v 0.82443 -0.787006 -0.0275146
+v -0.523632 0.52554 0.438975
+v -0.516259 0.525553 0.426695
+v -0.0234106 -0.95131 0.694468
+v -0.934039 -0.220913 0.269366
+v -0.932588 -0.203611 0.26925
+v -0.932267 -0.203726 0.256418
+v -0.410182 -0.965427 0.590961
+v -0.401461 -0.949756 0.606632
+v -0.42367 -0.96562 0.59317
+v -0.402026 -0.931798 0.605193
+v -0.40534 -0.914495 0.601327
+v -0.408217 -0.897 0.597268
+v 0.396194 -0.241003 0.687776
+v -0.590415 0.436226 -0.072486
+v -0.293175 -0.977553 0.367555
+v 0.467087 -0.359283 0.677011
+v -0.0957039 -0.0507518 -0.268775
+v -0.0818438 0.708932 -0.0982408
+v 0.953333 -0.616253 0.339244
+v 0.410105 -0.8928 0.589895
+v 0.397376 -0.875497 0.593466
+v 0.61256 -0.449714 -0.246591
+v 0.624249 -0.44875 -0.234028
+v 0.62213 -0.466965 -0.233579
+v 0.952871 -0.59904 0.338332
+v -0.935041 -0.220926 0.256495
+v -0.0156905 0.860995 -0.204934
+v -0.562785 0.525758 0.472386
+v 0.644995 -0.0524474 0.438667
+v 0.659985 -0.48035 0.525707
+v 0.624545 -0.58292 0.541609
+v 0.660807 -0.445809 0.527055
+v 0.507498 0.0663845 0.465616
+v 0.536721 -0.170431 0.597974
+v 0.546844 -0.17074 0.590074
+v -0.995106 0.1451 0.22889
+v -0.992177 0.1623 0.215994
+v 0.554949 -0.375802 0.623048
+v 0.546111 -0.375622 0.632926
+v 0.489913 -0.708431 0.616536
+v 0.480626 -0.708058 0.625797
+v 0.487986 -0.550755 0.637705
+v 0.482964 -0.586067 0.630126
+v -0.261832 0.764616 -0.148081
+v -0.248563 0.764488 -0.157368
+v 0.99851 -0.578411 0.175826
+v 0.47938 -0.358975 0.672336
+v 0.449373 -0.890821 0.578462
+v 0.438622 -0.873249 0.585502
+v 0.451005 -0.872838 0.581019
+v 0.450144 -0.855343 0.580029
+v 0.438339 -0.855677 0.585129
+v 0.444338 -0.821071 0.571616
+v 0.435501 -0.83858 0.580993
+v 0.461923 -0.872774 0.574416
+v 0.553253 -0.274196 -0.272834
+v 0.558892 -0.268968 -0.268685
+v -0.87102 -0.415276 0.231845
+v -0.884829 -0.396984 0.231729
+v -0.884816 -0.397061 0.21891
+v -0.490992 0.0868342 0.483343
+v -0.496105 0.0677975 0.475443
+v -0.486599 0.105563 0.490035
+v -0.483812 0.123983 0.494159
+v -0.481512 0.142506 0.497832
+v -0.478648 0.160348 0.50229
+v -0.479123 0.179166 0.501583
+v -0.481769 0.197291 0.497678
+v -0.484929 0.2153 0.493234
+v -0.487858 0.233399 0.489033
+v -0.490697 0.251575 0.484923
+v -0.494782 0.269469 0.479117
+v -0.499226 0.287709 0.472643
+v -0.505045 0.305538 0.464242
+v -0.510941 0.323278 0.455738
+v -0.517646 0.341145 0.446066
+v -0.522746 0.359655 0.438577
+v -0.524017 0.377934 0.436881
+v -0.526779 0.3962 0.432887
+v -0.526201 0.414698 0.433901
+v -0.524416 0.433285 0.436547
+v -0.523876 0.451833 0.437588
+v -0.525097 0.470189 0.43534
+v -0.524994 0.488674 0.435982
+v -0.523311 0.507338 0.438538
+v 0.233739 -0.968972 0.537935
+v 0.224517 -0.970103 0.560132
+v -0.419033 -0.968497 0.580171
+v -0.388281 -0.949062 0.603048
+v -0.388641 -0.931168 0.602265
+v -0.39139 -0.913776 0.598552
+v -0.20399 0.567595 -0.0815163
+v -0.0646697 0.822793 -0.163097
+v -0.0542007 0.822767 -0.170586
+v -0.0651963 0.841868 -0.163611
+v 0.631635 -0.00137445 0.419271
+v 0.627589 0.0159796 0.413143
+v 0.619342 0.0160438 0.424023
+v 0.470543 -0.410716 0.681661
+v 0.470658 -0.428031 0.681687
+v 0.459136 -0.533273 0.664063
+v 0.449451 -0.515983 0.672798
+v 0.951278 -0.581982 0.336483
+v 0.526689 -0.765888 0.533247
+v 0.5122 -0.784629 0.534711
+v 0.58001 -0.445732 0.591064
+v 0.576491 -0.708637 0.538321
+v 0.587409 -0.708765 0.531461
+v 0.580704 -0.690705 0.544641
+v 0.623093 -0.00100193 0.429328
+v 0.640357 -0.0355558 0.432052
+v 0.632201 -0.0354145 0.442957
+v 0.658533 -0.497871 0.523446
+v 0.648822 -0.480568 0.532091
+v 0.64836 -0.497948 0.531307
+v 0.624853 -0.565219 0.542136
+v 0.62556 -0.550061 0.542984
+v 0.61387 -0.567569 0.548648
+v 0.537685 0.0156199 0.486567
+v 0.517415 0.0322545 0.479785
+v -0.958908 0.302455 0.215249
+v -0.956236 0.30243 0.202352
+v -0.967424 0.284742 0.202519
+v 0.550569 -0.187516 0.59538
+v 0.540344 -0.18731 0.603202
+v 0.554255 -0.358602 0.622368
+v 0.544557 -0.358538 0.630922
+v 0.493459 -0.690024 0.621969
+v 0.483696 -0.689959 0.630422
+v 0.472341 -0.586169 0.637319
+v 0.751623 -0.362225 0.410356
+v 0.751315 -0.379489 0.410253
+v -0.654115 -0.3948 -0.199603
+v -0.654256 -0.376226 -0.204703
+v -0.641308 -0.394441 -0.204638
+v -0.433407 -0.842138 -0.101285
+v 0.50466 -0.932106 0.472925
+v 0.506702 -0.932389 0.460196
+v 0.523748 -0.913095 0.473105
+v 0.43956 -0.603678 0.657551
+v -0.067881 0.708046 -0.202468
+v -0.0807391 0.70802 -0.200772
+v 0.480832 -0.378076 0.674173
+v 0.483735 -0.603164 0.631179
+v 0.471801 -0.603459 0.636562
+v 0.473908 -0.620415 0.639323
+v 0.486137 -0.620132 0.634455
+v 0.487537 -0.654494 0.636369
+v 0.487485 -0.637191 0.636497
+v 0.475167 -0.637512 0.641263
+v 0.486047 -0.671989 0.634018
+v 0.460356 -0.89086 0.57195
+v 0.365404 0.150084 0.463227
+v -0.119031 0.669291 -0.173322
+v -0.967784 0.284934 0.2153
+v -0.420369 -0.841637 -0.107387
+v -0.482001 0.0865388 0.473645
+v -0.47825 0.105062 0.479232
+v -0.474871 0.123752 0.484409
+v -0.471776 0.142454 0.489265
+v -0.469258 0.159937 0.493606
+v -0.470311 0.179051 0.491679
+v -0.472521 0.197124 0.488661
+v -0.475732 0.215351 0.483767
+v -0.478455 0.233245 0.480183
+v -0.481063 0.251524 0.476304
+v -0.485135 0.269417 0.470536
+v -0.48981 0.287452 0.463767
+v -0.495861 0.305795 0.454788
+v -0.501179 0.323368 0.447286
+v -0.507678 0.341377 0.437832
+v -0.512662 0.359745 0.430549
+v -0.513626 0.37787 0.429418
+v -0.517261 0.396149 0.423843
+v -0.516323 0.414698 0.4255
+v -0.513677 0.433439 0.429855
+v -0.513793 0.451833 0.429842
+v -0.51554 0.470189 0.427286
+v -0.517556 0.488584 0.423689
+v -0.516362 0.507068 0.426657
+v -0.462244 0.503317 0.294761
+v -0.459187 0.503279 0.281826
+v -0.464916 0.523009 0.281749
+v -0.375179 -0.94842 0.5994
+v -0.374819 -0.93059 0.599195
+v -0.378108 -0.913147 0.595405
+v 0.827308 -0.703588 0.42708
+v 0.635746 -0.0186128 0.425475
+v 0.627358 -0.0182018 0.435648
+v 0.583902 -0.393336 0.597037
+v 0.582721 -0.376175 0.595405
+v 0.573035 -0.376123 0.603922
+v 0.578828 -0.290355 0.590485
+v 0.568873 -0.27304 0.598771
+v 0.564609 -0.8198 0.497319
+v 0.552804 -0.837976 0.50247
+v 0.428359 -0.240939 0.666735
+v 0.908323 -0.565309 0.364627
+v 0.90375 -0.544538 0.353451
+v 0.9484 -0.565193 0.332539
+v 0.806242 -0.325423 0.176083
+v 0.618764 -0.803936 0.439926
+v 0.624609 -0.784963 0.448635
+v 0.611481 -0.803165 0.452129
+v 0.578379 -0.273142 0.589985
+v 0.614757 0.0330381 0.417459
+v 0.622759 0.0328326 0.406412
+v 0.657711 -0.549869 0.521827
+v 0.646934 -0.549946 0.528777
+v 0.647589 -0.515302 0.529997
+v 0.646677 -0.532694 0.52852
+v 0.482232 -0.8905 0.558347
+v 0.480883 -0.908317 0.555611
+v 0.597403 -0.654815 0.546632
+v 0.599278 -0.637063 0.549548
+v 0.58931 -0.637319 0.55764
+v 0.553986 -0.341428 0.621892
+v 0.543016 -0.341479 0.628739
+v 0.480189 -0.462829 0.672657
+v 0.57861 -0.0519335 0.500594
+v 0.577197 -0.0348364 0.498565
+v 0.567692 -0.0522547 0.507286
+v -0.114561 0.784552 -0.122544
+v -0.115447 0.80364 -0.1237
+v -0.125261 0.803653 -0.115248
+v 0.619587 -0.018266 0.447415
+v 0.41017 -0.20731 0.662894
+v 0.398365 -0.207028 0.668482
+v -0.124837 0.784616 -0.114811
+v -0.0522739 0.616883 -0.0547081
+v 0.382642 -0.482084 0.711899
+v 0.39631 -0.481429 0.708881
+v 0.420536 -0.674096 0.651822
+v 0.423298 -0.7282 0.632682
+v -0.00815034 0.956114 -0.215698
+v -0.0160245 0.956101 -0.204459
+v 0.415231 -0.710281 0.643871
+v -0.106391 0.70942 -0.0883628
+v 0.452354 -0.292141 0.655791
+v 0.448603 -0.275069 0.650627
+v 0.439341 -0.275403 0.659593
+v 0.447241 -0.909139 0.575328
+v 0.495295 -0.603022 0.625219
+v 0.497569 -0.61994 0.628443
+v 0.493754 -0.585964 0.623151
+v 0.504146 -0.515469 0.638797
+v 0.494422 -0.5687 0.624102
+v 0.411544 -0.874688 0.59186
+v 0.508667 -0.480273 0.645695
+v -0.646138 0.688688 -0.712875
+v -0.644262 0.707031 -0.712567
+v -0.638906 0.688688 -0.725091
+v 0.46227 -0.854944 0.574878
+v 0.457967 -0.909126 0.568302
+v -0.2853 0.573427 -0.0965966
+v -0.472906 0.0862433 0.464178
+v -0.468911 0.105164 0.470266
+v -0.465481 0.123829 0.475533
+v -0.46218 0.142429 0.480633
+v -0.46078 0.160772 0.482958
+v -0.461743 0.178922 0.481622
+v -0.46349 0.19706 0.479001
+v -0.46588 0.215133 0.475764
+v -0.46877 0.233232 0.471577
+v -0.471467 0.251421 0.46762
+v -0.475886 0.269623 0.46112
+v -0.480896 0.287465 0.453979
+v -0.485764 0.305397 0.447004
+v -0.491429 0.323393 0.438808
+v -0.498031 0.341338 0.4292
+v -0.502116 0.359617 0.422867
+v -0.50394 0.377857 0.420799
+v -0.507588 0.396136 0.414903
+v -0.506407 0.414621 0.417035
+v -0.5043 0.433349 0.420594
+v -0.504467 0.451833 0.420427
+v -0.506497 0.470176 0.417524
+v -0.509554 0.48843 0.413233
+v -0.17013 0.884591 -0.0559927
+v 0.361152 -0.765811 0.655367
+v -0.362668 -0.948073 0.595277
+v -0.363271 -0.930102 0.593761
+v -0.36507 -0.912607 0.591385
+v -0.0689343 0.897167 -0.249327
+v -0.0688958 0.879363 -0.253322
+v -0.0817539 0.879312 -0.243547
+v 0.561474 -0.838233 0.492489
+v 0.646703 -0.70924 0.481891
+v 0.637968 -0.709048 0.491782
+v 0.632894 -0.727686 0.484229
+v 0.944585 -0.548713 0.327234
+v -0.00428391 0.765516 -0.256765
+v 0.939833 -0.53263 0.320542
+v 0.93025 -0.532528 0.328994
+v 0.314729 -0.622727 0.72513
+v -0.947514 0.320118 0.215146
+v -0.945767 0.320195 0.202519
+v 0.607062 -0.841919 0.422456
+v 0.612791 -0.822806 0.431062
+v 0.598841 -0.841251 0.43331
+v 0.630325 -0.765939 0.457241
+v 0.62222 -0.765438 0.468224
+v 0.616902 -0.783961 0.460517
+v -0.933641 -0.203829 0.217895
+v 0.951226 -0.761045 0.163431
+v 0.962029 -0.742047 0.163366
+v 0.962672 -0.742304 0.176212
+v 0.998086 -0.63177 0.1888
+v 0.998253 -0.613992 0.201645
+v 0.647859 -0.567107 0.529984
+v 0.65897 -0.566991 0.523549
+v -0.0552284 0.841868 -0.171896
+v 0.657005 -0.672207 0.497306
+v 0.660807 -0.654352 0.50306
+v 0.648488 -0.672284 0.507351
+v 0.573677 -0.0177907 0.493568
+v 0.562939 -0.0180476 0.500337
+v 0.566047 -0.0347337 0.504961
+v 0.738213 -0.378602 0.435918
+v 0.738547 -0.361235 0.436792
+v 0.46972 -0.3762 0.680711
+v 0.331608 0.0456137 0.526863
+v 0.327228 0.0629933 0.520723
+v 0.319328 0.0454595 0.531757
+v 0.738239 -0.343984 0.43656
+v 0.548732 -0.585373 0.589805
+v -0.120842 0.841817 -0.108568
+v -0.124143 0.822664 -0.113617
+v -0.0666992 -0.879556 0.711822
+v 0.480562 -0.820057 0.556445
+v 0.483131 -0.872697 0.559849
+v -0.943494 0.337844 0.214992
+v -0.719921 0.486747 -0.300747
+v 0.495899 -0.672079 0.62563
+v 0.436849 -0.785105 0.583793
+v 0.507293 -0.307542 0.645168
+v 0.510286 -0.324292 0.649561
+v 0.51342 -0.341325 0.6538
+v 0.515231 -0.392989 0.656189
+v 0.515835 -0.375532 0.657307
+v 0.51464 -0.358384 0.655573
+v 0.682477 -0.425989 -0.157856
+v 0.690338 -0.425256 -0.144767
+v 0.685187 -0.443677 -0.144497
+v -0.462617 0.0862947 0.456342
+v -0.460086 0.104985 0.460375
+v -0.456477 0.123585 0.465835
+v -0.453523 0.141979 0.470061
+v -0.452559 0.160463 0.472039
+v -0.453124 0.178755 0.470999
+v -0.454614 0.196983 0.469174
+v -0.456426 0.215249 0.466464
+v -0.458995 0.233232 0.463099
+v -0.461962 0.251305 0.458873
+v -0.466406 0.269443 0.452309
+v -0.47175 0.287632 0.444447
+v -0.476169 0.305281 0.438333
+v -0.481782 0.323316 0.43015
+v -0.488744 0.341595 0.419771
+v -0.493253 0.35981 0.41313
+v -0.494833 0.377909 0.411217
+v -0.498687 0.396175 0.405089
+v -0.497505 0.414646 0.40717
+v -0.495154 0.433272 0.411525
+v -0.495719 0.451731 0.410433
+v -0.498134 0.469997 0.407324
+v -0.502527 0.488224 0.400632
+v -0.502592 0.506721 0.400542
+v -0.492855 0.527145 0.385038
+v -0.103283 -0.0550421 -0.269533
+v -0.103116 -0.0735265 -0.278088
+v 0.611777 -0.431679 -0.247516
+v 0.62678 -0.430382 -0.233361
+v -0.215576 0.558835 0.0240721
+v -0.226084 0.558642 0.0314324
+v -0.349758 -0.947264 0.591038
+v -0.352661 -0.912106 0.586914
+v -0.356117 -0.894688 0.582521
+v -0.393381 0.320041 0.219989
+v -0.0442328 0.765785 -0.156571
+v -0.0557422 0.76576 -0.150637
+v -0.597583 0.705913 -0.397164
+v -0.595938 0.700454 -0.386053
+v -0.592342 0.70048 -0.411782
+v 0.635515 -0.747327 0.464871
+v 0.641218 -0.728341 0.473452
+v 0.627307 -0.746736 0.475751
+v 0.518327 0.100977 0.436098
+v -0.199854 0.765451 -0.0428519
+v -0.206906 0.765541 -0.030392
+v 0.605033 -0.82251 0.442289
+v 0.239918 -0.935741 0.615508
+v 0.937174 -0.780249 0.163508
+v 0.937289 -0.780326 0.17634
+v 0.951625 -0.761251 0.176263
+v 0.659394 -0.58414 0.524011
+v 0.648566 -0.584333 0.530999
+v 0.614513 -0.532913 0.549997
+v 0.625816 -0.532772 0.543613
+v 0.477094 -0.803049 0.551564
+v 0.483786 -0.854816 0.560967
+v -0.117181 0.860853 -0.103225
+v 0.519406 -0.290034 0.640338
+v 0.50719 -0.290214 0.645412
+v -0.862286 0.495739 0.0729613
+v -0.861168 0.512823 0.0737449
+v -0.849877 0.495507 0.0602188
+v 0.47825 -0.784976 0.553247
+v -0.108421 0.746671 -0.113925
+v -0.123 0.765554 -0.112319
+v -0.119391 0.746273 -0.107322
+v -0.11424 0.727673 -0.0998465
+v 0.445417 -0.766106 0.596818
+v 0.0488828 0.727648 -0.253746
+v 0.064644 0.722008 -0.25435
+v -0.419303 0.328955 0.304793
+v -0.411544 0.317446 0.307863
+v -0.414165 0.325834 0.294504
+v -0.0449136 0.619156 -0.0669112
+v 0.497004 -0.654725 0.627377
+v -0.0477395 0.937129 -0.159654
+v -0.050861 0.918297 -0.164535
+v -0.0538282 0.899068 -0.169391
+v -0.0468275 0.955639 -0.158537
+v -0.471467 -0.915112 -0.123289
+v -0.471455 -0.897347 -0.116494
+v -0.458853 -0.896602 -0.12045
+v 0.440985 -0.292269 0.661957
+v -0.496978 0.351049 -0.0250869
+v 0.0214838 0.651 -0.120489
+v -0.452071 0.0862819 0.448956
+v -0.448808 0.0684269 0.453734
+v -0.450619 0.104933 0.451397
+v -0.447074 0.123597 0.45692
+v -0.444184 0.141786 0.4613
+v -0.443799 0.160309 0.46211
+v -0.444325 0.178627 0.461711
+v -0.445815 0.196841 0.459258
+v -0.447036 0.21512 0.457614
+v -0.449682 0.233335 0.453709
+v -0.452816 0.251408 0.449354
+v -0.457004 0.26925 0.443458
+v -0.462103 0.287542 0.435751
+v -0.467113 0.305423 0.428673
+v -0.472739 0.323457 0.420504
+v -0.479496 0.341261 0.41078
+v -0.484595 0.359617 0.403047
+v -0.485957 0.377819 0.401326
+v -0.489374 0.39611 0.396123
+v -0.489682 0.414466 0.395802
+v -0.487871 0.433079 0.39918
+v -0.488372 0.451487 0.398859
+v -0.482746 0.443381 0.384768
+v -0.491429 0.46974 0.39462
+v -0.496156 0.506567 0.387645
+v -0.488282 0.5064 0.375442
+v 0.751688 -0.0936551 0.214491
+v -0.661873 0.475687 -0.340786
+v 0.00569689 -0.981676 -0.273001
+v -0.00766222 -0.982216 -0.275133
+v 0.00113681 -0.982588 -0.297214
+v 0.0144959 -0.982062 -0.295134
+v -0.340163 -0.911592 0.582868
+v -0.343027 -0.894187 0.578604
+v -0.34498 -0.876576 0.575649
+v -0.940513 0.337741 0.202172
+v 0.59238 -0.860622 0.423548
+v 0.584609 -0.859492 0.435391
+v 0.996737 -0.560761 0.188697
+v 0.998292 -0.578437 0.201581
+v 0.598469 -0.821444 0.455713
+v 0.592187 -0.840134 0.446682
+v 0.560524 0.0158126 0.474505
+v 0.55378 0.033128 0.464858
+v 0.548591 0.0162365 0.47999
+v 0.987206 -0.597242 0.111574
+v -0.256244 0.595084 -0.115698
+v -0.272648 0.592207 -0.111741
+v -0.272584 0.611462 -0.12433
+v -0.00107258 0.918079 -0.228338
+v -0.000995511 0.937154 -0.228197
+v 0.701706 -0.930436 0.20311
+v 0.692419 -0.931477 0.225666
+v 0.68434 -0.9384 0.206809
+v 0.768271 -0.520569 0.364832
+v -0.474075 -0.428211 -0.22722
+v -0.461294 -0.428134 -0.225165
+v 0.917739 -0.800763 0.176469
+v 0.658328 -0.601635 0.522315
+v 0.738688 -0.0580607 0.175993
+v 0.747089 -0.0756203 0.175993
+v 0.626395 -0.515392 0.544628
+v 0.550171 -0.017932 0.504628
+v 0.544043 -0.000937707 0.495931
+v 0.059994 0.710692 -0.163212
+v 0.0508353 0.710332 -0.153797
+v -0.0633594 0.803795 -0.161388
+v 0.452277 -0.481018 0.67723
+v 0.457055 -0.463176 0.684462
+v 0.518995 -0.306938 0.640582
+v -0.943404 0.355519 0.21494
+v -0.940385 0.355391 0.202134
+v 0.554345 -0.324048 0.62265
+v 0.542463 -0.324023 0.628662
+v 0.432533 -0.224228 0.650075
+v 0.43929 -0.207066 0.637307
+v 0.455745 -0.746299 0.612001
+v 0.498031 -0.637165 0.629047
+v 0.507113 -0.497704 0.643293
+v 0.506689 -0.136995 0.599683
+v 0.501397 -0.120425 0.591963
+v 0.514782 -0.170547 0.611526
+v 0.0217021 -0.876075 0.681803
+v 0.522951 -0.221556 0.623369
+v 0.525572 -0.238653 0.626928
+v 0.531352 -0.289751 0.635174
+v 0.529323 -0.272744 0.63222
+v 0.527473 -0.255673 0.629651
+v -0.136539 -0.763961 -0.293631
+v -0.441474 0.104663 0.441994
+v -0.437556 0.123546 0.448108
+v -0.435359 0.141838 0.45132
+v -0.435269 0.160065 0.451384
+v -0.43613 0.178421 0.45069
+v -0.43753 0.196726 0.448327
+v -0.437967 0.215082 0.44798
+v -0.440292 0.233194 0.444846
+v -0.44349 0.251177 0.440414
+v -0.447883 0.269353 0.433888
+v -0.452649 0.287336 0.426991
+v -0.458275 0.305346 0.418808
+v -0.46394 0.323355 0.410587
+v -0.476528 0.35954 0.391846
+v -0.478211 0.377626 0.389932
+v -0.481448 0.395956 0.384755
+v -0.482694 0.414261 0.383124
+v -0.482373 0.432707 0.384999
+v -0.47902 0.422533 0.372026
+v -0.474653 0.403702 0.371473
+v 0.625136 -0.255056 0.567492
+v 0.622425 -0.238139 0.563575
+v 0.612958 -0.2553 0.573067
+v 0.563761 -0.376008 0.61326
+v 0.563915 -0.393259 0.613376
+v -0.989685 0.232705 0.266938
+v 0.147663 -0.871168 0.638514
+v 0.737763 -0.326784 0.436226
+v 0.431467 -0.292153 0.670807
+v -0.669876 0.593337 0.00301864
+v -0.676774 0.591719 0.0192679
+v -0.659959 0.585951 0.00674378
+v 0.49536 0.1353 0.425462
+v 0.484377 0.140913 0.426644
+v -0.151465 0.629921 -0.14546
+v 0.666228 -0.729664 0.441724
+v 0.671045 -0.710872 0.448982
+v -0.862363 -0.381159 0.308775
+v -0.870635 -0.380234 0.295609
+v 0.604185 -0.80242 0.464332
+v -0.0576047 -0.843756 0.702381
+v 0.359174 -0.248312 -0.370625
+v 0.347125 -0.267388 -0.38139
+v 0.346418 -0.244009 -0.373079
+v -0.154535 0.784527 -0.0901098
+v 0.604737 -0.481056 0.558668
+v 0.590248 -0.498911 0.560119
+v -0.499188 -0.523831 -0.164523
+v -0.486355 -0.52414 -0.16311
+v -0.486111 -0.543433 -0.144831
+v 0.0913622 0.725721 -0.220156
+v 0.0816126 0.729459 -0.199732
+v 0.0807905 0.705682 -0.208248
+v 0.606626 -0.153257 0.541031
+v 0.673151 -0.272719 0.523844
+v 0.369245 -0.500517 0.714378
+v 0.800358 -0.437215 0.297523
+v 0.467318 -0.551102 0.652991
+v 0.769144 -0.503125 0.36604
+v 0.804687 -0.343483 0.227465
+v 0.806897 -0.361377 0.227452
+v 0.656812 -0.619118 0.520042
+v 0.647872 -0.601712 0.530305
+v 0.974309 -0.705066 0.150457
+v 0.625161 -0.498243 0.542829
+v 0.554435 -0.0351062 0.510524
+v 0.0448879 0.747442 -0.185525
+v 0.0549072 0.692195 -0.14844
+v 0.0533016 0.728983 -0.173078
+v 0.029936 0.785207 -0.207156
+v 0.0248878 0.80391 -0.214439
+v 0.0208929 0.82287 -0.220091
+v 0.0102313 0.822806 -0.212962
+v 0.0135582 0.804039 -0.208209
+v -0.23451 0.649792 -0.153
+v 0.45261 -0.586067 0.654018
+v 0.545662 -0.221414 0.610781
+v 0.556156 -0.221414 0.603344
+v 0.543632 -0.204356 0.607904
+v 0.553986 -0.204446 0.600274
+v 0.54737 -0.238614 0.613132
+v 0.557788 -0.238614 0.605617
+v 0.554101 -0.306823 0.622445
+v 0.543003 -0.306874 0.629098
+v 0.552187 -0.289777 0.619798
+v 0.542014 -0.289739 0.627775
+v 0.484043 -0.0701096 0.56694
+v 0.490196 -0.0869241 0.575803
+v -0.248332 0.54676 -0.0672837
+v -0.237888 0.545565 -0.0598591
+v 0.517235 -0.137021 0.592412
+v 0.522348 -0.153758 0.599773
+v 0.501654 -0.0867957 0.56974
+v 0.506895 -0.103533 0.57737
+v 0.512071 -0.120271 0.584936
+v 0.495372 -0.0701739 0.560749
+v -0.138299 -0.787828 -0.296521
+v -0.150515 -0.787288 -0.286656
+v -0.125788 -0.765541 -0.310766
+v -0.43103 0.104638 0.434479
+v -0.427948 0.123392 0.439438
+v -0.425944 0.141851 0.442469
+v -0.426316 0.159924 0.441583
+v -0.42823 0.178216 0.439489
+v -0.428808 0.196623 0.439014
+v -0.428898 0.214915 0.438911
+v -0.43166 0.233027 0.434852
+v -0.435308 0.251126 0.42947
+v -0.438648 0.269032 0.42491
+v -0.443465 0.286977 0.418025
+v -0.451506 0.32654 0.387825
+v -0.468796 0.35927 0.380413
+v -0.471455 0.377305 0.377215
+v -0.47351 0.395635 0.374338
+v -0.158903 0.597242 0.0162621
+v -0.170207 0.59687 0.0225178
+v 0.668373 -0.54983 0.51466
+v -0.0532245 0.635701 -0.0335776
+v 0.671366 -0.445745 0.519772
+v 0.573151 -0.358808 0.60441
+v -0.00339758 0.841829 -0.209892
+v 0.671957 -0.307401 0.521815
+v -0.416644 0.422931 0.0756845
+v -0.41938 0.423522 0.0632246
+v -0.402128 0.43823 0.0636741
+v 0.381743 -0.728354 0.663036
+v 0.455655 -0.359399 0.6831
+v 0.459187 -0.376213 0.688123
+v 0.0904887 0.88147 -0.337009
+v 0.0932633 0.861187 -0.324845
+v 0.690839 -0.138203 0.437511
+v 0.68705 -0.120977 0.431486
+v 0.694243 -0.155004 0.441904
+v 0.661835 -0.748046 0.435109
+v 0.697712 -0.172024 0.446926
+v 0.608989 -0.783537 0.471577
+v -0.910455 -0.0659092 0.217098
+v 0.733255 -0.167785 -0.0551449
+v 0.729645 -0.149905 -0.0549265
+v 0.73644 -0.149352 -0.042261
+v 0.770146 -0.485514 0.368146
+v 0.801347 -0.419617 0.298756
+v 0.632175 -0.0693389 0.465437
+v -0.181973 0.18546 0.279925
+v -0.175422 0.803615 -0.0523703
+v -0.171697 0.82296 -0.0463458
+v -0.965305 0.180142 0.561905
+v -0.97016 0.180451 0.548815
+v 0.880577 -0.796511 0.322533
+v 0.887527 -0.777988 0.33259
+v -0.499008 -0.544564 -0.138781
+v 0.281909 -0.918156 0.607544
+v 0.441474 -0.966801 -0.153848
+v 0.450555 -0.958799 -0.130226
+v 0.914399 -0.685489 0.372706
+v 0.771739 -0.450587 0.370497
+v 0.770981 -0.468006 0.369354
+v 0.981901 -0.686491 0.150393
+v -0.163399 0.784527 -0.0802831
+v 0.646562 -0.619246 0.527775
+v 0.645084 -0.636793 0.525463
+v -0.445571 0.443869 0.217407
+v -0.449913 0.443574 0.230021
+v 0.625971 -0.480941 0.54423
+v 0.615219 -0.480928 0.55123
+v 0.556131 -0.0524859 0.512836
+v 0.544005 -0.0524859 0.51791
+v 0.0366155 0.766389 -0.197548
+v 0.0171292 0.841945 -0.225435
+v 0.572971 -0.153784 0.559991
+v 0.576863 -0.119538 0.543176
+v 0.5694 -0.136879 0.554776
+v 0.565765 -0.120091 0.549637
+v 0.559946 -0.103251 0.541288
+v 0.5708 -0.102917 0.534441
+v 0.58922 -0.170598 0.560903
+v 0.577313 -0.17065 0.566208
+v 0.553523 -0.0868984 0.531898
+v 0.592868 -0.187387 0.566169
+v 0.581513 -0.187516 0.572322
+v -0.0950873 0.803705 -0.139513
+v 0.595784 -0.204253 0.570344
+v 0.58511 -0.204356 0.57746
+v -0.0428583 0.65416 -0.0412077
+v 0.0144574 0.861097 -0.22916
+v 0.011747 0.879877 -0.232731
+v 0.00189468 0.880083 -0.224677
+v 0.00928073 0.899042 -0.236379
+v -4.49585e-05 0.898965 -0.226964
+v 0.558366 -0.255763 0.606234
+v 0.54904 -0.255698 0.615418
+v 0.540434 -0.272706 0.625553
+v 0.550222 -0.272783 0.617024
+v 0.538815 -0.255596 0.623241
+v 0.339829 0.158601 0.466849
+v 0.520241 -0.324395 0.641353
+v 0.421512 -0.839325 0.583344
+v 0.411056 -0.766556 0.614493
+v 0.731662 -0.1567 0.382944
+v 0.742426 -0.166758 0.368724
+v 0.564493 -0.341377 0.614429
+v 0.563825 -0.358743 0.613312
+v 0.563542 -0.410651 0.612605
+v 0.561539 -0.428365 0.609458
+v 0.55333 -0.463445 0.597576
+v 0.557698 -0.445847 0.603973
+v 0.551275 -0.481121 0.594378
+v -0.479868 0.522675 0.358731
+v -0.485366 0.528841 0.36911
+v -0.41875 0.123186 0.429971
+v -0.41771 0.141568 0.431499
+v -0.418853 0.159693 0.429971
+v -0.420613 0.17792 0.42735
+v -0.419919 0.196867 0.4292
+v -0.42051 0.214812 0.428057
+v -0.4234 0.232937 0.423882
+v -0.427305 0.250984 0.41832
+v -0.430131 0.269212 0.414171
+v -0.435218 0.287054 0.40708
+v 0.895889 -0.820622 0.202211
+v 0.893268 -0.821367 0.215107
+v -0.437003 0.301017 0.39385
+v 0.848811 -0.85312 0.231215
+v 0.827989 -0.866865 0.240169
+v -0.462296 0.358782 0.36753
+v -0.649272 0.464974 -0.294132
+v 0.400484 -0.766607 0.621751
+v 0.693293 0.0113938 0.081375
+v 0.701154 -0.000166989 0.0841752
+v 0.702798 -0.00545925 0.0732567
+v -0.0499361 0.746877 -0.1423
+v 0.588899 -0.516432 0.557987
+v 0.601025 -0.516086 0.552952
+v 0.66976 -0.48044 0.51728
+v 0.670685 -0.463112 0.51868
+v -0.000854212 0.82305 -0.20636
+v -0.054676 0.653813 -0.0357998
+v 0.602913 -0.136481 0.535777
+v 0.598302 -0.119911 0.529188
+v 0.559907 -0.567981 0.583433
+v -0.44796 -0.804848 0.285076
+v -0.942928 0.284099 0.099808
+v -0.196796 0.55588 -0.0491076
+v 0.667756 -0.498038 0.514133
+v 0.586818 -0.654866 0.553928
+v 0.438095 -0.498821 0.679131
+v 0.449335 -0.498783 0.672837
+v 0.438712 -0.48166 0.680313
+v -0.500755 -0.738463 0.12853
+v -0.502733 -0.728431 0.118292
+v -0.506445 -0.745618 0.118678
+v 0.644802 -0.120206 0.483548
+v 0.640473 -0.103225 0.477306
+v 0.546728 -0.551089 0.587043
+v 0.548218 -0.568212 0.58897
+v 0.525379 -0.358332 0.648405
+v 0.74258 -0.225037 0.398628
+v 0.771097 -0.433452 0.369277
+v 0.771277 -0.415982 0.37015
+v -0.901798 -0.327324 0.0774571
+v -0.90244 -0.327568 0.0901355
+v -0.911406 -0.309649 0.0773158
+v 0.357568 -0.517177 0.720249
+v 0.471095 -0.890873 0.564885
+v 0.64249 -0.654262 0.521506
+v 0.629272 -0.463291 0.549124
+v 0.547049 -0.0694931 0.522547
+v 0.587679 -0.221376 0.581121
+v 0.588758 -0.238486 0.582598
+v 0.638276 -0.289212 0.563626
+v 0.637544 -0.272063 0.562727
+v 0.626818 -0.272128 0.569766
+v 0.637274 -0.306681 0.562097
+v 0.626292 -0.289494 0.56888
+v 0.625649 -0.30681 0.567839
+v 0.635116 -0.341467 0.558642
+v 0.635566 -0.324138 0.559464
+v 0.624288 -0.324267 0.565758
+v 0.624275 -0.341492 0.565527
+v 0.636041 -0.255095 0.560594
+v 0.633151 -0.238011 0.556535
+v 0.62967 -0.221093 0.551526
+v 0.619484 -0.221286 0.559387
+v 0.626806 -0.204202 0.547467
+v 0.616696 -0.204356 0.555431
+v 0.588193 -0.307709 0.58125
+v 0.599137 -0.307658 0.574622
+v 0.588938 -0.290368 0.582496
+v 0.588462 -0.324935 0.581442
+v 0.588193 -0.273207 0.581866
+v 0.588783 -0.342199 0.582046
+v 0.591391 -0.359103 0.585489
+v 0.00786774 0.918053 -0.238113
+v 0.561641 -0.289918 0.610897
+v 0.55974 -0.272924 0.608225
+v 0.536876 -0.238589 0.620582
+v 0.495668 -0.103443 0.583767
+v -0.18196 0.591449 -0.108774
+v 0.427562 -0.709947 0.639169
+v 0.405198 -0.785464 0.605746
+v 0.441692 -0.586015 0.660749
+v 0.541744 -0.855548 0.50929
+v 0.534358 -0.855137 0.520928
+v 0.544531 -0.819736 0.513427
+v 0.545097 -0.801919 0.514403
+v 0.533472 -0.802125 0.520196
+v 0.543902 -0.837629 0.512258
+v 0.534705 -0.837257 0.521686
+v 0.546394 -0.78382 0.516407
+v 0.548539 -0.765464 0.519464
+v 0.536323 -0.765939 0.524525
+v 0.533639 -0.819787 0.520299
+v 0.553934 -0.747005 0.527775
+v 0.560537 -0.72784 0.537614
+v 0.534165 -0.784295 0.521314
+v 0.566381 -0.709125 0.546298
+v 0.541988 -0.746826 0.53308
+v -0.411107 0.122981 0.418025
+v -0.409836 0.105203 0.420041
+v -0.412006 0.141196 0.417536
+v -0.413175 0.159217 0.41498
+v -0.412495 0.177715 0.416175
+v -0.411994 0.196726 0.418294
+v -0.413086 0.214516 0.416534
+v -0.415744 0.232693 0.412475
+v -0.419315 0.250843 0.407119
+v -0.42236 0.268569 0.403625
+v -0.428153 0.286848 0.394543
+v 0.782401 -0.16433 0.175993
+v 0.777173 -0.14668 0.175942
+v 0.781848 -0.164523 0.188762
+v 0.763017 -0.111138 0.175981
+v 0.787141 -0.182159 0.175968
+v 0.595566 -0.480761 0.568006
+v -0.242307 -0.540042 -0.186963
+v 0.573767 -0.393272 0.605039
+v 0.670647 -0.359476 0.519156
+v 0.382642 -0.894187 0.59466
+v 0.649131 -0.137111 0.489778
+v 0.522977 -0.819825 0.527402
+v 0.521847 -0.80233 0.525861
+v 0.549926 -0.619786 0.591269
+v 0.549747 -0.602509 0.591153
+v 0.675515 -0.462559 -0.157458
+v 0.911663 -0.703704 0.368365
+v 0.369578 -0.482418 0.715445
+v 0.872408 -0.685489 0.402469
+v 0.894026 -0.759427 0.342147
+v 0.867668 -0.721212 0.39525
+v 0.870712 -0.703164 0.399733
+v 0.612136 -0.307324 0.570986
+v 0.683222 -0.10406 0.426156
+v 0.522784 -0.784565 0.527441
+v 0.717275 -0.0230958 0.214529
+v 0.71775 -0.0227747 0.20171
+v 0.706138 -0.00539503 0.214542
+v 0.770994 -0.398692 0.369957
+v 0.771739 -0.381248 0.371113
+v 0.772458 -0.329109 0.372963
+v 0.779626 -0.291306 0.343059
+v 0.774295 -0.29173 0.355686
+v 0.678778 -0.0870911 0.419682
+v 0.643813 -0.690011 0.500723
+v 0.629105 -0.708855 0.501545
+v 0.633048 -0.445436 0.554801
+v 0.588655 -0.255814 0.582483
+v 0.623697 -0.187426 0.543138
+v 0.619895 -0.17029 0.537563
+v 0.609978 -0.170316 0.545848
+v -0.60466 0.0109956 -0.159423
+v -0.591956 0.0297882 -0.158151
+v -0.789812 -0.381801 0.458975
+v -0.780602 -0.392257 0.459065
+v -0.780538 -0.38139 0.467864
+v 0.576786 -0.879569 0.423304
+v -0.244465 -0.0757102 -0.246052
+v -0.306829 -0.520658 -0.193489
+v -0.319546 -0.520569 -0.196854
+v -0.306881 -0.50202 -0.201928
+v -0.471506 -0.771707 -0.0585489
+v 0.757442 -0.129892 0.0220554
+v -0.32787 -0.000706491 -0.218229
+v -0.329668 -0.0169044 -0.227092
+v -0.908028 -0.308942 0.218434
+v 0.591776 -0.103058 0.519669
+v 0.601179 -0.103417 0.510819
+v 0.585431 -0.0865002 0.510421
+v 0.607782 -0.120168 0.520479
+v 0.594769 -0.0861791 0.501339
+v 0.591044 -0.0691848 0.495983
+v 0.580909 -0.069416 0.503818
+v 0.593421 -0.376085 0.588353
+v 0.589169 -0.0518693 0.493362
+v 0.00753377 0.937129 -0.238306
+v 0.534358 -0.221491 0.617088
+v 0.526176 -0.170444 0.605322
+v -0.0830898 0.672374 -0.0544898
+v -0.0652991 0.653607 -0.0286707
+v -0.0963076 0.690383 -0.0737962
+v 0.573421 -0.480902 0.580929
+v 0.443323 -0.568584 0.66328
+v 0.602669 -0.445308 0.578681
+v 0.604236 -0.427864 0.581096
+v 0.593356 -0.427877 0.587968
+v 0.591327 -0.445501 0.584795
+v 0.599972 -0.463227 0.574634
+v 0.588873 -0.462957 0.581019
+v 0.584763 -0.481288 0.574981
+v 0.580036 -0.49913 0.567942
+v 0.578071 -0.516432 0.564846
+v 0.579072 -0.533568 0.566259
+v 0.59053 -0.533388 0.560248
+v 0.774848 -0.345641 0.36884
+v -0.0792748 -0.0358127 -0.260837
+v -0.0945478 -0.0349777 -0.259976
+v -0.40701 0.140438 0.401852
+v -0.4062 0.158729 0.402263
+v -0.404428 0.177432 0.404999
+v -0.404119 0.195968 0.405963
+v -0.406419 0.214157 0.403818
+v -0.408628 0.232423 0.39999
+v -0.41184 0.250483 0.395635
+v -0.415719 0.268531 0.390035
+v -0.573331 0.509059 0.487415
+v 0.962569 -0.742176 0.201928
+v 0.968914 -0.723614 0.214761
+v 0.743492 -0.57141 0.396868
+v 0.724777 -0.189943 0.418847
+v 0.393419 -0.929884 0.589252
+v 0.728592 -0.224112 0.423458
+v 0.727204 -0.206938 0.42184
+v -0.655939 0.783268 -0.455122
+v 0.735413 -0.292564 0.433349
+v 0.750185 -0.449033 0.407414
+v 0.779356 -0.346142 0.357806
+v 0.778624 -0.329726 0.359347
+v 0.358108 -0.499798 0.721161
+v 0.358133 -0.482585 0.721392
+v 0.916762 -0.615572 0.376842
+v 0.701745 -0.189031 0.452925
+v 0.512521 -0.81989 0.534891
+v 0.807899 -0.361261 0.201825
+v -0.616696 -0.135878 -0.199179
+v -0.603684 -0.135441 -0.205306
+v -0.603941 -0.154105 -0.202776
+v 0.807616 -0.361274 0.214645
+v 0.662027 -0.0188312 0.395275
+v 0.656915 -0.00170842 0.387697
+v 0.66651 -0.0358512 0.40175
+v 0.670557 -0.053141 0.407877
+v 0.674397 -0.0700454 0.413272
+v -0.617197 -0.154195 -0.198768
+v 0.638816 -0.672284 0.515944
+v 0.634654 -0.690358 0.509817
+v 0.635386 -0.427825 0.558295
+v 0.616285 -0.153399 0.532476
+v 0.612457 -0.1367 0.527068
+v 0.0662111 0.8798 -0.289302
+v 0.684455 -0.655868 0.468802
+v 0.675643 -0.691963 0.456175
+v 0.680152 -0.673672 0.462572
+v 0.688604 -0.637628 0.475494
+v 0.690839 -0.62003 0.478898
+v 0.692869 -0.602393 0.482161
+v 0.694834 -0.585013 0.48482
+v 0.695644 -0.567634 0.486002
+v -0.192981 0.579593 -0.0950809
+v 0.402989 -0.533285 0.695624
+v -0.237799 0.149108 0.374466
+v 0.377144 -0.62283 0.68003
+v 0.366136 -0.622701 0.68653
+v -0.731854 -0.57046 0.100797
+v -0.724623 -0.581455 0.112101
+v -0.742375 -0.566529 0.116867
+v 0.733499 -0.27548 0.430035
+v 0.594718 -0.393195 0.590216
+v 0.58764 -0.0348621 0.491217
+v -0.000391782 0.956063 -0.227028
+v 0.594448 -0.410561 0.589702
+v 0.529567 -0.187464 0.610177
+v 0.523504 -0.341287 0.645874
+v 0.533523 -0.341312 0.637705
+v 0.531095 -0.324305 0.634391
+v 0.531493 -0.307118 0.635033
+v 0.410439 -0.85718 0.590254
+v 0.569811 -0.498911 0.575688
+v 0.390825 -0.568648 0.700287
+v -0.567049 0.751283 -0.744424
+v 0.59143 -0.619657 0.560928
+v 0.544146 0.0840982 0.428211
+v 0.552483 0.0667056 0.44035
+v 0.959049 -0.724539 0.111934
+v 0.55545 0.0839954 0.422019
+v 0.557634 -0.726697 -0.246501
+v 0.5745 -0.725194 -0.234195
+v 0.742837 -0.58888 0.395712
+v 0.701193 -0.078382 -0.0424409
+v 0.706292 -0.0794739 -0.0300066
+v -0.590286 0.578886 -0.437691
+v -0.400099 0.139975 0.389123
+v -0.398904 0.158601 0.390767
+v -0.396618 0.177265 0.393683
+v -0.397478 0.195672 0.393182
+v -0.400279 0.214761 0.391139
+v -0.401794 0.231986 0.388236
+v -0.404839 0.250239 0.38306
+v -0.409052 0.26812 0.377331
+v 0.728836 -0.0405269 0.188839
+v -0.398005 0.249905 0.370407
+v -0.402861 0.267812 0.363458
+v 0.737455 -0.0579323 0.188864
+v 0.7182 -0.0224536 0.188877
+v 0.748104 -0.203688 -0.0544641
+v 0.74696 -0.185409 -0.0417601
+v 0.121536 -0.943243 0.651128
+v 0.138003 -0.93533 0.645926
+v 0.123424 -0.925529 0.648508
+v -0.0547788 -0.8612 0.70644
+v 0.810365 -0.40726 0.219834
+v 0.0702445 0.860879 -0.283663
+v 0.0823448 0.841868 -0.28672
+v 0.602785 -0.533183 0.555392
+v 0.750352 -0.431602 0.408249
+v -0.553921 -0.829896 0.388134
+v -0.543144 -0.831039 0.375314
+v -0.57089 -0.84621 0.375391
+v 0.807359 -0.451384 0.0737705
+v -0.746074 -0.565296 0.129853
+v -0.731662 -0.578462 0.130958
+v -0.00761084 -0.610961 0.685014
+v 0.691405 -0.693363 0.433362
+v -0.160264 0.80373 -0.0753762
+v 0.852163 -0.776781 0.372128
+v 0.862954 -0.739529 0.388275
+v 0.857931 -0.75768 0.38094
+v 0.971689 -0.545219 0.098729
+v 0.705611 -0.205846 0.458166
+v -0.0303984 0.201684 0.315172
+v -0.642271 -0.191523 -0.200656
+v -0.629606 -0.172705 -0.202686
+v 0.592277 -0.550447 0.562637
+v 0.464171 0.204279 0.0340657
+v 0.751418 -0.344973 0.410202
+v 0.614718 -0.00101478 0.440093
+v 0.652111 -0.69046 0.490112
+v 0.0175146 0.649458 -0.13187
+v 0.614256 -0.76495 0.479309
+v -0.149474 0.86138 -0.0583177
+v 0.63635 -0.41051 0.559734
+v 0.571006 -0.727622 0.530138
+v 0.565662 -0.746081 0.522213
+v 0.369373 -0.605129 0.691501
+v 0.694115 -0.51597 0.484216
+v 0.693781 -0.498706 0.483947
+v 0.377851 -0.842073 0.588469
+v 0.381383 -0.858991 0.593003
+v 0.693948 -0.481455 0.484114
+v 0.708707 -0.222737 0.462225
+v 0.710223 -0.239976 0.464589
+v 0.711225 -0.257099 0.465925
+v 0.711854 -0.274286 0.467016
+v 0.712381 -0.291498 0.467376
+v 0.712753 -0.30875 0.467633
+v 0.695605 -0.550318 0.485963
+v 0.694988 -0.533093 0.485462
+v 0.697814 -0.428994 0.490433
+v 0.697506 -0.4464 0.489637
+v 0.697442 -0.411743 0.490125
+v 0.697134 -0.394505 0.489894
+v -0.942183 0.372 0.21485
+v -0.938445 0.373117 0.202313
+v 0.559625 0.0498911 0.450664
+v 0.53545 -0.358409 0.640351
+v 0.425173 -0.856319 0.588327
+v 0.473009 -0.872543 0.567685
+v 0.737532 -0.395995 0.434878
+v -0.21803 -0.974714 0.357934
+v -0.231838 -0.976178 0.356316
+v -0.224093 -0.977617 0.336328
+v -0.629721 0.403702 -0.088183
+v -0.643158 0.138203 -0.0945671
+v -0.655887 0.138241 -0.0953506
+v -0.643248 0.157047 -0.0955048
+v 0.432366 -0.309289 0.672053
+v 0.805175 -0.289584 0.15029
+v 0.802876 -0.271588 0.163161
+v -0.390722 0.140772 0.379527
+v -0.732497 -0.102595 -0.138871
+v -0.745291 -0.103276 -0.128954
+v -0.732728 -0.0844193 -0.129378
+v -0.944907 0.064098 0.414788
+v -0.95237 0.0759928 0.409187
+v -0.94894 0.0762882 0.396393
+v -0.391518 0.158421 0.378551
+v -0.390426 0.176828 0.379823
+v -0.39076 0.195287 0.379527
+v -0.392584 0.213617 0.376727
+v -0.395744 0.231716 0.373361
+v -0.409643 0.277792 0.366258
+v 0.73924 -0.18573 -0.0548623
+v 0.742105 -0.167426 -0.0418371
+v 0.721013 -0.139243 0.390086
+v 0.538687 -0.967867 0.0608482
+v 0.554949 -0.962049 0.0587801
+v 0.32119 -0.253052 -0.389457
+v 0.310092 -0.248685 -0.394672
+v -0.259828 0.6115 -0.126167
+v -0.6187 0.325898 -0.0826723
+v -0.720718 0.287876 -0.0806042
+v -0.708065 0.306926 -0.0825953
+v -0.141138 0.860982 -0.0696986
+v -0.152275 0.841932 -0.0634815
+v 0.917495 -0.632747 0.377806
+v 0.507665 -0.708726 0.596972
+v -0.683222 0.424357 -0.143328
+v 0.574243 -0.943307 0.0210791
+v 0.77865 -0.38157 0.356727
+v 0.778072 -0.399168 0.3576
+v 0.784353 -0.381724 0.343535
+v -0.689401 0.455481 0.57439
+v 0.56782 -0.516522 0.572631
+v 0.845869 -0.795509 0.362738
+v 0.602425 -0.602213 0.554365
+v 0.592945 -0.6022 0.563266
+v 0.821283 -0.82892 0.346759
+v 0.836967 -0.815111 0.349392
+v 0.828066 -0.814803 0.35918
+v 0.581937 -0.103109 0.527993
+v 0.384839 -0.241042 0.693993
+v 0.713434 -0.325949 0.468699
+v 0.714269 -0.343098 0.469932
+v 0.714475 -0.360362 0.470099
+v 0.714822 -0.377575 0.470369
+v 0.714166 -0.412321 0.468789
+v 0.714886 -0.394826 0.470472
+v 0.0624217 0.898824 -0.294748
+v 0.624159 -0.727455 0.494146
+v 0.619111 -0.746132 0.486606
+v 0.636748 -0.393105 0.560556
+v 0.636774 -0.375776 0.560864
+v 0.570415 -0.690949 0.552335
+v 0.626279 -0.375815 0.568212
+v -0.922466 -0.100309 0.178858
+v -0.92533 -0.117663 0.166103
+v 0.695939 -0.463857 0.487299
+v 0.712599 -0.447029 0.466477
+v 0.711893 -0.464563 0.464756
+v 0.71328 -0.429675 0.467569
+v 0.391929 -0.361146 0.703575
+v 0.460241 -0.603703 0.642445
+v 0.50904 -0.966711 0.0298525
+v 0.711649 -0.499078 0.464614
+v 0.711803 -0.516342 0.46473
+v 0.71143 -0.481801 0.464435
+v 0.712265 -0.533581 0.46509
+v 0.696928 -0.377266 0.489663
+v -0.97219 0.232988 0.382405
+v 0.695823 -0.32559 0.488263
+v 0.695759 -0.308313 0.488237
+v 0.565418 0.0334877 0.459219
+v 0.583324 -0.602149 0.571963
+v 0.582554 -0.61949 0.570704
+v 0.580562 -0.637191 0.567634
+v 0.42543 -0.873904 0.588931
+v 0.526792 -0.375481 0.650409
+v 0.536876 -0.375494 0.642265
+v 0.387665 -0.804411 0.602714
+v 0.473086 -0.85488 0.568045
+v 0.581012 -0.550562 0.568957
+v 0.544339 0.101272 0.411717
+v 0.996031 -0.56071 0.201633
+v 0.992755 -0.543163 0.201543
+v -0.655335 -0.100193 -0.17634
+v -0.655887 -0.081619 -0.169095
+v -0.642772 -0.0813493 -0.17679
+v 0.695823 -0.291062 0.488275
+v 0.695977 -0.273708 0.488943
+v 0.695733 -0.256495 0.488776
+v 0.694963 -0.239321 0.487569
+v 0.690043 -0.205281 0.480966
+v 0.693229 -0.222275 0.485719
+v 0.806229 -0.379489 0.0735265
+v -0.384492 0.176443 0.365693
+v -0.385186 0.194915 0.364447
+v -0.386509 0.213193 0.363689
+v -0.389579 0.231254 0.360426
+v -0.392058 0.249507 0.356418
+v -0.397106 0.26767 0.348416
+v 0.780679 -0.164458 0.201633
+v 0.785573 -0.182249 0.201658
+v 0.962813 -0.742343 0.18907
+v 0.5108 -0.802587 0.532515
+v -0.266932 -0.931284 -0.357369
+v 0.706947 -0.104651 0.392141
+v 0.368461 -0.378821 0.714661
+v 0.0082531 -0.85876 0.684834
+v 0.357645 -0.294144 0.721931
+v 0.345789 -0.292898 0.727134
+v -0.0480478 -0.975318 -0.241235
+v -0.141883 0.709125 -0.0719594
+v 0.665881 -0.61931 0.510498
+v -0.148537 0.727802 -0.0816062
+v -0.12047 0.671835 -0.0409508
+v -0.13293 0.671642 -0.0364293
+v -0.6001 0.781097 -0.604435
+v -0.606921 0.801714 -0.617011
+v -0.612355 0.801803 -0.604076
+v -0.599124 0.721238 -0.451602
+v 0.209924 -0.109198 0.589535
+v -0.431172 0.329931 0.338268
+v 0.379302 -0.931091 0.591629
+v 0.387511 -0.941547 0.590922
+v -0.244183 -0.148325 -0.270162
+v -0.486753 -0.466284 -0.203932
+v -0.49956 -0.46658 -0.20433
+v -0.486818 -0.446695 -0.218113
+v -0.163167 0.746492 -0.0801418
+v 0.750493 -0.414312 0.408288
+v -0.0976949 0.595996 -0.0703408
+v 0.635592 -0.358666 0.559104
+v 0.62529 -0.358679 0.566863
+v 0.423182 -0.909665 0.585155
+v 0.459701 -0.445244 0.688213
+v -0.605752 0.618591 -0.604371
+v 0.574782 -0.672413 0.558937
+v 0.60538 -0.0866544 0.494338
+v 0.601744 -0.0690563 0.488905
+v 0.610094 -0.10352 0.501159
+v 0.599676 -0.0518822 0.486028
+v 0.686536 -0.188351 0.475983
+v 0.681771 -0.171767 0.469598
+v -0.260047 0.668893 -0.154079
+v -0.235281 -0.950295 0.625951
+v -0.243027 -0.942549 0.618077
+v -0.243939 -0.956975 0.608032
+v 0.560061 -0.945054 0.0200515
+v 0.636093 -0.0862176 0.470921
+v -0.24435 -0.11178 -0.262121
+v -0.12029 0.690178 -0.0633659
+v -0.133341 0.69082 -0.0594223
+v -0.720486 0.269109 -0.0849203
+v -0.244298 -0.0939505 -0.255082
+v 0.669401 -0.566966 0.516021
+v 0.807449 -0.794983 0.397613
+v 0.788143 -0.814379 0.391897
+v 0.813987 -0.776498 0.407324
+v 0.708437 -0.6031 0.459374
+v 0.705624 -0.620929 0.454903
+v 0.709953 -0.585694 0.46166
+v 0.701886 -0.638835 0.449123
+v 0.593138 -0.0177907 0.476753
+v 0.587897 -0.00087348 0.46911
+v 0.582168 0.0164548 0.460748
+v 0.577672 -0.654571 0.563318
+v 0.526766 -0.392835 0.650203
+v 0.537235 -0.392745 0.642663
+v 0.527653 -0.480555 0.627737
+v 0.529811 -0.462957 0.631102
+v 0.518468 -0.480311 0.637204
+v 0.532444 -0.445475 0.635072
+v 0.522181 -0.445257 0.64301
+v 0.519997 -0.462855 0.639593
+v 0.548809 -0.637371 0.589561
+v 0.582733 -0.567621 0.571346
+v 0.571455 -0.567762 0.57764
+v 0.572483 -0.584923 0.579053
+v 0.309411 0.176751 -0.102351
+v 0.310696 0.167066 -0.117278
+v 0.297504 0.167156 -0.117624
+v 0.698315 -0.65669 0.443985
+v 0.69513 -0.674712 0.439065
+v -0.703171 -0.398641 0.518385
+v -0.69739 -0.416534 0.513144
+v -0.691906 -0.398551 0.525283
+v -0.590261 0.520337 -0.0774957
+v -0.59229 0.525231 -0.061362
+v -0.588231 0.506888 -0.059538
+v -0.465353 0.384062 0.358756
+v -0.378699 0.194619 0.351601
+v -0.380407 0.212821 0.349777
+v -0.38385 0.230881 0.345384
+v -0.386342 0.249199 0.341338
+v 0.993924 -0.56098 0.162904
+v 0.983622 -0.525861 0.162788
+v 0.980861 -0.520273 0.162583
+v 0.989608 -0.543407 0.16284
+v -0.573485 0.842202 -0.759658
+v -0.587216 0.856589 -0.765965
+v -0.582502 0.861675 -0.746119
+v -0.148138 0.597139 0.00931284
+v -0.171016 0.603755 -0.122056
+v 0.737147 -0.309597 0.435096
+v 0.951933 -0.705155 0.313618
+v 0.954232 -0.687172 0.317099
+v 0.750031 -0.483754 0.406644
+v 0.956377 -0.669163 0.320464
+v 0.957906 -0.651706 0.322764
+v 0.959897 -0.634044 0.326026
+v -0.0460183 -0.920648 -0.0756331
+v -0.0588636 -0.920186 -0.0786132
+v -0.049525 -0.919338 -0.101362
+v -0.658598 0.0289661 0.5994
+v 0.712509 -0.550832 0.465282
+v 0.461037 -0.410561 0.690435
+v 0.460831 -0.427992 0.690165
+v 0.381139 -0.912247 0.592399
+v 0.653293 -0.0525373 0.427813
+v -0.0142647 0.842048 -0.203084
+v 0.678302 -0.154696 0.464499
+v 0.169513 -0.257176 -0.437883
+v 0.180149 -0.263855 -0.437254
+v 0.167329 -0.263637 -0.439296
+v 0.613369 -0.272539 0.573298
+v -0.69197 0.509727 -0.512386
+v 0.960706 -0.616664 0.327221
+v 0.960514 -0.599426 0.327041
+v 0.959422 -0.582277 0.325641
+v 0.956788 -0.565373 0.32189
+v 0.952961 -0.548815 0.316649
+v -0.595604 0.433375 -0.0877848
+v -0.593035 0.417729 -0.070906
+v 0.819202 -0.757706 0.415109
+v 0.748746 -0.293515 0.407042
+v 0.736556 -0.430767 0.432912
+v 0.736941 -0.413375 0.433824
+v 0.667088 -0.103649 0.448121
+v 0.668874 -0.584333 0.515109
+v 0.597004 -0.0346695 0.482225
+v -0.460292 -0.543369 -0.146411
+v 0.507678 -0.619953 0.620505
+v 0.507678 -0.637242 0.620389
+v -0.299379 0.689715 0.0616446
+v 0.506381 -0.602868 0.618707
+v 0.533908 -0.708829 0.567274
+v 0.539278 -0.690293 0.575277
+v 0.543696 -0.672413 0.581686
+v 0.583633 -0.584744 0.572489
+v 0.799331 -0.883846 0.125653
+v 0.775824 -0.52098 0.353515
+v -0.838689 0.545874 0.0937707
+v -0.719947 0.434454 -0.134092
+v -0.717005 0.433888 -0.147528
+v -0.705033 0.434467 -0.159179
+v -0.715258 0.429585 -0.114066
+v -0.374717 0.2125 0.334736
+v -0.377555 0.230547 0.331511
+v 0.788438 -0.236598 0.0220554
+v -0.378994 0.247298 0.321312
+v -0.374807 0.230098 0.323226
+v 0.524583 -0.427748 0.646979
+v 0.5136 -0.427671 0.65326
+v -0.167946 0.578231 0.0028645
+v 0.343618 -0.362186 0.723717
+v 0.344993 -0.344691 0.725849
+v -0.403657 0.336778 0.225229
+v 0.368628 -0.275249 0.715419
+v -0.937328 0.422842 0.400619
+v -0.93386 0.427273 0.407273
+v -0.935491 0.44035 0.398204
+v 0.399521 -0.394749 0.71416
+v -0.769067 0.707686 -0.274954
+v -0.766511 0.698887 -0.248133
+v -0.754424 0.706633 -0.239154
+v -0.51229 -0.676279 0.144137
+v -0.65265 -0.572541 -0.0326399
+v -0.656928 -0.575688 -0.0260503
+v -0.662734 -0.557216 -0.0386001
+v -0.0961406 -0.88129 0.714301
+v 0.687911 -0.711617 0.428031
+v 0.823107 -0.739504 0.420979
+v 0.432469 -0.568571 0.670178
+v 0.38331 -0.876306 0.595675
+v 0.546625 -0.654622 0.586144
+v 0.55491 -0.672657 0.575302
+v -0.746447 -0.565514 0.141067
+v 0.438827 -0.515996 0.68003
+v -0.969865 0.0750679 0.165139
+v 0.443413 -0.463805 0.68739
+v 0.447691 -0.445616 0.69353
+v 0.776171 -0.486336 0.353554
+v 0.392533 -0.224279 0.682458
+v 0.825381 -0.721559 0.424357
+v 0.775785 -0.50378 0.352629
+v 0.381152 -0.499464 0.709497
+v -0.881965 -0.397267 0.244574
+v 0.799536 -0.827623 -0.00391782
+v 0.800731 -0.844784 0.0251896
+v 0.787616 -0.851399 0.0264228
+v 0.986371 -0.525822 0.201594
+v 0.662605 -0.0867058 0.441621
+v 0.657814 -0.069917 0.434916
+v 0.0166539 0.709754 -0.136109
+v 0.0615482 0.860905 -0.273759
+v 0.625547 -0.15381 0.523446
+v 0.621218 -0.136969 0.517254
+v 0.616298 -0.120039 0.510074
+v 0.750634 -0.310484 0.409675
+v 0.483105 -0.837257 0.559914
+v 0.810545 -0.343136 0.137612
+v 0.808759 -0.325281 0.137599
+v 0.807475 -0.307362 0.13756
+v -0.924238 0.355121 0.163688
+v -0.405237 -0.966981 0.581841
+v 0.423503 -0.639066 0.656523
+v 0.425879 -0.621494 0.660223
+v 0.819575 -0.470202 0.12546
+v 0.821592 -0.479708 0.109378
+v 0.356052 -0.379078 0.719311
+v -0.323978 0.572515 -0.0892106
+v -0.163643 0.822908 -0.0574313
+v -0.160046 0.841945 -0.0520877
+v 0.506471 -0.915305 0.511924
+v -0.168061 0.803769 -0.0640338
+v -0.125659 -0.836589 -0.341158
+v -0.13853 -0.836691 -0.341145
+v 0.0845028 0.239077 0.04027
+v -0.172249 0.784539 -0.0704308
+v -0.180072 0.784552 -0.0591141
+v -0.588128 0.51949 -0.257433
+v 0.0436034 -0.916371 -0.0854469
+v 0.0343034 -0.917193 -0.0626337
+v 0.0302057 -0.916936 -0.0876178
+v -0.119737 -0.925003 0.715278
+v -0.104092 -0.925696 0.717551
+v -0.0947662 -0.916987 0.716575
+v -0.0949846 -0.898991 0.715766
+v -0.110874 -0.900147 0.7152
+v -0.0799556 -0.89804 0.714995
+v -0.0802253 -0.88016 0.714288
+v 0.504313 -0.862112 -0.143777
+v 0.507576 -0.861804 -0.130958
+v 0.494807 -0.881419 -0.130881
+v -0.170502 0.72775 -0.0681828
+v 0.801502 -0.402122 0.299706
+v 0.796197 -0.418744 0.314761
+v -0.173611 0.746504 -0.072653
+v -0.183283 0.765464 -0.0640595
+v -0.174523 0.765451 -0.0739889
+v 0.795207 -0.436226 0.313528
+v -0.532444 -0.886544 0.260079
+v -0.509001 -0.871361 0.259822
+v 0.460998 -0.393272 0.69055
+v 0.434807 -0.550999 0.673749
+v 0.43735 -0.533452 0.677628
+v 0.394486 -0.785439 0.612888
+v 0.776774 -0.468879 0.354646
+v -0.674757 0.40261 -0.0950167
+v -0.1072 0.650499 -0.159539
+v 0.750352 -0.46631 0.407556
+v 0.731662 -0.258422 0.428301
+v -0.0730833 0.637088 -0.0167246
+v -0.15591 0.822895 -0.0687994
+v 0.745149 -0.259359 0.401711
+v 0.744109 -0.242211 0.400337
+v 0.265005 -0.943307 0.613016
+v 0.795259 -0.380105 0.317305
+v 0.793448 -0.36225 0.31724
+v 0.790275 -0.381852 0.329687
+v 0.779588 -0.363779 0.357164
+v 0.648925 -0.0354787 0.421454
+v 0.644391 -0.0184844 0.414916
+v 0.784327 -0.344909 0.343059
+v 0.784019 -0.326964 0.342918
+v 0.0577332 0.879954 -0.279218
+v 0.0542907 0.898747 -0.283753
+v 0.494615 -0.880121 -0.143315
+v 0.639998 -0.00137445 0.408519
+v 0.635669 0.0157997 0.402122
+v -0.819421 0.376085 0.628636
+v -0.827423 0.358576 0.637088
+v 0.733858 -0.517537 0.428686
+v -0.755477 -0.541583 0.0703922
+v -0.743942 -0.548995 0.0522932
+v -0.740705 -0.554531 0.0619529
+v 0.0357035 -0.922999 0.317484
+v 0.0281505 -0.920944 0.337292
+v 0.0228454 -0.922549 0.31444
+v 0.0884591 0.727763 -0.259257
+v 0.10011 0.744925 -0.259218
+v 0.788065 -0.20031 0.227272
+v 0.937482 -0.780429 0.202018
+v 0.937559 -0.780493 0.189186
+v 0.951689 -0.761251 0.201979
+v 0.951625 -0.761251 0.189134
+v -0.58642 0.559002 -0.386258
+v 0.751122 -0.396907 0.409392
+v -0.781116 0.690833 -0.287696
+v -0.363927 -0.969062 0.548289
+v -0.37771 -0.970565 0.54658
+v -0.369514 -0.970732 0.526105
+v -0.44737 0.539438 0.185242
+v -0.438314 0.53949 0.175749
+v -0.41717 0.345333 0.0765837
+v 0.803994 -0.37972 0.0608353
+v 0.994271 -0.63222 0.227503
+v -0.895606 -0.361749 0.231511
+v -0.591224 -0.116288 -0.21426
+v 0.0576947 0.947431 -0.319784
+v 0.069538 0.933442 -0.335262
+v -0.0767956 0.653402 -0.0227747
+v -0.701758 0.544602 -0.557216
+v -0.698688 0.524692 -0.541609
+v 0.388397 -0.257921 0.69908
+v -0.250477 -0.972222 0.440016
+v -0.242256 -0.972556 0.41936
+v -0.119506 0.746029 -0.213913
+v -0.0658129 -0.897193 0.712657
+v -0.0945478 -0.934996 0.716305
+v -0.28539 0.592284 -0.109814
+v 0.794334 -0.884322 0.112872
+v -0.471467 -0.844424 -0.0842138
+v -0.471532 -0.826402 -0.0745926
+v -0.458571 -0.825747 -0.0809254
+v 0.573369 -0.341518 0.604667
+v 0.579317 -0.597627 -0.2474
+v 0.574153 -0.588841 -0.249507
+v 0.573626 -0.580106 -0.248454
+v 0.796415 -0.40121 0.315699
+v 0.437325 -0.621327 0.654211
+v 0.661848 -0.0528584 0.417768
+v -0.209976 0.577473 0.0323958
+v 0.666061 -0.0700454 0.424049
+v -0.254125 0.525 -0.0186385
+v 0.861669 -0.667968 0.409662
+v 0.860731 -0.685618 0.408031
+v 0.962338 -0.687866 0.305346
+v 0.959113 -0.705554 0.301479
+v 0.964483 -0.669497 0.309585
+v 0.965973 -0.652002 0.311845
+v 0.606227 -0.204304 0.562868
+v 0.378172 -0.824835 0.589381
+v 0.967745 -0.599863 0.314941
+v 0.843082 -0.77646 0.381647
+v 0.856762 -0.721174 0.402045
+v 0.852896 -0.739324 0.396355
+v 0.848387 -0.757795 0.389624
+v 0.646446 -0.375892 0.552001
+v 0.645431 -0.358731 0.550639
+v 0.951548 -0.742933 0.278974
+v 0.960822 -0.724064 0.278948
+v 0.640075 -0.221183 0.544011
+v 0.636786 -0.204112 0.539271
+v 0.633472 -0.187503 0.534698
+v -0.417029 0.483124 0.161106
+v 0.648604 -0.0016442 0.398538
+v 0.643903 0.0157612 0.391268
+v 0.836312 -0.795676 0.371396
+v 0.966692 -0.58274 0.313541
+v 0.96456 -0.565823 0.310792
+v 0.916236 -0.495032 0.09914
+v 0.90429 -0.801033 0.112396
+v 0.802478 -0.289726 0.188826
+v 0.804019 -0.307606 0.188839
+v 0.998741 -0.614018 0.188787
+v 0.975671 -0.508584 0.199899
+v 0.511468 -0.445282 0.650113
+v 0.915876 -0.667647 0.375006
+v 0.917199 -0.650113 0.377164
+v -0.441705 0.52098 0.193347
+v -0.432264 0.502148 0.184638
+v -0.434306 0.520903 0.181183
+v -0.454524 0.539515 0.197586
+v -0.447986 0.521159 0.207079
+v -0.470671 -0.783794 0.452103
+v -0.445122 -0.767558 0.452399
+v -0.575707 0.801354 -0.707146
+v 0.818252 -0.814585 0.367632
+v 0.816993 -0.820442 0.361839
+v 0.96113 -0.549072 0.305847
+v -0.587126 0.869228 -0.755316
+v 0.0568854 -0.923423 0.229353
+v 0.0482148 -0.923461 0.250856
+v 0.0440915 -0.92296 0.226321
+v -0.0390047 -0.0550935 -0.270522
+v -0.0389277 -0.0730384 -0.273207
+v -0.053263 -0.896782 0.708328
+v -0.0535585 -0.878888 0.708136
+v 0.0318756 -0.0979069 0.576895
+v 0.658058 -0.0359026 0.412424
+v 0.0190945 -0.981137 -0.270907
+v 0.571866 0.0894675 0.403574
+v 0.553215 0.0914971 0.415288
+v -0.550941 -0.467312 -0.199565
+v -0.53789 -0.485719 -0.1925
+v -0.780731 0.785233 -0.45412
+v 0.974027 -0.634879 0.30171
+v 0.978009 -0.633479 0.29164
+v -0.218736 -0.11142 -0.265744
+v -0.231594 -0.111497 -0.264202
+v -0.578212 0.821393 -0.707249
+v 0.685598 -0.155043 0.452437
+v 0.688925 -0.172114 0.457331
+v 0.693871 -0.188685 0.463959
+v 0.697956 -0.205602 0.469971
+v 0.77179 -0.183469 0.0221581
+v 0.85928 -0.70337 0.405821
+v 0.549233 -0.856293 0.497254
+v 0.0467119 0.784732 -0.302764
+v -0.568488 0.760943 -0.732978
+v -0.569721 0.740262 -0.732799
+v -0.00424537 -0.85926 0.689214
+v 0.703839 -0.274003 0.477935
+v 0.702644 -0.23968 0.476432
+v 0.646652 -0.393156 0.552194
+v 0.605277 -0.764578 0.488982
+v -0.90262 -0.0487736 0.217021
+v -0.900385 -0.048658 0.229918
+v -0.895863 -0.0315224 0.21697
+v -0.972896 0.0939762 0.460414
+v -0.974451 0.0940404 0.473234
+v -0.977238 0.11142 0.460298
+v -0.272866 0.630319 -0.134811
+v 0.569066 -0.878374 0.435237
+v 0.562117 -0.877822 0.447697
+v 0.552778 -0.897617 0.43385
+v 0.643479 -0.238113 0.54888
+v 0.0841688 0.803563 -0.261312
+v 0.0934688 0.802715 -0.272937
+v 0.08291 0.822035 -0.273117
+v 0.653318 -0.0185871 0.405192
+v 0.812433 -0.41489 0.137753
+v 0.811688 -0.396971 0.137689
+v 0.812176 -0.378923 0.137663
+v 0.811213 -0.361017 0.13765
+v 0.720242 -0.0230702 0.150316
+v -0.424479 0.501981 0.172718
+v -0.425558 0.520736 0.171369
+v -0.427922 0.539374 0.168415
+v 0.0425757 0.666658 -0.143944
+v 0.0285487 0.656395 -0.128247
+v 0.459046 -0.939672 -0.143187
+v 0.462026 -0.939068 -0.13029
+v -0.0405976 -0.914328 0.704231
+v -0.0408802 -0.896383 0.70382
+v -0.0411114 -0.87849 0.703588
+v -0.0781444 -0.166295 0.59651
+v -0.0618565 -0.16627 0.597409
+v -0.694898 -0.136379 0.537987
+v 0.682747 -0.137984 0.448455
+v 0.360715 0.160887 0.455815
+v -0.0718502 -0.937463 0.714751
+v 0.742272 -0.185011 0.381518
+v 0.735104 -0.173758 0.388044
+v 0.824225 -0.7761 0.39963
+v 0.829196 -0.757924 0.406978
+v 0.833114 -0.739696 0.412848
+v -0.590466 0.720724 -0.514506
+v -0.120431 -0.74775 -0.319642
+v -0.125055 -0.729035 -0.319283
+v -0.113199 -0.745772 -0.327041
+v 0.747192 -0.51895 0.401968
+v 0.745663 -0.536304 0.400426
+v 0.744135 -0.553915 0.397999
+v -0.00956332 0.765978 -0.174157
+v 0.749003 -0.501172 0.405321
+v -0.0152153 0.785028 -0.182198
+v 0.777866 -0.451422 0.355956
+v 0.777635 -0.434081 0.355776
+v 0.581423 -0.727416 0.522611
+v 0.711919 -0.568225 0.464268
+v 0.567627 -0.000886326 0.48482
+v 0.556388 -0.000719337 0.491204
+v 0.777519 -0.41665 0.35656
+v -0.23338 0.74635 -0.0013616
+v 0.505225 -0.551243 0.617345
+v 0.704006 -0.291254 0.478038
+v -0.378365 0.675547 -0.0817218
+v -0.37595 0.692451 -0.0804501
+v -0.364171 0.687005 -0.090585
+v 0.645727 -0.410523 0.550781
+v 0.60055 -0.783499 0.481801
+v 0.63721 -0.515353 0.537704
+v 0.637583 -0.497999 0.538321
+v 0.610081 -0.745734 0.496188
+v 0.63739 -0.480735 0.538128
+v 0.638559 -0.463548 0.539926
+v 0.641757 -0.445539 0.54482
+v 0.644172 -0.427954 0.548481
+v 0.746524 -0.0759029 0.1888
+v -0.237786 0.727326 -0.0077971
+v -0.272776 0.649664 -0.144163
+v 0.97562 -0.669407 0.0990629
+v 0.980475 -0.651218 0.098973
+v 0.955632 -0.724745 0.0991657
+v -0.465623 -0.733017 -0.0629548
+v -0.459046 -0.733826 -0.0684526
+v -0.463735 -0.751334 -0.0623254
+v -0.852587 -0.425642 0.268981
+v -0.216707 -0.576214 -0.192474
+v -0.119134 0.616459 0.00631989
+v -0.137657 0.597358 0.0017855
+v -0.415577 0.50184 0.16302
+v -0.415899 0.520671 0.162968
+v -0.416708 0.539258 0.162121
+v -0.29794 -0.972286 0.452694
+v 0.67504 -0.103906 0.437074
+v -0.499342 -0.503805 -0.181799
+v -0.486548 -0.504229 -0.180605
+v 0.181729 -0.918529 0.343393
+v 0.168871 -0.918092 0.340362
+v 0.764905 -0.34681 -0.0546696
+v 0.768001 -0.328531 -0.0546439
+v 0.770814 -0.346284 -0.0416059
+v 0.0980803 0.840147 -0.350176
+v -0.0559605 -0.94842 0.706954
+v -0.318364 0.803358 -0.0445218
+v -0.318262 0.803165 -0.057213
+v -0.028356 -0.895947 0.699516
+v -0.0279835 -0.877886 0.699825
+v -0.0290496 -0.860134 0.698386
+v -0.273406 0.668495 -0.147053
+v -0.437389 -0.805978 0.259295
+v -0.446021 -0.823332 0.259668
+v 0.704263 -0.308583 0.47764
+v 0.704777 -0.325744 0.478603
+v 0.730159 -0.241325 0.425077
+v 0.757262 -0.814674 0.415378
+v 0.581359 -0.341813 0.593658
+v 0.696556 -0.360002 0.489354
+v 0.696055 -0.342841 0.488455
+v 0.581436 -0.359077 0.59371
+v 0.45008 -0.427967 0.697153
+v 0.70362 -0.256778 0.477768
+v 0.789414 -0.435584 0.327324
+v 0.790634 -0.400593 0.32952
+v 0.790493 -0.417935 0.32952
+v 0.615078 -0.726992 0.503638
+v 0.619535 -0.708919 0.510215
+v 0.596285 -0.801958 0.475456
+v 0.591237 -0.820712 0.467954
+v 0.585007 -0.840185 0.458282
+v 0.577107 -0.85935 0.446798
+v 0.645662 -0.255031 0.55186
+v 0.719317 -0.0226976 0.176006
+v 0.64809 -0.289276 0.555277
+v 0.705162 -0.342995 0.478937
+v 0.705303 -0.360272 0.47904
+v 0.43568 -0.326129 0.676819
+v 0.439894 -0.34288 0.682843
+v -0.191864 0.765413 -0.0539759
+v 0.356695 -0.622612 0.695804
+v -0.406213 0.50175 0.154195
+v -0.40534 0.52062 0.155685
+v -0.405725 0.539374 0.155467
+v -0.40769 0.558102 0.153
+v -0.575283 0.842395 -0.746954
+v 0.679214 -0.120964 0.44333
+v 0.788502 -0.453054 0.326116
+v 0.549271 -0.893134 0.447851
+v 0.777892 -0.201324 0.0222866
+v -0.145351 0.84093 -0.205319
+v -0.132621 0.841059 -0.213643
+v 0.0241813 -0.26225 -0.460234
+v 0.0373991 -0.279809 -0.468751
+v 0.0241427 -0.279861 -0.468866
+v -0.273842 0.687647 -0.149301
+v -0.131851 0.669651 -0.174272
+v -0.131953 0.688713 -0.184176
+v -0.015318 -0.895317 0.695599
+v -0.400484 0.302545 0.0827109
+v -0.0155107 -0.877424 0.695496
+v -0.0166025 -0.859672 0.693877
+v 0.706061 -0.377421 0.480209
+v 0.795426 -0.819068 0.380041
+v 0.788181 -0.487774 0.325243
+v 0.973012 -0.652361 0.299655
+v -0.810147 -0.507453 0.189622
+v -0.809825 -0.507608 0.206681
+v -0.312674 0.725772 -0.123109
+v -0.605932 0.344742 -0.0783178
+v 0.809761 -0.451153 0.0864103
+v 0.119802 -0.100463 0.581648
+v 0.424492 -0.223906 0.661032
+v 0.998484 -0.596202 0.201645
+v 0.675181 -0.137496 0.459785
+v 0.671327 -0.12063 0.454428
+v 0.576876 0.0335648 0.453144
+v 0.570659 0.0505334 0.444152
+v 0.700949 -0.222378 0.473298
+v 0.83612 -0.721572 0.417395
+v 0.703659 -0.46428 0.475546
+v 0.702464 -0.481609 0.474081
+v 0.00274247 0.803833 -0.201376
+v 0.403683 -0.975677 0.0409893
+v 0.398301 -0.969139 0.0578681
+v 0.390234 -0.976281 0.0388056
+v 0.704096 -0.550549 0.475957
+v 0.703826 -0.567942 0.475186
+v 0.702747 -0.49886 0.474287
+v 0.703723 -0.533298 0.475636
+v 0.704931 -0.446772 0.47764
+v 0.703094 -0.516137 0.47457
+v 0.705817 -0.429251 0.479476
+v 0.705727 -0.412013 0.479412
+v 0.0134041 -0.923641 0.267105
+v 0.00055877 -0.923179 0.264112
+v 0.008677 -0.924193 0.243444
+v 0.647268 -0.272115 0.554146
+v 0.423811 -0.12704 -0.268377
+v 0.423876 -0.145345 -0.271652
+v 0.735695 -0.482636 0.43182
+v 0.26891 -0.10695 -0.260824
+v -0.441975 0.503382 0.204433
+v 0.690929 -0.406746 -0.156815
+v 0.698341 -0.406515 -0.144651
+v 0.907925 -0.721533 0.363111
+v -0.222063 0.707236 -0.174555
+v -0.703633 -0.0140784 0.507376
+v -0.694911 -0.00671809 0.528147
+v -0.486625 -0.485334 -0.192384
+v -0.499444 -0.485167 -0.193887
+v -0.564236 0.379733 -0.0567248
+v -0.146263 0.671668 -0.0330766
+v -0.39997 0.482701 0.140309
+v -0.39708 0.501583 0.144677
+v -0.39559 0.520504 0.14722
+v -0.395089 0.539323 0.148235
+v -0.39595 0.557948 0.147156
+v -0.223155 -0.971503 0.513015
+v -0.235846 -0.970963 0.509817
+v -0.518661 -0.675907 0.131202
+v -0.518019 -0.674083 0.143906
+v -0.273932 0.706864 -0.149172
+v -0.95404 0.0587801 0.460555
+v -0.945998 0.0525116 0.447004
+v -0.938201 0.042184 0.457023
+v -0.731032 -0.342019 -0.17607
+v -0.718482 -0.341544 -0.183071
+v -0.717969 -0.359784 -0.180798
+v -0.116038 -0.0734366 -0.277086
+v -0.116102 -0.0553375 -0.269045
+v -0.00350034 -0.913018 0.690049
+v -0.00285808 -0.894919 0.691128
+v -0.00305076 -0.876961 0.691026
+v 0.812767 -0.829922 0.0112396
+v 0.528642 0.124137 0.406053
+v 0.428898 -0.603729 0.664654
+v 0.430709 -0.586388 0.667467
+v 0.734693 -0.50017 0.429817
+v 0.746678 -0.276495 0.404242
+v 0.39225 -0.551166 0.702496
+v 0.343323 -0.934958 0.598706
+v 0.361833 -0.924939 0.593915
+v -0.0876756 -0.92472 0.131305
+v -0.101086 -0.925311 0.129095
+v -0.611687 -0.859029 0.4785
+v -0.616221 -0.864 0.465321
+v -0.622952 -0.880442 0.472155
+v -0.274022 0.726055 -0.147515
+v -0.446509 0.503471 0.217625
+v -0.444865 0.483625 0.217574
+v 0.670634 -0.0869241 0.430626
+v 0.635168 0.0294671 0.390767
+v 0.628116 0.0423381 0.388159
+v 0.630377 0.0328583 0.394428
+v 0.577647 -0.000552348 0.47683
+v 0.58362 -0.0176109 0.485488
+v 0.571378 0.0162108 0.467684
+v -0.411865 0.444473 0.127734
+v 0.634256 -0.636767 0.532412
+v 0.635836 -0.619272 0.53493
+v 0.636607 -0.601879 0.536188
+v 0.69134 -0.656112 0.456445
+v 0.702619 -0.585257 0.473696
+v 0.700833 -0.602958 0.4706
+v 0.783801 -0.434749 0.342147
+v 0.710583 -0.0598848 0.00909447
+v 0.708527 -0.0420683 0.0221324
+v 0.736196 -0.447993 0.432745
+v 0.695566 -0.637987 0.463214
+v 0.751366 -0.327658 0.41087
+v 0.628244 -0.672349 0.523343
+v 0.631777 -0.654288 0.528597
+v 0.624648 -0.690126 0.517922
+v 0.606112 0.0333335 0.427453
+v 0.70619 -0.394646 0.480311
+v 0.610903 0.0159667 0.434698
+v 0.485995 -0.935613 -0.0399746
+v 0.784019 -0.417292 0.343059
+v 0.848233 -0.703678 0.412501
+v 0.516079 -0.914868 -0.0406811
+v 0.499457 -0.916242 -0.0531795
+v 0.33252 -0.257818 -0.384665
+v -0.00938349 -0.917617 -0.0948882
+v -0.0227426 -0.918182 -0.0970719
+v -0.0134169 -0.91736 -0.119872
+v 0.367253 -0.747121 0.66441
+v 0.667821 -0.601635 0.513542
+v -0.784456 -0.510935 0.0905979
+v -0.387549 0.501493 0.135955
+v -0.385956 0.520427 0.138575
+v -0.384415 0.539387 0.141106
+v -0.385006 0.558077 0.140438
+v 0.296142 -0.283958 -0.40699
+v -0.111594 -0.922845 0.40279
+v -0.119622 -0.921868 0.42333
+v -0.124965 -0.923448 0.400542
+v 0.842889 -0.739761 0.40437
+v 0.846357 -0.721341 0.409585
+v -0.943776 0.213399 0.0876178
+v -0.939499 0.23101 0.0874636
+v -0.934695 0.213193 0.0749138
+v -0.0778489 0.0624795 -0.182737
+v -0.0625502 0.0650101 -0.185692
+v -0.0769626 0.0506233 -0.196083
+v 0.261331 -0.172063 -0.345731
+v 0.274369 -0.173347 -0.344601
+v 0.263117 -0.181376 -0.361557
+v -0.274254 0.745207 -0.144445
+v -0.207753 -0.956435 0.412668
+v -0.0442071 -0.918272 -0.149172
+v 0.00884399 -0.912581 0.685258
+v 0.00886968 -0.894675 0.685875
+v 0.00937064 -0.876525 0.686427
+v -0.00903667 0.115055 -0.135967
+v 0.00565835 0.117008 -0.13828
+v -0.00736678 0.106076 -0.15214
+v 0.7991 -0.253785 0.201594
+v 0.683273 -0.69285 0.444216
+v 0.679227 -0.711424 0.438102
+v 0.83892 -0.757962 0.398461
+v 0.405032 -0.360619 0.700159
+v 0.782169 -0.487184 0.338936
+v 0.629709 -0.170753 0.529432
+v 0.636414 -0.532733 0.536291
+v 0.687204 -0.67425 0.450202
+v 0.698919 -0.620312 0.468044
+v 0.783248 -0.452257 0.341043
+v -0.0540081 -0.920982 -0.196533
+v -0.0637576 -0.93122 -0.213065
+v -0.299225 0.668328 -0.134131
+v -0.286662 0.668328 -0.139564
+v -0.286328 0.649086 -0.135916
+v -0.956724 0.0591526 0.499091
+v -0.967116 0.076635 0.486156
+v -0.956647 0.0591526 0.486272
+v 0.735849 -0.465398 0.431885
+v -0.244118 -0.166616 -0.273284
+v -0.0376817 -0.132486 0.588507
+v -0.0375147 -0.150496 0.59204
+v 0.484672 0.1353 0.432758
+v 0.473176 0.135235 0.438757
+v -0.40051 0.332873 0.21715
+v 0.346945 0.183007 -0.0838541
+v 0.348371 0.173232 -0.0987418
+v 0.335731 0.17512 -0.10072
+v 0.562553 0.0620428 -0.0818888
+v 0.551224 0.0666286 -0.0868727
+v 0.550993 0.0789857 -0.0744257
+v -0.575656 0.384177 -0.0613106
+v 0.73319 -0.0768791 0.0220168
+v 0.109384 -0.138883 -0.304523
+v 0.0428969 0.686877 -0.132114
+v -0.378223 0.501583 0.126937
+v -0.37586 0.520556 0.130675
+v -0.374447 0.53931 0.132897
+v -0.374228 0.55818 0.133488
+v -0.378172 0.57669 0.127862
+v 0.784083 -0.399951 0.343021
+v -0.195358 0.161247 -0.0537833
+v -0.18223 0.159885 -0.0526914
+v -0.193572 0.151767 -0.06966
+v -0.924624 -0.221157 0.307645
+v -0.92754 -0.238434 0.294954
+v -0.257991 0.777372 -0.146552
+v 0.0686902 -0.948959 -0.309495
+v 0.0544962 -0.948831 -0.312757
+v 0.0672516 -0.930128 -0.314222
+v 0.307549 -0.927353 0.377022
+v 0.296425 -0.923731 0.371486
+v 0.298261 -0.936332 0.359977
+v 0.106057 -0.92061 0.143687
+v 0.0926596 -0.921201 0.141478
+v 0.101343 -0.921188 0.119872
+v 0.0209956 -0.929935 0.679735
+v 0.0212012 -0.912196 0.680801
+v -0.0082531 -0.944977 0.691193
+v 0.0217407 -0.894046 0.681456
+v 0.738123 -0.258961 0.414954
+v 0.736967 -0.241813 0.413464
+v 0.392135 -0.533953 0.702458
+v 0.392533 -0.516535 0.703023
+v 0.826974 -0.795047 0.380632
+v -0.656607 0.2697 -0.0932183
+v 0.600588 -0.861329 0.412732
+v 0.585546 -0.879787 0.413452
+v 0.794578 -0.887533 0.134002
+v 0.729427 -0.0401544 0.175993
+v 0.645521 -0.324215 0.551205
+v 0.647397 -0.306604 0.554146
+v 0.418442 -0.692156 0.648777
+v 0.503709 -0.5687 0.615046
+v 0.635862 -0.550074 0.535443
+v -0.243849 -0.239565 -0.287773
+v -0.205904 -0.111266 -0.267413
+v 0.575167 -0.745926 0.513131
+v 0.460716 0.134863 0.443317
+v -0.924765 -0.203778 0.307593
+v -0.929004 -0.203675 0.294761
+v -0.92894 -0.221003 0.294838
+v 0.558404 -0.690525 -0.247221
+v 0.570248 -0.707506 -0.234786
+v -0.907989 -0.291177 0.30803
+v -0.903686 -0.308968 0.295442
+v -0.254035 0.52545 0.0248428
+v -0.915709 -0.273476 0.30794
+v -0.919884 -0.273232 0.295069
+v -0.911843 -0.291357 0.295442
+v -0.823043 0.192076 -0.0471808
+v -0.621629 0.763884 -0.750564
+v -0.536233 0.432707 -0.0106616
+v -0.516297 0.437575 -0.00404627
+v -0.523812 0.430587 -0.00825953
+v -0.151131 -0.803705 -0.308094
+v -0.368345 0.501429 0.118562
+v -0.372726 0.482341 0.111857
+v -0.365699 0.520376 0.122711
+v -0.364004 0.539336 0.125447
+v -0.363117 0.558154 0.126937
+v -0.368268 0.576882 0.119898
+v -0.371621 0.59511 0.114709
+v -0.512739 -0.879312 -0.0903281
+v -0.509862 -0.898952 -0.101709
+v -0.923737 0.266052 0.061606
+v -0.13835 -0.802998 -0.310021
+v -0.875465 0.406926 0.0735136
+v -0.866216 0.406592 0.060861
+v -0.881733 0.389251 0.0607454
+v -0.77057 0.565887 -0.0560312
+v -0.769093 0.566015 -0.0431602
+v -0.766293 0.574763 -0.0457036
+v -0.732766 -0.0663074 -0.119667
+v -0.745573 -0.0668726 -0.111394
+v -0.308782 -0.970051 0.516047
+v 0.696812 -0.904694 0.0179577
+v 0.0341492 -0.929267 0.676099
+v 0.0342905 -0.911541 0.677024
+v 0.00840725 -0.930205 0.683717
+v 0.0341107 -0.893609 0.676909
+v -0.833563 -0.408956 0.371614
+v -0.845381 -0.391371 0.376663
+v -0.844302 -0.399925 0.360375
+v -0.222204 0.764437 -0.174349
+v -0.234844 0.76427 -0.167554
+v -0.221832 0.783268 -0.172101
+v 0.72854 -0.17336 0.40148
+v 0.724905 -0.156391 0.396252
+v 0.7354 -0.2246 0.410972
+v 0.703967 -0.0875664 0.388044
+v 0.833551 -0.776614 0.390369
+v -0.218955 0.168094 -0.0615547
+v -0.230374 0.172564 -0.0660762
+v -0.231967 0.182146 -0.0508288
+v 0.683877 -0.90296 0.00634558
+v 0.694231 -0.919351 0.0491461
+v 0.785162 -0.362803 0.342777
+v 0.782747 -0.46974 0.339989
+v -0.941965 0.0276045 0.212166
+v -0.95675 0.0403085 0.216623
+v 0.644917 -0.341518 0.550151
+v 0.792394 -0.470536 0.0354659
+v -0.428063 -0.770911 0.246488
+v -0.921361 0.372642 0.163598
+v -0.920976 0.354967 0.150971
+v 0.173611 -0.91754 0.36401
+v 0.733357 -0.207464 0.408211
+v 0.75251 -0.545835 -0.0413105
+v 0.752214 -0.564255 -0.0288377
+v 0.675117 -0.729934 0.431962
+v 0.798791 -0.502868 0.302931
+v 0.918933 -0.800211 0.189237
+v 0.731353 -0.190329 0.405475
+v 0.978728 -0.597872 0.291858
+v -0.223669 0.653338 0.013282
+v 0.973307 -0.598334 0.304356
+v -0.611417 0.61398 -0.656151
+v 0.0463779 0.822664 -0.32577
+v -0.851251 -0.416612 0.296084
+v -0.856338 -0.416509 0.282943
+v -0.569541 0.80138 -0.746273
+v -0.571866 0.801303 -0.732876
+v -0.568732 0.781007 -0.73303
+v 0.983314 -0.579644 0.278936
+v 0.0166154 0.647056 -0.118716
+v 0.206559 -0.0959415 -0.272038
+v 0.21812 -0.0909832 -0.269392
+v 0.218197 -0.109249 -0.272667
+v 0.757108 -0.527775 -0.0417215
+v -0.35839 0.501211 0.110238
+v -0.35514 0.520363 0.115364
+v -0.353303 0.539348 0.118421
+v -0.352212 0.558359 0.120271
+v -0.355217 0.576908 0.11616
+v -0.362488 0.595161 0.105473
+v -0.361088 0.613748 0.107515
+v -0.385237 -0.205075 -0.261749
+v -0.398069 -0.205139 -0.261877
+v -0.385237 -0.186475 -0.26302
+v 0.980527 -0.561943 0.279038
+v 0.760923 -0.509534 -0.0420298
+v -0.720486 0.231858 -0.0918439
+v -0.733344 0.231703 -0.0887482
+v -0.720576 0.250496 -0.0886326
+v -0.516965 0.551667 0.00747596
+v -0.527871 0.550639 0.0137445
+v -0.517235 0.570704 0.0125755
+v -0.33216 -0.971927 0.467723
+v 0.0468532 -0.928792 0.67213
+v 0.0418436 -0.939428 0.674995
+v 0.0469303 -0.91113 0.673209
+v 0.0465706 -0.893108 0.672593
+v -0.7582 -0.158524 -0.140309
+v -0.766729 -0.180258 -0.140797
+v -0.770763 -0.162056 -0.12907
+v -0.89481 -0.344626 0.244356
+v 0.532341 -0.20442 0.614172
+v 0.976275 -0.704924 0.214671
+v 0.714655 -0.105267 0.381737
+v -0.931188 -0.152075 0.16627
+v 0.763891 -0.491178 -0.0419142
+v 0.0314646 -0.92156 0.0827237
+v 0.0180284 -0.922151 0.08054
+v 0.0273284 -0.921085 0.0581121
+v 0.707641 -0.0707904 0.370574
+v 0.0940468 0.783512 -0.259809
+v 0.793846 -0.272385 0.0219526
+v -0.380369 0.464191 0.102364
+v -0.354794 0.482585 0.092833
+v -0.349026 0.501339 0.101285
+v -0.345545 0.52035 0.10668
+v -0.342796 0.539336 0.111009
+v -0.340715 0.558411 0.114375
+v -0.341897 0.577126 0.112833
+v -0.350914 0.595508 0.0998337
+v -0.352045 0.613915 0.098061
+v 0.372212 -0.0554275 -0.232423
+v 0.450003 -0.410716 0.697294
+v 0.449746 -0.393439 0.69687
+v 0.765226 -0.473002 -0.0418371
+v -0.733486 0.250381 -0.0856781
+v 0.656324 -0.917822 0.323098
+v 0.651019 -0.911297 0.339591
+v 0.641257 -0.921483 0.323368
+v -0.228704 -0.977013 0.242468
+v -0.237516 -0.969191 0.233566
+v -0.916878 0.0258319 0.289572
+v -0.92745 0.0305975 0.283265
+v -0.915953 0.0220297 0.280914
+v -0.620961 0.652721 -0.721045
+v 0.059159 -0.910603 0.668071
+v 0.0590819 -0.89271 0.668405
+v 0.765239 -0.455019 -0.0418628
+v 0.717558 -0.122364 0.385757
+v 0.447716 -0.37638 0.694109
+v 0.444171 -0.35963 0.688958
+v 0.636452 -0.567261 0.535842
+v 0.636684 -0.584487 0.536253
+v -0.151388 -0.819646 -0.326656
+v 0.393663 -0.499297 0.705155
+v 0.702927 -0.053886 0.364023
+v 0.700769 -0.0415545 0.356123
+v 0.766524 -0.436817 -0.0417087
+v -0.339456 0.501365 0.0925632
+v -0.33577 0.52026 0.0981509
+v -0.33243 0.53931 0.103392
+v -0.329989 0.558347 0.107348
+v -0.329565 0.577229 0.108119
+v -0.33902 0.596163 0.0950295
+v -0.343014 0.614069 0.0885683
+v 0.767551 -0.41868 -0.0413747
+v 0.115755 -0.263457 -0.448198
+v 0.102974 -0.263277 -0.450086
+v 0.105325 -0.249854 -0.446284
+v -0.656889 0.344871 -0.0852157
+v -0.501834 0.0317793 -0.192358
+v -0.488038 0.0446117 -0.187862
+v -0.488847 0.0317407 -0.195159
+v 0.0717089 -0.928163 0.663768
+v 0.0714777 -0.910231 0.663318
+v 0.0593645 -0.928561 0.668161
+v 0.0720043 -0.892106 0.664089
+v 0.546368 0.13345 -0.00467569
+v -0.0561018 0.974598 -0.180399
+v 0.742221 -0.292976 0.420324
+v 0.536439 -0.410125 0.641391
+v 0.50692 -0.654609 0.619143
+v -0.849106 -0.399836 0.321877
+v -0.845458 -0.417215 0.309019
+v -0.296681 0.520581 0.0643806
+v 0.974631 -0.517974 0.141144
+v -0.430979 -0.770577 0.259269
+v -0.430028 -0.752683 0.259064
+v 0.594679 -0.880378 0.403946
+v -0.496901 -0.880853 -0.0982151
+v -0.243874 -0.221247 -0.286013
+v -0.117605 -0.172153 -0.295917
+v -0.13352 -0.175968 -0.292398
+v 0.766537 -0.400786 -0.0416958
+v -0.0239886 -0.946544 -0.215095
+v -0.325468 0.520427 0.0904823
+v -0.322629 0.539194 0.0948497
+v -0.319341 0.558359 0.100142
+v -0.317003 0.577358 0.103816
+v -0.320342 0.595611 0.0986262
+v -0.333303 0.614403 0.0802189
+v -0.33279 0.632798 0.0806942
+v -0.436233 -0.279578 -0.25769
+v -0.423375 -0.279385 -0.259269
+v -0.423323 -0.297895 -0.259257
+v -0.609631 0.8905 -0.75276
+v -0.138517 -0.854148 -0.351987
+v -0.279751 -0.892671 -0.336495
+v 0.0736871 -0.944759 0.664808
+v 0.0845413 -0.927366 0.659118
+v 0.0837578 -0.909755 0.658655
+v 0.0845285 -0.891669 0.660017
+v -0.701064 0.423317 -0.114208
+v 0.74407 -0.310047 0.42288
+v 0.745124 -0.34446 0.423574
+v 0.744995 -0.327183 0.423432
+v -0.0115672 0.822947 -0.199295
+v 0.740268 -0.275981 0.417703
+v 0.525931 -0.410202 0.64888
+v 0.535244 -0.427684 0.639452
+v 0.505109 -0.672361 0.616227
+v -0.0258769 0.861046 -0.197188
+v 0.799806 -0.253695 0.188826
+v -0.938651 0.390792 0.202185
+v -0.458558 -0.807494 -0.0744899
+v -0.847 -0.42419 0.291511
+v 0.738367 -0.821303 0.416779
+v 0.0907328 0.822472 -0.285384
+v 0.0794803 0.706774 -0.194041
+v -0.411865 -0.883371 -0.124779
+v -0.380959 -0.886685 -0.137547
+v -0.395976 -0.893699 -0.130688
+v 0.156038 -0.116931 0.587197
+v 0.766858 -0.382777 -0.0418885
+v 0.513035 -0.515623 0.629021
+v -0.31577 0.520414 0.0819016
+v -0.312417 0.5394 0.0870526
+v -0.309385 0.558 0.0919081
+v -0.305403 0.57746 0.0980867
+v -0.305981 0.596022 0.0970462
+v -0.321922 0.614583 0.0742201
+v -0.324003 0.632631 0.0704436
+v -0.322333 0.651629 0.0732054
+v -0.640884 -0.412694 -0.200579
+v -0.628283 -0.412552 -0.204394
+v -0.125608 -0.784385 -0.307028
+v 0.0105524 -0.0723961 -0.272474
+v -0.00177907 -0.0524987 -0.267131
+v -0.759241 0.287465 -0.071073
+v -0.036577 -0.961971 -0.227323
+v -0.0237445 -0.96246 -0.224343
+v 0.0970141 -0.909126 0.655393
+v 0.097605 -0.89104 0.656266
+v -0.599574 0.638514 -0.642894
+v -0.00804758 0.803679 -0.194426
+v -0.11591 -0.0916897 -0.28302
+v 0.745162 -0.378988 0.423715
+v 0.745111 -0.361736 0.423625
+v 0.744635 -0.396367 0.422687
+v 0.540382 -0.874688 0.498783
+v 0.52105 -0.516265 0.617576
+v -0.812523 0.54536 0.061362
+v 0.5164 -0.497986 0.633928
+v 0.525225 -0.498128 0.62414
+v 0.471711 -0.837513 0.565964
+v 0.499316 -0.708251 0.607621
+v 0.502617 -0.690268 0.612515
+v -0.0222673 0.822895 -0.192178
+v -0.642374 -0.173206 -0.195968
+v -0.859023 -0.381223 0.321556
+v -0.95684 0.496753 0.227079
+v -0.951098 0.514364 0.226951
+v -0.955247 0.496676 0.214298
+v 0.768155 -0.364601 -0.0417858
+v -0.303836 -0.800519 -0.142287
+v -0.285712 -0.789832 -0.137342
+v -0.471686 -0.861765 -0.0959544
+v -0.458763 -0.843679 -0.0893647
+v -0.626497 -0.609946 -0.0167117
+v -0.613305 -0.608122 -0.0263971
+v -0.622682 -0.611911 -0.0113296
+v 0.772831 -0.328133 -0.0418114
+v -0.30241 0.539156 0.0789215
+v -0.306752 0.520093 0.0722163
+v -0.298737 0.558013 0.0845221
+v -0.294729 0.577435 0.0909062
+v -0.293534 0.596446 0.0927944
+v -0.308653 0.615136 0.0713428
+v -0.314755 0.632721 0.0615675
+v -0.313753 0.651578 0.0629291
+v -0.310901 0.670704 0.0674635
+v -0.755605 -0.420504 -0.10194
+v -0.742978 -0.419643 -0.113655
+v -0.742567 -0.43823 -0.106706
+v -0.643556 0.213425 -0.0938092
+v -0.656388 0.213463 -0.0946185
+v -0.711919 -0.942588 0.126179
+v -0.703351 -0.960417 0.136558
+v -0.70389 -0.942113 0.136584
+v -0.471159 -0.808367 -0.0676947
+v 0.110065 -0.908497 0.651501
+v 0.110001 -0.89059 0.651822
+v 0.73671 -0.570832 0.409405
+v 0.739253 -0.535585 0.413927
+v 0.737622 -0.55317 0.411525
+v 0.743428 -0.448391 0.420645
+v 0.743813 -0.43114 0.420812
+v 0.744224 -0.41376 0.42175
+v 0.571609 0.0737192 0.422019
+v 0.56335 0.0671038 0.433503
+v 0.504518 -0.585848 0.616112
+v 0.477749 -0.76495 0.575636
+v 0.487216 -0.74558 0.589612
+v 0.466805 -0.785875 0.559451
+v 0.464942 -0.80355 0.55651
+v 0.468115 -0.820506 0.56089
+v 0.494589 -0.726633 0.600556
+v 0.564519 -0.89339 0.422662
+v 0.743184 -0.465642 0.420542
+v 0.74267 -0.483202 0.418859
+v 0.678752 -0.925362 0.0505206
+v 0.67933 -0.9114 0.0189211
+v 0.740397 -0.518166 0.415288
+v -0.291942 0.539271 0.0714841
+v -0.288204 0.558038 0.0771489
+v -0.284093 0.577396 0.0836743
+v -0.281203 0.596754 0.0881573
+v -0.286238 0.613735 0.0795766
+v -0.303978 0.633093 0.0547338
+v -0.305236 0.651616 0.0527685
+v -0.302526 0.67055 0.0566735
+v -0.65626 0.194606 -0.0942203
+v 0.741784 -0.500581 0.417588
+v -0.241883 -0.616317 -0.147811
+v -0.241793 -0.635341 -0.139628
+v 0.122499 -0.90806 0.647082
+v 0.110155 -0.926249 0.650794
+v 0.12309 -0.889961 0.647955
+v 0.319803 0.187708 0.440555
+v -0.883879 0.211562 -0.0149134
+v -0.892523 0.229378 -0.00186257
+v -0.880295 0.229019 -0.0144638
+v -0.561102 -0.93682 -0.0966737
+v -0.569053 -0.953789 -0.0964296
+v -0.573408 -0.937283 -0.0901868
+v -0.2797 -0.782613 -0.129763
+v -0.279726 -0.76504 -0.121619
+v 0.514448 -0.410369 0.654879
+v 0.509978 -0.462739 0.647801
+v 0.79594 -0.21792 0.175904
+v 0.797854 -0.235775 0.188787
+v 0.89585 -0.820673 0.176507
+v 0.715014 -0.0409637 0.304536
+v 0.49816 -0.916024 0.524666
+v -0.281537 0.539477 0.063931
+v -0.277812 0.558205 0.0695444
+v -0.273534 0.577332 0.0761855
+v -0.270297 0.596394 0.0811437
+v -0.271004 0.614249 0.0792426
+v -0.291723 0.633196 0.0499425
+v -0.296168 0.65177 0.0433015
+v -0.294806 0.670525 0.0452925
+v -0.290978 0.689715 0.0512784
+v -0.759729 0.75398 -0.346284
+v -0.767873 0.752632 -0.357549
+v -0.777841 0.734173 -0.346862
+v 0.135845 -0.924964 0.644693
+v 0.135678 -0.90743 0.643524
+v 0.135601 -0.889498 0.643832
+v -0.471686 -0.879415 -0.105832
+v -0.458892 -0.878914 -0.110675
+v 0.814129 -0.450883 0.124972
+v -0.0191716 0.803949 -0.187824
+v -0.590852 0.558603 -0.128761
+v -0.307934 0.225024 0.00643549
+v -0.300728 0.218678 -0.0119076
+v -0.31383 0.220053 -0.0129095
+v -0.936519 -0.221055 0.218023
+v 0.609914 -0.861097 0.403792
+v -0.581911 0.400632 -0.0611565
+v -0.62177 0.78224 -0.752169
+v -0.468462 -0.718887 0.168119
+v -0.27171 0.539323 0.0554917
+v -0.267214 0.558231 0.0622997
+v -0.263592 0.577075 0.0678746
+v -0.258724 0.596497 0.0753248
+v -0.258223 0.61511 0.0759286
+v -0.279225 0.633864 0.0458192
+v -0.285044 0.651758 0.0369045
+v -0.286816 0.670525 0.0342199
+v -0.283618 0.689548 0.0390369
+v -0.569092 0.760788 -0.720159
+v -0.572123 0.781071 -0.720082
+v 0.791778 -0.25444 0.0220168
+v 0.14914 -0.924412 0.63976
+v 0.148986 -0.906801 0.640428
+v 0.148755 -0.888895 0.640184
+v -0.500267 -0.316996 -0.255287
+v -0.487447 -0.316945 -0.255416
+v -0.48737 -0.335031 -0.256983
+v -0.591815 0.0114965 -0.16767
+v -0.434704 0.315185 0.015363
+v -0.43342 0.325063 0.0253952
+v -0.425057 0.30821 0.0230702
+v 0.555964 -0.856769 0.484653
+v -0.278223 0.520517 0.0458577
+v -0.256835 0.558449 0.0547081
+v -0.262063 0.539336 0.0468468
+v -0.252995 0.577036 0.0605913
+v -0.247368 0.596561 0.0689792
+v -0.244979 0.615213 0.0724346
+v -0.26584 0.634969 0.0432116
+v -0.27356 0.651873 0.0309315
+v -0.277632 0.67046 0.0250612
+v -0.276065 0.68942 0.027065
+v -0.271081 0.708521 0.0345795
+v -0.750621 0.741752 -0.306039
+v -0.755143 0.734738 -0.296983
+v -0.279816 -0.747057 -0.118369
+v 0.161934 -0.923949 0.635534
+v 0.162024 -0.906172 0.636433
+v 0.161819 -0.888317 0.636163
+v -0.351646 0.167901 0.333117
+v -0.338955 0.165653 0.337497
+v -0.774475 0.690871 -0.262083
+v 0.719472 -0.114387 -0.0547723
+v 0.715078 -0.0962498 -0.0421454
+v 0.545765 -0.874508 0.486207
+v 0.930404 -0.63827 0.0142583
+v -0.246354 0.558616 0.0472835
+v -0.25216 0.539104 0.0384588
+v -0.241806 0.57737 0.0541686
+v -0.236501 0.596574 0.0622997
+v -0.233393 0.615804 0.0669754
+v -0.244542 0.633941 0.0506875
+v -0.261884 0.652464 0.0255236
+v -0.267844 0.67055 0.016609
+v -0.267792 0.689471 0.0166732
+v -0.263964 0.708418 0.0221196
+v 0.495629 -0.967315 0.0276945
+v 0.717069 -0.0771103 0.356149
+v -0.287073 0.745181 -0.136199
+v -0.275833 0.769176 -0.137188
+v -0.935298 -0.151626 0.217625
+v -0.874437 -0.398731 0.090508
+v -0.870481 -0.398757 0.0780352
+v -0.115922 -0.109943 -0.285243
+v 0.174702 -0.923294 0.632682
+v 0.174548 -0.905773 0.632246
+v -0.757763 0.808766 -0.475212
+v 0.174227 -0.88788 0.631886
+v -0.716337 0.474929 -0.261094
+v 0.0398782 -0.629111 0.710782
+v -0.242924 -0.88111 -0.354325
+v -0.256604 -0.86865 -0.339874
+v 0.0283945 0.971914 -0.294633
+v 0.0191716 0.976487 -0.296187
+v 0.0523125 0.686388 -0.143148
+v 0.391004 -0.120386 -0.271498
+v -0.235859 0.558758 0.0399232
+v -0.23117 0.577396 0.0469496
+v -0.22584 0.596548 0.0551834
+v -0.221113 0.615842 0.0619786
+v -0.226122 0.633247 0.0538346
+v -0.248717 0.652413 0.0219526
+v -0.256655 0.670396 0.0101863
+v -0.259173 0.689446 0.00658964
+v -0.256655 0.708495 0.010379
+v -0.251864 0.727481 0.0171999
+v -0.663453 0.616112 -0.673132
+v -0.660781 0.59669 -0.664487
+v -0.668938 0.615829 -0.660865
+v -0.27988 -0.728778 -0.118369
+v 0.187586 -0.922909 0.627763
+v 0.187676 -0.905118 0.628623
+v 0.187432 -0.88725 0.628418
+v -0.244067 -0.202917 -0.281762
+v 0.722978 -0.662445 -0.042762
+v 0.731456 -0.657589 -0.038446
+v 0.734346 -0.676472 -0.0460119
+v 0.67107 -0.9021 -0.000295442
+v -0.833448 0.494865 0.493735
+v -0.324992 0.668058 -0.11941
+v -0.325326 0.6873 -0.118138
+v -0.312211 0.6682 -0.126192
+v 0.973012 -0.514595 0.23539
+v 0.967219 -0.513465 0.252179
+v 0.975042 -0.526542 0.253964
+v 0.691096 -0.0609509 -0.0423124
+v -0.242744 0.539361 0.0295442
+v -0.220599 0.577435 0.0396534
+v -0.214677 0.596728 0.0484268
+v -0.209552 0.615585 0.055967
+v -0.212789 0.633569 0.0507903
+v -0.235512 0.65213 0.0182789
+v -0.245673 0.670794 0.00357099
+v -0.249668 0.689446 -0.0021837
+v -0.249102 0.708444 -0.00118177
+v -0.244722 0.727391 0.00475276
+v -0.240599 0.746569 0.011124
+v 0.710557 -0.0780866 -0.0165961
+v -0.43613 -0.298101 -0.257638
+v -0.449039 -0.298152 -0.258113
+v 0.200162 -0.922447 0.623883
+v 0.200098 -0.904669 0.624192
+v 0.168884 -0.943667 0.638925
+v -0.388808 -0.537036 0.530575
+v -0.3806 -0.547505 0.528481
+v -0.142859 0.576176 -0.0547595
+v -0.458648 -0.861496 -0.100425
+v 0.81251 -0.808599 -0.0151575
+v -0.279957 -0.710178 -0.121619
+v -0.918908 0.407209 0.49078
+v -0.919999 0.409765 0.484242
+v -0.926833 0.392 0.484255
+v -0.589798 0.542855 -0.367504
+v -0.280072 -0.691745 -0.123263
+v -0.838509 -0.409958 0.348981
+v -0.829697 -0.417986 0.357626
+v -0.0908997 -0.922177 0.035119
+v -0.0955497 -0.922755 0.0113681
+v -0.280239 -0.673132 -0.124009
+v -0.575026 0.640338 -0.360323
+v -0.575103 0.640287 -0.373194
+v -0.579124 0.660364 -0.360375
+v -0.586715 0.68039 -0.37322
+v -0.578854 0.660454 -0.373182
+v 0.149436 -0.914534 0.425847
+v 0.136616 -0.914084 0.422803
+v 0.144105 -0.916127 0.403073
+v -0.0549715 0.708367 -0.205409
+v -0.991907 0.127734 0.216186
+v -0.993487 0.127798 0.229019
+v -0.992408 0.144998 0.216007
+v -0.985356 0.250226 0.266887
+v -0.866306 -0.36365 0.321608
+v -0.870956 -0.346168 0.321621
+v -0.88569 -0.326797 0.320927
+v -0.910507 -0.273553 0.32049
+v -0.320291 0.80138 -0.037611
+v -0.342334 0.786017 -0.0449457
+v -0.916236 -0.229635 0.326669
+v -0.922363 -0.212718 0.31408
+v -0.979679 0.26785 0.266771
+v -0.970571 0.285178 0.266668
+v -0.934772 -0.255788 0.218177
+v -0.919087 -0.291164 0.21837
+v -0.928465 -0.273091 0.218267
+v -0.932498 -0.134362 0.230329
+v -0.928298 -0.117188 0.230252
+v -0.923673 -0.100078 0.230136
+v -0.917662 -0.0830577 0.229969
+v -0.908965 -0.0658964 0.229931
+v -0.576478 0.579888 -0.32171
+v -0.580164 0.559849 -0.321736
+v -0.936686 -0.238344 0.230933
+v -0.573343 0.599952 -0.321788
+v -0.576992 0.6403 -0.3218
+v -0.935118 -0.151549 0.230419
+v -0.931894 -0.186437 0.230637
+v -0.933937 -0.168967 0.230573
+v -0.994104 0.215146 0.267054
+v -0.99973 0.179975 0.267221
+v -0.997071 0.197599 0.267131
+v -0.871855 0.544936 0.138588
+v -0.866717 0.542097 0.121619
+v -0.66976 0.36365 -0.0807712
+v -0.928028 0.320901 0.5371
+v -0.922736 0.320516 0.551397
+v -0.919434 0.33823 0.547312
+v -0.573742 0.620107 -0.3218
+v -0.151131 -0.956435 0.693633
+v -0.138299 -0.957039 0.696922
+v -0.132429 -0.921419 0.420285
+v 0.417607 -0.974059 0.0422996
+v -0.0127361 -0.969268 0.623639
+v -0.025453 -0.968741 0.620428
+v -0.00405269 -0.916987 0.419669
+v -0.0126334 -0.917064 0.44103
+v -0.580229 0.579657 -0.386014
+v -0.579483 0.579528 -0.373246
+v -0.576336 0.599721 -0.386078
+v -0.576118 0.59976 -0.37322
+v -0.280227 -0.654584 -0.127669
+v -0.573459 0.620055 -0.386014
+v -0.573652 0.620043 -0.373169
+v -0.574859 0.6403 -0.386053
+v -0.894322 -0.0308929 0.230252
+v -0.895799 -0.0139757 0.229725
+v -0.615849 -0.838888 0.137111
+v -0.628103 -0.854739 0.149789
+v -0.618649 -0.854906 0.158511
+v -0.963185 0.233181 0.433914
+v -0.895349 -0.0487993 0.255493
+v -0.891997 -0.048902 0.268236
+v -0.892087 -0.0313939 0.255377
+v -0.585123 0.539554 -0.321698
+v -0.577685 0.660248 -0.386078
+v -0.938201 0.0265898 0.237291
+v -0.934515 0.0228261 0.229545
+v -0.931599 0.0228389 0.242301
+v -0.58502 0.680351 -0.386091
+v -0.975632 0.215583 0.382841
+v 0.976544 -0.651398 0.291704
+v 0.890442 -0.597448 -0.00256906
+v 0.878355 -0.594455 -0.00581892
+v 0.879177 -0.579374 0.00475276
+v -0.922209 -0.195338 0.312976
+v -0.923506 -0.186462 0.307529
+v -0.977829 0.146038 0.460093
+v -0.971483 0.0938606 0.447556
+v -0.975774 0.111317 0.447492
+v -0.932935 0.33733 0.163726
+v -0.943044 0.319707 0.163778
+v -0.597994 0.638887 -0.604397
+v -0.597994 0.63872 -0.617242
+v -0.942402 0.42261 0.388031
+v -0.947771 0.422328 0.375108
+v -0.944817 0.409431 0.381492
+v -0.125865 -0.922524 -0.0187028
+v -0.999769 0.162673 0.267323
+v -0.870622 -0.0495186 0.332449
+v -0.865047 -0.0496085 0.345577
+v -0.88402 -0.317279 0.3334
+v -0.890738 -0.299231 0.339553
+v -0.5601 -0.829202 0.401005
+v -0.228871 -0.978144 0.312732
+v -0.60213 0.524499 -0.37385
+v -0.79653 0.0969306 0.668546
+v -0.790956 0.0794867 0.663498
+v -0.786396 0.0972004 0.6766
+v -0.997893 0.145409 0.267439
+v -0.994939 0.128055 0.267516
+v -0.990918 0.110534 0.267619
+v -0.978304 0.0759799 0.267773
+v -0.984945 0.0931027 0.267696
+v -0.967797 0.0587159 0.267773
+v -0.950237 0.302044 0.151022
+v -0.947386 0.301967 0.138215
+v -0.954695 0.284459 0.13828
+v -0.940244 0.319655 0.150945
+v -0.957688 0.284549 0.151099
+v -0.939691 0.319334 0.13819
+v -0.257863 0.83998 -0.0956332
+v 0.718521 -0.923513 0.200271
+v 0.711507 -0.92824 0.17977
+v -0.898278 0.00327555 0.26839
+v -0.922504 0.0221453 0.267953
+v 0.664571 -0.916718 0.0191652
+v 0.658392 -0.902279 -0.00405911
+v -0.9005 -0.107746 0.325243
+v -0.88971 -0.0140399 0.268236
+v -0.895298 -0.0136802 0.2553
+v -0.348589 -0.971464 0.508789
+v -0.360818 -0.96991 0.504846
+v -0.353124 -0.971143 0.48509
+v -0.887244 -0.0316251 0.268531
+v -0.584262 -0.926043 0.579143
+v -0.594217 -0.92612 0.570935
+v -0.59459 -0.944027 0.571757
+v -0.45121 -0.683819 0.385218
+v -0.456156 -0.666966 0.37146
+v -0.453484 -0.684975 0.369495
+v -0.915594 0.531808 0.316367
+v -0.896647 0.542354 0.319848
+v -0.90411 0.543677 0.298435
+v -0.555527 -0.943192 0.605579
+v -0.540819 -0.955857 0.608957
+v -0.539483 -0.938375 0.615264
+v -0.891881 -0.0837257 0.319732
+v -0.882581 -0.0667056 0.319591
+v -0.127804 -0.30189 -0.440298
+v -0.070206 -0.925671 0.298216
+v -0.0788509 -0.925735 0.319655
+v -0.0835394 -0.926274 0.29602
+v -0.926589 -0.204433 0.166565
+v -0.116372 -0.923371 0.379155
+v -0.130283 -0.925028 0.377806
+v 0.285943 -0.91998 -0.0576112
+v 0.265506 -0.917116 -0.0403085
+v -0.989852 0.179564 0.215788
+v -0.989582 0.197162 0.215762
+v -0.988259 0.179474 0.202956
+v 0.0607261 -0.969165 0.61669
+v 0.0474698 -0.96964 0.614211
+v 0.0567313 -0.967906 0.592078
+v -0.990456 0.16221 0.2032
+v -0.953012 0.302057 0.163893
+v -0.98745 0.214632 0.215788
+v -0.983609 0.232269 0.215608
+v -0.984894 0.214619 0.202866
+v -0.986654 0.197073 0.202917
+v -0.893782 -0.379103 0.218807
+v 0.272635 -0.928073 -0.0289019
+v 0.259289 -0.936242 -0.000128453
+v 0.253868 -0.922087 -0.014117
+v -0.004027 -0.96851 0.602303
+v -0.58317 0.579361 -0.398988
+v -0.931637 -0.255596 0.269417
+v -0.933872 -0.238306 0.269443
+v -0.93341 -0.255634 0.256675
+v -0.57825 0.599657 -0.398911
+v -0.935298 -0.238293 0.256611
+v -0.575078 0.620004 -0.398898
+v -0.573729 0.640171 -0.398872
+v -0.917495 -0.100296 0.268454
+v -0.868271 -0.398127 0.283123
+v -0.243104 -0.388879 -0.254041
+v 0.0404691 -0.190933 -0.40428
+v -0.578571 0.660557 -0.398885
+v 0.446265 0.0496085 -0.171472
+v 0.444839 0.0340914 -0.180271
+v 0.432598 0.0367761 -0.183058
+v -0.584442 0.680608 -0.398898
+v -0.612355 -0.902896 -0.0671809
+v -0.934232 0.530819 0.227015
+v -0.582104 0.540132 -0.193206
+v -0.124041 0.141941 -0.0855882
+v -0.122255 0.132178 -0.101388
+v -0.135897 0.132384 -0.101362
+v -0.874206 -0.0493388 0.319822
+v -0.137708 0.142056 -0.0854983
+v 0.12047 0.193219 -0.0925632
+v 0.120688 0.181144 -0.105177
+v 0.105402 0.178383 -0.101902
+v -0.204157 0.132075 -0.100399
+v -0.202911 0.121298 -0.115055
+v -0.216463 0.121876 -0.115364
+v -0.870905 -0.0320233 0.31963
+v -0.872485 -0.0144124 0.319552
+v -0.879601 0.00292873 0.319758
+v -0.0295121 0.727378 -0.223816
+v -0.15451 -0.092165 -0.276803
+v -0.167278 -0.0924348 -0.273438
+v -0.154638 -0.0738091 -0.272243
+v -0.385892 -0.0401159 -0.228184
+v -0.385892 -0.0221967 -0.219745
+v -0.373239 -0.0215544 -0.220785
+v -0.166212 -0.0426464 -0.251819
+v -0.153495 -0.0553504 -0.264318
+v -0.167085 -0.056879 -0.262635
+v -0.306534 -0.78364 -0.126475
+v -0.31794 -0.78355 -0.124086
+v -0.305442 -0.765015 -0.123212
+v -0.956352 0.0592939 0.473491
+v -0.944817 0.0461275 0.475186
+v -0.985266 0.110598 0.31909
+v -0.977457 0.0932826 0.31909
+v -0.991406 0.128042 0.319039
+v 0.214934 0.253772 0.0215673
+v -0.979242 0.163662 0.511397
+v -0.995581 0.14555 0.318872
+v -0.997277 0.16293 0.318833
+v -0.996121 0.180232 0.318782
+v -0.571327 -0.810834 0.105768
+v -0.914579 0.513041 0.151035
+v -0.871213 -0.415455 0.219064
+v 0.41911 0.024329 -0.195249
+v 0.41631 0.0055877 -0.201312
+v 0.405237 0.0110213 -0.206604
+v 0.557903 -0.672336 -0.259681
+v -0.994451 0.197856 0.318628
+v -0.991638 0.21548 0.318551
+v -0.98727 0.233065 0.318435
+v -0.798753 0.797089 -0.532515
+v -0.797455 0.796922 -0.54545
+v -0.603825 0.701122 -0.344241
+v -0.601732 0.69046 -0.324973
+v 0.548295 -0.691398 -0.259732
+v 0.567781 -0.653286 -0.259848
+v 0.521371 -0.637782 -0.303226
+v 0.503259 -0.635521 -0.312629
+v -0.981451 0.250637 0.318345
+v -0.974142 0.26821 0.318242
+v -0.965176 0.285628 0.318075
+v -0.201845 -0.966673 0.603318
+v -0.210053 -0.966801 0.623626
+v -0.215114 -0.967161 0.600929
+v 0.0694481 -0.968446 0.595251
+v 0.125813 -0.910513 0.48676
+v 0.112454 -0.911117 0.48455
+v 0.690351 -0.189378 -0.120039
+v 0.698328 -0.170316 -0.106076
+v 0.700717 -0.188145 -0.10668
+v -0.247818 -0.97438 0.397022
+v -0.240098 -0.975767 0.377061
+v -0.299417 -0.806826 -0.163508
+v -0.31478 -0.810397 -0.159834
+v 0.446676 0.139821 -0.0886968
+v 0.434948 0.143533 -0.092743
+v 0.43455 0.15539 -0.0801418
+v -0.32033 -0.806171 -0.137034
+v 0.0995061 0.842189 -0.324177
+v 0.0948176 0.842061 -0.310985
+v -0.579805 0.599567 -0.41182
+v 0.0596857 0.68739 -0.155248
+v -0.576568 0.619888 -0.411795
+v -0.574949 0.640235 -0.411756
+v -0.57739 0.660325 -0.411769
+v -0.584378 0.680634 -0.41173
+v -0.952639 0.303406 0.31805
+v -0.598392 0.680197 -0.307311
+v -0.586356 0.660338 -0.308955
+v -0.575142 0.620145 -0.308955
+v -0.578456 0.640454 -0.308917
+v -0.573279 0.599965 -0.308904
+v -0.576426 0.579939 -0.308865
+v 0.571982 -0.634776 -0.260875
+v 0.569862 -0.616574 -0.260503
+v 0.568668 -0.562239 -0.259269
+v -0.942504 0.320824 0.317998
+v 0.58755 -0.578938 -0.236996
+v 0.490902 -0.862716 -0.208068
+v 0.495951 -0.843808 -0.208389
+v 0.494075 -0.86242 -0.195146
+v 0.576914 -0.543407 -0.259501
+v 0.639677 -0.447543 -0.208877
+v 0.648771 -0.446682 -0.195518
+v 0.647756 -0.464923 -0.195955
+v -0.937302 0.30365 0.446387
+v 0.585572 -0.52473 -0.260066
+v -0.928413 -0.151677 0.268993
+v -0.931278 -0.151613 0.256135
+v -0.930443 -0.169006 0.256148
+v -0.929428 -0.134375 0.255955
+v -0.234806 -0.792889 -0.20284
+v -0.247908 -0.796113 -0.200053
+v -0.246212 -0.791669 -0.177098
+v -0.929531 -0.186411 0.269122
+v -0.927797 -0.169108 0.268993
+v -0.929685 -0.186437 0.256341
+v -0.0882922 -0.611757 -0.407337
+v -0.0881123 -0.63037 -0.400632
+v -0.0961663 -0.623074 -0.3971
+v -0.978484 0.0756716 0.229301
+v -0.978253 0.075646 0.216482
+v -0.774616 0.698592 -0.276495
+v -0.766691 0.716909 -0.284947
+v -0.938201 0.338345 0.317895
+v -0.940025 0.356084 0.317523
+v -0.940295 0.373798 0.317472
+v -0.941631 0.391512 0.317369
+v -0.294716 -0.809857 -0.186938
+v -0.311158 -0.815522 -0.181183
+v -0.948644 0.409264 0.317266
+v 0.590685 -0.506156 -0.260297
+v 0.101394 0.82242 -0.311216
+v -0.954104 0.426708 0.317305
+v -0.958047 0.444383 0.31715
+v -0.959614 0.462007 0.31706
+v -0.957007 0.479656 0.316983
+v 0.0978876 -0.913943 -0.148813
+v 0.0885362 -0.914701 -0.125948
+v 0.0845156 -0.914508 -0.150919
+v -0.960398 0.266823 0.138408
+v 0.120482 -0.912106 0.463972
+v 0.632483 -0.906056 0.354363
+v 0.617441 -0.909845 0.354659
+v 0.620897 -0.919081 0.340413
+v -0.256013 -0.97402 0.417703
+v -0.586972 0.579194 -0.424768
+v -0.931984 0.0391782 0.126783
+v -0.943571 0.0569175 0.113976
+v -0.948786 0.497588 0.317009
+v -0.5815 0.599503 -0.424653
+v -0.949338 0.0570845 0.126783
+v -0.956955 0.0744385 0.126552
+v -0.950032 0.0740917 0.11354
+v -0.578392 0.619888 -0.424627
+v -0.576593 0.64021 -0.424627
+v -0.578276 0.660531 -0.424588
+v -0.583003 0.680428 -0.424614
+v -0.59062 0.700428 -0.424653
+v -0.600691 -0.842536 0.439592
+v -0.597467 -0.84296 0.426708
+v -0.964573 0.266912 0.151318
+v 0.571314 -0.606799 -0.256585
+v 0.558494 -0.618745 -0.270625
+v -0.889839 -0.380041 0.141786
+v -0.280483 -0.820391 -0.255891
+v -0.253842 -0.80761 -0.242185
+v -0.264363 -0.816165 -0.260336
+v 0.582913 -0.470318 -0.271871
+v 0.596298 -0.469226 -0.259424
+v 0.59369 -0.487672 -0.260092
+v -0.241948 -0.973712 0.48834
+v -0.57983 0.559837 -0.308839
+v -0.161151 0.576112 -0.0734879
+v -0.602053 0.720236 -0.424666
+v -0.935478 0.514351 0.316893
+v -0.952293 0.108954 0.100874
+v -0.951021 0.126244 0.100746
+v -0.946461 0.108774 0.088016
+v -0.949711 0.143559 0.100592
+v -0.943596 0.143366 0.0879261
+v -0.945382 0.126038 0.0877848
+v -0.583979 0.540119 -0.154683
+v -0.585701 0.560106 -0.154696
+v -0.585521 0.540158 -0.141799
+v 0.501063 -0.843731 -0.19557
+v -0.981567 0.144522 0.164805
+v -0.984611 0.144664 0.177625
+v -0.926705 -0.1344 0.268826
+v 0.00338474 0.125344 -0.121272
+v 0.133071 -0.170136 -0.374055
+v 0.134831 -0.17959 -0.389791
+v 0.120662 -0.180502 -0.388776
+v -0.92149 0.531667 0.30356
+v -0.243707 -0.332436 -0.269944
+v -0.97675 0.111921 0.537229
+v -0.280317 -0.635727 -0.134169
+v -0.936159 0.321736 0.510549
+v -0.932498 0.339206 0.510292
+v -0.91666 -0.194735 0.326052
+v -0.916197 -0.177316 0.324858
+v -0.962453 0.215416 0.537871
+v -0.951625 0.232757 0.546079
+v -0.58782 -0.916396 0.337215
+v -0.589362 -0.898323 0.337138
+v -0.877867 0.546837 0.155197
+v -0.939614 0.409598 0.394441
+v -0.939601 0.391666 0.381762
+v -0.967938 0.285076 0.228171
+v -0.973706 0.267516 0.228222
+v 0.55369 -0.799222 -0.20713
+v 0.565636 -0.798798 -0.194812
+v 0.571956 -0.779735 -0.20758
+v 0.579522 -0.779697 -0.195338
+v -0.949839 0.0914842 0.100707
+v 0.483735 -0.881663 -0.194837
+v 0.104413 0.783589 -0.310676
+v -0.970661 0.249507 0.164099
+v 0.29532 -0.919235 -0.0805272
+v -0.933179 0.374196 0.407491
+v -0.577043 -0.881663 0.337061
+v -0.560074 -0.865452 0.336971
+v -0.533857 -0.85014 0.336868
+v -0.965716 0.231588 0.138755
+v -0.963057 0.249224 0.138575
+v -0.92366 0.495944 0.151086
+v -0.510735 -0.834495 0.336778
+v 0.636016 -0.915305 0.340066
+v 0.625739 -0.926788 0.324781
+v 0.587961 -0.939775 0.0231344
+v 0.0628199 0.223778 0.00480414
+v 0.0779902 0.226668 0.00129738
+v 0.0665964 0.218229 -0.0153501
+v -0.578122 0.560016 -0.25742
+v -0.578135 0.560029 -0.244613
+v -0.582027 0.540029 -0.244587
+v -0.918664 -0.290753 0.269648
+v -0.926127 -0.273181 0.269584
+v -0.921271 -0.290509 0.256842
+v -0.98456 0.0933211 0.280528
+v -0.48764 -0.818785 0.336701
+v -0.919999 0.336894 0.0994354
+v -0.58466 0.539554 -0.283149
+v -0.910571 0.372411 0.137984
+v -0.905998 0.390047 0.13792
+v 0.0945221 0.822472 -0.347041
+v -0.58994 0.579785 -0.15485
+v -0.593433 0.579785 -0.141966
+v -0.587717 0.559991 -0.141902
+v -0.912626 -0.24049 0.0899685
+v -0.908066 -0.223315 0.0893134
+v -0.908092 -0.240785 0.077136
+v 0.799292 -0.235686 0.175916
+v 0.644147 -0.42902 -0.20862
+v 0.719459 -0.0226077 0.163161
+v 0.201112 -0.94928 0.627942
+v 0.186405 -0.953031 0.629201
+v 0.18932 -0.963539 0.616138
+v -0.608154 -0.859928 0.426849
+v 0.203823 -0.96079 0.616741
+v -0.263733 -0.972684 0.437639
+v -0.584467 0.599105 -0.437768
+v -0.580126 0.619811 -0.437511
+v -0.57712 0.64012 -0.437447
+v -0.577274 0.660325 -0.437447
+v -0.0199809 0.0300323 -0.226386
+v -0.0226398 0.0122544 -0.233194
+v -0.0345988 0.0284266 -0.224446
+v 0.295564 -0.264793 -0.405398
+v 0.298505 -0.244279 -0.398885
+v 0.0996217 0.764077 -0.259501
+v 0.0985299 0.744629 -0.246437
+v -0.468051 -0.80251 0.336406
+v -0.0105653 -0.945966 -0.212936
+v -0.0247722 -0.931605 -0.204934
+v -0.583825 0.520222 -0.141786
+v -0.5838 0.520183 -0.15467
+v -0.585071 0.500183 -0.141786
+v 0.480318 -0.881958 -0.207721
+v -0.586471 0.500029 -0.154645
+v 0.451403 -0.922549 -0.207927
+v 0.46588 -0.902292 -0.207837
+v 0.457466 -0.921457 -0.194722
+v -0.942556 0.0912145 0.0878747
+v -0.878201 0.513131 0.0992428
+v -0.869273 0.513234 0.0861534
+v -0.87129 0.495841 0.0859736
+v -0.880192 0.495906 0.0990372
+v -0.963198 0.110559 0.383252
+v -0.963327 0.110559 0.396046
+v -0.96745 0.266925 0.16415
+v -0.582759 0.680531 -0.437434
+v 0.948478 -0.589406 0.0425179
+v 0.938754 -0.582444 0.0349521
+v -0.589952 0.700775 -0.437395
+v -0.461756 -0.785195 0.336418
+v -0.600062 0.720351 -0.437511
+v -0.0692426 0.192461 0.0152474
+v -0.0546503 0.194683 0.0127682
+v -0.0657743 0.188222 -0.00539503
+v -0.0189918 0.186668 -0.0307902
+v -0.00414261 0.187529 -0.0326913
+v -0.0161144 0.178395 -0.0484525
+v -0.908336 -0.308788 0.269777
+v -0.91007 -0.308865 0.256996
+v -0.457171 -0.767596 0.336341
+v -0.454319 -0.749831 0.336213
+v -0.45297 -0.731964 0.336161
+v -0.925253 -0.117188 0.255891
+v -0.923198 -0.117367 0.268557
+v -0.920475 -0.100193 0.255686
+v -0.452135 -0.714288 0.336059
+v -0.280381 -0.616446 -0.143777
+v -0.583324 0.539849 -0.257407
+v 0.853409 -0.816601 0.327594
+v -0.195846 0.630871 -0.146334
+v -0.20873 0.630653 -0.144946
+v -0.925317 -0.152602 0.127798
+v -0.927193 0.337189 0.137997
+v -0.918394 0.3548 0.137958
+v -0.576336 0.580132 -0.244626
+v -0.576658 0.600055 -0.244664
+v -0.576529 0.580081 -0.231768
+v -0.947964 0.479836 0.188762
+v -0.921078 -0.255891 0.307671
+v 0.666074 -0.390613 -0.194953
+v 0.656735 -0.409726 -0.195403
+v -0.00256264 0.179051 -0.048992
+v -0.0143418 0.168903 -0.0642265
+v -0.889672 -0.0498398 0.101439
+v -0.884636 -0.0326142 0.101529
+v -0.886615 -0.0500453 0.0886069
+v -0.880526 -0.0153501 0.101259
+v -0.913757 0.407414 0.503908
+v -0.924084 0.389713 0.49624
+v 0.0890243 0.841919 -0.298229
+v -0.914129 0.0214003 0.126989
+v -0.104246 -0.922768 0.0329482
+v -0.424364 -0.735188 0.233476
+v -0.42796 -0.734892 0.246193
+v -0.429283 -0.717358 0.233489
+v -0.978728 0.111587 0.485989
+v -0.128036 0.159089 -0.052473
+v -0.125813 0.151382 -0.0697371
+v -0.138928 0.152037 -0.0705078
+v -0.889659 -0.0900969 0.332
+v -0.886268 -0.0837257 0.332796
+v -0.143861 -0.923487 0.0255621
+v -0.156681 -0.923025 0.0225435
+v -0.971561 0.180399 0.43421
+v -0.968914 0.197985 0.434107
+v -0.969492 0.198036 0.421313
+v -0.935761 0.35665 0.433323
+v 0.209064 -0.967084 0.600325
+v 0.195101 -0.968754 0.598938
+v 0.203142 -0.96973 0.578437
+v 0.427948 -0.962755 0.0579965
+v 0.274742 -0.976114 -0.20108
+v 0.261922 -0.975626 -0.204086
+v 0.270169 -0.97709 -0.225384
+v 0.215923 -0.97018 0.581481
+v 0.211735 -0.969653 0.557075
+v -0.0254658 -0.916615 0.437986
+v 0.429001 -0.942485 -0.220001
+v 0.437736 -0.942074 -0.207516
+v 0.0947533 0.764295 -0.246707
+v -0.318557 -0.709934 -0.126449
+v 0.626562 -0.684205 -0.16993
+v 0.641963 -0.682214 -0.156366
+v 0.627307 -0.702599 -0.157509
+v 0.618752 -0.703139 -0.170046
+v -0.901143 -0.0668341 0.127438
+v -0.896852 -0.0669754 0.114529
+v -0.904033 -0.0842009 0.114798
+v -0.847668 0.512746 0.0607454
+v -0.585932 0.540093 -0.129057
+v 0.470645 -0.901624 -0.194825
+v 0.4443 -0.941393 -0.194619
+v -0.571404 0.821739 -0.746415
+v -0.928516 -0.272937 0.2567
+v 0.254446 -0.147772 -0.294812
+v 0.266726 -0.149905 -0.292256
+v 0.257144 -0.155287 -0.312796
+v -0.586921 0.599182 -0.450497
+v -0.583003 0.619619 -0.450446
+v -0.579676 0.640261 -0.450613
+v 0.102525 0.803088 -0.298229
+v 0.0964232 0.822587 -0.298139
+v -0.578482 0.660402 -0.450318
+v -0.581462 0.680338 -0.450305
+v -0.954052 0.250843 0.485193
+v 0.217631 0.0183688 -0.235968
+v 0.230502 0.0183816 -0.238768
+v 0.209488 0.014284 -0.236097
+v 0.326598 -0.977065 -0.19002
+v 0.319559 -0.973532 -0.170444
+v 0.313766 -0.976564 -0.192988
+v -0.919177 -0.15196 0.307311
+v -0.91463 -0.15995 0.322584
+v -0.927052 0.409611 0.458526
+v -0.921811 0.424177 0.456907
+v -0.923301 0.427402 0.445706
+v -0.990058 0.127669 0.203418
+v -0.990584 0.144908 0.203251
+v -0.575206 0.600004 -0.257574
+v -0.57861 0.62021 -0.257523
+v -0.582232 0.540158 -0.180361
+v -0.580485 0.560094 -0.180451
+v 0.418943 -0.943346 -0.232551
+v -0.280522 -0.597165 -0.155068
+v 0.637827 -0.574429 -0.208685
+v 0.639009 -0.556163 -0.208235
+v 0.649439 -0.573427 -0.195955
+v 0.637698 -0.538167 -0.208595
+v 0.652136 -0.554994 -0.195505
+v 0.647615 -0.410703 -0.208813
+v -0.0963333 0.948022 -0.158228
+v -0.104028 0.943359 -0.143084
+v 0.725727 -0.368031 -0.131639
+v 0.730326 -0.349572 -0.131536
+v 0.733216 -0.367196 -0.118524
+v 0.707513 -0.333464 -0.169982
+v 0.715554 -0.332783 -0.157098
+v 0.714038 -0.350895 -0.157149
+v 0.73328 -0.331319 -0.131369
+v 0.739844 -0.330779 -0.118588
+v 0.736774 -0.34902 -0.118678
+v 0.701655 -0.369534 -0.169198
+v 0.706048 -0.351589 -0.17011
+v 0.710274 -0.369007 -0.156777
+v 0.669234 -0.445077 -0.170496
+v 0.677146 -0.444422 -0.157393
+v 0.667294 -0.463253 -0.170226
+v -0.734552 0.51001 -0.402546
+v -0.731739 0.5101 -0.415391
+v -0.719112 0.495366 -0.396085
+v 0.682503 -0.353348 -0.195056
+v 0.694513 -0.352514 -0.182827
+v -0.962106 0.197766 0.557794
+v 0.662259 -0.71565 -0.0913814
+v 0.672753 -0.715278 -0.0786132
+v 0.658084 -0.734584 -0.0783178
+v -0.110399 0.14221 -0.0859094
+v -0.16819 -0.812555 -0.316277
+v -0.167381 -0.824617 -0.330548
+v -0.181716 -0.825824 -0.329482
+v 0.602656 -0.198524 -0.214491
+v 0.613485 -0.204253 -0.208453
+v 0.601346 -0.213938 -0.223855
+v -0.425301 -0.483831 0.545784
+v -0.410337 -0.495713 0.536818
+v 0.931162 -0.544319 0.0471166
+v 0.929929 -0.559862 0.0373284
+v 0.91797 -0.556792 0.0339373
+v -0.588424 0.700634 -0.450279
+v -0.0641045 0.0879518 -0.158305
+v -0.0638861 0.0757487 -0.171112
+v -0.078093 0.0750679 -0.170213
+v 0.537634 -0.837423 -0.143199
+v 0.545623 -0.836409 -0.130303
+v -0.570556 0.740583 -0.720159
+v 0.592688 -0.72355 -0.208505
+v 0.598135 -0.723165 -0.195916
+v 0.595694 -0.741431 -0.195364
+v -0.951111 0.514454 0.23977
+v -0.935928 0.53114 0.23968
+v 0.642066 -0.66423 -0.169352
+v 0.653357 -0.6631 -0.156417
+v -0.856107 0.424614 0.0603472
+v 0.746691 -0.312269 -0.105909
+v 0.746498 -0.294324 -0.105807
+v 0.751983 -0.311832 -0.0933082
+v 0.407678 -0.944528 -0.244536
+v 0.399508 -0.952761 -0.241492
+v -0.585688 0.520196 -0.116134
+v 0.0428969 0.668354 -0.157946
+v -0.660486 0.56739 -0.630833
+v -0.674629 0.562945 -0.6208
+v 0.983532 -0.597486 0.279
+v -0.123886 -0.966814 0.620184
+v -0.116154 -0.968034 0.600415
+v -0.913821 -0.309186 0.0902254
+v -0.918689 -0.291884 0.0900712
+v -0.914643 -0.292282 0.0771489
+v -0.422257 0.711989 0.0328583
+v -0.445224 0.693196 0.0457421
+v -0.422938 0.708765 0.0436355
+v -0.558533 -0.810988 0.477948
+v -0.655207 -0.137098 -0.181106
+v -0.655463 -0.118588 -0.178293
+v -0.642002 -0.118331 -0.185306
+v -0.589246 0.660749 -0.295981
+v -0.579702 0.640685 -0.295994
+v -0.449579 -0.696202 0.387491
+v -0.452341 -0.695958 0.374556
+v -0.45148 -0.714019 0.374774
+v -0.642515 -0.0997437 -0.18293
+v -0.769144 0.627608 -0.134811
+v -0.776363 0.60915 -0.1446
+v -0.295474 -0.16731 -0.265153
+v -0.308422 -0.16731 -0.264074
+v -0.295512 -0.149121 -0.261684
+v -0.575412 0.620107 -0.29611
+v -0.660306 0.855831 -0.728791
+v -0.669516 0.870577 -0.725348
+v -0.661141 0.874135 -0.734417
+v -0.715078 0.484255 -0.349161
+v -0.729144 0.493568 -0.338075
+v -0.727834 0.493979 -0.35119
+v 0.387857 -0.953134 -0.250933
+v 0.386534 -0.965774 -0.231986
+v 0.259995 -0.967572 -0.275056
+v 0.273085 -0.950847 -0.28618
+v 0.285943 -0.95122 -0.283213
+v -0.587229 0.519836 -0.244562
+v -0.249141 -0.971426 0.507415
+v -0.580678 0.620094 -0.244703
+v -0.574821 0.580068 -0.257497
+v -0.586574 0.640968 -0.25724
+v 0.684956 -0.872453 0.381698
+v 0.683081 -0.859749 0.393195
+v 0.669105 -0.861213 0.391563
+v -0.466214 -0.590845 0.447569
+v -0.456593 -0.610627 0.423163
+v -0.577685 0.841906 -0.733081
+v -0.973577 0.267401 0.215428
+v -0.978266 0.249944 0.215454
+v -0.920025 -0.274658 0.0900841
+v -0.917276 -0.257754 0.0899813
+v -0.915915 -0.274954 0.0771874
+v -0.919075 -0.135633 0.115081
+v -0.914592 -0.135929 0.102274
+v -0.918008 -0.153052 0.102197
+v -0.233688 -0.933031 0.632926
+v -0.242821 -0.92639 0.619901
+v -0.939601 0.108479 0.0749652
+v 0.726588 -0.38568 -0.118357
+v 0.718996 -0.386489 -0.131484
+v 0.664648 -0.517717 -0.183701
+v 0.652637 -0.518796 -0.195994
+v 0.662323 -0.499836 -0.183058
+v 0.707243 -0.315506 -0.169802
+v 0.715734 -0.314787 -0.157239
+v 0.657519 -0.464101 -0.183097
+v 0.65897 -0.482045 -0.182968
+v 0.651109 -0.500812 -0.196096
+v 0.648386 -0.482932 -0.196469
+v 0.659702 -0.445668 -0.1823
+v 0.91919 -0.541249 0.0437896
+v -0.120213 -0.190971 -0.302121
+v -0.119018 -0.201504 -0.317279
+v 0.538867 -0.692413 -0.272834
+v 0.542129 -0.711604 -0.258447
+v 0.555463 -0.654545 -0.273386
+v -0.216912 0.017187 -0.211986
+v -0.218659 0.000539503 -0.219989
+v -0.230091 0.0179963 -0.212692
+v 0.559753 -0.635727 -0.272937
+v 0.548 -0.673248 -0.272372
+v -0.2374 -0.978067 0.333926
+v -0.245108 -0.976628 0.353952
+v -0.258402 -0.977078 0.351563
+v 0.0462623 0.94472 -0.338448
+v 0.0468789 0.956975 -0.325577
+v 0.591481 -0.705592 -0.20889
+v 0.59983 -0.704911 -0.196148
+v -0.0584397 -0.25223 -0.445218
+v -0.0606234 -0.270021 -0.452745
+v -0.0729934 -0.254607 -0.44288
+v -0.771135 0.060527 -0.0451255
+v 0.234317 -0.967508 -0.281248
+v 0.247317 -0.968869 -0.276341
+v 0.225968 -0.978632 -0.256893
+v -0.822953 0.173142 -0.0454467
+v -0.771174 0.11792 -0.068671
+v -0.758174 0.0994611 -0.0699426
+v -0.631301 0.307093 -0.085935
+v -0.631443 0.325937 -0.0856781
+v -0.15135 -0.836884 -0.341017
+v -0.847475 -0.399848 0.334697
+v -0.839318 -0.417626 0.321852
+v -0.859318 -0.381287 0.334479
+v -0.867115 -0.363406 0.334402
+v -0.575129 0.580029 -0.296058
+v -0.574679 0.60003 -0.296071
+v 0.25952 -0.162968 -0.32988
+v 0.272134 -0.164959 -0.327825
+v -0.0414068 -0.91989 -0.0515482
+v -0.0507453 -0.920789 -0.0288634
+v -0.0542393 -0.919428 -0.0545797
+v 0.696183 -0.33435 -0.182879
+v -0.918471 -0.170457 0.102043
+v -0.913988 -0.153977 0.0897501
+v -0.912806 0.495687 0.138678
+v -0.917495 0.478641 0.138614
+v -0.921438 -0.25742 0.102827
+v -0.917122 -0.240143 0.102839
+v 0.0893069 -0.0859094 -0.283586
+v 0.0865709 -0.104445 -0.289469
+v 0.0761405 -0.0850487 -0.284562
+v 0.745098 -0.276341 -0.105871
+v 0.753088 -0.275686 -0.093
+v 0.753396 -0.293772 -0.0931669
+v 0.69811 -0.0803216 -0.0553247
+v 0.692676 -0.079127 -0.0680159
+v -0.585392 0.520196 -0.128915
+v -0.585084 0.500234 -0.116083
+v -0.583851 0.500247 -0.128941
+v -0.586895 0.480196 -0.11607
+v -0.527499 0.620402 0.072075
+v -0.508873 0.638643 0.0719979
+v -0.51035 0.638476 0.0591269
+v 0.591404 -0.687545 -0.208954
+v 0.596491 -0.66933 -0.20925
+v 0.602361 -0.686453 -0.195749
+v -0.870006 -0.346386 0.334569
+v -0.579689 0.559837 -0.29602
+v -0.877173 -0.328377 0.334427
+v -0.133777 -0.930205 0.242969
+v 0.312571 -0.936987 -0.13309
+v 0.308332 -0.928265 -0.117791
+v 0.297234 -0.924656 -0.123366
+v -0.141819 -0.929203 0.263547
+v -0.164182 -0.962485 0.265679
+v -0.770467 -0.381261 0.475944
+v 0.0535842 -0.966827 0.635791
+v 0.0397755 -0.968343 0.634095
+v 0.619304 -0.647364 -0.206244
+v 0.630222 -0.646992 -0.194619
+v 0.610364 -0.667699 -0.195672
+v -0.895375 0.00309572 0.127053
+v 0.461499 -0.864874 -0.258756
+v 0.469797 -0.845555 -0.258974
+v 0.474345 -0.863474 -0.245782
+v -0.943776 0.408532 0.20257
+v -0.94438 0.426233 0.202172
+v 0.97323 -0.669446 0.291665
+v -0.584185 0.579991 -0.180464
+v -0.589965 0.599708 -0.180541
+v -0.585495 0.520068 -0.180322
+v 0.599021 -0.759286 -0.169648
+v 0.603812 -0.758785 -0.156777
+v 0.593074 -0.778656 -0.156892
+v 0.590595 -0.778374 -0.169481
+v -0.952665 0.178293 0.10045
+v -0.965562 0.109365 0.126436
+v 0.00808611 -0.917296 -0.067836
+v -0.0560248 -0.922048 0.0187284
+v -0.065222 -0.923102 0.0411435
+v -0.069371 -0.922626 0.0165191
+v 0.697917 -0.152191 -0.105781
+v 0.706626 -0.151485 -0.0933596
+v 0.708296 -0.169609 -0.0933596
+v -0.0739054 -0.923127 0.062775
+v -0.0867379 -0.922665 0.0597306
+v -0.0780416 -0.922652 0.0381762
+v 0.718971 -0.404563 -0.118575
+v -0.115832 -0.12835 -0.286643
+v -0.10309 -0.109763 -0.285782
+v -0.0961021 -0.129917 -0.288595
+v 0.652419 -0.536908 -0.195775
+v 0.665586 -0.535765 -0.183058
+v 0.578661 -0.507017 -0.272526
+v 0.573164 -0.525424 -0.271781
+v 0.566677 -0.510806 -0.279796
+v 0.221498 -0.967534 -0.27936
+v 0.533664 -0.710949 -0.272539
+v -0.480485 -0.677153 0.274209
+v -0.484981 -0.675714 0.271678
+v -0.463413 -0.68739 0.265564
+v 0.208845 -0.968613 -0.284562
+v 0.211992 -0.980212 -0.258152
+v -0.435359 0.485694 -0.0150162
+v -0.655566 0.100514 -0.0924348
+v -0.655874 0.11941 -0.0931798
+v -0.473728 -0.783537 0.439258
+v -0.977315 0.128633 0.447376
+v -0.914682 -0.247388 0.32514
+v 0.662657 -0.554198 -0.183315
+v 0.541962 -0.637371 -0.287118
+v 0.725355 -0.314029 -0.14433
+v 0.725213 -0.332012 -0.144227
+v 0.72258 -0.296225 -0.144587
+v 0.102473 0.783743 -0.28523
+v 0.172455 0.251061 0.0255108
+v -0.778881 0.76996 -0.419553
+v -0.794308 0.751154 -0.42139
+v -0.789106 0.751604 -0.408802
+v -0.147381 -0.965131 0.679606
+v -0.588989 0.599207 -0.463279
+v -0.167869 -0.252706 -0.321877
+v 0.558918 -0.846171 -0.0702638
+v 0.566047 -0.835407 -0.0789472
+v 0.574063 -0.829048 -0.0727429
+v -0.921387 0.355365 0.530652
+v -0.918124 0.372822 0.527132
+v -0.926795 0.354864 0.518179
+v 0.105209 0.190483 -0.0892106
+v -0.964842 0.216174 0.524011
+v 0.612573 -0.685746 -0.183302
+v 0.513523 -0.895664 -0.0655881
+v -0.916698 -0.18776 0.10239
+v -0.913821 -0.170701 0.0892877
+v 0.493253 -0.91727 -0.0662432
+v -0.967257 0.197445 0.544589
+v -0.968657 0.198473 0.536818
+v -0.916583 0.461249 0.13819
+v -0.927373 0.461326 0.150483
+v 0.0423959 -0.944784 -0.203534
+v 0.0552669 -0.945247 -0.200528
+v 0.0421904 -0.928856 -0.194259
+v 0.750737 -0.420157 -0.0676562
+v 0.759626 -0.419373 -0.0542842
+v 0.758971 -0.437498 -0.0548237
+v 0.464955 -0.938439 -0.117393
+v 0.751392 -0.257792 -0.0929357
+v 0.742118 -0.258409 -0.106025
+v 0.746678 -0.240053 -0.093
+v 0.589554 -0.797243 -0.118138
+v 0.59274 -0.796845 -0.105383
+v 0.576902 -0.815548 -0.104766
+v -0.783223 -0.520414 0.11503
+v 0.735605 -0.240785 -0.105987
+v 0.729902 -0.244767 -0.113796
+v -0.760525 -0.529753 0.0652798
+v -0.763711 -0.529522 0.0781379
+v -0.773769 -0.511911 0.0648688
+v -0.87278 -0.381544 0.0776755
+v -0.878638 -0.380953 0.0905979
+v -0.874835 -0.364228 0.0774058
+v -0.459997 -0.767057 0.3878
+v -0.458596 -0.767031 0.400671
+v -0.453908 -0.749574 0.387697
+v 0.840577 -0.862703 0.189597
+v 0.832793 -0.867019 0.193155
+v -0.913718 -0.118421 0.114786
+v -0.908965 -0.101337 0.114773
+v -0.908888 -0.11878 0.10203
+v -0.967026 0.215788 0.498218
+v -0.959974 0.233361 0.498128
+v 0.651841 -0.645309 -0.169404
+v 0.660769 -0.644834 -0.157214
+v 0.081831 -0.126847 -0.29155
+v 0.0676883 -0.127965 -0.290445
+v 0.0739568 -0.102827 -0.290715
+v -0.88357 0.00227362 0.101221
+v -0.878586 0.00315994 0.0880931
+v -0.583979 0.619644 -0.463227
+v -0.604814 -0.838464 0.144394
+v -0.605418 -0.825002 0.11887
+v -0.580383 0.640068 -0.463279
+v -0.578995 0.660235 -0.463163
+v -0.582104 0.680659 -0.46315
+v -0.771379 0.716806 -0.298525
+v -0.849736 0.26699 -0.0241106
+v -0.587961 -0.979248 -0.0971105
+v -0.59992 -0.975844 -0.0813107
+v -0.911085 0.510318 0.371679
+v -0.896313 0.526182 0.365307
+v -0.915825 0.51484 0.355044
+v -0.225596 -0.832748 -0.322918
+v -0.224748 -0.844758 -0.337279
+v -0.240188 -0.848316 -0.333836
+v 0.454023 -0.940173 -0.168864
+v 0.466047 -0.920789 -0.169044
+v 0.457132 -0.939698 -0.15598
+v -0.941477 0.286193 0.485038
+v -0.940462 0.286219 0.47218
+v 0.448834 -0.959004 -0.155903
+v 0.477402 -0.900969 -0.169083
+v 0.479226 -0.900879 -0.156263
+v 0.469207 -0.92034 -0.156147
+v 0.557903 -0.816165 -0.16853
+v 0.574782 -0.798772 -0.169596
+v 0.560871 -0.817513 -0.156314
+v 0.579471 -0.798053 -0.156623
+v 0.490055 -0.880879 -0.169083
+v 0.499393 -0.862318 -0.169429
+v 0.491891 -0.880828 -0.15625
+v 0.510055 -0.844039 -0.170059
+v 0.502168 -0.861752 -0.15643
+v -0.923391 -0.135377 0.127875
+v -0.918959 -0.118254 0.127849
+v 0.606651 -0.740197 -0.169507
+v 0.612149 -0.739928 -0.156905
+v -0.909569 -0.188453 0.0891977
+v -0.912074 -0.171498 0.0770204
+v -0.205634 -0.148029 -0.273219
+v -0.439277 0.495109 -0.0182275
+v -0.439495 0.514107 -0.0254208
+v -0.879344 -0.363843 0.0903153
+v -0.908387 -0.188351 0.076802
+v -0.588026 0.46017 -0.0904823
+v -0.594397 0.439515 -0.0911117
+v 0.688681 -0.127079 -0.110457
+v 0.69373 -0.134066 -0.106308
+v 0.686485 -0.144394 -0.117804
+v 0.71048 -0.405141 -0.131176
+v 0.712715 -0.423278 -0.118678
+v 0.7052 -0.297793 -0.169455
+v 0.714282 -0.296906 -0.157342
+v 0.608861 -0.703961 -0.182814
+v -0.967386 0.249366 0.151408
+v -0.968747 0.214028 0.138768
+v -0.524647 -0.814841 0.388082
+v -0.337028 0.572091 -0.0848432
+v -0.337157 0.591179 -0.0946442
+v -0.474383 -0.82287 0.213348
+v -0.464428 -0.822523 0.221517
+v -0.464749 -0.806235 0.203264
+v -0.95702 0.0759928 0.421929
+v -0.96235 0.0936165 0.409097
+v 0.644917 -0.592014 -0.196199
+v 0.654808 -0.591192 -0.183392
+v -0.108177 -0.0351576 -0.259783
+v -0.122384 -0.0360439 -0.258936
+v -0.121561 -0.0218884 -0.248068
+v -0.954296 0.461583 0.227156
+v 0.658366 -0.572836 -0.183752
+v -0.979306 0.111561 0.498796
+v -0.955542 0.443882 0.227259
+v -0.953449 0.426207 0.214748
+v -0.972601 0.198267 0.51114
+v -0.971252 0.198344 0.523947
+v -0.966936 0.21584 0.511024
+v -0.00811181 -0.92228 0.0752991
+v -0.021548 -0.92287 0.0731411
+v -0.0122608 -0.921804 0.0507389
+v -0.402642 0.326592 0.127579
+v 0.0453118 -0.92016 0.0137573
+v 0.0313489 -0.921804 0.0124342
+v 0.0418436 -0.918798 -0.0119975
+v -0.408307 0.300657 0.0581635
+v -0.452392 -0.749677 0.400593
+v -0.449232 -0.731899 0.400491
+v -0.451352 -0.73172 0.387748
+v 0.905433 -0.478796 0.134079
+v 0.921888 -0.48613 0.121041
+v 0.913975 -0.486413 0.116147
+v -0.950289 0.285744 0.395083
+v -0.943262 0.303367 0.382173
+v -0.209192 0.688058 -0.171639
+v -0.209218 0.707301 -0.17792
+v -0.470799 -0.784013 0.387877
+v -0.981426 0.180245 0.370201
+v -0.981079 0.162878 0.37024
+v 0.57879 -0.456612 -0.274388
+v -0.440433 -0.788586 0.214722
+v -0.455745 -0.805965 0.212397
+v -0.446817 -0.805606 0.221569
+v -0.979563 0.249995 0.228299
+v -0.868464 0.529933 0.0995382
+v -0.859164 0.529393 0.0868085
+v 0.57274 -0.816781 -0.117933
+v 0.196039 -0.968857 -0.28487
+v 0.199725 -0.97867 -0.262006
+v 0.65405 -0.699568 -0.118331
+v 0.671905 -0.678643 -0.117342
+v 0.668193 -0.696523 -0.104137
+v 0.60511 -0.776691 -0.118023
+v 0.607371 -0.776974 -0.105473
+v 0.680306 -0.661096 -0.118575
+v 0.679137 -0.67845 -0.104985
+v 0.689812 -0.660043 -0.105588
+v 0.690133 -0.642111 -0.118639
+v 0.70091 -0.640865 -0.105331
+v -0.973153 0.111125 0.434582
+v -0.972896 0.12844 0.421724
+v 0.699369 -0.62301 -0.118344
+v 0.70768 -0.622278 -0.105653
+v -0.910751 0.0548237 0.0745541
+v -0.924649 0.0551063 0.0871553
+v -0.926756 0.0732182 0.0749009
+v 0.658713 -0.609137 -0.170958
+v 0.662927 -0.590524 -0.170431
+v 0.666498 -0.60834 -0.157882
+v 0.513382 -0.860545 -0.118035
+v 0.497415 -0.880725 -0.117958
+v 0.669118 -0.571744 -0.170341
+v 0.173636 0.164792 -0.113732
+v 0.186366 0.163444 -0.112281
+v 0.173456 0.15187 -0.125563
+v 0.439906 -0.878734 -0.262738
+v 0.452431 -0.859505 -0.267311
+v -0.0975022 -0.926852 0.154503
+v -0.106725 -0.927944 0.176841
+v -0.110861 -0.927443 0.152307
+v -0.115897 -0.929036 0.199192
+v -0.119493 -0.927495 0.17381
+v -0.433047 -0.716703 0.246154
+v -0.434987 -0.716626 0.258846
+v -0.451917 -0.694237 0.259526
+v 0.609336 -0.891155 0.38306
+v 0.626793 -0.883243 0.379501
+v 0.60827 -0.877796 0.394196
+v -0.902671 0.548263 0.222172
+v -0.849582 0.552797 0.12731
+v -0.146353 -0.923076 0.418872
+v -0.964097 0.0920366 0.126539
+v -0.959524 0.109185 0.113758
+v -0.592354 0.598951 -0.476162
+v 0.0817154 -0.140874 -0.302417
+v 0.0676112 -0.141966 -0.301222
+v 0.146635 0.127001 -0.150226
+v 0.133996 0.128569 -0.151844
+v 0.134227 0.141876 -0.140386
+v -0.61301 -0.824707 0.105781
+v -0.887411 -0.346129 0.0901098
+v 0.675656 -0.553054 -0.170444
+v -0.90578 -0.206154 0.0888381
+v -0.905908 -0.223482 0.076725
+v -0.980064 0.127207 0.164869
+v -0.984265 0.1274 0.177779
+v -0.976968 0.092666 0.177907
+v -0.980115 0.109981 0.177792
+v -0.977148 0.109853 0.164972
+v -0.965061 0.0579323 0.178151
+v -0.974399 0.0924476 0.164998
+v -0.972717 0.0751964 0.177972
+v -0.977932 0.196713 0.164381
+v -0.575322 0.460851 -0.0393837
+v -0.209025 0.669009 -0.164792
+v -0.929299 0.374312 0.497062
+v -0.923545 0.372629 0.51403
+v -0.919666 0.389868 0.510331
+v -0.585328 0.480286 -0.103199
+v -0.584981 0.480299 -0.0903924
+v 0.712368 -0.54965 -0.131253
+v 0.719703 -0.549214 -0.118947
+v 0.714077 -0.567531 -0.118485
+v 0.701283 -0.424216 -0.13151
+v -0.909813 -0.153681 0.0766864
+v 0.605521 -0.72233 -0.18266
+v 0.628386 -0.665052 -0.181543
+v 0.934438 -0.60432 0.0313682
+v 0.924457 -0.596664 0.0235968
+v 0.460331 0.202224 0.0237253
+v -0.647101 0.483253 -0.360657
+v -0.586972 0.619439 -0.476124
+v -0.581988 0.639927 -0.47606
+v -0.58037 0.660223 -0.476034
+v -0.914078 -0.205512 0.102184
+v 0.641475 -0.610447 -0.196006
+v 0.651456 -0.609574 -0.183264
+v 0.620935 -0.72057 -0.156494
+v 0.613485 -0.721533 -0.169725
+v -0.445584 -0.696626 0.235197
+v -0.43017 -0.716665 0.220965
+v 0.461384 -0.921483 -0.182018
+v 0.45053 -0.940379 -0.181658
+v -0.968799 0.0936808 0.434672
+v 0.216707 0.0535135 -0.224677
+v 0.20083 0.049159 -0.221543
+v 0.202191 0.0642008 -0.211909
+v -0.580999 0.680441 -0.476008
+v -0.586882 0.700518 -0.475995
+v 0.218043 0.0815548 -0.205024
+v 0.216565 0.0669754 -0.215056
+v 0.202885 0.0786518 -0.201774
+v 0.234818 0.228261 -0.028401
+v 0.236604 0.218832 -0.0440979
+v 0.222461 0.218062 -0.042929
+v -0.954977 0.0407196 0.242262
+v -0.943211 0.033873 0.25354
+v -0.973937 0.145409 0.383162
+v -0.978202 0.145447 0.370343
+v -0.883853 -0.0895703 0.34437
+v -0.141459 0.916178 -0.13503
+v -0.905998 -0.264408 0.335442
+v -0.911868 -0.265011 0.323098
+v 0.541744 -0.655727 -0.285936
+v -0.878098 -0.0667955 0.332501
+v 0.669272 -0.353284 -0.208132
+v 0.677223 -0.371563 -0.19467
+v -0.280612 -0.578244 -0.163251
+v -0.583889 0.520157 -0.16749
+v 0.722259 -0.35024 -0.144407
+v -0.110232 -0.131022 -0.287619
+v -0.90894 -0.136379 0.0899428
+v 0.15749 -0.968266 -0.289212
+v 0.170374 -0.968857 -0.288428
+v 0.159558 -0.980289 -0.268325
+v -0.578199 0.560094 -0.231781
+v -0.744571 -0.305744 -0.170444
+v -0.744045 -0.324357 -0.169699
+v -0.761167 -0.32085 -0.154195
+v 0.0983629 -0.979968 -0.256456
+v 0.085479 -0.97948 -0.259436
+v 0.0931348 -0.981946 -0.279848
+v -0.416053 0.298859 0.0336161
+v -0.40787 0.2897 0.0436869
+v 0.555604 -0.835664 -0.104651
+v 0.488834 -0.899646 -0.117714
+v -0.985035 0.232384 0.228454
+v -0.478365 -0.856203 0.259835
+v 0.556221 -0.563074 -0.270907
+v 0.563684 -0.581442 -0.258691
+v 0.0954727 -0.126693 -0.29164
+v -0.210374 -0.968792 0.377266
+v -0.138299 -0.924052 0.398333
+v -0.946153 0.268659 0.485128
+v -0.759356 0.0315737 -0.0532181
+v -0.770763 0.0419656 -0.0392424
+v 0.146867 0.140271 -0.138729
+v 0.14783 0.168209 -0.117213
+v 0.147098 0.153771 -0.127413
+v 0.134689 0.168787 -0.117727
+v -0.544621 -0.833403 -0.0355172
+v -0.557184 -0.845901 -0.0431345
+v -0.960488 0.284613 0.163945
+v -0.798033 0.797076 -0.519657
+v 0.432148 -0.0550806 -0.213065
+v 0.432829 -0.0665386 -0.226488
+v 0.419752 -0.0654982 -0.227632
+v -0.150823 0.142814 -0.0863204
+v 0.672548 -0.498899 -0.170586
+v 0.669015 -0.481172 -0.170329
+v -0.779665 -0.511179 0.077804
+v -0.894977 -0.0496471 0.127335
+v -0.937199 0.0734237 0.0876178
+v -0.935195 0.0910218 0.0750808
+v -0.893564 0.0195762 0.0878361
+v -0.958921 0.143816 0.11318
+v -0.950083 0.160939 0.100373
+v -0.678251 -0.872221 0.0542971
+v -0.683749 -0.881354 0.0463201
+v -0.681681 -0.879312 0.0604628
+v -0.510928 -0.678206 0.157727
+v -0.964303 0.126667 0.126308
+v -0.966294 0.14397 0.125961
+v -0.866229 -0.0321518 0.332449
+v -0.585315 0.500273 -0.103238
+v -0.585778 0.500209 -0.0904181
+v 0.705945 -0.568276 -0.131266
+v 0.706562 -0.586465 -0.118832
+v 0.600627 -0.740917 -0.182545
+v 0.0130059 0.21977 0.0366733
+v -0.867077 -0.0147721 0.332655
+v 0.0990308 -0.145871 -0.323149
+v 0.101767 -0.153065 -0.341081
+v 0.0876242 -0.154067 -0.339976
+v -0.294498 0.224536 0.0113296
+v -0.281126 0.223598 0.0163264
+v -0.277709 0.217985 -0.00119461
+v 0.637981 -0.628842 -0.195775
+v 0.647486 -0.627865 -0.182712
+v -0.886126 0.0191523 0.0748752
+v -0.898265 0.0371614 0.0747982
+v -0.912947 -0.257908 0.077136
+v 0.701321 -0.442328 -0.131523
+v 0.713254 -0.441326 -0.119089
+v 0.717712 -0.459027 -0.118755
+v 0.706112 -0.460041 -0.131395
+v 0.664596 -0.626529 -0.15765
+v -0.487948 -0.836923 0.221543
+v -0.484493 -0.822973 0.205332
+v -0.497235 -0.839415 0.218421
+v 0.656491 -0.627287 -0.170483
+v -0.928876 0.337382 0.150804
+v -0.432418 -0.788496 0.259411
+v -0.261794 0.523382 -0.0299167
+v -0.24918 0.534236 -0.0458449
+v -0.874951 0.00283881 0.332603
+v -0.892536 0.0217728 0.332167
+v -0.887077 0.0208608 0.345243
+v -0.89472 0.0263971 0.340901
+v 0.813987 -0.481185 0.0849074
+v 0.807513 -0.467183 0.0701353
+v 0.144696 -0.968831 -0.289918
+v 0.146135 -0.980828 -0.270496
+v 0.625405 -0.869473 0.390125
+v -0.265031 -0.969948 0.547788
+v -0.278261 -0.970424 0.545347
+v -0.270618 -0.971657 0.525604
+v 0.300329 -0.18853 -0.354119
+v 0.696337 -0.0969435 -0.0811309
+v 0.690737 -0.0965838 -0.0913558
+v -0.00249841 -0.980289 -0.251806
+v -0.00845863 -0.974753 -0.234028
+v 0.211068 0.209301 -0.0593324
+v 0.224208 0.208877 -0.0587415
+v 0.211864 0.198537 -0.0732182
+v 0.334459 0.185332 -0.0861277
+v 0.350567 0.16451 -0.115222
+v 0.351826 0.154272 -0.129904
+v 0.339174 0.156032 -0.131793
+v -0.727924 -0.411255 -0.141761
+v -0.735836 -0.39322 -0.141928
+v -0.723325 -0.394094 -0.154709
+v -0.5838 0.540132 -0.167516
+v -0.859216 0.477974 0.072987
+v 0.646883 0.0495828 0.00890179
+v 0.646883 0.0400902 -0.00637127
+v 0.635849 0.0575341 0.000809254
+v 0.89725 -0.820249 0.189353
+v 0.650865 -0.428506 -0.195904
+v -0.576966 0.0423895 -0.158472
+v -0.593151 0.0374184 -0.152987
+v -0.591866 0.0528584 -0.143264
+v -0.940912 0.12591 0.0750037
+v 0.725624 -0.16862 -0.0672965
+v 0.241357 -0.12063 -0.271948
+v 0.254061 -0.122351 -0.270265
+v 0.252815 -0.137702 -0.279629
+v 0.550671 -0.836113 -0.117509
+v 0.131851 -0.969447 -0.292847
+v 0.133366 -0.980327 -0.273425
+v 0.476169 -0.919826 -0.117689
+v -0.956814 0.479181 0.227169
+v 0.635348 -0.201735 -0.185229
+v 0.646305 -0.207336 -0.179372
+v 0.635245 -0.214953 -0.196995
+v -0.541718 0.231536 -0.0725246
+v -0.541821 0.212641 -0.0767763
+v 0.474165 -0.935844 0.536381
+v -0.518494 -0.797192 0.439361
+v -0.520048 -0.796986 0.452167
+v 0.945536 -0.743576 0.291884
+v 0.687757 -0.370959 -0.182609
+v -0.509605 -0.756986 0.119859
+v 0.553883 -0.547325 -0.278011
+v 0.565058 -0.544217 -0.271781
+v 0.677711 -0.389636 -0.1823
+v 0.66276 -0.427196 -0.182223
+v 0.566779 -0.529406 -0.274889
+v 0.733422 -0.313374 -0.131446
+v 0.730634 -0.295609 -0.13169
+v 0.738418 -0.295005 -0.118626
+v -0.612342 -0.938927 -0.0784976
+v -0.599933 -0.956551 -0.086102
+v -0.903904 -0.206128 0.076802
+v -0.167393 -0.0741045 -0.270291
+v -0.589079 0.52017 -0.0903795
+v -0.586985 0.500299 -0.0775342
+v -0.983044 0.110919 0.331781
+v -0.584994 0.480337 -0.0775599
+v -0.971522 0.0943487 0.537434
+v -0.967784 0.0937835 0.548982
+v -0.972383 0.111369 0.551102
+v -0.59378 0.535906 -0.0808226
+v -0.234998 0.707121 -0.169892
+v -0.596041 -0.842729 0.491153
+v -0.594512 -0.842844 0.504216
+v -0.617544 0.0650486 -0.120438
+v -0.617416 0.0828907 -0.1088
+v -0.604802 0.0834687 -0.11264
+v -0.586433 0.460337 -0.077637
+v -0.181588 -0.978324 0.230111
+v -0.175152 -0.974611 0.251215
+v -0.183193 -0.973622 0.271819
+v -0.190232 -0.978388 0.251511
+v -0.972717 0.0863204 0.320734
+v -0.135601 -0.926608 0.355057
+v -0.14205 -0.930295 0.333914
+v -0.9893 0.128222 0.331781
+v -0.982094 0.232192 0.202802
+v 0.698007 -0.587107 -0.131407
+v 0.702066 -0.605065 -0.119076
+v -0.90086 0.425552 0.137329
+v -0.984701 0.161954 0.177496
+v 0.594371 -0.759864 -0.182596
+v 0.5894 -0.760313 -0.195454
+v 0.585893 -0.778977 -0.182365
+v 0.29049 0.230445 -0.0315481
+v 0.303656 0.229289 -0.0305718
+v 0.293727 0.221157 -0.0466927
+v 0.638122 -0.288518 -0.222866
+v 0.627281 -0.282699 -0.228749
+v 0.641359 -0.268993 -0.217509
+v 0.295243 0.201106 -0.0773544
+v 0.308409 0.200387 -0.0765837
+v 0.295538 0.189365 -0.0900841
+v -0.16995 0.187349 0.0388056
+v -0.155846 0.182493 0.0267311
+v -0.978805 0.163662 0.524191
+v -0.444184 -0.709947 0.288878
+v -0.450684 -0.691552 0.278396
+v -0.438725 -0.712105 0.265744
+v 0.541282 -0.565489 -0.279706
+v 0.640961 -0.646568 -0.182686
+v -0.447215 -0.682984 0.398859
+v -0.453009 -0.666003 0.386142
+v -0.906897 0.0379579 0.0881316
+v 0.720114 -0.476766 -0.119371
+v 0.710621 -0.477781 -0.131061
+v -0.274472 -0.86111 -0.318486
+v -0.25672 -0.841303 -0.314543
+v -0.255654 -0.853596 -0.328621
+v 0.679343 -0.189661 -0.132319
+v 0.671186 -0.17485 -0.137329
+v -0.992807 0.145524 0.331807
+v -0.424826 -0.753248 0.233617
+v -0.583979 0.560081 -0.167554
+v -0.52877 -0.944258 0.615842
+v -0.527499 -0.955408 0.611449
+v -0.588732 0.61931 -0.488982
+v -0.58371 0.639876 -0.488995
+v -0.581988 0.660197 -0.488905
+v -0.582181 0.680518 -0.488841
+v 0.119057 -0.969332 -0.294453
+v 0.120521 -0.979826 -0.276431
+v -0.56606 0.760557 -0.747031
+v -0.961477 0.233219 0.45963
+v -0.95463 0.250907 0.459541
+v -0.586381 0.579824 -0.167721
+v -0.952794 0.25092 0.498038
+v 0.109358 -0.966493 -0.29566
+v 0.106584 -0.981394 -0.277677
+v 0.763467 -0.292937 -0.0676819
+v 0.763505 -0.274812 -0.0677076
+v 0.184581 -0.241003 -0.429226
+v -0.994194 0.162904 0.331666
+v 0.133366 0.154169 -0.127721
+v 0.47902 -0.844925 -0.246977
+v 0.482245 -0.934996 0.52387
+v 0.465327 -0.942293 0.538693
+v 0.0979904 0.803242 -0.334376
+v 0.676106 -0.516702 -0.170881
+v -0.973577 0.267336 0.20257
+v 0.678662 -0.534647 -0.1702
+v 0.668039 -0.408673 -0.182455
+v 0.679857 -0.407825 -0.169918
+v 0.690403 -0.388416 -0.169314
+v 0.700743 -0.387864 -0.156892
+v -0.150129 -0.929319 0.354453
+v 0.740063 -0.312809 -0.118716
+v -0.0123122 -0.983128 -0.299373
+v -0.0262622 -0.984708 -0.300657
+v -0.0472257 -0.922164 -0.0031471
+v -0.0606234 -0.922742 -0.00526657
+v 0.390516 -0.97343 -0.206411
+v 0.405558 -0.968792 -0.207079
+v -0.204953 -0.293541 -0.306553
+v -0.205069 -0.275647 -0.301582
+v -0.869556 0.33516 0.0239179
+v -0.855786 0.334877 0.011047
+v -0.862453 0.317459 0.0105331
+v -0.573228 0.821752 -0.732966
+v -0.573754 0.801148 -0.720017
+v -0.580331 0.841534 -0.720197
+v -0.575784 0.821521 -0.720017
+v 0.465032 -0.938465 -0.104509
+v 0.466959 -0.938477 -0.0917668
+v 0.479213 -0.919351 -0.10483
+v 0.484839 -0.917989 -0.091831
+v 0.49342 -0.898952 -0.104856
+v 0.498455 -0.898554 -0.0920879
+v 0.502001 -0.879967 -0.105152
+v 0.507344 -0.879839 -0.0926788
+v 0.732394 -0.547942 -0.0930642
+v 0.740101 -0.547145 -0.0799877
+v 0.735335 -0.565604 -0.080039
+v 0.727718 -0.56649 -0.0931284
+v 0.735965 -0.529663 -0.0932055
+v 0.743531 -0.528879 -0.0801033
+v -0.19099 -0.933326 0.418821
+v 0.309527 0.252449 0.0218755
+v -0.592804 -0.97569 0.235043
+v -0.581115 -0.978272 0.239719
+v -0.593523 -0.970745 0.247529
+v -0.913397 -0.101041 0.127644
+v -0.600871 0.503895 -0.313297
+v -0.959255 0.391204 0.26609
+v -0.583363 0.539901 -0.231729
+v 0.683017 -0.642522 -0.131061
+v 0.688412 -0.62414 -0.131472
+v 0.693023 -0.605579 -0.131305
+v -0.980154 0.111754 0.511667
+v 0.474203 -0.901419 -0.182018
+v -0.952087 0.496599 0.201556
+v 0.497364 -0.862189 -0.182249
+v 0.571918 -0.79795 -0.181877
+v -0.944226 0.0738605 0.100681
+v -0.956943 0.444524 0.342905
+v -0.955131 0.45683 0.344896
+v -0.958587 0.462122 0.329957
+v 0.72276 -0.494685 -0.118896
+v 0.712766 -0.495559 -0.131549
+v -0.118774 -0.966442 0.642933
+v -0.131542 -0.965915 0.639747
+v 0.0630768 -0.161864 -0.357639
+v 0.0653248 -0.170136 -0.374517
+v 0.0511692 -0.171305 -0.373374
+v -0.00185615 0.981882 -0.276097
+v 0.311325 -0.968677 -0.257767
+v 0.319893 -0.975279 -0.242532
+v 0.305699 -0.977 -0.243457
+v -0.587961 -0.93754 0.256932
+v -0.594461 -0.956191 0.263213
+v -0.579599 -0.937591 0.266733
+v -0.775117 -0.0374697 0.465437
+v -0.784944 -0.0314967 0.458372
+v -0.786498 -0.050238 0.448198
+v 0.582977 -0.761007 -0.208402
+v 0.589618 -0.742086 -0.208518
+v -0.0900776 -0.184356 -0.309058
+v -0.0745091 -0.179988 -0.313515
+v -0.0863011 -0.189841 -0.329212
+v -0.58344 0.539811 -0.270304
+v -0.578096 0.559978 -0.270291
+v -0.688681 0.519348 -0.538488
+v -0.582297 0.640351 -0.270394
+v -0.576876 0.620171 -0.270406
+v 0.712458 -0.0112653 0.162108
+v -0.92894 0.409688 0.445796
+v 0.355397 -0.949049 -0.270098
+v 0.363015 -0.933622 -0.272269
+v 0.365365 -0.957861 -0.257471
+v -0.974592 0.0940918 0.486066
+v 0.0985555 0.783794 -0.27232
+v 0.760872 -0.25679 -0.0679002
+v -0.913937 -0.222879 0.1023
+v 0.714526 -0.513452 -0.131651
+v 0.714757 -0.531538 -0.131831
+v -0.812446 -0.465398 0.288891
+v 0.40462 0.200926 -0.0262558
+v 0.405982 0.190945 -0.0409765
+v 0.392944 0.204549 -0.0302892
+v 0.542129 -0.969126 0.0866929
+v 0.0519785 -0.91858 -0.177702
+v 0.0391332 -0.918105 -0.180669
+v -0.257349 -0.971182 0.528019
+v -0.270567 -0.964669 0.564512
+v -0.28408 -0.964104 0.561918
+v 0.48999 -0.933879 0.511102
+v 0.472251 -0.94544 0.519734
+v -0.520228 -0.869614 0.247323
+v -0.535231 -0.871618 0.238961
+v 0.72714 -0.27778 -0.131497
+v 0.735567 -0.277035 -0.118845
+v -0.88402 -0.346232 0.0773544
+v 0.674629 -0.426297 -0.169661
+v 0.25961 -0.240695 -0.402944
+v 0.24751 -0.237754 -0.406194
+v 0.24968 -0.220258 -0.398397
+v -0.244594 -0.0207965 -0.236148
+v -0.624956 -0.939441 -0.0745156
+v -0.280766 -0.559426 -0.169699
+v 0.523851 -0.858438 -0.10483
+v 0.53324 -0.856961 -0.0917283
+v 0.718906 -0.603151 -0.092743
+v 0.723916 -0.584679 -0.0928458
+v 0.724057 -0.602753 -0.0800134
+v 0.559496 -0.836139 -0.0919466
+v 0.730352 -0.584063 -0.0799748
+v -0.0959736 -0.923731 0.08212
+v -0.109346 -0.924322 0.079962
+v -0.100123 -0.923256 0.0575598
+v -0.94551 0.248839 0.100142
+v -0.887 -0.0149776 0.126886
+v 0.673151 -0.661404 -0.130958
+v 0.660075 -0.680492 -0.130906
+v 0.632702 -0.719517 -0.130996
+v 0.64827 -0.699414 -0.13056
+v 0.639432 -0.719041 -0.118267
+v -0.886396 -0.379527 0.257253
+v 0.486946 -0.881316 -0.181928
+v -0.778534 0.69046 -0.275082
+v -0.203026 -0.691103 -0.12668
+v -0.195075 -0.703858 -0.139885
+v -0.202936 -0.709549 -0.125036
+v -0.909633 0.443433 0.137625
+v -0.922453 -0.152769 0.114978
+v -0.950494 0.0514968 0.492643
+v -0.955594 0.0584718 0.510613
+v -0.58755 0.520145 -0.103276
+v 0.751174 -0.329777 -0.0929229
+v 0.756145 -0.329431 -0.080129
+v 0.753576 -0.347748 -0.080373
+v 0.748104 -0.348056 -0.0929614
+v 0.617531 -0.757706 -0.118652
+v 0.622836 -0.756511 -0.105164
+v 0.373239 -0.970334 -0.233861
+v 0.629413 -0.895253 0.367465
+v 0.613177 -0.901008 0.369315
+v -0.590954 0.619297 -0.501789
+v -0.585585 0.63976 -0.50175
+v -0.583735 0.660133 -0.50175
+v -0.582541 0.680428 -0.501673
+v -0.585148 0.70048 -0.501699
+v 0.0982216 0.803139 -0.285268
+v -0.590351 0.660081 -0.283354
+v -0.596529 0.669908 -0.286232
+v -0.989801 0.110482 0.28049
+v -0.895401 0.354016 0.0608996
+v -0.888207 0.389598 0.0734237
+v -0.890879 0.371679 0.0608739
+v -0.993282 0.180245 0.331691
+v -0.896377 -0.327067 0.269944
+v -0.898162 -0.327131 0.257124
+v -0.890866 -0.361878 0.257137
+v 0.760294 -0.473426 -0.0546696
+v 0.75477 -0.47394 -0.0671809
+v 0.759189 -0.455494 -0.0549393
+v -0.991882 0.197908 0.331576
+v -0.902106 -0.118986 0.0888124
+v -0.574744 0.580055 -0.270329
+v -0.528269 -0.644474 0.0098395
+v -0.533921 -0.646221 0.0229289
+v -0.544056 -0.640184 0.013038
+v 0.373715 -0.952029 -0.259334
+v 0.494884 -0.933391 0.498372
+v 0.512559 -0.914367 0.49886
+v -0.797828 0.77908 -0.481133
+v -0.795567 0.769279 -0.457074
+v -0.80145 0.761328 -0.468108
+v 0.495886 -0.826325 -0.222622
+v 0.504017 -0.806916 -0.237073
+v 0.516811 -0.803589 -0.233142
+v -0.269295 -0.97447 0.415327
+v -0.282012 -0.97393 0.412154
+v 0.731238 -0.259013 -0.119256
+v 0.717994 -0.278319 -0.144818
+v 0.706549 -0.27548 -0.158614
+v 0.707821 -0.260027 -0.14916
+v 0.722387 -0.259976 -0.131536
+v -0.623106 -0.825285 0.0798335
+v -0.188961 -0.72242 -0.152294
+v -0.187265 -0.740544 -0.15223
+v -0.205711 -0.129712 -0.270162
+v -0.965523 0.0765066 0.460491
+v -0.952935 0.195968 0.10027
+v -0.894707 -0.0672323 0.101902
+v 0.714128 -0.621674 -0.0927687
+v 0.718148 -0.621507 -0.0802317
+v 0.580729 -0.815702 -0.0920751
+v 0.712291 -0.639734 -0.0798207
+v 0.698662 -0.658707 -0.092332
+v 0.707204 -0.64012 -0.0925247
+v 0.703865 -0.65845 -0.0796408
+v 0.718508 -0.36839 -0.144073
+v 0.71134 -0.386605 -0.14361
+v 0.454589 -0.927495 0.563138
+v -0.893744 -0.344267 0.257034
+v 0.621128 -0.739594 -0.1316
+v 0.628386 -0.738412 -0.118395
+v -0.520896 -0.492617 0.532181
+v 0.613382 -0.757706 -0.130996
+v 0.602798 -0.776498 -0.130727
+v 0.722901 -0.530819 -0.118935
+v 0.724443 -0.512604 -0.118896
+v -0.591391 0.539965 -0.103328
+v 0.757943 -0.311331 -0.0802189
+v -0.436451 -0.771129 0.210136
+v 0.749825 -0.36595 -0.0801033
+v 0.635168 -0.737911 -0.105742
+v -0.514229 -0.954996 0.614121
+v -0.514897 -0.944296 0.619182
+v -0.574936 0.600042 -0.270394
+v -0.426213 -0.735072 0.219565
+v -0.433394 -0.73556 0.206128
+v -0.280907 -0.540273 -0.179385
+v -0.617416 -0.0261016 -0.162609
+v -0.61703 -0.00809254 -0.157111
+v -0.60448 -0.00734751 -0.165743
+v 0.292198 -0.977643 -0.245345
+v -0.573523 0.599978 -0.283277
+v -0.574769 0.580004 -0.283175
+v -0.575489 0.620068 -0.283303
+v -0.123681 -0.926994 0.149314
+v 0.132107 -0.921445 0.289379
+v 0.119288 -0.920982 0.286335
+v 0.12738 -0.921997 0.265654
+v -0.898702 -0.32726 0.141542
+v -0.220162 -0.967829 0.577974
+v -0.228396 -0.967636 0.598488
+v -0.233945 -0.969332 0.576291
+v -0.578225 0.559939 -0.283149
+v -0.856634 0.00213232 0.371268
+v -0.845086 0.00134876 0.38455
+v -0.861271 0.0108414 0.381454
+v -0.592894 0.619272 -0.514595
+v -0.273881 -0.955189 0.578
+v -0.988927 0.215531 0.33146
+v 0.448436 -0.284767 -0.330176
+v 0.459367 -0.289803 -0.324691
+v 0.446303 -0.301633 -0.338165
+v -0.587563 0.639709 -0.514583
+v 0.49974 -0.932838 0.485642
+v 0.517569 -0.91402 0.486092
+v 0.482039 -0.943256 0.496612
+v 0.533921 -0.893917 0.486053
+v -0.971535 0.198254 0.485527
+v -0.950713 0.268505 0.433773
+v -0.506394 -0.853043 0.234427
+v -0.475668 -0.838104 0.234362
+v 0.686909 -0.152833 -0.118922
+v 0.59748 -0.796229 -0.0925632
+v 0.644494 -0.736716 -0.0926788
+v 0.629182 -0.755753 -0.0920366
+v -0.907758 -0.083777 0.127413
+v -0.944662 0.26654 0.0997951
+v -0.933102 0.356573 0.420452
+v -0.954862 0.268338 0.408082
+v -0.946474 0.286026 0.407992
+v -0.948208 0.231164 0.100347
+v -0.353573 -0.944296 -0.279026
+v -0.353265 -0.96386 -0.293322
+v -0.359778 -0.963616 -0.281004
+v -0.427845 -0.752901 0.246386
+v 0.586035 -0.79741 -0.130932
+v 0.570697 -0.816588 -0.130675
+v -0.435102 -0.716973 0.207285
+v 0.00472065 -0.916846 -0.164651
+v -0.00811181 -0.916371 -0.167695
+v -0.00105974 -0.919788 -0.187117
+v 0.744366 -0.366232 -0.0928073
+v 0.746087 -0.384241 -0.0797821
+v 0.650133 -0.717461 -0.104997
+v -0.960013 0.408558 0.227362
+v -0.959653 0.42622 0.22749
+v -0.575733 0.475032 -0.0316123
+v -0.569593 0.46428 -0.0310728
+v -0.585392 0.660017 -0.514634
+v -0.582708 0.680338 -0.514531
+v -0.584891 0.700518 -0.514531
+v 0.278685 -0.978298 -0.247246
+v -0.984393 0.233091 0.331306
+v 0.137952 -0.979377 -0.249173
+v 0.129693 -0.977951 -0.227953
+v 0.125107 -0.978889 -0.252179
+v 0.482245 0.0400388 -0.161221
+v 0.493793 0.0360824 -0.156867
+v 0.480716 0.0244831 -0.169943
+v 0.406072 -0.208569 -0.306964
+v 0.406149 -0.221132 -0.319347
+v 0.39473 -0.204202 -0.311498
+v -0.978792 0.250753 0.331267
+v 0.186392 -0.97921 -0.264125
+v 0.23934 -0.978092 -0.254774
+v 0.252262 -0.978516 -0.251935
+v 0.301164 -0.212911 -0.379874
+v 0.30092 -0.200207 -0.367209
+v 0.450594 -0.267208 -0.322481
+v 0.437402 -0.279141 -0.335802
+v 0.532097 -0.692952 -0.285525
+v -0.928362 0.478821 0.150752
+v -0.0701674 -0.184613 -0.334569
+v -0.324864 0.230303 0.0192808
+v -0.311466 0.230008 0.0241363
+v 0.299289 -0.910539 0.406682
+v 0.300278 -0.227644 -0.390369
+v -0.0561018 -0.354877 0.743512
+v -0.0547145 -0.372796 0.742677
+v 0.537389 -0.893763 0.473285
+v -0.587859 0.620055 -0.218987
+v -0.591597 0.619978 -0.206167
+v -0.580511 0.599978 -0.218987
+v 0.770159 -0.27381 0.355995
+v -0.0177843 0.629908 -0.105524
+v 0.639407 -0.483728 -0.208659
+v 0.638456 -0.465796 -0.20916
+v 0.638829 -0.519965 -0.208081
+v -0.578482 0.600055 -0.231845
+v -0.924791 0.33769 0.534788
+v -0.500832 -0.260978 -0.263149
+v -0.487794 -0.26076 -0.266077
+v -0.487794 -0.279514 -0.263264
+v -0.532483 0.61457 0.0662304
+v -0.544493 0.597666 0.0670525
+v -0.539111 0.60617 0.0878233
+v 0.67617 -0.696934 -0.0922035
+v 0.696607 -0.693736 -0.0591012
+v 0.683929 -0.711231 -0.0669625
+v 0.683325 -0.696742 -0.0797436
+v 0.686639 -0.678399 -0.0927174
+v 0.0446952 0.927983 -0.345282
+v -0.122191 -0.923859 0.0769433
+v -0.112942 -0.922793 0.054554
+v 0.715464 -0.168941 -0.0809639
+v 0.713601 -0.150907 -0.0808098
+v -0.227458 0.544345 -0.0522547
+v 0.758508 -0.293335 -0.0804501
+v 0.756903 -0.257201 -0.0804758
+v 0.752111 -0.239424 -0.0805015
+v -0.215551 -0.747327 -0.111998
+v -0.228396 -0.747404 -0.11196
+v -0.882504 -0.0153244 0.113976
+v -0.972537 0.268184 0.331062
+v 0.738804 -0.384922 -0.0931156
+v 0.743402 -0.40261 -0.0800134
+v 0.497492 -0.177252 -0.263033
+v 0.4857 -0.173514 -0.266758
+v 0.172365 -0.980777 -0.265371
+v -0.606703 0.692773 -0.308274
+v -0.581808 0.640544 -0.283136
+v -0.370234 -0.942382 -0.253566
+v -0.371993 -0.96097 -0.254273
+v -0.375063 -0.960456 -0.241196
+v -0.334074 0.232757 0.0258704
+v -0.360086 0.235724 0.0231215
+v -0.342321 0.234761 0.0316893
+v -0.594731 0.619118 -0.527441
+v -0.589259 0.639555 -0.527428
+v -0.584506 0.660017 -0.527389
+v 0.473587 -0.937732 -0.0661019
+v 0.478507 -0.937206 -0.0532694
+v 0.614962 -0.175634 -0.187439
+v 0.614037 -0.190072 -0.197715
+v 0.603401 -0.184202 -0.20397
+v -0.518648 -0.775214 0.111138
+v 0.60466 -0.169545 -0.194092
+v -0.583966 0.680351 -0.527377
+v -0.621899 -0.926043 0.362944
+v -0.621552 -0.904335 0.390163
+v -0.607756 -0.911682 0.35832
+v -0.584686 0.700557 -0.527377
+v -0.280997 -0.521301 -0.187464
+v 0.889235 -0.613247 -0.0125499
+v 0.877122 -0.610319 -0.015697
+v 0.430902 -0.200374 -0.29006
+v 0.418596 -0.197805 -0.292642
+v 0.419919 -0.182172 -0.283765
+v -0.894001 -0.34505 0.141709
+v -0.958176 0.126513 0.11363
+v -0.589773 0.720942 -0.527274
+v 0.527293 -0.913018 0.46035
+v 0.49238 -0.940019 0.472656
+v 0.543812 -0.893121 0.460401
+v -0.893397 -0.362263 0.141928
+v -0.0430896 -0.235287 -0.436779
+v -0.0443099 -0.250984 -0.446477
+v -0.0578488 -0.237253 -0.43525
+v 0.169834 -0.00944129 -0.261338
+v 0.15731 -0.00741174 -0.263701
+v 0.158569 0.00792555 -0.254478
+v -0.222654 -0.0333335 -0.235853
+v 0.905497 -0.502585 0.0811052
+v 0.918098 -0.504229 0.0829678
+v 0.906332 -0.513658 0.066924
+v -0.0919017 0.0611179 -0.181247
+v -0.0921072 0.0475148 -0.192615
+v -0.967052 0.0765965 0.473324
+v 0.671751 -0.0808098 -0.108376
+v 0.660512 -0.0885298 -0.125871
+v -0.90208 -0.281941 0.332308
+v -0.932447 0.356778 0.497306
+v 0.401178 -0.934996 -0.253605
+v 0.415244 -0.926095 -0.246912
+v 0.517492 -0.920366 -0.0311884
+v -0.203219 -0.653299 -0.141324
+v -0.719767 0.509419 -0.468031
+v -0.722747 0.527608 -0.466901
+v -0.719844 0.527479 -0.47981
+v 0.715656 -0.585424 -0.105588
+v 0.711251 -0.603999 -0.105845
+v 0.279918 0.260515 0.0393451
+v 0.266277 0.26076 0.0394864
+v 0.670236 -0.728739 -0.0703152
+v 0.423259 -0.163765 -0.276816
+v 0.436824 -0.163623 -0.274684
+v 0.436914 -0.181633 -0.281068
+v 0.195949 0.00125884 -0.247208
+v 0.207664 -0.00236353 -0.243483
+v 0.19406 -0.0151446 -0.255236
+v -0.951291 0.213617 0.100322
+v -0.226058 0.199218 -0.00106616
+v -0.238068 0.202622 -0.0054721
+v -0.240817 0.209378 0.0123315
+v 0.758714 -0.275172 -0.0805657
+v -0.221459 0.630897 -0.144381
+v -0.962543 0.285834 0.330985
+v -0.819498 -0.471859 0.258036
+v -0.952113 0.303226 0.330818
+v -0.940899 0.320888 0.330792
+v -0.934643 0.338397 0.330599
+v 0.761707 -0.329045 -0.0675663
+v 0.759433 -0.347144 -0.0672708
+v 0.733344 -0.403394 -0.0926788
+v -0.934373 0.35611 0.330407
+v 0.741874 -0.420863 -0.080039
+v -0.43807 -0.966018 0.596086
+v -0.337555 0.629484 -0.107913
+v -0.337786 0.648662 -0.109789
+v -0.324736 0.629407 -0.113116
+v 0.627949 -0.629676 -0.208492
+v 0.530389 -0.921676 -0.0190624
+v -0.800962 0.0793069 0.655329
+v 0.401525 -0.916114 -0.260901
+v 0.422501 -0.904476 -0.256071
+v -0.398904 -0.498886 0.541494
+v -0.59834 0.740596 -0.527402
+v 0.714141 -0.023083 0.073231
+v 0.708913 -0.0126398 0.086603
+v 0.716838 -0.0241363 0.0894161
+v -0.911676 -0.0661533 0.178691
+v 0.0530061 -0.130149 -0.288159
+v 0.0378101 -0.133116 -0.285243
+v 0.0457485 -0.105177 -0.288081
+v 0.183078 -0.966801 -0.28523
+v 0.435552 -0.295776 -0.344241
+v -0.0233335 -0.00269751 -0.242725
+v -0.0241042 -0.0170586 -0.253258
+v -0.0370009 -0.00235069 -0.243239
+v -0.779472 0.654982 -0.223315
+v -0.777584 0.654995 -0.210496
+v -0.776209 0.662612 -0.218794
+v 0.693203 -0.298486 -0.183123
+v 0.696979 -0.31638 -0.182121
+v 0.680409 -0.312128 -0.197394
+v 0.172031 0.0207452 -0.242545
+v 0.171234 0.00616574 -0.252628
+v 0.159352 0.0224407 -0.244356
+v 0.0968086 -0.921689 0.166077
+v 0.753614 -0.907109 0.192101
+v 0.742824 -0.910719 0.217124
+v 0.735721 -0.91524 0.196572
+v -0.957084 0.0917411 0.113591
+v -0.582053 0.540068 -0.218922
+v 0.537467 -0.606863 -0.2832
+v 0.540665 -0.585925 -0.276277
+v 0.550736 -0.593902 -0.270137
+v 0.735477 -0.583677 -0.0672323
+v 0.739061 -0.583446 -0.0545283
+v 0.73382 -0.601841 -0.0543099
+v -0.578289 0.560106 -0.218948
+v -0.270927 -0.953288 -0.36225
+v -0.281074 -0.502482 -0.197625
+v 0.632869 -0.611102 -0.208543
+v 0.523761 -0.693672 -0.298306
+v 0.525687 -0.711771 -0.285538
+v 0.516272 -0.709266 -0.300721
+v 0.0631154 0.931477 -0.317921
+v -0.596504 0.619028 -0.540325
+v 0.0528006 -0.14361 -0.299706
+v -0.58949 0.639567 -0.540273
+v -0.585675 0.659901 -0.540248
+v -0.584095 0.680236 -0.540248
+v -0.584467 0.700557 -0.540196
+v -0.588038 0.720891 -0.540119
+v 0.528115 -0.674121 -0.298101
+v -0.22837 0.0342969 -0.204022
+v 0.212532 0.187053 -0.0866929
+v 0.2267 0.188017 -0.0879261
+v 0.213315 0.175685 -0.100052
+v 0.585701 -0.724128 -0.221119
+v 0.583324 -0.706324 -0.221813
+v 0.58204 -0.688469 -0.222147
+v -0.90587 0.00420041 0.165614
+v 0.732253 -0.493889 -0.105832
+v 0.729645 -0.476021 -0.106295
+v 0.723248 -0.440465 -0.10641
+v 0.726241 -0.458256 -0.106205
+v 0.721026 -0.567043 -0.105884
+v 0.726087 -0.548571 -0.105999
+v 0.588616 -0.81461 -0.0786903
+v 0.519509 0.0843165 -0.106012
+v 0.519496 0.071741 -0.118228
+v 0.508269 0.0889794 -0.111099
+v 0.320317 0.0310599 -0.228158
+v 0.307664 0.0185871 -0.234362
+v 0.307613 0.032794 -0.229867
+v 0.0343547 0.952916 -0.291832
+v 0.116873 -0.97745 -0.230907
+v 0.0560248 -0.960212 -0.210676
+v 0.04264 -0.960713 -0.212782
+v -0.461397 -0.839838 0.259745
+v -0.497209 -0.607261 0.410099
+v -0.509515 -0.60608 0.406348
+v -0.496606 -0.613735 0.397112
+v 0.721617 -0.150393 -0.0678746
+v 0.718277 -0.132435 -0.067836
+v 0.745856 -0.510755 -0.0804501
+v 0.747436 -0.492604 -0.0804373
+v 0.752343 -0.51019 -0.0675534
+v 0.746999 -0.47457 -0.080206
+v 0.754064 -0.492026 -0.0676562
+v 0.752651 -0.401839 -0.0668983
+v 0.745291 -0.456715 -0.0801547
+v 0.753165 -0.456059 -0.0671681
+v 0.743672 -0.438795 -0.080129
+v 0.752548 -0.438076 -0.0667699
+v 0.75504 -0.383663 -0.0673736
+v 0.756415 -0.365474 -0.0673094
+v 0.763081 -0.310933 -0.0674763
+v -0.936107 0.373811 0.330381
+v 0.731019 -0.421788 -0.093244
+v 0.732561 -0.439746 -0.0932569
+v -0.94122 0.39173 0.330201
+v -0.974052 0.180862 0.536818
+v -0.975928 0.180926 0.524101
+v 0.537261 -0.674365 -0.285898
+v -0.263104 -0.959056 0.583896
+v 0.0520941 -0.910436 0.494595
+v 0.0386708 -0.91104 0.492373
+v -0.258364 -0.96621 0.568469
+v 0.458134 -0.0702381 -0.222532
+v 0.470363 -0.0729356 -0.219655
+v 0.458494 -0.0822228 -0.23539
+v 0.535681 0.139192 -0.010957
+v 0.5373 0.129686 -0.0265384
+v -0.870866 0.00124599 0.0749523
+v -0.974952 0.19792 0.395635
+v -0.978022 0.197908 0.38279
+v -0.11826 0.0889665 -0.159038
+v -0.11898 0.0744385 -0.169442
+v -0.131876 0.0888381 -0.158794
+v -0.564377 0.461159 -0.0267182
+v -0.429515 -0.788804 0.246643
+v -0.576645 0.580106 -0.218935
+v -0.948978 0.409264 0.330188
+v -0.643736 0.652811 -0.710705
+v -0.281203 -0.483741 -0.20397
+v 0.591969 -0.596574 -0.236289
+v 0.486394 -0.843975 -0.233438
+v 0.491519 -0.843551 -0.220657
+v 0.487267 -0.862857 -0.220862
+v 0.173212 0.138793 -0.137226
+v 0.186828 0.138524 -0.137085
+v 0.173418 0.126295 -0.149596
+v 0.435809 -0.904964 -0.246154
+v -0.664828 -0.598154 0.0218242
+v -0.646163 -0.607814 0.0154015
+v -0.655463 -0.605425 0.0310599
+v -0.592509 0.639246 -0.553208
+v -0.586985 0.659824 -0.55317
+v 0.0556137 -0.928278 -0.192089
+v 0.810725 -0.419296 0.232166
+v 0.810005 -0.436393 0.25056
+v 0.587794 -0.669767 -0.221607
+v 0.619779 -0.521648 -0.221466
+v 0.62931 -0.484563 -0.22126
+v 0.625585 -0.502893 -0.220746
+v -0.906422 0.00389213 0.178306
+v 0.731289 -0.512039 -0.106231
+v 0.729478 -0.530267 -0.106102
+v 0.738778 -0.475302 -0.0929871
+v 0.738996 -0.51132 -0.0931284
+v 0.621719 -0.775316 -0.0797179
+v 0.613601 -0.7761 -0.0925247
+v 0.632496 -0.76549 -0.0762112
+v 0.606343 -0.794353 -0.0785361
+v -0.0775149 -0.921946 -0.0331922
+v -0.0909254 -0.922536 -0.0353631
+v -0.0810089 -0.920584 -0.05887
+v -0.198826 -0.978452 0.272963
+v 0.756646 -0.239192 -0.0675406
+v -0.882517 -0.0502123 0.077136
+v -0.887694 -0.067592 0.0760056
+v 0.702631 -0.0966737 -0.0681186
+v 0.71617 -0.639632 -0.067258
+v 0.721373 -0.639259 -0.0544641
+v 0.714051 -0.657782 -0.0537704
+v 0.722554 -0.620955 -0.0672194
+v 0.72723 -0.620466 -0.0542072
+v 0.0286257 -0.929537 -0.32252
+v 0.022049 -0.936255 -0.322789
+v 0.542039 -0.749279 -0.258178
+v 0.503054 -0.897886 -0.0792555
+v 0.749915 -0.528289 -0.0672194
+v 0.486882 -0.918118 -0.0791142
+v 0.745098 -0.546722 -0.0672323
+v 0.740371 -0.565206 -0.0672451
+v 0.728977 -0.602316 -0.0672194
+v 0.619676 -0.783987 -0.0745027
+v 0.139943 -0.144368 -0.323868
+v 0.154073 -0.143585 -0.324858
+v 0.142191 -0.153386 -0.340465
+v -0.959422 0.479245 0.240014
+v -0.957122 0.461609 0.240027
+v -0.955106 0.426811 0.330086
+v 0.026776 -0.915664 -0.113385
+v -0.589323 -0.823422 0.128376
+v -0.446355 -0.823127 0.246887
+v -0.434139 -0.806351 0.24672
+v -0.585469 0.680197 -0.553106
+v -0.584365 0.700493 -0.553054
+v -0.586407 0.720788 -0.553029
+v 0.501718 0.152525 -0.0255365
+v 0.490222 0.156648 -0.0298011
+v 0.488603 0.166192 -0.0148492
+v 0.430118 -0.924772 -0.234016
+v 0.442784 -0.923063 -0.220605
+v -0.453895 -0.822574 0.234028
+v 0.0382212 -0.145974 -0.297214
+v 0.256167 0.0186514 -0.240772
+v 0.25636 0.0381634 -0.237086
+v 0.269372 0.0377909 -0.236752
+v 0.672265 -0.0673607 -0.0970334
+v 0.661475 -0.0740403 -0.115659
+v 0.333046 -0.954752 -0.0884913
+v 0.323143 -0.956551 -0.0647531
+v 0.318313 -0.941445 -0.0795766
+v 0.468012 -0.882716 -0.233001
+v 0.475115 -0.882318 -0.22049
+v 0.457774 -0.903268 -0.220836
+v 0.481525 -0.863024 -0.233386
+v 0.898985 -0.633414 -0.0172512
+v 0.887552 -0.630062 -0.0214773
+v -0.281177 -0.465462 -0.208197
+v 0.620062 -0.611873 -0.219757
+v -0.281293 -0.446631 -0.212204
+v -0.244093 -0.970706 0.530434
+v -0.251774 -0.969473 0.550164
+v -0.508834 -0.640646 -0.0250483
+v -0.524249 -0.62793 -0.0280541
+v 0.0476496 -0.963076 0.654185
+v 0.0331344 -0.965016 0.652413
+v -0.594435 0.639259 -0.565977
+v -0.588552 0.659696 -0.565938
+v -0.585816 0.68012 -0.565925
+v -0.584467 0.700441 -0.565887
+v 0.632201 -0.466169 -0.221003
+v 0.63283 -0.448095 -0.221504
+v 0.635977 -0.429714 -0.22144
+v 0.637737 -0.411473 -0.221607
+v -0.958034 0.444434 0.330009
+v 0.740165 -0.493195 -0.092833
+v -0.890725 -0.0673864 0.0888509
+v -0.89007 -0.0850359 0.0762882
+v -0.584596 0.460465 -0.0649073
+v 0.749915 -0.221671 -0.0673993
+v -0.238287 -0.80418 -0.245461
+v -0.204221 -0.794661 -0.254337
+v -0.239648 -0.810628 -0.266848
+v 0.517017 -0.877205 -0.0787674
+v 0.544339 -0.855381 -0.0783563
+v 0.117579 0.0849973 -0.182313
+v 0.103912 0.0848817 -0.182159
+v 0.105698 0.101028 -0.173707
+v -0.970687 0.0583819 0.216597
+v -0.220612 -0.77407 -0.151729
+v -0.253663 -0.791399 -0.158781
+v -0.253251 -0.788085 -0.152307
+v -0.678623 0.49886 -0.468327
+v -0.684841 0.495662 -0.451024
+v 0.01158 -0.13169 -0.286527
+v -0.00053308 -0.128992 -0.289238
+v 0.0026654 -0.109313 -0.28451
+v 0.155858 -0.152936 -0.340709
+v 0.158094 -0.161671 -0.357356
+v 0.143964 -0.162673 -0.356277
+v -0.95508 0.479579 0.329687
+v -0.338197 0.687134 -0.110033
+v -0.338352 0.706401 -0.10844
+v -0.325673 0.706479 -0.116789
+v 0.735901 -0.457472 -0.0932312
+v -0.457466 0.364627 0.346142
+v -0.462527 0.384434 0.346258
+v -0.105248 -0.92481 0.104548
+v 0.596003 -0.651051 -0.222057
+v -0.585868 0.720865 -0.565771
+v -0.590299 0.74084 -0.565887
+v -0.601732 0.760968 -0.565887
+v 0.448911 -0.903602 -0.233296
+v -0.648026 0.874187 -0.744989
+v -0.664018 0.897642 -0.733608
+v -0.647949 0.892825 -0.744976
+v -0.434177 -0.753492 0.207477
+v -0.778753 0.744141 -0.365269
+v -0.773704 0.752632 -0.369945
+v -0.779151 0.752208 -0.382546
+v 0.745291 -0.330407 -0.106038
+v -0.951766 0.0405012 0.178318
+v -0.945266 0.497267 0.329623
+v -0.929068 0.514724 0.329418
+v 0.454139 -0.884848 -0.246668
+v 0.426714 -0.897218 -0.258679
+v 0.265724 -0.976641 -0.249623
+v 0.0449136 -0.91515 -0.158216
+v 0.0314646 -0.915716 -0.160348
+v 0.0443227 -0.92296 0.295994
+v 0.0315031 -0.922498 0.292988
+v 0.157515 -0.915523 0.405269
+v 0.683723 -0.931451 0.247323
+v 0.676183 -0.937334 0.227683
+v 0.639394 -0.501814 -0.208659
+v 0.207766 -0.934226 0.269803
+v 0.193123 -0.921136 0.278319
+v 0.679022 -0.607069 -0.144664
+v 0.13704 0.235827 -0.00962113
+v 0.140341 0.229109 -0.0286065
+v 0.125646 0.227503 -0.0263072
+v 0.744494 -0.564628 -0.0542072
+v 0.753794 -0.528057 -0.0546311
+v -0.583388 0.49755 -0.0305076
+v -0.59071 0.514403 -0.0415032
+v -0.592586 0.518667 -0.0276559
+v 0.47026 -0.938118 -0.0789344
+v 0.468731 -0.956821 -0.0531795
+v -0.0361146 -0.91876 -0.0992299
+v 0.757481 -0.509778 -0.054798
+v -0.584686 0.480453 -0.0647917
+v -0.583324 0.480427 -0.0518693
+v -0.281344 -0.428108 -0.219667
+v -0.0262237 -0.916885 -0.122878
+v 0.286572 0.0831476 -0.207066
+v 0.285416 0.0682599 -0.216803
+v 0.273509 0.0842395 -0.208222
+v 0.331967 -0.974213 -0.238036
+v 0.721308 -0.187002 -0.0804886
+v 0.120071 0.115672 -0.163765
+v 0.118813 0.10036 -0.173065
+v 0.106404 0.115646 -0.163572
+v -0.597082 -0.915356 0.35006
+v -0.600152 -0.897116 0.349983
+v 0.608604 -0.631513 -0.221556
+v 0.34611 -0.973609 -0.237343
+v -0.549361 -0.626054 -0.0174696
+v -0.530864 -0.63538 -0.0166347
+v -0.55396 -0.636651 0.00648688
+v -0.594949 0.63931 -0.578758
+v -0.589195 0.659657 -0.578783
+v -0.585945 0.680094 -0.578719
+v -0.5894 -0.88034 0.349906
+v -0.585559 0.700403 -0.578732
+v 0.609567 -0.41376 -0.246835
+v 0.604891 -0.421865 -0.252217
+v 0.738662 -0.366913 -0.105948
+v 0.742901 -0.348442 -0.105704
+v 0.711456 -0.188286 -0.0945928
+v -0.924701 -0.255904 0.295095
+v 0.6238 -0.593633 -0.220297
+v -0.064721 -0.922421 -0.0301479
+v -0.584647 0.72066 -0.578706
+v -0.588411 0.740942 -0.578681
+v 0.488256 -0.825387 -0.233707
+v 0.298737 -0.178794 -0.338615
+v -0.494358 0.214285 -0.0574956
+v -0.496978 0.19661 -0.0645862
+v -0.503015 0.21232 -0.062775
+v 0.574936 -0.761842 -0.221453
+v 0.5829 -0.742689 -0.221363
+v -0.931188 0.0229289 0.178447
+v 0.624057 -0.557473 -0.220631
+v 0.620177 -0.539785 -0.221954
+v 0.760217 -0.491461 -0.0546311
+v 0.73093 -0.186372 -0.0675663
+v -0.569336 -0.864437 0.349829
+v -0.397106 0.665322 -0.069827
+v -0.415141 0.672182 -0.0516895
+v -0.394999 0.68432 -0.0663203
+v -0.547756 -0.848689 0.349726
+v 0.763017 -0.364961 -0.0545026
+v 0.761578 -0.38315 -0.0545283
+v 0.748553 -0.546413 -0.0544512
+v -0.431557 -0.734571 0.258961
+v -0.519997 -0.833506 0.34961
+v -0.49378 -0.818091 0.349546
+v -0.281434 -0.409405 -0.226219
+v -0.343271 -0.802587 -0.122017
+v -0.332533 -0.800468 -0.125113
+v -0.344145 -0.820365 -0.125165
+v -0.963661 0.0789344 0.328827
+v -0.973256 0.0931413 0.331987
+v -0.47378 -0.80206 0.349443
+v -0.464659 -0.784835 0.349328
+v 0.708566 -0.658013 -0.0663331
+v 0.70064 -0.676934 -0.0661533
+v -0.22801 -0.48053 -0.236675
+v 0.695181 -0.677011 -0.0789087
+v 0.74154 -0.222827 -0.0852928
+v 0.722464 -0.422469 -0.10582
+v 0.664545 -0.66197 -0.143443
+v 0.670634 -0.643935 -0.14442
+v -0.929197 0.356714 0.509997
+v 0.626908 -0.412308 -0.233361
+v 0.359341 -0.971965 -0.234953
+v -0.678803 -0.00043674 0.526644
+v -0.671815 -0.00696215 0.509753
+v -0.663171 0.00491975 0.525822
+v 0.581462 -0.842048 -0.0597949
+v 0.56931 -0.842831 -0.0645476
+v -0.812125 -0.0349007 0.416342
+v 0.0142262 -0.922601 0.33593
+v 0.30146 -0.933352 -0.138639
+v 0.302834 -0.947251 -0.149661
+v -0.458751 -0.76734 0.349199
+v 0.617403 -0.404537 -0.24049
+v 0.732368 -0.3855 -0.105999
+v -0.00183045 -0.91921 -0.0442007
+v -0.0151767 -0.919788 -0.0463587
+v -0.00586388 -0.918914 -0.0691205
+v -0.779215 -0.406464 0.448519
+v -0.455693 -0.749652 0.349135
+v -0.320021 -0.978606 -0.339874
+v -0.286778 -0.958092 -0.357677
+v -0.297863 -0.978375 -0.359784
+v 0.55405 -0.108761 -0.2074
+v 0.552174 -0.125242 -0.215377
+v 0.541076 -0.120335 -0.220657
+v -0.927257 -0.186372 0.29462
+v -0.923969 -0.169134 0.294761
+v 0.424222 -0.968908 0.34514
+v 0.41613 -0.967893 0.365796
+v 0.410838 -0.969512 0.342892
+v -0.217529 -0.980649 0.247966
+v -0.234446 -0.971824 0.259681
+v -0.596542 0.639105 -0.591603
+v 0.624326 -0.575559 -0.220991
+v 0.636157 -0.592708 -0.208608
+v -0.454088 -0.731771 0.349071
+v -0.958445 0.496882 0.239886
+v -0.453137 -0.714044 0.348968
+v -0.58976 0.659722 -0.591564
+v -0.586189 0.680069 -0.591577
+v -0.584712 0.700338 -0.591603
+v -0.318814 -0.6724 -0.131279
+v 0.608642 -0.758245 -0.14388
+v 0.617262 -0.739581 -0.144176
+v 0.759652 -0.401313 -0.0543485
+v 0.625251 -0.720647 -0.144188
+v 0.768117 -0.310535 -0.0547081
+v -0.932318 0.321158 0.382109
+v -0.94903 0.268467 0.446592
+v 0.794578 -0.491602 0.043674
+v -0.738123 0.528224 -0.376971
+v -0.739318 0.510446 -0.379694
+v 0.656941 -0.21259 -0.173707
+v 0.656941 -0.225756 -0.185473
+v 0.645907 -0.220233 -0.191318
+v 0.675682 -0.625438 -0.144587
+v 0.596349 -0.778361 -0.143983
+v 0.624185 -0.394466 -0.233874
+v -0.93612 0.409534 0.407222
+v -0.931072 0.374363 0.484409
+v -0.936994 0.321389 0.459194
+v -0.936698 0.339 0.446271
+v -0.584737 0.720608 -0.591577
+v -0.586818 0.740853 -0.591564
+v -0.488166 -0.854456 0.247413
+v 0.726524 -0.403805 -0.105409
+v -0.976699 0.249841 0.202635
+v -0.4457 -0.732246 0.413182
+v -0.446496 -0.714314 0.400478
+v -0.926576 0.356251 0.381904
+v -0.602618 -0.860237 0.400979
+v 0.72285 -0.113424 0.368711
+v 0.0845927 0.884399 -0.360413
+v -0.61626 -0.88472 0.429187
+v -0.616889 -0.876859 0.439335
+v -0.613151 -0.877321 0.426901
+v -0.97183 0.145653 0.408725
+v -0.973218 0.163007 0.408635
+v -0.921952 -0.169224 0.307388
+v -0.923172 -0.151857 0.294401
+v 0.337221 -0.951837 -0.272898
+v 0.324273 -0.951451 -0.275519
+v -0.779125 0.618951 -0.171793
+v -0.464929 -0.839081 0.247054
+v -0.0933404 -0.0193579 -0.25083
+v 0.730775 -0.91682 0.100913
+v -0.339893 -0.970668 0.487479
+v -0.344415 -0.970372 0.463728
+v -0.0772709 0.0373541 -0.207773
+v -0.0923641 0.0341942 -0.204356
+v -0.255075 -0.948471 -0.366823
+v 0.624442 0.0750165 0.00720621
+v 0.625649 0.0646761 -0.00736036
+v 0.614166 0.0811437 0.000745027
+v -0.078671 -0.0174054 -0.252873
+v -0.0920944 -0.00407196 -0.241209
+v -0.442899 -0.714571 0.41313
+v -0.961027 0.0763268 0.434865
+v 0.565778 -0.817115 -0.143521
+v 0.767166 -0.255865 0.35611
+v -0.584737 0.696292 -0.74558
+v 0.978163 -0.615688 0.291627
+v 0.920989 -0.629445 0.00515096
+v 0.748695 -0.184574 0.368596
+v 0.79892 -0.379823 0.304588
+v -0.61992 -0.88788 0.399476
+v -0.615206 -0.877051 0.401069
+v -0.618931 -0.894225 0.387915
+v -0.499611 -0.447004 -0.218563
+v 0.582695 -0.797667 -0.143752
+v 0.406355 -0.24681 -0.343894
+v 0.405314 -0.262224 -0.353849
+v 0.394126 -0.256803 -0.359193
+v 0.550569 0.0140271 -0.133116
+v 0.548308 0.000346823 -0.143932
+v 0.537736 0.00269751 -0.146668
+v -0.653896 0.500067 -0.436303
+v -0.590852 0.659465 -0.604397
+v -0.32787 -0.959454 0.570395
+v -0.342963 -0.962819 0.56983
+v -0.337427 -0.968099 0.553106
+v 0.52958 -0.787661 -0.243727
+v 0.542361 -0.78856 -0.232217
+v -0.479534 0.443407 0.371769
+v -0.483195 0.46315 0.371756
+v 0.06896 0.8984 -0.360439
+v 0.588758 0.105511 0.00624281
+v 0.590428 0.0970848 -0.0113296
+v 0.580074 0.103456 -0.015363
+v -0.586176 0.680017 -0.604384
+v -0.584686 0.700313 -0.604435
+v -0.581886 -0.826364 0.478115
+v -0.598957 -0.8426 0.478218
+v -0.94244 0.268069 0.536253
+v -0.93937 0.284832 0.532669
+v -0.258492 -0.969422 -0.372732
+v -0.278056 -0.981882 -0.360542
+v -0.974656 0.0942203 0.511757
+v -0.584545 0.720557 -0.60441
+v -0.584943 0.740788 -0.60441
+v -0.591699 0.530948 -0.34419
+v -0.0168595 -0.916101 -0.145679
+v -0.442861 0.463895 0.204805
+v -0.281537 -0.390394 -0.236032
+v -0.32489 0.648855 -0.117817
+v 0.765355 -0.237831 0.355995
+v 0.755297 -0.184137 0.355802
+v 0.74872 -0.166411 0.355776
+v 0.74181 -0.148851 0.355609
+v 0.734295 -0.130919 0.355866
+v 0.728309 -0.112936 0.356059
+v 0.963185 -0.70635 0.292064
+v -0.934091 0.321145 0.420645
+v -0.468718 0.403933 0.358872
+v 0.532226 -0.970976 0.110405
+v 0.528218 -0.970745 0.0853698
+v -0.0432052 -0.922511 0.0217471
+v -0.590543 0.76102 -0.604384
+v -0.615771 0.809999 -0.60757
+v -0.908953 0.537897 0.182236
+v -0.281665 -0.371679 -0.242609
+v 0.80768 -0.379219 0.240361
+v 0.806755 -0.379257 0.253232
+v -0.474178 0.423638 0.358885
+v -0.477492 0.443471 0.358988
+v -0.481191 0.463214 0.358962
+v -0.281794 -0.352603 -0.254054
+v 0.709825 -0.0596279 0.35584
+v -0.161112 -0.418204 -0.424627
+v -0.153199 -0.410883 -0.432
+v -0.15302 -0.429097 -0.430215
+v 0.802709 -0.379591 0.29155
+v -0.822594 0.154298 -0.0448815
+v -0.184503 -0.872838 -0.362366
+v -0.198312 -0.873365 -0.361749
+v -0.196501 -0.855677 -0.352591
+v 0.651764 -0.68125 -0.143572
+v -0.770917 0.0992042 -0.0649201
+v 0.298672 -0.95113 -0.280927
+v -0.376451 -0.521969 0.543266
+v -0.38814 -0.519361 0.538552
+v 0.219533 -0.968458 0.186565
+v 0.230695 -0.972106 0.192114
+v 0.213161 -0.964271 0.204805
+v 0.315859 -0.963757 -0.156006
+v 0.521731 -0.973879 0.134876
+v 0.509515 -0.972363 0.131035
+v 0.517698 -0.973648 0.109917
+v -0.83454 -0.418025 0.334492
+v 0.917546 -0.80039 0.214953
+v -0.855914 0.442379 0.0603986
+v 0.782259 -0.309135 0.342841
+v 0.776351 -0.273399 0.343021
+v 0.773165 -0.25548 0.343021
+v 0.771418 -0.237458 0.342969
+v 0.769799 -0.219398 0.342918
+v 0.766704 -0.201466 0.342982
+v 0.76163 -0.183739 0.342892
+v 0.755117 -0.166051 0.342892
+v 0.747179 -0.148325 0.342995
+v 0.739459 -0.130495 0.343136
+v 0.733152 -0.112628 0.343214
+v 0.728258 -0.0947341 0.343175
+v 0.722053 -0.0767892 0.343278
+v 0.714822 -0.0592682 0.343021
+v 0.70601 -0.0410536 0.34338
+v 0.6959 -0.0235711 0.343278
+v -0.590916 0.659426 -0.617217
+v -0.58606 0.679927 -0.617242
+v -0.584416 0.700274 -0.617255
+v 0.962273 -0.742009 0.214761
+v -0.173662 0.619798 -0.138177
+v -0.464685 0.4041 0.346129
+v -0.469194 0.423664 0.345898
+v -0.47536 0.443574 0.346219
+v -0.478314 0.463163 0.345911
+v -0.479059 0.482983 0.346181
+v -0.475616 0.502983 0.346091
+v 0.707834 -0.00520235 0.176019
+v -0.5829 0.720557 -0.617268
+v -0.598495 0.638887 -0.630036
+v 0.20065 -0.209674 -0.409778
+v 0.187586 -0.208582 -0.411075
+v 0.188306 -0.193887 -0.400362
+v 0.638739 -0.700608 -0.143572
+v -0.851688 -0.0326656 0.358564
+v -0.858779 -0.0498654 0.358307
+v -0.854154 -0.0539503 0.368005
+v 0.739767 -0.601211 -0.041105
+v 0.741488 -0.6259 -0.0274504
+v 0.733293 -0.619901 -0.040938
+v -0.935208 -0.221068 0.23083
+v -0.583119 0.740763 -0.617294
+v -0.587114 0.760943 -0.617294
+v -0.473857 -0.806466 0.194247
+v -0.932357 -0.203842 0.230727
+v -0.980629 0.146295 0.498654
+v -0.981439 0.129005 0.498732
+v -0.928477 0.339296 0.523163
+v 0.788746 -0.362559 0.330098
+v 0.78908 -0.344549 0.330214
+v 0.788682 -0.326605 0.330047
+v 0.787089 -0.308775 0.330021
+v 0.785239 -0.290946 0.329919
+v 0.781065 -0.273065 0.330124
+v 0.777995 -0.255133 0.330176
+v 0.776235 -0.237124 0.330098
+v 0.774604 -0.219115 0.330073
+v 0.771623 -0.201119 0.330137
+v 0.766665 -0.183354 0.330137
+v 0.760127 -0.16564 0.330111
+v 0.752111 -0.147991 0.330176
+v 0.744186 -0.130238 0.330265
+v 0.737802 -0.112396 0.330265
+v 0.732548 -0.0946827 0.330137
+v 0.726305 -0.0767635 0.330227
+v 0.71829 -0.0589471 0.33024
+v 0.709375 -0.0407967 0.33051
+v 0.918946 -0.800159 0.202095
+v 0.935979 -0.780506 0.214863
+v 0.761155 -0.111343 0.20162
+v -0.281845 -0.333759 -0.26225
+v -0.59599 0.781341 -0.617152
+v -0.600537 0.801084 -0.630255
+v -0.286123 -0.980957 -0.355057
+v -0.27392 -0.982485 -0.351242
+v 0.950186 -0.761392 0.214838
+v -0.453728 0.364768 0.333297
+v -0.676234 0.915472 -0.70468
+v -0.682606 0.905337 -0.718694
+v -0.459598 0.38428 0.333194
+v -0.462527 0.404254 0.333361
+v -0.465661 0.423689 0.333014
+v -0.472572 0.443458 0.33313
+v -0.47595 0.463279 0.333181
+v -0.47378 0.483137 0.333335
+v -0.471519 0.503112 0.333361
+v 0.0747661 -0.922305 0.18546
+v 0.0660955 -0.922331 0.206951
+v 0.0613941 -0.922896 0.183277
+v 0.727821 -0.638565 -0.0417858
+v 0.737378 -0.644372 -0.0327812
+v -0.923275 0.0956076 0.613324
+v -0.909107 0.0785875 0.617268
+v -0.913461 0.0956975 0.621828
+v 0.0751257 0.861624 -0.359463
+v 0.0736485 -0.285461 -0.461634
+v 0.0728778 -0.300169 -0.472219
+v -0.546111 -0.887623 0.250381
+v -0.54633 -0.871798 0.231806
+v -0.798419 0.361955 -0.0411949
+v -0.811007 0.361647 -0.0304819
+v -0.81251 0.370073 -0.0289661
+v -0.0901676 -0.968099 0.606054
+v -0.102923 -0.967559 0.602843
+v -0.792626 0.46193 0.562573
+v 0.477967 -0.825143 -0.247876
+v 0.478417 -0.805439 -0.253515
+v -0.050527 -0.963539 -0.228595
+v -0.0639375 -0.964104 -0.23074
+v 0.293406 -0.913211 0.384652
+v -0.458314 -0.668058 0.355776
+v -0.455706 -0.677872 0.361659
+v 0.743993 -0.583022 -0.0417087
+v 0.747012 -0.596343 -0.0299681
+v 0.792613 -0.344318 0.317433
+v 0.792292 -0.326309 0.31733
+v 0.790827 -0.308467 0.31733
+v 0.788926 -0.290612 0.317253
+v 0.785663 -0.272757 0.317202
+v 0.782645 -0.254812 0.317279
+v 0.780834 -0.236803 0.317189
+v 0.779099 -0.218858 0.317163
+v 0.775939 -0.200965 0.317163
+v 0.77021 -0.183033 0.317356
+v 0.764481 -0.165576 0.317112
+v 0.756556 -0.147849 0.317189
+v 0.74854 -0.130136 0.317215
+v 0.74118 -0.112152 0.317446
+v 0.735618 -0.0945799 0.317253
+v 0.729221 -0.0766993 0.317292
+v 0.721219 -0.0589214 0.317305
+v 0.713023 -0.0412463 0.317292
+v -0.446368 0.463818 0.217702
+v -0.449643 0.46369 0.230637
+v 0.753293 -0.093578 0.201645
+v 0.745124 -0.0759157 0.201645
+v 0.858149 -0.835098 0.288056
+v -0.0187092 -0.918452 -0.0721649
+v -0.032094 -0.91903 -0.0743229
+v -0.591584 0.659516 -0.630049
+v -0.586369 0.679953 -0.630075
+v 0.498391 0.171446 0.005729
+v 0.500022 0.161915 -0.00987803
+v 0.487113 0.175955 0.000616574
+v -0.448821 0.364588 0.320246
+v -0.457415 0.384473 0.320452
+v -0.460806 0.404254 0.320516
+v -0.462964 0.423946 0.320413
+v -0.468089 0.44342 0.320028
+v -0.470221 0.463381 0.320426
+v -0.468307 0.48324 0.320426
+v -0.467151 0.503086 0.32022
+v -0.469733 0.523112 0.320439
+v 0.746973 -0.564628 -0.0416316
+v -0.522386 -0.855548 0.225679
+v -0.5829 0.700287 -0.630088
+v -0.582618 0.720518 -0.630062
+v -0.957996 0.302943 0.266566
+v 0.71206 -0.854341 0.394376
+v -0.241601 -0.962472 -0.379476
+v -0.22733 -0.960905 -0.38076
+v -0.238338 -0.981753 -0.369084
+v -0.950828 0.320516 0.266489
+v -0.582759 0.740775 -0.630023
+v -0.58484 0.761045 -0.630049
+v -0.847051 -0.399553 0.347427
+v -0.85901 -0.381056 0.347273
+v 0.706857 -0.00480414 0.18889
+v 0.700897 0.00439309 0.176199
+v -0.281961 -0.315699 -0.260644
+v 0.797083 -0.36198 0.304511
+v 0.796261 -0.344048 0.304318
+v 0.795477 -0.326091 0.304485
+v 0.794077 -0.308223 0.304536
+v 0.792125 -0.290406 0.304434
+v 0.789247 -0.272474 0.304459
+v 0.785946 -0.254568 0.304446
+v 0.784058 -0.236598 0.304382
+v 0.782118 -0.218666 0.304292
+v 0.778213 -0.200656 0.304511
+v 0.77391 -0.183135 0.304241
+v 0.766819 -0.165139 0.304498
+v 0.758919 -0.147438 0.304536
+v 0.751777 -0.129956 0.304395
+v 0.743852 -0.112191 0.304472
+v 0.737763 -0.0942203 0.304536
+v 0.731174 -0.0764552 0.304498
+v 0.724134 -0.0589342 0.304421
+v -0.447704 0.483625 0.230624
+v -0.282025 -0.296868 -0.265641
+v 0.751893 -0.573131 -0.0280156
+v -0.618764 -0.88621 0.414813
+v -0.591083 0.781033 -0.630177
+v -0.602284 0.812208 -0.63994
+v -0.595116 0.801058 -0.643126
+v -0.696414 0.490729 -0.424922
+v -0.696992 0.496085 -0.455006
+v -0.442437 0.364254 0.307054
+v -0.43717 0.345461 0.320464
+v -0.454011 0.384434 0.307504
+v -0.459598 0.4041 0.307504
+v -0.462386 0.424075 0.307722
+v -0.465173 0.443625 0.307465
+v -0.467562 0.463561 0.307504
+v -0.465019 0.483317 0.307504
+v -0.464582 0.503176 0.307555
+v -0.183938 0.764745 -0.192859
+v -0.196539 0.764629 -0.187464
+v -0.865831 -0.363522 0.347273
+v -0.869877 -0.345654 0.347054
+v -0.425199 0.329906 0.321543
+v 0.725355 -0.0841624 -0.000912016
+v -0.933423 0.492463 0.358153
+v -0.927257 0.492476 0.370279
+v -0.924033 0.510023 0.348197
+v -0.658842 0.49132 -0.408994
+v 0.811714 -0.432501 0.213026
+v -0.436374 -0.959916 -0.141928
+v 0.423259 -0.923487 0.582303
+v -0.261061 -0.97483 0.394659
+v -0.0569882 -0.924065 0.0903667
+v -0.0611243 -0.92359 0.0657422
+v -0.873577 -0.328287 0.347131
+v 0.582618 0.0992685 -0.0191652
+v 0.800333 -0.361749 0.291704
+v 0.798586 -0.343881 0.291665
+v 0.797892 -0.325937 0.291537
+v 0.796736 -0.308043 0.291601
+v 0.794719 -0.290265 0.291485
+v 0.79197 -0.272333 0.29155
+v 0.788888 -0.254388 0.291563
+v 0.786948 -0.236456 0.291511
+v 0.784199 -0.218486 0.29155
+v 0.780577 -0.200695 0.291485
+v 0.77585 -0.182904 0.291498
+v 0.769761 -0.165049 0.291588
+v 0.761938 -0.14731 0.291652
+v 0.754 -0.129583 0.291665
+v 0.746742 -0.112139 0.29155
+v 0.739677 -0.0940019 0.291755
+v 0.73382 -0.0765323 0.291563
+v 0.726241 -0.0585874 0.291652
+v 0.71784 -0.0409893 0.291614
+v -0.448693 0.503356 0.230329
+v -0.282141 -0.277536 -0.27715
+v 0.871419 -0.841444 0.189494
+v -0.658803 0.465321 -0.302879
+v 0.14133 -0.913545 0.44649
+v 0.133906 -0.911502 0.466207
+v 0.12801 -0.914136 0.444267
+v -0.591365 0.659426 -0.642907
+v -0.586202 0.679902 -0.642933
+v -0.758688 0.575135 0.00827237
+v -0.767012 0.565912 0.00818245
+v -0.768592 0.564204 0.0211177
+v -0.843634 -0.01544 0.371062
+v 0.979897 -0.544345 0.265911
+v 0.990944 -0.561198 0.150007
+v -0.447498 0.384203 0.294324
+v -0.436875 0.36446 0.294209
+v -0.456631 0.403895 0.29444
+v -0.460677 0.424088 0.294851
+v -0.463413 0.443664 0.294607
+v -0.464981 0.463638 0.294594
+v -0.462591 0.483343 0.294774
+v -0.582913 0.700249 -0.642933
+v -0.581179 0.72048 -0.642971
+v -0.195961 0.650023 -0.157894
+v 0.90095 -0.802253 0.27927
+v 0.921271 -0.782446 0.27936
+v 0.939293 -0.762189 0.279051
+v 0.967399 -0.705785 0.279013
+v 0.802504 -0.361557 0.278987
+v 0.973423 -0.687313 0.27891
+v 0.968182 -0.688161 0.292218
+v 0.977148 -0.66933 0.279128
+v 0.981246 -0.651 0.278884
+v 0.981811 -0.633247 0.279013
+v 0.982954 -0.61529 0.278871
+v -0.174805 -0.985299 -0.353336
+v -0.187573 -0.984798 -0.356303
+v -0.177053 -0.967598 -0.370124
+v -0.581449 0.740711 -0.642971
+v -0.582926 0.761045 -0.642894
+v 0.801296 -0.343727 0.278794
+v 0.798843 -0.325872 0.278871
+v 0.798085 -0.307966 0.278743
+v 0.795516 -0.29015 0.278794
+v 0.793782 -0.272179 0.278781
+v 0.791598 -0.25426 0.278666
+v 0.788631 -0.236341 0.278704
+v 0.785702 -0.218396 0.27873
+v 0.782234 -0.200579 0.278679
+v 0.777597 -0.18275 0.278692
+v 0.771508 -0.164921 0.278769
+v 0.764623 -0.147374 0.278679
+v 0.756646 -0.12966 0.278704
+v 0.748707 -0.111895 0.278743
+v 0.741476 -0.0938221 0.278923
+v 0.73549 -0.0764295 0.27873
+v 0.728091 -0.0583433 0.278859
+v -0.116667 0.166783 -0.0349264
+v -0.114368 0.159359 -0.0527556
+v -0.79743 -0.0691205 0.439027
+v -0.793358 -0.039859 0.439913
+v 0.114895 0.244613 0.0332693
+v 0.128948 0.246244 0.0317279
+v 0.11862 0.239359 0.0129866
+v 0.0766158 0.878336 -0.362828
+v -0.586035 0.780878 -0.643138
+v -0.107907 -0.00599875 -0.238768
+v -0.107534 -0.0204369 -0.249636
+v -0.120804 -0.00746312 -0.237548
+v -0.426843 0.345372 0.294543
+v -0.432302 0.365076 0.28171
+v -0.422039 0.34514 0.281492
+v -0.440536 0.384241 0.281389
+v -0.451788 0.403805 0.281389
+v -0.459496 0.424062 0.28189
+v -0.461923 0.443612 0.281659
+v -0.461718 0.463638 0.281723
+v -0.459162 0.483407 0.281839
+v -0.458455 0.509868 0.267593
+v -0.282243 -0.258679 -0.282185
+v -0.50403 0.570652 0.00262044
+v -0.5043 0.58071 0.00516381
+v 0.90718 -0.801726 0.266424
+v 0.927501 -0.781919 0.266476
+v 0.94289 -0.762317 0.266399
+v 0.956043 -0.742394 0.266077
+v 0.964007 -0.723807 0.266116
+v 0.970263 -0.705451 0.266103
+v 0.975311 -0.687288 0.266155
+v 0.981426 -0.668855 0.266103
+v 0.983764 -0.651 0.266244
+v 0.985048 -0.633029 0.26618
+v 0.986756 -0.615084 0.26618
+v 0.9879 -0.597088 0.266065
+v 0.987925 -0.579246 0.266052
+v 0.985112 -0.561571 0.266116
+v -0.157361 -0.9849 -0.326129
+v -0.170168 -0.984399 -0.329097
+v -0.648219 -0.839826 0.0799491
+v -0.646883 -0.839633 0.0928843
+v 0.691006 -0.0238794 0.356136
+v 0.0123508 -0.919222 -0.184972
+v 0.801977 -0.34365 0.266065
+v 0.804636 -0.361467 0.265988
+v 0.800243 -0.325782 0.266
+v 0.798701 -0.307902 0.266
+v 0.7968 -0.290085 0.265936
+v 0.795207 -0.272076 0.265911
+v 0.792574 -0.254093 0.265988
+v 0.790198 -0.236238 0.265859
+v 0.787115 -0.218332 0.265872
+v 0.783852 -0.200464 0.265846
+v 0.779151 -0.182634 0.265885
+v 0.773049 -0.164831 0.265911
+v 0.766421 -0.147169 0.265911
+v 0.758547 -0.129416 0.265923
+v 0.750634 -0.111664 0.265962
+v 0.744006 -0.0939505 0.265962
+v 0.737288 -0.0762368 0.265923
+v 0.729889 -0.0581892 0.266013
+v -0.0298075 -0.92192 0.0239308
+v -0.156295 -0.800172 -0.302044
+v -0.170245 -0.80224 -0.299976
+v 0.0180798 -0.916281 -0.162493
+v -0.0656587 -0.924091 0.111921
+v -0.144542 -0.985401 -0.323175
+v -0.410427 0.326039 0.281685
+v -0.406033 0.316226 0.290972
+v -0.427357 0.364961 0.268698
+v -0.418288 0.345359 0.268698
+v -0.434974 0.384421 0.268544
+v -0.445841 0.404023 0.268634
+v -0.4564 0.423818 0.268814
+v -0.460459 0.443548 0.268724
+v -0.459341 0.4636 0.268993
+v -0.801951 -0.0306874 0.430806
+v 0.887077 -0.821778 0.25363
+v 0.91174 -0.801277 0.25354
+v 0.93165 -0.781084 0.253451
+v 0.945908 -0.761996 0.253451
+v 0.958163 -0.742612 0.253361
+v 0.965921 -0.723871 0.253348
+v 0.972049 -0.7054 0.253296
+v 0.978035 -0.686915 0.253194
+v 0.983404 -0.668829 0.253296
+v 0.987309 -0.650447 0.253129
+v 0.988195 -0.632747 0.253296
+v 0.989672 -0.614814 0.253271
+v 0.991304 -0.596818 0.253271
+v 0.991432 -0.578925 0.253309
+v 0.989261 -0.561314 0.253078
+v 0.983442 -0.54387 0.253219
+v -0.241151 -0.890487 -0.357626
+v -0.606921 0.711026 -0.363663
+v 0.804867 -0.361467 0.253181
+v 0.802902 -0.343625 0.253129
+v 0.801373 -0.325757 0.253129
+v 0.799909 -0.307838 0.253117
+v 0.798188 -0.290008 0.253104
+v 0.796569 -0.272012 0.253065
+v 0.79391 -0.254041 0.253091
+v 0.791598 -0.236186 0.252988
+v 0.788721 -0.218229 0.253001
+v 0.785175 -0.200451 0.252975
+v 0.780679 -0.182583 0.253001
+v 0.775374 -0.164959 0.252924
+v 0.768361 -0.146899 0.253104
+v 0.760641 -0.129082 0.253168
+v 0.753036 -0.111857 0.252962
+v 0.745663 -0.0938221 0.253091
+v 0.739099 -0.0760442 0.253104
+v 0.731572 -0.0580479 0.253168
+v 0.723248 -0.0403728 0.253155
+v 0.988992 -0.668225 0.214632
+v 0.862491 -0.527043 0.345718
+v -0.42385 0.365025 0.255827
+v -0.41559 0.345924 0.25611
+v -0.430966 0.384717 0.255878
+v -0.440099 0.404293 0.255865
+v -0.450131 0.423561 0.255634
+v -0.457505 0.443433 0.255673
+v -0.45577 0.46369 0.256122
+v -0.452264 0.48351 0.256045
+v -0.452097 0.503356 0.243239
+v -0.282346 -0.240181 -0.282455
+v -0.208755 0.650049 -0.156096
+v -0.0842844 0.957527 -0.172191
+v -0.0812786 0.954174 -0.186578
+v -0.0992492 0.935292 -0.186462
+v -0.945202 0.0755304 0.370523
+v -0.958253 0.0932569 0.370433
+v -0.948978 0.0749908 0.358448
+v 0.891354 -0.820994 0.240721
+v 0.911971 -0.801534 0.240759
+v 0.933282 -0.781071 0.240631
+v 0.9484 -0.761277 0.24049
+v 0.95946 -0.742355 0.240477
+v 0.967437 -0.72373 0.240477
+v 0.97377 -0.705348 0.240464
+v 0.980719 -0.686555 0.240284
+v 0.986089 -0.668495 0.240361
+v 0.989467 -0.650434 0.240413
+v 0.991522 -0.632528 0.240503
+v 0.992999 -0.614519 0.240413
+v 0.994348 -0.596574 0.240361
+v 0.994489 -0.578706 0.240374
+v 0.992344 -0.561095 0.240233
+v 0.986551 -0.543652 0.240323
+v 0.978947 -0.526285 0.240387
+v 0.805741 -0.361415 0.240297
+v 0.803942 -0.343586 0.240258
+v 0.801836 -0.32568 0.240336
+v 0.800924 -0.307812 0.240246
+v 0.798599 -0.289957 0.240297
+v 0.796903 -0.271973 0.240258
+v 0.795233 -0.253964 0.24022
+v 0.792471 -0.236019 0.240246
+v 0.790134 -0.218165 0.240181
+v 0.786614 -0.200374 0.24013
+v 0.782002 -0.18257 0.240156
+v 0.776415 -0.164574 0.240246
+v 0.770776 -0.147079 0.240143
+v 0.763081 -0.129275 0.240181
+v 0.754886 -0.111651 0.240156
+v 0.747127 -0.0938092 0.24022
+v 0.740679 -0.0759671 0.240246
+v 0.733807 -0.058369 0.240207
+v 0.724725 -0.0403599 0.240271
+v 0.993398 -0.649959 0.214555
+v -0.29997 -0.945658 0.570961
+v -0.395025 0.313772 0.257214
+v -0.421396 0.365384 0.2432
+v -0.428487 0.385076 0.243239
+v -0.434653 0.404409 0.24302
+v -0.443914 0.423972 0.242994
+v -0.453818 0.443471 0.242815
+v -0.451853 0.463754 0.24338
+v -0.449695 0.483561 0.243393
+v -0.282372 -0.221813 -0.280708
+v 0.865368 -0.842086 0.22803
+v 0.891663 -0.821418 0.227927
+v 0.863711 -0.841958 0.240824
+v 0.914771 -0.800969 0.227824
+v 0.933371 -0.781123 0.227747
+v 0.948709 -0.761546 0.227696
+v 0.960693 -0.742073 0.22758
+v 0.968568 -0.723434 0.227554
+v 0.975029 -0.705117 0.227554
+v 0.981477 -0.686812 0.227529
+v 0.987669 -0.668392 0.227516
+v 0.992062 -0.650113 0.227439
+v -0.54773 -0.902947 0.285756
+v 0.650056 0.0197175 0.378037
+v -0.2825 -0.203534 -0.276341
+v 0.372482 0.171999 0.441493
+v -0.28259 -0.185358 -0.271511
+v -0.509117 -0.612836 0.393349
+v -0.518173 -0.613633 0.388583
+v -0.488821 -0.630126 0.366746
+v -0.743004 0.585065 0.0150418
+v -0.754 0.575508 0.030058
+v -0.762131 0.568366 0.0452925
+v -0.768489 0.56834 0.0617602
+v -0.77495 0.568636 0.0782792
+v -0.781129 0.568443 0.0949011
+v -0.78479 0.571102 0.112358
+v -0.79057 0.573003 0.129005
+v -0.795323 0.5752 0.146102
+v -0.686305 0.593543 0.259141
+v -0.679073 0.592875 0.280361
+v -0.668347 0.59222 0.209481
+v -0.649465 0.590537 0.197612
+v -0.65495 0.591796 0.214247
+v -0.692291 0.591577 0.313091
+v -0.801643 0.575187 0.162647
+v -0.657365 0.589753 0.176186
+v -0.63915 0.586581 0.164034
+v -0.808117 0.575803 0.179153
+v -0.813576 0.576651 0.196006
+v -0.819973 0.577011 0.212577
+v -0.826036 0.576176 0.229237
+v -0.624673 0.579541 0.113321
+v -0.685277 0.592566 0.296803
+v -0.63432 0.584564 0.14713
+v -0.628822 0.582637 0.130547
+v -0.672882 0.593273 0.263868
+v -0.67459 0.592772 0.225936
+v -0.680101 0.593594 0.242609
+v -0.660473 0.592823 0.230946
+v -0.666665 0.593389 0.247362
+v -0.560729 0.586272 0.28505
+v -0.566304 0.586966 0.301633
+v -0.573164 0.585681 0.317883
+v -0.643941 0.588983 0.180977
+v -0.832998 0.574532 0.245628
+v -0.262526 -0.808316 -0.228402
+v -0.270413 -0.808021 -0.21548
+v -0.258659 -0.804411 -0.218588
+v -0.841643 0.570896 0.261633
+v -0.605662 0.577229 0.101555
+v -0.619856 0.577499 0.0963269
+v -0.580729 0.583292 0.333965
+v -0.586934 0.583189 0.35042
+v -0.59459 0.579323 0.366399
+v -0.602245 0.57642 0.382443
+v -0.590222 0.573042 0.386772
+v -0.610531 0.572168 0.398281
+v -0.61888 0.567903 0.414184
+v -0.606125 0.565887 0.418667
+v -0.615193 0.560261 0.434415
+v -0.615836 0.884386 -0.7003
+v -0.623633 0.881329 -0.684564
+v -0.607949 0.873737 -0.697538
+v -0.62791 0.562277 0.429919
+v -0.637698 0.555983 0.446002
+v -0.624956 0.553876 0.450472
+v -0.919113 0.301171 0.0616703
+v -0.923648 0.283676 0.0615804
+v -0.848194 0.568392 0.278049
+v -0.856569 0.564191 0.294144
+v -0.936197 0.195544 0.0749523
+v -0.927334 0.195338 0.0621456
+v -0.647576 0.549098 0.461866
+v -0.658803 0.54017 0.477845
+v -0.646009 0.537666 0.482135
+v -0.634782 0.54703 0.4664
+v -0.640781 0.871605 -0.653633
+v -0.631815 0.862035 -0.650255
+v -0.6238 0.865991 -0.666003
+v -0.669388 0.531217 0.49317
+v -0.657287 0.527813 0.497524
+v -0.632599 0.87578 -0.669304
+v -0.626022 0.577936 -0.055633
+v -0.631892 0.578655 -0.0391653
+v -0.674616 0.852504 -0.591539
+v -0.66529 0.843833 -0.588122
+v -0.619741 0.578231 -0.0719594
+v -0.656607 0.849241 -0.603523
+v -0.666009 0.857449 -0.606683
+v -0.648591 0.853519 -0.619131
+v -0.615836 0.869896 -0.68179
+v -0.657352 0.862665 -0.622213
+v -0.669991 0.515829 0.513054
+v -0.608231 0.887289 -0.716279
+v -0.600537 0.87569 -0.713441
+v -0.682053 0.519515 0.508854
+v -0.694012 0.508006 0.523883
+v -0.682606 0.503497 0.528276
+v -0.86849 0.556176 0.30979
+v -0.921284 0.248415 0.0613491
+v -0.879254 0.548366 0.325551
+v 0.675708 -0.946377 0.188813
+v -0.602168 0.887456 -0.732888
+v -0.594397 0.875792 -0.729883
+v -0.648977 0.867494 -0.638026
+v -0.640499 0.857359 -0.634994
+v -0.717635 0.808098 -0.459836
+v -0.725535 0.804193 -0.444306
+v -0.713537 0.800827 -0.439823
+v -0.254664 0.834739 -0.0326014
+v -0.266534 0.82287 -0.0185743
+v -0.70547 0.805028 -0.455186
+v -0.242757 0.846646 -0.0465
+v -0.298326 0.591924 -0.106924
+v -0.838689 0.526683 0.435725
+v -0.698123 0.807841 -0.470883
+v -0.926448 0.338641 0.381955
+v -0.200689 0.205499 0.234979
+v -0.18932 0.200862 0.239141
+v -0.232763 0.190933 0.299334
+v -0.73242 0.820725 -0.483741
+v -0.562309 -0.824745 0.536188
+v -0.546073 -0.809395 0.519644
+v -0.569194 -0.825323 0.524936
+v -0.706742 0.495495 0.539014
+v -0.695335 0.490922 0.543343
+v -0.88989 0.539747 0.341158
+v -0.376091 -0.960905 0.582945
+v -0.724815 0.888766 -0.609753
+v -0.723749 0.875664 -0.590845
+v -0.609285 0.826197 -0.642252
+v -0.735053 0.880391 -0.595084
+v -0.74628 0.871271 -0.581121
+v -0.929556 0.230869 0.0745027
+v -0.923249 0.23065 0.0619143
+v -0.925844 0.212962 0.0620942
+v -0.708142 0.477948 0.558038
+v -0.589721 0.873801 -0.74856
+v -0.58746 0.862125 -0.727468
+v -0.430183 -0.749664 0.45656
+v -0.437646 -0.750371 0.445925
+v -0.685419 0.583909 0.0725759
+v -0.512804 0.575341 0.265024
+v -0.51852 0.576086 0.281633
+v -0.500857 0.571102 0.268698
+v -0.754963 0.85208 -0.547865
+v -0.750609 0.842009 -0.527364
+v -0.684031 0.485732 0.547056
+v -0.763672 0.760172 -0.366797
+v -0.767988 0.766273 -0.387042
+v -0.613575 0.608687 -0.12564
+v -0.47965 0.56572 0.202827
+v -0.765663 0.838246 -0.53344
+v 0.95305 -0.532296 0.303534
+v -0.612021 0.549008 -0.0124599
+v -0.606561 0.544409 -0.00336547
+v -0.756093 0.86156 -0.566298
+v -0.602631 0.543305 -0.0466927
+v -0.607216 0.545925 -0.0298011
+v -0.599856 0.534069 -0.0267311
+v -0.652188 0.580196 0.103366
+v -0.633948 0.577242 0.0912145
+v -0.629143 0.574159 0.0743614
+v -0.618906 0.572759 0.070662
+v -0.598572 0.53949 -0.0638154
+v -0.596157 0.529175 -0.044175
+v -0.966461 0.250856 0.382019
+v -0.96411 0.250894 0.395494
+v -0.960616 0.268261 0.382353
+v -0.657891 0.876692 -0.641109
+v -0.666575 0.871528 -0.62554
+v -0.612252 0.551911 0.45507
+v -0.355307 -0.692927 0.520941
+v -0.713254 0.86901 -0.587223
+v -0.496683 -0.728932 0.131343
+v -0.491968 -0.720184 0.137355
+v -0.735939 0.778412 -0.374055
+v -0.747461 0.767211 -0.360079
+v 0.960629 -0.514711 0.268647
+v -0.956891 0.0932183 0.383342
+v -0.958368 0.0933082 0.396162
+v 0.953449 -0.516484 0.284844
+v 0.961336 -0.52807 0.287683
+v 0.945189 -0.520697 0.300696
+v -0.622798 0.807455 -0.591487
+v 0.936634 -0.525257 0.316303
+v -0.698803 0.584846 0.0677718
+v -0.751456 0.590447 0.217548
+v -0.758406 0.588983 0.233887
+v -0.73057 0.791347 -0.409238
+v -0.745329 0.789305 -0.4148
+v -0.647384 0.577499 0.0864232
+v -0.572008 -0.840994 0.546285
+v -0.578636 -0.84174 0.534891
+v -0.703826 0.827173 -0.509586
+v 0.804251 -0.469637 0.0609509
+v 0.680435 0.00393066 0.0208608
+v 0.679767 0.0146565 0.0392809
+v 0.959075 -0.502855 0.249199
+v 0.952485 -0.503343 0.265679
+v 0.945228 -0.505938 0.281941
+v 0.936698 -0.510357 0.297651
+v 0.927732 -0.515931 0.313297
+v -0.622721 0.543844 0.470896
+v -0.633999 0.533799 0.48613
+v -0.602412 0.558719 0.439155
+v -0.834732 -0.0346566 0.384408
+v -0.656671 0.911811 -0.715329
+v -0.512354 0.573234 0.302443
+v -0.506869 0.571963 0.285846
+v 0.966358 -0.507428 0.137984
+v -0.360561 0.259552 0.119333
+v -0.368538 0.268441 0.115839
+v -0.362167 0.269006 0.138113
+v -0.427074 -0.732542 0.452912
+v -0.434062 -0.73312 0.441544
+v 0.973076 -0.50947 0.15932
+v 0.969878 -0.503035 0.177394
+v 0.406393 -0.103662 -0.263945
+v 0.392751 -0.10397 -0.263547
+v 0.966178 -0.498487 0.194863
+v 0.961747 -0.494762 0.212346
+v 0.956262 -0.493452 0.229276
+v 0.949955 -0.493735 0.245898
+v 0.943211 -0.494968 0.262327
+v 0.936018 -0.496805 0.27864
+v 0.927553 -0.501288 0.294401
+v 0.91842 -0.507081 0.30988
+v 0.908066 -0.515482 0.324896
+v -0.949415 0.355853 0.279167
+v -0.948426 0.338422 0.279154
+v 0.464274 0.139705 0.43737
+v -0.676029 0.87989 -0.629176
+v -0.666754 0.886287 -0.644526
+v -0.751816 0.577781 0.367722
+v -0.601629 0.672194 -0.26952
+v -0.607319 0.672323 -0.253155
+v -0.613472 0.672117 -0.23688
+v -0.605791 0.660402 -0.23408
+v -0.619843 0.671655 -0.220721
+v -0.612072 0.660043 -0.217869
+v -0.786524 0.51701 0.491872
+v -0.803146 0.5129 0.486875
+v -0.329809 0.79276 -0.022916
+v -0.34417 0.782381 -0.0186642
+v -0.150772 -0.871541 0.690178
+v 0.963712 -0.500556 0.15598
+v 0.960603 -0.49466 0.173656
+v 0.956454 -0.490498 0.191164
+v 0.951933 -0.486978 0.208672
+v 0.946397 -0.485629 0.225615
+v 0.940231 -0.485668 0.242378
+v 0.933641 -0.486477 0.258858
+v 0.92605 -0.489162 0.275018
+v 0.917559 -0.49376 0.290728
+v 0.908028 -0.500427 0.30636
+v 0.897867 -0.508648 0.320773
+v -0.131144 -0.984862 -0.321017
+v -0.129063 -0.972684 -0.353374
+v -0.425712 -0.715021 0.451204
+v -0.432598 -0.715599 0.439849
+v -0.903814 -0.124908 0.32893
+v -0.62669 0.670139 -0.204728
+v -0.61888 0.658514 -0.201877
+v -0.633459 0.668546 -0.188723
+v -0.625739 0.656896 -0.185833
+v -0.760833 0.541429 0.461198
+v -0.773794 0.529689 0.476766
+v -0.64037 0.666941 -0.172731
+v -0.632599 0.655277 -0.169841
+v -0.656491 0.5966 -0.0297112
+v -0.646831 0.587749 -0.0259732
+v -0.640614 0.588032 -0.042428
+v -0.605136 0.71768 -0.399938
+v 0.956185 -0.50071 0.133809
+v 0.953731 -0.4929 0.152268
+v 0.950224 -0.487774 0.169622
+v 0.94569 -0.484152 0.187195
+v 0.941156 -0.480787 0.204716
+v 0.935709 -0.479309 0.221684
+v 0.929569 -0.479232 0.238447
+v 0.922864 -0.480183 0.254838
+v 0.915349 -0.482868 0.271126
+v 0.907475 -0.488571 0.287555
+v 0.897058 -0.495006 0.301929
+v 0.886627 -0.503767 0.316675
+v -0.732831 -0.0392167 0.498963
+v -0.746678 -0.0575726 0.488365
+v 0.874912 -0.514531 0.331486
+v 0.0329418 0.965889 -0.311511
+v 0.0418821 0.955896 -0.30785
+v -0.424942 -0.697538 0.449907
+v -0.431775 -0.698103 0.438526
+v -0.647949 0.663858 -0.156982
+v -0.639445 0.653723 -0.153822
+v -0.655579 0.660839 -0.141285
+v -0.647153 0.650563 -0.138151
+v -0.749491 0.550819 0.445488
+v 0.953731 -0.526914 0.0810924
+v 0.948066 -0.513953 0.092833
+v 0.945819 -0.493568 0.130316
+v 0.942749 -0.487209 0.14844
+v 0.939113 -0.482058 0.165704
+v 0.934283 -0.479168 0.182943
+v 0.929261 -0.476882 0.200181
+v 0.924277 -0.474634 0.217381
+v 0.918664 -0.473426 0.234491
+v 0.911457 -0.475546 0.250625
+v 0.903198 -0.479502 0.266643
+v 0.894078 -0.485385 0.282134
+v 0.88497 -0.491911 0.297266
+v 0.874 -0.501031 0.312449
+v 0.862902 -0.511114 0.327054
+v -0.290516 -0.896306 -0.330998
+v -0.303746 -0.913095 -0.331152
+v -0.305082 -0.894842 -0.318062
+v 0.0582213 0.918079 -0.301274
+v -0.663094 0.657885 -0.125511
+v -0.654526 0.647763 -0.122274
+v -0.738906 0.559169 0.429855
+v -0.671366 0.65353 -0.110007
+v -0.662027 0.644872 -0.106462
+v -0.680049 0.648508 -0.0943102
+v -0.670004 0.641134 -0.0905722
+v -0.233508 -0.960828 0.613928
+v -0.819896 -0.0309315 0.404203
+v 0.934463 -0.488699 0.126051
+v -0.724533 0.436856 -0.120849
+v -0.730403 0.439605 -0.106988
+v 0.931239 -0.482521 0.143636
+v 0.927488 -0.477704 0.161542
+v 0.922736 -0.474659 0.178717
+v 0.917739 -0.472424 0.195942
+v 0.91219 -0.471268 0.212859
+v 0.906448 -0.470048 0.229841
+v 0.899293 -0.472476 0.246103
+v 0.891059 -0.476342 0.262044
+v 0.88199 -0.482444 0.277471
+v 0.872305 -0.489753 0.292616
+v 0.861964 -0.498449 0.307542
+v 0.849466 -0.510267 0.322186
+v 0.00254979 -0.16889 0.659439
+v -0.719806 0.571038 0.397639
+v -0.728977 0.565797 0.41385
+v -0.689028 0.642856 -0.0789857
+v -0.677814 0.637486 -0.0751065
+v -0.698739 0.635842 -0.0637641
+v -0.687345 0.630871 -0.059782
+v -0.709992 0.626671 -0.0487607
+v -0.696337 0.625014 -0.0444062
+v -0.706652 0.616536 -0.02939
+v -0.3606 0.264793 0.213964
+v -0.368114 0.276508 0.210907
+v -0.364646 0.268711 0.231267
+v -0.764186 0.57529 -0.0300323
+v -0.263823 -0.80057 -0.195711
+v 0.918972 -0.479425 0.139166
+v 0.91481 -0.474865 0.156597
+v 0.910533 -0.471564 0.174272
+v 0.905073 -0.469868 0.191164
+v 0.899267 -0.469329 0.208094
+v 0.893577 -0.468635 0.224998
+v 0.885857 -0.471371 0.241196
+v 0.877533 -0.475713 0.257022
+v 0.869312 -0.480607 0.27268
+v 0.858291 -0.490678 0.287324
+v 0.847244 -0.500209 0.302186
+v 0.83549 -0.511256 0.316829
+v -0.717866 0.607287 -0.0143354
+v -0.710069 0.577987 0.382109
+v -0.744944 0.59362 -0.0133334
+v -0.750865 0.59353 -0.0256392
+v -0.729465 0.598514 0.00087348
+v -0.748399 0.587904 -0.0060116
+v -0.250926 0.179654 0.330908
+v -0.249346 0.168171 0.350844
+v -0.445391 -0.768984 0.297548
+v -0.111812 -0.921432 -0.0881187
+v -0.614551 -0.859094 0.452578
+v -0.611622 -0.85935 0.439682
+v -0.242718 -0.46428 -0.221312
+v -0.776749 0.637217 -0.1846
+v -0.774822 0.644898 -0.183212
+v -0.7796 0.637011 -0.197522
+v 0.901862 -0.473709 0.151947
+v 0.897006 -0.470703 0.169121
+v 0.892035 -0.468519 0.186347
+v 0.885754 -0.468789 0.203033
+v 0.879485 -0.469239 0.219706
+v 0.87183 -0.47245 0.235788
+v 0.864289 -0.47579 0.251794
+v 0.853936 -0.484653 0.266707
+v 0.843621 -0.492579 0.281903
+v 0.832574 -0.50238 0.296662
+v 0.820911 -0.513439 0.31128
+v 0.808579 -0.525578 0.325924
+v -0.496811 0.571667 0.215287
+v -0.282654 -0.167169 -0.266771
+v 0.201947 -0.117958 -0.275108
+v 0.193071 -0.0958259 -0.272975
+v -0.788143 0.556818 0.0549136
+v 0.120007 0.192641 0.426952
+v -0.00623639 -0.62897 0.684166
+v -0.605932 -0.859774 0.413798
+v -0.729658 0.494326 -0.298178
+v -0.748039 0.511102 -0.312526
+v -0.746716 0.510857 -0.32541
+v 0.887668 -0.474313 0.146539
+v 0.882774 -0.47141 0.163752
+v 0.877212 -0.469971 0.180695
+v 0.871688 -0.469483 0.197728
+v 0.86533 -0.470099 0.214349
+v 0.85788 -0.472553 0.230702
+v 0.848901 -0.479669 0.245898
+v 0.839447 -0.486117 0.26144
+v 0.828502 -0.495918 0.276251
+v 0.817751 -0.504499 0.291126
+v 0.808746 -0.510369 0.306604
+v -0.772368 0.578809 0.341698
+v -0.781553 0.573645 0.357575
+v -0.766562 0.575264 0.36252
+v -0.382809 0.301903 0.205268
+v -0.386239 0.307157 0.222763
+v -0.379277 0.294209 0.225589
+v -0.138466 -0.291948 -0.425025
+v -0.148498 -0.3097 -0.425064
+v -0.707551 0.586234 0.345359
+v -0.701706 0.582252 0.366168
+v -0.693421 0.587223 0.350304
+v -0.793268 0.546477 0.0349521
+v -0.783595 0.554583 0.0377395
+v -0.787256 0.548494 0.0211305
+v -0.79278 0.558963 0.0721135
+v -0.802272 0.545874 0.0482726
+v -0.798778 0.561108 0.0886454
+v -0.803531 0.563446 0.105755
+v -0.807398 0.566632 0.123199
+v -0.813101 0.568186 0.139937
+v -0.818701 0.56956 0.156725
+v -0.824263 0.57064 0.173591
+v -0.9814 0.19792 0.370099
+v -0.443799 -0.733145 0.297484
+v -0.442116 -0.715534 0.284639
+v -0.964971 0.215814 0.459708
+v 0.872202 -0.47737 0.140515
+v 0.891265 -0.479387 0.128671
+v 0.901361 -0.485116 0.114362
+v 0.888426 -0.484499 0.113501
+v 0.867347 -0.474711 0.157817
+v 0.863159 -0.471333 0.175403
+v 0.857006 -0.471692 0.19214
+v 0.850943 -0.471731 0.208929
+v 0.841836 -0.476008 0.224639
+v 0.833461 -0.483137 0.240104
+v 0.824469 -0.488751 0.255686
+v 0.816209 -0.492168 0.271434
+v 0.807449 -0.496638 0.286964
+v 0.791418 -0.505629 0.319257
+v -0.55274 0.56563 0.400067
+v -0.451506 0.658116 0.100437
+v -0.445969 0.672593 0.0855625
+v -0.375063 0.290342 0.208312
+v -0.699163 0.590113 0.329443
+v -0.685778 0.589907 0.334158
+v -0.678123 0.592258 0.318011
+v -0.671199 0.593119 0.301736
+v -0.658778 0.593787 0.268826
+v -0.664198 0.594416 0.285461
+v -0.829723 0.571641 0.190406
+v -0.65328 0.592708 0.25214
+v -0.836274 0.572155 0.207028
+v -0.84226 0.571359 0.223662
+v -0.849941 0.568417 0.23986
+v -0.857725 0.565887 0.25611
+v -0.949569 0.409341 0.368763
+v -0.942915 0.391871 0.368737
+v -0.782735 0.0413747 -0.0314838
+v -0.771521 0.0321132 -0.0402443
+v -0.140097 -0.428249 -0.439823
+v 0.876492 -0.48166 0.123071
+v 0.874399 -0.485013 0.114452
+v -0.836595 -0.398615 0.38473
+v -0.844932 -0.38428 0.387453
+v 0.853525 -0.476239 0.152628
+v 0.857006 -0.480517 0.134529
+v 0.848246 -0.47448 0.169481
+v 0.843519 -0.472167 0.186809
+v 0.837648 -0.471988 0.203675
+v 0.831238 -0.473079 0.22049
+v 0.82375 -0.475494 0.236546
+v 0.816261 -0.476612 0.252616
+v 0.809992 -0.477524 0.269276
+v 0.211453 -0.115351 0.599349
+v 0.224645 -0.117175 0.602393
+v -0.470029 0.602778 0.149815
+v 0.143643 0.247991 0.02939
+v -0.386997 0.308287 0.184677
+v -0.666189 0.585553 0.0232243
+v -0.495873 0.621545 0.121889
+v -0.511069 0.603793 0.135325
+v -0.521924 0.593517 0.149776
+v -0.530877 0.587878 0.165332
+v -0.647075 0.592554 0.235673
+v -0.865484 0.563125 0.272397
+v -0.874784 0.558013 0.288415
+v -0.885651 0.550267 0.304074
+v -0.578751 -0.845079 0.388159
+v 0.0652605 -0.0670653 -0.277471
+v 0.0637576 -0.054554 -0.272333
+v 0.0765644 -0.0542971 -0.272834
+v -0.9349 0.0223251 0.216713
+v 0.838971 -0.478937 0.146513
+v 0.860192 -0.486053 0.115569
+v 0.835041 -0.475096 0.164124
+v 0.830827 -0.471384 0.181761
+v 0.826447 -0.468083 0.199423
+v 0.822105 -0.464666 0.216893
+v 0.816518 -0.462713 0.234016
+v 0.81147 -0.460286 0.250984
+v -0.609105 0.810628 -0.623768
+v -0.151889 0.199834 0.177175
+v -0.935093 -0.220991 0.243675
+v -0.471866 0.58405 0.167875
+v -0.373406 0.284613 0.152409
+v -0.376322 0.290252 0.16993
+v -0.368435 0.279616 0.173219
+v 0.0752413 0.91736 -0.331781
+v -0.537813 0.585579 0.181466
+v -0.641565 0.591231 0.219038
+v -0.636093 0.590062 0.202365
+v -0.630556 0.58897 0.185704
+v -0.625059 0.587698 0.169031
+v -0.0915292 -0.984284 -0.313811
+v -0.104914 -0.984823 -0.315956
+v -0.0858644 -0.966288 -0.344986
+v -0.446162 -0.696408 0.400234
+v -0.449669 -0.714083 0.387645
+v 0.154189 -0.245885 -0.438153
+v 0.373162 -0.267555 -0.374004
+v 0.382771 -0.252693 -0.36374
+v 0.380869 -0.269392 -0.371923
+v 0.524326 -0.335738 -0.302211
+v 0.535373 -0.341492 -0.296636
+v 0.520524 -0.356444 -0.30654
+v -0.482938 0.2753 -0.0455751
+v -0.46868 0.289597 -0.0351576
+v -0.471262 0.271511 -0.041516
+v 0.529451 -0.730217 -0.26997
+v -0.630544 0.175891 -0.0955176
+v -0.635232 -0.839659 0.118909
+v 0.842478 -0.48369 0.128492
+v 0.824739 -0.469727 0.160296
+v 0.828387 -0.474672 0.142442
+v 0.820847 -0.464049 0.178498
+v 0.817468 -0.457729 0.196443
+v 0.814848 -0.450998 0.214427
+v 0.812446 -0.443086 0.23259
+v -0.569169 0.557884 0.432257
+v -0.578263 0.552052 0.447877
+v -0.729928 -0.437292 -0.118408
+v -0.728861 -0.416843 -0.136995
+v -0.716042 -0.434749 -0.138524
+v -0.472534 -0.602856 -0.0994226
+v -0.45947 -0.601892 -0.108851
+v -0.459855 -0.620762 -0.104407
+v -0.921849 0.514852 0.342263
+v -0.930635 0.509445 0.336829
+v -0.262166 0.209147 -0.0142711
+v 0.324145 -0.97456 -0.217676
+v 0.310041 -0.976268 -0.218627
+v -0.268512 0.220939 0.0211819
+v -0.265056 0.215531 0.00363522
+v -0.185557 0.193694 0.259719
+v -0.173816 0.189532 0.263855
+v -0.994656 0.215351 0.279886
+v -0.705046 0.584307 0.084278
+v -0.711225 0.58414 0.100771
+v -0.721771 0.796986 -0.424267
+v -0.735168 0.797706 -0.42929
+v 0.0684462 0.915805 -0.31593
+v -0.54403 0.585373 0.197908
+v -0.61536 0.582586 0.135274
+v -0.610518 0.580094 0.118357
+v -0.621783 0.564679 0.0399103
+v -0.615553 0.566619 0.051227
+v 0.165531 -0.916525 0.384678
+v 0.160226 -0.91813 0.361826
+v -0.276977 -0.973134 0.435199
+v -0.425507 -0.67985 0.449804
+v -0.431994 -0.680454 0.43823
+v -0.617377 0.896486 -0.719799
+v -0.685303 0.787378 -0.410857
+v -0.643119 -0.839248 0.109943
+v -0.663941 -0.856332 0.113167
+v -0.655772 -0.85515 0.122634
+v -0.940051 0.491936 0.34672
+v -0.656003 0.156995 -0.0954406
+v -0.951971 0.474236 0.34121
+v -0.500613 -0.298512 -0.256418
+v -0.500613 -0.279655 -0.261068
+v -0.487614 -0.298345 -0.257869
+v -0.791816 0.840917 -0.590601
+v -0.793332 0.832414 -0.584615
+v -0.824302 -0.471641 0.245178
+v -0.895452 0.549432 0.205679
+v 0.818843 -0.465758 0.139603
+v 0.817481 -0.457447 0.157856
+v 0.829312 -0.477819 0.133231
+v -0.284337 0.23548 0.128581
+v -0.271697 0.233245 0.133206
+v -0.266161 0.231768 0.116327
+v -0.72303 0.585489 0.134015
+v -0.728566 0.586722 0.150778
+v -0.731508 0.772619 -0.353837
+v -0.700062 0.781868 -0.379553
+v -0.47685 -0.838117 0.298255
+v -0.860333 -0.0323445 0.345372
+v -0.831791 -0.453529 0.245011
+v -0.275525 0.215017 -0.008054
+v -0.642503 0.599721 -0.0618886
+v -0.990135 0.232898 0.279835
+v -0.285339 0.2274 0.0337318
+v -0.272609 0.225204 0.0384331
+v -0.354935 0.708868 -0.0942203
+v -0.361589 0.729305 -0.0811437
+v -0.348153 0.728971 -0.0935138
+v -0.17686 0.201671 0.20582
+v -0.164876 0.198357 0.210175
+v -0.42981 0.318101 0.357947
+v -0.436811 0.316521 0.374415
+v -0.620203 0.585026 0.152165
+v -0.549592 0.586092 0.214542
+v -0.808425 -0.507762 0.219552
+v -0.896377 -0.0140784 0.242648
+v -0.604095 0.682548 -0.288891
+v -0.609413 0.683768 -0.272333
+v -0.61545 0.68364 -0.256084
+v -0.899575 -0.0487736 0.242596
+v -0.895362 -0.0310599 0.242802
+v -0.621822 0.683216 -0.23995
+v -0.861104 -0.0150033 0.345603
+v 0.962723 -0.522393 0.102416
+v 0.197028 -0.158216 0.693274
+v 0.812767 -0.425963 0.201234
+v -0.638174 0.816126 -0.578411
+v -0.645393 0.814109 -0.562393
+v -0.629593 0.805914 -0.575315
+v -0.278814 0.233977 0.111664
+v -0.261241 0.229481 0.0992171
+v -0.273329 0.232256 0.094824
+v -0.684263 0.58906 0.0354273
+v -0.676838 0.795895 -0.462893
+v -0.683094 0.795162 -0.446849
+v -0.672458 0.789305 -0.442867
+v -0.971625 0.198319 0.498359
+v -0.870455 0.00264613 0.3455
+v -0.649311 0.597936 -0.0457293
+v -0.692702 0.784732 -0.395186
+v -0.931997 -0.203752 0.243573
+v -0.640781 -0.431422 -0.194054
+v -0.628257 -0.431204 -0.199616
+v -0.0894996 0.198229 0.049904
+v -0.0730191 0.198036 0.0355172
+v -0.0853891 0.194503 0.0326656
+v -0.379354 0.296636 0.187708
+v -0.371582 0.28514 0.19074
+v -0.786036 0.582175 0.299334
+v -0.793692 0.578989 0.315481
+v -0.77883 0.581031 0.320593
+v -0.55518 0.58712 0.231164
+v -0.627987 0.682946 -0.223701
+v -0.933204 0.0279385 0.260747
+v -0.634757 0.68143 -0.207721
+v -0.642079 0.678733 -0.19187
+v 0.00299938 -0.961329 -0.22004
+v 0.0022672 -0.946467 -0.209956
+v -0.630955 0.232256 -0.0940276
+v -0.649375 0.676446 -0.176186
+v -0.899614 0.0337446 0.357112
+v -0.88962 0.0278229 0.364254
+v -0.656671 0.673813 -0.160309
+v 0.580113 0.0636228 0.425269
+v -0.207574 -0.775394 -0.177432
+v -0.358878 0.240631 0.0442135
+v -0.362103 0.245859 0.0617473
+v -0.346316 0.238923 0.0489406
+v -0.626472 0.592258 -0.0745413
+v -0.577492 0.571025 0.391268
+v -0.327202 0.243791 0.13178
+v -0.315269 0.240477 0.136186
+v -0.309707 0.239295 0.119256
+v -0.321794 0.242095 0.114914
+v -0.652278 0.812285 -0.546272
+v -0.635964 0.805464 -0.558989
+v -0.642785 0.803897 -0.542778
+v -0.256411 0.226745 0.0821714
+v -0.269616 0.228466 0.0772259
+v -0.666356 0.789626 -0.459014
+v -0.734141 0.587929 0.167516
+v -0.76461 0.588417 0.25047
+v -0.771469 0.586735 0.266835
+v -0.663787 0.594737 -0.014117
+v -0.298056 0.229211 0.0290689
+v -0.278981 0.809639 -0.0047913
+v -0.661668 0.913365 -0.698245
+v -0.708193 0.587069 0.139307
+v -0.694115 0.587891 0.144304
+v -0.628373 -0.393927 -0.209314
+v -0.561269 0.586748 0.24758
+v -0.548539 0.585412 0.252166
+v -0.664828 0.669613 -0.144715
+v -0.672997 0.665386 -0.129147
+v -0.681758 0.660081 -0.11363
+v -0.690788 0.654378 -0.0983179
+v -0.700705 0.64757 -0.083199
+v -0.712497 0.636703 -0.0685168
+v -0.725727 0.623357 -0.0543099
+v -0.282808 -0.148761 -0.263932
+v -0.75865 0.663639 -0.164381
+v -0.745291 0.681546 -0.178447
+v 0.719215 -0.0225692 0.127335
+v -0.567319 0.58825 0.264022
+v -0.57283 0.589317 0.280683
+v -0.554628 0.586118 0.268569
+v -0.579689 0.588045 0.296932
+v -0.761142 0.783936 -0.421107
+v -0.156449 0.196417 0.10018
+v -0.350221 0.242776 0.0661661
+v -0.669657 0.910321 -0.682201
+v -0.307728 0.234709 0.0632246
+v -0.312545 0.237124 0.0802831
+v -0.295024 0.232718 0.0678617
+v -0.318043 0.238486 0.0971747
+v -0.304209 0.237998 0.102416
+v -0.299854 0.235133 0.0849588
+v -0.659291 0.81005 -0.530691
+v -0.649876 0.80206 -0.526696
+v -0.256309 0.218229 0.0254594
+v -0.260509 0.222159 0.0428134
+v -0.24426 0.214915 0.0298653
+v -0.264735 0.226 0.0601288
+v -0.252635 0.222917 0.0644962
+v -0.247856 0.219834 0.0475019
+v -0.241164 0.224857 0.163328
+v -0.247355 0.224716 0.179988
+v -0.229128 0.221363 0.167695
+v -0.253765 0.224279 0.196636
+v -0.2411 0.221851 0.201183
+v -0.225287 0.194452 -0.0118691
+v -0.235769 0.194992 -0.0236996
+v -0.922286 -0.100065 0.242956
+v -0.158055 0.199616 0.193861
+v -0.302873 0.232307 0.0460761
+v -0.289539 0.23092 0.0511243
+v -0.597981 0.874302 -0.76012
+v -0.598559 0.88445 -0.749369
+v 0.691918 -0.0139243 0.338692
+v -0.742914 0.615059 -0.0610023
+v 0.134034 -0.124394 0.627005
+v -0.719549 0.667981 -0.127117
+v -0.705252 0.668444 -0.12203
+v -0.772291 0.517768 0.496728
+v -0.785856 0.504371 0.512052
+v -0.944675 0.285923 0.420812
+v -0.761771 0.571218 0.383496
+v -0.425725 -0.662214 0.449534
+v -0.432186 -0.662779 0.437935
+v -0.426907 -0.644423 0.450241
+v -0.433497 -0.644975 0.438744
+v -0.767423 0.880006 -0.615765
+v -0.783955 0.861932 -0.597306
+v -0.760255 0.529124 0.481545
+v -0.777622 0.823486 -0.520633
+v -0.773024 0.770435 -0.407363
+v -0.585855 0.587749 0.313348
+v -0.148794 -0.78847 0.613299
+v -0.16074 -0.804707 0.625386
+v -0.560087 -0.810898 0.465115
+v -0.365455 0.252359 0.079962
+v -0.353792 0.247092 0.0834559
+v -0.7875 0.577563 0.336868
+v -0.803313 0.575058 0.33173
+v -0.796453 0.571667 0.352501
+v -0.616028 0.823782 -0.62608
+v -0.666716 0.807764 -0.514236
+v -0.657069 0.799941 -0.510742
+v -0.220432 0.216456 0.0954534
+v -0.209166 0.211678 0.0996153
+v -0.204426 0.208826 0.0826466
+v -0.260727 0.22284 0.213103
+v -0.267754 0.220798 0.229456
+v -0.255705 0.217612 0.233926
+v -0.234741 0.222005 0.184561
+v -0.655913 -0.0634429 -0.161106
+v -0.643415 -0.0627493 -0.166462
+v -0.555488 -0.902087 0.29864
+v -0.558533 -0.919698 0.298717
+v -0.252763 0.213142 0.00782279
+v -0.633883 0.708996 -0.733145
+v -0.694179 0.800301 -0.450998
+v 0.127804 -0.0904951 -0.278769
+v 0.115139 -0.0886197 -0.280747
+v 0.115229 -0.0725246 -0.275968
+v -0.483092 0.589265 0.164137
+v -0.407459 0.691668 0.0830962
+v -0.821206 0.555418 0.100437
+v -0.816672 0.551551 0.0825182
+v -0.825998 0.558501 0.116674
+v -0.829851 0.561584 0.134169
+v -0.747397 0.541031 0.46604
+v -0.736068 0.550704 0.450459
+v -0.725483 0.558873 0.434633
+v -0.715515 0.565142 0.418525
+v -0.835619 0.56342 0.150894
+v -0.841091 0.564384 0.16776
+v -0.846627 0.565424 0.184638
+v -0.705701 0.572014 0.402649
+v -0.660691 0.578912 0.0815291
+v -0.524685 -0.545077 -0.132255
+v -0.511853 -0.544743 -0.135467
+v -0.511647 -0.565424 -0.107772
+v -0.906987 -0.0660891 0.242661
+v -0.390452 0.311036 0.240091
+v -0.383272 0.298216 0.242905
+v -0.745201 0.590318 0.201003
+v -0.348332 0.249918 0.19977
+v -0.353599 0.251896 0.216777
+v -0.345609 0.240657 0.219911
+v -0.28417 0.233142 0.166578
+v -0.296219 0.236058 0.162159
+v -0.291094 0.232012 0.183071
+v -0.331325 0.19828 0.28302
+v -0.341845 0.189545 0.298242
+v -0.32918 0.187824 0.302956
+v -0.318095 0.197445 0.287735
+v -0.237182 0.222827 0.10799
+v -0.22521 0.219308 0.112435
+v -0.215705 0.213604 0.0784719
+v -0.20029 0.204947 0.0653954
+v -0.212519 0.208351 0.0605014
+v -0.248036 0.220451 0.217689
+v -0.276206 0.216533 0.245538
+v -0.262718 0.215891 0.250303
+v -0.933731 -0.151562 0.243264
+v -0.932318 -0.169006 0.24338
+v -0.561063 0.561378 0.415931
+v -0.770943 -0.0681058 -0.0946185
+v -0.758329 -0.0674378 -0.103045
+v -0.630967 0.818708 -0.594403
+v -0.332533 0.245332 0.148723
+v -0.320754 0.241723 0.153116
+v -0.812202 0.56888 0.347414
+v -0.822915 0.561083 0.363008
+v -0.80628 0.564911 0.36821
+v -0.97797 0.110547 0.344832
+v -0.776351 0.568289 0.378153
+v -0.592766 0.586426 0.329597
+v -0.607332 0.581352 0.361852
+v -0.614937 0.578437 0.377947
+v -0.696581 0.577319 0.386785
+v -0.679959 0.585835 0.35498
+v -0.688257 0.581584 0.370857
+v -0.672381 0.589317 0.338885
+v -0.85314 0.565938 0.201183
+v -0.859113 0.565026 0.217908
+v -0.866871 0.562303 0.234131
+v -0.874784 0.559939 0.250419
+v -0.882633 0.557447 0.266758
+v -0.893705 0.550151 0.282391
+v -0.665431 0.591153 0.32261
+v -0.600344 0.584127 0.345744
+v -0.428461 -0.626722 0.451242
+v -0.357684 0.25575 0.23408
+v -0.350465 0.243072 0.236996
+v -0.339829 0.240066 0.20311
+v -0.305789 0.22672 0.215685
+v -0.317773 0.229957 0.211305
+v -0.314177 0.222442 0.231665
+v -0.303078 0.23503 0.178665
+v -0.310028 0.233129 0.195159
+v -0.298184 0.2297 0.199513
+v -0.320355 0.207619 0.267645
+v -0.307125 0.206963 0.272474
+v -0.242063 0.225396 0.125139
+v -0.230027 0.222057 0.129506
+v -0.232391 0.220053 0.0910089
+v -0.197824 0.198267 0.0471422
+v -0.208948 0.203341 0.0429033
+v -0.485713 0.565604 0.219166
+v -0.223579 0.22004 0.150765
+v -0.234947 0.22451 0.146616
+v -0.216899 0.202301 0.0212847
+v -0.20557 0.19783 0.0253952
+v -0.202847 0.190945 0.0076558
+v -0.62326 0.821868 -0.610126
+v -0.337298 0.247734 0.165936
+v -0.326303 0.242699 0.170085
+v -0.00149648 0.974765 -0.228505
+v -0.722156 0.863063 -0.572078
+v -0.622579 0.575521 0.394017
+v -0.657801 0.593311 0.306502
+v -0.651584 0.592862 0.289995
+v -0.92438 0.532373 0.292012
+v -0.64538 0.593029 0.273566
+v -0.0658129 -0.539258 0.650165
+v -0.0704629 -0.520915 0.65425
+v -0.077348 -0.521442 0.642997
+v -0.793589 0.824013 -0.55177
+v -0.801065 -0.0902254 -0.0773801
+v -0.787385 -0.0909062 -0.0903281
+v -0.795169 -0.108029 -0.0903924
+v -0.660357 0.55105 0.457331
+v -0.670878 0.543125 0.473272
+v -0.682156 0.533375 0.488764
+v -0.709375 0.812208 -0.475199
+v -0.791315 0.566735 0.37322
+v -0.423349 0.318435 0.341389
+v -0.370837 0.277047 0.13431
+v -0.365262 0.273374 0.155415
+v -0.366033 0.250021 0.288069
+v -0.371325 0.265769 0.285769
+v -0.372764 0.249713 0.304562
+v -0.856454 0.511975 0.443831
+v -0.326097 0.225949 0.227349
+v -0.323053 0.217175 0.24767
+v -0.334113 0.221838 0.243573
+v -0.31049 0.214915 0.252153
+v -0.297221 0.214028 0.256842
+v -0.247587 0.226951 0.14203
+v -0.193893 0.193591 0.0300323
+v -0.778419 0.585026 0.283187
+v -0.213829 0.214863 0.116558
+v -0.218107 0.218421 0.133938
+v -0.202024 0.186488 -0.00348108
+v -0.191466 0.186886 0.0116507
+v -0.188678 0.180387 -0.00624281
+v -0.220843 0.206976 0.0384331
+v -0.289976 0.236186 0.145473
+v -0.277914 0.233386 0.149892
+v -0.342758 0.248993 0.183045
+v -0.332944 0.241286 0.186706
+v -0.693563 0.434479 -0.17232
+v -0.691867 0.586426 0.051484
+v -0.984303 0.127965 0.344883
+v 0.60475 -0.439951 -0.253605
+v -0.631623 0.56992 0.409701
+v -0.632997 0.592682 0.240631
+v -0.639188 0.593132 0.257124
+v -0.339726 0.78513 -0.0570717
+v -0.357671 0.766762 -0.0569047
+v -0.627461 0.591821 0.223971
+v -0.621937 0.590986 0.207336
+v -0.612059 0.69398 -0.291755
+v -0.606125 0.58599 0.157137
+v -0.611635 0.587544 0.173758
+v -0.601256 0.583639 0.140232
+v -0.616452 0.589907 0.190676
+v -0.694128 0.522521 0.504268
+v -0.137901 0.200541 0.182339
+v -0.70118 0.817102 -0.490279
+v -0.640293 0.842318 -0.616138
+v -0.631764 0.832131 -0.613145
+v -0.676478 0.815458 -0.517794
+v -0.358133 0.252654 0.101696
+v -0.367241 0.259835 0.0978812
+v -0.366714 0.26311 0.268608
+v -0.359354 0.249276 0.271254
+v -0.624699 0.894367 -0.703498
+v -0.342 0.218434 0.259616
+v -0.333663 0.210008 0.263984
+v -0.301486 0.220284 0.236225
+v -0.288871 0.218113 0.240811
+v -0.253162 0.227978 0.158909
+v 0.457338 -0.059037 -0.208723
+v 0.444723 -0.0570845 -0.210804
+v 0.446059 -0.0415802 -0.201825
+v -0.224414 0.211947 0.0560569
+v -0.350182 0.185319 0.31435
+v -0.34051 0.177586 0.317883
+v -0.417299 0.318486 0.324665
+v -0.400369 0.315108 0.274144
+v -0.407267 0.326951 0.270047
+v -0.640627 0.56432 0.425385
+v -0.595669 0.581943 0.123636
+v -0.617955 0.693993 -0.27548
+v -0.590852 0.5794 0.106757
+v -0.624005 0.693852 -0.259231
+v -0.629978 0.694365 -0.242956
+v -0.636581 0.693017 -0.226938
+v -0.643941 0.690268 -0.211087
+v -0.651507 0.687262 -0.195416
+v -0.65897 0.684282 -0.17968
+v -0.666446 0.681494 -0.16388
+v -0.498404 -0.853968 0.298332
+v -0.674706 0.677024 -0.148415
+v -0.598328 0.515302 -0.336791
+v -0.683569 0.671462 -0.133064
+v -0.521538 -0.869601 0.298448
+v -0.706125 0.51132 0.51949
+v -0.573061 0.564731 0.411653
+v -0.581423 0.560479 0.42753
+v -0.717493 0.584397 0.117278
+v -0.739664 0.589188 0.18424
+v -0.713794 0.588726 0.155993
+v -0.3769 0.266951 0.302648
+v -0.602091 0.708572 -0.380401
+v -0.352584 0.210509 0.274594
+v -0.343888 0.200194 0.278486
+v -0.293843 0.223482 0.220078
+v -0.280471 0.222673 0.224844
+v -0.259392 0.227773 0.175557
+v -0.18697 0.176186 -0.0185486
+v -0.176231 0.177972 -0.00140014
+v -0.172801 0.172808 -0.0190239
+v -0.550864 -0.811964 0.439425
+v -0.179622 0.183379 0.0161337
+v -0.255384 0.200348 0.291036
+v -0.267574 0.202981 0.286514
+v -0.26453 0.194478 0.306707
+v -0.277221 0.196456 0.30216
+v -0.287703 0.188209 0.317497
+v -0.274292 0.187297 0.322186
+v -0.989454 0.145601 0.344562
+v -0.227124 0.21792 0.0743486
+v -0.362501 0.259218 0.251318
+v -0.354794 0.246707 0.254273
+v -0.990289 0.162878 0.344678
+v 0.0803024 0.900699 -0.32979
+v -0.989801 0.180258 0.344421
+v -0.541551 -0.885529 0.298525
+v -0.692445 0.665708 -0.117817
+v -0.702837 0.658167 -0.102531
+v -0.650467 0.557936 0.441506
+v -0.80041 -0.396997 0.436021
+v -0.791161 -0.388185 0.453041
+v -0.799344 -0.381557 0.450433
+v -0.715066 0.648109 -0.0875921
+v -0.728887 0.6324 -0.0741816
+v -0.414254 -0.608263 0.47299
+v -0.7596 0.592541 -0.0527043
+v -0.755914 0.610357 -0.0751964
+v -0.763146 0.592297 -0.0672837
+v -0.844122 0.549226 0.110508
+v -0.76348 0.886261 -0.633877
+v -0.781938 0.86955 -0.623228
+v -0.645894 0.522971 0.501635
+v -0.719472 0.498449 0.535251
+v -0.657904 0.51168 0.516741
+v -0.492919 0.581558 0.178935
+v -0.590312 0.555829 0.443728
+v -0.588719 0.544152 0.463895
+v -0.34945 0.253207 0.123366
+v -0.33857 0.248004 0.127657
+v -0.335063 0.242994 0.109583
+v -0.337799 0.240836 0.0709189
+v -0.320445 0.236251 0.0585617
+v -0.35866 0.210637 0.291511
+v -0.351852 0.196739 0.294427
+v -0.265801 0.227387 0.192256
+v -0.278492 0.229481 0.187618
+v -0.273393 0.224626 0.208453
+v -0.285455 0.227413 0.204035
+v -0.183039 0.188697 0.0336932
+v -0.258993 0.208595 0.270817
+v -0.247047 0.204831 0.275095
+v -0.448179 -0.786685 0.297728
+v -0.45261 -0.804283 0.297882
+v -0.210695 0.215595 0.19336
+v -0.222834 0.218935 0.188929
+v -0.217015 0.215172 0.209995
+v -0.259623 0.230059 0.137612
+v -0.364119 0.211999 0.308557
+v -0.369501 0.227734 0.306258
+v -0.756363 0.585964 0.309585
+v -0.771277 0.584333 0.304459
+v -0.763981 0.583074 0.32568
+v -0.970533 0.28523 0.279527
+v -0.837507 0.515328 0.456098
+v -0.853962 0.554531 0.144651
+v -0.859819 0.556356 0.161286
+v -0.948156 0.514595 0.278216
+v -0.930134 0.531384 0.277972
+v -0.864585 0.558719 0.178434
+v -0.870905 0.558681 0.195197
+v -0.877854 0.557113 0.211626
+v -0.884945 0.555829 0.228132
+v -0.892703 0.553029 0.244497
+v -0.628116 0.416316 -0.110637
+v -0.91183 0.543022 0.276572
+v -0.958073 0.496933 0.278345
+v -0.665521 0.581314 0.0984849
+v -0.12896 0.921175 -0.151934
+v -0.134098 0.921817 -0.135762
+v -0.114728 0.934483 -0.128492
+v -0.600152 0.548507 0.459425
+v -0.106147 -0.200849 -0.335185
+v -0.0985684 -0.200669 -0.343894
+v -0.111388 -0.212384 -0.357587
+v -0.352725 0.259218 0.141298
+v -0.34322 0.250894 0.144754
+v -0.356618 0.263354 0.158652
+v -0.360381 0.268313 0.176212
+v -0.351955 0.257535 0.179346
+v -0.358275 0.195762 0.311293
+v -0.271505 0.230958 0.171189
+v -0.930764 -0.186449 0.24347
+v -0.250631 0.212834 0.254812
+v -0.185364 0.195493 0.0519849
+v -0.244054 0.195788 0.295223
+v -0.253174 0.190072 0.310985
+v -0.211633 0.216353 0.155197
+v -0.217169 0.217728 0.172076
+v -0.200239 0.212063 0.159333
+v -0.205146 0.214375 0.176494
+v -0.927771 -0.117226 0.243033
+v -0.2067 0.214016 0.138074
+v -0.201883 0.211267 0.12099
+v -0.304067 0.198036 0.292654
+v -0.243836 0.22433 0.0868856
+v -0.249205 0.226154 0.103584
+v -0.254138 0.228505 0.120733
+v -0.363438 0.22672 0.289559
+v -0.633883 0.589394 -0.0586259
+v -0.671456 0.589561 0.171112
+v -0.758752 0.517306 0.501545
+v -0.0240914 -0.629497 0.665733
+v -0.0252346 -0.611783 0.666183
+v -0.0333785 -0.61186 0.656356
+v -0.161806 -0.825696 0.655534
+v -0.738932 0.805323 -0.449174
+v -0.745959 0.529342 0.486105
+v -0.260702 0.172654 0.346515
+v -0.270516 0.165537 0.362096
+v -0.259122 0.161157 0.366476
+v -0.791225 0.769523 -0.443433
+v -0.771559 0.564165 0.399296
+v -0.729491 0.813351 -0.464139
+v -0.957379 0.391371 0.27882
+v -0.347677 0.253913 0.161928
+v -0.26584 0.230329 0.154311
+v -0.243669 0.214337 0.238332
+v -0.239314 0.20794 0.258884
+v -0.188832 0.200695 0.0695188
+v -0.262256 0.184176 0.326694
+v -0.229102 0.218421 0.205602
+v -0.195371 0.209455 0.142249
+v -0.293547 0.205897 0.277047
+v -0.315204 0.188094 0.307696
+v -0.240612 0.219423 0.0689536
+v -0.988683 0.19792 0.344395
+v -0.672984 0.584423 0.0395507
+v -0.144811 0.198884 0.19873
+v -0.151684 0.197201 0.215082
+v -0.612984 0.55886 0.0339373
+v -0.734642 0.539297 0.470767
+v -0.124927 -0.507556 0.562907
+v -0.985947 0.21557 0.344331
+v -0.632226 0.891335 -0.687712
+v -0.692252 0.57123 0.407273
+v -0.683864 0.575302 0.391319
+v -0.625084 -0.838862 0.128119
+v 0.612894 0.0509701 0.400902
+v -0.981657 0.233206 0.344215
+v -0.930982 -0.134336 0.243174
+v -0.236 0.217047 0.222044
+v -0.231016 0.211768 0.242828
+v -0.193007 0.204523 0.08677
+v -0.285545 0.178395 0.337767
+v -0.272712 0.176482 0.342456
+v -0.190579 0.206681 0.125113
+v -0.327793 0.175993 0.322751
+v -0.23591 0.216225 0.0519464
+v -0.355397 0.231858 0.273322
+v -0.106404 0.192654 0.0436098
+v -0.702079 0.564384 0.423163
+v -0.711944 0.557936 0.439309
+v -0.609387 0.702985 -0.327722
+v -0.723248 0.548905 0.45516
+v -0.752792 0.699388 -0.223277
+v -0.74172 0.813146 -0.469341
+v -0.0876114 -0.319681 0.719465
+v -0.0840404 -0.302404 0.715329
+v -0.0933018 -0.302622 0.70644
+v -0.738675 0.754982 -0.319642
+v -0.536709 0.591462 0.144535
+v -0.658957 0.589085 0.343689
+v -0.66651 0.585168 0.359668
+v -0.674834 0.580916 0.375558
+v -0.615091 0.7031 -0.311357
+v -0.620601 0.704154 -0.294889
+v -0.626574 0.704089 -0.27864
+v -0.632843 0.703691 -0.262481
+v -0.231594 0.85709 -0.061028
+v -0.79355 0.546452 0.430729
+v -0.284543 0.211947 0.261427
+v -0.224054 0.213527 0.226424
+v -0.197773 0.207362 0.103726
+v -0.296669 0.168273 0.352783
+v -0.283258 0.167798 0.357703
+v -0.754064 -0.556099 0.129879
+v -0.958664 0.233489 0.510973
+v -0.915761 -0.083199 0.242699
+v -0.185839 0.203778 0.108183
+v -0.622618 0.902601 -0.742163
+v -0.232288 0.211292 0.0343612
+v -0.349219 0.231074 0.256649
+v -0.0821521 -0.924219 0.363882
+v -0.0901419 -0.92323 0.384408
+v -0.0949332 -0.923757 0.360837
+v -0.553883 -0.81014 0.509329
+v -0.544185 0.587261 0.160386
+v -0.550466 0.587069 0.176931
+v -0.639227 0.703087 -0.246398
+v -0.646446 0.700493 -0.23056
+v -0.653858 0.697718 -0.214761
+v -0.638174 0.592181 0.294735
+v -0.644391 0.592515 0.311254
+v -0.652008 0.59073 0.327388
+v -0.556709 0.58712 0.193347
+v -0.562258 0.588109 0.210008
+v -0.693781 0.819915 -0.505861
+v -0.363991 0.24171 0.0434428
+v -0.378198 0.254273 0.0564679
+v -0.322976 0.236636 0.191523
+v -0.329411 0.233926 0.207053
+v -0.0998915 0.202224 0.0834944
+v -0.188794 0.878606 -0.134721
+v -0.538224 0.570087 0.367851
+v -0.17221 0.193951 0.0570331
+v -0.977045 0.250715 0.344023
+v -0.12792 -0.337022 -0.451923
+v -0.212609 0.209237 0.23065
+v -0.649465 0.881509 -0.656883
+v -0.64055 0.887032 -0.672169
+v -0.181652 0.200258 0.0908805
+v -0.228781 0.206077 0.0167503
+v -0.342783 0.231588 0.240117
+v -0.461422 -0.821585 0.298152
+v 0.652381 -0.941085 0.249713
+v -0.958124 0.303085 0.279437
+v -0.949312 0.320529 0.279347
+v -0.0233463 -0.149596 0.593311
+v -0.00842009 -0.14975 0.599413
+v -0.513176 0.616048 0.116276
+v -0.525174 0.600697 0.129326
+v -0.457042 0.671796 0.0783692
+v -0.499059 0.633196 0.103045
+v -0.579933 0.589329 0.259514
+v -0.586266 0.589432 0.275891
+v -0.591764 0.590755 0.292552
+v -0.598597 0.589818 0.308827
+v -0.660871 0.695714 -0.198961
+v -0.668951 0.691706 -0.183341
+v -0.677121 0.687467 -0.167824
+v -0.631995 0.592605 0.278319
+v -0.568424 0.587814 0.226424
+v -0.356309 0.261055 0.196662
+v -0.743056 0.761071 -0.339848
+v -0.315025 0.238255 0.174272
+v -0.214125 0.195698 0.00342969
+v -0.213637 0.190509 -0.0076558
+v -0.531378 0.571654 0.35164
+v -0.176873 0.197471 0.073899
+v -0.227278 0.204613 0.263303
+v -0.224337 0.195338 0.283419
+v -0.235679 0.199924 0.279205
+v -0.845844 0.542123 0.394415
+v -0.833461 0.552836 0.378962
+v -0.525058 0.572258 0.335262
+v 0.164234 -0.116597 0.59949
+v -0.713306 0.589394 0.324498
+v -0.336309 0.232115 0.223482
+v -0.334408 0.721508 -0.108389
+v -0.734642 0.589599 0.298332
+v -0.573934 0.58888 0.243072
+v -0.625752 0.592361 0.261839
+v -0.62028 0.591552 0.245191
+v -0.614114 0.591333 0.228736
+v -0.605495 0.588366 0.325102
+v -0.612393 0.587107 0.341287
+v -0.602374 0.589856 0.195711
+v -0.607897 0.590961 0.212333
+v -0.685971 0.681803 -0.152538
+v -0.694847 0.676112 -0.137303
+v -0.717134 0.657654 -0.107567
+v -0.597518 0.587724 0.178832
+v -0.205133 0.874405 -0.106513
+v -0.30882 0.238332 0.15756
+v -0.950469 0.373605 0.278961
+v -0.969814 0.268274 0.34392
+v -0.219635 0.20749 0.247028
+v -0.960745 0.40893 0.278794
+v -0.974078 0.0944515 0.524576
+v -0.860885 -0.424486 0.221389
+v -0.97842 0.268004 0.279604
+v -0.627653 0.580453 0.373413
+v -0.592021 0.586748 0.162159
+v -0.731122 0.642586 -0.0938221
+v -0.733434 0.652811 -0.113463
+v -0.748271 0.634391 -0.100527
+v -0.580858 0.583909 0.128813
+v -0.586433 0.58509 0.145524
+v -0.63599 0.576214 0.389277
+v -0.683607 0.545026 0.468674
+v -0.694873 0.535482 0.484345
+v -0.620087 0.583369 0.357356
+v -0.938343 0.321454 0.472013
+v -0.745098 0.628379 -0.0865773
+v 0.148087 -0.12993 -0.288146
+v 0.162037 -0.116173 -0.277458
+v 0.161241 -0.130906 -0.287028
+v -0.575283 0.583112 0.112152
+v -0.21406 0.869729 -0.0911374
+v -0.221549 0.86472 -0.0758643
+v -0.21925 0.85926 -0.121478
+v -0.196141 0.878426 -0.121606
+v -0.302616 0.238267 0.140836
+v -0.183694 0.745695 -0.194182
+v -0.325506 0.165165 0.342379
+v 0.580562 0.0795509 0.406978
+v -0.960758 0.285692 0.343779
+v -0.166469 0.182223 0.0212461
+v -0.758919 0.628533 -0.108761
+v -0.750377 0.644449 -0.120258
+v -0.95061 0.303239 0.34365
+v -0.287125 0.233078 0.0895703
+v -0.291492 0.236071 0.107014
+v -0.297041 0.237394 0.123931
+v -0.645007 0.570588 0.404987
+v -0.663183 0.559914 0.436933
+v -0.673036 0.552926 0.452784
+v -0.585983 0.576972 0.0899042
+v -0.56967 0.582085 0.0955176
+v -0.862992 0.536651 0.104265
+v -0.654012 0.565373 0.420863
+v -0.706935 0.524718 0.499823
+v -0.938176 0.321043 0.343663
+v -0.911509 0.527903 0.334928
+v -0.554743 0.586491 0.0636741
+v -0.930687 0.338448 0.343483
+v -0.884611 0.547505 0.171639
+v -0.888207 0.550588 0.189314
+v -0.928978 0.35611 0.343368
+v -0.718906 0.513375 0.515045
+v 0.142397 -0.120155 0.610871
+v -0.937867 0.143199 0.0749908
+v -0.936069 0.160515 0.0751193
+v -0.933307 0.142865 0.0621841
+v -0.578276 0.573838 0.0692233
+v -0.561847 0.584872 0.0796794
+v -0.31365 0.176327 0.327465
+v -0.301794 0.187426 0.312488
+v -0.239867 0.855137 -0.0825567
+v -0.364235 0.272449 0.193579
+v -0.934772 0.373837 0.343252
+v -0.163013 0.177162 0.00363522
+v -0.271813 0.210226 0.266116
+v -0.943725 0.391936 0.342995
+v -0.282308 0.230676 0.0725374
+v -0.7317 0.501557 0.530678
+v -0.950353 0.409341 0.343008
+v -0.95535 0.426862 0.342969
+v -0.239045 -0.970013 0.553337
+v -0.2467 -0.968792 0.573157
+v 0.046455 0.803653 -0.314363
+v -0.634204 -0.930025 0.50193
+v -0.630454 -0.912813 0.497447
+v -0.637274 -0.931361 0.486451
+v -0.59423 0.518192 -0.321967
+v -0.0386836 -0.95605 0.69538
+v 0.048446 0.941175 -0.30496
+v 0.0327748 0.956641 -0.324896
+v -0.289925 0.19846 0.297548
+v -0.345995 0.247734 0.105319
+v -0.280201 0.205242 0.281852
+v -0.663453 0.798875 -0.494839
+v -0.659857 0.790885 -0.475058
+v -0.669722 0.798271 -0.478667
+v -0.282873 -0.130495 -0.260644
+v -0.276823 0.229019 0.0557743
+v -0.757982 0.504319 0.521506
+v -0.183116 0.20117 0.222519
+v 0.350734 -0.970372 -0.0706106
+v 0.340792 -0.972145 -0.046834
+v 0.329681 -0.968535 -0.0524088
+v -0.985215 0.250265 0.279706
+v -0.0449907 0.981432 -0.193502
+v -0.299572 0.177201 0.332526
+v -0.311428 0.165923 0.347414
+v -0.796633 0.78734 -0.492823
+v 0.684879 -0.00119461 0.335969
+v 0.049448 -0.685284 0.684616
+v -0.745149 0.516368 0.506079
+v -0.611854 0.71258 -0.34708
+v -0.617441 0.713582 -0.330625
+v -0.711019 0.547826 0.459733
+v -0.721206 0.538423 0.475289
+v -0.733203 0.527544 0.49069
+v -0.69924 0.556137 0.443818
+v -0.193302 0.190419 0.27584
+v 0.765021 -0.902125 0.165884
+v -0.683171 0.813929 -0.50193
+v 0.701103 -0.00182403 0.249969
+v 0.696915 0.00191395 0.266861
+v 0.692265 0.00447016 0.283509
+v 0.687564 0.00782279 0.30031
+v 0.682811 0.00945414 0.316804
+v 0.67757 0.0115865 0.333271
+v 0.671597 0.0114452 0.349379
+v -0.565482 0.567659 0.395597
+v 0.453176 0.144754 0.433606
+v -0.679523 0.569021 0.411743
+v -0.68863 0.563498 0.427787
+v -0.623093 0.714468 -0.314247
+v -0.629131 0.714327 -0.298011
+v -0.66976 0.576214 0.396252
+v -0.68091 0.836935 -0.556869
+v -0.373304 -0.713184 0.508366
+v -0.635206 0.714134 -0.2818
+v -0.642027 0.712606 -0.265833
+v -0.649028 0.710705 -0.249995
+v -0.661411 0.580235 0.380285
+v -0.65635 0.707969 -0.234234
+v -0.653087 0.584487 0.364408
+v -0.542476 0.595058 0.123764
+v -0.519342 -0.795805 0.48965
+v -0.878445 -0.316765 0.345847
+v -0.00772645 -0.0902254 -0.278653
+v -0.0132242 -0.0731283 -0.272654
+v -0.000391782 -0.0731026 -0.272629
+v -0.516953 -0.797141 0.477858
+v 0.704584 0.000256906 0.159295
+v 0.716132 -0.0171356 0.144587
+v 0.701128 0.0017855 0.213219
+v 0.697403 0.00671809 0.23038
+v 0.693537 0.0107001 0.247311
+v 0.689349 0.0144638 0.264189
+v 0.684661 0.0170457 0.280824
+v 0.680268 0.0197818 0.297497
+v 0.675348 0.0221324 0.314093
+v 0.670171 0.0242776 0.330548
+v 0.664237 0.0250483 0.34663
+v -0.51369 -0.242725 -0.259514
+v -0.513767 -0.261286 -0.259796
+v -0.0943551 0.200836 0.0668212
+v -0.196861 0.198511 0.255544
+v -0.0812786 0.190624 0.0154529
+v -0.101446 0.189468 0.0267953
+v -0.517608 0.624436 0.0962884
+v -0.531147 0.606645 0.109391
+v -0.663916 0.704911 -0.218524
+v -0.645495 0.588315 0.34839
+v -0.671366 0.70197 -0.20284
+v -0.638572 0.590036 0.332115
+v -0.592843 0.59037 0.254979
+v -0.606857 0.59073 0.249957
+v -0.61861 0.59213 0.283085
+v -0.679548 0.697744 -0.18731
+v -0.688373 0.692169 -0.171999
+v -0.600678 0.59055 0.233528
+v -0.599008 0.590537 0.271344
+v -0.550967 0.589496 0.13959
+v -0.558302 0.586812 0.155505
+v -0.648167 -0.855356 0.133398
+v -0.716813 0.545476 -0.4799
+v -0.894245 -0.107387 0.337395
+v -0.935427 0.177895 0.074644
+v 0.714192 -0.016686 0.107322
+v 0.711122 -0.0112011 0.124535
+v 0.708026 -0.00493259 0.142069
+v 0.696992 0.00918439 0.193424
+v 0.704982 -0.00222224 0.196276
+v 0.693036 0.0131279 0.210355
+v 0.689491 0.0182275 0.227554
+v 0.685688 0.0222609 0.244472
+v 0.681475 0.0259732 0.261312
+v 0.677108 0.0287606 0.278011
+v 0.672779 0.0324087 0.2948
+v 0.667898 0.0347722 0.311383
+v 0.662824 0.0369816 0.327825
+v 0.657031 0.0369688 0.343959
+v 0.650351 0.0354916 0.359822
+v 0.642952 0.0326014 0.375378
+v 0.433689 -0.959081 -0.178742
+v -0.11993 -0.907071 0.714815
+v -0.624044 0.593067 0.299694
+v -0.587293 0.589561 0.238319
+v -0.612393 0.591359 0.266617
+v -0.752972 0.628122 -0.0967636
+v -0.797674 0.750962 -0.436175
+v -0.798727 0.761482 -0.455276
+v -0.588976 0.588893 0.200502
+v -0.605148 0.591629 0.287812
+v -0.612046 0.590614 0.304087
+v -0.792895 0.806068 -0.515893
+v -0.78181 0.825195 -0.527505
+v 0.706254 -0.00598591 0.104163
+v 0.702991 0.000115608 0.121735
+v 0.699921 0.00557486 0.138948
+v 0.696273 0.0105974 0.156173
+v 0.692907 0.0157997 0.173373
+v 0.688938 0.0205653 0.190573
+v 0.685059 0.0245345 0.207477
+v 0.681372 0.0287092 0.224407
+v 0.677737 0.0337189 0.241569
+v 0.673498 0.0374312 0.258447
+v 0.669285 0.0411178 0.275275
+v 0.665085 0.0440337 0.291974
+v 0.660653 0.0475661 0.308698
+v 0.65554 0.0489149 0.325089
+v 0.649516 0.0495315 0.34112
+v 0.642323 0.046834 0.356778
+v 0.635669 0.0453567 0.372629
+v -0.0662111 0.969242 -0.164574
+v 0.523337 0.152422 0.000834944
+v 0.511378 0.157483 -0.00480414
+v 0.509489 0.166539 0.0109956
+v -0.631674 0.591243 0.315776
+v -0.564544 0.586773 0.171921
+v -0.570094 0.587968 0.188582
+v -0.5945 0.590229 0.217098
+v 0.718739 -0.252487 -0.13142
+v -0.577916 0.587261 0.167143
+v -0.583466 0.588276 0.183803
+v -0.618238 0.590344 0.320516
+v -0.625714 0.588096 0.336585
+v -0.307369 -0.353271 -0.247696
+v -0.320253 -0.353426 -0.247927
+v 0.698225 0.00622997 0.101709
+v 0.69486 0.011458 0.118922
+v 0.691623 0.016776 0.136109
+v 0.688103 0.0218755 0.153347
+v 0.684661 0.0270779 0.170534
+v 0.680717 0.0310214 0.187451
+v 0.677031 0.0359668 0.204626
+v 0.67337 0.0401416 0.221543
+v 0.669747 0.0451127 0.238678
+v 0.665611 0.0488892 0.25557
+v 0.661514 0.0526657 0.27241
+v 0.657043 0.0553761 0.289019
+v 0.65265 0.0588572 0.305731
+v 0.647718 0.0611051 0.322186
+v 0.641501 0.0608225 0.338152
+v 0.634577 0.0591526 0.353811
+v 0.627987 0.0577525 0.369662
+v 0.620717 0.0549393 0.38532
+v 0.0545861 0.926082 -0.302545
+v 0.0570652 -0.141953 0.638976
+v 0.0711051 -0.14108 0.643871
+v -0.575643 0.588777 0.205178
+v -0.581796 0.588777 0.221658
+v -0.696389 0.830115 -0.525193
+v -0.632779 0.585399 0.352796
+v -0.640357 0.582483 0.368891
+v -0.57229 0.586041 0.150521
+v -0.628553 -0.929229 0.514377
+v -0.585135 -0.842626 0.523446
+v -0.44376 -0.664256 0.413143
+v -0.445366 -0.646504 0.414132
+v -0.450838 -0.64721 0.401621
+v -0.43911 0.639195 -0.0385616
+v -0.427652 0.628623 -0.0499297
+v -0.440369 0.628508 -0.0393195
+v -0.672984 0.807134 -0.498487
+v 0.69012 0.0167631 0.098562
+v 0.686755 0.0219783 0.115788
+v 0.683312 0.0271678 0.133013
+v 0.680036 0.0324729 0.150239
+v 0.676632 0.0384845 0.16767
+v 0.672907 0.042595 0.184613
+v 0.669234 0.0467697 0.20153
+v 0.665239 0.0514454 0.218678
+v 0.661514 0.0563266 0.235775
+v 0.657557 0.0602188 0.252654
+v 0.653434 0.0638797 0.269417
+v 0.648861 0.0664359 0.286013
+v 0.644545 0.0699426 0.302699
+v 0.639664 0.0715483 0.319141
+v 0.633614 0.0720621 0.335172
+v 0.626857 0.0705978 0.350946
+v 0.620203 0.0691719 0.366746
+v 0.612907 0.0663973 0.382392
+v 0.604943 0.062274 0.397832
+v -0.441217 -0.698026 0.21801
+v -0.619741 -0.879235 0.48667
+v -0.608771 -0.860417 0.492347
+v -0.371313 0.280657 0.227529
+v -0.88208 0.246797 -0.00201671
+v -0.874527 0.264343 -0.00211947
+v -0.871033 0.246347 -0.0143225
+v -0.689054 0.832645 -0.541262
+v -0.648732 0.578231 0.384755
+v -0.558738 0.58888 0.118048
+v -0.56606 0.586349 0.134028
+v -0.715862 0.895137 -0.624731
+v -0.551083 0.593196 0.102094
+v -0.657031 0.574249 0.400799
+v -0.666074 0.568597 0.41656
+v -0.6759 0.561635 0.432296
+v -0.490453 0.400054 -0.00639696
+v -0.537094 0.575598 0.330895
+v 0.685059 0.0217985 0.0782279
+v 0.681912 0.028067 0.0957745
+v 0.678431 0.0331922 0.112987
+v 0.675219 0.0385359 0.130187
+v 0.671854 0.0437768 0.1474
+v 0.668617 0.049069 0.164587
+v 0.664789 0.0539374 0.181722
+v 0.661103 0.0580479 0.19864
+v 0.657108 0.0627364 0.215775
+v 0.65337 0.0674763 0.232834
+v 0.649336 0.0711886 0.24961
+v 0.645072 0.0747083 0.266373
+v 0.640576 0.0773287 0.282943
+v 0.636273 0.0801547 0.299514
+v 0.631507 0.0825053 0.316007
+v 0.625739 0.0833146 0.332167
+v 0.619124 0.0819658 0.34803
+v 0.612586 0.0806428 0.363894
+v 0.605058 0.0777397 0.379386
+v 0.596812 0.0733723 0.394595
+v 0.588899 0.0692618 0.410009
+v -0.293085 -0.673055 -0.125653
+v -0.293175 -0.654224 -0.130251
+v 0.229089 -0.14433 -0.298705
+v 0.231556 -0.151819 -0.316739
+v 0.21934 -0.149005 -0.319052
+v -0.135319 0.9184 -0.098639
+v -0.675913 0.585707 0.132063
+v -0.489554 0.652644 0.0754404
+v -0.512598 0.633607 0.081452
+v -0.685791 0.554904 0.448275
+v -0.543992 0.574146 0.347144
+v 0.678534 0.0240978 0.0573414
+v 0.676568 0.0320747 0.0751193
+v 0.673704 0.0385102 0.0926531
+v 0.670274 0.044509 0.110161
+v 0.667178 0.0499554 0.127361
+v 0.663582 0.0549907 0.144535
+v 0.660319 0.0602701 0.161735
+v 0.656568 0.0651385 0.178896
+v 0.652766 0.0698913 0.196006
+v 0.648887 0.0737192 0.21277
+v 0.645097 0.0776884 0.229571
+v 0.640974 0.0813493 0.246386
+v 0.636684 0.0848175 0.263136
+v 0.632149 0.0873994 0.279719
+v 0.627795 0.0902125 0.296302
+v 0.622926 0.0924861 0.312822
+v 0.617249 0.0933339 0.328994
+v 0.611147 0.0931413 0.344973
+v 0.604365 0.0915741 0.360696
+v 0.596799 0.088016 0.376367
+v 0.588527 0.0836486 0.391538
+v -0.638187 -0.855022 0.141594
+v -0.116783 0.185525 0.0212204
+v -0.282808 -0.112435 -0.2553
+v -0.368011 -0.962768 -0.268236
+v -0.366842 -0.974958 -0.256623
+v -0.452675 -0.705554 0.334235
+v 0.67143 0.0250355 0.0361081
+v 0.67012 0.0343997 0.05422
+v 0.66827 0.043263 0.0723704
+v 0.665586 0.0498783 0.0898529
+v 0.662284 0.0551449 0.107053
+v 0.659047 0.0612335 0.124535
+v 0.655618 0.0664359 0.141696
+v 0.652098 0.0714712 0.158883
+v 0.648309 0.0754661 0.175724
+v 0.644532 0.0800904 0.192744
+v 0.640601 0.0839312 0.209558
+v 0.636684 0.0877848 0.22636
+v 0.632419 0.0913044 0.243136
+v 0.628219 0.0948497 0.259925
+v 0.62353 0.0973545 0.276469
+v 0.619253 0.100193 0.293078
+v 0.614269 0.102351 0.309546
+v 0.608719 0.10334 0.325782
+v 0.602823 0.103315 0.341852
+v 0.595861 0.101555 0.357536
+v 0.588539 0.098806 0.373105
+v 0.580126 0.0937835 0.388467
+v 0.441499 0.133887 0.448083
+v -0.599574 -0.878824 0.36243
+v -0.154073 0.198627 0.138562
+v -0.609285 -0.895895 0.36243
+v -0.609914 0.72012 -0.383201
+v -0.732497 0.514583 0.51069
+v -0.720448 0.525745 0.49534
+v -0.614654 0.722638 -0.366463
+v -0.620165 0.723691 -0.350034
+v -0.625714 0.724706 -0.333605
+v -0.697057 0.545707 0.463972
+v -0.708437 0.536355 0.479746
+v 0.66398 0.02483 0.0145023
+v 0.663376 0.0373027 0.033873
+v 0.662297 0.0467954 0.0518436
+v 0.660255 0.0546824 0.069583
+v 0.657493 0.061195 0.0870654
+v 0.654089 0.0671424 0.104561
+v 0.650672 0.0715483 0.121427
+v 0.647461 0.076892 0.138575
+v 0.643838 0.0824668 0.155916
+v 0.639856 0.0862048 0.172718
+v 0.636054 0.0901611 0.18952
+v 0.632252 0.0941175 0.206308
+v 0.628244 0.0978812 0.223097
+v 0.623761 0.101182 0.239886
+v 0.619445 0.103996 0.256469
+v 0.614872 0.107168 0.273207
+v 0.610376 0.109827 0.289764
+v 0.605585 0.112165 0.30627
+v 0.60019 0.113257 0.32252
+v 0.594166 0.113141 0.338589
+v 0.587049 0.110701 0.354312
+v 0.579753 0.108479 0.369623
+v 0.571365 0.103584 0.385102
+v 0.562386 0.097483 0.400401
+v -0.631777 0.724462 -0.317433
+v -0.638353 0.723203 -0.301415
+v -0.644982 0.722175 -0.285461
+v -0.651636 0.720724 -0.269507
+v -0.658893 0.718104 -0.253695
+v -0.666395 0.715085 -0.237985
+v -0.581654 -0.863101 0.362636
+v -0.742542 0.528417 -0.351229
+v 0.656786 0.0265769 -0.00620428
+v 0.655977 0.0371358 0.0122673
+v 0.655669 0.0481056 0.0305461
+v 0.654153 0.05729 0.0486708
+v 0.651828 0.0657551 0.0668598
+v 0.649092 0.0714841 0.0839569
+v 0.645727 0.0774186 0.101478
+v 0.642592 0.0828522 0.118613
+v 0.639099 0.0877591 0.135646
+v 0.635258 0.0917283 0.152448
+v 0.631533 0.0963783 0.169481
+v 0.627525 0.100168 0.186257
+v 0.623504 0.103944 0.203033
+v 0.619304 0.107477 0.219822
+v 0.614949 0.110842 0.23661
+v 0.610569 0.113668 0.253207
+v 0.606009 0.116276 0.269777
+v 0.601308 0.118742 0.286322
+v 0.596555 0.121105 0.302854
+v 0.591404 0.122994 0.319244
+v 0.585187 0.122133 0.335211
+v 0.577955 0.119577 0.350946
+v 0.570402 0.116635 0.366476
+v 0.562168 0.112384 0.381749
+v 0.553472 0.107078 0.396907
+v -0.673974 0.71213 -0.222262
+v -0.680987 0.707468 -0.206193
+v -0.690775 0.702702 -0.191382
+v -0.759485 0.887572 -0.64879
+v -0.737802 0.66134 -0.133052
+v -0.13555 -0.92445 0.0747853
+v -0.126314 -0.923371 0.0523703
+v 0.647486 0.0594095 0.0278358
+v 0.449707 -0.0214902 -0.197522
+v 0.461371 -0.0253052 -0.193463
+v 0.645598 0.0682085 0.0460632
+v 0.643093 0.0749395 0.0634301
+v 0.640267 0.081375 0.0809125
+v 0.637069 0.0867443 0.0980482
+v 0.633832 0.0926146 0.115389
+v 0.630184 0.0967765 0.132165
+v 0.626459 0.101452 0.149211
+v 0.622695 0.105473 0.165987
+v 0.618752 0.109956 0.182956
+v 0.614538 0.11291 0.19959
+v 0.610171 0.116263 0.216366
+v 0.605816 0.119628 0.233142
+v 0.601423 0.122441 0.249751
+v 0.59676 0.124933 0.266296
+v 0.592123 0.127451 0.282866
+v 0.587255 0.129712 0.299385
+v 0.582168 0.131651 0.31575
+v 0.576041 0.130958 0.33182
+v 0.56886 0.12889 0.347427
+v 0.561205 0.125383 0.363059
+v 0.553356 0.122082 0.378333
+v 0.544788 0.117008 0.393631
+v -0.450928 -0.718425 0.186783
+v -0.756093 0.646106 -0.130457
+v -0.743672 0.663331 -0.143341
+v 0.826935 -0.83533 0.329957
+v 0.845201 -0.815856 0.338525
+v 0.638443 0.0684012 0.0243932
+v 0.636658 0.0772516 0.0426079
+v 0.63423 0.0847404 0.0604243
+v 0.631109 0.090174 0.0775471
+v 0.628283 0.0965067 0.0949011
+v 0.624802 0.101452 0.111934
+v 0.621166 0.106231 0.12898
+v 0.617518 0.110431 0.145743
+v 0.613716 0.11503 0.162763
+v 0.609631 0.118177 0.179333
+v 0.605444 0.122326 0.19634
+v 0.601154 0.125691 0.213091
+v 0.596658 0.128402 0.229674
+v 0.592162 0.131112 0.246232
+v 0.587499 0.133617 0.26284
+v 0.582875 0.136173 0.279411
+v 0.577852 0.138164 0.295853
+v 0.572663 0.13959 0.312218
+v 0.566548 0.139346 0.328262
+v 0.559625 0.137599 0.343997
+v 0.552226 0.134876 0.359604
+v 0.544673 0.131934 0.375108
+v 0.536863 0.128273 0.390677
+v -0.780846 0.618822 -0.184677
+v -0.778624 0.626773 -0.178421
+v 0.634449 0.0676819 0.0155171
+v -0.557017 -0.847674 0.362571
+v -0.246919 -0.971438 0.326091
+v -0.3076 -0.3162 -0.255621
+v -0.30769 -0.297703 -0.25593
+v -0.294793 -0.315904 -0.259051
+v -0.113944 -0.599618 0.536689
+v -0.106764 -0.599002 0.547749
+v -0.116603 -0.581057 0.53904
+v -0.121215 -0.469496 0.594468
+v -0.127547 -0.450664 0.600415
+v -0.134805 -0.451384 0.589355
+v -0.0892042 -0.616189 0.567146
+v -0.0916191 -0.597949 0.569034
+v -0.0994547 -0.598334 0.558745
+v -0.0871361 -0.652374 0.5659
+v -0.0880609 -0.634288 0.566439
+v -0.0960507 -0.634712 0.556291
+v -0.892716 -0.102441 0.0765708
+v -0.895889 -0.11932 0.0759928
+v 0.628925 0.0769433 0.0211691
+v 0.627307 0.0858837 0.0393066
+v 0.624648 0.0924861 0.0567248
+v 0.621873 0.098973 0.0741816
+v 0.618867 0.104959 0.0914842
+v 0.615617 0.110187 0.108466
+v 0.611892 0.114863 0.125524
+v 0.608308 0.119153 0.142275
+v 0.604506 0.123764 0.159307
+v 0.600537 0.127579 0.17607
+v 0.596362 0.131163 0.192885
+v 0.591866 0.133874 0.209417
+v 0.587537 0.137239 0.226206
+v 0.582862 0.139744 0.242789
+v 0.578096 0.14212 0.259321
+v 0.573382 0.144587 0.275853
+v 0.568321 0.146513 0.292333
+v 0.56281 0.147092 0.308544
+v 0.556747 0.146912 0.324652
+v 0.550376 0.146346 0.34058
+v 0.543465 0.144651 0.356303
+v 0.535784 0.141093 0.371948
+v 0.528462 0.138472 0.38762
+v 0.520703 0.1353 0.403085
+v -0.667487 0.909524 -0.725027
+v -0.921798 -0.274453 0.102814
+v -0.0374633 -0.167246 0.61091
+v -0.119095 -0.374595 0.679927
+v -0.11984 -0.356688 0.680441
+v -0.126224 -0.35733 0.668392
+v -0.217888 0.157471 -0.0756331
+v -0.229449 0.161555 -0.0800262
+v -0.532727 -0.668893 0.113051
+v -0.902466 -0.136661 0.0765451
+v 0.619253 0.0845991 0.0174182
+v 0.617493 0.0933982 0.0356329
+v 0.614808 0.0999364 0.0530768
+v 0.612303 0.107194 0.0708161
+v 0.609182 0.112615 0.0877591
+v 0.606035 0.117984 0.104741
+v 0.602631 0.123508 0.122069
+v 0.598931 0.127669 0.138781
+v 0.595232 0.132396 0.155852
+v 0.59125 0.136212 0.172615
+v 0.587191 0.139937 0.189404
+v 0.582515 0.142454 0.205962
+v 0.578122 0.145768 0.22275
+v 0.573485 0.148248 0.239308
+v 0.568706 0.150598 0.25584
+v 0.563992 0.153065 0.272372
+v 0.5587 0.154336 0.288724
+v 0.55333 0.155441 0.304986
+v 0.54737 0.155402 0.32112
+v 0.541166 0.155094 0.337138
+v 0.534435 0.15363 0.352963
+v 0.527062 0.150894 0.368634
+v 0.519599 0.147978 0.38419
+v 0.511635 0.144176 0.399784
+v 0.5029 0.138871 0.415057
+v -0.209462 0.8026 -0.172744
+v -0.222821 0.795124 -0.167657
+v -0.136231 -0.924014 0.713171
+v -0.682387 0.363625 -0.080039
+v 0.653524 -0.930989 0.287606
+v 0.637865 -0.935793 0.288788
+v 0.64484 -0.938953 0.269687
+v -0.0167695 0.727288 -0.227349
+v -0.52773 -0.832658 0.362481
+v 0.475308 0.179564 -0.00277458
+v 0.476837 0.169763 -0.0182275
+v -0.937443 0.303586 0.433567
+v -0.282886 -0.0943487 -0.247452
+v 0.609259 0.0919723 0.0138087
+v 0.607473 0.100681 0.032049
+v 0.604725 0.107194 0.0494929
+v 0.602194 0.113886 0.0668084
+v 0.599394 0.120168 0.0840596
+v 0.596414 0.126244 0.101311
+v 0.593035 0.131305 0.118318
+v 0.589503 0.136186 0.135351
+v 0.585752 0.140335 0.152127
+v 0.581821 0.144754 0.16916
+v 0.577698 0.148286 0.185923
+v 0.573164 0.150984 0.20248
+v 0.568514 0.153553 0.219064
+v 0.564069 0.156777 0.235801
+v 0.559342 0.159166 0.252359
+v 0.554448 0.161016 0.268736
+v 0.549284 0.162891 0.285204
+v 0.543619 0.163187 0.301376
+v 0.538212 0.164317 0.317703
+v 0.531956 0.163842 0.333695
+v 0.525148 0.162236 0.349508
+v 0.517723 0.159359 0.365102
+v 0.510312 0.156546 0.38067
+v 0.502425 0.152808 0.396355
+v 0.493754 0.14749 0.41164
+v -0.681565 0.479952 -0.363124
+v -0.5015 -0.817256 0.362404
+v -0.37929 0.265076 0.0712015
+v -0.147483 -0.45254 0.56563
+v 0.645984 -0.925889 0.0279642
+v -0.607795 0.72793 -0.419232
+v 0.23451 -0.142531 0.663228
+v -0.243219 -0.369739 -0.265538
+v -0.243296 -0.351319 -0.268826
+v -0.656709 0.307182 -0.0881958
+v -0.320509 -0.297703 -0.25548
+v -0.320689 -0.278833 -0.263149
+v 0.600653 0.0980867 0.0096982
+v 0.597133 0.107091 0.0280156
+v 0.594577 0.114285 0.0459733
+v 0.592059 0.121003 0.0631475
+v 0.589696 0.127901 0.080296
+v 0.586625 0.133822 0.0976371
+v 0.58326 0.138896 0.114619
+v 0.579895 0.144034 0.131613
+v 0.576324 0.148813 0.148659
+v 0.572213 0.152461 0.16546
+v 0.567987 0.155993 0.182223
+v 0.563491 0.158716 0.198794
+v 0.559021 0.161992 0.215608
+v 0.554474 0.164574 0.232153
+v 0.549734 0.166976 0.248685
+v 0.545058 0.169494 0.265255
+v 0.539702 0.170714 0.281595
+v 0.534666 0.172666 0.298037
+v 0.528937 0.172988 0.314247
+v 0.522617 0.172371 0.330188
+v 0.515463 0.169956 0.345962
+v 0.507935 0.166899 0.361467
+v 0.5001 0.163212 0.377074
+v 0.492482 0.160027 0.392642
+v 0.484338 0.155749 0.407941
+v 0.474563 0.148286 0.423034
+v -0.330272 0.22722 0.00554917
+v -0.479932 -0.801367 0.362302
+v 0.198402 -0.919518 0.301184
+v 0.430234 0.139038 0.444319
+v -0.683325 -0.431396 0.512604
+v -0.695143 -0.42893 0.508109
+v 0.294074 -0.976153 0.0672066
+v 0.287613 -0.971747 0.0857681
+v 0.280162 -0.977771 0.0658964
+v -0.466239 -0.784616 0.36216
+v -0.167548 -0.838721 -0.342841
+v 0.232237 -0.132628 0.642933
+v 0.221626 -0.137997 0.659246
+v 0.213328 -0.144805 0.674879
+v 0.554499 -0.713685 -0.248261
+v 0.170309 -0.92287 0.228646
+v 0.157503 -0.922395 0.225628
+v -0.612843 0.730152 -0.402572
+v -0.254125 -0.952158 0.601481
+v -0.250644 -0.926801 0.609664
+v -0.885715 -0.363304 0.103032
+v 0.586972 0.114182 0.024496
+v 0.58484 0.121966 0.0422867
+v 0.582284 0.12862 0.0594352
+v 0.579573 0.134991 0.0766736
+v 0.576812 0.14135 0.093912
+v 0.573934 0.14749 0.111163
+v 0.570389 0.152345 0.128183
+v 0.5666 0.156867 0.145242
+v 0.562566 0.160618 0.162005
+v 0.558135 0.163456 0.178614
+v 0.553896 0.16695 0.195326
+v 0.549348 0.169622 0.21187
+v 0.544968 0.172898 0.228646
+v 0.540228 0.175287 0.245191
+v 0.535309 0.177137 0.261594
+v 0.530363 0.17932 0.278126
+v 0.525007 0.180425 0.294401
+v 0.519136 0.180579 0.310586
+v 0.512842 0.179911 0.326553
+v 0.505584 0.177394 0.342212
+v 0.498019 0.174208 0.357754
+v 0.490067 0.170341 0.373259
+v 0.482514 0.167079 0.38875
+v 0.473844 0.161915 0.404113
+v 0.463979 0.154285 0.419104
+v -0.253444 -0.793775 -0.175737
+v -0.215268 0.11106 -0.129982
+v -0.228922 0.110906 -0.129738
+v -0.61784 0.731617 -0.38604
+v 0.220201 -0.129159 0.638617
+v 0.211093 -0.134773 0.654558
+v 0.201292 -0.14126 0.670602
+v -0.00685297 -0.683986 0.668392
+v -0.622952 0.733068 -0.369508
+v -0.628694 0.733903 -0.353156
+v -0.0681893 -0.921059 -0.0558514
+v -0.215448 -0.889717 -0.364254
+v -0.22846 -0.889948 -0.361364
+v 0.578726 0.11282 0.00265898
+v 0.576683 0.120746 0.0203983
+v 0.574435 0.128299 0.038279
+v 0.572213 0.135762 0.0557871
+v 0.569644 0.14239 0.0729741
+v 0.566779 0.148607 0.0902125
+v 0.563889 0.154722 0.107502
+v 0.560357 0.159551 0.124522
+v 0.556426 0.163521 0.141285
+v 0.552688 0.168004 0.158318
+v 0.548192 0.17083 0.174863
+v 0.544095 0.174491 0.191639
+v 0.539406 0.17697 0.208197
+v 0.535013 0.180309 0.224973
+v 0.53044 0.182904 0.241492
+v 0.525752 0.185332 0.258062
+v 0.520562 0.186809 0.274427
+v 0.515141 0.187888 0.290715
+v 0.50913 0.187811 0.306848
+v 0.502938 0.187349 0.322879
+v 0.495668 0.184728 0.338564
+v 0.487511 0.180412 0.353901
+v 0.481422 0.176327 0.367928
+v 0.471416 0.172358 0.384832
+v 0.46272 0.166719 0.399977
+v 0.452816 0.158896 0.414852
+v 0.441345 0.148248 0.429405
+v 0.190014 -0.151433 0.685733
+v -0.021047 -0.982755 -0.277291
+v -0.0747404 0.961483 -0.187092
+v -0.149628 -0.905748 0.708726
+v -0.13573 -0.906274 0.712786
+v -0.14652 -0.888137 0.705258
+v -0.634628 0.73389 -0.336906
+v -0.64091 0.733441 -0.320773
+v 0.215795 -0.12221 0.618218
+v 0.441088 0.21268 0.0255493
+v 0.448693 0.206116 0.0195762
+v 0.199044 -0.131189 0.650306
+v 0.188524 -0.139487 0.665952
+v 0.176565 -0.150316 0.681366
+v -0.766305 0.0949267 0.688302
+v -0.777185 0.11449 0.685425
+v -0.647769 0.731732 -0.304883
+v -0.654641 0.729985 -0.289006
+v -0.589952 -0.861714 0.37516
+v -0.336296 -0.836177 -0.177149
+v -0.32349 -0.818836 -0.164548
+v -0.320625 -0.820763 -0.176726
+v 0.568154 0.118935 -0.00128453
+v 0.566034 0.126745 0.0165191
+v 0.563966 0.13458 0.0342969
+v 0.56159 0.141799 0.0518822
+v 0.558918 0.148325 0.0690949
+v 0.556555 0.155531 0.0866287
+v 0.553408 0.16099 0.103572
+v 0.550235 0.166642 0.120836
+v 0.546394 0.17074 0.137612
+v 0.54263 0.174927 0.154362
+v 0.538353 0.17837 0.171164
+v 0.534152 0.181877 0.187914
+v 0.529464 0.184317 0.204484
+v 0.524814 0.186899 0.221042
+v 0.520138 0.18943 0.237599
+v 0.51536 0.191793 0.254157
+v 0.510119 0.193206 0.270535
+v 0.505032 0.19503 0.287015
+v 0.499136 0.19503 0.30311
+v 0.492392 0.193566 0.318962
+v 0.485019 0.190663 0.334594
+v 0.476952 0.186539 0.349983
+v 0.468731 0.182146 0.365243
+v 0.460331 0.177252 0.380747
+v 0.451326 0.171459 0.395725
+v 0.44069 0.162647 0.410626
+v 0.429861 0.153411 0.425539
+v -0.504403 -0.681417 0.176353
+v -0.0698592 0.962691 -0.200965
+v -0.317157 0.226193 0.00638411
+v -0.661668 0.72802 -0.273142
+v -0.669452 0.724269 -0.257561
+v 0.195422 -0.124188 0.629612
+v 0.185582 -0.130354 0.645669
+v 0.17442 -0.13765 0.661392
+v 0.164529 -0.146976 0.676973
+v -0.676427 0.72215 -0.241813
+v -0.685008 0.717281 -0.226308
+v 0.55554 0.133334 0.0131793
+v 0.553292 0.140617 0.0304048
+v 0.550967 0.147901 0.0479772
+v 0.54886 0.155505 0.0654339
+v 0.54624 0.162095 0.0826852
+v 0.543414 0.168222 0.0998722
+v 0.539997 0.173245 0.116879
+v 0.536285 0.177882 0.133976
+v 0.532804 0.182712 0.150945
+v 0.528398 0.185653 0.167438
+v 0.523838 0.188402 0.184009
+v 0.51938 0.191433 0.200811
+v 0.514705 0.194003 0.217355
+v 0.509965 0.196405 0.2339
+v 0.504788 0.19792 0.250265
+v 0.499958 0.200104 0.266771
+v 0.49464 0.201414 0.283136
+v 0.488539 0.201106 0.299193
+v 0.481731 0.199398 0.314992
+v 0.473792 0.195621 0.330471
+v 0.465815 0.191716 0.345975
+v 0.45807 0.188274 0.361313
+v 0.449489 0.183264 0.37674
+v 0.440189 0.176828 0.391974
+v 0.430041 0.16889 0.406798
+v 0.420587 0.162287 0.422096
+v -0.523414 0.615482 0.0457293
+v -0.526921 0.619811 0.059371
+v -0.282898 -0.0763653 -0.241787
+v -0.692342 0.71249 -0.210406
+v 0.306739 -0.973044 -0.173437
+v 0.300381 -0.977116 -0.195133
+v 0.20408 -0.121414 0.613556
+v 0.18196 -0.123508 0.624847
+v 0.17284 -0.128273 0.64116
+v 0.162936 -0.135325 0.656883
+v -0.460086 -0.767211 0.362109
+v -0.945395 0.195814 0.0876049
+v -0.942749 0.178087 0.0874636
+v 0.434306 -0.0378936 -0.205628
+v 0.419945 -0.0522547 -0.215955
+v 0.545238 0.139834 0.00912016
+v 0.543131 0.147631 0.026821
+v 0.540716 0.154812 0.044419
+v 0.538751 0.162634 0.0618244
+v 0.536092 0.169121 0.0789986
+v 0.533125 0.175094 0.0962755
+v 0.529567 0.179641 0.112923
+v 0.525931 0.184279 0.129982
+v 0.522283 0.188954 0.147027
+v 0.518288 0.192757 0.163752
+v 0.513793 0.195595 0.180309
+v 0.509284 0.198588 0.197073
+v 0.504338 0.200477 0.213425
+v 0.499483 0.202673 0.229995
+v 0.494589 0.204767 0.246488
+v 0.489322 0.206116 0.262866
+v 0.483555 0.206629 0.279038
+v 0.477312 0.205884 0.295018
+v 0.469939 0.203058 0.310638
+v 0.462617 0.200656 0.326425
+v 0.455167 0.197741 0.342032
+v 0.447562 0.194619 0.357536
+v 0.439495 0.190637 0.37304
+v 0.430542 0.185049 0.388134
+v 0.420292 0.177676 0.403175
+v 0.411878 0.172178 0.418628
+v 0.402835 0.166244 0.433644
+v -0.660126 0.905992 -0.730782
+v -0.653691 0.912196 -0.725066
+v -0.849556 0.477729 0.0604628
+v -0.611404 0.89655 -0.736626
+v 0.168575 -0.12284 0.62012
+v 0.159417 -0.127811 0.636292
+v 0.150258 -0.133527 0.652323
+v -0.942492 0.160695 0.0876435
+v 0.534782 0.146154 0.00513812
+v 0.532984 0.154413 0.0226976
+v 0.53107 0.162647 0.0406168
+v 0.528578 0.169417 0.0577139
+v 0.52561 0.175364 0.0750422
+v 0.522592 0.18126 0.0923577
+v 0.519367 0.186578 0.109275
+v 0.515809 0.191292 0.126334
+v 0.511853 0.195261 0.143071
+v 0.507717 0.198858 0.159847
+v 0.503221 0.201748 0.176392
+v 0.498455 0.204086 0.192936
+v 0.493715 0.20654 0.20952
+v 0.488911 0.208775 0.226064
+v 0.484004 0.210791 0.242571
+v 0.478622 0.212012 0.25891
+v 0.472803 0.212333 0.275044
+v 0.465417 0.21074 0.291755
+v 0.458648 0.208004 0.306592
+v 0.451917 0.206552 0.322481
+v 0.445212 0.205139 0.338371
+v 0.437826 0.20248 0.354055
+v 0.430311 0.199577 0.369713
+v 0.421332 0.1939 0.384781
+v 0.412302 0.188196 0.399797
+v 0.403721 0.183161 0.41534
+v 0.39419 0.176148 0.430215
+v -0.348602 0.764359 0.0243418
+v 0.155126 -0.122172 0.61538
+v 0.146764 -0.126411 0.631513
+v 0.13758 -0.131305 0.647853
+v 0.126353 -0.139487 0.663318
+v 0.522515 0.161029 0.0192808
+v 0.520742 0.169121 0.0365706
+v 0.518443 0.17643 0.0541044
+v 0.515642 0.182712 0.0713171
+v 0.512226 0.187695 0.0883371
+v 0.508706 0.192525 0.105383
+v 0.504968 0.196854 0.122082
+v 0.501268 0.201324 0.13914
+v 0.497094 0.204895 0.155903
+v 0.492585 0.207734 0.172474
+v 0.487781 0.210021 0.189019
+v 0.483054 0.2125 0.205563
+v 0.47834 0.21494 0.222134
+v 0.472932 0.215994 0.23846
+v 0.467511 0.21706 0.254786
+v 0.461538 0.217188 0.270907
+v 0.454871 0.215737 0.286823
+v 0.447665 0.213489 0.30261
+v 0.441294 0.212667 0.318563
+v 0.435089 0.212294 0.334581
+v 0.428474 0.211074 0.350522
+v 0.420985 0.208132 0.366207
+v 0.41234 0.202969 0.381608
+v 0.403323 0.197201 0.396637
+v 0.394486 0.191729 0.411807
+v 0.384569 0.183791 0.426721
+v 0.102294 -0.148543 0.674314
+v 0.11433 -0.137869 0.65881
+v -0.868182 -0.345693 0.359874
+v -0.110052 0.934598 -0.160656
+v -0.129744 0.91587 -0.160463
+v -0.723813 0.509997 -0.453837
+v -0.704892 0.495854 -0.45236
+v -0.707615 0.4943 -0.430356
+v 0.524377 0.143687 -0.0160309
+v 0.510068 0.175107 0.0326784
+v 0.507961 0.182712 0.050148
+v 0.505071 0.1888 0.0673864
+v 0.501615 0.193771 0.0843936
+v 0.498173 0.198691 0.101426
+v 0.494679 0.203521 0.118446
+v 0.490324 0.206732 0.134953
+v 0.486111 0.210162 0.15178
+v 0.481898 0.213643 0.168556
+v 0.477106 0.215929 0.185075
+v 0.472367 0.21837 0.201633
+v 0.467228 0.220117 0.218023
+v 0.462219 0.221877 0.234529
+v 0.456824 0.223007 0.250817
+v 0.450876 0.22311 0.266964
+v 0.443709 0.220811 0.282738
+v 0.437581 0.220502 0.29882
+v 0.431467 0.22031 0.314954
+v 0.42543 0.220066 0.331023
+v 0.418712 0.21873 0.346977
+v 0.41112 0.215608 0.362584
+v 0.402899 0.211292 0.377922
+v 0.394062 0.205666 0.393079
+v 0.384299 0.198293 0.408313
+v 0.374151 0.190098 0.423047
+v 0.361897 0.178036 0.437524
+v 0.100097 -0.138048 0.654147
+v 0.0889087 -0.148119 0.669446
+v -0.282975 -0.0578938 -0.2404
+v 0.19582 -0.154786 -0.338743
+v 0.197105 -0.164561 -0.353734
+v 0.184388 -0.163418 -0.355417
+v -0.204748 -0.981098 0.25101
+v 0.494126 0.194157 0.0631218
+v 0.497415 0.188877 0.046166
+v 0.491005 0.199783 0.0804886
+v 0.487563 0.204741 0.0975087
+v 0.483606 0.208685 0.114259
+v 0.479573 0.212538 0.131035
+v 0.475873 0.215955 0.14916
+v 0.470889 0.21891 0.164407
+v 0.466445 0.221825 0.18117
+v 0.461628 0.224125 0.197753
+v 0.456413 0.225692 0.214054
+v 0.451557 0.227786 0.230599
+v 0.445815 0.228402 0.246771
+v 0.439868 0.228518 0.262918
+v 0.433625 0.227927 0.278961
+v 0.427562 0.22776 0.295082
+v 0.421011 0.22672 0.3111
+v 0.414755 0.226141 0.327106
+v 0.407999 0.224536 0.342969
+v 0.400073 0.220875 0.358654
+v 0.39252 0.217715 0.374261
+v 0.383695 0.212089 0.389367
+v 0.37374 0.204356 0.404383
+v 0.363554 0.195994 0.419052
+v 0.352507 0.185949 0.433375
+v 0.0414967 -0.133437 0.603395
+v 0.037155 -0.611051 0.713197
+v 0.0293708 -0.629471 0.703408
+v 0.0859415 -0.138858 0.649124
+v 0.0747147 -0.148607 0.664616
+v -0.784931 0.770114 -0.43191
+v -0.09686 -0.466939 0.64274
+v -0.0905658 -0.466644 0.654288
+v -0.102987 -0.448622 0.648058
+v -0.546677 -0.807828 0.121658
+v -0.5564 -0.80865 0.113296
+v -0.56791 -0.823396 0.143315
+v 0.486715 0.194709 0.0423509
+v 0.483491 0.200181 0.0592297
+v 0.479997 0.205037 0.0762882
+v 0.476593 0.210098 0.0933082
+v 0.472585 0.214016 0.110059
+v 0.468423 0.217561 0.12686
+v 0.464287 0.22117 0.143675
+v 0.460176 0.224793 0.160476
+v 0.455398 0.227143 0.177021
+v 0.450542 0.229327 0.193591
+v 0.445302 0.230766 0.209944
+v 0.440395 0.232847 0.226437
+v 0.435102 0.234221 0.242815
+v 0.429656 0.235262 0.259128
+v 0.423131 0.234247 0.275108
+v 0.417016 0.233964 0.291203
+v 0.41085 0.233553 0.307285
+v 0.404119 0.232102 0.323149
+v 0.396888 0.229494 0.338885
+v 0.389373 0.226642 0.354633
+v 0.381923 0.223752 0.370317
+v 0.372597 0.217355 0.385552
+v 0.362591 0.209353 0.400375
+v 0.352353 0.200785 0.414993
+v 0.341923 0.191986 0.429521
+v -0.455732 -0.749574 0.362006
+v 0.0598527 -0.150611 0.659555
+v -0.208755 -0.0197946 -0.224215
+v 0.0331473 -0.163816 0.669805
+v -0.771341 0.85822 -0.572207
+v -0.449515 -0.749819 0.413516
+v 0.403349 -0.278306 -0.362289
+v 0.41649 -0.267092 -0.348724
+v 0.411647 -0.287041 -0.358756
+v 0.472726 0.205936 0.0554018
+v 0.475398 0.199359 0.0382405
+v 0.469168 0.210663 0.0724475
+v 0.465327 0.214902 0.0891207
+v 0.461795 0.219642 0.106205
+v 0.457607 0.223161 0.122994
+v 0.453407 0.226591 0.13977
+v 0.448873 0.229456 0.156289
+v 0.444197 0.232037 0.172859
+v 0.439316 0.23417 0.189417
+v 0.434409 0.236161 0.205974
+v 0.429129 0.237638 0.222288
+v 0.423888 0.239179 0.238678
+v 0.418493 0.240297 0.255031
+v 0.412469 0.240181 0.271126
+v 0.406303 0.239835 0.287208
+v 0.399701 0.238576 0.303162
+v 0.39288 0.236816 0.319013
+v 0.385519 0.234144 0.334671
+v 0.378185 0.231755 0.350574
+v 0.369078 0.228544 0.367221
+v 0.361396 0.222262 0.381467
+v 0.351891 0.214966 0.396213
+v 0.341717 0.206771 0.411037
+v 0.330773 0.197342 0.425886
+v -0.0251832 -0.684552 0.650319
+v -0.0283431 -0.666144 0.652952
+v -0.0360889 -0.666542 0.642612
+v -0.717365 -0.187773 0.543883
+v -0.708001 -0.204921 0.552939
+v -0.0589792 -0.250586 0.7068
+v -0.048035 -0.250124 0.714121
+v -0.0528134 -0.233168 0.700146
+v 0.04413 -0.153707 0.654339
+v -0.283053 -0.0394736 -0.237445
+v -0.158967 0.878156 -0.172782
+v -0.162577 0.871065 -0.175069
+v -0.169025 0.878361 -0.160155
+v 0.461435 0.210586 0.0512656
+v 0.458095 0.215814 0.0682471
+v 0.454524 0.220502 0.0852799
+v 0.450555 0.224484 0.102017
+v 0.446355 0.228017 0.118845
+v 0.44227 0.231626 0.135621
+v 0.438121 0.23521 0.152384
+v 0.433343 0.23751 0.168954
+v 0.428102 0.239051 0.185268
+v 0.422694 0.240181 0.20162
+v 0.417414 0.241633 0.217985
+v 0.412623 0.243855 0.234504
+v 0.4071 0.245358 0.251177
+v -0.123424 -0.581597 0.527544
+v -0.388191 -0.607082 0.50157
+v -0.397633 -0.607107 0.492758
+v -0.283155 -0.0211691 -0.232782
+v -0.199943 -0.648996 -0.152448
+v 0.592046 -0.457408 -0.263457
+v 0.477569 0.19187 0.0207965
+v -0.504878 -0.795304 0.51227
+v -0.509374 -0.801392 0.527364
+v -0.228177 -0.92508 0.641802
+v -0.220496 -0.924682 0.652271
+v -0.228922 -0.907045 0.64179
+v -0.120251 -0.287002 0.660531
+v -0.116359 -0.269597 0.656035
+v -0.127175 -0.287465 0.649304
+v -0.123989 -0.322096 0.665386
+v -0.122705 -0.304421 0.66328
+v -0.132159 -0.322378 0.654789
+v -0.268743 -0.874546 0.572245
+v -0.276925 -0.875163 0.562598
+v -0.279661 -0.892453 0.566298
+v -0.0743679 -0.502778 0.657422
+v -0.0813685 -0.503343 0.646208
+v -0.783904 0.86034 -0.614917
+v -0.781784 0.849562 -0.62387
+v -0.0857873 -0.706106 0.566401
+v -0.0782471 -0.705708 0.576857
+v -0.0863525 -0.688187 0.566336
+v 0.111683 -0.918285 0.0254337
+v 0.0988638 -0.917822 0.0224536
+v 0.10819 -0.916936 -0.000282597
+v -0.0812015 -0.183958 0.600248
+v -0.0711694 -0.183624 0.60852
+v -0.0724796 -0.539747 0.638797
+v -0.192288 -0.773839 0.547377
+v -0.176925 -0.758232 0.531654
+v -0.201151 -0.774353 0.538192
+v -0.0295506 -0.518963 0.703897
+v -0.0704629 -0.596125 0.602522
+v -0.0637191 -0.595572 0.613902
+v -0.0753184 -0.578154 0.60626
+v -0.0498205 -0.464846 0.704462
+v -0.0895767 -0.285474 0.702214
+v -0.0796858 -0.285191 0.710461
+v -0.0849138 -0.267902 0.697089
+v -0.0801354 -0.217535 0.654712
+v -0.0892427 -0.217676 0.645682
+v -0.0957167 -0.234774 0.652605
+v -0.0538154 -0.183585 0.627351
+v -0.0635906 -0.184458 0.619066
+v -0.0779003 -0.200387 0.633774
+v -0.788926 0.85095 -0.610087
+v -0.789979 0.832928 -0.596985
+v -0.790339 0.850166 -0.597923
+v -0.0938285 -0.251832 0.669304
+v -0.102088 -0.251961 0.659439
+v -0.109076 -0.268891 0.666671
+v -0.0872003 -0.559914 0.59976
+v -0.0916962 -0.541455 0.603742
+v -0.0985427 -0.541982 0.592438
+v -0.0884848 -0.579079 0.583408
+v -0.0816383 -0.578514 0.594673
+v -0.0940212 -0.560427 0.58843
+v -0.249578 -0.840108 0.569715
+v -0.256039 -0.840905 0.558552
+v -0.263887 -0.857539 0.566914
+v -0.0358705 -0.250085 0.720249
+v -0.0295378 -0.232782 0.713364
+v -0.112698 -0.506028 0.587236
+v -0.105518 -0.505861 0.597833
+v -0.1165 -0.487839 0.590344
+v -0.249449 -0.856293 0.588405
+v -0.243746 -0.839337 0.582264
+v -0.257362 -0.856833 0.57809
+v -0.0368339 -0.6487 0.642676
+v -0.0298846 -0.648122 0.65389
+v -0.0385166 -0.630434 0.644063
+v -0.385764 -0.660068 0.500723
+v -0.394113 -0.660492 0.490819
+v -0.0855176 -0.48482 0.650011
+v -0.0789151 -0.484409 0.661443
+v -0.366444 -0.642239 0.517704
+v -0.368165 -0.624192 0.518552
+v -0.377067 -0.642136 0.509714
+v -0.591365 -0.908908 0.567672
+v -0.598507 -0.90946 0.556651
+v -0.602322 -0.926596 0.560774
+v -0.609323 -0.927186 0.549548
+v -0.610826 -0.944643 0.551718
+v -0.144477 -0.758027 0.553761
+v -0.127933 -0.743627 0.518745
+v -0.57879 -0.857488 0.55344
+v -0.584866 -0.858554 0.541648
+v -0.393663 -0.678193 0.490947
+v -0.0361531 -0.593787 0.658488
+v -0.0435134 -0.594005 0.647891
+v -0.106944 -0.561763 0.564962
+v -0.110797 -0.543536 0.568096
+v -0.383927 -0.713197 0.500723
+v -0.107586 -0.707712 0.533722
+v -0.100932 -0.707108 0.545154
+v -0.108267 -0.689805 0.533722
+v -0.778162 0.861932 -0.586555
+v -0.0955754 -0.523266 0.606902
+v -0.102461 -0.523818 0.595611
+v -0.133842 -0.888548 0.710473
+v -0.4908 -0.672695 0.279398
+v -0.502861 -0.65186 0.308839
+v -0.522283 -0.657358 0.296816
+v -0.0935716 -0.268402 0.687609
+v -0.100791 -0.268672 0.676639
+v -0.106532 -0.286078 0.682997
+v -0.290259 -0.973596 0.432797
+v -0.303554 -0.974059 0.430395
+v -0.28322 -0.00292873 -0.22487
+v -0.590505 -0.87524 0.547595
+v -0.584737 -0.874482 0.559914
+v -0.595245 -0.892299 0.552952
+v -0.588796 -0.891579 0.564538
+v -0.0810217 -0.233861 0.674044
+v -0.0877013 -0.234452 0.662638
+v -0.0135454 -0.166578 0.641186
+v -0.00434813 -0.166809 0.650062
+v 0.0109763 -0.149995 0.616227
+v 0.0610473 -0.116725 0.584435
+v -0.714539 -0.170508 0.540671
+v -0.207805 -0.805362 0.583202
+v -0.216334 -0.805837 0.572284
+v -0.226957 -0.822382 0.583331
+v -0.0989538 -0.504949 0.609792
+v -0.103565 -0.486554 0.613851
+v -0.109654 -0.487312 0.601635
+v -0.350349 -0.588302 0.536201
+v -0.359328 -0.60626 0.527454
+v -0.241729 -0.908394 0.61836
+v -0.251325 -0.908599 0.609702
+v -0.259892 -0.90892 0.600299
+v -0.257773 -0.89122 0.597679
+v -0.266842 -0.909511 0.589162
+v -0.080585 -0.559413 0.611154
+v -0.073777 -0.558886 0.62247
+v -0.0849781 -0.540941 0.615097
+v -0.166995 -0.757937 0.539862
+v -0.156822 -0.757924 0.547865
+v -0.139031 -0.74364 0.511808
+v -0.746768 0.34392 -0.0633145
+v -0.296039 -0.0211305 -0.231498
+v -0.295936 -0.0394993 -0.237587
+v -0.119057 -0.889318 0.713479
+v -0.384351 -0.570794 0.514942
+v -0.380998 -0.588828 0.512116
+v -0.151645 -0.72707 0.487864
+v -0.164362 -0.743833 0.499759
+v -0.228332 -0.765104 -0.118459
+v -0.131337 -0.72689 0.503574
+v -0.130335 -0.70915 0.501969
+v -0.086391 -0.670293 0.5659
+v -0.0792619 -0.669702 0.577024
+v -0.0223059 -0.702676 0.648032
+v -0.0340593 -0.684796 0.641057
+v -0.14372 -0.341338 0.631025
+v -0.143848 -0.323586 0.630678
+v -0.148935 -0.324241 0.617409
+v -0.707654 0.232654 -0.0949781
+v -0.707718 0.250663 -0.0917925
+v -0.12977 -0.304832 0.652104
+v -0.138325 -0.322956 0.643151
+v -0.0564101 -0.337112 0.74328
+v -0.0545604 -0.319514 0.740981
+v -0.427395 0.609291 -0.0514454
+v -0.414242 0.609445 -0.0615161
+v -0.414331 0.590473 -0.0600775
+v -0.170528 -0.905773 0.692696
+v -0.16625 -0.888689 0.687981
+v -0.177721 -0.888419 0.680274
+v -0.173122 -0.871553 0.676061
+v -0.0703601 -0.200888 0.644539
+v -0.755361 0.593093 -0.0391525
+v -0.242063 -0.855458 0.59904
+v -0.235718 -0.838939 0.592464
+v -0.617531 -0.910989 0.521057
+v -0.125544 -0.33963 0.66766
+v -0.132596 -0.340131 0.655907
+v -0.0729677 -0.233425 0.684629
+v -0.0874058 -0.2511 0.680916
+v -0.262654 -0.874045 0.583767
+v -0.0807777 -0.633697 0.577486
+v -0.0814199 -0.615791 0.577422
+v -0.192056 -0.90594 0.677872
+v -0.179905 -0.905953 0.684025
+v -0.190091 -0.888304 0.675676
+v -0.140123 -0.288415 0.625836
+v -0.146417 -0.288891 0.613761
+v -0.147933 -0.306566 0.615996
+v -0.0642586 -0.686607 0.598809
+v -0.0573478 -0.686029 0.610023
+v -0.0650935 -0.668546 0.599272
+v -0.414627 0.6287 -0.0601802
+v -0.908567 0.524923 0.34699
+v -0.0684205 -0.337112 0.736935
+v -0.0667891 -0.319514 0.734944
+v -0.107984 -0.468661 0.617268
+v -0.114548 -0.469033 0.605848
+v -0.00199744 -0.199051 0.702779
+v -0.374036 -0.695483 0.508622
+v -0.618148 -0.617859 0.000578038
+v -0.433394 -0.769061 -0.0847918
+v -0.420536 -0.768406 -0.0911502
+v 0.0875985 -0.922768 0.188441
+v 0.0795188 -0.92174 0.209186
+v -0.476297 -0.631231 0.372038
+v -0.459701 -0.648777 0.374466
+v -0.469052 -0.631719 0.37972
+v -0.0986326 -0.285705 0.693184
+v -0.0203148 -0.665695 0.663049
+v -0.0160374 -0.684282 0.659401
+v -0.0795188 -0.250509 0.691527
+v 0.290824 -0.957989 0.33137
+v 0.288961 -0.94535 0.342892
+v 0.279738 -0.954341 0.325885
+v -0.138119 -0.414042 0.609779
+v -0.131786 -0.413747 0.621263
+v -0.142217 -0.396046 0.613003
+v 0.0457357 -0.0985106 0.579631
+v -0.228023 -0.791232 0.529303
+v -0.218261 -0.775214 0.518333
+v -0.431506 -0.765361 0.476972
+v -0.108318 -0.67186 0.533298
+v -0.116064 -0.672259 0.522945
+v -0.0641173 -0.948201 -0.221504
+v -0.114227 -0.449817 0.62319
+v -0.120226 -0.450549 0.610961
+v -0.21794 -0.822048 0.592464
+v -0.933513 0.321479 0.523086
+v -0.935825 0.302378 0.528353
+v -0.0710795 -0.687159 0.58748
+v -0.0720557 -0.669124 0.588083
+v -0.0668919 -0.372681 0.736549
+v -0.0349071 -0.19882 0.681443
+v -0.0209314 -0.182198 0.667056
+v -0.0307838 -0.182827 0.658835
+v -0.0972967 -0.48622 0.625438
+v -0.0914649 -0.485565 0.637743
+v -0.102294 -0.467453 0.630229
+v -0.137374 -0.358525 0.643511
+v -0.131876 -0.357909 0.655984
+v -0.138158 -0.340747 0.643472
+v -0.207291 -0.838387 0.618552
+v -0.196951 -0.822587 0.607814
+v -0.214998 -0.839068 0.608122
+v -0.0901547 -0.337253 0.722484
+v -0.0986968 -0.337587 0.712811
+v -0.0997116 -0.355224 0.71443
+v -0.173418 -0.820917 0.638707
+v -0.597711 -0.859787 0.518115
+v -0.603658 -0.860506 0.505848
+v -0.609066 -0.876871 0.513093
+v -0.11731 -0.321569 0.676729
+v -0.433895 -0.750795 -0.0838669
+v -0.874668 0.190894 -0.0215929
+v -0.861797 0.191254 -0.0302121
+v -0.861849 0.172255 -0.0287349
+v -0.443323 -0.473298 0.555251
+v -0.0985299 -0.409958 0.696755
+v -0.103257 -0.391692 0.700852
+v -0.110425 -0.391846 0.690139
+v -0.106481 -0.373503 0.703588
+v -0.113276 -0.373978 0.692272
+v -0.238312 -0.962305 0.204112
+v -0.231748 -0.97438 0.216341
+v 0.670043 -0.306168 -0.203983
+v 0.656208 -0.333258 -0.216931
+v -0.120393 -0.431563 0.628559
+v -0.126725 -0.43182 0.617011
+v -0.654641 -0.284189 -0.204921
+v -0.737712 0.510357 -0.389662
+v -0.736427 0.52816 -0.389791
+v 0.0332372 0.916191 -0.339347
+v 0.0331473 0.898529 -0.338885
+v 0.0201478 0.91754 -0.329148
+v -0.0448494 -0.199308 0.673273
+v -0.207342 -0.871027 0.655855
+v -0.197554 -0.870693 0.664423
+v -0.200894 -0.85411 0.648957
+v -0.126777 -0.393875 0.652117
+v -0.121215 -0.393323 0.664564
+v -0.130579 -0.375815 0.655226
+v -0.140842 -0.452129 0.577139
+v -0.146469 -0.433606 0.5822
+v -0.458712 -0.914662 -0.126693
+v -0.744725 -0.231575 -0.165704
+v -0.757481 -0.232089 -0.158999
+v -0.0126719 -0.198254 0.69565
+v 0.000237638 -0.18144 0.682304
+v -0.0931477 -0.706684 0.555456
+v -0.0936743 -0.688803 0.555341
+v -0.101304 -0.689202 0.544923
+v -0.109641 -0.653761 0.534082
+v -0.111272 -0.635727 0.535084
+v -0.602952 -0.876692 0.523857
+v -0.0393644 -0.918259 0.436573
+v -0.0313875 -0.919235 0.416072
+v -0.555835 -0.925388 0.605412
+v -0.553382 -0.908047 0.602175
+v -0.562425 -0.908317 0.593042
+v -0.565765 -0.925504 0.597024
+v -0.548809 -0.890937 0.597448
+v -0.558918 -0.891104 0.589265
+v -0.0470202 -0.166693 0.601995
+v -0.078838 -0.540093 0.627262
+v -0.0896794 -0.522624 0.619182
+v -0.711148 0.544384 -0.516753
+v -0.544275 -0.873904 0.592271
+v -0.555501 -0.873891 0.585283
+v -0.0984913 -0.428943 0.679131
+v -0.0916576 -0.428429 0.69046
+v -0.104965 -0.410279 0.685194
+v -0.190965 -0.853788 0.65732
+v -0.182551 -0.83691 0.648431
+v -0.191633 -0.837205 0.639221
+v -0.607409 -0.893699 0.528674
+v -0.614346 -0.894264 0.517396
+v -0.241639 -0.823551 0.561712
+v -0.231016 -0.807096 0.550627
+v -0.247535 -0.824129 0.549689
+v -0.0230509 -0.21566 0.706312
+v -0.0248235 -0.198588 0.689497
+v -0.0974765 -0.616664 0.557139
+v -0.702105 -0.113296 0.523022
+v -0.0449136 -0.631231 0.632117
+v -0.0469174 -0.612965 0.633723
+v -0.0538411 -0.61353 0.622509
+v -0.474139 -0.409804 -0.232654
+v -0.46132 -0.409547 -0.23214
+v -0.802067 0.742766 -0.455648
+v -0.801553 0.743473 -0.442302
+v -0.388487 0.533106 -0.0469753
+v -0.117053 -0.65416 0.523497
+v -0.483414 -0.612361 0.404884
+v -0.149616 -0.271306 0.602817
+v -0.486239 -0.565578 -0.113283
+v -0.390324 -0.589239 0.50324
+v -0.219867 0.813942 -0.162532
+v -0.218877 0.829151 -0.15327
+v 0.053096 0.891875 -0.351781
+v 0.0461981 0.879607 -0.345333
+v -0.135511 -0.772953 0.599644
+v -0.799074 0.743653 -0.429457
+v -0.498854 -0.56536 -0.111215
+v -0.549759 -0.58572 -0.0742972
+v -0.550363 -0.56748 -0.095235
+v -0.537094 -0.585938 -0.078048
+v -0.565829 0.468866 -0.0244703
+v -0.312571 0.706594 -0.126295
+v -0.299957 0.725939 -0.131523
+v -0.0137637 -0.647262 0.674096
+v -0.136411 -0.305384 0.640723
+v -0.101613 -0.201581 0.60274
+v -0.423118 -0.749163 0.467839
+v -0.438673 -0.767327 0.464704
+v -0.419341 -0.732054 0.463381
+v -0.0755368 -0.390626 0.727532
+v -0.0858644 -0.390882 0.719825
+v -0.779254 0.131973 0.686877
+v -0.796004 0.743717 -0.416624
+v -0.784649 0.751951 -0.395057
+v -0.119198 -0.506927 0.575251
+v -0.418249 -0.71452 0.461814
+v -0.0696665 -0.40884 0.722175
+v -0.123411 -0.488417 0.579092
+v -0.418044 -0.569882 0.492861
+v -0.0510408 -0.649651 0.620826
+v -0.0438988 -0.64906 0.631873
+v -0.0519014 -0.631783 0.62089
+v -0.0452733 -0.537678 0.683986
+v -0.0362815 -0.537422 0.693145
+v -0.0491911 -0.519554 0.687339
+v -0.418031 -0.696934 0.461198
+v -0.0429868 -0.501326 0.698784
+v -0.0525052 -0.501249 0.690062
+v -0.417864 -0.679439 0.460273
+v -0.418648 -0.661623 0.460709
+v -0.0691912 -0.25065 0.6989
+v -0.0627814 -0.233489 0.692002
+v -0.107367 -0.725618 0.534043
+v -0.115165 -0.708161 0.52324
+v -0.805394 0.0967508 0.659259
+v -0.807924 0.113989 0.661392
+v -0.816222 0.113501 0.652066
+v -0.813846 0.0960571 0.650216
+v 0.219147 -0.938426 0.62071
+v -0.011914 -0.181825 0.676228
+v -0.353034 -0.677821 0.524011
+v -0.131221 -0.507942 0.551243
+v -0.419213 -0.644012 0.460671
+v -0.133353 -0.253258 0.61791
+v -0.140611 -0.253605 0.606927
+v -0.144644 -0.271203 0.611475
+v -0.46403 -0.649484 0.360901
+v -0.11361 -0.356213 0.69204
+v -0.112557 -0.338589 0.690538
+v -0.0637063 -0.302096 0.731283
+v -0.0586195 -0.284742 0.725811
+v 0.105197 -0.0684911 -0.276148
+v 0.0894225 -0.0543228 -0.272706
+v 0.102306 -0.0543613 -0.272449
+v -0.0543934 -0.446528 0.708431
+v -0.616928 -0.172268 -0.206462
+v -0.0255043 -0.482521 0.716845
+v -0.0325564 -0.501082 0.706568
+v -0.420356 -0.626234 0.461377
+v 0.449797 -0.163508 -0.273605
+v -0.028523 -0.593466 0.668945
+v -0.500138 -0.353426 -0.255403
+v -0.500267 -0.335224 -0.255686
+v -0.487293 -0.35322 -0.25706
+v -0.788014 0.743923 -0.390934
+v 0.153855 -0.109391 -0.278345
+v -0.0406361 -0.920417 -0.194401
+v -0.0973866 -0.448095 0.660505
+v -0.104285 -0.429572 0.666787
+v -0.110014 -0.430176 0.654391
+v -0.0744578 -0.615226 0.588674
+v -0.0773094 -0.596677 0.591243
+v -0.0846184 -0.597345 0.580235
+v -0.0973224 -0.217908 0.635585
+v -0.104593 -0.235159 0.64337
+v -0.391069 -0.552399 0.521095
+v -0.40069 -0.534621 0.52622
+v -0.154831 -0.360349 0.606478
+v -0.148858 -0.359733 0.618797
+v -0.155846 -0.342533 0.606568
+v -0.753049 0.68134 -0.188736
+v -0.174394 -0.951785 0.684076
+v -0.163219 -0.95474 0.689446
+v -0.225917 -0.979608 0.199051
+v -0.0222159 -0.647776 0.664372
+v -0.425147 0.674006 -0.0418628
+v -0.416181 0.692464 -0.0425308
+v -0.403901 0.692798 -0.0552219
+v 0.537723 -0.322956 -0.28952
+v 0.540858 -0.304164 -0.283637
+v 0.552123 -0.311087 -0.275943
+v -0.093533 -0.201453 0.613157
+v -0.0914393 -0.184009 0.592566
+v -0.443092 -0.681918 0.413208
+v -0.448988 -0.664911 0.400542
+v -0.0659413 -0.650653 0.5994
+v -0.0587608 -0.650062 0.610498
+v -0.0666735 -0.632541 0.599837
+v -0.743711 0.510652 -0.351126
+v 0.0619079 0.873121 -0.355468
+v -0.395051 -0.642676 0.491191
+v -0.386354 -0.642432 0.500748
+v -0.395732 -0.625078 0.491358
+v -0.157426 -0.888291 0.697397
+v -0.245955 -0.873223 0.603446
+v -0.254793 -0.873583 0.594159
+v -0.604159 -0.172076 -0.208415
+v -0.689799 -0.309482 0.556356
+v -0.701976 -0.309392 0.550203
+v -0.525418 -0.656562 0.0268467
+v -0.528 -0.650062 0.0163778
+v -0.60547 0.250959 -0.0896216
+v -0.689259 -0.112897 0.529586
+v -0.0864938 -0.201157 0.62432
+v -0.364941 -0.677538 0.517062
+v -0.365622 -0.659876 0.517332
+v -0.642605 -0.15494 -0.189931
+v -0.629863 -0.15458 -0.195004
+v -0.110296 -0.411268 0.672053
+v -0.115576 -0.411705 0.659452
+v -0.785188 0.715586 -0.338589
+v -0.762786 0.64581 -0.141735
+v -0.629439 -0.13634 -0.192384
+v 0.747911 -0.85199 0.37638
+v 0.731148 -0.858888 0.379103
+v 0.736029 -0.866608 0.363586
+v -0.12747 0.858695 -0.213682
+v -0.147124 0.848008 -0.201684
+v -0.553459 0.156957 -0.0917411
+v -0.553806 0.17557 -0.0880417
+v -0.539201 0.168145 -0.08519
+v -0.170823 0.726581 -0.192744
+v 0.0593389 0.84174 -0.343856
+v -0.109949 -0.580556 0.550485
+v -0.102448 -0.653196 0.545167
+v -0.128164 -0.470022 0.583215
+v -0.780911 0.715907 -0.324909
+v -0.784995 0.708264 -0.326489
+v -0.110155 -0.252294 0.649304
+v -0.123244 -0.270034 0.644783
+v -0.235782 -0.907636 0.630499
+v 0.717943 -0.925838 0.130007
+v 0.700152 -0.934059 0.134529
+v -0.653716 -0.326849 0.575315
+v -0.650415 -0.308981 0.581019
+v -0.651212 -0.380259 0.556433
+v -0.662837 -0.380593 0.550203
+v -0.656941 -0.362353 0.561635
+v -0.661411 -0.344524 0.565476
+v -0.668206 -0.362456 0.554763
+v -0.672072 -0.344948 0.558282
+v -0.507036 0.638193 0.0463458
+v -0.624506 -0.896075 0.4915
+v -0.634294 -0.91393 0.482855
+v -0.142037 -0.306001 0.628264
+v -0.17379 -0.789511 0.583934
+v -0.163977 -0.773261 0.573568
+v -0.174279 -0.773081 0.56572
+v -0.106391 -0.338063 0.702586
+v -0.1044 -0.320606 0.700082
+v -0.656491 -0.309405 0.577833
+v -0.776505 0.716151 -0.311203
+v -0.149628 -0.341968 0.618707
+v -0.187111 -0.870731 0.672156
+v -0.299559 0.68748 -0.134413
+v -0.312199 0.687352 -0.127579
+v -0.299546 0.706684 -0.134233
+v -0.0683434 -0.354864 0.737474
+v -0.0798785 -0.354903 0.730987
+v -0.078594 -0.37286 0.730358
+v -0.634513 0.81899 -0.744257
+v -0.63486 0.837269 -0.749163
+v -0.622207 0.818798 -0.757346
+v -0.669529 -0.291897 0.571847
+v -0.679895 -0.292102 0.564153
+v -0.678713 -0.309546 0.563549
+v -0.570132 -0.891014 0.582226
+v -0.567101 -0.873686 0.578719
+v -0.0419335 -0.232693 0.707622
+v -0.115216 -0.430587 0.641764
+v -0.063475 -0.390831 0.733775
+v -0.108382 -0.922292 0.00836229
+v -0.121793 -0.922883 0.0061529
+v -0.113058 -0.922986 -0.0156713
+v -0.180521 -0.257034 -0.300092
+v -0.0576561 -0.668122 0.609792
+v -0.739998 0.404781 -0.0669882
+v -0.746948 0.381659 -0.0634429
+v -0.0533915 -0.26749 0.720069
+v -0.66827 -0.309251 0.571063
+v -0.676324 -0.327003 0.561763
+v -0.668758 -0.274787 0.570562
+v -0.57193 -0.908509 0.584512
+v -0.574705 -0.925709 0.587775
+v -0.376502 -0.659786 0.509701
+v -0.064477 -0.267709 0.712875
+v -0.272545 -0.89226 0.576535
+v -0.281807 -0.910321 0.56879
+v -0.584339 -0.955318 0.576959
+v -0.574744 -0.944104 0.59055
+v -0.58484 -0.943667 0.580248
+v -0.667602 -0.247901 -0.193643
+v -0.120046 0.860198 -0.21882
+v -0.12056 0.87858 -0.211459
+v -0.107265 0.879235 -0.222057
+v -0.761 0.699105 -0.235583
+v -0.11185 -0.882575 0.713158
+v -0.0595315 -0.632181 0.610524
+v -0.060739 -0.614095 0.611231
+v -0.0675085 -0.614622 0.599914
+v -0.47062 -0.714905 -0.0631732
+v -0.459264 -0.715008 -0.0735265
+v -0.6652 -0.327003 0.568867
+v -0.0621134 -0.576715 0.629574
+v -0.0552412 -0.576163 0.640852
+v -0.0672516 -0.558488 0.633941
+v -0.0100514 -0.592798 0.686889
+v -0.01474 -0.574377 0.690961
+v -0.019467 -0.593196 0.678129
+v -0.14476 -0.414967 0.597807
+v -0.148768 -0.396509 0.601597
+v -0.154651 -0.397138 0.589278
+v 0.0221517 -0.916473 -0.13756
+v -0.241973 -0.597242 -0.157599
+v -0.0566799 -0.519811 0.676703
+v 0.256 -0.970025 -0.186244
+v 0.268794 -0.970488 -0.183238
+v 0.254061 -0.957155 -0.174375
+v -0.454884 -0.686299 0.352796
+v -0.644172 0.344755 -0.084278
+v -0.130772 -0.691218 0.501904
+v -0.15826 -0.379001 0.592297
+v -0.15257 -0.37841 0.604705
+v -0.160252 -0.361133 0.593401
+v -0.216064 -0.871515 0.646427
+v -0.223271 -0.871964 0.635316
+v -0.227548 -0.889241 0.640081
+v -0.123231 -0.72653 0.513581
+v -0.156796 -0.415931 0.573902
+v -0.0437575 -0.666954 0.63222
+v -0.51378 -0.626773 0.354941
+v -0.52123 -0.633325 0.336881
+v -0.49378 -0.651591 0.317985
+v -0.0422803 -0.685245 0.631025
+v -0.151221 -0.415327 0.586324
+v -0.0799042 -0.651796 0.576972
+v -0.140123 -0.432784 0.594288
+v -0.224157 -0.806492 0.561776
+v -0.234741 -0.822973 0.572926
+v 0.631443 -0.931567 0.30708
+v -0.769684 0.680788 -0.226116
+v -0.774103 0.68057 -0.239745
+v -0.779575 0.662432 -0.23354
+v -0.254549 0.811553 -0.132859
+v -0.719484 -0.120502 -0.151677
+v -0.732355 -0.120977 -0.145139
+v -0.7196 -0.102197 -0.145319
+v -0.11573 -0.303971 0.674494
+v -0.233714 -0.889974 0.627942
+v -0.393304 -0.695855 0.491204
+v -0.113585 -0.286489 0.671912
+v -0.100418 -0.561327 0.576433
+v -0.104824 -0.542829 0.580363
+v -0.164452 -0.789742 0.592656
+v -0.0779388 -0.319617 0.727853
+v -0.0747789 -0.30225 0.724167
+v -0.0359733 -0.482816 0.709343
+v -0.765573 0.681186 -0.212384
+v -0.0506169 -0.667544 0.620955
+v -0.0875471 -0.503664 0.634583
+v -0.231826 -0.855985 0.607146
+v -0.116064 -0.392437 0.677795
+v -0.127984 -0.372848 -0.455327
+v -0.286868 0.687583 -0.141311
+v -0.146905 -0.37778 0.617088
+v -0.591108 -0.190033 -0.218023
+v -0.603967 -0.190187 -0.216186
+v -0.59134 -0.17196 -0.210252
+v -0.773358 0.6631 -0.203868
+v -0.759947 0.68143 -0.199899
+v -0.76908 0.663472 -0.190187
+v -0.225249 -0.839093 0.600184
+v -0.12476 -0.375198 0.667532
+v -0.0158318 -0.628983 0.675611
+v -0.767359 0.566169 -0.00462431
+v -0.0166668 -0.611243 0.675894
+v -0.0953314 -0.579631 0.572104
+v -0.130669 -0.270304 0.633838
+v -0.12598 -0.253027 0.628919
+v -0.137657 -0.270727 0.622624
+v -0.686677 -0.327272 0.554043
+v -0.698482 -0.32699 0.547364
+v -0.69504 -0.344665 0.544525
+v -0.365905 0.766903 -0.0187413
+v -0.364993 0.764257 0.00235069
+v -0.77179 0.645335 -0.168633
+v -0.764276 0.663395 -0.176726
+v -0.737365 -0.443073 0.465578
+v -0.72723 -0.448083 0.472219
+v -0.732407 -0.435263 0.476008
+v -0.197246 -0.789202 0.571089
+v -0.184285 -0.773467 0.557537
+v -0.206199 -0.789947 0.561661
+v -0.084734 -0.446926 0.684192
+v -0.0571295 -0.595097 0.625335
+v -0.161022 -0.905671 0.701854
+v -0.110874 -0.320991 0.688251
+v -0.118453 -0.33918 0.678257
+v -0.259533 -0.927058 0.600518
+v -0.473523 -0.651308 0.334081
+v -0.466329 -0.649818 0.346014
+v -0.496811 -0.630563 0.356508
+v -0.594988 0.527454 -0.0109442
+v 0.0361017 -0.914868 -0.136237
+v -0.687024 -0.380144 0.537704
+v -0.683158 -0.344922 0.551089
+v -0.767153 0.645476 -0.155197
+v 0.0521583 -0.923975 0.205628
+v -0.141446 -0.377318 0.629587
+v -0.0416123 -0.575097 0.663421
+v -0.0341107 -0.574878 0.67398
+v -0.0476625 -0.556677 0.66879
+v -0.143116 -0.359129 0.631141
+v -0.0646953 -0.216328 0.675367
+v -0.0735714 -0.216726 0.666157
+v -0.286392 -0.892568 0.556805
+v -0.206405 -0.82242 0.599105
+v -0.133585 -0.287876 0.637294
+v -0.216552 -0.855176 0.628302
+v -0.222924 -0.855574 0.616253
+v -0.228871 -0.872799 0.622907
+v -0.256244 -0.824951 0.539798
+v -0.263913 -0.841354 0.548507
+v -0.115357 -0.525116 0.572142
+v -0.20205 -0.888008 0.669446
+v -0.509233 -0.657628 -0.0114195
+v -0.519252 -0.641841 -0.00849074
+v -0.271376 -0.858246 0.556304
+v -0.132994 -0.432681 0.604898
+v -0.119699 -0.235711 0.622098
+v -0.111388 -0.218511 0.613145
+v -0.507588 -0.839145 0.210637
+v -0.545302 -0.925285 0.612811
+v -0.54335 -0.907931 0.61037
+v -0.117978 -0.252693 0.639066
+v -0.112544 -0.235531 0.633196
+v -0.0344704 -0.983308 -0.279385
+v -0.0473028 -0.982807 -0.282391
+v -0.0390818 -0.984207 -0.303637
+v -0.285493 0.611179 -0.121324
+v -0.691649 -0.362379 0.541738
+v -0.680114 -0.362122 0.548212
+v -0.714744 -0.957334 0.0562367
+v -0.715721 -0.951567 0.0385744
+v -0.719741 -0.958246 0.033051
+v -0.351672 0.779209 -0.0305333
+v -0.365879 0.766877 -0.0315224
+v -0.453959 -0.68924 0.31611
+v -0.451994 -0.690923 0.296161
+v -0.752163 -0.257484 0.526323
+v -0.763017 -0.2576 0.519001
+v -0.762722 -0.274799 0.519168
+v 0.054342 -0.920802 0.342546
+v 0.0410086 -0.921406 0.340323
+v 0.0496021 -0.921355 0.318859
+v -0.539342 -0.89077 0.606015
+v 0.209423 -0.126064 0.629702
+v -0.0697821 -0.28487 0.718733
+v -0.882568 0.511384 0.415584
+v -0.875349 0.511179 0.426605
+v -0.108819 -0.303496 0.685721
+v -0.153867 -0.307144 0.603703
+v -0.091542 -0.447402 0.672837
+v -0.155447 -0.324793 0.60599
+v 0.0363458 -0.648405 0.697063
+v -0.120084 0.841187 -0.222198
+v -0.699908 -0.153501 0.543343
+v -0.410362 -0.71407 0.472167
+v -0.410131 -0.696498 0.471487
+v -0.410349 -0.678887 0.471178
+v -0.184414 -0.806004 0.594994
+v -0.186135 -0.789318 0.578026
+v -0.203951 -0.905825 0.671796
+v -0.213559 -0.906005 0.663087
+v -0.213148 -0.923975 0.663177
+v -0.409335 -0.58974 0.485899
+v -0.0688058 -0.577216 0.618218
+v -0.706523 -0.344819 0.537987
+v -0.702786 -0.362366 0.534673
+v -0.6982 -0.380169 0.530678
+v -0.0951644 -0.391242 0.710962
+v -0.764058 0.62748 -0.121619
+v -0.769414 0.609484 -0.115633
+v -0.0313361 -0.630126 0.654751
+v -0.410773 -0.661199 0.471037
+v -0.411339 -0.643549 0.470986
+v -0.412366 -0.625784 0.471589
+v -0.249976 -0.890744 0.607917
+v -0.0717988 -0.704911 0.588777
+v -0.812138 0.148158 0.665117
+v -0.776466 0.583087 -0.145935
+v -0.604635 -0.025575 -0.170842
+v -0.591982 -0.02483 -0.18099
+v -0.60353 -0.227143 -0.221774
+v -0.590813 -0.208428 -0.222211
+v -0.798239 0.0681058 0.65073
+v -0.788643 0.114554 0.678322
+v -0.798971 0.114246 0.670512
+v -0.667435 -0.358204 -0.203598
+v -0.654346 -0.357587 -0.20961
+v -0.0608161 -0.557524 0.6459
+v -0.136501 -0.395455 0.625373
+v -0.544249 -0.649445 0.046911
+v -0.534679 -0.658411 0.051728
+v -0.537646 -0.659234 0.0645091
+v -0.406021 -0.57123 0.500324
+v -0.411518 -0.563164 0.502649
+v -0.10923 -0.524332 0.584307
+v -0.121189 -0.525771 0.559824
+v -0.1123 -0.617615 0.535675
+v -0.105235 -0.617062 0.546824
+v -0.124028 -0.527621 0.553594
+v -0.103989 -0.635136 0.546079
+v -0.0626401 -0.200232 0.654879
+v -0.0473799 -0.184035 0.639323
+v -0.0315288 -0.167271 0.622779
+v -0.808451 0.0739632 0.643793
+v -0.591301 -0.135055 -0.211357
+v -0.591019 -0.153797 -0.207503
+v -0.774449 0.583408 -0.120258
+v -0.772356 0.591629 -0.111947
+v -0.773332 0.573658 -0.110405
+v -0.769787 0.591757 -0.0963654
+v -0.765869 0.609664 -0.101131
+v -0.79251 0.743743 -0.40383
+v -0.18065 -0.853776 0.665207
+v -0.200971 -0.83813 0.630409
+v -0.189192 -0.822009 0.618167
+v -0.275153 -0.909807 0.579747
+v -0.265493 -0.891695 0.587326
+v -0.454871 -0.687699 0.33498
+v -0.108446 -0.449149 0.635572
+v -0.167612 -0.805169 0.614352
+v -0.155537 -0.789266 0.601892
+v -0.175743 -0.805516 0.604089
+v 0.00473349 -0.923693 0.288621
+v -0.459496 -0.669279 0.339026
+v -0.460215 -0.670216 0.32225
+v -0.0390818 -0.036866 -0.265731
+v -0.0248621 -0.0316251 -0.263367
+v -0.380343 -0.967315 -0.218743
+v -0.377581 -0.959916 -0.228043
+v -0.373882 -0.971644 -0.237265
+v -0.14923 -0.401082 -0.437113
+v -0.16372 -0.399733 -0.423869
+v -0.161343 -0.381749 -0.42473
+v -0.180008 -0.18388 -0.285243
+v -0.654795 -0.302481 -0.208608
+v -0.667577 -0.302905 -0.203585
+v -0.307227 -0.390805 -0.232847
+v -0.307369 -0.371961 -0.241119
+v -0.294485 -0.371897 -0.240926
+v -0.487177 -0.371576 -0.255262
+v -0.478738 -0.731604 -0.0492746
+v -0.539997 -0.0784719 -0.218396
+v -0.540087 -0.0601545 -0.213425
+v -0.527023 -0.0602316 -0.215788
+v -0.531519 -0.907957 0.617435
+v -0.472058 -0.621507 -0.0941689
+v -0.71856 -0.274543 0.547826
+v -0.397967 -0.00346823 -0.216122
+v -0.384004 -0.00429033 -0.214054
+v -0.18074 -0.820956 0.627865
+v -0.0831797 -0.522123 0.630653
+v -0.358172 0.764359 0.0136674
+v -0.672201 0.477062 -0.348364
+v -0.0538539 -0.199603 0.664166
+v -0.571674 -0.857038 0.564538
+v -0.564288 -0.840327 0.556728
+v -0.576799 -0.87402 0.570164
+v -0.596349 -0.875972 0.535251
+v -0.591083 -0.859106 0.529509
+v -0.580126 -0.891168 0.573992
+v -0.77206 0.573889 -0.0937064
+v -0.772638 0.565553 -0.107361
+v -0.0789022 -0.687596 0.577216
+v -0.761386 0.609933 -0.087682
+v -0.766447 0.592027 -0.081786
+v -0.235345 -0.972813 0.19101
+v -0.154869 -0.77312 0.582586
+v -0.0798014 -0.337138 0.730255
+v -0.461898 -0.671591 0.305564
+v -0.483606 -0.651449 0.326039
+v 0.0445796 -0.973584 -0.224626
+v 0.59238 -0.403689 -0.257574
+v 0.591815 -0.421223 -0.261749
+v 0.579008 -0.419001 -0.269944
+v -0.472829 -0.923628 -0.125447
+v -0.489258 -0.928561 -0.121157
+v -0.484017 -0.915728 -0.119294
+v -0.192108 -0.257574 -0.299077
+v -0.6029 -0.393336 -0.216405
+v -0.589927 -0.392912 -0.221093
+v -0.589914 -0.411743 -0.214799
+v -0.170887 0.764822 -0.200554
+v -0.178363 -0.238691 -0.298139
+v -0.179892 -0.202121 -0.289739
+v -0.52701 -0.0785105 -0.219308
+v -0.6545 -0.320927 -0.211292
+v -0.667615 -0.321389 -0.205345
+v -0.0549586 0.897437 -0.262853
+v -0.0625502 0.916114 -0.249661
+v -0.333766 -0.241106 -0.272719
+v -0.320882 -0.240811 -0.275968
+v -0.320741 -0.259565 -0.272333
+v -0.0401223 -0.556458 0.679362
+v -0.0315802 -0.555765 0.689009
+v -0.211941 -0.888227 0.660993
+v -0.0744064 -0.268004 0.704654
+v -0.286919 0.706787 -0.141196
+v -0.582721 -0.908535 0.577088
+v -0.237156 -0.87235 0.611423
+v -0.240175 -0.890642 0.616472
+v -0.1016 -0.671295 0.544653
+v -0.417954 0.652194 -0.0540787
+v -0.442064 -0.628007 0.428519
+v -0.437838 -0.681186 0.425847
+v -0.438031 -0.716369 0.427312
+v -0.437659 -0.698797 0.426156
+v -0.440176 -0.733878 0.429868
+v -0.071696 -0.484293 0.672143
+v -0.0845413 -0.465886 0.666504
+v -0.220008 -0.790949 0.53922
+v -0.209064 -0.775188 0.527261
+v -0.0498847 -0.685643 0.620569
+v -0.0527621 -0.53791 0.673466
+v -0.063565 -0.52035 0.665463
+v -0.286906 0.725965 -0.139423
+v -0.448667 -0.628495 0.417074
+v 0.000789986 -0.14993 0.608212
+v -0.768438 0.58387 -0.081619
+v -0.8563 -0.381403 0.360169
+v -0.500061 0.332809 -0.0308287
+v -0.0902189 -0.35507 0.723139
+v -0.0894996 -0.372822 0.722882
+v -0.115113 -0.690358 0.52247
+v -0.70994 -0.327144 0.540748
+v -0.830416 0.375635 0.62134
+v -0.822285 0.393002 0.612682
+v -0.122692 -0.690769 0.511949
+v -0.0729292 -0.651244 0.588186
+v -0.0734815 -0.633325 0.588083
+v -0.136064 -0.376701 0.642098
+v -0.122242 -0.708752 0.512078
+v -0.106687 -0.355712 0.703254
+v -0.0506811 -0.594647 0.636844
+v -0.0400966 -0.519258 0.696408
+v 0.0541237 -0.981484 -0.287863
+v 0.0406875 -0.982023 -0.290021
+v 0.0419463 -0.968124 -0.308981
+v -0.439662 -0.645784 0.426567
+v -0.438018 -0.663537 0.425578
+v -0.102383 -0.580235 0.560954
+v 0.540922 -0.730743 -0.25873
+v -0.0462238 -0.482983 0.701392
+v -0.0559477 -0.482996 0.692927
+v -0.537081 -0.809087 0.528777
+v -0.55432 -0.824373 0.546349
+v -0.683363 -0.414903 0.52166
+v -0.695297 0.562367 -0.583074
+v -0.692728 0.580633 -0.583035
+v -0.124927 -0.956499 0.699298
+v -0.656465 0.232269 -0.0966609
+v -0.766498 0.583896 -0.068838
+v -0.104336 -0.21819 0.624384
+v -0.532161 -0.925735 0.61827
+v -0.0400966 -0.6124 0.645014
+v -0.139892 -0.464769 -0.434813
+v -0.127226 -0.482585 -0.438384
+v -0.809594 0.131099 0.662792
+v -0.713306 -0.309456 0.543407
+v -0.844752 0.340991 0.636729
+v -0.834565 0.341197 0.644783
+v -0.837713 0.358487 0.629214
+v -0.746716 0.362764 -0.063019
+v 0.136244 -0.914444 -0.068671
+v 0.126841 -0.915253 -0.0458577
+v 0.122807 -0.915022 -0.0707776
+v -0.071452 -0.921046 0.409405
+v -0.0789665 -0.919017 0.429136
+v -0.0842587 -0.920597 0.406387
+v -0.456066 -0.647776 0.388994
+v -0.0663652 -0.44622 0.702098
+v -0.0759607 -0.446798 0.693556
+v -0.636427 -0.915279 0.467132
+v -0.62994 -0.898773 0.462277
+v -0.633935 -0.917398 0.447106
+v -0.624378 -0.882048 0.456612
+v -0.640537 -0.932389 0.471795
+v -0.640897 -0.934431 0.452912
+v -0.62407 -0.901406 0.439348
+v -0.390902 -0.964438 0.582778
+v -0.394858 -0.956448 0.596972
+v -0.644121 -0.95325 0.439733
+v -0.631957 -0.965658 0.44342
+v -0.642014 -0.952068 0.455366
+v -0.835824 0.148119 0.652387
+v -0.844919 0.166013 0.660094
+v -0.854129 0.148376 0.652233
+v -0.853409 0.183508 0.667981
+v -0.863018 0.182891 0.659786
+v -0.8563 0.165589 0.653556
+v -0.0943294 -0.670692 0.555675
+v -0.0947662 -0.652785 0.555521
+v -0.114445 -0.726132 0.522906
+v -0.149359 -0.491924 -0.411127
+v -0.14905 -0.473619 -0.423792
+v -0.139596 -0.483279 -0.428057
+v -0.0776948 -0.465372 0.677782
+v -0.0985812 -0.373079 0.713813
+v -0.197015 -0.805811 0.588713
+v -0.0964746 -0.320041 0.710088
+v -0.0590948 -0.538796 0.66152
+v -0.0543163 -0.557126 0.657358
+v 0.031015 -0.922536 0.153424
+v 0.0218434 -0.923615 0.175852
+v 0.0176302 -0.923127 0.151279
+v -0.618276 -0.945748 0.540222
+v -0.604288 -0.910218 0.544294
+v -0.600678 -0.893031 0.540003
+v -0.682272 0.485462 -0.393207
+v -0.180072 -0.924181 0.684911
+v -0.831791 0.166051 0.667313
+v -0.12783 -0.926493 0.124728
+v -0.295371 0.758438 -0.125023
+v -0.209064 -0.854392 0.638887
+v -0.289103 -0.910333 0.560813
+v -0.849504 0.218717 0.68134
+v -0.859742 0.218473 0.673428
+v -0.857392 0.200772 0.671629
+v -0.160444 -0.39778 0.576882
+v -0.718213 -0.136597 0.524974
+v -0.707153 -0.136417 0.532078
+v -0.713242 -0.11941 0.519592
+v -0.501988 0.0430703 -0.186013
+v -0.514782 0.031638 -0.189224
+v -0.871059 0.323021 0.627043
+v -0.861078 0.323419 0.635303
+v -0.864996 0.340452 0.620505
+v -0.120136 0.784051 -0.224561
+v 0.607139 -0.901277 -0.0178807
+v 0.594435 -0.902035 -0.0205782
+v -0.855555 0.340439 0.629253
+v -0.847925 0.358294 0.621237
+v -0.858779 0.357754 0.6138
+v -0.804777 0.461763 0.556625
+v -0.84059 0.375455 0.613337
+v -0.832407 0.392784 0.604654
+v -0.842709 0.392745 0.59678
+v -0.850763 0.37525 0.605309
+v -0.823274 0.410125 0.594981
+v -0.833525 0.410086 0.58712
+v -0.824996 0.426965 0.577987
+v -0.814167 0.427594 0.585373
+v -0.815028 0.444601 0.567557
+v -0.804058 0.445102 0.574789
+v -0.649516 -0.344806 0.57204
+v -0.877327 0.200412 0.655136
+v -0.886563 0.200168 0.646183
+v -0.884752 0.182519 0.645296
+v -0.833551 0.130919 0.650113
+v -0.852806 0.131009 0.651937
+v -0.849171 0.229456 -0.0390754
+v -0.819434 0.130932 0.654648
+v -0.731803 -0.212692 -0.168839
+v -0.122795 -0.672811 0.511538
+v 0.571828 0.10483 -0.0253309
+v -0.28927 -0.877822 -0.318538
+v -0.272956 -0.876011 -0.332411
+v -0.761797 0.575713 -0.0144124
+v -0.401602 -0.696215 0.481133
+v -0.40191 -0.678591 0.480838
+v -0.402784 -0.660762 0.481223
+v -0.403285 -0.643126 0.481198
+v -0.404261 -0.625309 0.481712
+v -0.405944 -0.607672 0.482919
+v -0.768708 0.565912 -0.0303663
+v -0.814681 0.478603 0.529804
+v -0.850545 0.236328 0.681764
+v -0.860269 0.236084 0.673492
+v -0.847115 0.201055 0.679516
+v -0.710673 -0.153283 0.536484
+v -0.722452 -0.153604 0.529817
+v -0.721296 -0.327221 0.533979
+v -0.724687 -0.309559 0.536715
+v -0.732522 -0.327285 0.52703
+v -0.735965 -0.309649 0.529933
+v -0.742773 -0.153887 0.513889
+v -0.739048 -0.136584 0.509804
+v -0.749054 -0.136841 0.501596
+v -0.745727 -0.171087 0.51737
+v -0.752612 -0.154182 0.50554
+v -0.755605 -0.171343 0.509072
+v -0.762234 -0.240323 0.517755
+v -0.752266 -0.240091 0.525925
+v -0.761476 -0.222982 0.516484
+v -0.751469 -0.222815 0.524628
+v -0.750467 -0.205525 0.523125
+v -0.760307 -0.205743 0.514827
+v -0.74854 -0.188299 0.520671
+v -0.758354 -0.188543 0.512373
+v -0.171144 0.561558 -0.0279642
+v -0.120046 0.803152 -0.225718
+v 0.0288441 -0.948368 -0.319784
+v -0.736081 -0.119166 0.505026
+v -0.745881 -0.11968 0.49782
+v -0.743595 -0.102493 0.494827
+v -0.873474 0.182622 0.652181
+v -0.883365 0.165345 0.644744
+v -0.868862 0.165358 0.648495
+v -0.294279 -0.427774 -0.220194
+v -0.85242 0.113848 0.651745
+v -0.0601481 -0.46509 0.696575
+v -0.822529 0.341685 0.651128
+v -0.646138 0.633543 -0.70188
+v -0.703877 -0.292102 0.551937
+v -0.716068 -0.292038 0.545861
+v -0.114484 -0.519323 -0.432052
+v -0.131337 -0.529881 -0.410947
+v -0.129423 -0.511705 -0.423664
+v -0.114419 -0.538269 -0.422238
+v -0.101728 -0.303085 0.696806
+v -0.720011 -0.204985 0.546799
+v 0.0440144 -0.667532 0.690152
+v -0.70127 -0.119102 0.526066
+v -0.221986 -0.906403 0.653158
+v -0.153264 -0.289379 0.602547
+v -0.184979 -0.758656 0.521532
+v -0.394768 -0.571128 0.507222
+v -0.213059 -0.790564 0.55037
+v -0.193084 -0.758977 0.511281
+v -0.634898 0.855587 -0.752336
+v -0.622335 0.837231 -0.760609
+v -0.848991 0.253913 0.679812
+v -0.859357 0.253707 0.671963
+v -0.727988 -0.291884 0.539323
+v -0.739228 -0.291999 0.532463
+v -0.747757 -0.309418 0.523279
+v -0.743788 -0.32735 0.52017
+v -0.852664 0.392308 0.588546
+v -0.843775 0.410022 0.579233
+v -0.854553 0.409367 0.57177
+v 0.136256 -0.113347 -0.280528
+v -0.624866 -0.902986 0.422829
+v -0.625508 -0.903718 0.406258
+v -0.636658 -0.920314 0.413696
+v -0.0203662 -0.555752 0.695958
+v -0.634217 -0.919081 0.429367
+v -0.643016 -0.93709 0.420529
+v -0.644378 -0.935934 0.437203
+v -0.644237 -0.954919 0.421878
+v -0.628809 -0.966467 0.400054
+v -0.635977 -0.964245 0.419026
+v -0.128087 -0.354864 -0.453901
+v -0.140752 -0.355609 -0.445475
+v 0.336784 -0.969396 0.281184
+v 0.326983 -0.971528 0.304356
+v 0.32173 -0.973147 0.28144
+v -0.869196 0.131035 0.649959
+v -0.870185 0.148376 0.649741
+v -0.885047 0.131086 0.647711
+v -0.618379 0.269674 -0.0908034
+v -0.535309 -0.918002 -0.0995896
+v -0.333021 -0.39069 -0.23408
+v -0.332995 -0.371666 -0.24162
+v -0.320188 -0.371807 -0.242339
+v -0.319251 -0.577435 -0.167015
+v -0.0343933 -0.215685 0.699504
+v -0.131748 -0.394646 0.638797
+v -0.222166 0.745425 -0.176122
+v -0.0235005 -0.166976 0.633145
+v -0.840667 0.323868 0.651411
+v -0.85156 0.323355 0.64396
+v -0.846614 0.306322 0.657795
+v -0.856852 0.306142 0.649779
+v -0.866537 0.270972 0.660377
+v -0.856377 0.271241 0.668469
+v -0.862504 0.288441 0.655842
+v -0.85233 0.28866 0.663896
+v -0.869428 0.253425 0.663794
+v -0.870571 0.235865 0.665566
+v -0.870006 0.21819 0.665438
+v -0.867372 0.200618 0.663357
+v -0.725702 -0.170637 0.533671
+v -0.846113 0.271434 0.676382
+v -0.36945 -0.606401 0.519297
+v -0.741373 -0.067502 0.491757
+v -0.742079 -0.0849845 0.492977
+v -0.0250034 -0.574583 0.683139
+v -0.283271 -0.92833 0.57141
+v -0.203322 -0.923924 0.671642
+v -0.751919 -0.274722 0.526567
+v -0.729851 -0.274632 0.54098
+v -0.741039 -0.274671 0.534018
+v -0.725265 -0.362494 0.520851
+v -0.72899 -0.344935 0.524088
+v -0.735669 -0.362803 0.513208
+v -0.739896 -0.344819 0.516689
+v -0.835233 0.426939 0.570126
+v -0.895979 0.217471 0.63678
+v -0.887989 0.217715 0.647005
+v -0.896737 0.235056 0.636818
+v -0.877854 0.357125 0.59651
+v -0.868182 0.357742 0.605014
+v -0.870802 0.374569 0.588983
+v -0.860834 0.374967 0.597204
+v -0.862748 0.392038 0.580453
+v -0.230297 -0.411833 -0.256482
+v -0.717108 -0.416393 -0.150932
+v -0.717468 -0.397652 -0.159333
+v -0.0395571 -0.924964 0.257523
+v -0.0487286 -0.926069 0.279835
+v -0.052929 -0.925568 0.255275
+v -0.735194 -0.398487 0.495739
+v -0.744623 -0.398975 0.487081
+v -0.738637 -0.416753 0.481634
+v -0.729016 -0.416946 0.490215
+v -0.72321 -0.434878 0.485
+v -0.750352 -0.345127 0.509098
+v -0.761322 -0.34505 0.501853
+v -0.756761 -0.362815 0.497922
+v -0.741077 -0.380658 0.501018
+v -0.751058 -0.380722 0.492823
+v -0.745997 -0.363047 0.505424
+v -0.754835 -0.327324 0.512964
+v -0.765638 -0.32726 0.505514
+v -0.0254016 -0.537563 0.700544
+v -0.884893 0.148337 0.64712
+v -0.8833 0.113707 0.646196
+v -0.895658 0.113527 0.640184
+v -0.891997 0.0961727 0.636857
+v -0.457029 -0.581738 0.464306
+v -0.617364 0.101028 -0.0988703
+v -0.617364 0.119461 -0.0935009
+v -0.604506 0.119513 -0.0950552
+v -0.320355 -0.791566 -0.125601
+v -0.330567 -0.783884 -0.122005
+v -0.627962 -0.449919 -0.190997
+v -0.849389 0.248235 -0.0324344
+v -0.0896024 -0.409739 0.706029
+v -0.426958 0.57132 -0.0477717
+v -0.427241 0.590318 -0.0514711
+v -0.414087 0.5715 -0.0563652
+v -0.19099 -0.924142 0.677551
+v -0.822838 0.148119 0.657602
+v -0.471377 -0.671681 0.296135
+v -0.480677 -0.672554 0.287452
+v -0.0769498 -0.28207 -0.454287
+v -0.0759607 -0.272988 -0.450074
+v -0.0641045 -0.281852 -0.456047
+v -0.847912 0.0967379 -0.0151446
+v -0.192609 -0.23882 -0.294247
+v -0.590441 -0.264009 -0.224639
+v -0.603466 -0.264099 -0.223585
+v -0.590646 -0.245525 -0.223662
+v -0.72845 -0.187901 0.536818
+v 0.204195 -0.924759 0.28383
+v 0.131067 -0.00574185 -0.265384
+v 0.127856 -0.0175081 -0.270599
+v 0.117001 -0.00687223 -0.264151
+v -0.560383 0.425912 -0.0289661
+v -0.638944 0.816319 -0.738309
+v -0.0603793 -0.501622 0.679799
+v -0.707179 -0.931836 0.0494544
+v -0.70854 -0.933288 0.0327684
+v -0.756055 -0.530331 0.0523831
+v -0.749902 -0.53096 0.0394864
+v -0.952331 0.422135 0.361878
+v -0.946949 0.43981 0.37367
+v -0.9521 0.439605 0.36067
+v -0.697262 -0.916345 0.0445989
+v -0.319366 -0.558616 -0.177368
+v -0.306495 -0.558963 -0.174375
+v -0.690942 -0.899209 0.0355044
+v -0.683094 -0.889768 0.028401
+v -0.658688 0.61511 -0.678913
+v -0.646639 0.59696 -0.667043
+v 0.642541 -0.878618 0.378577
+v -0.193033 -0.0568661 -0.25214
+v -0.667577 -0.229468 -0.191832
+v -0.654821 -0.229186 -0.195274
+v -0.720679 -0.380285 0.516856
+v -0.730994 -0.380542 0.509123
+v 0.581911 -0.903371 -0.0220554
+v -0.825214 0.444512 0.559593
+v -0.883262 0.339899 0.602277
+v -0.874887 0.340028 0.612181
+v -0.916236 0.182172 0.621969
+v -0.905998 0.182326 0.629972
+v -0.91427 0.199629 0.6194
+v -0.753139 -0.0851386 0.485848
+v -0.751636 -0.0676947 0.483998
+v -0.904392 0.199783 0.62766
+v -0.912177 0.21697 0.6166
+v -0.87445 0.172024 -0.0231087
+v -0.522283 -0.659311 0.292834
+v -0.825201 0.461776 0.540967
+v -0.835195 0.461429 0.532784
+v -0.835388 0.44437 0.551641
+v -0.845304 0.443921 0.543407
+v -0.844585 0.427029 0.561365
+v -0.855413 0.426451 0.553992
+v -0.758984 -0.309495 0.516407
+v -0.761424 -0.292102 0.518346
+v -0.771701 -0.292308 0.510575
+v -0.769286 -0.309726 0.508674
+v -0.879627 0.0964425 0.642702
+v -0.897225 0.130855 0.641533
+v -0.874489 0.0883885 0.640158
+v -0.162191 0.857449 -0.185859
+v -0.105312 -0.568417 -0.411037
+v -0.101394 -0.556124 -0.423741
+v -0.100868 -0.574956 -0.411846
+v 0.190965 -0.978259 -0.23986
+v 0.178158 -0.977758 -0.24284
+v -0.709234 -0.416098 0.506619
+v -0.709414 -0.380208 0.523741
+v -0.715014 -0.398191 0.51177
+v -0.876968 0.305487 0.633376
+v -0.867025 0.305885 0.641738
+v -0.881643 0.287863 0.638501
+v -0.872523 0.288133 0.64766
+v -0.885857 0.270496 0.64319
+v -0.876788 0.270766 0.652374
+v -0.888092 0.252975 0.645887
+v -0.879473 0.253155 0.655573
+v -0.889017 0.2353 0.647454
+v -0.879729 0.217998 0.656896
+v -0.880385 0.235583 0.657024
+v -0.731058 -0.257227 0.541609
+v -0.74163 -0.257291 0.533761
+v -0.731315 -0.222391 0.540697
+v -0.835644 0.306771 0.665258
+v -0.0641558 -0.483484 0.682933
+v -0.150129 -0.743614 0.504884
+v -0.0694353 -0.465501 0.687609
+v -0.708001 -0.930064 0.0683498
+v -0.714282 -0.950385 0.0525244
+v -0.701604 -0.913069 0.061529
+v -0.694295 -0.896961 0.0560697
+v 0.528796 -0.654751 -0.299116
+v 0.528899 -0.63669 -0.29778
+v -0.452842 -0.6961 0.361775
+v -0.15284 -0.433953 0.570537
+v -0.725188 -0.39841 0.50387
+v -0.617274 -0.0801932 -0.193412
+v -0.815002 0.461853 0.54888
+v -0.880179 0.322725 0.617885
+v -0.888374 0.322456 0.607788
+v -0.917983 0.164985 0.624359
+v -0.907874 0.165203 0.632541
+v -0.767102 -0.363098 0.490151
+v -0.903365 0.217227 0.625951
+v -0.761116 -0.380786 0.484692
+v -0.77585 -0.327478 0.497691
+v -0.771713 -0.345346 0.494171
+v -0.779331 -0.309918 0.500633
+v -0.773178 -0.274889 0.511474
+v -0.782157 -0.2753 0.502495
+v -0.78145 -0.292475 0.502225
+v -0.772882 -0.257831 0.51078
+v -0.781913 -0.258113 0.501763
+v -0.754154 -0.398744 0.478385
+v -0.864752 0.409213 0.563819
+v -0.29252 -0.782792 -0.128106
+v -0.292597 -0.765092 -0.121606
+v -0.869697 0.113989 0.650345
+v -0.89734 0.148183 0.640942
+v -0.63116 0.288403 -0.0881187
+v -0.0483047 -0.918053 -0.174105
+v -0.15293 -0.447312 -0.428506
+v -0.160765 -0.436355 -0.42419
+v -0.849928 0.0967765 0.64879
+v -0.400356 -0.589394 0.495032
+v -0.714179 -0.362533 0.527993
+v -0.540215 -0.0418885 -0.207079
+v -0.527139 -0.0418243 -0.211292
+v -0.717981 -0.344986 0.531371
+v -0.373252 -0.0396277 -0.230432
+v 0.520459 -0.185794 -0.254208
+v 0.512932 -0.164137 -0.252269
+v 0.523799 -0.165794 -0.249083
+v -0.511031 -0.795162 0.502392
+v -0.241151 -0.781392 -0.141234
+v -0.00332051 -0.922691 0.309225
+v -0.00859993 -0.924283 0.286412
+v -0.7303 -0.205139 0.53913
+v -0.731122 -0.239809 0.54107
+v -0.741951 -0.239912 0.533658
+v -0.830211 0.323791 0.659015
+v -0.621539 0.801598 -0.755869
+v -0.606908 0.651809 -0.7203
+v -0.456027 -0.95858 0.607454
+v -0.455642 -0.951682 0.616317
+v -0.470337 -0.961137 0.606491
+v -0.0998015 -0.150431 -0.292744
+v -0.292661 -0.74698 -0.119975
+v -0.715387 -0.927238 0.0937064
+v -0.713177 -0.948343 0.0705721
+v -0.70836 -0.969897 0.0687866
+v -0.695888 -0.912286 0.0738733
+v -0.68976 -0.895626 0.0682214
+v -0.677108 -0.877128 0.0714327
+v -0.0484203 -0.575611 0.65213
+v -0.0932376 -0.504345 0.622201
+v -0.590389 -0.301081 -0.225268
+v -0.603363 -0.301094 -0.225268
+v -0.590466 -0.282494 -0.224908
+v -0.848862 0.210599 -0.0403214
+v -0.60457 0.101208 -0.101683
+v -0.719472 -0.416342 0.498744
+v -0.885895 0.305089 0.624063
+v -0.893757 0.30469 0.613748
+v -0.908362 0.147965 0.633492
+v -0.918843 0.147772 0.62572
+v -0.918445 0.130418 0.625784
+v -0.292725 -0.728495 -0.121606
+v -0.754411 -0.102454 0.487826
+v -0.762606 -0.0853313 0.477306
+v -0.0446695 -0.215621 0.691694
+v -0.765355 -0.10266 0.480466
+v -0.633665 -0.922511 0.392642
+v 0.501333 -0.16433 -0.258704
+v 0.508706 -0.182082 -0.258023
+v -0.63784 -0.939659 0.397318
+v -0.629336 -0.942691 0.370844
+v -0.61721 -0.960828 0.350677
+v -0.605264 -0.969178 0.340002
+v -0.615245 -0.964836 0.355275
+v -0.283078 -0.947199 0.572309
+v 0.0415995 -0.948574 -0.31602
+v -0.633549 -0.96079 0.390266
+v -0.235846 -0.925773 0.631077
+v -0.872896 0.39182 0.572425
+v -0.879871 0.374273 0.57985
+v -0.896865 0.165345 0.639978
+v -0.398069 -0.223906 -0.257998
+v -0.385211 -0.223765 -0.258602
+v -0.385211 -0.242211 -0.259269
+v -0.758239 -0.416085 0.461198
+v -0.747076 -0.417472 0.471949
+v -0.46254 -0.772041 0.181915
+v -0.453189 -0.7719 0.190753
+v -0.460318 -0.754417 0.179205
+v -0.450196 -0.736292 0.186745
+v -0.459547 -0.718643 0.177342
+v -0.210836 -0.857102 -0.351255
+v -0.827706 0.334736 -0.0158126
+v -0.842221 0.334684 -0.00213232
+v -0.832613 0.352719 -0.00337831
+v -0.896094 0.252641 0.63556
+v -0.903262 0.234722 0.625258
+v -0.292854 -0.710114 -0.123238
+v -0.894013 0.270188 0.633055
+v -0.900616 0.269751 0.621545
+v -0.902633 0.252256 0.624025
+v -0.628642 -0.897167 0.477986
+v -0.741476 -0.22257 0.532784
+v 0.167137 -0.0276174 -0.267542
+v 0.179404 -0.0174568 -0.260284
+v -0.176976 -0.889575 -0.366207
+v -0.666331 -0.908497 -0.00227362
+v -0.664404 -0.892697 0.00355815
+v -0.653524 -0.889293 -0.00247914
+v -0.308409 -0.149211 -0.258948
+v -0.308383 -0.131073 -0.256482
+v -0.295654 -0.130675 -0.258987
+v -0.17686 -0.907764 -0.366862
+v -0.148485 -0.919479 0.461313
+v -0.153867 -0.921046 0.438603
+v -0.712908 -0.925953 0.109313
+v -0.715952 -0.943359 0.11291
+v -0.707628 -0.90883 0.10361
+v -0.696376 -0.893827 0.0939248
+v -0.776826 -0.144111 -0.116211
+v -0.202847 -0.728714 -0.115261
+v -0.713229 -0.434839 0.493221
+v -0.706434 -0.441942 0.493979
+v -0.768348 -0.421416 -0.0903538
+v -0.768091 -0.402263 -0.0982151
+v -0.889929 0.28767 0.628546
+v -0.897572 0.287195 0.61809
+v -0.292982 -0.691514 -0.124073
+v -0.908285 0.130662 0.633967
+v 0.354601 0.00540787 -0.226463
+v -0.891881 0.339321 0.592759
+v -0.899768 0.338923 0.582521
+v -0.903583 0.321415 0.586863
+v -0.904354 0.286823 0.606799
+v -0.90068 0.304356 0.602547
+v -0.910648 0.28654 0.594776
+v -0.896968 0.32189 0.598283
+v -0.907013 0.3041 0.590524
+v -0.886576 0.356598 0.587056
+v -0.894219 0.356675 0.576394
+v -0.912716 0.269122 0.597242
+v -0.125646 -0.854212 -0.35042
+v -0.940835 0.0947983 0.594378
+v -0.592997 0.288171 -0.0824283
+v -0.895786 0.182339 0.637795
+v -0.731931 -0.231151 -0.170778
+v 0.128768 -0.919877 0.333734
+v 0.115396 -0.920468 0.331524
+v 0.124028 -0.92043 0.310047
+v -0.392661 0.728097 0.0490305
+v -0.729285 -0.136764 0.517884
+v -0.740589 -0.205255 0.531371
+v 0.243964 -0.109288 -0.268158
+v -0.0530061 -0.918028 -0.127168
+v -0.0663781 -0.918593 -0.129326
+v -0.0570267 -0.917797 -0.152165
+v 0.545135 -0.630768 -0.283997
+v -0.210233 -0.632014 -0.167721
+v -0.208242 -0.612156 -0.165486
+v -0.0926981 -0.166038 0.593055
+v -0.709388 -0.960918 0.124689
+v -0.708026 -0.924874 0.122223
+v -0.703698 -0.907173 0.116931
+v -0.695977 -0.890616 0.110315
+v -0.684019 -0.875921 0.098562
+v -0.121651 -0.411846 0.647853
+v -0.866139 0.0968407 0.646761
+v -0.141883 -0.0554531 -0.266026
+v -0.362347 -0.943282 -0.265654
+v -0.293213 -0.635444 -0.135261
+v -0.775464 -0.189121 0.493157
+v -0.774013 -0.171729 0.491166
+v -0.783981 -0.17196 0.482945
+v -0.845047 0.460889 0.524486
+v -0.773036 -0.154465 0.48965
+v -0.7833 -0.15458 0.481763
+v -0.293265 -0.616459 -0.143623
+v -0.772279 -0.0856139 0.468776
+v -0.769401 -0.0673607 0.466965
+v -0.906589 0.269417 0.609342
+v -0.915452 0.251627 0.600569
+v -0.306046 -0.654134 -0.131896
+v -0.331903 -0.634712 -0.142364
+v -0.331852 -0.615971 -0.149622
+v -0.319084 -0.615868 -0.147592
+v -0.436079 -0.316598 -0.257548
+v -0.423208 -0.316431 -0.258846
+v -0.423131 -0.334633 -0.258512
+v -0.669324 -0.858426 0.100951
+v -0.89517 0.199873 0.636703
+v -0.847745 0.0776755 -0.00816961
+v -0.849235 0.0335905 0.0225563
+v -0.293393 -0.597075 -0.154722
+v -0.6145 -0.928895 0.337574
+v -0.617557 -0.946236 0.341145
+v 0.217863 -0.96368 0.228582
+v 0.204337 -0.948471 0.235403
+v -0.771945 -0.240567 0.509367
+v -0.73328 -0.153848 0.522405
+v -0.738637 -0.188068 0.528931
+v -0.220445 -0.888676 0.651244
+v -0.505443 0.634609 0.0916255
+v -0.699125 -0.924399 0.131831
+v -0.695592 -0.906737 0.127323
+v -0.688951 -0.889794 0.120181
+v -0.681938 -0.873121 0.112859
+v -0.293521 -0.578218 -0.163084
+v -0.29365 -0.559284 -0.171318
+v -0.631134 0.269636 -0.0922935
+v -0.451236 -0.754173 0.188261
+v -0.906525 0.113411 0.632528
+v -0.916762 0.113334 0.624744
+v -0.784559 -0.18934 0.484075
+v -0.785702 -0.206642 0.485809
+v -0.78926 -0.310085 0.492424
+v -0.786151 -0.327684 0.489881
+v -0.79057 -0.292796 0.493298
+v 0.371441 -0.947559 0.593234
+v -0.442553 -0.699709 0.412694
+v -0.908516 0.251935 0.611732
+v 0.545109 -0.582573 -0.27313
+v -0.112043 -0.730319 -0.332244
+v -0.407254 0.70933 0.0639696
+v 0.633922 -0.850962 0.397588
+v 0.723389 -0.825246 0.417215
+v -0.693897 -0.968176 0.139063
+v -0.699972 -0.971066 0.11747
+v -0.624095 -0.911823 0.509252
+v -0.293714 -0.540569 -0.179873
+v -0.621667 -0.968702 0.381094
+v -0.765008 -0.171472 0.500414
+v -0.762773 -0.154336 0.497563
+v -0.736414 -0.17092 0.526105
+v -0.293868 -0.521403 -0.189532
+v -0.75039 -0.292025 0.525501
+v -0.633357 -0.961059 0.48378
+v -0.63888 -0.948908 0.488828
+v -0.293907 -0.502675 -0.19792
+v -0.693922 -0.941586 0.145563
+v -0.690146 -0.924142 0.1409
+v -0.685265 -0.90666 0.135531
+v -0.679985 -0.889434 0.129596
+v -0.673113 -0.872645 0.122262
+v -0.66732 -0.960058 0.183058
+v -0.678752 -0.959248 0.166552
+v -0.675566 -0.966891 0.164561
+v -0.343708 -0.0183688 -0.225294
+v -0.360291 -0.0217086 -0.223367
+v -0.358185 -0.00346823 -0.215917
+v -0.457248 -0.789356 0.195338
+v -0.466727 -0.789382 0.186629
+v -0.459162 -0.736562 0.177535
+v -0.294035 -0.483857 -0.204292
+v -0.780692 -0.240901 0.50008
+v -0.779112 -0.223637 0.497974
+v -0.788721 -0.241183 0.48992
+v -0.777391 -0.206347 0.495649
+v -0.908696 -0.246771 0.337446
+v -0.910224 -0.229211 0.338332
+v -0.910802 -0.211613 0.338756
+v -0.916775 -0.212179 0.326502
+v -0.910571 -0.194221 0.33769
+v -0.910224 -0.176803 0.337112
+v -0.908554 -0.159487 0.3348
+v -0.906461 -0.14221 0.332282
+v -0.792176 -0.0730127 -0.0777397
+v -0.947874 0.032884 0.230072
+v -0.039647 -0.183418 0.649612
+v -0.60967 -0.867726 0.421184
+v -0.66696 -0.376598 -0.199487
+v -0.619818 -0.895137 0.504897
+v -0.759883 -0.137098 0.49412
+v -0.294112 -0.465218 -0.208916
+v -0.766961 -0.188736 0.502855
+v -0.94623 0.47457 0.353593
+v -0.77653 0.0933596 0.681032
+v 0.64186 -0.864013 0.38875
+v -0.687204 -0.961098 0.15801
+v -0.685406 -0.941432 0.154747
+v -0.679947 -0.924014 0.148967
+v -0.675515 -0.906711 0.144163
+v -0.670364 -0.889511 0.138395
+v -0.664815 -0.872491 0.132358
+v -0.615116 -0.878272 0.500067
+v -0.903159 0.0960186 0.629766
+v -0.540228 0.591102 0.0467697
+v -0.787449 -0.223919 0.488147
+v -0.895735 -0.28162 0.343804
+v -0.899717 -0.263701 0.347504
+v -0.90208 -0.246077 0.349341
+v -0.903609 -0.228582 0.350253
+v -0.903994 -0.211125 0.35006
+v -0.90411 -0.193694 0.3497
+v -0.903391 -0.176379 0.348429
+v -0.901798 -0.159012 0.346155
+v -0.899871 -0.141709 0.343702
+v -0.897777 -0.124432 0.341171
+v -0.494666 -0.823075 0.197329
+v -0.126417 -0.413246 0.633838
+v -0.66836 -0.939749 0.173771
+v -0.825047 -0.448969 0.294825
+v -0.833962 -0.440285 0.285487
+v -0.768708 -0.206013 0.505141
+v -0.94447 0.457395 0.370458
+v -0.950237 0.457061 0.358191
+v -0.954232 0.426939 0.355892
+v -0.940179 0.474647 0.365731
+v -0.676273 -0.941111 0.163726
+v -0.670544 -0.923847 0.157702
+v -0.665508 -0.906595 0.152114
+v -0.660576 -0.889164 0.146745
+v -0.655374 -0.871772 0.141093
+v -0.0107836 -0.930038 -0.203662
+v 0.0300644 -0.91113 0.513696
+v -0.769787 -0.443176 -0.0779067
+v -0.757494 -0.462007 -0.0779453
+v -0.771135 -0.460658 -0.0647917
+v -0.745689 -0.0849588 -0.119705
+v -0.928876 0.147477 0.617422
+v -0.928696 0.130174 0.61773
+v -0.349835 0.572117 -0.081375
+v -0.884649 -0.298499 0.351781
+v -0.889402 -0.280862 0.355879
+v -0.89278 -0.263226 0.358743
+v -0.895208 -0.245602 0.360593
+v -0.896621 -0.22812 0.361441
+v -0.897212 -0.210676 0.361364
+v -0.897302 -0.193245 0.360991
+v -0.896878 -0.175852 0.359887
+v -0.895632 -0.158524 0.358268
+v -0.893204 -0.141196 0.355108
+v -0.890879 -0.124009 0.352424
+v -0.887591 -0.10686 0.348737
+v -0.294382 -0.390587 -0.23232
+v -0.60326 -0.282622 -0.224639
+v -0.770493 -0.223303 0.507441
+v -0.941323 0.44008 0.385924
+v -0.938265 0.45755 0.382507
+v -0.933449 0.475058 0.377074
+v -0.215743 0.55597 -0.066924
+v -0.671045 -0.974342 0.14925
+v -0.661719 -0.923526 0.166629
+v -0.656016 -0.906544 0.160823
+v -0.650955 -0.889293 0.155248
+v -0.645919 -0.871849 0.149763
+v -0.757442 -0.430729 0.451255
+v -0.747307 -0.436496 0.458205
+v 0.50421 -0.936756 0.448108
+v -0.695194 0.543741 -0.572181
+v -0.29496 -0.297317 -0.261081
+v 0.496464 0.180425 0.0215673
+v -0.444248 -0.771604 0.199937
+v -0.442899 -0.753813 0.198164
+v -0.305506 -0.746864 -0.121581
+v -0.926923 0.112897 0.616433
+v -0.790172 -0.25846 0.491924
+v -0.873795 -0.316071 0.359296
+v -0.878239 -0.298242 0.363265
+v -0.882607 -0.280426 0.36717
+v -0.885561 -0.262699 0.369752
+v -0.888092 -0.245101 0.371653
+v -0.889351 -0.227606 0.372424
+v -0.889993 -0.210213 0.372385
+v -0.89034 -0.192795 0.37218
+v -0.889646 -0.175441 0.370921
+v -0.888297 -0.158177 0.369212
+v -0.885985 -0.140836 0.366155
+v -0.883737 -0.123636 0.363509
+v -0.88059 -0.1065 0.359925
+v -0.876865 -0.0891977 0.355558
+v -0.0674828 -0.502225 0.668688
+v -0.843891 0.478051 0.504795
+v 0.276 -0.976872 0.111831
+v 0.267291 -0.976744 0.133655
+v 0.262629 -0.977463 0.109609
+v -0.756839 -0.119898 0.490536
+v -0.931599 0.457909 0.393785
+v -0.926769 0.475456 0.388403
+v -0.920526 0.492836 0.381634
+v -0.787629 0.733505 -0.373143
+v -0.0560761 -0.98246 -0.26031
+v -0.656748 -0.922703 0.178896
+v -0.662939 -0.939929 0.186527
+v -0.649439 -0.905838 0.171613
+v -0.642554 -0.889113 0.165049
+v -0.636157 -0.872131 0.158228
+v -0.294896 -0.277882 -0.272102
+v -0.127226 -0.501378 -0.430407
+v -0.295089 -0.258987 -0.279051
+v 0.254587 -0.914495 -0.117072
+v 0.247497 -0.91104 -0.0975343
+v 0.242333 -0.91298 -0.120913
+v -0.442052 -0.735843 0.196777
+v -0.209256 0.72644 -0.182622
+v -0.209321 0.745515 -0.182622
+v -0.871406 -0.297433 0.375083
+v -0.875028 -0.279822 0.378037
+v -0.877854 -0.262378 0.38008
+v -0.88023 -0.244754 0.381891
+v -0.881733 -0.227285 0.382816
+v -0.882401 -0.209854 0.382841
+v -0.882722 -0.192384 0.382905
+v -0.881875 -0.175094 0.381557
+v -0.8805 -0.157779 0.379489
+v -0.878522 -0.14054 0.377022
+v -0.875889 -0.123251 0.373772
+v -0.872909 -0.106012 0.370253
+v -0.869607 -0.0889023 0.366541
+v -0.295281 -0.240451 -0.279616
+v -0.910494 0.234465 0.614249
+v -0.925793 0.458166 0.406078
+v -0.920256 0.475957 0.399797
+v -0.913808 0.493259 0.392989
+v -0.904303 0.510703 0.382957
+v -0.654539 -0.957912 0.196893
+v -0.654269 -0.939608 0.196417
+v -0.650518 -0.921933 0.191767
+v -0.643068 -0.905375 0.184176
+v -0.6359 -0.888355 0.176366
+v -0.628321 -0.871669 0.168363
+v -0.831739 -0.429418 0.321865
+v -0.838008 -0.432064 0.300143
+v -0.829196 -0.440093 0.308865
+v -0.6038 -0.943962 0.562547
+v -0.359752 -0.978336 -0.276058
+v -0.755695 -0.439463 -0.0938991
+v -0.209423 0.764539 -0.181054
+v -0.209629 0.783615 -0.177959
+v -0.917867 0.0781123 0.608469
+v -0.862298 -0.331961 0.385025
+v -0.863287 -0.314735 0.385102
+v -0.86488 -0.297073 0.386554
+v -0.867282 -0.279809 0.387902
+v -0.869967 -0.26207 0.390304
+v -0.872266 -0.244407 0.392077
+v -0.873692 -0.226874 0.392912
+v -0.874656 -0.209353 0.393451
+v -0.874951 -0.191999 0.393207
+v -0.874219 -0.174696 0.391923
+v -0.872793 -0.157381 0.389829
+v -0.870661 -0.140168 0.38726
+v -0.868336 -0.123032 0.384485
+v -0.864996 -0.105678 0.380452
+v -0.861797 -0.0884913 0.376817
+v -0.85883 -0.07124 0.373349
+v -0.842247 -0.0364164 0.373747
+v -0.641501 -0.959017 0.435751
+v -0.472598 -0.640531 -0.0883243
+v -0.459752 -0.639606 -0.0980867
+v -0.112377 -0.945401 -0.356084
+v -0.0996346 -0.945478 -0.353837
+v -0.110348 -0.955523 -0.353849
+v -0.448333 -0.78901 0.20451
+v 0.775194 -0.851399 0.0189597
+v -0.295243 -0.22198 -0.279115
+v -0.771045 -0.137213 0.487068
+v -0.768155 -0.119975 0.483767
+v -0.914219 0.476188 0.411962
+v -0.906974 0.493568 0.404267
+v -0.897161 0.510665 0.394068
+v -0.646009 -0.957771 0.206514
+v -0.646163 -0.939184 0.206116
+v 0.00961471 -0.953108 0.681006
+v -0.640974 -0.921727 0.200952
+v -0.634243 -0.905401 0.193707
+v -0.628591 -0.88806 0.1874
+v -0.619214 -0.871284 0.177625
+v -0.607705 -0.854521 0.165858
+v -0.595579 -0.838567 0.153257
+v -0.578135 -0.823332 0.135415
+v 0.379161 -0.104342 -0.263059
+v 0.3769 -0.121439 -0.270599
+v -0.647371 0.837423 -0.736459
+v -0.654461 0.834366 -0.725605
+v -0.5257 -0.791836 0.118318
+v -0.513215 -0.774302 0.123636
+v -0.739163 -0.48175 -0.078382
+v -0.716787 -0.495032 -0.0758386
+v -0.726819 -0.500825 -0.0656138
+v -0.295243 -0.203752 -0.275699
+v -0.850018 -0.366733 0.391705
+v -0.855799 -0.367363 0.37936
+v -0.85409 -0.34884 0.395494
+v -0.856428 -0.331344 0.397305
+v -0.857841 -0.313952 0.398127
+v -0.859036 -0.296508 0.398808
+v -0.860641 -0.279128 0.399707
+v -0.862324 -0.26171 0.400696
+v -0.863673 -0.244176 0.401493
+v -0.86542 -0.226488 0.402867
+v -0.866563 -0.209019 0.403484
+v -0.867077 -0.191613 0.403407
+v -0.866537 -0.174285 0.402276
+v -0.864867 -0.156995 0.400041
+v -0.862735 -0.139808 0.397434
+v -0.86005 -0.122531 0.394158
+v -0.856852 -0.105357 0.39051
+v -0.853743 -0.0881701 0.386952
+v -0.850301 -0.0707519 0.382893
+v -0.846203 -0.0535906 0.37823
+v 0.189744 -0.970334 0.576227
+v 0.198376 -0.970244 0.554865
+v -0.295512 -0.185358 -0.270355
+v 0.760397 -0.658604 -0.0384717
+v 0.747307 -0.658758 -0.0380092
+v 0.750878 -0.645643 -0.0325885
+v -0.928015 0.164728 0.616035
+v -0.914682 0.459104 0.430793
+v -0.908439 0.476573 0.424177
+v -0.900166 0.493902 0.415571
+v -0.636054 -0.93921 0.214414
+v -0.645585 -0.968214 0.194735
+v -0.632291 -0.92138 0.210123
+v -0.625662 -0.904861 0.203161
+v -0.618585 -0.887854 0.195583
+v -0.608951 -0.871271 0.185512
+v -0.597236 -0.854867 0.173437
+v -0.584198 -0.838849 0.160065
+v -0.0555495 -0.216135 0.684359
+v -0.961785 0.0928843 0.357703
+v -0.957366 0.0818759 0.351165
+v 0.587615 -0.890539 0.401467
+v 0.569387 -0.900828 0.407119
+v -0.639895 -0.488982 -0.146025
+v -0.647898 0.855651 -0.740082
+v -0.788245 0.726145 -0.365128
+v -0.643337 0.175839 -0.0956718
+v -0.656157 0.175775 -0.0946313
+v -0.643453 0.194645 -0.0942716
+v 0.320779 0.00021837 -0.233399
+v 0.320355 0.0182917 -0.232076
+v 0.329694 0.0099808 -0.231125
+v -0.106455 0.707725 -0.196109
+v 0.0154336 -0.929922 -0.198486
+v -0.850956 -0.383471 0.37367
+v -0.838586 -0.384049 0.398924
+v -0.843647 -0.365911 0.403702
+v -0.847424 -0.348377 0.406798
+v -0.849774 -0.330882 0.408635
+v -0.851765 -0.313335 0.410266
+v -0.852806 -0.296097 0.41042
+v -0.853422 -0.278627 0.410741
+v -0.854142 -0.261363 0.410728
+v -0.855246 -0.243765 0.411332
+v -0.856968 -0.226244 0.412424
+v -0.858496 -0.208633 0.41358
+v -0.858946 -0.191292 0.413452
+v -0.858265 -0.173977 0.412218
+v -0.856608 -0.156713 0.409983
+v -0.854347 -0.13959 0.407234
+v -0.851431 -0.12239 0.403792
+v -0.848528 -0.105139 0.400349
+v -0.845086 -0.0877462 0.396342
+v -0.842003 -0.0705335 0.392771
+v -0.0433336 0.979993 -0.220862
+v -0.032839 0.985209 -0.201055
+v -0.66398 -0.855882 0.0671167
+v -0.66502 -0.85998 0.0781379
+v -0.196128 -0.981047 0.229545
+v -0.926307 0.181979 0.613774
+v -0.888117 0.374132 0.569882
+v -0.882003 0.391563 0.563356
+v -0.874013 0.409148 0.554878
+v -0.864855 0.426605 0.545283
+v -0.855349 0.443625 0.535276
+v -0.909595 0.459271 0.443908
+v -0.920513 0.441377 0.437138
+v -0.90235 0.476702 0.436316
+v -0.893281 0.494261 0.426746
+v -0.477595 0.475636 -0.00159282
+v -0.295705 -0.112396 -0.253065
+v -0.627281 -0.95709 0.224279
+v -0.626061 -0.938876 0.222596
+v -0.520125 0.347722 -0.0468083
+v -0.621706 -0.921457 0.217843
+v -0.615592 -0.904746 0.211164
+v -0.60836 -0.887751 0.203559
+v -0.598739 -0.871245 0.193514
+v -0.58687 -0.855137 0.181196
+v -0.573909 -0.839132 0.167862
+v -0.556747 -0.823307 0.150406
+v -0.537595 -0.807802 0.130727
+v -0.636362 -0.95736 0.215197
+v -0.295718 -0.0943872 -0.247413
+v -0.593922 -0.982447 -0.0822741
+v 0.562245 -0.381981 -0.28004
+v 0.548783 -0.394813 -0.292642
+v 0.552431 -0.375031 -0.287683
+v -0.607332 -0.983025 -0.0844065
+v -0.337298 0.610203 -0.102827
+v -0.324684 0.610113 -0.106642
+v -0.324376 0.591192 -0.098061
+v -0.220457 -0.016108 -0.228004
+v -0.64231 -0.136764 -0.185936
+v 0.141446 -0.263752 -0.443227
+v 0.128601 -0.263598 -0.445025
+v -0.581205 0.381814 -0.0644449
+v 0.470799 -0.189044 -0.276007
+v 0.475732 -0.181954 -0.271935
+v -0.631032 0.251036 -0.0942716
+v -0.707898 0.288056 -0.0838798
+v -0.830455 -0.401981 0.391525
+v -0.831624 -0.383458 0.410125
+v -0.836723 -0.365372 0.414877
+v -0.840461 -0.347864 0.417999
+v -0.843005 -0.330394 0.419938
+v -0.84461 -0.312834 0.421326
+v -0.845458 -0.295596 0.421403
+v -0.845792 -0.278281 0.421133
+v -0.845933 -0.260952 0.420761
+v -0.846781 -0.243393 0.42112
+v -0.848747 -0.225872 0.422379
+v -0.850044 -0.208376 0.423137
+v -0.850301 -0.190958 0.422854
+v -0.849723 -0.173643 0.421698
+v -0.847989 -0.156353 0.419425
+v -0.845458 -0.139294 0.416457
+v -0.842375 -0.122146 0.412848
+v -0.839716 -0.104792 0.409624
+v -0.836518 -0.0876435 0.405988
+v -0.83296 -0.0702509 0.401878
+v -0.268743 -0.79759 -0.172101
+v -0.279816 -0.807866 -0.202468
+v -0.527306 -0.643639 -0.00253052
+v 0.285532 -0.922074 -0.128055
+v -0.295769 -0.0762882 -0.242262
+v -0.295846 -0.0576882 -0.241299
+v -0.924251 0.199398 0.611141
+v -0.756543 -0.05264 0.481275
+v -0.761 -0.0679902 0.475212
+v -0.77513 -0.102968 0.47209
+v -0.777943 -0.120271 0.47534
+v -0.7805 -0.137316 0.4785
+v -0.916005 0.441904 0.450536
+v -0.910661 0.441981 0.463587
+v -0.903596 0.459515 0.456098
+v -0.895298 0.476882 0.447415
+v -0.886769 0.493876 0.438513
+v -0.618841 -0.957065 0.233861
+v -0.616054 -0.938824 0.230766
+v -0.611301 -0.921432 0.225589
+v -0.604365 -0.904823 0.218152
+v -0.5973 -0.887636 0.210727
+v -0.588565 -0.871194 0.201491
+v -0.576606 -0.85524 0.18907
+v -0.562579 -0.839299 0.174709
+v -0.545405 -0.823461 0.157252
+v -0.529284 -0.807905 0.140669
+v -0.518533 -0.791476 0.129442
+v -0.503388 -0.7561 0.13142
+v -0.818355 -0.400619 0.413118
+v -0.823891 -0.401685 0.402944
+v -0.816852 -0.411152 0.399463
+v -0.621526 0.726697 -0.748354
+v -0.117875 -0.964027 -0.352873
+v -0.111388 -0.966288 -0.349418
+v 0.330105 -0.275519 -0.391846
+v 0.334498 -0.284999 -0.39146
+v -0.744905 -0.121684 -0.136571
+v -0.850121 0.285718 -0.0140014
+v -0.236565 -0.923667 -0.365333
+v -0.230734 -0.898657 -0.362944
+v 0.0922357 -0.248929 -0.447466
+v 0.0900263 -0.263406 -0.45123
+v -0.638058 -0.876576 -0.023083
+v -0.640653 -0.87673 -0.00992942
+v -0.655374 -0.155338 -0.185011
+v -0.320394 -0.334774 -0.252834
+v -0.736312 -0.410921 -0.128903
+v -0.745162 -0.409996 -0.116301
+v -0.745316 -0.392617 -0.129249
+v 0.192172 -0.0544127 -0.265821
+v 0.19162 -0.0350677 -0.261273
+v -0.718482 -0.0185486 0.508751
+v -0.730069 -0.022505 0.508006
+v -0.567473 0.34446 -0.0671295
+v 0.821219 -0.871669 0.219398
+v -0.82393 -0.383188 0.420491
+v -0.829209 -0.36514 0.425321
+v -0.832934 -0.347555 0.428429
+v -0.835799 -0.329854 0.430973
+v -0.837327 -0.3125 0.431897
+v -0.838059 -0.295108 0.432308
+v -0.838291 -0.277844 0.431949
+v -0.838188 -0.260605 0.431075
+v -0.838869 -0.243046 0.431332
+v -0.839986 -0.225602 0.43173
+v -0.841707 -0.208004 0.432989
+v -0.842106 -0.190624 0.432797
+v -0.841515 -0.173309 0.431679
+v -0.839549 -0.156109 0.429187
+v -0.836415 -0.139012 0.425526
+v -0.833461 -0.121812 0.422045
+v -0.830545 -0.104574 0.418628
+v -0.827436 -0.087348 0.415019
+v -0.823891 -0.0699812 0.410985
+v -0.753486 0.0714327 0.681584
+v -0.753435 0.0882472 0.690396
+v -0.765458 0.0731668 0.677191
+v -0.332867 -0.409046 -0.230252
+v -0.32006 -0.390728 -0.234427
+v -0.36963 0.710884 -0.080874
+v -0.0757166 -0.91384 0.494287
+v -0.0891143 -0.914444 0.492065
+v 0.503992 -0.309289 -0.304202
+v 0.502103 -0.326232 -0.313066
+v 0.49297 -0.304318 -0.309597
+v -0.402026 -0.55168 0.516253
+v -0.412122 -0.547749 0.512348
+v -0.792561 0.725901 -0.377999
+v -0.921284 0.216803 0.607621
+v -0.782683 -0.345282 0.486952
+v -0.77725 -0.363252 0.482135
+v -0.790827 -0.275609 0.49308
+v -0.904714 0.442251 0.475751
+v -0.917572 0.424344 0.471024
+v -0.924277 0.409688 0.471384
+v -0.896762 0.459887 0.467286
+v -0.888387 0.47719 0.458577
+v -0.878933 0.494236 0.448725
+v -0.86569 0.511898 0.434865
+v 0.320458 -0.111857 -0.252474
+v -0.609336 -0.956666 0.242545
+v -0.605765 -0.938644 0.238678
+v -0.599625 -0.921663 0.232089
+v -0.594294 -0.90463 0.226244
+v -0.587049 -0.887649 0.218653
+v -0.577274 -0.871271 0.208402
+v -0.565456 -0.855086 0.196135
+v -0.551391 -0.839299 0.181645
+v -0.536195 -0.823705 0.166141
+v -0.520202 -0.807674 0.149763
+v -0.511725 -0.790898 0.140784
+v -0.506663 -0.77357 0.13512
+v -0.493099 -0.737988 0.138896
+v -0.562489 -0.626876 -0.0143867
+v -0.575758 -0.628289 -0.00581892
+v -0.574975 -0.625617 -0.0153887
+v -0.612753 -0.957155 -0.0811566
+v -0.141523 -0.974136 -0.361261
+v -0.152557 -0.972158 -0.36365
+v -0.164593 -0.969242 -0.367183
+v -0.758573 -0.140232 -0.132641
+v -0.770801 -0.141221 -0.122056
+v -0.810635 -0.391332 0.429136
+v -0.809183 -0.404832 0.418333
+v 0.193084 -0.282224 -0.436971
+v 0.193842 -0.262468 -0.434582
+v 0.205968 -0.282468 -0.432206
+v 0.572097 -0.390741 -0.271575
+v 0.578841 -0.36663 -0.261954
+v 0.727782 -0.913044 0.0737705
+v -0.815888 -0.382777 0.430626
+v -0.821386 -0.364781 0.43561
+v -0.825535 -0.346913 0.439309
+v -0.827989 -0.329469 0.441223
+v -0.829581 -0.312141 0.442199
+v -0.830378 -0.294748 0.442623
+v -0.830622 -0.277471 0.442341
+v -0.830879 -0.260169 0.442032
+v -0.83111 -0.242712 0.44166
+v -0.831714 -0.225255 0.441634
+v -0.833114 -0.207734 0.442443
+v -0.833371 -0.190329 0.442135
+v -0.83278 -0.172975 0.441043
+v -0.83066 -0.155801 0.438423
+v -0.827385 -0.138729 0.434633
+v -0.824007 -0.121375 0.430729
+v -0.821258 -0.104381 0.427492
+v -0.817802 -0.0869627 0.423574
+v 0.102473 -0.0868599 -0.282391
+v 0.0895381 -0.0725246 -0.278936
+v -0.963057 0.0764809 0.538141
+v -0.938766 0.0674507 0.367144
+v -0.962607 0.0938863 0.561494
+v -0.966628 0.111433 0.565155
+v -0.974515 0.128235 0.553915
+v -0.969377 0.128659 0.567171
+v -0.970032 0.145961 0.567069
+v -0.968696 0.163135 0.565489
+v -0.957212 0.215197 0.552399
+v -0.900064 0.0204369 0.306951
+v -0.946358 0.249969 0.540492
+v -0.941644 0.250445 0.553838
+v -0.32128 -0.131086 -0.255377
+v -0.334087 -0.131138 -0.255506
+v -0.321319 -0.11273 -0.254851
+v -0.74434 -0.268518 -0.170072
+v -0.731803 -0.249571 -0.173835
+v -0.91833 0.234183 0.603986
+v -0.912125 0.42491 0.48342
+v -0.906216 0.425269 0.495649
+v -0.898625 0.442431 0.487864
+v -0.889608 0.460029 0.478372
+v -0.880988 0.476959 0.469406
+v -0.870108 0.494775 0.457961
+v -0.309938 -0.821033 -0.202763
+v -0.465083 0.671848 0.0683755
+v -0.468667 0.675187 0.0460375
+v -0.472225 0.670563 0.0579451
+v -0.601642 -0.972556 0.236482
+v -0.597416 -0.937964 0.248762
+v -0.602682 -0.95551 0.254144
+v -0.591661 -0.921252 0.242301
+v -0.584082 -0.904592 0.234208
+v -0.575874 -0.887649 0.225653
+v -0.566047 -0.871297 0.215377
+v -0.554191 -0.855214 0.203058
+v -0.541192 -0.839325 0.189597
+v -0.52606 -0.823576 0.174131
+v -0.51157 -0.806967 0.159269
+v -0.503992 -0.790281 0.151176
+v -0.498866 -0.773056 0.145512
+v -0.495437 -0.755663 0.141632
+v -0.48534 -0.737526 0.149211
+v -0.792484 -0.423484 -0.0644834
+v -0.786717 -0.406823 -0.0779196
+v -0.780885 -0.422212 -0.0786774
+v 0.269989 -0.229571 -0.398281
+v 0.270079 -0.247542 -0.403291
+v 0.309385 -0.93998 0.3655
+v 0.305108 -0.91578 0.389405
+v -0.538725 -0.372989 -0.240914
+v -0.539046 -0.354569 -0.244754
+v -0.525931 -0.372604 -0.245962
+v -0.0103726 -0.961907 -0.222198
+v -0.182384 -0.268929 -0.309906
+v -0.592085 -0.00656395 -0.174593
+v -0.64791 -0.893545 -0.0346181
+v -0.650056 -0.905812 -0.0438282
+v -0.0850551 -0.920289 -0.0838284
+v -0.0943808 -0.921162 -0.0610665
+v -0.0984785 -0.920867 -0.0859864
+v -0.617428 0.138125 -0.0937835
+v -0.604725 0.157008 -0.0934495
+v -0.0399938 0.897437 -0.275416
+v -0.0371936 0.916448 -0.275968
+v -0.0310407 0.898413 -0.283252
+v -0.149988 -0.382777 -0.437922
+v -0.151234 -0.364421 -0.437408
+v -0.807693 -0.382225 0.440607
+v -0.813319 -0.364318 0.445668
+v -0.817751 -0.346579 0.449598
+v -0.820564 -0.328878 0.452052
+v -0.822054 -0.311601 0.452989
+v -0.822684 -0.294363 0.452977
+v -0.823249 -0.277022 0.453182
+v -0.823107 -0.259809 0.452321
+v -0.822979 -0.242352 0.451692
+v -0.823159 -0.224908 0.451281
+v -0.82452 -0.207426 0.451975
+v -0.824366 -0.190046 0.451281
+v -0.823737 -0.172705 0.450125
+v -0.821348 -0.155634 0.447286
+v -0.818021 -0.138601 0.44342
+v -0.815208 -0.12135 0.440093
+v -0.811585 -0.104008 0.435969
+v -0.80926 -0.0868214 0.433182
+v -0.074856 -0.92517 0.134285
+v -0.250592 -0.980225 -0.372925
+v -0.955928 0.0941175 0.572926
+v -0.960167 0.111638 0.576664
+v -0.962543 0.129005 0.578475
+v -0.962941 0.146269 0.578321
+v -0.962209 0.163572 0.577024
+v -0.959987 0.180695 0.574442
+v -0.956236 0.19819 0.570151
+v -0.951316 0.215595 0.564705
+v -0.946461 0.233014 0.559259
+v -0.954168 0.0682342 0.547081
+v -0.947399 0.0729484 0.567685
+v -0.955915 0.0764552 0.555495
+v -0.938702 0.267837 0.550447
+v -0.931535 0.302674 0.542521
+v 0.33708 -0.974971 -0.214863
+v 0.713922 -0.924643 0.104445
+v -0.91323 0.390407 0.521712
+v -0.907077 0.407902 0.515225
+v -0.899871 0.425295 0.50762
+v -0.890918 0.442996 0.498205
+v -0.881656 0.460337 0.488494
+v -0.872909 0.477113 0.479425
+v -0.861014 0.494865 0.467004
+v -0.830622 0.508545 0.473837
+v -0.841784 0.495276 0.484088
+v 0.777031 -0.896229 0.138472
+v -0.58195 -0.920892 0.250715
+v -0.57554 -0.904656 0.243778
+v -0.566471 -0.887777 0.234337
+v -0.555784 -0.871425 0.223174
+v -0.542913 -0.855304 0.209956
+v -0.529926 -0.839389 0.196546
+v -0.515039 -0.82314 0.181376
+v -0.502412 -0.806813 0.168312
+v -0.495064 -0.78996 0.160451
+v -0.489849 -0.772773 0.154709
+v -0.48719 -0.755304 0.151626
+v -0.539804 0.374659 -0.0508032
+v -0.542515 0.356547 -0.0569817
+v -0.55509 0.362764 -0.0599875
+v -0.627512 -0.488956 -0.154812
+v -0.866268 0.0704179 0.0101349
+v -0.372931 -0.0759928 -0.247811
+v -0.373034 -0.0579837 -0.239475
+v -0.398095 -0.186514 -0.263714
+v -0.60457 0.138087 -0.0927174
+v -0.459701 -0.65863 -0.0899813
+v -0.472238 -0.659439 -0.0799748
+v -0.805021 -0.363779 0.455546
+v -0.80998 -0.345783 0.460093
+v -0.812818 -0.328493 0.462328
+v -0.814617 -0.311254 0.463523
+v -0.815118 -0.293888 0.46369
+v -0.815105 -0.276739 0.46297
+v -0.814861 -0.259475 0.462289
+v -0.81418 -0.242121 0.460954
+v -0.813743 -0.224754 0.4599
+v -0.814707 -0.20722 0.460311
+v -0.81513 -0.189815 0.46017
+v -0.814604 -0.172448 0.459117
+v -0.812317 -0.155338 0.456316
+v -0.808978 -0.138292 0.452514
+v -0.806075 -0.121093 0.449123
+v -0.802529 -0.103726 0.445077
+v -0.799703 -0.0864103 0.441775
+v -0.433381 -0.787263 -0.0864617
+v -0.657711 -0.00138729 0.509522
+v 0.00204882 -0.930501 -0.200656
+v -0.948606 0.0946185 0.583973
+v -0.952331 0.111908 0.587056
+v -0.954643 0.129314 0.588816
+v -0.955183 0.146603 0.58906
+v -0.954553 0.163829 0.587916
+v -0.952922 0.181003 0.585669
+v -0.949698 0.198357 0.582033
+v -0.944804 0.216135 0.576202
+v -0.940167 0.233232 0.571359
+v -0.936146 0.250612 0.566889
+v -0.932781 0.26821 0.562714
+v -0.929043 0.285705 0.558359
+v -0.934887 0.285307 0.546054
+v -0.92569 0.303033 0.554801
+v -0.911522 0.37331 0.538526
+v -0.916005 0.355584 0.543677
+v -0.906319 0.39078 0.533003
+v -0.899987 0.408159 0.526323
+v -0.891277 0.425976 0.517075
+v -0.883339 0.442687 0.508892
+v -0.873525 0.460517 0.498565
+v -0.863146 0.477691 0.487723
+v -0.851791 0.494839 0.47588
+v -0.44105 0.690024 0.0620043
+v -0.401371 0.727352 0.0396791
+v -0.787552 0.0633915 0.656857
+v -0.0541365 -0.127579 -0.290676
+v -0.0678039 -0.127579 -0.291062
+v -0.0644898 -0.10957 -0.286874
+v -0.573562 -0.920687 0.260528
+v -0.564416 -0.90463 0.250997
+v -0.556208 -0.887803 0.242249
+v -0.531725 -0.85524 0.217008
+v -0.519624 -0.839556 0.204394
+v -0.504827 -0.823165 0.189301
+v -0.493972 -0.80689 0.17801
+v -0.486085 -0.789626 0.169661
+v -0.4815 -0.772542 0.164587
+v -0.477582 -0.755059 0.160129
+v 0.317658 -0.918439 0.60229
+v 0.325493 -0.944078 0.603536
+v 0.230502 0.0546953 -0.22776
+v 0.231877 0.0696472 -0.21801
+v -0.285442 0.00269751 -0.221954
+v -0.260034 -0.790641 -0.150817
+v -0.603556 -0.245666 -0.222147
+v -0.180753 -0.0451384 -0.249032
+v 0.54579 -0.347452 -0.290124
+v 0.555784 -0.355288 -0.282301
+v 0.542142 -0.368133 -0.294748
+v -0.306187 -0.616266 -0.144805
+v -0.436297 -0.260811 -0.260708
+v -0.449284 -0.223816 -0.261851
+v -0.436477 -0.223906 -0.259501
+v -0.796094 -0.363535 0.464704
+v -0.800949 -0.34595 0.469008
+v -0.804649 -0.328056 0.472257
+v -0.806473 -0.310831 0.473529
+v -0.807372 -0.293489 0.473966
+v -0.807025 -0.276367 0.473041
+v -0.806409 -0.259167 0.471872
+v -0.805805 -0.241813 0.47078
+v -0.804572 -0.224497 0.468892
+v -0.8047 -0.207066 0.468455
+v -0.805214 -0.189597 0.468404
+v -0.805227 -0.17223 0.467813
+v -0.80276 -0.154966 0.464961
+v -0.799536 -0.137856 0.461249
+v -0.796518 -0.120682 0.457729
+v -0.793435 -0.103482 0.45412
+v -0.790468 -0.0861663 0.45069
+v -0.788502 -0.0687866 0.44825
+v -0.262654 -0.960456 0.336072
+v -0.517852 0.51475 0.000937707
+v -0.503671 0.513825 -0.00445732
+v -0.503593 0.494852 -0.00366091
+v -0.457389 0.0638925 -0.182467
+v -0.472084 0.0620299 -0.180412
+v -0.470286 0.0782407 -0.171652
+v -0.944829 0.112384 0.597897
+v -0.946898 0.129571 0.599323
+v -0.94718 0.146925 0.599079
+v -0.946474 0.164099 0.598
+v -0.944894 0.181299 0.595868
+v -0.941361 0.198884 0.591744
+v -0.937482 0.216315 0.587287
+v -0.932716 0.23372 0.581879
+v -0.929454 0.251036 0.578205
+v -0.926396 0.268402 0.57475
+v -0.922723 0.285923 0.570447
+v -0.919743 0.30338 0.567004
+v -0.916852 0.320863 0.563613
+v -0.913089 0.338422 0.559323
+v -0.909132 0.355943 0.554943
+v -0.904611 0.373182 0.55019
+v -0.898291 0.391101 0.543176
+v -0.89201 0.408468 0.536535
+v -0.883686 0.425732 0.5278
+v -0.874707 0.443343 0.518321
+v -0.864418 0.460697 0.507582
+v -0.85314 0.478012 0.495828
+v -0.431172 0.690846 0.0702381
+v -0.416335 0.709112 0.0549907
+v -0.38462 0.746183 0.0223123
+v -0.390259 0.745901 0.00976243
+v -0.40638 0.730037 0.0198074
+v -0.407202 0.727352 0.0272834
+v -0.621629 -0.957912 0.527608
+v -0.613742 -0.953378 0.54685
+v -0.565585 -0.92025 0.270702
+v -0.573112 -0.937013 0.278589
+v -0.48385 -0.806775 0.186064
+v -0.476631 -0.789613 0.178408
+v -0.472405 -0.772272 0.173643
+v -0.469386 -0.754725 0.170097
+v -0.468153 -0.736832 0.168363
+v -0.882658 0.193887 -0.0152474
+v -0.897777 0.194349 -0.00226077
+v -0.59071 -0.226938 -0.223649
+v -0.50159 0.408493 -0.00974958
+v -0.503362 0.418808 -0.00612721
+v -0.506638 0.28207 -0.053141
+v -0.503516 0.268595 -0.0541815
+v -0.516297 0.268891 -0.059615
+v -0.557107 0.133899 -0.0995511
+v -0.566034 0.120155 -0.105421
+v -0.566086 0.138318 -0.0967122
+v -0.319764 -0.46509 -0.214401
+v -0.319841 -0.44631 -0.218678
+v -0.148395 -0.346309 -0.437793
+v 0.647088 -0.926775 0.305898
+v -0.786935 -0.363175 0.473645
+v -0.791945 -0.345693 0.478089
+v -0.795914 -0.327786 0.481532
+v -0.798021 -0.310368 0.483202
+v -0.798933 -0.293232 0.483536
+v -0.798894 -0.275994 0.483035
+v -0.798329 -0.258807 0.481943
+v -0.797211 -0.241517 0.480337
+v -0.79567 -0.224202 0.478179
+v -0.794565 -0.206938 0.476483
+v -0.794951 -0.189468 0.476304
+v -0.794886 -0.172114 0.475623
+v -0.793191 -0.154863 0.473375
+v -0.790211 -0.137689 0.470035
+v -0.787295 -0.12045 0.466593
+v -0.784263 -0.103238 0.463099
+v -0.781245 -0.085935 0.45963
+v -0.241395 -0.968702 0.278666
+v -0.33803 0.667981 -0.10993
+v 0.594243 -0.822561 -0.0664487
+v -0.402039 0.648109 -0.0687352
+v 0.282308 -0.0729613 -0.255198
+v 0.274035 -0.0838798 -0.259115
+v 0.276887 -0.0653055 -0.253605
+v -0.932459 0.0952736 0.604268
+v -0.93612 0.112589 0.607364
+v -0.938021 0.12984 0.608752
+v -0.938574 0.14722 0.608829
+v -0.937623 0.164407 0.607377
+v -0.935966 0.18162 0.605181
+v -0.933449 0.199166 0.602059
+v -0.929569 0.216636 0.597538
+v -0.925613 0.233977 0.593003
+v -0.922324 0.25128 0.589304
+v -0.919614 0.268788 0.586028
+v -0.9163 0.286412 0.581905
+v -0.913654 0.303676 0.579143
+v -0.910764 0.320927 0.574622
+v -0.906512 0.338962 0.570742
+v -0.901952 0.3562 0.566002
+v -0.897019 0.373721 0.560607
+v -0.89025 0.391409 0.553324
+v -0.883018 0.408802 0.545732
+v -0.874771 0.426156 0.537036
+v -0.865548 0.443471 0.527312
+v -0.854989 0.460491 0.516304
+v -0.210952 0.859106 -0.134156
+v -0.55238 -0.920417 0.285936
+v 0.516888 -0.728829 -0.288081
+v -0.542502 0.344087 -0.0592939
+v -0.53879 -0.336007 -0.247246
+v -0.52597 -0.335571 -0.252205
+v -0.525906 -0.353914 -0.25056
+v -0.398609 -0.0585103 -0.235775
+v -0.398712 -0.0403085 -0.227978
+v -0.234125 -0.448314 -0.244652
+v -0.23022 -0.429894 -0.256354
+v -0.500896 -0.242391 -0.263277
+v -0.487986 -0.242224 -0.265127
+v -0.527293 -0.0235069 -0.206565
+v -0.53098 0.352642 -0.0525373
+v -0.516914 0.366759 -0.0418885
+v -0.849042 0.0878618 0.646144
+v -0.86181 0.088016 0.643472
+v -0.777096 -0.0583947 0.45877
+v -0.779472 -0.0684783 0.45737
+v -0.0111561 -0.920083 -0.021503
+v -0.638084 0.725194 -0.725618
+v -0.644365 0.725284 -0.712606
+v -0.605123 0.744308 -0.759838
+v 0.158312 0.0460375 -0.218062
+v 0.159083 0.0348108 -0.231806
+v 0.145942 0.0358384 -0.232834
+v 0.468847 0.0276559 -0.173591
+v 0.466753 0.0110213 -0.181003
+v 0.132326 0.00960828 -0.256212
+v 0.118157 0.00855497 -0.255159
+v -0.609464 0.800416 -0.765528
+v -0.595656 0.798335 -0.771142
+v 0.181767 0.230124 -0.0303406
+v 0.184002 0.221748 -0.0471294
+v 0.170386 0.222288 -0.0471936
+v 0.0883178 0.0549522 -0.201466
+v 0.0890115 0.0696729 -0.191498
+v 0.102666 0.0697114 -0.191613
+v 0.129025 -0.152576 -0.341351
+v 0.131324 -0.160977 -0.358178
+v 0.117657 -0.160682 -0.358281
+v -0.206173 0.153848 -0.0717538
+v -0.205326 0.142788 -0.0856524
+v -0.287125 0.784578 -0.120309
+v -0.298094 0.765849 -0.119628
+v -0.302847 0.78427 -0.10704
+v 0.313689 0.146745 -0.147233
+v 0.326804 0.145897 -0.146424
+v 0.313894 0.134221 -0.159474
+v -0.958099 0.046667 0.263303
+v -0.948323 0.0405141 0.270535
+v 0.049782 0.0857937 -0.182814
+v 0.0361017 0.0860378 -0.183033
+v 0.0363586 0.0988959 -0.170855
+v 0.270246 0.166989 -0.117188
+v 0.271492 0.156738 -0.131908
+v 0.256771 0.155454 -0.130059
+v 0.207419 -0.942331 0.0903795
+v 0.21284 -0.956499 0.104291
+v 0.198723 -0.942344 0.11205
+v 0.146199 0.0232115 -0.24514
+v 0.145197 0.0467826 -0.218832
+v 0.118902 0.023083 -0.244934
+v 0.133071 0.0236353 -0.245564
+v 0.168126 0.230406 -0.0302635
+v 0.126276 -0.145011 -0.323586
+v 0.114882 -0.153411 -0.340349
+v -0.00998722 -0.928548 -0.333785
+v 0.11266 -0.145383 -0.323368
+v 0.954001 -0.539451 0.0681957
+v 0.301408 0.237856 -0.0138601
+v -0.158029 -0.874315 -0.36049
+v 0.350298 0.239526 0.0096982
+v 0.337619 0.241299 0.0077971
+v 0.326341 0.119538 -0.16934
+v 0.313149 0.120116 -0.169892
+v -0.180598 -0.0315352 -0.237574
+v -0.195101 -0.0197561 -0.224189
+v 0.327073 0.133642 -0.158896
+v 0.050026 0.0991272 -0.171176
+v -0.104015 0.935176 -0.173591
+v 0.100136 -0.104676 -0.288672
+v 0.140701 -0.0172127 -0.269944
+v 0.123578 -0.137291 -0.305834
+v 0.104387 0.0345924 -0.23137
+v 0.918985 -0.51534 0.0687737
+v 0.931445 -0.517421 0.0709831
+v 0.919576 -0.527351 0.0552862
+v -0.862761 0.266694 -0.0138087
+v 0.931714 -0.53001 0.0581764
+v 0.297311 -0.168864 -0.323714
+v 0.568526 -0.342661 -0.268762
+v 0.578559 -0.34997 -0.260336
+v 0.565546 -0.362263 -0.274607
+v 0.352546 0.230971 -0.00701353
+v 0.34024 0.233168 -0.00980096
+v 0.288216 0.238576 -0.0146308
+v 0.354357 0.22198 -0.0228775
+v 0.34209 0.224382 -0.0257291
+v 0.291685 -0.141581 -0.275377
+v 0.292481 -0.152461 -0.28934
+v 0.356463 0.213155 -0.0394351
+v 0.343875 0.215184 -0.0414903
+v -0.173739 0.0346695 -0.204651
+v -0.177002 0.015363 -0.209995
+v -0.186931 0.035209 -0.20496
+v 0.528603 -0.130855 -0.23512
+v 0.539509 -0.135942 -0.229533
+v 0.527216 -0.146346 -0.244228
+v -0.390041 0.283406 0.0774957
+v -0.380921 0.274761 0.0871425
+v -0.100457 -0.744873 -0.336919
+v -0.638264 0.743447 -0.725721
+v -0.638585 0.761649 -0.725939
+v -0.644404 0.797976 -0.726003
+v -0.594769 0.833506 -0.771065
+v -0.576889 0.837244 -0.769909
+v -0.222975 0.186038 -0.028812
+v -0.220817 0.177419 -0.0456522
+v -0.234356 0.190342 -0.0338474
+v 0.0598013 -0.155415 -0.338743
+v 0.0734558 -0.155223 -0.338795
+v 0.562014 0.0865516 -0.0567634
+v 0.550916 0.0914714 -0.0620942
+v 0.550479 0.103507 -0.0493902
+v 0.295191 -0.160322 -0.30699
+v 0.357748 0.202853 -0.0540145
+v 0.345211 0.205101 -0.0561982
+v -0.453946 -0.731694 0.361903
+v 0.35857 0.191896 -0.0676947
+v 0.346393 0.194632 -0.0706748
+v 0.158505 0.0854469 -0.182968
+v 0.159584 0.100283 -0.173052
+v 0.228755 0.140643 -0.139744
+v 0.242821 0.142352 -0.141504
+v 0.228922 0.1288 -0.152628
+v -0.64538 0.743447 -0.712413
+v -0.63012 0.725271 -0.738142
+v -0.646074 0.761572 -0.712888
+v -0.648848 0.779799 -0.712837
+v -0.65319 0.797963 -0.712798
+v -0.657583 0.816139 -0.712721
+v -0.64958 0.81628 -0.725297
+v -0.663903 0.834199 -0.71294
+v -0.544185 -0.886698 -0.0835073
+v -0.541937 -0.869139 -0.0737577
+v -0.527023 -0.866158 -0.0767763
+v -0.673023 0.852298 -0.712888
+v -0.683518 0.870385 -0.712644
+v -0.35681 -0.971271 0.529265
+v -0.692047 0.888034 -0.711886
+v -0.675592 0.888419 -0.725258
+v 0.57274 -0.255442 -0.257086
+v -0.691623 0.905041 -0.711424
+v -0.452739 -0.71398 0.361826
+v 0.291903 -0.128209 -0.263791
+v 0.359675 0.181144 -0.0819145
+v -0.862517 0.24794 -0.0222994
+v -0.875401 0.228762 -0.0188697
+v -0.651597 0.688932 -0.699285
+v -0.651944 0.670846 -0.699452
+v -0.650171 0.707082 -0.699465
+v -0.650261 0.725297 -0.699568
+v -0.650428 0.743537 -0.699786
+v -0.653331 0.761623 -0.69976
+v -0.656542 0.779722 -0.699979
+v -0.660897 0.797911 -0.699915
+v -0.666934 0.81601 -0.699979
+v -0.674796 0.834007 -0.700146
+v -0.686279 0.85244 -0.699426
+v -0.698816 0.870038 -0.699671
+v -0.707769 0.88797 -0.699426
+v -0.707371 0.907109 -0.698784
+v 0.361422 0.17178 -0.0975729
+v -0.6531 0.65213 -0.699516
+v -0.231312 0.00227362 -0.221748
+v -0.656363 0.670704 -0.686466
+v -0.658302 0.652233 -0.686877
+v -0.656144 0.688919 -0.686427
+v -0.655001 0.707159 -0.686684
+v -0.655245 0.72531 -0.686877
+v -0.65653 0.743422 -0.686889
+v -0.659548 0.761585 -0.686941
+v -0.664134 0.779684 -0.687056
+v -0.66872 0.797796 -0.687185
+v -0.676234 0.815895 -0.687159
+v -0.685265 0.834019 -0.687095
+v -0.697891 0.85181 -0.687429
+v -0.712766 0.870012 -0.686941
+v -0.723068 0.885709 -0.686812
+v 0.145531 -0.91366 -0.0914714
+v 0.132159 -0.914238 -0.0936037
+v -0.118646 -0.711565 -0.332218
+v -0.115511 -0.693826 -0.345294
+v -0.100893 -0.707532 -0.350304
+v 0.543016 -0.900314 -0.0397305
+v 0.485327 0.185216 0.0163649
+v -0.662503 0.652464 -0.673428
+v -0.658996 0.634879 -0.687223
+v -0.663659 0.634404 -0.673312
+v -0.660948 0.670794 -0.673556
+v -0.660717 0.688958 -0.673543
+v -0.660897 0.707146 -0.673736
+v -0.66127 0.72531 -0.67398
+v -0.663787 0.74346 -0.673826
+v -0.666947 0.761611 -0.673954
+v -0.671687 0.779671 -0.674121
+v -0.677878 0.797732 -0.674263
+v -0.685573 0.815741 -0.674391
+v -0.697583 0.833865 -0.67425
+v -0.712728 0.85199 -0.674018
+v -0.728373 0.869742 -0.674301
+v 0.363233 0.162827 -0.11336
+v -0.214741 0.0863718 -0.155557
+v -0.213983 0.0746954 -0.169147
+v -0.227664 0.0743229 -0.168762
+v -0.667114 0.634378 -0.660582
+v -0.666729 0.652631 -0.660467
+v -0.665675 0.670846 -0.660724
+v -0.665521 0.688996 -0.660788
+v -0.665791 0.707146 -0.66098
+v -0.667345 0.725297 -0.661109
+v -0.668951 0.743396 -0.661263
+v -0.673241 0.761546 -0.661199
+v -0.679625 0.77953 -0.661481
+v -0.687114 0.797629 -0.661456
+v -0.696363 0.815612 -0.661584
+v -0.709838 0.833788 -0.661302
+v -0.724417 0.851091 -0.662201
+v -0.750287 0.869434 -0.660364
+v 0.36444 0.152409 -0.127952
+v -0.672625 0.598064 -0.64748
+v -0.672997 0.616112 -0.64748
+v -0.508449 0.200708 -0.068337
+v -0.671315 0.634481 -0.647506
+v -0.670069 0.652708 -0.647686
+v -0.670081 0.670884 -0.647814
+v -0.67021 0.689035 -0.647955
+v -0.67152 0.707172 -0.647968
+v -0.673344 0.725284 -0.648199
+v -0.676376 0.743434 -0.648302
+v -0.679959 0.761392 -0.648662
+v -0.687358 0.779478 -0.648649
+v -0.695194 0.797333 -0.648893
+v -0.70705 0.815522 -0.64861
+v -0.721026 0.833326 -0.648906
+v -0.75075 0.85181 -0.647737
+v -0.765894 0.869023 -0.647891
+v -0.674115 0.579246 -0.634956
+v -0.677493 0.598116 -0.634699
+v -0.676016 0.616215 -0.634571
+v -0.675631 0.634583 -0.634558
+v -0.674115 0.652747 -0.634648
+v -0.674436 0.670897 -0.634853
+v -0.674667 0.689086 -0.635046
+v -0.676119 0.707262 -0.635097
+v -0.67829 0.725258 -0.635508
+v -0.682657 0.743383 -0.635495
+v -0.689092 0.762458 -0.635534
+v -0.694924 0.779414 -0.635714
+v -0.705547 0.797487 -0.635739
+v -0.717956 0.815278 -0.635945
+v -0.735194 0.832735 -0.636433
+v -0.769915 0.851117 -0.635611
+v -0.776286 0.869087 -0.635817
+v -0.682361 0.580004 -0.622021
+v -0.679869 0.598437 -0.621417
+v -0.678919 0.616446 -0.6217
+v -0.678534 0.634622 -0.621648
+v -0.677313 0.652798 -0.621854
+v -0.677711 0.670974 -0.622046
+v -0.679099 0.689099 -0.622136
+v -0.680782 0.707198 -0.622252
+v -0.683196 0.725181 -0.622791
+v -0.687808 0.743306 -0.62292
+v -0.695232 0.761315 -0.622933
+v -0.702927 0.779209 -0.623087
+v -0.714809 0.79732 -0.622946
+v -0.727628 0.814687 -0.623614
+v -0.761989 0.833416 -0.62247
+v -0.684198 0.598514 -0.608469
+v -0.681604 0.616536 -0.6087
+v -0.680242 0.634686 -0.608841
+v -0.681591 0.652837 -0.608893
+v -0.681745 0.671 -0.609021
+v -0.68362 0.68915 -0.60924
+v -0.68556 0.707224 -0.609509
+v -0.690377 0.725258 -0.609715
+v -0.694963 0.743319 -0.609805
+v -0.701488 0.761161 -0.610036
+v -0.711764 0.779324 -0.609985
+v -0.724186 0.797089 -0.610229
+v -0.741463 0.814392 -0.610845
+v -0.779292 0.83294 -0.609972
+v -0.976082 0.180887 0.511281
+v 0.365121 0.140951 -0.141337
+v 0.352533 0.14284 -0.143289
+v -0.216758 0.134079 -0.102441
+v -0.229141 0.123456 -0.117111
+v -0.686254 0.598642 -0.595791
+v -0.68669 0.580299 -0.609265
+v -0.689748 0.580453 -0.595919
+v -0.684545 0.616574 -0.595842
+v -0.684417 0.634738 -0.595868
+v -0.684558 0.652901 -0.596009
+v -0.684995 0.671064 -0.596227
+v -0.688116 0.689176 -0.596304
+v -0.691443 0.707275 -0.596536
+v -0.695322 0.725181 -0.596985
+v -0.701257 0.74337 -0.597075
+v -0.708926 0.761238 -0.597152
+v -0.719651 0.779119 -0.597281
+v -0.734912 0.796948 -0.597396
+v -0.771662 0.816396 -0.595714
+v 0.45017 -0.126411 -0.268762
+v 0.436695 -0.12695 -0.268454
+v 0.44579 -0.106243 -0.261158
+v 0.209038 -0.246591 -0.423471
+v 0.206135 -0.265461 -0.429521
+v -0.229398 0.135839 -0.10433
+v -0.689234 0.598706 -0.58292
+v -0.687358 0.6166 -0.58292
+v -0.686318 0.634802 -0.583164
+v -0.687821 0.653697 -0.583549
+v -0.689401 0.671115 -0.583318
+v -0.691623 0.689176 -0.583652
+v -0.695053 0.707198 -0.583883
+v -0.701013 0.72531 -0.583857
+v -0.70741 0.743229 -0.584166
+v -0.716646 0.761148 -0.584333
+v -0.72881 0.779029 -0.584487
+v -0.752702 0.7975 -0.583883
+v -0.785496 0.814263 -0.584101
+v -0.938561 0.303817 0.472103
+v -0.937662 0.303766 0.459219
+v -0.784083 -0.0686067 -0.0834816
+v -0.783929 -0.0504563 -0.0751707
+v -0.937983 0.0658578 0.575431
+v 0.65906 0.0116892 -0.0273476
+v 0.649799 0.0197304 -0.035954
+v 0.64836 0.0299295 -0.0211947
+v -0.69531 0.5808 -0.569984
+v -0.697044 0.56274 -0.570036
+v -0.692162 0.598758 -0.570036
+v -0.690197 0.616703 -0.570036
+v -0.689311 0.634866 -0.57028
+v -0.690775 0.653016 -0.570357
+v -0.692818 0.671141 -0.570575
+v -0.69608 0.689227 -0.570742
+v -0.699651 0.707249 -0.571012
+v -0.705727 0.725258 -0.571115
+v -0.713524 0.743178 -0.57132
+v -0.72416 0.761135 -0.571462
+v -0.738187 0.778669 -0.571847
+v -0.775978 0.797179 -0.571115
+v -0.794372 0.815008 -0.57114
+v 0.00693004 0.935292 -0.31435
+v 0.0208158 0.935741 -0.326386
+v 0.00744385 0.917424 -0.31751
+v -0.212455 -0.77488 -0.164587
+v -0.701141 0.562971 -0.556921
+v -0.690171 0.547492 -0.581609
+v -0.698136 0.580864 -0.557049
+v -0.694809 0.598771 -0.557088
+v -0.691841 0.61678 -0.557216
+v -0.692317 0.634917 -0.557422
+v -0.694192 0.653081 -0.557589
+v -0.697159 0.671205 -0.557653
+v -0.700473 0.689317 -0.557794
+v -0.705265 0.707352 -0.557961
+v -0.711482 0.725412 -0.558102
+v -0.719728 0.743088 -0.558552
+v -0.73215 0.760737 -0.558925
+v -0.757442 0.779299 -0.558295
+v -0.790493 0.79592 -0.55886
+v -0.771264 0.565758 -0.0816832
+v -0.231851 -0.465912 -0.243406
+v -0.333213 -0.817937 -0.138986
+v -0.137888 0.915805 -0.147682
+v -0.801694 0.77786 -0.507826
+v -0.800153 0.779247 -0.493915
+v -0.703004 0.563009 -0.54423
+v -0.706395 0.544859 -0.544332
+v -0.699908 0.580967 -0.544307
+v -0.696697 0.598899 -0.544319
+v -0.69513 0.616806 -0.544397
+v -0.696478 0.63502 -0.544461
+v -0.698495 0.653132 -0.544628
+v -0.700499 0.671231 -0.544885
+v -0.704892 0.689381 -0.544898
+v -0.70985 0.707391 -0.545129
+v -0.716453 0.72522 -0.545463
+v -0.727269 0.743049 -0.545643
+v -0.742953 0.760467 -0.546208
+v -0.781874 0.779337 -0.545206
+v 0.45798 -0.109031 -0.258242
+v -0.705868 0.563074 -0.531307
+v -0.708797 0.545206 -0.531153
+v -0.701655 0.581044 -0.531474
+v -0.699818 0.598976 -0.531513
+v -0.698418 0.616908 -0.531603
+v -0.698624 0.635033 -0.531744
+v -0.701732 0.653183 -0.531847
+v -0.704789 0.671308 -0.531924
+v -0.708399 0.689292 -0.532206
+v -0.714732 0.707352 -0.532348
+v -0.722452 0.725271 -0.532579
+v -0.735014 0.742792 -0.532977
+v -0.764828 0.761649 -0.532181
+v -0.794193 0.778412 -0.532964
+v -0.821951 0.370343 -0.0163778
+v -0.938034 0.321492 0.497601
+v -0.939486 0.303804 0.484936
+v -0.713447 0.545321 -0.505501
+v -0.71504 0.545386 -0.492669
+v -0.707615 0.563189 -0.518513
+v -0.709157 0.563253 -0.505655
+v -0.703338 0.581147 -0.518642
+v -0.701475 0.599053 -0.518693
+v -0.700332 0.616985 -0.518873
+v -0.701668 0.635097 -0.518886
+v -0.704815 0.653222 -0.519014
+v -0.708116 0.671334 -0.519143
+v -0.712689 0.689433 -0.519258
+v -0.719407 0.707288 -0.519592
+v -0.730056 0.725258 -0.519695
+v -0.744558 0.742317 -0.520543
+v -0.781668 0.761598 -0.519284
+v -0.800525 0.779132 -0.519605
+v -0.288114 0.216816 -0.00996795
+v -0.452469 0.494595 -0.0140399
+v -0.100598 -0.726325 -0.341955
+v -0.642939 0.119384 -0.0940661
+v -0.705945 0.581173 -0.505732
+v -0.70407 0.599105 -0.505732
+v -0.703197 0.61705 -0.505951
+v -0.704764 0.635187 -0.506053
+v -0.707936 0.65326 -0.506182
+v -0.712458 0.671437 -0.506246
+v -0.717481 0.68942 -0.506477
+v -0.725445 0.707275 -0.506734
+v -0.737725 0.725168 -0.506914
+v -0.762452 0.742689 -0.507248
+v -0.796685 0.761521 -0.5064
+v -0.61396 -0.895279 0.375134
+v -0.710801 0.563369 -0.492823
+v -0.706459 0.581263 -0.492964
+v -0.70461 0.599182 -0.49299
+v -0.705997 0.617101 -0.493054
+v -0.707834 0.635213 -0.493208
+v -0.711019 0.653325 -0.493349
+v -0.715849 0.671398 -0.493491
+v -0.722105 0.68942 -0.493632
+v -0.731559 0.707249 -0.493927
+v -0.747346 0.72459 -0.49448
+v -0.781694 0.743563 -0.493606
+v -0.802221 0.761161 -0.493889
+v -0.712548 0.563498 -0.480003
+v -0.70908 0.581327 -0.480042
+v -0.707294 0.599272 -0.480093
+v -0.708848 0.617204 -0.480132
+v -0.71084 0.635277 -0.48035
+v -0.715361 0.653427 -0.480401
+v -0.719227 0.671359 -0.480761
+v -0.727089 0.689253 -0.480941
+v -0.738226 0.706877 -0.481403
+v -0.76091 0.724732 -0.481442
+v -0.795079 0.743653 -0.480645
+v -0.802658 0.760429 -0.481557
+v -0.493805 -0.79989 0.387967
+v 0.365057 0.128222 -0.15318
+v 0.352841 0.130714 -0.155916
+v 0.311736 0.0921265 -0.191112
+v 0.311312 0.0783306 -0.201915
+v 0.29934 0.0943744 -0.193489
+v 0.299289 0.157548 -0.133193
+v 0.300535 0.147387 -0.147926
+v 0.286367 0.147027 -0.147194
+v 0.28566 0.157573 -0.133052
+v -0.361743 -0.958362 0.58387
+v 0.393869 0.193925 -0.0441364
+v 0.395539 0.184343 -0.059615
+v 0.596298 -0.24979 -0.237381
+v 0.593716 -0.268133 -0.243919
+v 0.583337 -0.261363 -0.250804
+v 0.564198 0.0496342 -0.0927045
+v 0.562952 0.0372385 -0.106655
+v 0.551108 0.053886 -0.0989602
+v 0.209333 0.21891 -0.0437382
+v -0.203322 -0.800943 -0.274877
+v -0.189115 -0.797449 -0.279539
+v -0.19916 -0.806813 -0.295776
+v 0.106417 0.140951 -0.139115
+v 0.106648 0.1288 -0.151896
+v 0.0924669 0.127721 -0.150547
+v 0.090052 0.187464 -0.0857295
+v 0.0902318 0.175248 -0.0982922
+v -0.968208 0.076892 0.499014
+v -0.892523 0.00291588 0.281402
+v -0.969839 0.128312 0.40884
+v -0.923352 -0.273335 0.282404
+v -0.928208 -0.255968 0.282404
+v -0.719472 0.545565 -0.466939
+v -0.715053 0.563459 -0.467081
+v -0.71066 0.581417 -0.467209
+v -0.70908 0.599349 -0.467286
+v -0.710737 0.617268 -0.467363
+v -0.713858 0.635354 -0.467492
+v -0.718572 0.653453 -0.467607
+v -0.723633 0.671411 -0.467839
+v -0.733036 0.689304 -0.468031
+v -0.747474 0.706543 -0.468712
+v -0.779909 0.725798 -0.467736
+v -0.800975 0.743178 -0.468173
+v -0.957957 0.268364 0.395275
+v -0.953372 0.285782 0.382263
+v 0.36516 0.115569 -0.165242
+v 0.352738 0.117791 -0.167554
+v 0.364492 0.101491 -0.175724
+v 0.351736 0.103045 -0.177329
+v 0.362693 0.0852928 -0.183893
+v 0.349514 0.0860378 -0.184561
+v 0.288409 -0.224086 -0.39394
+v 0.360009 0.0671552 -0.189995
+v 0.347819 0.0699812 -0.192962
+v 0.549528 -0.0135389 -0.154901
+v 0.548321 -0.0287478 -0.164291
+v 0.536799 -0.0118177 -0.156713
+v 0.289437 -0.20907 -0.383972
+v 0.560755 0.109699 -0.0305847
+v 0.56168 0.0987546 -0.0442392
+v 0.549682 0.114657 -0.0359026
+v 0.526715 -0.318833 -0.294633
+v 0.529271 -0.300182 -0.28812
+v 0.00272963 -0.910089 -0.333682
+v 0.238364 0.209507 -0.0598462
+v 0.585636 -0.243932 -0.243547
+v -0.204812 -0.970308 0.538449
+v -0.218094 -0.970771 0.536009
+v 0.279083 0.22162 -0.0478873
+v 0.280869 0.212474 -0.0637127
+v -0.588848 -0.854855 -0.0340015
+v -0.603928 -0.870423 -0.0453567
+v -0.608707 -0.863782 -0.0347594
+v 0.294485 0.212474 -0.0639054
+v 0.530158 0.0788701 -0.100283
+v 0.530337 0.0665772 -0.112666
+v 0.0905015 0.162994 -0.110804
+v 0.457851 -0.0451641 -0.198203
+v -0.883519 -0.0316893 0.281209
+v 0.0116956 -0.194414 -0.40085
+v 0.0263136 -0.19223 -0.403085
+v 0.0124535 -0.206 -0.414762
+v -0.895516 -0.0661147 0.281325
+v -0.887861 -0.0489791 0.281235
+v 0.26548 -0.0480799 -0.246373
+v 0.264183 -0.063687 -0.255018
+v 0.252365 -0.0471936 -0.247349
+v -0.725573 0.527775 -0.454004
+v -0.720011 0.545668 -0.454197
+v -0.715438 0.563626 -0.454287
+v -0.712073 0.581455 -0.454325
+v -0.71179 0.599426 -0.454351
+v -0.713486 0.617332 -0.454479
+v -0.716813 0.635483 -0.454608
+v -0.721681 0.653517 -0.454775
+v -0.728116 0.671501 -0.454968
+v -0.739176 0.689292 -0.455263
+v -0.758136 0.706479 -0.455867
+v -0.793486 0.725824 -0.454852
+v -0.288923 0.821611 -0.0827751
+v -0.978189 0.163611 0.498513
+v 0.35893 0.0523061 -0.199732
+v 0.347099 0.0558385 -0.203431
+v -0.187997 0.111099 -0.130264
+v -0.187239 0.0998722 -0.14415
+v -0.200907 0.099641 -0.143893
+v -0.191645 0.130508 -0.0986005
+v -0.189757 0.120707 -0.1144
+v 0.294498 -0.110816 -0.256071
+v 0.269449 -0.157342 -0.310073
+v 0.215602 0.116199 -0.164831
+v 0.216951 0.105409 -0.179141
+v 0.202191 0.1037 -0.177124
+v 0.0261081 0.182275 -0.0528456
+v 0.0416766 0.186077 -0.0574313
+v 0.0269173 0.170855 -0.0664744
+v 0.551095 0.0409123 -0.110637
+v 0.540447 0.0593196 -0.104741
+v 0.201434 0.115042 -0.163521
+v 0.227702 0.164625 -0.113912
+v 0.241845 0.165666 -0.115184
+v 0.227908 0.152499 -0.126565
+v -0.136077 0.0155428 -0.210136
+v -0.136282 0.00196533 -0.221594
+v -0.149706 0.0154786 -0.210046
+v 0.158338 0.24979 0.0269494
+v 0.281588 0.201633 -0.0775214
+v -0.212403 -0.793711 -0.241517
+v 0.0908741 0.150573 -0.123302
+v 0.105543 0.152654 -0.125781
+v 0.0916962 0.138973 -0.136777
+v 0.105171 0.165036 -0.113231
+v -0.18616 0.0501352 -0.195197
+v -0.199854 0.0498654 -0.194735
+v -0.199597 0.0632117 -0.183058
+v 0.00642907 0.0285166 -0.224549
+v -0.00619786 0.0302378 -0.226373
+v -0.00496471 0.0454852 -0.216867
+v 0.269321 -0.036699 -0.241068
+v 0.25645 -0.0368275 -0.242095
+v 0.0271228 -0.203778 -0.416997
+v 0.0105139 -0.184163 -0.38577
+v 0.0251318 -0.181954 -0.387954
+v 0.372482 -0.219911 -0.346296
+v 0.384325 -0.223431 -0.342546
+v 0.372392 -0.233232 -0.35823
+v 0.186135 0.201222 -0.0760185
+v 0.186443 0.189237 -0.0887225
+v 0.174214 0.191485 -0.0912658
+v -0.906628 -0.308711 0.282597
+v -0.916043 -0.290946 0.282519
+v -0.905407 -0.0834045 0.281184
+v 0.226996 -0.135133 -0.282365
+v 0.215563 -0.11792 -0.274902
+v 0.228203 -0.119782 -0.272886
+v 0.498931 -0.9677 0.124612
+v 0.504917 -0.973185 0.106899
+v 0.223694 -0.968946 0.211164
+v 0.208447 -0.956885 0.220541
+v -0.726896 0.510074 -0.440979
+v -0.727371 0.527826 -0.44121
+v -0.722811 0.54572 -0.441313
+v -0.718071 0.563613 -0.441403
+v -0.713486 0.581545 -0.44148
+v -0.713498 0.599464 -0.441557
+v -0.716324 0.617473 -0.441557
+v -0.71996 0.635508 -0.441801
+v -0.724738 0.653556 -0.441904
+v -0.732959 0.671398 -0.442225
+v -0.745689 0.688842 -0.442675
+v -0.774282 0.707365 -0.442354
+v -0.798534 0.725592 -0.442199
+v 0.358673 0.0390626 -0.211318
+v 0.346752 0.0422996 -0.214516
+v 0.357966 0.0250098 -0.221286
+v 0.345494 0.0270907 -0.223675
+v 0.348422 -0.967097 -0.0981895
+v 0.358968 -0.971747 -0.0918182
+v 0.340214 -0.965735 -0.0769562
+v -0.203771 0.0163007 -0.211112
+v -0.206045 -0.00146436 -0.217728
+v 0.504929 0.0311884 -0.151626
+v 0.492174 0.0205011 -0.165512
+v 0.877096 -0.492502 0.0963269
+v 0.863493 -0.492823 0.0965067
+v -0.197323 -0.816614 -0.312398
+v -0.195936 -0.827597 -0.327838
+v -0.210168 -0.829267 -0.326271
+v 0.517299 0.118254 -0.0653055
+v 0.518301 0.107554 -0.0796922
+v 0.505983 0.122788 -0.0703537
+v 0.519213 0.0965453 -0.0934752
+v 0.507884 0.101003 -0.0984335
+v 0.507087 0.112229 -0.0848303
+v 0.508822 -0.0518179 -0.190894
+v 0.496118 -0.0501352 -0.192679
+v 0.497453 -0.0346309 -0.183649
+v 0.0604179 -0.103096 -0.290175
+v 0.11889 -0.170868 -0.373092
+v 0.175704 0.244639 0.00642265
+v 0.17898 0.237805 -0.0124856
+v 0.16539 0.237381 -0.0121131
+v -0.824199 -0.415879 0.379489
+v 0.090797 0.0857552 -0.18302
+v 0.0920044 0.101118 -0.173707
+v 0.493754 -0.118742 -0.247747
+v 0.505662 -0.121902 -0.244215
+v 0.492174 -0.134876 -0.256366
+v 0.0928009 0.115325 -0.163122
+v -0.0390561 0.148273 -0.0934881
+v -0.0254658 0.148235 -0.0935138
+v -0.0383368 0.137149 -0.10731
+v -0.160007 -0.363638 -0.424974
+v -0.15853 -0.345526 -0.424833
+v -0.144863 -0.328364 -0.437716
+v -0.155101 -0.327478 -0.425077
+v -0.164478 0.142634 -0.0860506
+v -0.163758 0.131677 -0.100091
+v -0.177888 0.130688 -0.0988446
+v -0.138235 -0.273631 -0.411795
+v -0.127727 -0.284523 -0.43042
+v 0.394139 0.0158768 -0.211857
+v 0.390375 -0.00434171 -0.215673
+v 0.0887674 0.19792 -0.071073
+v 0.103951 0.200862 -0.074567
+v -0.371711 -0.00400773 -0.214619
+v 0.231016 -0.109378 -0.270805
+v 0.37207 -0.0188055 -0.224343
+v -0.729016 0.509843 -0.428326
+v -0.729273 0.527839 -0.428416
+v -0.724533 0.545822 -0.428493
+v -0.718585 0.563767 -0.428622
+v -0.715284 0.581622 -0.428635
+v -0.716389 0.599554 -0.428686
+v -0.718277 0.617473 -0.428853
+v -0.721694 0.635521 -0.428969
+v -0.729054 0.653736 -0.428956
+v -0.738714 0.671616 -0.429238
+v -0.75495 0.688739 -0.429932
+v -0.787924 0.707609 -0.429303
+v -0.800384 0.725554 -0.429393
+v -0.961862 0.250663 0.408121
+v -0.613485 -0.858772 0.465668
+v 0.332944 0.029146 -0.226077
+v 0.322102 0.0473221 -0.219963
+v -0.0724025 -0.239642 -0.43254
+v -0.201652 0.110945 -0.130007
+v -0.105338 -0.226514 -0.394697
+v -0.0896152 -0.220631 -0.400375
+v -0.103617 -0.237625 -0.411191
+v 0.491647 -0.214812 -0.274825
+v -0.192288 0.141465 -0.0844835
+v -0.134587 0.0443805 -0.18907
+v -0.147214 0.0462688 -0.191087
+v -0.146494 0.06045 -0.180284
+v 0.249013 0.228865 -0.0295185
+v 0.250772 0.219732 -0.0453696
+v -0.285223 -0.972826 0.455841
+v 0.0475212 0.221389 0.00818245
+v 0.0508481 0.214671 -0.0108928
+v 0.119879 0.167079 -0.115646
+v 0.119699 0.153733 -0.127104
+v 0.0396085 0.231061 0.0498783
+v 0.0432052 0.226064 0.02948
+v -0.142178 -0.510369 -0.410446
+v -0.138132 -0.49299 -0.424306
+v -0.158222 -0.473259 -0.411846
+v -0.155743 -0.454942 -0.424036
+v -0.167432 -0.454043 -0.411319
+v -0.174124 -0.435276 -0.411448
+v -0.176038 -0.416997 -0.41173
+v -0.174202 -0.398846 -0.411563
+v -0.172493 -0.380773 -0.411448
+v -0.169564 -0.362841 -0.411717
+v -0.166212 -0.344896 -0.411692
+v -0.161729 -0.326887 -0.412039
+v -0.157965 -0.309096 -0.41173
+v -0.149873 -0.291164 -0.411884
+v -0.436515 0.674224 -0.0298139
+v -0.435359 0.659979 -0.0368403
+v -0.443889 0.655752 -0.0293001
+v -0.127676 -0.267272 -0.417446
+v -0.123552 -0.256277 -0.411795
+v 0.300291 0.134426 -0.159551
+v 0.286123 0.133604 -0.158498
+v -0.913114 -0.100386 0.281325
+v -0.715541 0.497152 -0.413529
+v -0.73206 0.527967 -0.415545
+v -0.726113 0.545899 -0.415674
+v -0.721257 0.563754 -0.415687
+v -0.717108 0.581674 -0.415854
+v -0.71838 0.599593 -0.415892
+v -0.721257 0.617576 -0.415944
+v -0.725817 0.635727 -0.416034
+v -0.732394 0.653697 -0.4162
+v -0.744713 0.671758 -0.416303
+v -0.768412 0.689176 -0.41674
+v -0.79549 0.707699 -0.416445
+v -0.80032 0.725618 -0.416547
+v -0.894746 -0.32708 0.282776
+v 0.134933 -0.129018 -0.289148
+v 0.124554 -0.109789 -0.283984
+v 0.586446 0.00435456 -0.12275
+v 0.585559 -0.0104432 -0.132589
+v 0.574153 -0.00593453 -0.137393
+v 0.58344 -0.0401159 -0.15214
+v 0.582721 -0.0543356 -0.162634
+v 0.570774 -0.0509059 -0.166218
+v 0.334203 0.0443677 -0.216829
+v 0.646292 -0.194221 -0.167567
+v 0.23135 0.246784 0.00318563
+v 0.244979 0.246951 0.00287735
+v 0.233072 0.237548 -0.0126398
+v 0.2467 0.237754 -0.0129866
+v 0.252519 0.210496 -0.0611308
+v -0.11975 -0.548931 -0.41078
+v -0.119699 -0.566966 -0.397806
+v 0.0692169 0.211318 -0.0335776
+v 0.0720172 0.203726 -0.0514583
+v 0.0563459 0.199834 -0.0469367
+v -0.130078 -0.548289 -0.398268
+v -0.142653 -0.528777 -0.397896
+v -0.150926 -0.50992 -0.397999
+v -0.158941 -0.490999 -0.397909
+v -0.166289 -0.472938 -0.398435
+v -0.175961 -0.453478 -0.39859
+v -0.182422 -0.4348 -0.398371
+v -0.185557 -0.416098 -0.3985
+v -0.183951 -0.398024 -0.3985
+v -0.180855 -0.38008 -0.398744
+v -0.177361 -0.36216 -0.398564
+v -0.174124 -0.344241 -0.398564
+v -0.168241 -0.326373 -0.399039
+v -0.163399 -0.308467 -0.399168
+v -0.157991 -0.290586 -0.398885
+v -0.146969 -0.272603 -0.399232
+v -0.104079 -0.249404 -0.422687
+v -0.133495 -0.25539 -0.399013
+v -0.115627 -0.237998 -0.399155
+v -0.125428 -0.23733 -0.386245
+v -0.734732 0.528096 -0.402584
+v -0.728874 0.545925 -0.402764
+v -0.723004 0.56387 -0.40288
+v -0.720062 0.581776 -0.403008
+v -0.720075 0.599657 -0.403111
+v -0.722786 0.61764 -0.403098
+v -0.7289 0.635817 -0.403137
+v -0.737442 0.653492 -0.403574
+v -0.752831 0.671359 -0.403753
+v -0.781566 0.68987 -0.403458
+v -0.798496 0.707725 -0.403586
+v -0.798817 0.725721 -0.403676
+v 0.67766 -0.238563 -0.171909
+v 0.677506 -0.251896 -0.183559
+v 0.666703 -0.246129 -0.189622
+v 0.323515 0.0756331 -0.199076
+v 0.33577 0.0730641 -0.196315
+v 0.32277 0.0614391 -0.209455
+v 0.334652 0.0580222 -0.205859
+v 0.253752 0.200631 -0.0760313
+v 0.239584 0.199577 -0.0746826
+v 0.333445 -3.85359e-05 -0.231023
+v 0.342321 0.00806685 -0.229019
+v 0.561372 -0.0170971 -0.151176
+v 0.0534429 0.20767 -0.0290818
+v 0.159879 -0.170688 -0.373284
+v 0.146713 -0.17011 -0.374094
+v -0.104336 -0.604166 -0.397138
+v 0.0706813 -0.147862 -0.320901
+v 0.0848625 -0.146693 -0.32207
+v -0.114047 -0.62143 -0.384164
+v -0.119005 -0.602868 -0.384241
+v -0.109731 -0.585797 -0.397703
+v -0.122628 -0.584512 -0.384627
+v -0.101292 -0.594146 -0.40252
+v -0.129397 -0.565964 -0.384794
+v -0.140637 -0.546876 -0.384588
+v -0.152043 -0.527685 -0.384678
+v -0.160663 -0.509033 -0.385025
+v -0.167471 -0.490408 -0.38523
+v -0.175871 -0.471666 -0.385346
+v -0.184067 -0.452822 -0.385423
+v -0.190464 -0.433953 -0.38541
+v -0.194112 -0.415443 -0.385719
+v -0.193431 -0.397215 -0.385333
+v -0.190489 -0.37927 -0.385642
+v -0.184054 -0.361544 -0.385757
+v -0.179301 -0.343702 -0.385886
+v -0.175679 -0.325924 -0.385706
+v -0.169616 -0.30821 -0.385886
+v -0.16467 -0.289995 -0.386053
+v -0.155319 -0.271884 -0.386361
+v -0.141947 -0.254504 -0.386271
+v -0.919242 -0.117367 0.281479
+v -0.1002 -0.923448 -0.0126141
+v -0.730621 0.546054 -0.389932
+v -0.723633 0.564063 -0.39015
+v -0.721578 0.581841 -0.390125
+v -0.72163 0.599734 -0.390253
+v -0.725547 0.617769 -0.390189
+v -0.732407 0.635701 -0.390433
+v -0.743505 0.65353 -0.390703
+v -0.763659 0.671334 -0.390882
+v -0.789376 0.689818 -0.390664
+v -0.798432 0.707814 -0.39069
+v -0.795644 0.725785 -0.39087
+v 0.616362 -0.277947 -0.232025
+v 0.468616 -0.206347 -0.283483
+v 0.33726 0.0885426 -0.187233
+v 0.324324 0.090007 -0.188852
+v 0.325545 0.105036 -0.179359
+v 0.332391 -0.128723 -0.2632
+v 0.255589 0.190534 -0.0911759
+v 0.24083 0.189006 -0.0891721
+v 0.230246 0.118023 -0.167015
+v 0.243887 0.118459 -0.167438
+v 0.231016 0.106732 -0.180605
+v -0.0882793 -0.668379 -0.38306
+v -0.0953828 -0.659028 -0.383278
+v -0.0881765 -0.649291 -0.392681
+v -0.112043 -0.657782 -0.370869
+v -0.120495 -0.638938 -0.371306
+v -0.105595 -0.640184 -0.383753
+v -0.125608 -0.620415 -0.371447
+v -0.131825 -0.60161 -0.371165
+v -0.13564 -0.583318 -0.371679
+v -0.140393 -0.564705 -0.371602
+v -0.14598 -0.546477 -0.372192
+v -0.159699 -0.526721 -0.371499
+v -0.166995 -0.50843 -0.371859
+v -0.175525 -0.489586 -0.372205
+v -0.180586 -0.470921 -0.372141
+v -0.188922 -0.452347 -0.372449
+v -0.195679 -0.43358 -0.372655
+v -0.199455 -0.415057 -0.372938
+v -0.198402 -0.396804 -0.372462
+v -0.196552 -0.378756 -0.372462
+v -0.194921 -0.36076 -0.372514
+v -0.188563 -0.343059 -0.372681
+v -0.180765 -0.325423 -0.372963
+v -0.174317 -0.307735 -0.373002
+v -0.169397 -0.28979 -0.372963
+v -0.161536 -0.271601 -0.373259
+v -0.149628 -0.25435 -0.373092
+v -0.13221 -0.236662 -0.37349
+v -0.112326 -0.219719 -0.3734
+v -0.121767 -0.219526 -0.360298
+v -0.863711 -0.363342 0.360028
+v -0.733319 0.546079 -0.377048
+v -0.726292 0.564063 -0.377228
+v -0.72303 0.581905 -0.377279
+v -0.724224 0.59985 -0.377292
+v -0.727487 0.617743 -0.377433
+v -0.735695 0.635637 -0.377652
+v -0.748618 0.653209 -0.378088
+v -0.775374 0.671938 -0.377677
+v -0.793512 0.689625 -0.377986
+v -0.796903 0.707853 -0.377922
+v -0.979717 0.215531 0.369919
+v -0.53026 0.532155 0.00937707
+v 0.330657 -0.145139 -0.271511
+v 0.338262 0.10352 -0.177805
+v 0.331415 -0.156571 -0.285166
+v 0.255795 0.17855 -0.103751
+v 0.240997 0.177458 -0.102069
+v 0.217683 0.0941303 -0.192808
+v -0.0989152 -0.677024 -0.370741
+v 0.089885 -0.162313 -0.356907
+v 0.0767185 -0.161748 -0.357716
+v -0.113623 -0.675727 -0.357909
+v -0.122178 -0.657024 -0.358332
+v -0.130887 -0.638321 -0.358769
+v -0.136886 -0.619362 -0.358448
+v -0.141908 -0.600813 -0.358538
+v -0.147214 -0.582342 -0.35891
+v -0.151876 -0.563716 -0.358795
+v -0.157079 -0.545244 -0.359039
+v -0.164696 -0.526272 -0.358705
+v -0.173315 -0.507633 -0.359
+v -0.179018 -0.489688 -0.35945
+v -0.185248 -0.470587 -0.359347
+v -0.19099 -0.451628 -0.359013
+v -0.198826 -0.433824 -0.359604
+v -0.200843 -0.414556 -0.359617
+v -0.201626 -0.39647 -0.359566
+v -0.202975 -0.378243 -0.359527
+v -0.201729 -0.360144 -0.359835
+v -0.198197 -0.34234 -0.359822
+v -0.188948 -0.324729 -0.360079
+v -0.180598 -0.307272 -0.360002
+v -0.174022 -0.289405 -0.360028
+v -0.166276 -0.271395 -0.360285
+v -0.154625 -0.253874 -0.360259
+v -0.138671 -0.236148 -0.360529
+v -0.128562 -0.218704 -0.347581
+v -0.975401 0.233142 0.369816
+v -0.925407 -0.151729 0.2818
+v -0.926461 -0.169095 0.281852
+v -0.973307 0.128093 0.370317
+v -0.460125 -0.767095 0.374929
+v -0.734886 0.546169 -0.364228
+v -0.727718 0.564101 -0.364357
+v -0.724738 0.581995 -0.36446
+v -0.72601 0.599888 -0.364498
+v -0.73057 0.61782 -0.364588
+v -0.740281 0.635675 -0.364794
+v -0.757404 0.653492 -0.365051
+v -0.784212 0.672194 -0.364717
+v -0.795374 0.689934 -0.364948
+v -0.795464 0.70793 -0.365089
+v 0.488873 -0.326206 -0.319424
+v 0.479419 -0.317189 -0.322057
+v 0.0596214 0.860905 -0.351242
+v -0.452508 -0.731771 0.374787
+v -0.966281 0.110482 0.370484
+v -0.923622 -0.13449 0.281633
+v -0.928079 -0.186398 0.282057
+v 0.909389 -0.63931 -0.0110084
+v 0.332635 -0.166835 -0.299976
+v 0.339906 0.119192 -0.169031
+v 0.255461 0.166141 -0.115646
+v 0.231787 0.0954149 -0.194259
+v -0.100829 -0.695188 -0.358165
+v -0.0878811 -0.687185 -0.372848
+v 0.24521 0.107695 -0.181787
+v -0.123784 -0.674969 -0.345359
+v -0.132005 -0.656099 -0.345397
+v -0.140007 -0.637127 -0.345372
+v -0.146802 -0.618501 -0.345654
+v -0.153032 -0.599683 -0.3455
+v -0.158569 -0.581288 -0.345975
+v -0.163386 -0.562714 -0.345988
+v -0.166597 -0.544294 -0.345975
+v -0.174381 -0.525386 -0.34577
+v -0.181215 -0.506811 -0.346001
+v -0.186944 -0.488532 -0.346425
+v -0.191543 -0.469868 -0.346348
+v -0.197015 -0.451512 -0.34672
+v -0.203861 -0.432398 -0.346746
+v -0.203797 -0.414248 -0.346656
+v -0.204748 -0.396175 -0.346605
+v -0.205955 -0.37796 -0.346566
+v -0.20485 -0.359874 -0.346772
+v -0.20345 -0.341801 -0.347016
+v -0.195371 -0.324151 -0.347273
+v -0.186957 -0.30681 -0.347067
+v -0.178749 -0.289071 -0.347106
+v -0.169513 -0.271139 -0.347311
+v -0.160894 -0.253566 -0.347298
+v -0.145145 -0.235788 -0.347632
+v -0.134895 -0.218499 -0.334659
+v -0.931869 -0.203598 0.28198
+v -0.932973 -0.220849 0.28198
+v -0.788284 0.7082 -0.339334
+v -0.736453 0.546259 -0.351357
+v -0.729183 0.564178 -0.351499
+v -0.726292 0.582046 -0.351627
+v -0.727641 0.59994 -0.351691
+v -0.734051 0.617769 -0.351846
+v -0.745008 0.635662 -0.352038
+v -0.767577 0.654108 -0.351897
+v -0.78926 0.671976 -0.352013
+v -0.795362 0.689985 -0.352102
+v -0.792279 0.707981 -0.352282
+v 0.211209 -0.91998 0.304215
+v 0.203694 -0.917899 0.324087
+v -0.938445 0.321531 0.484859
+v 0.617313 -0.368622 -0.234003
+v 0.617981 -0.386579 -0.23652
+v 0.605765 -0.39087 -0.244806
+v -0.97061 0.250573 0.369572
+v -0.93183 -0.238242 0.28216
+v 0.0817667 0.221119 -0.0188697
+v 0.241986 0.153925 -0.128068
+v 0.324312 0.166758 -0.117252
+v 0.326046 0.156905 -0.132666
+v 0.312417 0.157265 -0.132756
+v 0.258081 0.144715 -0.144471
+v 0.234228 -0.15941 -0.333811
+v 0.246893 -0.16099 -0.331922
+v 0.235551 -0.169494 -0.348647
+v 0.079005 -0.170008 -0.374607
+v -0.125351 -0.69285 -0.332372
+v 0.113443 -0.915831 -0.0479643
+v -0.131735 -0.67407 -0.332256
+v -0.137117 -0.655663 -0.332642
+v -0.144773 -0.636574 -0.332411
+v -0.15284 -0.61773 -0.332488
+v -0.158569 -0.599426 -0.332989
+v -0.168267 -0.580376 -0.332976
+v -0.171491 -0.561956 -0.333053
+v -0.173097 -0.543664 -0.333066
+v -0.177644 -0.525039 -0.332924
+v -0.186302 -0.506374 -0.33322
+v -0.193315 -0.487762 -0.333605
+v -0.196912 -0.46965 -0.333772
+v -0.207792 -0.450343 -0.333567
+v -0.21275 -0.431808 -0.333644
+v -0.209886 -0.413927 -0.333836
+v -0.207522 -0.395841 -0.333631
+v -0.207599 -0.377729 -0.333708
+v -0.209513 -0.359463 -0.333875
+v -0.206084 -0.341634 -0.333914
+v -0.200021 -0.323881 -0.334235
+v -0.1918 -0.306386 -0.334235
+v -0.18345 -0.288749 -0.334222
+v -0.174137 -0.270817 -0.334517
+v -0.163129 -0.252962 -0.334697
+v -0.151504 -0.235493 -0.334723
+v -0.0520941 -0.0317022 -0.263419
+v -0.0508738 -0.0161979 -0.254234
+v -0.0372192 -0.0161337 -0.254273
+v -0.934155 0.374171 0.368891
+v -0.925562 0.356329 0.369033
+v -0.744995 0.51087 -0.338217
+v -0.635271 -0.595829 -0.0263714
+v -0.745445 0.528494 -0.338384
+v -0.738123 0.546362 -0.338538
+v -0.730737 0.564255 -0.338666
+v -0.727834 0.582085 -0.338808
+v -0.730673 0.600017 -0.33882
+v -0.738341 0.617897 -0.338885
+v -0.749786 0.635547 -0.33927
+v -0.775349 0.65407 -0.339077
+v -0.792112 0.671604 -0.339386
+v -0.79382 0.690037 -0.339321
+v -0.239623 0.786389 -0.156867
+v -0.255859 0.795368 -0.140874
+v -0.93287 0.338859 0.420568
+v -0.966371 0.233129 0.408262
+v 0.334485 -0.175852 -0.315904
+v -0.545122 0.0652541 -0.157098
+v -0.540575 0.0492746 -0.169763
+v -0.561384 0.0464743 -0.163045
+v -0.339007 -0.945889 -0.318859
+v -0.331518 -0.928407 -0.318217
+v -0.324324 -0.94761 -0.330394
+v 0.257824 0.131317 -0.155878
+v 0.243669 0.130534 -0.154734
+v -0.319996 -0.911387 -0.318204
+v -0.318942 -0.930115 -0.330253
+v 0.135383 -0.204292 -0.415789
+v 0.122178 -0.203688 -0.416496
+v 0.121947 -0.190958 -0.403805
+v -0.295307 -0.97438 0.409778
+v 0.171735 0.0330638 -0.229969
+v 0.265506 -0.139423 -0.277767
+v 0.267047 -0.12361 -0.268595
+v 0.259379 0.108633 -0.182981
+v 0.260098 0.0973545 -0.196559
+v 0.246508 0.0969306 -0.196058
+v 0.258595 0.119705 -0.169198
+v -0.128575 -0.710628 -0.31945
+v -0.133418 -0.692053 -0.319463
+v -0.136835 -0.67362 -0.319552
+v -0.143514 -0.655033 -0.319642
+v -0.149603 -0.636112 -0.319514
+v -0.154484 -0.617512 -0.319617
+v -0.162705 -0.598681 -0.319707
+v -0.171684 -0.580068 -0.320131
+v -0.175152 -0.561686 -0.32031
+v -0.177901 -0.543176 -0.320169
+v -0.182538 -0.524551 -0.320118
+v -0.189603 -0.506053 -0.320387
+v -0.198004 -0.487415 -0.320593
+v -0.204748 -0.468789 -0.320721
+v -0.212224 -0.449714 -0.320477
+v -0.217516 -0.431255 -0.320696
+v -0.21898 -0.413002 -0.320709
+v -0.214048 -0.395314 -0.320798
+v -0.212493 -0.377331 -0.320876
+v -0.212558 -0.359219 -0.320965
+v -0.211003 -0.341261 -0.321068
+v -0.203681 -0.323329 -0.321377
+v -0.196591 -0.305949 -0.321338
+v -0.142435 -0.218601 -0.321274
+v 0.0267375 -0.98359 -0.291293
+v -0.746845 0.528623 -0.325513
+v -0.739664 0.546452 -0.32568
+v -0.732176 0.56432 -0.325821
+v -0.730519 0.5822 -0.325885
+v -0.733589 0.600107 -0.325975
+v -0.741488 0.617859 -0.326181
+v -0.758611 0.635906 -0.326245
+v -0.783801 0.654481 -0.326052
+v -0.79224 0.672117 -0.326335
+v -0.790981 0.690139 -0.32645
+v 0.335718 -0.186295 -0.330561
+v 0.336283 -0.198177 -0.343817
+v 0.336695 -0.210136 -0.356624
+v 0.337915 0.166218 -0.117072
+v 0.395153 -0.241993 -0.348981
+v -0.348743 -0.964181 -0.309495
+v -0.345789 -0.945247 -0.30496
+v -0.339906 -0.974714 -0.323393
+v -0.348705 -0.974431 -0.301428
+v -0.339983 -0.927392 -0.305551
+v -0.328422 -0.910308 -0.305564
+v -0.314909 -0.89375 -0.305217
+v -0.29699 -0.877347 -0.305294
+v -0.28155 -0.85998 -0.305885
+v 0.33988 0.144587 -0.145178
+v 0.340201 0.132666 -0.15792
+v -0.131619 -0.746543 -0.306437
+v -0.135165 -0.728123 -0.306643
+v -0.137978 -0.709587 -0.30636
+v -0.13862 -0.691565 -0.30672
+v -0.14309 -0.672952 -0.306527
+v -0.149834 -0.65425 -0.306707
+v -0.15442 -0.635598 -0.306656
+v -0.157747 -0.617139 -0.306784
+v -0.164323 -0.598475 -0.306874
+v -0.174176 -0.579516 -0.306977
+v -0.179931 -0.561018 -0.307337
+v -0.182756 -0.542637 -0.307234
+v -0.187419 -0.524114 -0.307247
+v -0.194035 -0.50545 -0.307324
+v -0.200637 -0.486811 -0.307427
+v -0.209385 -0.468352 -0.307748
+v -0.217092 -0.449329 -0.307658
+v -0.220432 -0.43096 -0.307773
+v -0.222256 -0.412694 -0.307838
+v -0.220701 -0.394697 -0.307966
+v -0.217786 -0.376855 -0.308172
+v -0.216103 -0.358859 -0.308287
+v -0.215743 -0.340824 -0.308107
+v -0.210297 -0.320978 -0.307619
+v -0.203206 -0.305435 -0.30875
+v 0.308717 0.188415 -0.0891721
+v 0.296245 0.177702 -0.103263
+v 0.00672451 -0.920545 0.355673
+v -0.00185615 -0.92061 0.377138
+v -0.0066346 -0.921149 0.35349
+v 0.161022 0.166976 -0.11598
+v 0.161305 0.180399 -0.10483
+v 0.465327 -0.238897 -0.300644
+v 0.336014 -0.224651 -0.367414
+v 0.172429 0.0728714 -0.195351
+v 0.157772 0.0710859 -0.193322
+v -0.853178 -0.0152088 0.358358
+v -0.864302 0.00245345 0.358409
+v -0.748232 0.511076 -0.299719
+v -0.303181 -0.822215 -0.228377
+v -0.289809 -0.812876 -0.21038
+v -0.748309 0.5287 -0.31268
+v -0.741077 0.546465 -0.312822
+v -0.732381 0.564384 -0.312989
+v -0.730801 0.582226 -0.313066
+v -0.735348 0.600119 -0.313168
+v -0.746678 0.617692 -0.313489
+v -0.768939 0.636305 -0.313207
+v -0.787963 0.654057 -0.313451
+v -0.792035 0.672169 -0.313515
+v -0.78813 0.690268 -0.313579
+v 0.334524 -0.240451 -0.376676
+v 0.13099 0.0462174 -0.217985
+v 0.132788 0.0364421 -0.233515
+v 0.118556 0.0358384 -0.232667
+v -0.00599233 0.0696986 -0.19101
+v 0.00764937 0.0699298 -0.191344
+v -0.00523446 0.0579323 -0.20433
+v 0.609336 0.00879903 -0.101799
+v 0.620177 0.00271036 -0.0951837
+v 0.608552 -0.00544641 -0.112139
+v 0.0285872 0.147798 -0.0934238
+v 0.0309122 0.138986 -0.110187
+v 0.0157034 0.136237 -0.106873
+v 0.0336996 0.0542328 -0.200399
+v 0.0304883 0.00937707 -0.229918
+v 0.0286257 -0.00666671 -0.238563
+v 0.0173476 0.0104818 -0.231164
+v -0.349039 -0.944823 -0.292128
+v -0.342719 -0.927186 -0.292231
+v -0.332764 -0.910115 -0.292269
+v -0.320188 -0.892941 -0.292513
+v -0.302963 -0.877115 -0.291948
+v -0.288717 -0.859993 -0.292436
+v -0.27496 -0.842099 -0.293361
+v -0.882735 0.020424 0.358153
+v -0.88032 0.0209121 0.371473
+v -0.223579 -0.504589 -0.231318
+v -0.222577 -0.485013 -0.243521
+v -0.13993 -0.745695 -0.293631
+v -0.141793 -0.727468 -0.293785
+v -0.144503 -0.708971 -0.293502
+v -0.144863 -0.690769 -0.293695
+v -0.147933 -0.672438 -0.293695
+v -0.154638 -0.653774 -0.29381
+v -0.156359 -0.635418 -0.293952
+v -0.161009 -0.616831 -0.2939
+v -0.167586 -0.598154 -0.293977
+v -0.177439 -0.579169 -0.294106
+v -0.184529 -0.560659 -0.294389
+v -0.187561 -0.542187 -0.294389
+v -0.190939 -0.523818 -0.294478
+v -0.19767 -0.505321 -0.294607
+v -0.205518 -0.486374 -0.294594
+v -0.213752 -0.467607 -0.294671
+v -0.220355 -0.448956 -0.294825
+v -0.223694 -0.430613 -0.294902
+v -0.22417 -0.412514 -0.295108
+v -0.224465 -0.394415 -0.295275
+v -0.223206 -0.376419 -0.295622
+v -0.222615 -0.358345 -0.295416
+v -0.224671 -0.340143 -0.29629
+v -0.373252 0.729484 -0.0686967
+v 0.891624 -0.581725 0.00741174
+v -0.121009 0.122159 -0.116481
+v -0.135203 0.121144 -0.115222
+v 0.295346 0.0353631 -0.232333
+v 0.282808 0.0373927 -0.234594
+v 0.284144 0.0528327 -0.225756
+v -0.435989 -0.334723 -0.259051
+v -0.520986 0.58816 0.0230573
+v -0.768528 0.565823 -0.0175467
+v -0.308743 -0.0396277 -0.238756
+v -0.750043 0.528725 -0.299848
+v -0.74145 0.546606 -0.30004
+v -0.734077 0.564499 -0.300156
+v -0.733691 0.582342 -0.300233
+v -0.73865 0.599978 -0.300387
+v -0.752921 0.617512 -0.300811
+v -0.778059 0.636382 -0.300349
+v -0.790403 0.653633 -0.300927
+v -0.789581 0.672271 -0.300619
+v -0.782298 0.654738 -0.236212
+v -0.58371 -0.825978 0.465257
+v 0.160907 -0.220836 -0.424267
+v 0.147804 -0.21968 -0.425745
+v 0.148537 -0.205204 -0.4148
+v -0.211234 -0.941663 -0.373503
+v -0.224902 -0.942254 -0.372462
+v 0.322616 0.17616 -0.101696
+v 0.00740531 0.056211 -0.202519
+v 0.0071741 0.0429161 -0.214131
+v -0.000648688 -0.231614 -0.440221
+v -0.0143161 -0.231703 -0.440221
+v -0.0140078 -0.218306 -0.428249
+v 0.272006 0.132474 -0.157226
+v 0.272314 0.120039 -0.169481
+v 0.198954 -0.226257 -0.4185
+v 0.197105 -0.243059 -0.426695
+v 0.186327 -0.224305 -0.420658
+v 0.205852 -0.0188055 -0.251498
+v 0.203142 -0.037033 -0.257844
+v -0.485957 -0.659837 -0.0629291
+v -0.476284 -0.660634 -0.0755432
+v -0.480934 -0.678026 -0.0626465
+v -0.349476 -0.926287 -0.276726
+v -0.338467 -0.909897 -0.279218
+v -0.327433 -0.89271 -0.279115
+v -0.312969 -0.875844 -0.279385
+v -0.300329 -0.85858 -0.279758
+v -0.282192 -0.841508 -0.281132
+v -0.3211 -0.203919 -0.273181
+v -0.321152 -0.185537 -0.270188
+v -0.308358 -0.185358 -0.270548
+v 0.721347 -0.196482 -0.0876948
+v 0.720782 -0.210008 -0.0990372
+v 0.710339 -0.20406 -0.105473
+v -0.147894 -0.74486 -0.280631
+v -0.1481 -0.726787 -0.28076
+v -0.149731 -0.70847 -0.280824
+v -0.151131 -0.690139 -0.28076
+v -0.15424 -0.671706 -0.280734
+v -0.157901 -0.653415 -0.280978
+v -0.162872 -0.634853 -0.281081
+v -0.167522 -0.616189 -0.281081
+v -0.170849 -0.597794 -0.281171
+v -0.177439 -0.579105 -0.281273
+v -0.185647 -0.560338 -0.281389
+v -0.190631 -0.541789 -0.28144
+v -0.19722 -0.523163 -0.281543
+v -0.202179 -0.504666 -0.281659
+v -0.208794 -0.486015 -0.281736
+v -0.215384 -0.467389 -0.281852
+v -0.220368 -0.448866 -0.281967
+v -0.225339 -0.430395 -0.282031
+v -0.227034 -0.412218 -0.282147
+v -0.228511 -0.394132 -0.282712
+v -0.237169 -0.393978 -0.271601
+v -0.229411 -0.37611 -0.28347
+v -0.231016 -0.357896 -0.283907
+v -0.233072 -0.339565 -0.283791
+v -0.0510151 0.189609 -0.00764295
+v 0.321858 0.187374 -0.0882215
+v -0.585379 0.497588 -0.0393066
+v 0.0803538 -0.981445 -0.282776
+v 0.0814585 -0.949884 -0.30776
+v -0.971047 0.110341 0.35778
+v -0.967155 0.0913943 0.343702
+v 0.267831 -0.912286 0.378654
+v 0.259713 -0.911284 0.399258
+v 0.254433 -0.91289 0.376431
+v -0.729427 0.493658 -0.28672
+v -0.749414 0.511294 -0.286848
+v 0.188794 -0.117252 -0.275724
+v -0.751546 0.528841 -0.28699
+v -0.742914 0.546657 -0.287169
+v -0.735605 0.564512 -0.287336
+v -0.735477 0.58238 -0.287439
+v -0.742028 0.59994 -0.287632
+v -0.764533 0.61818 -0.287529
+v -0.783724 0.636369 -0.287568
+v -0.789517 0.654262 -0.287748
+v -0.786884 0.672387 -0.287748
+v 0.180406 -0.145293 -0.322995
+v 0.193585 -0.146051 -0.322057
+v 0.182166 -0.154683 -0.338782
+v 0.177618 -0.138023 -0.305063
+v 0.193791 -0.138601 -0.303239
+v 0.386239 -0.142313 -0.274478
+v -0.0068915 0.194979 -0.0146565
+v -0.0215223 0.192911 -0.0122287
+v 0.320278 0.20943 -0.0609381
+v 0.332944 0.207619 -0.059037
+v 0.321152 0.198858 -0.0749009
+v 0.334164 0.197265 -0.0735393
+v 0.259867 0.0843679 -0.208287
+v 0.246251 0.0840082 -0.20785
+v 0.00199744 -0.00581892 -0.239642
+v 0.00121388 -0.020758 -0.249289
+v -0.0107066 -0.00421326 -0.241209
+v 0.145467 0.0090174 -0.255673
+v -0.979178 0.128119 0.357497
+v -0.361614 -0.925311 -0.266206
+v -0.354113 -0.907751 -0.266707
+v -0.34426 -0.890603 -0.26672
+v -0.332802 -0.873609 -0.266784
+v -0.320548 -0.856036 -0.267362
+v -0.776029 0.0779067 0.671064
+v -0.160752 -0.778541 -0.268711
+v -0.184401 -0.80418 -0.298294
+v -0.156128 -0.744051 -0.267812
+v -0.155846 -0.725939 -0.267722
+v -0.156257 -0.70784 -0.267979
+v -0.159018 -0.689394 -0.267773
+v -0.156231 -0.671539 -0.268069
+v -0.161176 -0.653029 -0.26812
+v -0.167458 -0.634288 -0.268107
+v -0.172596 -0.615752 -0.268313
+v -0.17573 -0.597306 -0.268351
+v -0.180701 -0.578796 -0.268415
+v -0.188909 -0.559991 -0.268531
+v -0.193881 -0.541468 -0.268621
+v -0.200483 -0.522804 -0.268724
+v -0.207073 -0.504178 -0.268839
+v -0.213688 -0.485565 -0.268891
+v -0.22029 -0.466939 -0.268993
+v -0.223617 -0.448596 -0.269122
+v -0.228601 -0.430112 -0.269173
+v -0.228666 -0.411974 -0.269302
+v 0.0418179 0.174195 -0.0701867
+v 0.478584 0.00738605 -0.177342
+v 0.476027 -0.0106231 -0.183932
+v 0.46412 -0.00705207 -0.187426
+v -0.182422 -0.814199 -0.314774
+v 0.683453 -0.293554 -0.191369
+v 0.0748688 0.15905 -0.106243
+v 0.0762561 0.148376 -0.120797
+v 0.0611115 0.145332 -0.117303
+v 0.0586067 0.154336 -0.10072
+v 0.0735329 0.195004 -0.0676176
+v 0.0572965 0.190252 -0.062107
+v -0.984046 0.145473 0.357523
+v -0.985857 0.162878 0.357523
+v 0.244786 -0.946454 0.030225
+v 0.232057 -0.953661 0.0580222
+v 0.228948 -0.935343 0.0407324
+v -0.731045 0.493593 -0.273875
+v -0.750917 0.511384 -0.27399
+v -0.753165 0.528892 -0.274183
+v -0.744199 0.546709 -0.274311
+v -0.736967 0.564538 -0.274504
+v -0.73838 0.582419 -0.274517
+v -0.748258 0.599901 -0.274954
+v -0.774796 0.618591 -0.274491
+v -0.786755 0.636497 -0.274645
+v -0.788001 0.654352 -0.274864
+v -0.784854 0.672451 -0.274928
+v -0.710968 -0.520222 -0.0394351
+v -0.743351 -0.498642 -0.0519978
+v 0.800448 -0.885259 0.156854
+v 0.788387 -0.891335 0.184009
+v 0.782015 -0.894598 0.162287
+v 0.0743935 0.183444 -0.0811181
+v 0.0580286 0.179025 -0.0757744
+v 0.259623 0.0705335 -0.219064
+v 0.245467 0.0699041 -0.218383
+v -0.0126334 -0.0338217 -0.261479
+v -0.0177458 -0.188518 -0.381814
+v -0.00415545 -0.186347 -0.383586
+v -0.0165769 -0.196841 -0.398551
+v -0.0319912 0.935292 -0.275814
+v -0.0192615 0.93578 -0.289764
+v -0.0249006 0.916281 -0.287953
+v -0.0242969 0.954329 -0.276315
+v -0.020302 0.973198 -0.265705
+v -0.0190303 0.960803 -0.278383
+v -0.985716 0.180245 0.357395
+v 0.0669176 -0.981972 -0.284896
+v 0.0528391 -0.966737 -0.310124
+v -0.366611 -0.924682 -0.253438
+v -0.358866 -0.907263 -0.253733
+v -0.35085 -0.889845 -0.253887
+v -0.338108 -0.872722 -0.254106
+v -0.32647 -0.855856 -0.25408
+v -0.312121 -0.838721 -0.254375
+v 0.38367 -0.237933 -0.353336
+v 0.371158 -0.248788 -0.367851
+v -0.19618 -0.79524 -0.267246
+v -0.218569 -0.804707 -0.271203
+v -0.170605 -0.780519 -0.255493
+v -0.159738 -0.761392 -0.25512
+v -0.160547 -0.743576 -0.254697
+v -0.164105 -0.725156 -0.254915
+v -0.164079 -0.707018 -0.254979
+v -0.162769 -0.68906 -0.255185
+v -0.162846 -0.670923 -0.255275
+v -0.165749 -0.652477 -0.255198
+v -0.172326 -0.633774 -0.255313
+v -0.177567 -0.615303 -0.255454
+v -0.182551 -0.596767 -0.255583
+v -0.187214 -0.578167 -0.255557
+v -0.190554 -0.55976 -0.255673
+v -0.19713 -0.541147 -0.255788
+v -0.203746 -0.52247 -0.255865
+v -0.210348 -0.503831 -0.255968
+v -0.218569 -0.485103 -0.256097
+v -0.225172 -0.466477 -0.256187
+v -0.228524 -0.448095 -0.256225
+v -0.985344 0.197908 0.357112
+v -0.982993 0.215583 0.357176
+v -0.978818 0.233219 0.357112
+v -0.973089 0.250856 0.357035
+v -0.966975 0.268351 0.35683
+v -0.958189 0.285923 0.356675
+v -0.948889 0.3032 0.356444
+v -0.936249 0.320914 0.356406
+v 0.241704 -0.928176 0.0129095
+v -0.733126 0.493131 -0.261106
+v -0.75242 0.511448 -0.261119
+v -0.754758 0.528969 -0.261299
+v -0.74565 0.546786 -0.261415
+v -0.738547 0.564628 -0.261646
+v -0.741681 0.582393 -0.261774
+v -0.76014 0.600209 -0.26189
+v -0.781013 0.618283 -0.261903
+v -0.788399 0.636497 -0.26189
+v -0.786473 0.654442 -0.261993
+v -0.781758 0.672528 -0.262083
+v -0.927758 0.177663 0.0619786
+v -0.930211 0.160296 0.0622483
+v 0.17126 -0.162352 -0.35647
+v -0.199854 0.0757102 -0.170341
+v -0.213739 0.0623511 -0.181954
+v 0.273123 0.10862 -0.18293
+v 0.286187 0.107926 -0.182378
+v 0.273277 0.0967508 -0.195942
+v 0.657673 -0.747301 -0.0688893
+v 0.646343 -0.747558 -0.0789087
+v -0.0499489 0.916345 -0.262892
+v -0.043796 0.935356 -0.263341
+v -0.0309764 0.973507 -0.250894
+v -0.0344575 0.954573 -0.263804
+v -0.92754 0.338499 0.356316
+v -0.374023 -0.941971 -0.240939
+v -0.370246 -0.924181 -0.240836
+v -0.363747 -0.906711 -0.240939
+v -0.354113 -0.889485 -0.241081
+v -0.342886 -0.87226 -0.241248
+v -0.329887 -0.85533 -0.241286
+v -0.315204 -0.838554 -0.241389
+v -0.29708 -0.822279 -0.241376
+v -0.218788 -0.793364 -0.228646
+v 0.193046 -0.944951 0.159924
+v -0.176938 -0.778207 -0.2418
+v -0.165351 -0.761148 -0.241723
+v -0.163797 -0.743216 -0.241826
+v -0.167432 -0.724732 -0.242044
+v -0.167458 -0.706671 -0.242172
+v -0.167689 -0.688534 -0.242327
+v -0.169307 -0.67028 -0.242391
+v -0.170798 -0.653646 -0.242558
+v -0.175589 -0.633453 -0.242468
+v -0.181099 -0.614956 -0.242699
+v -0.187535 -0.596394 -0.242802
+v -0.192095 -0.577692 -0.242763
+v -0.197066 -0.559181 -0.24284
+v -0.203656 -0.540543 -0.242905
+v -0.208627 -0.52202 -0.243033
+v -0.215987 -0.503767 -0.243367
+v 0.000995511 0.134734 -0.104843
+v -0.011336 0.123726 -0.119114
+v 0.299148 0.119937 -0.169558
+v 0.299302 0.107104 -0.181453
+v 0.0093578 -0.149237 -0.293888
+v 0.080752 -0.179192 -0.390446
+v 0.0938927 -0.180001 -0.389546
+v 0.0819851 -0.189764 -0.405372
+v -0.926191 0.356329 0.3562
+v -0.934322 0.374029 0.35602
+v -0.944264 0.391859 0.355905
+v -0.95088 0.409303 0.355892
+v -0.942132 0.286078 0.43367
+v -0.18855 -0.963783 -0.374081
+v -0.19925 -0.982241 -0.360966
+v -0.200522 -0.961124 -0.377369
+v -0.734745 0.493118 -0.248325
+v -0.753036 0.511243 -0.248351
+v -0.756427 0.529008 -0.248505
+v -0.744725 0.546863 -0.248685
+v -0.74005 0.564679 -0.248801
+v -0.746177 0.58238 -0.248968
+v -0.77084 0.600402 -0.248993
+v -0.784379 0.61845 -0.248968
+v -0.786678 0.636433 -0.249083
+v -0.784777 0.654519 -0.249147
+v -0.819947 -0.015363 0.414351
+v -0.51229 -0.816113 0.375237
+v -0.782401 0.0323958 -0.0293387
+v -0.78574 0.0152345 -0.0277587
+v 0.772895 -0.561506 0.0120489
+v 0.762478 -0.566375 -0.00877334
+v -0.0548687 0.935279 -0.250175
+v -0.044297 0.954624 -0.250997
+v -0.0405719 0.973006 -0.237959
+v -0.0211626 0.985132 -0.25119
+v -0.0766415 0.954547 -0.199487
+v -0.376027 -0.941869 -0.228145
+v -0.372019 -0.923937 -0.227991
+v -0.365352 -0.906441 -0.228055
+v -0.355603 -0.88928 -0.228171
+v -0.3462 -0.871836 -0.228312
+v -0.334614 -0.854932 -0.228351
+v -0.319996 -0.83813 -0.228492
+v 0.776492 -0.540748 0.0165704
+v -0.189693 -0.77732 -0.228813
+v -0.165351 -0.761122 -0.228916
+v -0.165428 -0.742998 -0.229006
+v -0.170361 -0.724398 -0.229109
+v -0.170875 -0.706337 -0.22934
+v -0.17397 -0.687879 -0.229378
+v -0.17424 -0.669805 -0.229533
+v -0.175537 -0.651513 -0.22952
+v -0.18074 -0.633106 -0.229725
+v -0.187419 -0.614378 -0.229828
+v -0.192468 -0.595919 -0.229944
+v -0.195846 -0.577512 -0.230098
+v -0.202307 -0.558809 -0.230124
+v -0.205942 -0.540389 -0.230368
+v -0.215345 -0.521493 -0.23029
+v 0.0957681 -0.139551 -0.303843
+v -0.476888 -0.946223 -0.129121
+v -0.4922 -0.950424 -0.124625
+v -0.497042 -0.916281 -0.113257
+v -0.48069 -0.967534 -0.13476
+v -0.496207 -0.971554 -0.130804
+v 0.144118 0.0708932 -0.193013
+v 0.131041 0.0710859 -0.193168
+v 0.131761 0.0857295 -0.183148
+v -0.486111 -0.800712 0.375147
+v -0.470543 -0.78427 0.375057
+v -0.455436 -0.749497 0.374877
+v -0.724006 0.475109 -0.235403
+v -0.738817 0.493683 -0.235352
+v -0.755849 0.511423 -0.235493
+v -0.758123 0.529059 -0.23566
+v -0.746203 0.546914 -0.235865
+v -0.742786 0.564769 -0.235865
+v -0.755554 0.582483 -0.236161
+v -0.778586 0.600479 -0.236122
+v -0.785882 0.618514 -0.236148
+v -0.785291 0.636536 -0.236212
+v 0.108318 -0.217484 -0.428185
+v 0.107496 -0.232538 -0.438153
+v 0.0946891 -0.217317 -0.428481
+v -0.407408 -0.913673 -0.133617
+v -0.407523 -0.895459 -0.128851
+v -0.0460697 -0.267632 -0.455173
+v -0.0730576 0.916332 -0.23751
+v -0.0646825 0.935138 -0.237497
+v -0.0535328 0.957463 -0.234992
+v -0.047123 0.972851 -0.225229
+v -0.228216 -0.79348 -0.215685
+v -0.19293 -0.776845 -0.203136
+v -0.378378 -0.941329 -0.215017
+v -0.373522 -0.923744 -0.215107
+v -0.365365 -0.906416 -0.215236
+v -0.357234 -0.889049 -0.215313
+v -0.346059 -0.871836 -0.215493
+v -0.334935 -0.854559 -0.215608
+v -0.323233 -0.837745 -0.215608
+v -0.306675 -0.821444 -0.215608
+v 0.00496471 -0.974187 -0.231883
+v -0.19618 -0.776627 -0.215981
+v -0.170232 -0.760634 -0.216096
+v -0.168678 -0.742638 -0.216148
+v -0.171992 -0.724192 -0.216263
+v -0.173688 -0.705952 -0.216353
+v -0.175987 -0.687724 -0.216636
+v -0.179121 -0.66933 -0.216739
+v -0.180714 -0.65109 -0.216803
+v -0.186083 -0.632631 -0.21706
+v -0.192493 -0.613902 -0.217201
+v -0.197631 -0.595457 -0.217253
+v -0.203977 -0.576741 -0.217253
+v -0.206135 -0.558655 -0.217535
+v -0.212609 -0.539965 -0.217599
+v 0.144876 0.0853827 -0.182827
+v -0.973898 0.0938863 0.498911
+v -0.937713 0.303599 0.420722
+v 0.550851 -0.910911 0.41227
+v -0.725368 0.475353 -0.222493
+v -0.742054 0.493593 -0.222558
+v -0.75707 0.511551 -0.222622
+v -0.759241 0.529188 -0.222815
+v -0.746318 0.546966 -0.223033
+v -0.745047 0.563831 -0.223033
+v -0.767449 0.58283 -0.223123
+v -0.780923 0.600852 -0.223097
+v -0.784854 0.618514 -0.223328
+v -0.783659 0.636664 -0.223328
+v -0.199455 -0.776203 -0.190252
+v -0.975799 0.180772 0.498449
+v 0.159006 0.21408 -0.063931
+v 0.172609 0.213694 -0.063931
+v 0.160303 0.203932 -0.0787545
+v -0.0745991 0.935253 -0.224716
+v -0.0844257 0.916281 -0.224664
+v -0.0621134 0.954547 -0.225229
+v -0.070206 0.95456 -0.212384
+v -0.383259 -0.958927 -0.202095
+v -0.383002 -0.940828 -0.202095
+v -0.381627 -0.959171 -0.214915
+v -0.378455 -0.923153 -0.202275
+v -0.368641 -0.905992 -0.202365
+v -0.358866 -0.888818 -0.20248
+v -0.349296 -0.871502 -0.202596
+v -0.338108 -0.854238 -0.20275
+v -0.324915 -0.837655 -0.202724
+v -0.479637 0.613607 -0.00734751
+v -0.501333 0.59958 0.0093
+v -0.493908 0.618373 0.0098395
+v -0.176745 -0.759992 -0.203225
+v -0.171928 -0.742253 -0.203315
+v -0.173623 -0.724 -0.203392
+v -0.176938 -0.705592 -0.203508
+v -0.179365 -0.68739 -0.204022
+v -0.184002 -0.668816 -0.203842
+v -0.187278 -0.650434 -0.203945
+v -0.19248 -0.632104 -0.204189
+v -0.198993 -0.613389 -0.204266
+v -0.202615 -0.595007 -0.20442
+v -0.209693 -0.57651 -0.204767
+v -0.212969 -0.558128 -0.204908
+v 0.134612 0.194491 -0.0940661
+v 0.527023 -0.600877 -0.28961
+v 0.598687 -0.128325 -0.186578
+v 0.609259 -0.134966 -0.179834
+v 0.595707 -0.146732 -0.192461
+v 0.943185 -0.534352 0.0628135
+v -0.147226 -0.949447 -0.364434
+v 0.0312719 0.0243033 -0.220194
+v 0.0190817 0.0265127 -0.222391
+v 0.0198139 0.0408994 -0.21196
+v -0.164118 -0.88973 -0.363368
+v -0.253354 -0.976217 0.374684
+v -0.933847 0.321158 0.369302
+v -0.946153 0.303329 0.369302
+v -0.926255 0.338551 0.369161
+v -0.138081 -0.90323 -0.358332
+v -0.125428 -0.904977 -0.356714
+v -0.131324 -0.931271 -0.357587
+v 0.718059 -0.67538 -0.0463073
+v -0.963712 0.268274 0.369572
+v -0.284877 -0.806672 -0.189609
+v -0.955196 0.285923 0.369521
+v -0.729876 0.475597 -0.209648
+v -0.745355 0.493516 -0.209738
+v -0.759151 0.511448 -0.209828
+v -0.759164 0.529278 -0.209918
+v -0.746704 0.546876 -0.210265
+v -0.748759 0.564307 -0.210612
+v -0.772754 0.583061 -0.210252
+v -0.782863 0.600787 -0.210367
+v -0.783621 0.618604 -0.210445
+v -0.782041 0.636793 -0.21047
+v -0.450761 -0.961625 -0.140296
+v -0.448307 -0.942524 -0.133052
+v -0.0968086 0.897013 -0.223894
+v -0.0954855 0.916127 -0.211536
+v -0.0831283 0.93542 -0.212204
+v -0.0600325 0.964052 -0.217188
+v 0.488526 0.186565 0.0243932
+v -0.389771 -0.958144 -0.189237
+v -0.386534 -0.940404 -0.189353
+v -0.383284 -0.922601 -0.189455
+v -0.376425 -0.905285 -0.189391
+v -0.365404 -0.888111 -0.189609
+v -0.355641 -0.870873 -0.189712
+v -0.342706 -0.853981 -0.189841
+v -0.329565 -0.837179 -0.189892
+v -0.178363 -0.759735 -0.190342
+v -0.175178 -0.741932 -0.190444
+v -0.175242 -0.723807 -0.190599
+v -0.17695 -0.705489 -0.190676
+v -0.180277 -0.687121 -0.19074
+v -0.186854 -0.668418 -0.190843
+v -0.190181 -0.650023 -0.190945
+v -0.195152 -0.631475 -0.191061
+v -0.201729 -0.612811 -0.191164
+v -0.2067 -0.594288 -0.191266
+v 0.201228 -0.132127 -0.285679
+v 0.214407 -0.13282 -0.284832
+v 0.203926 -0.139449 -0.303329
+v 0.205775 0.237471 -0.0121517
+v 0.21943 0.237522 -0.0124086
+v 0.208062 0.228287 -0.0286065
+v 0.13081 0.0578938 -0.20487
+v 0.144388 0.0582406 -0.205281
+v 0.188498 -0.130817 -0.287015
+v 0.60633 -0.153321 -0.185743
+v 0.0493837 -0.279578 -0.468095
+v 0.0379001 -0.262108 -0.460234
+v 0.0510922 -0.262943 -0.459335
+v 0.890687 -0.492489 0.0963012
+v 0.903699 -0.493259 0.0972004
+v 0.892459 -0.50175 0.0801547
+v 0.00876692 -0.279295 -0.468635
+v 0.0104882 -0.262519 -0.460067
+v -0.031593 -0.149571 -0.293682
+v -0.0458128 -0.15047 -0.292976
+v -0.0415224 -0.129134 -0.289661
+v 0.519123 0.0583305 -0.129416
+v 0.517967 0.0432501 -0.138806
+v 0.506689 0.0479258 -0.143777
+v -0.35121 -0.969589 0.551461
+v -0.357298 -0.965376 0.568867
+v -0.754359 -0.480132 -0.0650486
+v -0.849941 0.322956 0.000166989
+v 0.244774 0.0553375 -0.228338
+v 0.243142 0.0380606 -0.236238
+v -0.870006 0.0154657 0.378577
+v -0.305609 -0.728585 -0.121594
+v -0.167972 -0.92278 -0.365423
+v -0.30566 -0.709972 -0.124843
+v -0.310708 -0.971734 0.449483
+v -0.732985 0.47561 -0.196816
+v -0.748489 0.493555 -0.196944
+v -0.760615 0.511525 -0.197008
+v -0.759138 0.529355 -0.197111
+v -0.746768 0.547017 -0.197355
+v -0.755824 0.563626 -0.197458
+v -0.776363 0.583112 -0.197381
+v -0.783094 0.600813 -0.197509
+v -0.782234 0.618732 -0.197548
+v 0.515206 -0.31408 -0.299154
+v -0.676877 -0.872363 0.0414004
+v -0.108588 0.89718 -0.211434
+v -0.106417 0.886467 -0.219398
+v -0.0948176 0.879402 -0.23232
+v -0.104362 0.916576 -0.199295
+v -0.121086 0.896692 -0.198229
+v -0.0914521 0.935613 -0.199475
+v -0.391415 -0.939813 -0.176494
+v -0.393034 -0.957733 -0.176392
+v -0.386534 -0.922177 -0.176584
+v -0.379675 -0.904874 -0.176584
+v -0.370272 -0.887546 -0.176764
+v -0.358904 -0.870487 -0.17688
+v -0.349129 -0.8533 -0.176983
+v -0.183335 -0.759196 -0.177573
+v -0.176809 -0.7417 -0.177612
+v -0.178492 -0.723434 -0.17774
+v -0.178582 -0.705322 -0.177817
+v -0.183527 -0.686761 -0.17792
+v -0.190104 -0.668084 -0.178023
+v -0.193431 -0.649677 -0.178139
+v -0.198402 -0.631154 -0.178229
+v -0.205005 -0.612464 -0.178306
+v -0.0507582 0.100681 -0.146038
+v -0.0644127 0.101067 -0.146218
+v -0.0636549 0.114773 -0.135248
+v -0.227484 0.840738 -0.134169
+v 0.283117 0.178678 -0.104188
+v 0.283862 0.167528 -0.117714
+v 0.221164 -0.15801 -0.33498
+v 0.208922 -0.155736 -0.337793
+v -0.103514 -0.170932 -0.297279
+v -0.105775 -0.188415 -0.304832
+v 0.187342 0.113681 -0.162005
+v 0.172917 0.0995639 -0.172448
+v 0.3927 -0.0781251 -0.239822
+v 0.0415481 -0.215364 -0.430818
+v 0.0408031 -0.229802 -0.441801
+v 0.0273926 -0.216379 -0.429829
+v 0.0400966 -0.244664 -0.452244
+v 0.0259025 -0.245384 -0.451795
+v 0.0271485 -0.229905 -0.441801
+v 0.0324793 0.218036 0.0118434
+v 0.0357806 0.211434 -0.00727044
+v 0.0200194 0.20785 -0.00278743
+v -0.0130572 0.158806 -0.0791142
+v -0.0123251 0.147631 -0.0928458
+v -0.0267375 0.158742 -0.0789215
+v 0.173482 0.203071 -0.0779067
+v 0.69757 -0.85709 0.393863
+v 0.699972 -0.868496 0.381274
+v -0.736158 0.475623 -0.183983
+v -0.75048 0.493439 -0.184112
+v -0.76127 0.511448 -0.184214
+v -0.75793 0.529368 -0.184279
+v -0.746524 0.547081 -0.184471
+v -0.765638 0.565322 -0.184471
+v -0.778226 0.583035 -0.184574
+v -0.782092 0.6008 -0.184651
+v -0.79427 -0.025742 0.45114
+v -0.745804 0.00622997 -0.0790757
+v -0.131427 0.897103 -0.185871
+v -0.134304 0.87804 -0.198152
+v -0.11537 0.916229 -0.186283
+v -0.396284 -0.95736 -0.163611
+v -0.394665 -0.939402 -0.163675
+v -0.389784 -0.92174 -0.163778
+v -0.382835 -0.904502 -0.163636
+v -0.374652 -0.887289 -0.163739
+v -0.363657 -0.870051 -0.164022
+v -0.352379 -0.852941 -0.164163
+v -0.339572 -0.835844 -0.164253
+v -0.330863 -0.818978 -0.151202
+v -0.186546 -0.758836 -0.164702
+v -0.180483 -0.741251 -0.164946
+v -0.185004 -0.722805 -0.164869
+v -0.186713 -0.704488 -0.164959
+v -0.186777 -0.686414 -0.165088
+v -0.191722 -0.667866 -0.165203
+v -0.198325 -0.649176 -0.165255
+v -0.191658 -0.685913 -0.15223
+v 0.426753 -0.273271 -0.342006
+v 0.425134 -0.289777 -0.350754
+v -0.179943 0.151369 -0.0696087
+v 0.29839 0.066924 -0.21521
+v 0.296848 0.05115 -0.224073
+v 0.278955 -0.140117 -0.276957
+v 0.258377 0.0556844 -0.228826
+v 0.279751 -0.125357 -0.266835
+v 0.581898 -0.397767 -0.263932
+v 0.269424 0.178807 -0.104124
+v 0.551005 0.0278871 -0.122287
+v 0.562797 0.0242519 -0.118421
+v 0.0931862 0.229456 -0.00222224
+v 0.0726594 -0.000500967 -0.245397
+v 0.0739054 0.0148363 -0.23593
+v 0.433625 0.166282 -0.0660248
+v 0.421846 0.169712 -0.0699298
+v 0.420305 0.179539 -0.0545925
+v 0.406265 -0.0652413 -0.228171
+v 0.406355 -0.077971 -0.24004
+v -0.012081 0.135595 -0.105717
+v -0.0252217 0.136263 -0.106449
+v 0.274588 0.23846 -0.0143739
+v 0.276784 0.230303 -0.0312655
+v -0.20995 -0.842138 -0.339745
+v -0.152043 0.177188 0.00639696
+v -0.160534 0.172127 -0.0142968
+v -0.0881509 -0.243778 -0.428391
+v -0.0894868 -0.259359 -0.438384
+v 0.024207 -0.133347 -0.284922
+v 0.0152923 -0.111035 -0.283008
+v 0.559162 -0.0469881 -0.170393
+v 0.558045 -0.0620685 -0.179988
+v 0.546355 -0.0582534 -0.184047
+v 0.903198 -0.58563 0.011625
+v -0.308692 -0.0576882 -0.242776
+v -0.245262 -0.0118048 -0.23223
+v -0.117669 -0.923359 0.030803
+v -0.73802 0.47543 -0.171215
+v -0.754552 0.493722 -0.171228
+v -0.76249 0.511577 -0.171356
+v -0.755477 0.529342 -0.171485
+v -0.749363 0.546824 -0.171832
+v -0.770043 0.5659 -0.171613
+v -0.778843 0.582958 -0.171754
+v -0.780474 0.600942 -0.171793
+v 0.670403 -0.87497 0.38094
+v -0.141202 0.897051 -0.173078
+v -0.146006 0.878207 -0.185615
+v -0.123398 0.916088 -0.173322
+v -0.39541 -0.939287 -0.144921
+v -0.393034 -0.921342 -0.150945
+v -0.385532 -0.904463 -0.150174
+v -0.378699 -0.886891 -0.150727
+v -0.369591 -0.869717 -0.150791
+v -0.356785 -0.852748 -0.151022
+v -0.34426 -0.835445 -0.151395
+v -0.190695 -0.704192 -0.152358
+v 0.535373 -0.0402443 -0.177663
+v 0.534178 -0.0553504 -0.187182
+v 0.522643 -0.0385359 -0.179423
+v -0.137772 0.177586 0.00524088
+v -0.124092 0.178383 0.0047913
+v -0.134009 0.172345 -0.0151061
+v -0.0780159 0.0229931 -0.218357
+v -0.00427106 -0.149404 -0.293746
+v -0.00208736 -0.159333 -0.309469
+v -0.0170136 -0.161504 -0.306887
+v 0.422732 0.158896 -0.08361
+v 0.318544 0.218897 -0.0453439
+v 0.331659 0.217753 -0.0443933
+v 0.206726 -0.147053 -0.321094
+v 0.411069 -0.305487 -0.35972
+v 0.411775 -0.323535 -0.360323
+v 0.590402 -0.287632 -0.249083
+v 0.602811 -0.294196 -0.242147
+v 0.591956 -0.294427 -0.248261
+v 0.135589 -0.190894 -0.403779
+v 0.22119 0.228068 -0.0281055
+v 0.432675 -0.105229 -0.262314
+v 0.433407 -0.0909319 -0.251883
+v 0.0746376 0.0549265 -0.201427
+v 0.0744449 0.0414132 -0.212705
+v 0.0609959 0.054798 -0.201209
+v -0.112506 -0.908715 -0.354646
+v -0.112506 -0.927174 -0.353978
+v -0.746472 -0.357279 -0.154812
+v -0.75549 -0.33891 -0.154632
+v -0.743287 -0.339797 -0.16776
+v 0.302462 -0.97641 0.257201
+v -0.757442 -0.288004 -0.158935
+v -0.762953 -0.303265 -0.154465
+v -0.762657 -0.285731 -0.154195
+v -0.0436419 -0.209969 -0.411114
+v -0.0289726 -0.207824 -0.413259
+v -0.0428583 -0.22162 -0.425051
+v -0.000918439 -0.21873 -0.427569
+v 0.0223958 -0.174606 -0.37006
+v -0.028189 -0.219436 -0.427158
+v -0.0284588 -0.233116 -0.438975
+v 0.00447659 -0.170496 -0.348827
+v 0.0191202 -0.168325 -0.351088
+v 0.0077136 -0.17688 -0.367825
+v 0.907116 -0.525231 0.0529869
+v 0.907013 -0.538346 0.0407196
+v 0.894026 -0.524178 0.051895
+v 0.893667 -0.55105 0.0277972
+v 0.894296 -0.536792 0.0390369
+v 0.500909 -0.157175 -0.258062
+v 0.51527 -0.143302 -0.247747
+v -0.828001 -0.454364 0.258062
+v -0.727012 0.457639 -0.158216
+v -0.742195 0.475893 -0.158241
+v -0.756042 0.493812 -0.15837
+v -0.762503 0.511654 -0.158498
+v -0.75364 0.529188 -0.158755
+v -0.7526 0.545142 -0.158639
+v -0.772368 0.565193 -0.158832
+v -0.778727 0.583112 -0.158858
+v -0.779189 0.601083 -0.158871
+v -0.151298 0.897385 -0.160515
+v -0.0662496 -0.0327684 -0.262327
+v -0.0518886 -0.0370073 -0.265487
+v -0.0646953 -0.055299 -0.268801
+v -0.374036 -0.869575 -0.137676
+v -0.363708 -0.852735 -0.137496
+v -0.316476 -0.968805 0.535829
+v -0.350208 -0.835176 -0.138241
+v -0.0396085 -0.917463 -0.12501
+v -0.21749 0.14555 -0.0886582
+v -0.229565 0.148479 -0.0917668
+v -0.228691 0.0982537 -0.142275
+v -0.215011 0.0987161 -0.142763
+v -0.228422 0.0857937 -0.154979
+v 0.616979 -0.159179 -0.179474
+v 0.137246 -0.136944 -0.305949
+v 0.47071 -0.0849716 -0.232474
+v 0.316797 0.228145 -0.0296341
+v 0.329488 0.226604 -0.0278615
+v -0.457954 -0.920597 -0.128581
+v -0.462784 -0.943115 -0.133039
+v 0.134638 -0.218961 -0.426477
+v 0.121497 -0.218075 -0.427504
+v 0.413227 0.103238 -0.152063
+v 0.425417 0.100437 -0.149057
+v 0.412443 0.0889665 -0.162262
+v -0.743621 -0.375211 -0.142043
+v -0.733152 -0.375995 -0.155017
+v -0.755849 -0.35665 -0.14203
+v -0.764995 -0.338319 -0.141992
+v -0.770968 -0.320297 -0.141825
+v -0.773897 -0.302507 -0.141786
+v -0.774282 -0.284973 -0.14212
+v -0.762568 -0.268248 -0.154092
+v -0.775259 -0.267413 -0.141645
+v -0.76258 -0.25065 -0.154092
+v -0.757468 -0.250727 -0.158986
+v -0.775182 -0.249854 -0.141607
+v -0.763094 -0.232962 -0.154709
+v -0.775734 -0.232179 -0.142146
+v -0.762298 -0.21557 -0.153694
+v -0.775541 -0.214594 -0.142043
+v -0.717763 -0.378795 -0.169327
+v -0.0610987 -0.917578 -0.177085
+v -0.07045 -0.918362 -0.154311
+v -0.0744578 -0.91813 -0.179282
+v -0.77337 -0.197278 -0.141311
+v 0.942903 -0.521789 0.075723
+v -0.211324 0.182185 -0.0246758
+v -0.209076 0.173656 -0.0415931
+v -0.154844 0.159718 -0.0530254
+v -0.141151 0.159783 -0.0532438
+v -0.15257 0.151947 -0.0702638
+v 0.262706 -0.221337 -0.397022
+v -0.14959 0.132409 -0.101182
+v -0.136989 -0.0382533 -0.256533
+v -0.151607 -0.0404627 -0.254106
+v -0.159892 0.0480286 -0.192936
+v -0.160598 0.0336161 -0.203482
+v -0.172544 0.0498911 -0.194889
+v -0.83856 -0.440414 0.262031
+v -0.829633 -0.448378 0.270702
+v -0.730107 0.457768 -0.14537
+v -0.743826 0.47588 -0.145422
+v -0.758765 0.494004 -0.145447
+v -0.762786 0.511731 -0.145653
+v -0.752844 0.529201 -0.145948
+v -0.759253 0.546144 -0.146051
+v -0.77269 0.565129 -0.145974
+v -0.445353 0.308364 -0.00339116
+v -0.183155 0.860044 -0.162249
+v -0.597544 0.576343 0.0946955
+v -0.159134 0.897013 -0.147541
+v -0.180226 0.878117 -0.147258
+v -0.374704 -0.866595 -0.128941
+v 0.173662 -0.222468 -0.42261
+v 0.172275 -0.238447 -0.431576
+v 0.272173 0.146346 -0.146179
+v 0.134343 0.182801 -0.106899
+v 0.213585 0.163739 -0.112756
+v 0.213829 0.151022 -0.124985
+v -0.652625 -0.980392 -0.0551834
+v -0.641102 -0.981072 -0.0695958
+v -0.650441 -0.982164 -0.0471294
+v 0.494974 -0.0908933 -0.22618
+v 0.48308 -0.0875022 -0.229815
+v 0.482925 -0.0750679 -0.21742
+v 0.538597 0.119513 -0.0411306
+v 0.439328 -0.262417 -0.327465
+v 0.427716 -0.258512 -0.331627
+v 0.212018 -0.175017 -0.368493
+v 0.213315 -0.185345 -0.383188
+v 0.200573 -0.183713 -0.385102
+v 0.540395 0.0467055 -0.116892
+v 0.445469 -0.0684526 -0.224446
+v 0.43315 -0.0786774 -0.239231
+v 0.503375 0.143071 -0.0410793
+v 0.491699 0.146835 -0.0451898
+v 0.393445 -0.0896473 -0.253168
+v 0.378827 -0.0914842 -0.251357
+v -0.120328 0.172833 -0.0154144
+v -0.130746 0.166218 -0.0343612
+v 0.324967 0.243149 0.0058703
+v 0.312288 0.245024 0.00391782
+v 0.239661 -0.0454338 -0.24907
+v 0.23785 -0.0618758 -0.257086
+v 0.227034 -0.0435712 -0.251061
+v 0.0312462 0.940006 -0.334247
+v 0.521461 -0.274979 -0.287812
+v 0.533253 -0.278756 -0.284061
+v 0.51703 -0.29566 -0.291794
+v 0.0155621 0.949126 -0.317934
+v 0.133341 -0.234928 -0.435687
+v -0.754706 -0.374543 -0.129455
+v -0.767911 -0.355648 -0.12898
+v -0.777198 -0.337446 -0.129044
+v -0.781951 -0.31954 -0.129159
+v -0.784726 -0.301736 -0.128864
+v -0.786062 -0.284151 -0.128761
+v -0.78488 -0.266823 -0.12907
+v -0.786344 -0.249122 -0.129095
+v -0.786563 -0.231498 -0.129339
+v -0.78768 -0.213849 -0.128941
+v -0.786986 -0.196482 -0.128325
+v -0.779305 -0.179385 -0.128363
+v -0.17257 0.0758001 -0.17065
+v -0.159391 0.0748495 -0.169686
+v -0.172789 0.0626594 -0.18257
+v -0.15916 0.0621969 -0.182121
+v 0.143065 0.222044 -0.0467055
+v 0.1453 0.214016 -0.063687
+v 0.131696 0.213515 -0.0632246
+v 0.0331216 0.130765 -0.127246
+v 0.047701 0.133142 -0.129815
+v 0.0348686 0.121542 -0.143238
+v -0.166366 -0.0164548 -0.227811
+v -0.165981 -0.0292487 -0.240104
+v 0.161947 -0.192268 -0.402186
+v 0.161703 -0.205897 -0.413978
+v 0.148768 -0.191549 -0.403034
+v -0.734745 0.457832 -0.132563
+v -0.748117 0.476149 -0.132474
+v -0.760422 0.494017 -0.132628
+v -0.762323 0.511821 -0.132795
+v -0.75224 0.529355 -0.133064
+v -0.763698 0.547634 -0.132987
+v -0.773974 0.565322 -0.133077
+v 0.321807 -0.284613 -0.396753
+v -0.21582 0.840455 -0.14668
+v -0.199532 0.852016 -0.15291
+v -0.198132 0.859415 -0.147066
+v 0.536079 -0.0259732 -0.167233
+v -0.390362 0.6924 -0.0675277
+v -0.3941 0.711013 -0.0555559
+v -0.382565 0.710833 -0.0681186
+v 0.314562 0.236726 -0.0129224
+v 0.220933 -0.249764 -0.419656
+v 0.231607 -0.264998 -0.419283
+v 0.327202 0.234863 -0.0109442
+v 0.362963 0.237535 0.0116892
+v 0.445828 -0.0804758 -0.23733
+v 0.446458 -0.0921779 -0.250522
+v 0.36516 0.228942 -0.00503536
+v 0.199314 -0.173232 -0.370433
+v 0.18792 -0.181992 -0.386977
+v 0.505983 -0.292475 -0.296097
+v 0.146533 -0.235698 -0.434839
+v 0.141369 -0.245795 -0.438449
+v -0.754655 -0.391974 -0.116597
+v -0.768271 -0.373374 -0.116443
+v -0.768219 -0.383034 -0.109699
+v -0.782092 -0.354787 -0.116417
+v -0.789825 -0.336624 -0.116378
+v -0.794231 -0.318692 -0.116224
+v -0.7954 -0.300991 -0.115942
+v -0.793782 -0.283624 -0.115916
+v -0.792343 -0.26627 -0.116044
+v -0.793037 -0.248749 -0.116687
+v -0.797841 -0.23083 -0.116944
+v -0.798714 -0.213142 -0.116366
+v -0.796864 -0.195711 -0.116121
+v -0.791418 -0.178717 -0.115402
+v -0.782632 -0.161517 -0.115852
+v 0.398879 0.165435 -0.090752
+v 0.411017 0.162544 -0.0876692
+v 0.400112 0.155171 -0.105254
+v -0.180457 -0.0178036 -0.22627
+v 0.0494865 0.123662 -0.145679
+v -0.165569 -0.00219655 -0.216983
+v 0.606279 -0.061362 -0.15503
+v 0.617159 -0.0670268 -0.149057
+v 0.605136 -0.0765066 -0.164535
+v -0.986294 0.127451 0.190483
+v -0.307818 -0.278216 -0.269006
+v 0.366907 0.219655 -0.0207323
+v -0.675862 -0.872954 0.0672965
+v -0.739099 0.458153 -0.11959
+v -0.751431 0.476124 -0.119718
+v -0.762208 0.49403 -0.119847
+v -0.761322 0.511808 -0.120026
+v -0.75206 0.530344 -0.12045
+v -0.76461 0.547801 -0.120091
+v -0.773884 0.565476 -0.120245
+v 0.654693 -0.139282 -0.149121
+v 0.651469 -0.158537 -0.154336
+v 0.64109 -0.150984 -0.161799
+v -0.591687 0.573401 0.0698142
+v -0.259302 0.821393 -0.120553
+v -0.261999 0.802484 -0.132512
+v -0.273547 0.784193 -0.132396
+v -0.275795 0.803101 -0.120527
+v -0.240329 0.840532 -0.121285
+v 0.153122 -0.94991 0.642136
+v 0.368628 0.210278 -0.0363779
+v 0.369912 0.200053 -0.0510215
+v 0.454576 0.0138472 -0.18397
+v 0.451865 -0.00432887 -0.190123
+v 0.0555752 0.911823 -0.352282
+v 0.0419463 0.907854 -0.345513
+v -0.187008 0.0874893 -0.156944
+v -0.200098 0.0879132 -0.157471
+v -0.0668919 0.146963 -0.0917797
+v -0.0656844 0.136802 -0.106783
+v -0.0793647 0.136725 -0.106565
+v 0.371081 0.189571 -0.0654211
+v 0.372302 0.179256 -0.0799748
+v 0.203026 0.0921265 -0.190534
+v 0.239006 -0.188351 -0.380028
+v 0.238775 -0.201825 -0.391794
+v 0.225904 -0.187259 -0.381223
+v -0.445751 -0.914714 -0.127567
+v 0.103989 -0.161003 -0.358088
+v 0.620409 0.0164805 -0.084278
+v 0.609477 0.0219911 -0.0902511
+v 0.609156 0.0341556 -0.0776627
+v 0.0422675 0.161632 -0.0825439
+v 0.0442328 0.151677 -0.0979325
+v 0.0574891 -0.00355815 -0.24207
+v 0.0583112 0.0106359 -0.23137
+v 0.0741752 0.0281184 -0.224317
+v 0.0590434 0.024907 -0.220785
+v 0.0597627 0.0394479 -0.210573
+v 0.0484075 -0.163945 -0.355468
+v 0.0370137 -0.172512 -0.372218
+v -0.0104625 -0.108466 -0.285487
+v -0.60931 -0.84481 0.00308287
+v -0.595347 -0.837488 0.00493259
+v -0.602746 -0.846287 -0.00940276
+v 0.895221 -0.654224 -0.0218242
+v 0.884482 -0.648443 -0.0276431
+v 0.55053 -0.141478 -0.223842
+v 0.538507 -0.151086 -0.239334
+v -0.796441 -0.353991 -0.103674
+v -0.801823 -0.335648 -0.103186
+v -0.804816 -0.317883 -0.103161
+v -0.805818 -0.300195 -0.102814
+v -0.802773 -0.282982 -0.102904
+v -0.801784 -0.265679 -0.103405
+v -0.803981 -0.24812 -0.104047
+v -0.809735 -0.230111 -0.103726
+v -0.812279 -0.21232 -0.103289
+v -0.809928 -0.195133 -0.102621
+v -0.803583 -0.178049 -0.102467
+v -0.793589 -0.16081 -0.103161
+v -0.789376 -0.143315 -0.103597
+v 0.470658 0.0442777 -0.16546
+v 0.456965 0.0312269 -0.177201
+v 0.412238 0.15223 -0.102146
+v 0.159275 -0.237317 -0.433233
+v -0.10458 0.0887353 -0.158909
+v -0.105338 0.0747083 -0.169815
+v -0.158171 0.166372 -0.0339758
+v -0.171376 0.167066 -0.0347337
+v 0.159635 0.138806 -0.138421
+v 0.159802 0.126192 -0.149442
+v -0.16855 0.15995 -0.0529098
+v -0.987617 0.144805 0.190393
+v -0.98754 0.162056 0.190354
+v -0.772651 0.565668 -0.0945285
+v -0.742876 0.457716 -0.10704
+v -0.756453 0.476047 -0.107014
+v -0.765419 0.494094 -0.106988
+v -0.760808 0.511936 -0.107104
+v -0.754102 0.529689 -0.107297
+v -0.76759 0.54789 -0.107258
+v 0.0925439 -0.922177 0.281954
+v 0.0844643 -0.921162 0.302622
+v 0.0791591 -0.922768 0.279771
+v -0.465302 -0.485809 0.538693
+v -0.312969 0.766029 -0.107155
+v -0.288807 0.803127 -0.107772
+v -0.272622 0.821637 -0.108145
+v 0.216668 -0.141247 -0.301428
+v 0.3741 0.170085 -0.0956846
+v 0.375873 0.160964 -0.111407
+v 0.377067 0.15047 -0.125961
+v 0.46385 0.183662 -0.00769433
+v 0.462167 0.193168 0.00793839
+v 0.612586 -0.218743 -0.218794
+v -0.19794 -0.942344 -0.372655
+v 0.540382 0.0848303 -0.0807712
+v 0.540318 0.0976371 -0.0690435
+v 0.219815 -0.00524088 -0.240361
+v 0.21749 -0.0226334 -0.2474
+v -0.0379001 -0.969229 -0.335185
+v 0.377427 0.138562 -0.138665
+v 0.0790949 -0.248004 -0.448661
+v 0.377594 0.126064 -0.150932
+v 0.237542 -0.217355 -0.40148
+v 0.225043 -0.215261 -0.40392
+v 0.226212 -0.199757 -0.394068
+v 0.661218 -0.036699 -0.0782022
+v 0.0963975 0.223187 -0.021336
+v 0.099095 0.216174 -0.0394351
+v 0.0844129 0.214144 -0.0370073
+v 0.186173 -0.1725 -0.371319
+v 0.217143 0.246116 0.0043674
+v 0.0264164 -0.153617 -0.314838
+v 0.0414325 -0.152294 -0.316444
+v 0.0305268 -0.159847 -0.334222
+v 0.0567313 -0.0178678 -0.252641
+v 0.447036 0.127759 -0.101362
+v 0.0338024 -0.166141 -0.353233
+v -0.781257 -0.364755 -0.111433
+v 0.463683 -0.254722 -0.309328
+v 0.461782 -0.272038 -0.317459
+v -0.796993 -0.370857 -0.0901868
+v -0.805291 -0.353014 -0.0905979
+v -0.0225628 -0.947109 -0.33453
+v -0.809954 -0.33516 -0.0906493
+v -0.813563 -0.317099 -0.0899299
+v -0.813846 -0.299694 -0.0902254
+v -0.8126 -0.28243 -0.0905593
+v -0.812934 -0.265088 -0.0909447
+v -0.818997 -0.247156 -0.0909319
+v -0.824572 -0.229122 -0.0904309
+v -0.824456 -0.211575 -0.0903281
+v -0.821052 -0.194349 -0.0900712
+v -0.814707 -0.177239 -0.0899685
+v -0.805779 -0.160129 -0.0902254
+v -0.80059 -0.142557 -0.0911502
+v -0.798457 -0.125267 -0.0906107
+v -0.0730448 0.172384 -0.0417472
+v 0.293688 0.0176366 -0.237689
+v 0.307626 5.13812e-05 -0.23706
+v 0.407254 -0.180387 -0.285551
+v 0.394884 -0.177959 -0.288146
+v 0.880256 -0.563973 0.0151831
+v 0.867103 -0.563099 0.0141812
+v 0.413561 0.116622 -0.140823
+v 0.401435 0.106732 -0.155813
+v 0.400523 0.0921779 -0.165794
+v 0.3699 -0.160797 -0.280567
+v 0.372597 -0.142583 -0.27408
+v 0.31243 0.106115 -0.180451
+v -0.527088 -0.133386 -0.229378
+v -0.540036 -0.133784 -0.22478
+v -0.52719 -0.11512 -0.224818
+v 0.314485 -0.949833 -0.144985
+v -0.7354 0.439412 -0.0944001
+v -0.74881 0.458038 -0.0941047
+v -0.760949 0.476188 -0.0941047
+v -0.767089 0.494171 -0.0941946
+v -0.75874 0.511911 -0.0944258
+v -0.757134 0.529804 -0.0944772
+v -0.769761 0.547826 -0.0944515
+v -0.902093 0.0117663 0.281158
+v -0.327382 0.765901 -0.0942845
+v 0.645598 -0.901933 -0.00933853
+v -0.314703 0.784604 -0.0947855
+v -0.298878 0.803409 -0.0953506
+v -0.2811 0.821983 -0.0956461
+v 0.514268 -0.972376 0.0840596
+v 0.0133013 -0.217908 -0.428404
+v 0.201459 -0.195094 -0.399219
+v 0.480099 -0.210817 -0.279154
+v 0.46692 -0.222673 -0.291974
+v 0.0384396 0.204253 -0.0253952
+v 0.0228068 0.200335 -0.0207837
+v 0.59879 -0.232192 -0.230445
+v 0.648052 -0.178627 -0.158716
+v 0.637878 -0.172564 -0.165576
+v 0.185313 0.212102 -0.0621584
+v -0.227394 0.0619657 -0.18153
+v 0.116886 0.0703152 -0.19232
+v 0.48841 -0.246861 -0.292051
+v 0.486406 -0.264112 -0.299848
+v 0.475128 -0.259334 -0.304729
+v 0.454101 0.178498 -0.0276688
+v 0.442398 0.182275 -0.0317793
+v 0.440138 0.191048 -0.0166218
+v 0.377337 0.112782 -0.162275
+v 0.376708 0.0988574 -0.172923
+v 0.223617 -0.23119 -0.412951
+v 0.51491 0.139063 -0.0368532
+v 0.0451833 -0.157573 -0.336495
+v 0.0278807 0.158871 -0.0796537
+v 0.0138922 0.146115 -0.091253
+v -0.371081 -0.966866 0.567235
+v -0.0637962 -0.00186257 -0.243637
+v -0.0645284 -0.0163007 -0.254067
+v -0.0778746 -0.00324986 -0.242095
+v -0.797353 -0.388429 -0.0775856
+v -0.804186 -0.370022 -0.076892
+v -0.811444 -0.352847 -0.0774058
+v -0.815657 -0.33453 -0.07747
+v -0.81978 -0.316624 -0.0771489
+v -0.821617 -0.299167 -0.0774828
+v -0.823518 -0.281762 -0.0779324
+v -0.82452 -0.264536 -0.0791013
+v -0.834283 -0.246142 -0.0780609
+v -0.836852 -0.228325 -0.0775728
+v -0.835118 -0.210933 -0.0773801
+v -0.831611 -0.193733 -0.0770589
+v -0.824379 -0.176507 -0.0774957
+v -0.818445 -0.159295 -0.0777012
+v -0.813666 -0.142018 -0.0775728
+v -0.810725 -0.124561 -0.0777397
+v -0.807436 -0.107335 -0.0775728
+v 0.881168 -0.53606 0.0381762
+v 0.88095 -0.549496 0.0261659
+v 0.867539 -0.536201 0.0382405
+v -0.103694 -0.922061 -0.0383689
+v 0.867321 -0.549393 0.0259603
+v 0.866807 -0.577191 0.00256906
+v 0.411377 0.0740275 -0.171883
+v 0.399726 0.0779196 -0.176058
+v -0.148254 0.171665 -0.0138601
+v 0.633254 -0.24478 -0.21706
+v 0.64344 -0.250946 -0.210162
+v 0.630492 -0.263226 -0.223393
+v 0.875696 -0.626439 -0.0250483
+v 0.87287 -0.645335 -0.0316893
+v 0.0742394 0.232179 0.0214902
+v 0.0888188 0.234427 0.0189982
+v -0.095691 0.143867 -0.0880802
+v -0.1081 0.13336 -0.10275
+v -0.0934817 0.135518 -0.10519
+v -0.106918 0.123379 -0.117868
+v -0.0504371 0.0880545 -0.158524
+v -0.0908227 0.176379 -0.0200644
+v -0.102371 0.168286 -0.0369045
+v -0.0362687 0.0119718 -0.232615
+v -0.0499232 0.0117791 -0.23232
+v 0.626754 -0.0873609 -0.152846
+v 0.625161 -0.10424 -0.160939
+v 0.614294 -0.0985234 -0.166937
+v 0.0854533 -0.289135 -0.457986
+v 0.699985 -0.105331 -0.0819273
+v 0.0490883 0.0709446 -0.192679
+v 0.226957 0.17607 -0.100527
+v -0.201087 0.0344768 -0.204343
+v 0.375487 0.0837128 -0.182288
+v 0.373072 0.0661661 -0.188941
+v 0.37139 0.0500453 -0.197329
+v -0.0722741 -0.920751 -0.0807841
+v -0.727204 0.421929 -0.0813493
+v -0.740114 0.43972 -0.0816704
+v -0.753473 0.458179 -0.0813236
+v -0.765483 0.476304 -0.0812465
+v -0.768695 0.494223 -0.0813107
+v -0.76023 0.512039 -0.081619
+v -0.764379 0.529958 -0.0815805
+v -0.771842 0.547878 -0.0816062
+v -0.390144 0.748341 -0.00578038
+v -0.338763 0.747571 -0.0939762
+v -0.339675 0.766582 -0.0822998
+v -0.350362 0.747686 -0.0815805
+v -0.324736 0.784835 -0.0822356
+v -0.308987 0.803011 -0.0805143
+v -0.152968 -0.966532 0.657654
+v -0.159571 -0.96359 0.67565
+v -0.166225 -0.96702 0.655174
+v 0.385211 -0.127027 -0.272834
+v 0.630762 0.0229417 -0.0654339
+v 0.631032 0.0106488 -0.0779453
+v 0.620267 0.0293515 -0.072486
+v 0.18661 0.176816 -0.101041
+v 0.173919 0.17828 -0.102621
+v 0.222937 -0.167169 -0.350844
+v 0.224671 -0.176764 -0.366528
+v 0.237259 -0.178896 -0.364383
+v 0.338955 -0.914714 0.599182
+v -0.474961 -0.696549 -0.0628392
+v -0.468885 -0.679362 -0.0759286
+v -0.493626 -0.659067 -0.0499682
+v -0.50096 -0.658206 -0.0368403
+v -0.485148 -0.641918 -0.0718823
+v -0.0156135 -0.247041 -0.45042
+v -0.0302956 -0.249456 -0.448108
+v -0.121086 0.00500967 -0.224908
+v -0.106507 0.00725759 -0.227336
+v 0.229693 -0.0254465 -0.24442
+v 0.371248 0.0370715 -0.209109
+v 0.174805 -0.207066 -0.412629
+v 0.36999 0.0217599 -0.218344
+v -0.0322096 -0.164407 -0.303907
+v 0.517312 -0.125666 -0.240194
+v 0.503671 -0.138858 -0.251909
+v -0.742824 -0.477087 -0.0793968
+v -0.729966 -0.476047 -0.087181
+v -0.755541 -0.458513 -0.0824026
+v -0.784867 -0.441724 -0.0646118
+v -0.799087 -0.405821 -0.0648816
+v -0.495681 -0.85876 -0.0840211
+v -0.806293 -0.387517 -0.0644063
+v -0.814051 -0.369534 -0.064432
+v -0.820346 -0.351704 -0.0646118
+v -0.825831 -0.333605 -0.0642008
+v -0.82935 -0.316046 -0.0646118
+v -0.832767 -0.298525 -0.0650357
+v -0.837648 -0.280952 -0.0653954
+v -0.843737 -0.263072 -0.0651
+v -0.848066 -0.245358 -0.0651642
+v -0.847591 -0.227606 -0.0646504
+v -0.844443 -0.210316 -0.0646375
+v -0.840564 -0.193193 -0.0640595
+v -0.833499 -0.175968 -0.0645733
+v -0.829774 -0.158447 -0.0653697
+v -0.829055 -0.141157 -0.0647531
+v -0.82443 -0.123893 -0.064766
+v -0.818522 -0.106603 -0.0650229
+v -0.81233 -0.089429 -0.0650357
+v -0.80461 -0.072319 -0.0650357
+v -0.796633 -0.0552733 -0.0647788
+v -0.139725 -0.923975 0.0501866
+v 0.862607 -0.751026 -0.018767
+v -0.765098 -0.00363522 -0.0656138
+v -0.0922485 0.125383 -0.120245
+v -0.0914906 0.114015 -0.134054
+v -0.105055 0.113424 -0.133475
+v -0.745843 0.0425179 -0.0595251
+v -0.746434 0.0308287 -0.0653312
+v 0.50737 -0.0931541 -0.223727
+v 0.495103 -0.0777526 -0.214555
+v 0.427781 0.00161851 -0.196803
+v 0.414139 -0.011047 -0.208466
+v -0.0528134 0.148004 -0.0931413
+v -0.0493195 0.026487 -0.222301
+v -0.0474313 0.042428 -0.213386
+v -0.0325564 0.0579323 -0.204202
+v -0.0328005 0.0445603 -0.21575
+v -0.0472 0.0558642 -0.201902
+v -0.0479579 0.0672194 -0.188145
+v -0.0333143 0.0693775 -0.190521
+v -0.037078 0.100823 -0.146244
+v 0.435976 0.132833 -0.107117
+v -0.0358191 0.0900584 -0.160836
+v -0.0346245 0.0798592 -0.175775
+v -0.0491911 0.0776241 -0.173334
+v 0.618199 -0.0393066 -0.127207
+v 0.617981 -0.0521262 -0.139166
+v 0.606857 -0.0351062 -0.13169
+v 0.00770076 0.197214 -0.0172127
+v -0.0142133 -0.128851 -0.289739
+v -0.0179513 -0.149417 -0.293759
+v -0.027855 -0.128967 -0.2897
+v 0.0289083 -0.110855 -0.283239
+v 0.0347401 -0.0867186 -0.282404
+v -0.207522 0.163919 -0.0567377
+v 0.424698 0.137278 -0.111716
+v 0.423773 0.148235 -0.0979197
+v -0.094946 0.188055 0.0107387
+v -0.109436 0.180605 0.00233784
+v 0.514242 0.0100707 -0.154516
+v 0.512585 -0.00605014 -0.16293
+v 0.501101 -0.00199102 -0.167451
+v 0.0808162 -0.231023 -0.440388
+v 0.590158 -0.209121 -0.228942
+v 0.503131 0.0149648 -0.159808
+v 0.922543 -0.615084 0.0158639
+v 0.914116 -0.590665 0.0170586
+v -0.118029 -0.924348 0.101516
+v -0.131427 -0.924939 0.0993584
+v 0.154137 -0.13738 -0.304729
+v -0.739215 0.422456 -0.0681828
+v -0.0725824 -0.967289 -0.342237
+v -0.0610344 -0.946313 -0.344498
+v -0.0485103 -0.94621 -0.341325
+v -0.747487 0.44017 -0.0686581
+v -0.756967 0.458128 -0.0686967
+v -0.768746 0.476381 -0.0684526
+v -0.772497 0.493902 -0.0700968
+v -0.765085 0.512412 -0.0691848
+v -0.769825 0.529856 -0.0690049
+v -0.772908 0.547916 -0.0687352
+v -0.770416 0.565771 -0.0688765
+v -0.488809 0.656909 0.0590241
+v -0.362064 0.748123 -0.0690049
+v -0.349488 0.766672 -0.0696215
+v -0.334768 0.78504 -0.0697243
+v -0.314819 0.803024 -0.0698527
+v -0.0867636 -0.945722 -0.350522
+v 0.184645 0.0186771 -0.24031
+v 0.196822 0.0159796 -0.237535
+v 0.183784 0.00409765 -0.250342
+v -0.476413 -0.803525 -0.0629163
+v -0.483953 -0.784912 -0.0496728
+v 0.283181 0.254144 0.0202057
+v 0.285968 0.246578 0.00233784
+v 0.272301 0.246861 0.00244061
+v -0.143604 -0.928471 -0.359745
+v -0.478622 -0.749921 -0.049069
+v 0.603825 0.0876435 -0.00651257
+v 0.605328 0.078048 -0.0220168
+v 0.594744 0.0835587 -0.0276174
+v -0.480575 -0.713608 -0.0495058
+v -0.484223 -0.695586 -0.0498526
+v -0.48886 -0.677294 -0.0498012
+v 0.171684 0.0587159 -0.20591
+v 0.171453 0.045254 -0.217227
+v -0.243797 -0.816396 -0.286964
+v -0.241678 -0.82454 -0.304845
+v -0.258056 -0.830371 -0.29909
+v 0.225429 0.198768 -0.0735265
+v 0.0951644 -0.190483 -0.404524
+v -0.214728 0.0342456 -0.203958
+v 0.14643 0.114041 -0.162082
+v -0.150926 -0.000102762 -0.219282
+v -0.163386 0.0154015 -0.209944
+v -0.766986 -0.479207 -0.0522161
+v -0.783608 -0.459708 -0.0519592
+v -0.795824 -0.440928 -0.0518179
+v -0.803685 -0.422803 -0.051895
+v -0.811328 -0.404717 -0.0517537
+v -0.817288 -0.386798 -0.0515996
+v -0.825201 -0.36893 -0.0518565
+v -0.832613 -0.350805 -0.0518051
+v -0.83996 -0.332732 -0.0515996
+v -0.842799 -0.315018 -0.0514583
+v -0.844649 -0.2976 -0.0517665
+v -0.8498 -0.280053 -0.0522675
+v -0.85707 -0.262108 -0.0519207
+v -0.859883 -0.244343 -0.0517537
+v -0.858085 -0.226951 -0.0515739
+v -0.853576 -0.209725 -0.0517409
+v -0.85007 -0.192525 -0.0514454
+v -0.843249 -0.175287 -0.0521391
+v -0.843429 -0.157753 -0.0523446
+v -0.843069 -0.140322 -0.0520748
+v -0.838213 -0.123161 -0.0519078
+v -0.831894 -0.106064 -0.0517922
+v -0.823005 -0.0888766 -0.0521648
+v -0.816749 -0.0716768 -0.0520877
+v -0.80899 -0.0546311 -0.0520491
+v -0.799973 -0.0374312 -0.0522932
+v -0.787513 -0.0381634 -0.064933
+v -0.790313 -0.0206295 -0.0518822
+v -0.775156 -0.00355815 -0.0521391
+v -0.76497 0.0140656 -0.0528584
+v -0.757391 0.0136546 -0.0656138
+v 0.420574 0.039859 -0.186462
+v -0.0686645 0.15634 -0.0759542
+v -0.0539438 0.158023 -0.0781123
+v -0.0501159 -0.00179834 -0.24374
+v -0.0515032 0.137792 -0.108016
+v -0.0644256 0.126526 -0.121761
+v -0.0512463 0.125563 -0.120823
+v -0.0626529 0.0395635 -0.210239
+v -0.0625373 0.0532694 -0.198922
+v -0.0475083 -0.167143 -0.301081
+v -0.0599683 -0.1516 -0.291909
+v -0.0621134 -0.169327 -0.298794
+v -0.0591976 -0.177265 -0.31647
+v -0.0139436 -0.167284 -0.326605
+v -0.0289726 -0.170881 -0.323175
+v 0.383413 -0.186655 -0.304498
+v 0.395076 -0.190496 -0.3004
+v 0.383901 -0.198794 -0.317266
+v 0.615926 -0.0822484 -0.158485
+v 0.603491 -0.092743 -0.172988
+v 0.0939698 -0.232063 -0.439194
+v 0.0815227 -0.216469 -0.429431
+v 0.032505 0.0391396 -0.210123
+v 0.534846 -0.624821 -0.290522
+v 0.0122865 -0.245949 -0.451165
+v 0.601603 -0.109185 -0.181029
+v 0.612239 -0.115762 -0.174413
+v 0.0752156 -0.269237 -0.453298
+v 0.591931 -0.192744 -0.220605
+v 0.526227 -0.239899 -0.273746
+v 0.52394 -0.257368 -0.280991
+v 0.511981 -0.254286 -0.284485
+v 0.161575 0.243444 0.00780994
+v -0.197207 0.17029 -0.0376881
+v 0.0130187 -0.231421 -0.440273
+v 0.0200579 0.054387 -0.200605
+v -0.755965 0.422777 -0.0551192
+v -0.756582 0.440555 -0.0557357
+v -0.762914 0.458295 -0.0556844
+v -0.771701 0.476548 -0.0555431
+v -0.776312 0.494428 -0.0556458
+v -0.774026 0.512232 -0.0560055
+v -0.77567 0.530023 -0.0560569
+v -0.774745 0.54798 -0.0559156
+v -0.15108 -0.0137573 -0.230689
+v -0.383169 0.729626 -0.0561083
+v -0.37374 0.748213 -0.0565707
+v 0.0590306 0.229481 0.0249713
+v -0.0723897 -0.967932 0.632168
+v -0.0856589 -0.968407 0.629754
+v -0.0769626 -0.967611 0.608482
+v -0.638765 -0.895317 -0.048157
+v -0.631301 -0.877899 -0.0355815
+v 0.516362 -0.654044 -0.307953
+v -0.518879 -0.817398 -0.0360568
+v -0.502476 -0.800802 -0.0366605
+v -0.491596 -0.802022 -0.0495315
+v -0.50254 -0.818541 -0.0497884
+v -0.49455 -0.783846 -0.0364935
+v 0.591789 -0.349443 -0.247465
+v 0.597595 -0.367247 -0.243701
+v 0.591584 -0.367607 -0.248723
+v -0.490838 -0.766415 -0.0360953
+v -0.488051 -0.748855 -0.0363907
+v -0.480755 -0.767301 -0.04957
+v -0.488385 -0.730653 -0.0366605
+v -0.488333 -0.712811 -0.0365577
+v -0.490517 -0.695059 -0.0369045
+v -0.49545 -0.676729 -0.0371101
+v -0.50561 -0.657731 -0.0240079
+v 0.567396 -0.200387 -0.238293
+v 0.578803 -0.205049 -0.233489
+v 0.565187 -0.217664 -0.245731
+v 0.296347 0.253219 0.021092
+v 0.299096 0.245705 0.00315994
+v -0.4657 -0.964566 -0.137535
+v 0.0788894 -0.0668726 -0.277805
+v -0.677557 -0.531924 -0.053809
+v -0.665097 -0.532258 -0.0644577
+v -0.66687 -0.541455 -0.0528199
+v -0.147971 0.0318692 -0.201633
+v -0.681038 -0.540492 -0.0402829
+v -0.693306 -0.522829 -0.0540016
+v -0.703543 -0.513748 -0.0624025
+v -0.753717 -0.497152 -0.0384974
+v -0.777404 -0.477986 -0.038857
+v -0.795708 -0.458564 -0.03878
+v -0.805959 -0.439695 -0.038279
+v -0.812549 -0.421904 -0.0384974
+v -0.818984 -0.404062 -0.0387414
+v -0.824726 -0.38613 -0.0384717
+v -0.833358 -0.368737 -0.0389341
+v -0.844752 -0.349867 -0.03878
+v -0.850917 -0.332012 -0.0388827
+v -0.855131 -0.31417 -0.038613
+v -0.858034 -0.296572 -0.0385487
+v -0.860153 -0.279231 -0.0389726
+v -0.866216 -0.261466 -0.0389726
+v -0.869132 -0.24374 -0.0388699
+v -0.867167 -0.226347 -0.03869
+v -0.86411 -0.209121 -0.0387543
+v -0.859447 -0.191947 -0.0387543
+v -0.855285 -0.174593 -0.0390882
+v -0.854193 -0.157098 -0.0394608
+v -0.854103 -0.139628 -0.0394351
+v -0.849042 -0.122506 -0.0391782
+v -0.842465 -0.105537 -0.0388699
+v -0.834976 -0.0883756 -0.0390754
+v -0.828798 -0.0711373 -0.0390754
+v -0.821206 -0.0540402 -0.0392167
+v -0.812163 -0.0368917 -0.039358
+v -0.802619 -0.0200772 -0.0390882
+v -0.788605 -0.00330124 -0.0389084
+v -0.773242 0.0146565 -0.0403985
+v -0.0623575 -0.918863 -0.104368
+v -0.0948561 0.183084 -0.00021837
+v -0.105569 0.174439 -0.0177137
+v -0.0833082 0.154272 -0.0735265
+v -0.0979775 0.152397 -0.0712015
+v 0.660524 -0.942138 0.228878
+v 0.668681 -0.943205 0.208004
+v 0.508038 -0.0661404 -0.201273
+v 0.507717 -0.0796537 -0.212448
+v 0.495321 -0.0644705 -0.203033
+v 0.000738605 -0.165113 -0.32884
+v -0.0106423 -0.173668 -0.345577
+v 0.528449 -0.222519 -0.26636
+v 0.540498 -0.225474 -0.263136
+v -0.0632695 0.0248685 -0.220374
+v 0.74145 -0.197124 -0.0610152
+v -0.0441043 -0.173925 -0.319951
+v -0.0253245 -0.176045 -0.343316
+v -0.00741816 -0.18004 -0.364588
+v -0.0220104 -0.18239 -0.36234
+v -0.135203 -0.952363 -0.36067
+v -0.130489 -0.922896 0.0277844
+v 0.0126462 -0.155736 -0.312924
+v 0.49527 0.115659 -0.0882857
+v 0.174857 -0.130868 -0.28699
+v -0.240432 -0.86251 -0.346001
+v 0.173187 0.112859 -0.160939
+v 0.00831733 0.0845477 -0.181106
+v -0.00522161 0.0837257 -0.180232
+v 0.028767 0.223431 0.0321261
+v 0.0168209 0.21417 0.0164291
+v 0.0920815 -0.170624 -0.373785
+v -0.768515 0.440838 -0.0425822
+v -0.779575 0.422829 -0.0410664
+v -0.770326 0.458731 -0.0428262
+v -0.776299 0.47665 -0.0427235
+v -0.779909 0.494544 -0.0430189
+v -0.780615 0.512476 -0.0432373
+v -0.778971 0.530318 -0.0431987
+v -0.774771 0.548057 -0.0430446
+v 0.670107 -0.0325885 -0.0568918
+v 0.669657 -0.0197175 -0.045087
+v -0.406303 0.71154 -0.0434428
+v -0.394665 0.729716 -0.0435199
+v -0.380536 0.748444 -0.0439695
+v -0.364081 0.766556 -0.0441108
+v 0.104824 0.0216957 -0.243406
+v -0.94429 0.0752734 0.383394
+v -0.0810474 0.14582 -0.0904309
+v 0.407793 0.181799 -0.0567505
+v -0.598867 -0.978516 0.213502
+v -0.620165 -0.861547 -0.022582
+v -0.528488 -0.815946 -0.0234684
+v -0.511917 -0.799697 -0.0237381
+v -0.503671 -0.782947 -0.0234555
+v -0.497877 -0.765528 -0.0237766
+v -0.496272 -0.74775 -0.023751
+v -0.496028 -0.729831 -0.0236996
+v -0.49464 -0.712182 -0.0237766
+v -0.495257 -0.694417 -0.0240849
+v -0.498584 -0.676356 -0.0242005
+v 0.334215 -0.110662 -0.255287
+v 0.133752 0.115543 -0.163675
+v -0.675605 -0.556548 -0.0261145
+v -0.695644 -0.537178 -0.0258062
+v -0.721964 -0.515944 -0.0248043
+v -0.75942 -0.495931 -0.0251254
+v -0.78813 -0.477254 -0.0264613
+v -0.804726 -0.457216 -0.0256778
+v -0.813949 -0.439142 -0.0254851
+v -0.821271 -0.420786 -0.0252025
+v -0.824597 -0.403163 -0.0254208
+v -0.829389 -0.385757 -0.0256392
+v -0.841682 -0.36753 -0.025742
+v -0.854501 -0.349482 -0.026153
+v -0.861579 -0.33119 -0.0258704
+v -0.866036 -0.313412 -0.0258319
+v -0.867372 -0.29593 -0.025742
+v -0.869094 -0.278486 -0.0258961
+v -0.873435 -0.260451 -0.0259989
+v -0.875259 -0.243316 -0.0259989
+v -0.875079 -0.225795 -0.0259603
+v -0.871932 -0.208569 -0.0260246
+v -0.867475 -0.191344 -0.0261273
+v -0.863621 -0.17399 -0.0266283
+v -0.862042 -0.156597 -0.0266411
+v -0.862876 -0.139204 -0.0263072
+v -0.858894 -0.121825 -0.0267439
+v -0.852035 -0.104895 -0.0263842
+v -0.844662 -0.087682 -0.0265898
+v -0.838265 -0.0705592 -0.026487
+v -0.830802 -0.0533594 -0.0267182
+v -0.823082 -0.0362494 -0.0266797
+v -0.813628 -0.019345 -0.0265512
+v -0.799665 -0.00249199 -0.0264099
+v -0.796749 0.0157355 -0.0151703
+v -0.0911952 0.101529 -0.146655
+v -0.104837 0.101516 -0.146526
+v 0.619394 0.0400902 -0.058125
+v 0.608552 0.0456522 -0.0642393
+v 0.241716 -0.146398 -0.296559
+v 0.396027 -0.0457164 -0.222648
+v 0.39315 -0.0643293 -0.229237
+v 0.383901 -0.0427877 -0.225807
+v 0.53879 0.0176366 -0.136995
+v -0.0369495 -0.0908805 -0.279604
+v -0.0208929 -0.0894547 -0.27936
+v -0.0236032 -0.107682 -0.286116
+v -0.00247272 -0.195672 -0.399669
+v -0.513446 0.319719 -0.0431088
+v -0.515925 0.303791 -0.0503664
+v -0.529721 0.306155 -0.0573286
+v 0.484505 0.095736 -0.118344
+v 0.496529 0.092666 -0.115132
+v 0.484724 0.083366 -0.130739
+v -0.172506 -0.945902 -0.368917
+v 0.298801 0.0805272 -0.204304
+v 0.28688 0.0961471 -0.195428
+v 0.731379 -0.202699 -0.0809511
+v 0.731598 -0.216443 -0.092165
+v -0.0775663 0.0099808 -0.230393
+v -0.0924412 0.00855497 -0.228788
+v 0.175602 -0.116391 -0.276662
+v -0.787436 0.405064 -0.0410921
+v -0.809363 0.387838 -0.0289661
+v -0.804417 0.405423 -0.028645
+v -0.79504 0.38744 -0.040938
+v -0.79558 0.423201 -0.0290304
+v -0.786473 0.441018 -0.0292231
+v -0.780692 0.458873 -0.0296726
+v -0.780911 0.47674 -0.0298653
+v -0.783171 0.494338 -0.0301608
+v -0.782722 0.512515 -0.0300965
+v -0.781129 0.530344 -0.0301736
+v -0.77522 0.548237 -0.0302507
+v 0.344299 -0.144818 -0.271819
+v -0.0361788 -0.913082 0.501776
+v -0.4155 0.711411 -0.0306874
+v -0.425969 0.692696 -0.0302635
+v -0.403156 0.730037 -0.0309186
+v -0.386778 0.74838 -0.031137
+v 0.348101 -0.124728 -0.267285
+v 0.344055 -0.158164 -0.283393
+v 0.902029 -0.601391 0.00166989
+v -0.627897 -0.860648 -0.00972389
+v -0.566279 -0.831014 -0.00994226
+v -0.537492 -0.81524 -0.0104047
+v -0.519612 -0.798823 -0.0107515
+v -0.511802 -0.781932 -0.0107901
+v -0.506869 -0.764616 -0.0107387
+v -0.50263 -0.747044 -0.0109699
+v -0.501024 -0.729292 -0.0110084
+v -0.499676 -0.711655 -0.011124
+v -0.50001 -0.693864 -0.0112653
+v -0.503144 -0.675984 -0.0112653
+v 0.345314 -0.168595 -0.298024
+v -0.650377 -0.593504 -0.0126783
+v -0.670659 -0.574185 -0.0128967
+v -0.689105 -0.554827 -0.0127939
+v -0.70461 -0.536188 -0.0129224
+v -0.730519 -0.516047 -0.0125113
+v -0.769838 -0.495006 -0.0119975
+v -0.793101 -0.475276 -0.012036
+v -0.808631 -0.456612 -0.0121388
+v -0.82005 -0.438371 -0.0127811
+v -0.827205 -0.420285 -0.0123443
+v -0.831701 -0.402469 -0.01237
+v -0.835811 -0.385282 -0.0128838
+v -0.847591 -0.367555 -0.0130251
+v -0.862465 -0.348185 -0.0125627
+v -0.870532 -0.330394 -0.0128196
+v -0.8735 -0.312796 -0.0128196
+v -0.874951 -0.295339 -0.0128453
+v -0.875067 -0.278024 -0.0129609
+v -0.877841 -0.259552 -0.0132307
+v -0.880102 -0.243958 -0.012871
+v -0.879729 -0.225461 -0.0131793
+v -0.876955 -0.208158 -0.0133591
+v -0.875259 -0.190843 -0.0133591
+v -0.872061 -0.17354 -0.0133591
+v -0.869016 -0.156302 -0.0135261
+v -0.867334 -0.138806 -0.0135518
+v -0.866049 -0.121414 -0.0137702
+v -0.861862 -0.104163 -0.0138858
+v -0.854193 -0.0870397 -0.01395
+v -0.847732 -0.0699812 -0.0138344
+v -0.840179 -0.052807 -0.01395
+v -0.833525 -0.0358384 -0.0137188
+v -0.824251 -0.0188055 -0.0136417
+v -0.812664 -0.00227362 -0.0128325
+v -0.809145 0.0149519 -0.00346823
+v 0.00987161 0.189044 -0.0342584
+v 0.888413 -0.659079 -0.0262044
+v -0.23943 -0.944913 -0.369701
+v -0.0916962 0.0746954 -0.169879
+v -0.0914393 0.0882472 -0.158395
+v 0.53053 -0.205358 -0.258627
+v 0.542258 -0.209121 -0.254722
+v 0.401602 0.2204 0.00409765
+v 0.389489 0.223367 0.00101478
+v 0.387626 0.232294 0.0168659
+v 0.584699 0.0775085 -0.0467826
+v 0.573292 0.0820044 -0.0517922
+v 0.572855 0.0940276 -0.0390626
+v 0.571853 -0.165717 -0.223611
+v 0.582643 -0.171472 -0.217535
+v 0.570261 -0.181324 -0.2325
+v -0.121497 0.0440722 -0.188826
+v -0.133341 0.0597949 -0.179641
+v 0.586407 0.0427492 -0.0869627
+v 0.574679 0.0464743 -0.0909832
+v 0.574178 0.0581764 -0.0777526
+v -0.0555752 -0.182223 -0.336842
+v 0.635515 -0.188441 -0.173694
+v 0.594063 -0.162981 -0.200888
+v 0.593035 -0.177496 -0.210997
+v 0.0240528 -0.147246 -0.295891
+v 0.417132 -0.239269 -0.325834
+v 0.406689 -0.232744 -0.332732
+v -0.820012 0.388056 -0.0160952
+v -0.814103 0.405744 -0.0162878
+v -0.807706 0.42342 -0.0161208
+v -0.801784 0.441185 -0.0163135
+v -0.795773 0.45904 -0.0165447
+v -0.789722 0.476817 -0.0166989
+v -0.78777 0.494493 -0.0172898
+v -0.785638 0.512553 -0.0172384
+v -0.780782 0.530344 -0.0172384
+v -0.77495 0.548224 -0.0173925
+v -0.513227 -0.657718 0.00138729
+v -0.455976 0.655496 -0.0164677
+v -0.44719 0.674121 -0.0169301
+v -0.435809 0.693055 -0.0178935
+v -0.421833 0.711501 -0.018022
+v -0.406714 0.730371 -0.0183431
+v -0.388654 0.748534 -0.0185101
+v -0.716774 0.490472 -0.378975
+v -0.17609 -0.798913 -0.292128
+v -0.780602 -0.383586 -0.099474
+v 0.347022 -0.178062 -0.313734
+v 0.348191 -0.188646 -0.328223
+v -0.633601 -0.860571 0.00337831
+v -0.615964 -0.96973 0.225204
+v -0.618238 -0.844309 0.016108
+v -0.544865 -0.814816 0.00269751
+v 0.591854 -0.439258 -0.263341
+v -0.525482 -0.798387 0.00231215
+v -0.516721 -0.781354 0.00205525
+v -0.511892 -0.764 0.00202956
+v -0.508732 -0.746389 0.00196533
+v -0.507062 -0.72865 0.00192679
+v -0.505751 -0.710987 0.00175981
+v -0.505867 -0.694956 0.00149005
+v -0.50773 -0.675367 0.0015029
+v -0.519509 -0.657384 0.013783
+v -0.635142 -0.61091 0.00151575
+v -0.660936 -0.592348 0.00043674
+v -0.681527 -0.573247 7.70718e-05
+v -0.701077 -0.553414 0.000321132
+v -0.719356 -0.534159 0.000539503
+v -0.744019 -0.514608 0.000642265
+v -0.773075 -0.494351 0.00087348
+v -0.794437 -0.474903 0.000886326
+v -0.808579 -0.456522 0.000732182
+v -0.822105 -0.437806 0.000757873
+v -0.831906 -0.419771 0.000475276
+v -0.836826 -0.40225 0.000295442
+v -0.841579 -0.38473 0.000192679
+v -0.851585 -0.366155 0.000423895
+v -0.866794 -0.347619 0.00043674
+v -0.875118 -0.329996 0.000141298
+v -0.879306 -0.312231 0.000205525
+v -0.880641 -0.294851 0.00021837
+v -0.88095 -0.277536 0
+v -0.881284 -0.260246 -0.000179834
+v -0.882722 -0.242699 -0.000231215
+v -0.884379 -0.225165 -0.000321132
+v -0.883082 -0.207786 -0.000462431
+v -0.880102 -0.190457 -0.000603729
+v -0.877931 -0.173167 -0.000398204
+v -0.874643 -0.156083 -0.000565193
+v -0.870468 -0.138588 -0.000757873
+v -0.868117 -0.121465 -0.000385359
+v -0.865934 -0.103983 -0.000822099
+v -0.86077 -0.0864745 -0.00145152
+v -0.854232 -0.0694417 -0.00119461
+v -0.846756 -0.0522418 -0.00141298
+v -0.839986 -0.0353246 -0.00109185
+v -0.833319 -0.0184073 -0.000745027
+v -0.822144 -0.00143867 -0.000269751
+v 0.0595701 -0.912466 0.474878
+v 0.0461467 -0.913069 0.472668
+v 0.161626 -0.18004 -0.389071
+v 0.147997 -0.179963 -0.38911
+v 0.210245 -0.165717 -0.352642
+v 0.384479 -0.210213 -0.330882
+v 0.372584 -0.206938 -0.334273
+v 0.372649 -0.193938 -0.322443
+v -0.107278 0.018767 -0.213656
+v 0.695656 -0.283881 -0.175852
+v -0.873705 0.134349 -0.0186642
+v -0.882774 0.141234 -0.0152731
+v -0.874591 0.152987 -0.0216315
+v 0.538327 -0.242802 -0.270586
+v -0.898047 0.141786 -0.00233784
+v -0.899858 0.159307 -0.00253052
+v -0.874617 0.209841 -0.0231986
+v -0.896197 0.211973 -0.00228646
+v -0.0404691 -0.179051 -0.340105
+v -0.0367183 -0.184458 -0.360195
+v -0.0513105 -0.186706 -0.357921
+v -0.00208736 0.216713 0.0402315
+v -0.232583 -0.0133206 -0.230933
+v -0.829517 0.370523 -0.00349392
+v -0.823493 0.352539 -0.0163264
+v -0.826691 0.388301 -0.00366091
+v -0.823377 0.405976 -0.00355815
+v -0.817121 0.423702 -0.00353246
+v -0.812921 0.441506 -0.0038279
+v -0.809556 0.459155 -0.00362237
+v -0.803441 0.476972 -0.00369945
+v -0.796351 0.494904 -0.00426464
+v -0.790249 0.512707 -0.00435456
+v -0.785676 0.530511 -0.00447016
+v -0.777121 0.547826 -0.00449585
+v -0.455668 0.674468 -0.00488121
+v -0.467729 0.655907 -0.00447016
+v -0.441795 0.692901 -0.00503536
+v -0.426496 0.711437 -0.00534364
+v -0.409887 0.730371 -0.0055877
+v -0.650582 -0.87646 0.00342969
+v 0.494345 0.126616 -0.0744513
+v -0.6759 -0.89104 0.0159796
+v -0.675091 -0.909023 0.00274889
+v -0.662169 -0.874456 0.015774
+v -0.645727 -0.859492 0.0164291
+v -0.629028 -0.84323 0.028979
+v -0.552521 -0.814019 0.0155428
+v -0.576992 -0.830076 0.00298011
+v -0.530093 -0.797847 0.0152088
+v -0.52272 -0.780686 0.0150033
+v -0.516619 -0.763512 0.0149391
+v -0.514679 -0.745759 0.0149776
+v -0.51202 -0.728084 0.0147336
+v -0.51071 -0.710473 0.0146051
+v -0.510761 -0.69276 0.0145023
+v -0.512508 -0.674982 0.0143482
+v -0.637801 -0.612541 0.0159282
+v -0.671353 -0.590897 0.0136802
+v -0.691906 -0.571885 0.0132949
+v -0.711931 -0.552566 0.013115
+v -0.733319 -0.533131 0.013115
+v -0.754462 -0.513118 0.0137702
+v -0.775413 -0.493298 0.0139757
+v -0.791726 -0.47543 0.0136674
+v -0.808181 -0.456214 0.0136931
+v -0.82506 -0.437485 0.0136417
+v -0.835966 -0.419271 0.0135004
+v -0.842285 -0.401531 0.0133976
+v -0.846576 -0.383676 0.0134233
+v -0.854065 -0.365487 0.0133463
+v -0.868002 -0.347247 0.0133591
+v -0.879203 -0.329366 0.0131279
+v -0.884007 -0.31191 0.0130251
+v -0.885446 -0.294504 0.0130123
+v -0.885536 -0.275313 0.012704
+v -0.883891 -0.25995 0.0127939
+v -0.884045 -0.242519 0.0126269
+v -0.885497 -0.224985 0.0125755
+v -0.885625 -0.207541 0.0124985
+v -0.88587 -0.190085 0.0123829
+v -0.883904 -0.172795 0.0125242
+v -0.880462 -0.155595 0.0126269
+v -0.87621 -0.138344 0.01237
+v -0.873063 -0.121041 0.0124342
+v -0.869607 -0.103623 0.0117534
+v -0.865317 -0.0862433 0.0115865
+v -0.861361 -0.0692362 0.0118947
+v -0.853898 -0.0521904 0.0117021
+v -0.844379 -0.0350163 0.0116892
+v -0.841194 -0.0178164 0.0119461
+v -0.832998 -0.00065511 0.0123957
+v -0.147535 0.110714 -0.129969
+v -0.146276 0.100091 -0.144741
+v -0.159943 0.100052 -0.144561
+v 0.724905 -0.919723 0.221646
+v -0.145505 0.0885041 -0.158408
+v -0.159686 0.0875921 -0.157239
+v -0.161202 0.110572 -0.129725
+v -0.0702702 0.164946 -0.0597178
+v -0.119789 0.111703 -0.131343
+v -0.118491 0.10117 -0.146141
+v -0.122191 0.0293644 -0.199038
+v -0.107496 0.0310599 -0.200875
+v -0.121934 0.0165704 -0.211267
+v -0.888117 0.123533 -0.00319848
+v -0.902723 0.124497 0.0104946
+v -0.908323 0.142275 0.0108414
+v -0.908631 0.159654 0.0105845
+v -0.907154 0.176995 0.0104432
+v -0.906974 0.194645 0.0105075
+v -0.90551 0.212307 0.0104047
+v -0.901798 0.229738 0.0108029
+v -0.892678 0.247156 0.0107644
+v -0.885291 0.264729 0.0105717
+v -0.879113 0.28225 0.0107258
+v -0.0171806 0.213476 0.0438795
+v -0.836685 0.370497 0.00985234
+v -0.84533 0.352642 0.0105845
+v -0.833808 0.388339 0.00959544
+v -0.829402 0.406143 0.00935138
+v -0.825098 0.423908 0.00910732
+v -0.823493 0.441686 0.00913301
+v -0.823313 0.459374 0.00922292
+v -0.815747 0.477126 0.00912016
+v -0.806717 0.494891 0.00890179
+v -0.801013 0.512836 0.00849074
+v -0.790313 0.530575 0.00837513
+v -0.781129 0.548379 0.00827237
+v -0.463246 0.63705 -0.0157869
+v -0.47482 0.637307 -0.00384074
+v -0.475899 0.656253 0.00796408
+v -0.486779 0.63723 0.00932569
+v -0.463426 0.674494 0.00782279
+v -0.446612 0.693055 0.00755304
+v -0.428037 0.711463 0.0073732
+v -0.40954 0.73005 0.00714199
+v -0.671289 -0.873596 0.0287349
+v -0.652817 -0.857565 0.0286065
+v -0.638495 -0.841752 0.0416445
+v -0.613588 -0.836216 0.0285551
+v -0.750621 -0.557897 0.15503
+v -0.758714 -0.547865 0.144034
+v -0.561873 -0.813017 0.0283367
+v -0.588873 -0.829703 0.016108
+v -0.534653 -0.797333 0.028067
+v -0.525829 -0.780275 0.0278358
+v -0.521359 -0.762921 0.0278101
+v -0.517055 -0.745413 0.0276688
+v -0.515437 -0.727699 0.0276045
+v -0.514306 -0.710114 0.0274632
+v -0.514499 -0.692297 0.0270265
+v -0.517415 -0.674532 0.0271935
+v -0.678457 -0.589445 0.0270522
+v -0.702349 -0.57064 0.0263586
+v -0.725804 -0.551333 0.0260888
+v -0.743711 -0.531538 0.0265769
+v -0.760551 -0.512515 0.0266797
+v -0.779099 -0.493568 0.0266155
+v -0.793859 -0.474287 0.0267439
+v -0.812895 -0.455841 0.026487
+v -0.82989 -0.437177 0.0264356
+v -0.840757 -0.418975 0.02632
+v -0.846833 -0.401082 0.0262943
+v -0.849877 -0.383445 0.0262173
+v -0.857366 -0.365397 0.0261787
+v -0.871277 -0.347041 0.0261273
+v -0.883814 -0.329097 0.0259989
+v -0.890173 -0.311434 0.0258576
+v -0.892883 -0.293965 0.0259475
+v -0.89129 -0.276765 0.0258833
+v -0.887103 -0.259758 0.0255878
+v -0.884649 -0.242416 0.0257548
+v -0.88578 -0.224831 0.0258319
+v -0.888297 -0.207246 0.0254594
+v -0.88989 -0.189764 0.0254208
+v -0.888734 -0.172448 0.0252795
+v -0.887552 -0.155043 0.0250612
+v -0.884855 -0.13774 0.0248171
+v -0.880963 -0.120527 0.0251639
+v -0.876929 -0.103263 0.0247657
+v -0.87251 -0.0859993 0.0246501
+v -0.866165 -0.0688765 0.0246501
+v -0.861078 -0.0518436 0.02483
+v -0.851483 -0.0347594 0.0249841
+v -0.84619 -0.01702 0.0235454
+v -0.843493 0.000154144 0.0242905
+v -0.839203 0.0175467 0.0239822
+v -0.867411 0.0532438 0.0234041
+v -0.860603 0.0771489 0.00211947
+v -0.878638 0.0709189 0.0229802
+v -0.888079 0.0885041 0.022672
+v -0.901926 0.106603 0.0228903
+v -0.886666 0.114554 0.00173412
+v -0.911509 0.124998 0.0234041
+v -0.916043 0.142544 0.0236097
+v -0.915863 0.159924 0.0236353
+v -0.913525 0.177214 0.0231986
+v -0.914617 0.194927 0.0233271
+v -0.913269 0.212603 0.0231986
+v -0.908285 0.229879 0.0233142
+v -0.901541 0.247413 0.0237124
+v -0.89445 0.26505 0.0234555
+v -0.888529 0.282661 0.0233142
+v -0.882247 0.300169 0.0234555
+v -0.876004 0.317716 0.023584
+v -0.862876 0.352552 0.0243161
+v -0.850699 0.341903 0.00986519
+v 0.606497 -0.0481056 -0.143533
+v -0.852626 0.370279 0.0237895
+v -0.85084 0.360696 0.0184458
+v -0.841309 0.388442 0.0226077
+v -0.835657 0.406284 0.0221453
+v -0.834321 0.424113 0.0219526
+v -0.833101 0.441891 0.0217086
+v -0.832484 0.459553 0.0220425
+v -0.826653 0.477357 0.0218627
+v -0.817211 0.494916 0.0219783
+v -0.811123 0.512553 0.0218884
+v -0.802593 0.530755 0.0212718
+v -0.495681 0.637718 0.0210406
+v -0.483863 0.65642 0.0206424
+v -0.468474 0.674879 0.0204497
+v -0.448179 0.692888 0.0202956
+v -0.426791 0.711796 0.0201029
+v -0.662027 -0.856627 0.0415032
+v -0.569349 -0.812555 0.0412976
+v -0.596773 -0.828483 0.0288377
+v -0.537929 -0.796897 0.0407838
+v -0.528873 -0.779889 0.0407838
+v -0.523028 -0.762612 0.0407453
+v -0.520048 -0.745053 0.0407324
+v -0.517055 -0.727429 0.0406168
+v -0.515424 -0.709895 0.0404884
+v -0.517621 -0.691925 0.0398846
+v -0.519432 -0.673993 0.0403599
+v -0.532418 -0.657474 0.0389598
+v 0.375924 -0.93411 -0.267503
+v -0.710698 -0.570665 0.0386387
+v -0.699253 -0.581828 0.0475533
+v -0.736903 -0.550716 0.0384074
+v -0.763839 -0.512309 0.0394351
+v -0.78461 -0.493812 0.0391139
+v -0.803942 -0.474248 0.0392424
+v -0.823647 -0.454929 0.0393451
+v -0.839061 -0.436368 0.0393066
+v -0.848451 -0.41832 0.0391525
+v -0.852703 -0.400555 0.0392552
+v -0.85463 -0.383111 0.0390112
+v -0.860693 -0.365269 0.0389726
+v -0.87576 -0.346489 0.0389598
+v -0.888554 -0.328711 0.0387671
+v -0.89621 -0.310946 0.0387671
+v -0.899152 -0.293477 0.0387286
+v -0.898676 -0.276277 0.0389084
+v -0.89418 -0.259334 0.0387543
+v -0.888798 -0.242224 0.0383817
+v -0.886846 -0.224754 0.0384331
+v -0.891342 -0.207182 0.0377523
+v -0.893872 -0.189507 0.037945
+v -0.89481 -0.172037 0.0381762
+v -0.892305 -0.154734 0.0378166
+v -0.889209 -0.137458 0.037778
+v -0.886165 -0.120155 0.0376881
+v -0.881977 -0.102852 0.0374569
+v -0.878368 -0.0857167 0.0375597
+v -0.872087 -0.0686453 0.0375982
+v -0.867398 -0.051394 0.0375853
+v -0.859781 -0.03413 0.0374954
+v -0.851945 -0.0167888 0.0368018
+v -0.850224 0.000539503 0.0366733
+v -0.852125 0.0179063 0.0363265
+v -0.86163 0.0352475 0.0360696
+v -0.878432 0.0535906 0.0360696
+v -0.890507 0.0716896 0.0362366
+v -0.900154 0.089262 0.0358384
+v -0.911098 0.107104 0.0357485
+v -0.91901 0.125357 0.0364678
+v -0.921695 0.142621 0.0364421
+v -0.920346 0.160027 0.0363265
+v -0.918972 0.177445 0.0362237
+v -0.918908 0.19512 0.0361852
+v -0.917546 0.212705 0.0360568
+v -0.914425 0.230316 0.0361595
+v -0.909235 0.24776 0.0364678
+v -0.903558 0.265371 0.0363008
+v -0.901605 0.282802 0.036699
+v -0.895683 0.300413 0.0365834
+v -0.887103 0.318152 0.0360182
+v -0.882568 0.335802 0.0358898
+v -0.879087 0.353259 0.036198
+v -0.87093 0.370561 0.0364806
+v -0.85481 0.388416 0.035787
+v -0.844983 0.406489 0.0349521
+v -0.840847 0.424267 0.0345924
+v -0.8419 0.442032 0.0347722
+v -0.841361 0.459708 0.0350805
+v -0.835246 0.477318 0.0351319
+v -0.826396 0.495006 0.034875
+v -0.821784 0.512553 0.0348236
+v -0.810391 0.529445 0.035286
+v -0.50308 0.637409 0.0338474
+v -0.504364 0.617859 0.0224022
+v -0.487062 0.656549 0.0333207
+v -0.468821 0.675277 0.0332436
+v -0.448205 0.693068 0.0330638
+v -0.665688 -0.855638 0.0541815
+v -0.643646 -0.840429 0.0541943
+v -0.613678 -0.826788 0.054387
+v -0.606215 -0.827109 0.0415288
+v -0.579843 -0.812272 0.0542842
+v -0.539072 -0.79682 0.0539117
+v -0.530325 -0.779607 0.0538475
+v -0.52552 -0.762394 0.0537833
+v -0.521102 -0.744886 0.053719
+v -0.517184 -0.727416 0.0536677
+v -0.51563 -0.709857 0.0535264
+v -0.517017 -0.692053 0.0533594
+v -0.521487 -0.674006 0.0531924
+v -0.523093 -0.6738 0.0660762
+v 0.010334 -0.980777 -0.248826
+v -0.733255 -0.556047 0.041015
+v -0.7689 -0.512193 0.0521262
+v -0.791816 -0.49281 0.0520877
+v -0.815079 -0.47367 0.0519078
+v -0.833474 -0.454518 0.0518436
+v -0.8456 -0.436021 0.0519849
+v -0.854784 -0.417858 0.0519464
+v -0.858792 -0.399977 0.0521262
+v -0.860744 -0.382623 0.0518822
+v -0.864341 -0.365243 0.0516124
+v -0.87639 -0.346887 0.0516253
+v -0.894553 -0.32812 0.0516766
+v -0.901091 -0.310638 0.0514968
+v -0.905369 -0.292988 0.0515739
+v -0.905227 -0.275866 0.0516124
+v -0.901849 -0.258833 0.0516895
+v -0.89508 -0.241697 0.0511243
+v -0.890764 -0.224626 0.0509316
+v -0.896531 -0.206912 0.0502893
+v -0.901284 -0.189019 0.0509316
+v -0.902106 -0.171523 0.0510729
+v -0.898329 -0.154323 0.0506875
+v -0.89341 -0.137265 0.0508032
+v -0.890378 -0.119962 0.0506747
+v -0.88587 -0.10275 0.0505462
+v -0.882735 -0.0854598 0.050482
+v -0.876904 -0.0682342 0.0503407
+v -0.872189 -0.0510729 0.0503407
+v -0.865754 -0.0339244 0.0504178
+v -0.860834 -0.0164291 0.0497498
+v -0.856762 0.000809254 0.0493131
+v -0.864778 0.0183174 0.0489663
+v -0.876248 0.036532 0.0495315
+v -0.888991 0.0541686 0.0491204
+v -0.901271 0.0721649 0.0490562
+v -0.912292 0.0898785 0.0488121
+v -0.923224 0.108132 0.0495828
+v -0.927296 0.125601 0.0496214
+v -0.926281 0.14284 0.0492746
+v -0.924675 0.160194 0.049236
+v -0.923288 0.177561 0.0491076
+v -0.923275 0.195249 0.0489534
+v -0.921631 0.21277 0.0489149
+v -0.918792 0.23038 0.0489663
+v -0.91603 0.248145 0.0489277
+v -0.914836 0.265846 0.0487351
+v -0.913911 0.28329 0.0493773
+v -0.908002 0.30076 0.0492746
+v -0.89919 0.318332 0.0488892
+v -0.893654 0.336149 0.0484011
+v -0.889286 0.353862 0.0481442
+v -0.882851 0.371358 0.0482855
+v -0.871778 0.38866 0.0485167
+v -0.855298 0.406567 0.0480543
+v -0.848323 0.424434 0.0475404
+v -0.849479 0.442161 0.0477074
+v -0.84777 0.459913 0.0477717
+v -0.84172 0.47755 0.0476817
+v -0.837224 0.495238 0.0476432
+v -0.835143 0.512425 0.0480799
+v -0.823775 0.529046 0.0485681
+v 0.540125 -0.292038 -0.283598
+v -0.48981 0.656292 0.0461917
+v -0.0380285 -0.108723 -0.286309
+v -0.646986 -0.839594 0.0671167
+v -0.61992 -0.82594 0.0671424
+v -0.58019 -0.811309 0.066924
+v -0.541924 -0.796691 0.0668212
+v -0.53008 -0.779671 0.0668212
+v -0.52421 -0.76242 0.0667313
+v -0.51956 -0.744937 0.0666414
+v -0.515655 -0.727429 0.0666799
+v -0.514756 -0.70996 0.0665258
+v -0.516503 -0.691938 0.066256
+v -0.544043 -0.657345 0.0772388
+v -0.525777 -0.391486 -0.237754
+v -0.799022 -0.491731 0.0651513
+v -0.806691 -0.491012 0.0780095
+v -0.822555 -0.47299 0.0648174
+v -0.837879 -0.453991 0.0649073
+v -0.850314 -0.435661 0.0648045
+v -0.859485 -0.417613 0.0646761
+v -0.864662 -0.399373 0.0650614
+v -0.866833 -0.382109 0.0647531
+v -0.869273 -0.364935 0.0643678
+v -0.881875 -0.346078 0.0647018
+v -0.899036 -0.327696 0.0645091
+v -0.906923 -0.310098 0.0644063
+v -0.910276 -0.29268 0.0642779
+v -0.911355 -0.275339 0.0643806
+v -0.908362 -0.25828 0.0642907
+v -0.902491 -0.24117 0.0640852
+v -0.899665 -0.223881 0.063687
+v -0.904084 -0.206103 0.0627878
+v -0.907732 -0.18862 0.0636484
+v -0.908362 -0.171074 0.0638668
+v -0.904225 -0.153951 0.0636484
+v -0.897687 -0.137034 0.0637641
+v -0.893256 -0.119808 0.0635842
+v -0.88867 -0.102595 0.0635072
+v -0.885998 -0.0852285 0.0632888
+v -0.88172 -0.0679131 0.0630833
+v -0.876788 -0.0508545 0.0631218
+v -0.870507 -0.0335776 0.0630961
+v -0.866383 -0.0161208 0.0629291
+v -0.864533 0.00113039 0.0621841
+v -0.875902 0.0185229 0.0616317
+v -0.889132 0.0366733 0.0618886
+v -0.899961 0.0545154 0.0617602
+v -0.913603 0.0726402 0.0618886
+v -0.9242 0.0904309 0.061773
+v -0.932228 0.108286 0.0621969
+v -0.933795 0.125678 0.0620942
+v 0.437273 -0.324305 -0.348493
+v 0.450247 -0.324806 -0.340542
+v -0.516349 0.41859 -0.0108928
+v -0.44498 0.0484268 -0.19205
+v -0.459123 0.0474505 -0.190933
+v -0.800012 -0.503227 0.0967893
+v -0.720114 -0.0656009 -0.128119
+v -0.720088 -0.0474505 -0.119975
+v -0.706369 0.489881 -0.40121
+v 0.529849 0.0906621 -0.0871297
+v 0.529348 0.102647 -0.0744128
+v 0.528603 0.113938 -0.0608353
+v 0.348178 -0.201376 -0.340246
+v 0.205172 -0.0726915 -0.267683
+v 0.513163 0.148312 -0.0205782
+v 0.418159 0.188081 -0.0379322
+v 0.526253 0.13458 -0.0318178
+v 0.484826 -0.032794 -0.18564
+v 0.487601 -0.0145023 -0.179654
+v 0.470401 -0.11133 -0.255609
+v 0.468847 -0.12722 -0.264472
+v 0.545264 -0.0732824 -0.19381
+v 0.532996 -0.0707391 -0.196495
+v 0.409707 0.172564 -0.072987
+v 0.146135 0.100579 -0.173424
+v 0.0776434 0.137637 -0.135312
+v 0.0629227 0.135813 -0.133103
+v -0.0762561 0.178768 -0.0226206
+v 0.607229 -0.255506 -0.231639
+v 0.604211 -0.274889 -0.237291
+v 0.197965 0.0317536 -0.228929
+v 0.610287 -0.236161 -0.226077
+v 0.416913 -0.252783 -0.337613
+v 0.05659 -0.149018 -0.319758
+v 0.160303 0.152923 -0.126603
+v 0.128858 0.220965 -0.0453311
+v 0.000777141 0.146809 -0.091998
+v 0.445764 0.163392 -0.0629291
+v 0.446483 0.152114 -0.0763268
+v 0.348795 -0.213078 -0.353541
+v 0.548192 -0.329739 -0.282751
+v 0.558327 -0.33665 -0.275519
+v 0.348294 -0.227208 -0.364742
+v 0.277067 -0.193514 -0.374299
+v 0.276977 -0.206796 -0.386566
+v 0.264388 -0.191716 -0.376303
+v 0.508154 0.0759286 -0.122698
+v 0.496631 0.0801418 -0.127335
+v 0.248679 -0.170419 -0.347658
+v 0.65098 -0.00318563 -0.0630319
+v 0.660396 -0.0117278 -0.0536677
+v 0.650813 -0.01702 -0.0737962
+v 0.451943 -0.2511 -0.31331
+v 0.561038 -0.599875 -0.263637
+v 0.473857 0.189442 0.012036
+v 0.598379 0.0268081 -0.0954919
+v 0.598276 0.0137059 -0.107091
+v 0.586767 0.0177522 -0.11142
+v 0.597685 -0.000333978 -0.117701
+v 0.26137 -0.0820686 -0.260965
+v 0.251029 -0.0627364 -0.256148
+v -0.475218 0.0313168 -0.197985
+v -0.462604 0.0147207 -0.208608
+v -0.476079 0.0140784 -0.207118
+v 0.586767 0.0307003 -0.0996667
+v 0.52755 0.124509 -0.0464743
+v 0.539535 0.108568 -0.0548109
+v 0.540241 0.0716639 -0.0923192
+v 0.567833 -0.0954406 -0.195852
+v 0.565611 -0.112756 -0.20311
+v 0.501821 -0.23435 -0.279578
+v 0.500061 -0.250753 -0.287915
+v 0.148331 0.194208 -0.0940019
+v 0.407819 -0.0493902 -0.219064
+v 0.482707 -0.0626208 -0.204998
+v 0.117361 0.0458192 -0.217612
+v -0.667127 0.903448 -0.729189
+v 0.39094 0.233784 0.0249841
+v 0.395526 -0.215249 -0.325577
+v -0.0780801 0.126423 -0.121517
+v -0.0772966 0.114798 -0.135133
+v -0.119712 0.0598462 -0.17977
+v -0.132082 0.0749652 -0.169943
+v 0.573138 -0.0205268 -0.147361
+v 0.49491 -0.103649 -0.238165
+v 0.482874 -0.10063 -0.241427
+v 0.48448 0.0701225 -0.142159
+v 0.496156 0.0663588 -0.138087
+v 0.48367 0.0558642 -0.152384
+v 0.495295 0.0520106 -0.148299
+v 0.490029 0.00331409 -0.172744
+v 0.472803 -0.0297497 -0.189134
+v 0.65608 -0.319797 -0.215518
+v 0.410375 -0.019512 -0.212294
+v 0.425815 -0.014862 -0.204459
+v 0.771469 -0.898927 0.187606
+v 0.50394 -0.217047 -0.271973
+v 0.46999 -0.0608996 -0.206796
+v 0.439521 -0.00214516 -0.192898
+v 0.483401 -0.0483112 -0.194568
+v 0.470543 -0.0469753 -0.196263
+v -0.05966 -0.968458 0.63538
+v -0.0673158 -0.967546 0.65493
+v 0.0954084 -0.202853 -0.417575
+v 0.619034 -0.0114452 -0.105678
+v 0.629799 -0.0171228 -0.0995767
+v 0.618212 -0.0262815 -0.115492
+v 0.395988 -0.227323 -0.338435
+v 0.520626 -0.0681315 -0.199141
+v 0.425276 0.125691 -0.125023
+v 0.413368 0.129005 -0.128427
+v 0.413021 0.141054 -0.1158
+v 0.307613 0.211292 -0.0628777
+v 0.407125 -0.0894418 -0.253412
+v 0.709015 -0.10099 -0.0607454
+v 0.758573 -0.588623 -0.012036
+v 0.481846 -0.299398 -0.314761
+v 0.506651 -0.10731 -0.234298
+v 0.47148 0.122364 -0.0954791
+v 0.483568 0.119359 -0.092332
+v 0.472033 0.110675 -0.108761
+v 0.472636 0.0991272 -0.122082
+v 0.221575 -0.956615 0.0824411
+v 0.217297 -0.940366 0.0668212
+v 0.0400067 0.195428 -0.041516
+v 0.0243226 0.191639 -0.0369945
+v -0.0775406 0.101555 -0.146809
+v 0.365173 -0.0920494 -0.250406
+v 0.305853 0.220374 -0.0471037
+v 0.75513 -0.611603 -0.0155557
+v 0.7526 -0.628854 -0.0233784
+v 0.644468 -0.891438 0.367106
+v 0.157515 0.0578809 -0.204882
+v -0.0773223 -0.109647 -0.288069
+v -0.0772452 -0.128106 -0.28925
+v -0.0824219 -0.129776 -0.288724
+v 0.41008 0.0587544 -0.181054
+v 0.398275 0.0623254 -0.184805
+v 0.764289 -0.645759 -0.0318949
+v 0.496143 0.104651 -0.102416
+v 0.425494 0.113385 -0.13738
+v 0.437299 0.109789 -0.133527
+v 0.437003 0.12203 -0.121028
+v 0.585264 0.0659606 -0.0602188
+v 0.573754 0.0702638 -0.0650357
+v 0.444133 0.172949 -0.0474505
+v 0.432405 0.176559 -0.0514583
+v 0.430594 0.185704 -0.0357356
+v -0.0899107 -0.17065 -0.297574
+v -0.0762304 -0.170663 -0.297446
+v -0.0819851 -0.194298 -0.35033
+v 0.584044 0.0892363 -0.0338474
+v 0.454691 -0.21995 -0.2948
+v 0.442077 -0.218036 -0.296881
+v 0.443837 -0.201594 -0.288621
+v 0.459958 0.113668 -0.111921
+v 0.460652 0.102274 -0.125421
+v 0.448025 0.117046 -0.115698
+v 0.461243 0.090675 -0.138665
+v 0.449373 0.0940533 -0.14221
+v 0.449039 0.106128 -0.129532
+v 0.472803 0.073899 -0.146205
+v 0.471853 0.0593838 -0.156109
+v 0.457505 0.159796 -0.0589599
+v 0.458339 0.148736 -0.0725631
+v 0.282359 0.190444 -0.0910475
+v 0.630569 -0.00282597 -0.0892234
+v 0.942607 -0.548289 0.0513812
+v 0.94131 -0.563896 0.0417472
+v -0.133893 0.110637 -0.130046
+v 0.650891 -0.0294543 -0.0862305
+v -0.14625 0.0743871 -0.16925
+v -0.0148042 -0.206604 -0.414415
+v 0.596658 0.0615161 -0.0552605
+v 0.597338 0.0503664 -0.0693775
+v 0.453022 -0.236148 -0.303599
+v -0.132095 0.100669 -0.145614
+v 0.456464 -0.203508 -0.28654
+v -0.16625 0.151767 -0.0700069
+v -0.178132 0.142236 -0.0856268
+v 0.282012 0.000205525 -0.240747
+v 0.279584 0.0183302 -0.239642
+v 0.421833 0.0550549 -0.177201
+v 0.40859 0.043173 -0.189776
+v 0.424633 0.0861791 -0.159269
+v 0.574255 -0.135133 -0.204703
+v 0.572907 -0.150521 -0.213964
+v 0.561783 -0.145653 -0.219154
+v 0.927565 -0.577602 0.0298782
+v 0.507717 0.0624281 -0.133874
+v 0.10404 0.237124 0.01553
+v 0.10783 0.231344 -0.00461146
+v 0.430748 0.0204882 -0.191074
+v 0.482257 -0.193566 -0.271729
+v -0.102461 -0.195043 -0.323868
+v -0.0383882 -0.281338 -0.462444
+v -0.0313875 -0.265397 -0.457293
+v -0.056834 -0.92508 0.300439
+v -0.0615739 -0.925619 0.276778
+v 0.519278 -0.0965453 -0.220168
+v 0.437504 0.0974187 -0.145807
+v 0.212904 -0.212371 -0.407003
+v 0.0355622 0.110367 -0.157162
+v 0.0220104 0.10984 -0.15661
+v 0.478725 0.160669 -0.0346438
+v 0.465571 0.174324 -0.0233399
+v 0.596683 -0.0149005 -0.127708
+v 0.480215 0.150945 -0.0494544
+v 0.468783 0.155197 -0.0543741
+v 0.46728 0.164972 -0.0389983
+v 0.0720814 -0.980006 -0.261556
+v 0.0587094 -0.980559 -0.263675
+v -0.757031 -0.196764 -0.153373
+v 0.494255 -0.196597 -0.268236
+v 0.413342 0.216867 0.00811823
+v 0.415089 0.207516 -0.00755304
+v -0.0378487 0.112499 -0.132705
+v -0.023706 0.113077 -0.13363
+v -0.0249263 0.12361 -0.118909
+v 0.547563 -0.264215 -0.273451
+v 0.561783 -0.250432 -0.262596
+v 0.550415 -0.245743 -0.267362
+v 0.535732 -0.261119 -0.277253
+v 0.553934 -0.212975 -0.250625
+v 0.569965 -0.0652541 -0.176482
+v 0.581783 -0.0688636 -0.172718
+v 0.568963 -0.0802831 -0.186218
+v 0.428513 0.194478 -0.0192037
+v 0.0270072 -0.0231729 -0.246912
+v 0.0150996 -0.00682085 -0.238537
+v 0.574975 0.0213489 -0.115235
+v 0.56263 0.011047 -0.129904
+v 0.562284 -0.00247914 -0.141029
+v 0.574731 0.00811823 -0.12677
+v 0.560768 -0.160797 -0.22889
+v 0.581102 -0.187683 -0.226231
+v 0.516233 -0.219757 -0.269225
+v 0.514024 -0.237099 -0.276675
+v -0.000712914 0.169224 -0.0645862
+v -6.42265e-06 0.158511 -0.0786646
+v 0.0947148 -0.949679 -0.306848
+v 0.350529 -0.0938863 -0.248736
+v 0.17555 -0.192525 -0.401904
+v 0.552239 -0.22925 -0.259154
+v 0.529913 0.0527043 -0.123392
+v 0.214086 0.138845 -0.137612
+v 0.214844 0.127515 -0.151215
+v -0.226662 -0.984335 -0.364383
+v 0.422398 -0.0347851 -0.209314
+v 0.0257998 -0.0388185 -0.25593
+v 0.0133527 -0.0232757 -0.246784
+v 0.518353 -0.111086 -0.230316
+v 0.690069 -0.111651 -0.101131
+v 0.667487 -0.231716 -0.179153
+v -0.0381184 0.124741 -0.119949
+v 0.435668 0.068337 -0.165781
+v 0.423131 0.0704308 -0.168081
+v 0.543941 -0.0887482 -0.202917
+v 0.542695 -0.104098 -0.212204
+v 0.531211 -0.0997052 -0.2167
+v 0.622849 -0.121658 -0.168119
+v 0.628167 -0.0719208 -0.143713
+v 0.864456 -0.608418 -0.0177907
+v 0.557235 -0.0764295 -0.190354
+v -0.213855 -0.809768 -0.293117
+v -0.195705 -0.840404 -0.341377
+v 0.595848 0.072987 -0.0421968
+v 0.187047 0.126321 -0.149712
+v 0.0740724 0.170393 -0.0926788
+v 0.576799 -0.117612 -0.197959
+v 0.563247 -0.130161 -0.210111
+v -0.245454 0.195094 -0.039024
+v -0.257452 0.198126 -0.042184
+v 0.571866 -0.0358512 -0.156597
+v 0.560216 -0.0322417 -0.160618
+v 0.00174054 0.210945 0.0200515
+v 0.64696 -0.114965 -0.149455
+v 0.657223 -0.121028 -0.142673
+v 0.644365 -0.133283 -0.155813
+v -0.057579 -0.223637 -0.422983
+v 0.0797629 -0.914431 -0.103906
+v 0.40674 -0.194311 -0.296315
+v 0.660627 -0.0246758 -0.0654339
+v -0.267985 -0.843358 -0.305744
+v -0.212082 -0.81926 -0.309867
+v 0.0866865 0.205884 -0.0539631
+v 0.677763 -0.225268 -0.160194
+v 0.687898 -0.23277 -0.152281
+v 0.548064 -0.612785 -0.276996
+v 0.916326 -0.572875 0.0249327
+v 0.493253 0.137226 -0.060617
+v 0.481487 0.140823 -0.0641237
+v 0.166764 -0.109352 -0.277009
+v 0.392328 -0.273386 -0.367504
+v 0.42543 0.213836 0.0112525
+v 0.416438 0.197586 -0.022338
+v 0.403285 0.21092 -0.0114965
+v 0.880886 -0.523651 0.0511885
+v 0.282873 -0.247593 -0.403008
+v 0.598045 0.0389983 -0.0829036
+v 0.585816 0.0543998 -0.0736292
+v 0.458969 0.137226 -0.0857937
+v 0.401782 0.120155 -0.144664
+v 0.574898 0.0339501 -0.103058
+v 0.562142 0.0741174 -0.0691976
+v 0.730904 -0.230149 -0.103469
+v -0.399341 0.292012 0.0678489
+v 0.470594 -0.294633 -0.319681
+v 0.468115 -0.312385 -0.326913
+v 0.456965 -0.307504 -0.331987
+v 0.678919 -0.198126 -0.137702
+v -0.184516 0.168312 -0.0357356
+v 0.770544 -0.57958 0.00462431
+v 0.768887 -0.595714 -0.00463715
+v 0.766948 -0.613646 -0.0125884
+v 0.765933 -0.62924 -0.0231601
+v 0.17478 -0.180977 -0.388069
+v 0.516285 0.129082 -0.0515739
+v 0.504814 0.133167 -0.0558514
+v 0.687178 -0.259758 -0.175236
+v 0.675682 -0.268364 -0.191934
+v 0.687577 -0.246232 -0.163778
+v 0.667307 -0.128684 -0.134709
+v 0.528989 0.0378294 -0.133052
+v 0.516182 0.0265127 -0.146603
+v 0.254433 -0.913493 -0.0458706
+v 0.673061 -0.286746 -0.198421
+v 0.865587 -0.592759 -0.00764295
+v -0.199314 0.178704 -0.021426
+v 0.437132 0.0839312 -0.156841
+v 0.472945 -0.276893 -0.312346
+v 0.0494094 -0.0846634 -0.284498
+v -0.272301 0.208325 -0.027155
+v 0.521538 -0.0535777 -0.189057
+v 0.531853 -0.0857424 -0.206103
+v 0.519946 -0.0823512 -0.20961
+v 0.378609 -0.000578038 -0.219513
+v 0.382167 0.0189211 -0.2153
+v 0.0460054 0.142287 -0.113822
+v 0.100341 0.242314 0.0358255
+v 0.264131 -0.205358 -0.387992
+v 0.251479 -0.20347 -0.390022
+v -0.0225499 0.103109 -0.148749
+v -0.0206874 0.0932954 -0.164343
+v 0.587525 -0.227426 -0.235441
+v 0.200689 0.126552 -0.150046
+v 0.68592 -0.275198 -0.184703
+v 0.437813 -0.017855 -0.201016
+v 0.634397 -0.22943 -0.207413
+v -0.135332 0.0301864 -0.199899
+v 0.452225 0.18758 -0.0118691
+v 0.654025 -0.257561 -0.20347
+v 0.655913 -0.351422 -0.217895
+v 0.657699 0.0219911 -0.0126269
+v 0.271929 0.0552219 -0.228107
+v 0.272751 0.069827 -0.218332
+v 0.68908 -0.204934 -0.130418
+v 0.688386 -0.218588 -0.141529
+v 0.678238 -0.212333 -0.148222
+v 0.556054 -0.0916897 -0.199744
+v -0.00844578 0.0129994 -0.23372
+v 0.510055 -0.0365834 -0.181517
+v 0.00466927 0.0121773 -0.232885
+v 0.470876 -0.0975087 -0.244819
+v 0.458751 -0.0946313 -0.247889
+v 0.450452 0.196828 0.00384074
+v 0.437029 0.209905 0.0154272
+v 0.25162 -0.190265 -0.377934
+v 0.5257 0.00565193 -0.14993
+v 0.524364 -0.00963397 -0.15914
+v 0.629053 -0.0574699 -0.13345
+v 0.678893 -0.119294 -0.118742
+v 0.644905 -0.23539 -0.201029
+v 0.655476 -0.241312 -0.194735
+v 0.651777 -0.274234 -0.211228
+v 0.438827 0.200682 -0.000295442
+v -0.185955 0.0632888 -0.183174
+v 0.606471 0.0675663 -0.0366091
+v -0.261331 -0.862575 -0.331255
+v 0.114253 0.219115 -0.0429418
+v 0.101805 0.208877 -0.057457
+v 0.470119 0.145075 -0.0689921
+v -0.0777975 0.0882986 -0.158524
+v 0.482656 0.130405 -0.0785618
+v 0.699972 -0.197445 -0.112576
+v 0.459431 0.125383 -0.0989987
+v 0.563787 -0.233219 -0.254825
+v -0.0835394 0.896987 -0.236456
+v 0.583568 -0.156391 -0.207734
+v 0.58493 -0.140964 -0.198537
+v 0.587923 -0.122506 -0.192679
+v 0.676928 -0.136546 -0.126256
+v 0.664674 -0.146167 -0.141607
+v -0.446047 -0.752028 -0.0748624
+v 0.559111 -0.177085 -0.237407
+v 0.499355 -0.0182018 -0.175724
+v 0.211209 -0.22898 -0.4157
+v -0.0453246 -0.200489 -0.395083
+v -0.0307067 -0.198216 -0.397331
+v 0.624314 -0.209327 -0.202943
+v 0.623556 -0.223739 -0.213373
+v 0.621924 -0.240014 -0.221954
+v 0.230361 0.0368917 -0.235942
+v 0.391223 0.214003 -0.0146565
+v 0.249925 -0.180785 -0.362327
+v 0.595463 -0.0306489 -0.136635
+v 0.584416 -0.0251768 -0.142429
+v 0.594834 -0.0442906 -0.147631
+v 0.455809 0.169147 -0.0433143
+v -0.240342 -0.835458 -0.320336
+v 0.539817 0.0322545 -0.127066
+v 0.574975 -0.238049 -0.249738
+v 0.641128 0.00381505 -0.0705592
+v 0.640794 0.0165961 -0.0587287
+v 0.650801 0.00919723 -0.0505334
+v 0.640743 -0.0095569 -0.0819016
+v 0.640563 -0.0233528 -0.0928073
+v 0.648899 -0.0978169 -0.141786
+v 0.636016 -0.109262 -0.155351
+v 0.651096 -0.0418114 -0.0987418
+v 0.640357 -0.0360696 -0.104959
+v 0.593498 -0.0575084 -0.159796
+v 0.593549 -0.0726273 -0.168749
+v 0.544596 -0.191678 -0.247593
+v 0.556067 -0.196263 -0.243046
+v 0.547563 -0.172551 -0.241877
+v 0.473009 0.0870654 -0.134747
+v 0.650351 -0.0823384 -0.132641
+v 0.637853 -0.0922292 -0.14758
+v 0.639304 -0.076802 -0.138498
+v 0.607512 0.0566221 -0.0504306
+v 0.482142 -0.114914 -0.251845
+v -0.171273 -0.961008 0.670987
+v 0.518481 -0.202378 -0.261928
+v 0.527447 0.0222737 -0.141851
+v 0.433959 0.052229 -0.174144
+v 0.618662 -0.259514 -0.227246
+v 0.480588 -0.130919 -0.26067
+v 0.576542 -0.222429 -0.240875
+v 0.637146 0.0472193 -0.0138986
+v 0.639985 0.0273348 -0.0443034
+v 0.638739 0.0376753 -0.0296341
+v 0.27618 -0.182557 -0.360388
+v 0.427113 0.204343 -0.0043674
+v 0.428937 -0.230085 -0.309893
+v 0.42954 -0.216007 -0.299128
+v 0.187638 0.0757616 -0.198575
+v 0.258646 0.247002 0.00263329
+v 0.260907 0.238216 -0.0140399
+v 0.0227554 0.0984078 -0.170277
+v 0.460022 0.0627236 -0.159834
+v 0.790223 -0.513362 0.0404498
+v 0.787475 -0.532964 0.0345924
+v 0.784893 -0.550858 0.0273348
+v 0.783261 -0.567711 0.0188184
+v 0.782324 -0.582239 0.0073732
+v 0.78109 -0.597833 -0.00241492
+v 0.471031 0.134208 -0.0826723
+v 0.661411 -0.16627 -0.146218
+v 0.592342 -0.0878747 -0.17819
+v 0.624699 -0.195904 -0.191511
+v 0.780345 -0.613825 -0.0127297
+v 0.779318 -0.629214 -0.0227233
+v 0.778483 -0.644307 -0.0332693
+v -0.228627 -0.812452 -0.290612
+v 0.658354 -0.18537 -0.151523
+v -0.0634879 0.0112396 -0.231716
+v 0.786229 -0.675778 -0.0504306
+v 0.777134 -0.660351 -0.0429547
+v 0.790814 -0.659606 -0.0439823
+v 0.511416 -0.0211691 -0.172422
+v 0.199725 0.175839 -0.100078
+v 0.19943 0.162904 -0.111728
+v 0.200213 0.150752 -0.124612
+v 0.484043 -0.281813 -0.307157
+v 0.494884 -0.286913 -0.301415
+v 0.152146 -0.917129 0.382469
+v 0.420009 -0.077881 -0.24013
+v 0.419894 -0.104291 -0.262853
+v 0.289539 -0.195852 -0.371923
+v 0.461076 0.077637 -0.150213
+v 0.664956 -0.263277 -0.197574
+v 0.662464 -0.281672 -0.204304
+v 0.156719 0.222301 -0.0469881
+v 0.417607 -0.212564 -0.302699
+v 0.41744 -0.225833 -0.314363
+v 0.213675 -0.197741 -0.396483
+v 0.633665 -0.127438 -0.162082
+v 0.630646 -0.146693 -0.16749
+v -0.599342 0.816177 -0.770821
+v -0.609387 0.818888 -0.767095
+v 0.733537 -0.911746 0.239642
+v 0.628591 0.0444319 -0.0369816
+v 0.629901 0.0341685 -0.0516895
+v 0.618418 0.0507004 -0.0435712
+v -0.260252 -0.821971 -0.281261
+v 0.619998 -0.140823 -0.173733
+v 0.681321 -0.0886582 -0.099885
+v 0.0678296 -0.190676 -0.404434
+v 0.068626 -0.202365 -0.418204
+v 0.699189 -0.2111 -0.123687
+v 0.180033 -0.0924476 -0.274697
+v 0.192378 -0.0725759 -0.269546
+v 0.0822677 -0.202339 -0.418192
+v 0.475989 -0.325821 -0.325885
+v 0.109063 -0.203046 -0.417279
+v -0.0949203 -0.205897 -0.363984
+v -0.0101927 0.201581 0.00439309
+v 0.00429675 0.204073 0.00179834
+v -0.249102 -0.812362 -0.263984
+v -0.227664 0.0490305 -0.193733
+v 0.708296 -0.0902768 -0.0462431
+v 0.662079 -0.0604371 -0.104419
+v 0.66177 -0.0481699 -0.091754
+v 0.580717 -0.0839954 -0.182339
+v 0.59062 -0.104201 -0.186527
+v 0.579188 -0.100129 -0.191035
+v 0.549528 -0.156045 -0.2339
+v 0.0179898 0.127734 -0.123777
+v 0.627422 -0.165897 -0.172538
+v 0.513574 -0.329944 -0.308146
+v 0.509579 -0.351499 -0.312038
+v 0.501757 -0.344614 -0.316071
+v 0.497697 -0.268261 -0.295056
+v 0.484197 0.107849 -0.105704
+v 0.667718 -0.218922 -0.167002
+v 0.698855 -0.225178 -0.134554
+v 0.523581 -0.0239308 -0.169481
+v 0.0534429 -0.17959 -0.390253
+v 0.0392488 -0.180643 -0.389148
+v 0.0115929 0.180014 -0.0502893
+v -0.150656 -0.901342 -0.360734
+v -0.155807 -0.925606 -0.362404
+v 0.805252 -0.484846 0.0625694
+v 0.627268 0.0547595 -0.0222609
+v 0.61712 0.0614647 -0.0296084
+v 0.615656 0.0715868 -0.0148106
+v 0.802247 -0.504461 0.0569689
+v 0.230592 -8.99171e-05 -0.23882
+v 0.7991 -0.523716 0.051227
+v 0.797558 -0.539014 0.0412848
+v 0.796402 -0.553375 0.0305975
+v 0.797198 -0.567621 0.0182532
+v 0.697468 -0.253284 -0.156289
+v 0.696812 -0.267645 -0.166899
+v -0.173598 0.100001 -0.144407
+v -0.172801 0.0880288 -0.157792
+v 0.625251 -0.182352 -0.180322
+v 0.640075 -0.0629933 -0.127579
+v 0.650968 -0.0681186 -0.122056
+v 0.651237 -0.0547467 -0.110585
+v 0.449104 0.0807969 -0.153591
+v -0.322578 -0.971528 0.514403
+v 0.659946 0.000462431 -0.0410536
+v 0.147149 0.20478 -0.0795381
+v 0.133418 0.204484 -0.0791399
+v 0.796042 -0.58301 0.00818245
+v 0.795747 -0.59678 -0.0038279
+v 0.197965 0.21029 -0.0602316
+v 0.198762 0.199282 -0.0739632
+v 0.108279 -0.191125 -0.403715
+v 0.133251 0.241504 0.0105203
+v 0.147406 0.242481 0.00917154
+v 0.107008 -0.180798 -0.388609
+v 0.0441557 0.00947983 -0.230072
+v 0.0675984 -0.178447 -0.391396
+v 0.0122223 0.169352 -0.0643678
+v 0.0127746 0.157933 -0.0779838
+v 0.0416509 -0.0211562 -0.249006
+v 0.0429483 -0.0060116 -0.239282
+v 0.502476 -0.617448 -0.311563
+v 0.429258 0.216366 0.021092
+v 0.37735 0.226308 -0.00205525
+v 0.794886 -0.611899 -0.014361
+v 0.24444 -0.153668 -0.314748
+v -0.104863 -0.264022 -0.433516
+v 0.698251 -0.238833 -0.145807
+v 0.79409 -0.62721 -0.0246244
+v 0.388834 -0.974008 -0.132114
+v 0.384402 -0.974804 -0.1567
+v 0.792754 -0.642907 -0.0347594
+v 0.629298 -0.0436997 -0.122467
+v 0.805124 -0.658476 -0.0449842
+v 0.199943 0.137817 -0.136327
+v 0.607281 -0.0211947 -0.120964
+v 0.640396 -0.0490947 -0.116687
+v 0.0380927 -0.0728328 -0.275711
+v 0.0386451 -0.0534236 -0.268377
+v 0.0509252 -0.0547081 -0.270676
+v 0.44254 0.0168273 -0.187259
+v 0.288281 -0.18555 -0.357241
+v 0.286624 -0.175826 -0.341723
+v 0.893256 -0.512656 0.0658578
+v 0.199494 0.187824 -0.0874251
+v 0.151196 0.236765 -0.0109442
+v 0.154484 0.230213 -0.0299681
+v -0.0433208 0.879428 -0.27295
+v -0.0562303 0.879402 -0.263252
+v 0.173534 -0.170881 -0.373194
+v 0.215602 0.0359411 -0.232474
+v 0.715014 -0.86472 0.380992
+v 0.578944 -0.293785 -0.257779
+v 0.0288056 -0.910911 -0.3269
+v 0.39884 -0.96797 0.408827
+v 0.385995 -0.967508 0.405821
+v 0.394678 -0.967469 0.384306
+v 0.680499 -0.103777 -0.109609
+v 0.509464 -0.272025 -0.291203
+v 0.232082 0.0829935 -0.206629
+v 0.529875 -0.115492 -0.225782
+v 0.629387 -0.0310856 -0.110303
+v -0.0286386 0.205152 0.0270907
+v -0.0438217 0.202442 0.0305461
+v 0.284902 -0.166488 -0.325949
+v 0.256399 0.254722 0.0197561
+v 0.196681 0.220245 -0.0453953
+v -0.0510023 0.113206 -0.133488
+v 0.111619 0.225807 -0.0247529
+v -0.148794 0.120938 -0.114991
+v -0.0614712 -0.97587 -0.24338
+v -0.128562 0.184638 0.0257677
+v 0.379097 0.216944 -0.017765
+v -0.14449 0.165987 -0.03404
+v -0.266122 -0.975665 0.371537
+v 0.668694 -0.19205 -0.144368
+v 0.657185 -0.199834 -0.161581
+v 0.547486 -0.0432116 -0.174439
+v 0.814745 -0.496638 0.0746569
+v 0.811893 -0.511692 0.0647788
+v 0.38078 0.207452 -0.0333592
+v 0.382077 0.197317 -0.0480286
+v 0.279828 -0.150752 -0.29128
+v 0.282629 -0.1581 -0.309173
+v 0.263181 0.22979 -0.0308416
+v 0.194908 0.229109 -0.0294414
+v -0.0140849 0.207529 0.0245345
+v 0.0528134 -0.24609 -0.450934
+v -0.0152281 -0.921213 0.374916
+v 0.536028 -0.16862 -0.246142
+v 0.532328 -0.189455 -0.250586
+v 0.811829 -0.525809 0.0532181
+v 0.812009 -0.53877 0.0403599
+v -0.0721328 -0.226077 -0.420606
+v 0.0399553 -0.037534 -0.25733
+v -0.163514 -0.929922 0.352295
+v -0.159584 -0.946686 -0.366566
+v -0.536914 -0.943115 -0.106706
+v -0.604763 0.573376 0.0693004
+v -0.602515 0.565244 0.0521391
+v -0.600588 0.556471 0.0358769
+v -0.598726 0.546773 0.0200258
+v -0.596696 0.537473 0.00404627
+v 0.506381 -0.199436 -0.265165
+v 0.811598 -0.552091 0.028234
+v 0.811238 -0.566375 0.0171356
+v 0.383297 0.18695 -0.0625181
+v -0.186199 0.0757359 -0.170521
+v 0.264864 0.220926 -0.0467697
+v 0.266636 0.211909 -0.0626851
+v 0.105775 -0.170508 -0.37385
+v 0.0253373 -0.073231 -0.273541
+v 0.0449136 0.0238409 -0.219578
+v 0.148575 0.182249 -0.10677
+v -0.112133 0.151382 -0.0699426
+v 0.18503 0.0458192 -0.21792
+v 0.184876 0.0318563 -0.228646
+v -0.162474 0.120682 -0.114657
+v 0.400985 0.144124 -0.119037
+v 0.38462 0.176893 -0.0772388
+v 0.810763 -0.580672 0.005729
+v 0.144657 -0.00576754 -0.265268
+v 0.809954 -0.595803 -0.0047913
+v 0.809222 -0.610743 -0.0155685
+v 0.447973 0.0657551 -0.163122
+v 0.386354 0.167644 -0.0928715
+v 0.205287 -0.954393 0.12424
+v -0.588873 0.565334 0.0517537
+v -0.588038 0.554583 0.0376496
+v -0.58624 0.544538 0.0220811
+v -0.584519 0.532425 0.00962113
+v -0.585752 0.51949 -0.002325
+v -0.585315 0.50712 -0.0147464
+v 0.8084 -0.625566 -0.0264613
+v 0.807012 -0.641546 -0.0361467
+v 0.267921 0.201594 -0.077303
+v 0.269205 0.190766 -0.0914842
+v 0.189873 0.245499 0.00511243
+v 0.20354 0.245782 0.00475276
+v 0.192647 0.237831 -0.0127425
+v 0.0456329 0.0384074 -0.209417
+v 0.672008 -0.912928 0.321942
+v 0.66678 -0.906814 0.338679
+v 0.18634 0.0606298 -0.20803
+v 0.401589 0.132538 -0.132319
+v 0.293098 0.260117 0.0400003
+v -0.312147 -0.946917 -0.337407
+v -0.332494 -0.954701 -0.334697
+v 0.388037 0.158164 -0.108401
+v 0.818894 -0.658142 -0.0453439
+v -0.226867 -0.821868 -0.307362
+v 0.388923 0.147169 -0.12221
+v 0.389579 0.135711 -0.135633
+v -0.561295 0.580132 0.0611179
+v -0.575309 0.565668 0.0512014
+v -0.573921 0.554943 0.036532
+v -0.573665 0.542444 0.0241235
+v -0.574358 0.528378 0.0136032
+v -0.575206 0.513838 0.00372514
+v -0.575116 0.501442 -0.00872196
+v -0.575245 0.488391 -0.0203084
+v 0.709067 -0.231344 -0.127978
+v 0.71942 -0.238088 -0.120849
+v 0.708771 -0.245486 -0.138832
+v 0.161061 0.192744 -0.0924091
+v 0.0688701 -0.215184 -0.430857
+v 0.0546632 -0.215506 -0.430626
+v 0.0468532 0.0537704 -0.200078
+v -0.162898 -0.898529 -0.363445
+v -0.182756 -0.854919 -0.353348
+v -0.0556266 0.16686 -0.0620299
+v 0.119982 0.141363 -0.139641
+v -0.066969 -0.190868 -0.353644
+v -0.0788123 -0.200605 -0.369341
+v -0.0760377 -0.208248 -0.38744
+v -0.0604307 -0.203919 -0.391743
+v -0.0733531 -0.215608 -0.405577
+v -0.609259 0.726761 -0.754019
+v 0.489823 -0.152268 -0.263406
+v 0.389771 0.123289 -0.147952
+v 0.122448 0.233605 -0.00710345
+v -0.0927238 0.0210534 -0.216148
+v -0.0803538 0.185794 -0.00285166
+v 0.458661 0.0473478 -0.168839
+v 0.116963 0.211768 -0.0609509
+v 0.11862 0.202879 -0.076969
+v -0.56028 0.56843 0.0474762
+v -0.558674 0.557242 0.0333079
+v -0.559406 0.542958 0.02325
+v -0.561243 0.527068 0.0149262
+v -0.563491 0.510228 0.0076558
+v -0.563876 0.496766 -0.00341685
+v -0.564776 0.483112 -0.0143482
+v 0.389463 0.109917 -0.15923
+v 0.169449 -0.15345 -0.340503
+v 0.0681636 -0.229558 -0.441814
+v 0.0544833 -0.229571 -0.441994
+v 0.0195827 0.118909 -0.139988
+v -0.181395 -0.83917 -0.342481
+v -0.910545 0.0296469 0.311242
+v -0.904675 0.0324087 0.333721
+v -0.914964 0.0375083 0.327324
+v -0.0583626 0.174311 -0.0440979
+v -0.106109 0.060283 -0.180297
+v 0.371428 -0.183534 -0.30776
+v 0.0184266 0.967521 -0.309212
+v -0.11591 -0.146539 -0.290342
+v 0.397234 0.174979 -0.0752221
+v -0.0917218 -0.212436 -0.383072
+v -0.0885105 -0.230971 -0.415597
+v -0.0114516 -0.0188184 -0.251382
+v 0.553793 -0.400979 -0.288698
+v -0.114265 -0.967084 0.666465
+v -0.541089 0.577088 0.0365063
+v -0.541705 0.562675 0.0267054
+v -0.54344 0.546477 0.0190753
+v -0.547023 0.527993 0.0136289
+v -0.549849 0.5101 0.00763011
+v -0.552097 0.49317 0.000449585
+v -0.553613 0.478359 -0.0087348
+v -0.555501 0.461609 -0.0162878
+v 0.420767 -0.944669 0.577923
+v -0.091208 -0.276123 -0.447132
+v -0.0897308 -0.282532 -0.45069
+v -0.562618 0.395738 -0.0479643
+v -0.341935 -0.0020424 -0.216674
+v -0.334408 -0.0396149 -0.238974
+v -0.34742 -0.0394479 -0.236443
+v 0.159545 0.11282 -0.160836
+v -0.174831 0.110418 -0.129493
+v 0.065967 -0.247041 -0.449804
+v 0.0633594 -0.265564 -0.456792
+v 0.00735393 0.107875 -0.154285
+v -0.171234 -0.873467 -0.361749
+v -0.0616895 0.181016 -0.0251126
+v 0.395757 0.0319206 -0.203328
+v 0.407601 0.0286707 -0.199577
+v 0.402321 -0.00730897 -0.21223
+v 0.0503086 0.112075 -0.159256
+v 0.120829 0.129583 -0.15291
+v 0.742632 -0.894547 0.296469
+v 0.736196 -0.890308 0.314761
+v 0.726498 -0.900558 0.298512
+v 0.0158961 -0.161928 -0.332089
+v 0.385815 -0.286129 -0.37331
+v 0.594872 -0.385924 -0.250278
+v 0.584956 -0.378949 -0.257754
+v -0.520035 0.603434 0.0318692
+v -0.523041 0.571115 0.0166732
+v -0.535064 0.511911 0.00544641
+v -0.538443 0.493054 0.000423895
+v -0.540896 0.475841 -0.00603729
+v -0.544737 0.456008 -0.00996795
+v -0.547653 0.436034 -0.014695
+v -0.557557 0.443343 -0.0225949
+v -0.549592 0.420889 -0.0232115
+v -0.549875 0.407401 -0.0345795
+v -0.550492 0.392886 -0.0448558
+v -0.5522 0.376804 -0.0534107
+v 0.799164 -0.805888 -0.0295185
+v 0.811559 -0.78594 -0.0376367
+v -0.176629 0.119782 -0.113463
+v 0.0636549 0.0993584 -0.171549
+v 0.00862562 0.0972774 -0.168954
+v -0.781103 -0.403445 -0.0853698
+v -0.00604371 0.0953763 -0.166732
+v -0.124131 -0.052473 -0.267349
+v -0.398776 -0.0216058 -0.222596
+v -0.106815 0.0457164 -0.190599
+v -0.213457 -0.960571 -0.378718
+v 0.605418 -0.403869 -0.248145
+v -0.491686 0.589792 -0.00298011
+v 0.00540145 -0.0908419 -0.27837
+v 0.0201093 -0.088928 -0.279989
+v 0.709568 -0.883782 -0.00471422
+v -0.532739 0.453028 -0.0064098
+v -0.537685 0.417755 -0.0197304
+v -0.537698 0.404511 -0.0315737
+v -0.538263 0.390561 -0.0421326
+v -0.528205 0.370805 -0.0466156
+v 0.0641045 0.125833 -0.148119
+v 0.0643999 0.113437 -0.160785
+v -0.579085 0.0301736 -0.164677
+v -0.298004 -0.942549 -0.345256
+v 0.396425 0.0457678 -0.192936
+v -0.654706 0.904335 -0.735432
+v -0.033417 -0.190804 -0.379142
+v -0.0516445 -0.10966 -0.286514
+v -0.20661 -0.939775 0.666388
+v -0.215987 -0.948266 0.649959
+v 0.823557 -0.489303 0.0933853
+v 0.82384 -0.500581 0.0792555
+v 0.825484 -0.51263 0.0656009
+v -0.00139371 -0.246142 -0.451178
+v 0.668 -0.205576 -0.155454
+v -0.525533 0.401583 -0.0283367
+v -0.525739 0.414287 -0.0160952
+v -0.526394 0.387042 -0.0384974
+v -0.529657 0.344036 -0.052974
+v 0.057836 0.165614 -0.0871168
+v 0.269526 0.254311 0.0203726
+v -0.574949 0.0723447 -0.1381
+v -0.591789 0.0666286 -0.131818
+v -0.591442 0.0824283 -0.119988
+v 0.527588 -0.363689 -0.303021
+v -0.575694 0.0578038 -0.1488
+v -0.56633 0.0305847 -0.169763
+v 0.880141 -0.512014 0.0650486
+v -0.0011625 -0.206347 -0.414569
+v -0.00311498 -0.262918 -0.459669
+v 0.825548 -0.525244 0.0526914
+v 0.825638 -0.538282 0.0402443
+v -0.368615 0.0124214 -0.206
+v 0.825368 -0.552091 0.0285423
+v 0.825715 -0.565155 0.016108
+v 0.269077 0.0186899 -0.240644
+v -0.513484 0.411525 -0.0131921
+v -0.514191 0.397202 -0.0235454
+v -0.514949 0.382482 -0.033629
+v 0.0248878 -0.0546311 -0.265577
+v 0.000109185 -0.280708 -0.469085
+v -0.0126077 -0.263637 -0.460041
+v 0.286097 0.119654 -0.169108
+v -0.0735329 -0.151947 -0.29137
+v -0.214009 0.0489791 -0.193758
+v -0.57563 0.0855368 -0.126
+v -0.591828 0.101683 -0.107477
+v -0.578931 0.101902 -0.112255
+v -0.559406 0.0764937 -0.142775
+v -0.558623 0.0908933 -0.131985
+v -0.560074 0.0618758 -0.153321
+v -0.0398268 0.159115 -0.0794353
+v 0.824931 -0.579657 0.00480414
+v 0.824148 -0.594378 -0.00624281
+v 0.823416 -0.609175 -0.0172384
+v 0.822054 -0.625142 -0.0269109
+v -0.343413 0.228492 0.00459862
+v -0.356117 0.230201 0.00269751
+v -0.0901933 -0.109712 -0.286835
+v 0.310567 0.0641366 -0.212333
+v 0.309784 0.0498526 -0.222532
+v -0.10264 -0.282789 -0.446027
+v -0.572984 -0.983963 -0.100142
+v -0.581128 -0.982909 -0.0793069
+v -0.503067 0.393195 -0.0187927
+v 0.186572 0.150727 -0.124471
+v -0.0637319 -0.19724 -0.372668
+v -0.0485873 -0.194028 -0.375905
+v -0.559162 0.103983 -0.119757
+v -0.559111 0.117868 -0.108607
+v -0.543774 0.120566 -0.111536
+v -0.543337 0.107644 -0.123906
+v -0.543542 0.0940533 -0.135582
+v -0.5443 0.0796152 -0.146321
+v 0.038735 -0.298448 -0.475302
+v 0.0259282 -0.298396 -0.475571
+v 0.879357 -0.501159 0.0793582
+v -0.0420619 0.167297 -0.062441
+v -0.122332 -0.952928 -0.357973
+v 0.820757 -0.640968 -0.036866
+v 0.824443 -0.675573 -0.0511371
+v 0.811804 -0.675547 -0.051728
+v -0.548051 -0.9184 -0.0961085
+v 0.388795 0.0958388 -0.169712
+v 0.388011 0.0815676 -0.17995
+v 0.385879 0.0645348 -0.187323
+v 0.383875 0.0476946 -0.195056
+v -0.490453 0.418924 -0.00113039
+v -0.502656 0.315493 -0.0375468
+v -0.504338 0.299925 -0.0461275
+v -0.492495 0.296238 -0.0423253
+v -0.494936 0.278319 -0.049069
+v -0.518263 0.285885 -0.0573157
+v -0.058247 -0.212243 -0.408917
+v 0.404569 -0.950565 0.57985
+v -0.541166 0.151664 -0.0928715
+v -0.52633 0.166681 -0.0827751
+v -0.541115 0.175248 -0.0842395
+v -0.527691 0.137419 -0.103469
+v -0.542412 0.135646 -0.101452
+v -0.527524 0.151318 -0.0922806
+v -0.527897 0.123983 -0.115454
+v -0.528873 0.110084 -0.126642
+v -0.528385 0.0970719 -0.138973
+v -0.528526 0.0833917 -0.150483
+v -0.529348 0.0690563 -0.161324
+v 0.720242 -0.224215 -0.109814
+v 0.709542 -0.217805 -0.11661
+v -0.044875 0.175056 -0.0445989
+v 0.132968 0.101067 -0.1739
+v 0.0783756 0.100771 -0.173193
+v 0.383631 0.0347208 -0.206347
+v 0.166764 -0.145781 -0.322764
+v -0.515899 0.45692 -0.00233784
+v -0.389964 0.667673 -0.0744513
+v 0.248293 -0.0810667 -0.262288
+v -0.115344 -0.28347 -0.439194
+v -0.115267 -0.266155 -0.427658
+v -0.489888 0.326849 -0.023828
+v -0.491185 0.312051 -0.0332565
+v -0.480382 0.293335 -0.0392167
+v -0.51315 0.165948 -0.0822613
+v -0.524274 0.183482 -0.0756588
+v -0.513382 0.152165 -0.0933596
+v -0.513626 0.138793 -0.105229
+v -0.51333 0.126295 -0.118048
+v -0.513793 0.11327 -0.130238
+v -0.513446 0.100527 -0.14284
+v -0.514281 0.0862433 -0.153758
+v -0.514807 0.0713299 -0.163945
+v -0.515283 0.0563395 -0.1739
+v -0.0471358 0.183624 -0.0277458
+v -0.0247208 0.199192 0.00694931
+v -0.168948 -0.854752 -0.353361
+v -0.0886133 -0.926801 0.202686
+v -0.101972 -0.927392 0.200502
+v -0.0939055 -0.928407 0.17986
+v 0.351891 -0.0781893 -0.240387
+v -0.478198 0.323509 -0.0200772
+v -0.479085 0.309135 -0.0301864
+v -0.511789 0.18153 -0.0733338
+v -0.498584 0.181029 -0.0730512
+v -0.499008 0.16677 -0.0831861
+v -0.499226 0.153321 -0.0947855
+v -0.498301 0.141337 -0.108273
+v -0.498173 0.129249 -0.121452
+v -0.497967 0.116905 -0.134362
+v -0.498301 0.10361 -0.146308
+v -0.499008 0.0890436 -0.156892
+v -0.499573 0.0741559 -0.16704
+v -0.500793 0.0586773 -0.176584
+v -0.00311498 0.989859 -0.257998
+v 0.0791848 0.114696 -0.162403
+v -0.181909 0.846903 -0.173823
+v -0.164632 0.839697 -0.191857
+v -0.0511949 -0.281762 -0.45895
+v 0.23961 -0.137149 -0.28022
+v -0.114471 -0.925902 0.126912
+v -0.466278 0.319925 -0.0162493
+v -0.467216 0.30559 -0.0265641
+v -0.590145 -0.963474 0.270355
+v -0.586163 -0.971862 0.255827
+v -0.484197 0.19539 -0.0625951
+v -0.144734 0.865824 -0.195685
+v -0.482412 0.211382 -0.0539503
+v -0.484634 0.181286 -0.0729613
+v -0.484865 0.167978 -0.0846505
+v -0.484557 0.15539 -0.0972261
+v -0.483709 0.143623 -0.110881
+v -0.482938 0.132063 -0.124715
+v -0.483336 0.119012 -0.136802
+v -0.483002 0.106269 -0.149391
+v -0.483747 0.091831 -0.159988
+v -0.485597 0.0756331 -0.168903
+v -0.486792 0.0601031 -0.178318
+v -0.0255557 -0.281068 -0.465706
+v 0.0783499 0.126488 -0.149134
+v 0.114908 -0.017354 -0.268248
+v 0.102319 -0.00883756 -0.26225
+v 0.0820493 -0.944155 -0.19625
+v 0.0948176 -0.944643 -0.19327
+v 0.0818181 -0.928188 -0.186925
+v 0.566086 -0.401827 -0.278178
+v 0.357196 -0.159089 -0.28234
+v 0.357941 -0.144561 -0.272089
+v 0.357979 -0.170444 -0.296058
+v 0.359199 -0.180746 -0.310753
+v 0.846036 -0.486747 0.115903
+v 0.832664 -0.485231 0.11476
+v -0.455693 0.315416 -0.0111112
+v -0.456413 0.300593 -0.0209764
+v -0.457839 0.284613 -0.0295185
+v -0.460266 0.265923 -0.0356585
+v -0.463799 0.245936 -0.0402443
+v -0.476284 0.250625 -0.0458706
+v -0.467575 0.226039 -0.0444833
+v -0.479136 0.230432 -0.0486837
+v -0.490376 0.230881 -0.0526015
+v -0.469322 0.210432 -0.0529226
+v -0.470221 0.195955 -0.0630062
+v -0.469939 0.183148 -0.0751964
+v -0.469695 0.170791 -0.0879774
+v -0.469464 0.158511 -0.100771
+v -0.468629 0.146809 -0.11449
+v -0.468436 0.134439 -0.127374
+v -0.468166 0.12194 -0.140168
+v -0.468346 0.10826 -0.151639
+v -0.469001 0.0936808 -0.162108
+v -0.473227 0.0463073 -0.189635
+v 0.540292 -0.273772 -0.279282
+v 0.729208 -0.887135 0.333888
+v 0.719484 -0.897398 0.317664
+v 0.257092 -0.24758 -0.406066
+v 0.835298 -0.493298 0.0974958
+v 0.837468 -0.50229 0.0810538
+v 0.83874 -0.512784 0.0659349
+v -0.30015 0.745156 -0.126655
+v 0.36051 -0.191048 -0.32559
+v 0.360767 -0.203431 -0.33805
+v 0.839472 -0.525052 0.0524859
+v 0.164747 -0.978298 -0.244934
+v -0.446175 0.292706 -0.0124985
+v -0.447768 0.277227 -0.0215416
+v -0.450234 0.259873 -0.0284395
+v -0.453356 0.240181 -0.0334363
+v -0.455411 0.223842 -0.0413875
+v -0.456271 0.209584 -0.0518822
+v -0.456104 0.197098 -0.0643036
+v -0.455372 0.185448 -0.0778425
+v -0.45518 0.173206 -0.0907006
+v -0.454293 0.161568 -0.104278
+v -0.45351 0.14975 -0.117946
+v -0.453201 0.137291 -0.130688
+v -0.454113 0.123251 -0.141671
+v -0.454319 0.109737 -0.153386
+v -0.455038 0.0952093 -0.163945
+v -0.455616 0.0803088 -0.173938
+v -0.460253 0.0316123 -0.199924
+v 0.360445 -0.216944 -0.349482
+v 0.839806 -0.537935 0.0398333
+v 0.839524 -0.551127 0.0276174
+v 0.360394 -0.230124 -0.361621
+v 0.839845 -0.564114 0.0150675
+v -0.435308 0.301646 0.00407196
+v -0.436066 0.286656 -0.00562624
+v -0.437993 0.270304 -0.0137188
+v -0.440151 0.253104 -0.0209121
+v -0.442116 0.236623 -0.0287863
+v -0.442283 0.222866 -0.0403728
+v -0.442206 0.210226 -0.0526272
+v -0.441448 0.198755 -0.0663845
+v -0.440677 0.18731 -0.0801418
+v -0.439984 0.176058 -0.0940404
+v -0.438596 0.165306 -0.108633
+v -0.438404 0.152987 -0.121529
+v -0.438648 0.139603 -0.133296
+v -0.438905 0.126154 -0.144998
+v -0.438994 0.112281 -0.156237
+v -0.440266 0.0969178 -0.165807
+v -0.442026 0.0806042 -0.174401
+v -0.443259 0.0649972 -0.183752
+v -0.44674 0.0321646 -0.200811
+v -0.435873 0.0155685 -0.211125
+v -0.449091 0.0153501 -0.210085
+v 0.360022 -0.267516 -0.376701
+v 0.867025 -0.511448 0.064265
+v 0.86727 -0.523728 0.0512014
+v 0.839061 -0.578527 0.00373798
+v 0.838278 -0.59317 -0.00739889
+v -0.42543 0.294132 0.0124086
+v -0.426201 0.280477 0.00131022
+v -0.427755 0.262969 -0.00574185
+v -0.429527 0.247323 -0.0146179
+v -0.430594 0.233386 -0.0248685
+v -0.429258 0.221877 -0.0392038
+v -0.428538 0.210483 -0.0530125
+v -0.426779 0.200631 -0.0686838
+v -0.426059 0.18943 -0.0825953
+v -0.424646 0.178588 -0.0971747
+v -0.423965 0.16731 -0.111035
+v -0.423888 0.155287 -0.124175
+v -0.423991 0.141658 -0.135685
+v -0.424325 0.128286 -0.147374
+v -0.424903 0.113527 -0.157702
+v -0.426714 0.0974316 -0.166565
+v -0.428436 0.0809896 -0.175043
+v -0.429605 0.0650743 -0.183855
+v -0.43139 0.0487094 -0.192435
+v -0.43261 0.0330253 -0.201684
+v -0.450285 -0.00387928 -0.218511
+v -0.0866865 -0.151189 -0.292141
+v 0.837558 -0.607891 -0.018433
+v 0.836351 -0.623549 -0.028645
+v -0.416258 0.285525 0.0220168
+v -0.416836 0.271267 0.0114965
+v -0.417761 0.256212 0.00186257
+v -0.418558 0.242339 -0.00918439
+v -0.41762 0.230958 -0.0230445
+v -0.415693 0.22162 -0.0392038
+v -0.41392 0.212127 -0.0551706
+v -0.412662 0.201877 -0.0701353
+v -0.411403 0.191523 -0.0850487
+v -0.410594 0.179924 -0.0986647
+v -0.409836 0.16844 -0.112371
+v -0.408988 0.156661 -0.126
+v -0.409283 0.143315 -0.137676
+v -0.410054 0.129159 -0.148556
+v -0.410786 0.114619 -0.158935
+v -0.412495 0.0982665 -0.167528
+v -0.415308 0.0802574 -0.174426
+v -0.416451 0.0641237 -0.182789
+v -0.418211 0.0479258 -0.19169
+v -0.419482 0.0321903 -0.200875
+v -0.421204 0.0160952 -0.209931
+v -0.0400709 0.196918 0.0102505
+v -0.0362559 0.191138 -0.00991657
+v 0.218428 -0.26487 -0.424935
+v 0.218595 -0.282828 -0.428404
+v 0.834514 -0.640711 -0.0371229
+v -0.488372 -0.820326 -0.0624025
+v -0.465944 0.608983 -0.0219141
+v -0.453702 0.628572 -0.0275917
+v 0.164439 -0.13774 -0.305744
+v 0.832138 -0.6589 -0.044509
+v -0.407446 0.277484 0.0309315
+v -0.407138 0.263675 0.0199616
+v -0.407382 0.250766 0.00773287
+v -0.40769 0.23891 -0.00427748
+v -0.404402 0.230034 -0.0222737
+v -0.40254 0.220798 -0.0383946
+v -0.400253 0.212384 -0.0554788
+v -0.398493 0.20293 -0.0714327
+v -0.397273 0.192679 -0.0864232
+v -0.395886 0.181799 -0.100951
+v -0.395706 0.169596 -0.113758
+v -0.39541 0.157021 -0.126372
+v -0.39568 0.143726 -0.138164
+v -0.395898 0.130213 -0.149738
+v -0.397196 0.115107 -0.159718
+v -0.39839 0.0993969 -0.168851
+v -0.4006 0.0819402 -0.176135
+v -0.403863 0.0630447 -0.182275
+v -0.405571 0.0462688 -0.190072
+v -0.40683 0.0305975 -0.199295
+v -0.407626 0.0157098 -0.209276
+v -0.386599 -0.895035 -0.135878
+v -0.0186449 0.0456393 -0.216983
+v -0.0183624 0.0589471 -0.205345
+v -0.0191202 0.0701482 -0.191485
+v -0.0199809 0.0820558 -0.178216
+v -0.0629612 -0.91429 0.497383
+v 0.0504371 -0.0687095 -0.276302
+v -0.398403 0.281338 0.0530639
+v -0.397234 0.269379 0.040103
+v -0.397286 0.256688 0.0276431
+v -0.397466 0.244061 0.0146308
+v -0.393985 0.236893 -0.00342969
+v -0.391146 0.229378 -0.0216186
+v -0.388358 0.221813 -0.039769
+v -0.38611 0.213322 -0.0567634
+v -0.384338 0.203842 -0.0726915
+v -0.383066 0.193656 -0.0876948
+v -0.381782 0.182904 -0.102326
+v -0.381512 0.170393 -0.114863
+v -0.381756 0.157226 -0.126719
+v -0.382051 0.144034 -0.138588
+v -0.382257 0.130521 -0.150239
+v -0.382963 0.115852 -0.160566
+v -0.384184 0.100347 -0.169956
+v -0.386509 0.0834302 -0.178164
+v -0.390247 0.063353 -0.183007
+v -0.392417 0.0451769 -0.188813
+v -0.394139 0.0289405 -0.197663
+v -0.395385 0.0135133 -0.207259
+v 0.865767 -0.501005 0.0793454
+v -0.00535007 0.917385 -0.305988
+v -0.0186835 0.917475 -0.293399
+v -0.00753377 0.935253 -0.301415
+v -0.221729 -0.964219 0.618938
+v -0.22521 -0.955202 0.632502
+v -0.388487 0.273078 0.0625181
+v -0.387523 0.26234 0.047746
+v -0.387549 0.249828 0.035209
+v -0.385173 0.240644 0.018934
+v -0.381833 0.233964 -0.000321132
+v -0.378018 0.228466 -0.020758
+v -0.374691 0.221877 -0.0399489
+v -0.371955 0.214221 -0.0580479
+v -0.370144 0.20478 -0.0739889
+v -0.368923 0.194619 -0.0889408
+v -0.368666 0.18239 -0.101709
+v -0.367883 0.170727 -0.115261
+v -0.368127 0.157419 -0.127014
+v -0.367844 0.144458 -0.13923
+v -0.368602 0.130547 -0.15038
+v -0.369322 0.116109 -0.160887
+v -0.37058 0.100656 -0.17038
+v -0.371788 0.084856 -0.179243
+v -0.375038 0.0656909 -0.184818
+v -0.379302 0.0446246 -0.188543
+v -0.380998 0.0277587 -0.196225
+v -0.38227 0.012203 -0.205705
+v -0.213251 -0.983796 -0.362225
+v 0.741476 -0.210316 -0.0727686
+v 0.849171 -0.493593 0.0975343
+v 0.85156 -0.502071 0.0804501
+v 0.85287 -0.512489 0.0653697
+v -0.375975 0.245088 0.0402829
+v -0.372815 0.237856 0.0212204
+v -0.369245 0.231575 0.00173412
+v -0.365853 0.225615 -0.0177008
+v -0.362038 0.220001 -0.0380092
+v -0.359277 0.212474 -0.0561083
+v -0.357016 0.204137 -0.0732567
+v -0.355282 0.19476 -0.0892363
+v -0.354485 0.183238 -0.102865
+v -0.354755 0.170239 -0.114734
+v -0.354485 0.157509 -0.127194
+v -0.354716 0.144163 -0.138973
+v -0.354922 0.130598 -0.150521
+v -0.355693 0.11598 -0.160823
+v -0.357414 0.100001 -0.16993
+v -0.35866 0.0841881 -0.178794
+v -0.361409 0.0658065 -0.185049
+v -0.365635 0.0447016 -0.188697
+v -0.367883 0.0271164 -0.195775
+v -0.384852 -0.968381 0.565514
+v 0.243322 0.0185358 -0.24049
+v -0.0522739 -0.9235 0.11413
+v 0.853127 -0.524563 0.0520877
+v 0.853936 -0.536818 0.0387286
+v 0.853679 -0.54992 0.0264099
+v 0.853384 -0.563369 0.0143867
+v -0.352289 0.224934 -0.0177522
+v -0.348936 0.219077 -0.0371743
+v -0.346123 0.211549 -0.0552476
+v -0.343387 0.204099 -0.0734109
+v -0.342102 0.193977 -0.0884527
+v -0.341332 0.18248 -0.102107
+v -0.341075 0.170226 -0.11485
+v -0.340818 0.157483 -0.127335
+v -0.341049 0.143996 -0.138922
+v -0.341743 0.129725 -0.149648
+v -0.342488 0.115274 -0.160219
+v -0.344222 0.0989859 -0.168839
+v -0.345969 0.082531 -0.177239
+v -0.348743 0.0642522 -0.183765
+v -0.352006 0.0447402 -0.188762
+v -0.354768 0.0265384 -0.195313
+v -0.354948 0.0125755 -0.206218
+v -0.0331344 0.185563 -0.0293644
+v -0.509181 -0.956628 -0.119204
+v -0.528488 0.474981 -0.00418757
+v -0.516041 0.47588 -0.00249199
+v 0.853191 -0.577268 0.00254337
+v 0.851984 -0.592682 -0.00786132
+v 0.851226 -0.607839 -0.0183559
+v -0.339623 0.223033 -0.0157997
+v -0.33577 0.218152 -0.0363137
+v -0.332995 0.21065 -0.0544255
+v -0.330721 0.202185 -0.0714327
+v -0.328949 0.192975 -0.0874636
+v -0.328165 0.181594 -0.101259
+v -0.327921 0.169455 -0.114105
+v -0.327613 0.156957 -0.126822
+v -0.327844 0.143405 -0.138382
+v -0.328628 0.128787 -0.148749
+v -0.329797 0.11354 -0.158472
+v -0.331492 0.0973417 -0.16722
+v -0.333329 0.0805914 -0.175094
+v -0.33559 0.0630319 -0.182108
+v -0.338313 0.0447273 -0.18862
+v -0.340574 0.0272963 -0.195994
+v -0.341345 0.0128068 -0.206552
+v -0.0301929 0.176867 -0.0469367
+v -0.0279193 0.168325 -0.0637255
+v 0.269604 -0.0911888 -0.260207
+v 0.849954 -0.623806 -0.0280156
+v -0.369617 -0.857655 -0.126809
+v -0.381692 -0.840519 -0.118742
+v -0.369309 -0.839903 -0.12126
+v -0.394717 -0.858914 -0.120707
+v -0.587473 -0.865979 -0.0499425
+v -0.459136 -0.677166 -0.0845863
+v -0.459303 -0.696215 -0.0783949
+v 0.848156 -0.640813 -0.0365449
+v 0.8619 -0.641379 -0.0340657
+v 0.850005 -0.658026 -0.0412206
+v 0.0772067 -0.316084 -0.474223
+v 0.863043 -0.624705 -0.0269237
+v -0.32647 0.22189 -0.014862
+v -0.323168 0.21557 -0.03413
+v -0.320368 0.208736 -0.0524859
+v -0.317594 0.201299 -0.0706106
+v -0.315808 0.191896 -0.0864874
+v -0.315012 0.180605 -0.100283
+v -0.314267 0.169031 -0.113874
+v -0.314459 0.15598 -0.125897
+v -0.314691 0.14239 -0.13738
+v -0.315885 0.12722 -0.147156
+v -0.317144 0.111754 -0.15661
+v -0.318441 0.0961727 -0.165858
+v -0.320638 0.0789472 -0.17345
+v -0.322449 0.0621456 -0.181273
+v -0.323605 0.0463458 -0.190187
+v -0.325892 0.0293001 -0.198177
+v -0.326624 0.0147978 -0.208723
+v -0.571943 -0.861932 -0.0540273
+v -0.574024 -0.901316 -0.0804501
+v -0.573793 -0.893056 -0.076892
+v -0.558353 -0.888946 -0.0811052
+v 0.420279 -0.0899299 -0.252962
+v -0.00120104 0.970141 -0.289302
+v -0.310554 0.213566 -0.0321261
+v -0.307266 0.207207 -0.0513298
+v -0.304954 0.198999 -0.0684141
+v -0.303117 0.190149 -0.084612
+v -0.302308 0.178845 -0.0984335
+v -0.301139 0.168119 -0.112987
+v -0.301357 0.154812 -0.124728
+v -0.302038 0.140566 -0.135531
+v -0.30322 0.125357 -0.145203
+v -0.30453 0.109712 -0.154413
+v -0.305853 0.0940276 -0.163469
+v -0.307536 0.0778425 -0.172178
+v -0.308807 0.0622612 -0.181466
+v -0.310041 0.0467697 -0.190945
+v -0.311222 0.0311627 -0.200194
+v -0.311865 0.0159539 -0.210303
+v 0.333676 -0.091754 -0.245422
+v 0.282218 -0.0549136 -0.248441
+v 0.141883 -0.0895317 -0.279244
+v 0.153816 -0.0906621 -0.280477
+v -0.542682 -0.842163 -0.0467055
+v -0.556478 -0.857745 -0.058202
+v -0.556914 -0.87199 -0.0709703
+v -0.548436 -0.90034 -0.0887353
+v -0.571853 -0.974046 -0.102223
+v 0.397838 -0.019101 -0.216379
+v -0.297915 0.211626 -0.0301864
+v -0.29469 0.205114 -0.0492874
+v -0.292353 0.197098 -0.0664487
+v -0.290516 0.18794 -0.082454
+v -0.289231 0.17774 -0.0974059
+v -0.288435 0.166308 -0.111125
+v -0.288627 0.153077 -0.122878
+v -0.289372 0.138614 -0.13345
+v -0.291004 0.122634 -0.142326
+v -0.292301 0.10704 -0.151575
+v -0.293624 0.0914842 -0.160887
+v -0.293933 0.0774571 -0.171754
+v -0.294613 0.0631732 -0.182467
+v -0.295911 0.0480029 -0.19232
+v -0.297118 0.0325371 -0.2018
+v -0.297773 0.0177137 -0.211883
+v -0.706151 0.484756 -0.371345
+v -0.540858 -0.853994 -0.0620171
+v -0.555733 -0.968805 -0.107348
+v -0.414023 0.533208 -0.0395764
+v -0.401204 0.533234 -0.0431474
+v -0.284877 0.210175 -0.029146
+v -0.282115 0.20311 -0.0472579
+v -0.279816 0.194915 -0.0643549
+v -0.278351 0.185088 -0.0794739
+v -0.277092 0.174773 -0.0942588
+v -0.276309 0.163431 -0.108016
+v -0.27609 0.150907 -0.120682
+v -0.277157 0.135878 -0.130495
+v -0.278852 0.119744 -0.139179
+v -0.279751 0.104972 -0.149185
+v -0.27997 0.0915484 -0.160964
+v -0.280291 0.0778168 -0.172307
+v -0.280509 0.0643036 -0.183829
+v -0.281729 0.0491461 -0.193656
+v -0.282475 0.0346438 -0.204112
+v -0.283721 0.0191909 -0.213643
+v -0.271261 0.00367376 -0.222994
+v -0.376682 0.667622 -0.0838027
+v -0.525996 -0.850937 -0.0650486
+v -0.00132949 0.954778 -0.300567
+v -0.65951 0.579451 -0.644757
+v -0.539689 -0.963616 -0.112461
+v -0.55247 -0.947276 -0.102878
+v 0.54019 -0.382238 -0.297587
+v -0.269539 0.201016 -0.0452411
+v -0.267561 0.192435 -0.0614647
+v -0.266289 0.182146 -0.0763524
+v -0.265467 0.170842 -0.0900841
+v -0.264748 0.159449 -0.103751
+v -0.264298 0.147284 -0.116764
+v -0.264979 0.133077 -0.127515
+v -0.265968 0.118151 -0.137483
+v -0.266778 0.103507 -0.147785
+v -0.266803 0.0907649 -0.160142
+v -0.266585 0.0781508 -0.172705
+v -0.266842 0.0649844 -0.184638
+v -0.267587 0.0502123 -0.194825
+v -0.268833 0.0348236 -0.204369
+v -0.270053 0.0193836 -0.213913
+v -0.257645 0.00376367 -0.223123
+v 0.0630383 -0.0845092 -0.284665
+v -0.494512 -0.827237 -0.0624153
+v -0.511249 -0.862639 -0.080129
+v -0.524107 -0.959505 -0.116404
+v -0.419136 -0.939338 -0.13521
+v 0.591661 -0.312899 -0.249212
+v 0.604712 -0.350111 -0.237805
+v -0.255088 0.190149 -0.0592682
+v -0.254086 0.179423 -0.0733466
+v -0.254125 0.166488 -0.0852285
+v -0.253624 0.154632 -0.0985363
+v -0.253162 0.142531 -0.111574
+v -0.252905 0.130033 -0.124227
+v -0.25365 0.11571 -0.134876
+v -0.254369 0.101401 -0.145499
+v -0.253727 0.0896345 -0.158986
+v -0.25293 0.0781508 -0.172744
+v -0.2532 0.0646504 -0.18433
+v -0.253919 0.0506105 -0.195313
+v -0.255178 0.0349264 -0.204549
+v -0.256399 0.0194606 -0.213977
+v -0.0878426 -0.70635 -0.361492
+v 0.561564 -0.317895 -0.269648
+v -0.495976 -0.843564 -0.0727301
+v -0.484364 -0.827134 -0.0681058
+v -0.512264 -0.976795 -0.125717
+v -0.16679 -0.92842 0.39638
+v -0.181241 -0.93113 0.395866
+v -0.243476 0.186295 -0.055132
+v -0.242012 0.176417 -0.0702252
+v -0.241704 0.164176 -0.0828907
+v -0.24223 0.150316 -0.0937193
+v -0.241665 0.138447 -0.107155
+v -0.241408 0.125961 -0.119834
+v -0.241601 0.11264 -0.131574
+v -0.241858 0.0990629 -0.143109
+v -0.241575 0.0866801 -0.155865
+v -0.240804 0.0753762 -0.169789
+v -0.240034 0.0639696 -0.183675
+v -0.240278 0.0503022 -0.195069
+v -0.241524 0.0349649 -0.204587
+v -0.242731 0.0194478 -0.214003
+v -0.244003 0.00380221 -0.223136
+v -0.673473 -0.598629 0.0445475
+v -0.692586 -0.593504 0.0585746
+v -0.68741 -0.58825 0.0400645
+v 0.128061 -0.0725502 -0.275737
+v -0.463079 -0.00417472 -0.216443
+v -0.476143 -0.00407196 -0.213951
+v -0.58055 0.344472 -0.0711758
+v -0.861836 0.210213 -0.0319334
+v -0.862453 0.22916 -0.0292873
+v -0.745445 0.137239 -0.0794867
+v -0.514448 -0.11476 -0.228158
+v -0.514139 -0.0967379 -0.224086
+v -0.719985 0.137599 -0.0864745
+v -0.719973 0.156391 -0.0860892
+v -0.707102 0.137779 -0.0894675
+v -0.514306 -0.0782792 -0.219809
+v -0.514306 -0.0599747 -0.216482
+v -0.707628 0.213283 -0.0934367
+v -0.720384 0.213078 -0.0915998
+v -0.720139 0.175248 -0.0864232
+v -0.720139 0.194234 -0.0894033
+v -0.707243 0.175428 -0.0891335
+v -0.538931 -0.299244 -0.247285
+v -0.539021 -0.280721 -0.247323
+v -0.526355 -0.298961 -0.251305
+v -0.719844 0.0808868 -0.0753377
+v -0.706883 0.0811694 -0.0799877
+v -0.706832 0.0623382 -0.080039
+v -0.655271 -0.210663 -0.194401
+v -0.707063 0.156597 -0.0889794
+v -0.667885 -0.192423 -0.189198
+v -0.65504 -0.192089 -0.19399
+v -0.707384 0.194375 -0.0911502
+v -0.667756 -0.210958 -0.190547
+v -0.719985 0.0434942 -0.0774315
+v -0.719549 0.0621327 -0.0716254
+v -0.423477 -0.260914 -0.258846
+v -0.516028 0.230856 -0.0628649
+v -0.719818 0.100052 -0.0814777
+v -0.70687 0.100219 -0.0843936
+v -0.668771 -0.0638154 -0.154516
+v -0.667859 -0.155736 -0.182442
+v -0.873885 0.114927 -0.00694931
+v -0.719163 -0.193771 -0.172525
+v -0.667795 -0.173977 -0.187259
+v -0.655091 -0.173656 -0.190817
+v -0.707256 0.0440337 -0.0857937
+v -0.668052 -0.13738 -0.176289
+v -0.720152 0.0254465 -0.0874123
+v -0.423529 -0.242429 -0.258871
+v -0.720294 0.00734751 -0.0958002
+v -0.707641 0.026153 -0.0945285
+v -0.719895 0.11887 -0.0847147
+v -0.706935 0.119076 -0.0875279
+v -0.668283 -0.100527 -0.170008
+v -0.668643 -0.0820815 -0.162506
+v -0.668835 -0.0456393 -0.146449
+v -0.668912 -0.0274247 -0.138408
+v -0.334087 -0.149442 -0.257433
+v -0.599085 -0.920507 -0.0789472
+v -0.599586 -0.902331 -0.0720493
+v -0.58669 -0.901868 -0.0768149
+v -0.515488 0.193758 -0.0716896
+v -0.58642 -0.919762 -0.0826081
+v -0.795863 0.0408866 -0.0214131
+v -0.668912 -0.0092743 -0.130213
+v -0.656003 -0.00892748 -0.136687
+v -0.655836 0.00914585 -0.12975
+v -0.720024 -0.0111112 -0.10352
+v -0.707346 0.00772002 -0.103816
+v -0.707102 -0.0107001 -0.1116
+v -0.783608 0.0605399 -0.0410793
+v -0.720088 -0.0293001 -0.111805
+v -0.668232 -0.118999 -0.173296
+v -0.308088 -0.222159 -0.277484
+v -0.308204 -0.203791 -0.27462
+v -0.719125 -0.212243 -0.174105
+v -0.478609 0.570819 -0.0151318
+v -0.465764 0.570986 -0.023751
+v -0.465481 0.552014 -0.0235454
+v -0.719022 -0.249147 -0.178922
+v -0.718868 -0.230727 -0.176867
+v -0.551301 -0.429598 -0.218177
+v -0.538314 -0.428969 -0.222506
+v -0.551609 -0.373567 -0.234478
+v -0.551699 -0.354928 -0.239424
+v -0.590171 -0.319552 -0.22582
+v -0.603209 -0.319578 -0.226501
+v -0.668771 0.00886326 -0.123456
+v -0.668823 0.0271421 -0.115364
+v -0.65608 0.0276045 -0.121966
+v -0.668784 0.0452668 -0.105537
+v -0.707371 -0.0287092 -0.118613
+v -0.706935 -0.0471936 -0.127669
+v -0.784058 0.0795381 -0.0503536
+v -0.784045 0.0986262 -0.0572386
+v -0.707346 -0.0651 -0.134837
+v -0.334344 -0.0760313 -0.248839
+v -0.32146 -0.0760313 -0.246116
+v -0.321383 -0.094323 -0.25065
+v -0.55125 -0.410677 -0.224189
+v -0.538404 -0.410369 -0.227542
+v -0.734077 0.381826 -0.0666286
+v -0.551417 -0.392141 -0.229327
+v -0.538635 -0.391756 -0.234388
+v -0.551699 -0.336547 -0.240811
+v -0.551866 -0.318281 -0.241003
+v -0.539072 -0.317767 -0.247709
+v 0.347189 -0.975677 0.00570331
+v 0.343721 -0.974431 -0.0201671
+v -0.669079 0.0635714 -0.0948497
+v -0.707307 -0.0832504 -0.143007
+v -0.719767 -0.0839312 -0.137458
+v -0.783672 0.11774 -0.0632117
+v -0.784032 0.136404 -0.0654596
+v -0.784083 0.155248 -0.0654083
+v -0.706986 -0.101671 -0.150701
+v -0.668399 0.0816447 -0.0897629
+v 0.514589 -0.363239 -0.309353
+v -0.524351 -0.585938 -0.0815676
+v -0.52421 -0.606388 -0.0588828
+v -0.513394 -0.298666 -0.254465
+v -0.526176 -0.317369 -0.252551
+v -0.513253 -0.317189 -0.254131
+v -0.650865 -0.940764 -0.0611179
+v -0.422321 -0.486143 -0.181157
+v -0.435231 -0.485745 -0.182108
+v -0.422475 -0.467235 -0.193168
+v -0.551725 -0.299771 -0.240605
+v -0.0787224 -0.984785 -0.310843
+v -0.820603 0.0780223 0.638398
+v -0.668617 0.119397 -0.0925632
+v -0.706819 -0.120039 -0.156957
+v -0.783916 0.174259 -0.0682214
+v -0.706678 -0.13828 -0.163315
+v -0.719639 -0.138704 -0.156905
+v -0.784238 0.193013 -0.0688508
+v -0.746357 0.250226 -0.0825824
+v -0.668514 0.100437 -0.0895831
+v 0.887822 -0.677268 -0.0252795
+v -0.478481 0.551885 -0.0151189
+v -0.332712 -0.428159 -0.22302
+v -0.319996 -0.409187 -0.228942
+v -0.478918 0.589856 -0.0136674
+v -0.46597 0.589985 -0.0238794
+v -0.51631 0.250059 -0.0607197
+v -0.50299 0.231228 -0.0583305
+v -0.503259 0.249995 -0.0561982
+v -0.551956 -0.281363 -0.239385
+v -0.117734 -0.984322 -0.318936
+v -0.668681 0.138215 -0.0953763
+v -0.706267 -0.17494 -0.175634
+v -0.719382 -0.175236 -0.169584
+v -0.706639 -0.156507 -0.169828
+v -0.719279 -0.157021 -0.164458
+v -0.784212 0.211973 -0.0704436
+v -0.784905 0.23074 -0.0681315
+v -0.706125 -0.193373 -0.178652
+v -0.668848 0.156931 -0.0945671
+v -0.668912 0.175749 -0.0941689
+v 0.87576 -0.695342 -0.0297882
+v 0.875465 -0.676755 -0.0327298
+v 0.875491 -0.658591 -0.032717
+v -0.536066 -0.626684 -0.0231858
+v -0.53703 -0.606427 -0.0551834
+v -0.450375 -0.0586645 -0.228813
+v -0.463131 -0.0589728 -0.226848
+v -0.450183 -0.0406682 -0.224895
+v -0.463067 -0.0408224 -0.223251
+v -0.463054 -0.0224279 -0.22144
+v -0.450208 -0.0222866 -0.223084
+v -0.490504 0.268608 -0.0494929
+v -0.551943 -0.26293 -0.237702
+v -0.539355 -0.262262 -0.246283
+v -0.552123 -0.2446 -0.234722
+v -0.539496 -0.225563 -0.241492
+v -0.524737 -0.523549 -0.165884
+v -0.525007 -0.504872 -0.181234
+v -0.511994 -0.523048 -0.16722
+v -0.706164 -0.211819 -0.180399
+v -0.78479 0.249443 -0.0645733
+v -0.785034 0.268133 -0.0581635
+v -0.669028 0.194568 -0.0938863
+v 0.862645 -0.713081 -0.0343612
+v 0.862401 -0.694391 -0.0390369
+v 0.862555 -0.676228 -0.0392552
+v 0.862722 -0.65827 -0.0377266
+v -0.423619 -0.224073 -0.25697
+v -0.435346 -0.466811 -0.19417
+v -0.667037 -0.395455 -0.193258
+v -0.653768 -0.413297 -0.194221
+v -0.706138 -0.23029 -0.182069
+v -0.706215 -0.248711 -0.18397
+v -0.78506 0.286925 -0.0563652
+v -0.785304 0.305667 -0.0532309
+v -0.718906 -0.286142 -0.182095
+v -0.706125 -0.285705 -0.187182
+v 0.836993 -0.749292 -0.0375211
+v 0.850031 -0.73127 -0.036365
+v 0.849697 -0.712285 -0.0425051
+v 0.849569 -0.693839 -0.0455494
+v 0.850005 -0.675817 -0.0447659
+v -0.811213 0.342764 -0.0308287
+v -0.551776 -0.226283 -0.232307
+v 0.61942 -0.821945 -0.0611051
+v 0.606921 -0.841547 -0.0568404
+v 0.607088 -0.822908 -0.0641366
+v 0.231055 -0.0909832 -0.266668
+v 0.230811 -0.0729484 -0.262622
+v -0.669195 0.213489 -0.0949267
+v -0.705868 -0.267234 -0.186514
+v -0.785201 0.324447 -0.047746
+v 0.169898 -0.97632 -0.221569
+v 0.155948 -0.9779 -0.22284
+v -0.785342 0.343252 -0.046166
+v -0.691148 -0.51421 -0.0662689
+v 0.743608 -0.843281 0.391114
+v 0.740088 -0.83366 0.404948
+v 0.837199 -0.730653 -0.0430703
+v 0.837045 -0.711938 -0.0478616
+v 0.837109 -0.69362 -0.0497113
+v 0.837314 -0.675586 -0.0485167
+v -0.463015 -0.0770461 -0.234658
+v -0.462989 -0.0949524 -0.244407
+v -0.450054 -0.0769305 -0.237638
+v -0.449939 -0.0948882 -0.247285
+v -0.551095 -0.207657 -0.230239
+v -0.538777 -0.206989 -0.242288
+v -0.666523 -0.413798 -0.187529
+v -0.669246 0.232243 -0.0973545
+v -0.718804 -0.32329 -0.183534
+v -0.705804 -0.322738 -0.189815
+v -0.785419 0.362186 -0.0479387
+v -0.113148 -0.764372 -0.322186
+v 0.824623 -0.768085 -0.0365192
+v 0.824096 -0.748727 -0.0439181
+v 0.824174 -0.729973 -0.0492746
+v 0.824263 -0.711565 -0.0527685
+v 0.824495 -0.693376 -0.0534878
+v 0.0802895 -0.930642 -0.312179
+v 0.0931477 -0.930732 -0.310638
+v -0.484313 -0.844989 -0.0792683
+v -0.4499 -0.112987 -0.255416
+v -0.463002 -0.112974 -0.252718
+v -0.484313 -0.897732 -0.111844
+v -0.551738 -0.189147 -0.231074
+v -0.539496 -0.188492 -0.24144
+v -0.669298 0.250882 -0.0958388
+v -0.705573 -0.340978 -0.189507
+v -0.7061 -0.304215 -0.188749
+v -0.785496 0.381056 -0.0479258
+v -0.728926 0.494223 -0.316405
+v 0.811855 -0.767481 -0.0434685
+v 0.811572 -0.748367 -0.0496985
+v 0.811495 -0.729651 -0.0546054
+v 0.811611 -0.711385 -0.0565322
+v 0.811637 -0.693376 -0.0560183
+v -0.334164 -0.112692 -0.255287
+v -0.334241 -0.094323 -0.253386
+v -0.43473 -0.543574 -0.150316
+v -0.421782 -0.543035 -0.154914
+v -0.421512 -0.561815 -0.148286
+v -0.434833 -0.523767 -0.164086
+v -0.422026 -0.52405 -0.164792
+v -0.434075 -0.600582 -0.123816
+v -0.434267 -0.582008 -0.127246
+v -0.421422 -0.599978 -0.132229
+v -0.540138 -0.169905 -0.239244
+v -0.55229 -0.170804 -0.229867
+v -0.540357 -0.151742 -0.231781
+v -0.434088 -0.562226 -0.13968
+v -0.421679 -0.581263 -0.137368
+v -0.553074 -0.152499 -0.223354
+v -0.552804 -0.134131 -0.22144
+v -0.669324 0.269507 -0.0926146
+v -0.669401 0.288261 -0.0896345
+v 0.798971 -0.78567 -0.0431987
+v 0.798727 -0.766607 -0.0495957
+v 0.79856 -0.747673 -0.0560312
+v 0.798663 -0.729266 -0.059448
+v 0.798971 -0.711308 -0.058703
+v 0.798971 -0.693299 -0.0569817
+v 0.799048 -0.675624 -0.0518693
+v -0.435077 -0.504563 -0.175492
+v -0.422116 -0.504666 -0.173733
+v -0.334986 -0.260169 -0.267336
+v -0.552971 -0.0240721 -0.198331
+v -0.553253 -0.00567762 -0.190714
+v -0.540421 -0.00534364 -0.195711
+v -0.552714 -0.115633 -0.221222
+v -0.53992 -0.115376 -0.223123
+v -0.540036 -0.023828 -0.203033
+v -0.58046 0.325603 -0.0724089
+v -0.58019 0.306887 -0.0746697
+v -0.593433 0.344537 -0.0754661
+v -0.669452 0.307105 -0.0880545
+v -0.66958 0.325949 -0.0867186
+v -0.705316 -0.359322 -0.187477
+v -0.704956 -0.377986 -0.178986
+v -0.74452 -0.287118 -0.170303
+v -0.744828 -0.250059 -0.167541
+v -0.525225 -0.466683 -0.206116
+v 0.091542 -0.917938 -0.17038
+v 0.0781572 -0.918503 -0.172551
+v 0.786151 -0.825593 -0.0151831
+v 0.786177 -0.804745 -0.0376624
+v 0.786139 -0.785105 -0.0481956
+v 0.785972 -0.766145 -0.0547595
+v 0.785946 -0.747404 -0.0613106
+v 0.785997 -0.729163 -0.0628906
+v 0.786113 -0.711244 -0.0614904
+v 0.786203 -0.693492 -0.0569689
+v 0.243926 -0.916371 -0.0213489
+v -0.540395 0.0128453 -0.189006
+v -0.47446 -0.353194 -0.257176
+v -0.474525 -0.33498 -0.25715
+v -0.461679 -0.334941 -0.257433
+v -0.592342 0.194516 -0.0921008
+v -0.579625 0.194414 -0.0903024
+v -0.579381 0.175698 -0.0920494
+v -0.553163 0.0124985 -0.183958
+v -0.591905 0.156905 -0.0932697
+v -0.592149 0.175801 -0.0935009
+v -0.579098 0.156918 -0.0937835
+v -0.591648 0.138036 -0.0938349
+v -0.578828 0.138074 -0.0957874
+v -0.0652991 -0.984245 -0.308724
+v -0.0524795 -0.984746 -0.305731
+v -0.733165 0.0430317 -0.0680801
+v -0.732959 0.0249456 -0.079127
+v -0.669632 0.344781 -0.0851258
+v -0.704918 -0.39701 -0.169417
+v -0.704674 -0.415687 -0.160733
+v -0.651867 -0.551243 -0.0543228
+v -0.745072 0.0612721 -0.0583562
+v -0.707744 0.269225 -0.0866415
+v -0.602502 -0.411717 -0.212333
+v -0.589606 -0.430009 -0.210753
+v -0.74312 -0.457871 -0.0942973
+v -0.729375 -0.455391 -0.104882
+v 0.773435 -0.824822 -0.0236996
+v 0.773627 -0.804758 -0.0416188
+v 0.773576 -0.785079 -0.0522418
+v 0.773268 -0.76558 -0.0615804
+v 0.773152 -0.747044 -0.0657808
+v 0.773216 -0.729086 -0.0658322
+v 0.773345 -0.71127 -0.0630319
+v 0.773409 -0.693479 -0.0571873
+v 0.773409 -0.676009 -0.0500967
+v -0.578482 -0.17178 -0.21327
+v -0.578327 -0.189905 -0.219603
+v -0.578058 -0.153488 -0.212102
+v -0.512945 -0.353567 -0.253476
+v -0.512881 -0.372038 -0.250316
+v -0.614153 -0.589586 -0.0449072
+v -0.601796 -0.588726 -0.0527299
+v -0.66565 -0.470716 -0.149327
+v -0.653036 -0.470087 -0.159346
+v -0.652689 -0.489984 -0.134619
+v -0.704854 -0.496201 -0.0768791
+v -0.478275 0.5329 -0.0151318
+v -0.465571 0.532913 -0.0206295
+v -0.308602 -0.0761598 -0.244215
+v -0.332263 -0.520736 -0.199012
+v -0.319585 -0.501956 -0.205512
+v -0.716479 -0.454659 -0.1195
+v -0.703749 -0.453542 -0.134233
+v -0.702888 -0.472296 -0.115723
+v -0.717904 -0.476021 -0.0942845
+v -0.308538 -0.0943487 -0.249057
+v -0.332366 -0.502046 -0.20758
+v -0.319675 -0.483536 -0.210984
+v -0.318339 -0.746787 -0.123186
+v -0.478044 0.513902 -0.0132563
+v -0.465327 0.513863 -0.0170842
+v -0.318917 -0.653646 -0.136186
+v -0.318287 -0.76522 -0.121568
+v -0.745509 0.15607 -0.0794739
+v -0.318416 -0.728457 -0.123199
+v -0.664417 -0.509303 -0.104368
+v -0.66547 -0.490896 -0.123238
+v -0.65247 -0.50956 -0.113244
+v -0.663813 -0.941984 -0.0495443
+v -0.602361 -0.468532 -0.188145
+v -0.602322 -0.449072 -0.2009
+v -0.5894 -0.46789 -0.192731
+v -0.654333 -0.339167 -0.21101
+v -0.630145 -0.0083366 -0.149378
+v -0.308473 -0.112628 -0.253759
+v 0.761309 -0.847507 -0.000642265
+v 0.760795 -0.824527 -0.0308416
+v 0.760782 -0.804398 -0.0448558
+v 0.760833 -0.784873 -0.0559541
+v 0.760499 -0.765182 -0.0660634
+v 0.760512 -0.74707 -0.067836
+v 0.760576 -0.729073 -0.067592
+v 0.760602 -0.711385 -0.064188
+v 0.760602 -0.693685 -0.0569047
+v 0.760589 -0.676343 -0.0481699
+v -0.678007 -0.513131 -0.0742201
+v -0.422642 -0.447415 -0.20889
+v -0.52552 -0.447761 -0.218254
+v -0.52543 -0.428648 -0.225807
+v -0.512482 -0.447248 -0.219025
+v -0.525803 -0.410407 -0.229879
+v -0.512804 -0.410009 -0.23286
+v -0.512585 -0.428429 -0.227323
+v -0.602798 -0.374595 -0.222622
+v -0.360201 -0.0397947 -0.234491
+v -0.541538 0.25047 -0.0700069
+v -0.529079 0.250214 -0.0657551
+v -0.524634 -0.566555 -0.101606
+v -0.511519 -0.586002 -0.0834174
+v -0.527165 -0.0967636 -0.221594
+v -0.703929 -0.434248 -0.15056
+v -0.321524 -0.0577653 -0.243984
+v -0.514396 -0.0416059 -0.213283
+v -0.514229 -0.0233913 -0.210856
+v -0.732253 0.0616317 -0.0649587
+v -0.527332 -0.00520235 -0.201633
+v -0.514345 -0.00506105 -0.20618
+v -0.526754 -0.206321 -0.251434
+v -0.527139 -0.187721 -0.250496
+v -0.514525 -0.168967 -0.24961
+v -0.527242 -0.169352 -0.245808
+v -0.514705 -0.150675 -0.241684
+v -0.695271 0.363445 -0.0772259
+v 0.747307 -0.843692 -0.0175981
+v 0.748001 -0.824386 -0.0344511
+v 0.747988 -0.804334 -0.0466541
+v 0.747834 -0.783974 -0.0598206
+v 0.74786 -0.765387 -0.0666286
+v 0.747834 -0.747172 -0.068337
+v 0.747847 -0.729215 -0.0677333
+v 0.74786 -0.711398 -0.0633659
+v 0.747834 -0.694044 -0.0563395
+v 0.747487 -0.676677 -0.0472322
+v -0.694911 0.269366 -0.0897244
+v -0.694821 0.250715 -0.0944772
+v -0.694963 0.288107 -0.0864617
+v -0.514422 -0.132897 -0.234517
+v 0.0894482 -0.018099 -0.263945
+v -0.490851 0.249764 -0.0519978
+v -0.694616 0.194478 -0.0927045
+v -0.759408 -0.547402 0.129648
+v -0.745933 0.193861 -0.0836229
+v -0.746074 0.212731 -0.0854341
+v -0.733023 0.19408 -0.0863718
+v -0.321601 -0.0395121 -0.239115
+v -0.47527 -0.205422 -0.260747
+v -0.462309 -0.205448 -0.260361
+v -0.462167 -0.223778 -0.262519
+v -0.512161 -0.504717 -0.181144
+v -0.527293 0.0129481 -0.195004
+v -0.514384 0.0131664 -0.199693
+v -0.311993 0.648932 -0.12433
+v -0.689336 -0.975639 0.1237
+v -0.553549 0.138742 -0.0973417
+v -0.695284 0.344537 -0.0791399
+v -0.695117 0.306977 -0.0852799
+v -0.695155 0.325757 -0.0836486
+v 0.734899 -0.843564 -0.0268595
+v 0.734886 -0.823371 -0.0386387
+v 0.735207 -0.804334 -0.0485424
+v 0.734141 -0.78355 -0.0611565
+v 0.735104 -0.765477 -0.0664873
+v 0.735143 -0.747314 -0.0681443
+v 0.735079 -0.729292 -0.0667699
+v 0.735066 -0.711707 -0.0626722
+v 0.734783 -0.69407 -0.054721
+v -0.694385 0.137946 -0.0913943
+v -0.385558 -0.112743 -0.257009
+v -0.398429 -0.112666 -0.257381
+v -0.385622 -0.0945029 -0.253438
+v -0.694487 0.175557 -0.0910989
+v -0.694385 0.1567 -0.0909832
+v 0.140958 -0.072486 -0.274594
+v -0.694847 0.232115 -0.0965067
+v -0.694847 0.213399 -0.0950552
+v -0.435475 -0.447389 -0.210676
+v -0.43559 -0.428326 -0.220271
+v -0.422707 -0.428545 -0.217086
+v -0.746228 0.231524 -0.085524
+v -0.733267 0.212898 -0.0886197
+v -0.422835 -0.390818 -0.239244
+v -0.435706 -0.39069 -0.240618
+v -0.422964 -0.371704 -0.248582
+v -0.745689 0.174966 -0.0814649
+v -0.733036 0.175094 -0.0835073
+v -0.592701 0.250894 -0.0863332
+v -0.579959 0.250792 -0.0829421
+v -0.579895 0.231922 -0.0842395
+v -0.580151 0.269469 -0.082454
+v -0.746588 0.306489 -0.0729998
+v -0.512996 -0.335262 -0.255069
+v 0.179404 -0.0358898 -0.264857
+v -0.731341 -0.323714 -0.178062
+v -0.869261 -0.415186 0.244652
+v 0.106019 -0.930899 -0.309276
+v 0.107868 -0.95384 -0.302545
+v -0.676838 -0.943937 -0.0323316
+v -0.664802 -0.960571 -0.0520363
+v -0.578867 -0.0788187 -0.21205
+v -0.796402 0.0604243 -0.0340143
+v -0.796543 0.0793582 -0.0429418
+v -0.796967 0.0981381 -0.0487222
+v 0.721951 -0.842664 -0.0333335
+v 0.722272 -0.823512 -0.0426335
+v 0.722246 -0.803666 -0.0532052
+v 0.722375 -0.784231 -0.0619657
+v 0.722375 -0.765605 -0.0661019
+v 0.722362 -0.747404 -0.0677204
+v 0.722298 -0.729536 -0.0659863
+v 0.722015 -0.711655 -0.0603087
+v 0.721758 -0.694031 -0.0533208
+v -0.796518 0.117329 -0.0549008
+v -0.79662 0.136122 -0.0584589
+v -0.796813 0.154953 -0.0585746
+v -0.797147 0.173771 -0.0591398
+v -0.694064 0.0812979 -0.0831861
+v -0.694243 0.119166 -0.0894932
+v -0.694076 0.100309 -0.0859736
+v -0.678123 -0.49078 -0.114644
+v -0.678855 -0.472437 -0.135145
+v -0.577904 -0.208312 -0.22356
+v -0.577904 -0.226848 -0.223868
+v -0.5787 0.119615 -0.101362
+v -0.591597 0.119551 -0.0980738
+v -0.580087 0.288223 -0.0795766
+v -0.592701 0.23205 -0.0874251
+v -0.579625 0.213245 -0.0864874
+v -0.592586 0.213245 -0.0901483
+v 0.182705 -0.976808 -0.21855
+v 0.176796 -0.971233 -0.200746
+v -0.435655 -0.409649 -0.227002
+v -0.630107 0.119307 -0.0940147
+v -0.630325 0.138203 -0.0941689
+v -0.630441 0.157085 -0.0954663
+v -0.435822 -0.371679 -0.250393
+v -0.435873 -0.353271 -0.256199
+v -0.423079 -0.352963 -0.254825
+v 0.121587 -0.916358 0.00186257
+v -0.677069 -0.928792 0.000488121
+v -0.661835 -0.925195 -0.0397819
+v -0.578546 -0.097393 -0.216366
+v -0.57888 -0.0606298 -0.203803
+v -0.578263 -0.134709 -0.215801
+v -0.732728 0.156237 -0.0827751
+v -0.797031 0.192641 -0.060617
+v -0.694603 0.0445732 -0.0926531
+v -0.694141 0.0626465 -0.0852799
+v 0.709478 -0.863024 -0.0236097
+v 0.709439 -0.842806 -0.0373798
+v 0.709439 -0.822985 -0.0476817
+v 0.709401 -0.803332 -0.0562496
+v 0.709542 -0.784051 -0.0627878
+v 0.709529 -0.765875 -0.0649587
+v 0.709439 -0.747583 -0.0663717
+v 0.709182 -0.729523 -0.0643806
+v 0.70899 -0.711732 -0.0586002
+v 0.706356 -0.693209 -0.0536548
+v 0.709311 -0.675958 -0.0519721
+v -0.112621 -0.890179 -0.355866
+v -0.797224 0.211524 -0.0609509
+v -0.694487 -0.0465385 -0.133206
+v -0.694552 -0.0282853 -0.125229
+v -0.797828 0.230406 -0.0582534
+v -0.679009 -0.45272 -0.154709
+v -0.67915 -0.433375 -0.169417
+v -0.666048 -0.451345 -0.169224
+v -0.666587 -0.432771 -0.179603
+v -0.577659 -0.263919 -0.224883
+v -0.861553 0.153386 -0.0283239
+v -0.539907 -0.0969306 -0.221286
+v -0.553215 0.030636 -0.175801
+v -0.540318 0.0308929 -0.180618
+v -0.552829 -0.0970462 -0.220001
+v -0.552894 -0.078549 -0.216906
+v -0.552868 -0.0603729 -0.211459
+v -0.553151 -0.0420298 -0.203881
+v 0.131799 -0.950192 -0.301351
+v -0.579278 0.0121388 -0.173219
+v -0.57915 -0.00619143 -0.181093
+v -0.578751 -0.0245987 -0.188543
+v -0.579124 -0.0425051 -0.194221
+v -0.55432 0.212885 -0.0806942
+v -0.554499 0.231691 -0.0772259
+v -0.578379 -0.116006 -0.217702
+v -0.577672 -0.245397 -0.224703
+v -0.679613 -0.395841 -0.18618
+v -0.577634 -0.282365 -0.226475
+v -0.679266 -0.414428 -0.179282
+v -0.797687 0.249019 -0.0543741
+v 0.696748 -0.882999 -0.0114452
+v 0.696723 -0.862485 -0.028645
+v 0.696671 -0.842587 -0.040848
+v 0.696633 -0.822754 -0.0511885
+v 0.696594 -0.802985 -0.0590113
+v 0.696697 -0.784103 -0.0623511
+v 0.696658 -0.765914 -0.0648045
+v 0.69644 -0.747558 -0.0658707
+v 0.696093 -0.729536 -0.0629291
+v 0.695027 -0.71118 -0.0598077
+v -0.797789 0.267747 -0.0493773
+v -0.797725 0.28654 -0.0473863
+v -0.694706 -0.00999364 -0.117278
+v -0.679548 -0.376932 -0.194028
+v -0.679869 -0.358397 -0.199449
+v -0.680268 -0.340156 -0.200091
+v -0.66714 -0.33963 -0.206103
+v -0.577505 -0.300811 -0.227927
+v -0.577544 -0.31936 -0.22812
+v 0.198286 -0.95122 0.143379
+v 0.191183 -0.940237 0.13196
+v -0.434332 -0.619323 -0.121041
+v -0.421371 -0.618373 -0.130624
+v -0.39744 -0.33471 -0.257484
+v -0.397517 -0.3162 -0.260348
+v -0.384685 -0.316367 -0.259591
+v -0.384543 -0.353169 -0.250175
+v -0.397401 -0.353066 -0.251627
+v -0.384607 -0.334479 -0.256649
+v -0.397684 -0.297715 -0.261261
+v -0.3848 -0.297536 -0.262673
+v -0.397812 -0.279128 -0.261851
+v -0.384929 -0.278961 -0.263097
+v -0.554101 0.19417 -0.0841752
+v -0.554602 0.250573 -0.0755946
+v -0.554564 0.269379 -0.0744899
+v -0.54168 0.269289 -0.0699812
+v -0.554731 0.288056 -0.0726787
+v -0.542039 0.287825 -0.0676947
+v -0.554769 0.306707 -0.0680672
+v -0.541898 0.306656 -0.0635585
+v -0.555129 0.325397 -0.0657808
+v -0.542039 0.325448 -0.0602958
+v -0.576503 -0.411371 -0.217895
+v -0.57703 -0.374068 -0.227298
+v -0.577043 -0.392604 -0.224279
+v -0.680383 -0.321839 -0.200245
+v -0.680499 -0.248043 -0.192166
+v -0.694487 -0.0646632 -0.141414
+v -0.797995 0.30541 -0.0460375
+v -0.694346 -0.0829036 -0.149519
+v 0.68425 -0.883371 -0.0155557
+v 0.684031 -0.862613 -0.0307773
+v 0.683993 -0.842664 -0.0430446
+v 0.683852 -0.822125 -0.0558385
+v 0.6838 -0.80296 -0.0605142
+v 0.6838 -0.784282 -0.062775
+v 0.683723 -0.765978 -0.0648559
+v 0.683184 -0.747327 -0.0653826
+v 0.68249 -0.728868 -0.0648302
+v -0.694642 0.0264613 -0.102441
+v -0.694449 0.00811823 -0.110392
+v -0.680319 -0.284909 -0.196751
+v -0.680281 -0.266489 -0.194915
+v -0.590274 -0.337793 -0.226463
+v -0.57739 -0.337485 -0.229494
+v -0.860731 0.115646 -0.0167631
+v -0.861194 0.134439 -0.024329
+v -0.306855 -0.483715 -0.207657
+v -0.321165 -0.222314 -0.275262
+v -0.333881 -0.222558 -0.273001
+v -0.484403 -0.880018 -0.102223
+v -0.484403 -0.862433 -0.0908548
+v -0.758097 -0.176803 -0.146758
+v -0.501769 0.0136417 -0.202005
+v -0.501718 -0.00459862 -0.208569
+v -0.501564 -0.0230958 -0.213116
+v -0.501435 -0.0599233 -0.217856
+v -0.501551 -0.041516 -0.21485
+v -0.501577 -0.0779324 -0.223303
+v -0.501487 -0.0962241 -0.229378
+v -0.501667 -0.11422 -0.236225
+v -0.501551 -0.132371 -0.242545
+v -0.501551 -0.16871 -0.252885
+v -0.501435 -0.150662 -0.247336
+v -0.514371 -0.187284 -0.254375
+v -0.50123 -0.187156 -0.257253
+v -0.514088 -0.205769 -0.257086
+v -0.500934 -0.223958 -0.261607
+v -0.513844 -0.224266 -0.258229
+v -0.50132 -0.205525 -0.259501
+v -0.55491 0.344331 -0.0633915
+v -0.576837 -0.430061 -0.2111
+v -0.680704 -0.211061 -0.18925
+v -0.680794 -0.229597 -0.189532
+v -0.693999 -0.101349 -0.157021
+v -0.798149 0.32419 -0.0409893
+v -0.798149 0.342995 -0.039191
+v 0.671263 -0.882292 -0.0200387
+v 0.671199 -0.862022 -0.0338474
+v 0.671135 -0.841894 -0.0475661
+v 0.671096 -0.822176 -0.0578681
+v 0.67107 -0.803216 -0.0610023
+v 0.670942 -0.78418 -0.064265
+v 0.670505 -0.765374 -0.066346
+v 0.669914 -0.746903 -0.0669497
+v -0.680152 -0.303303 -0.199706
+v -0.577107 -0.355686 -0.22889
+v -0.616928 -0.190419 -0.212936
+v -0.33401 -0.185782 -0.26839
+v -0.44841 -0.409868 -0.229263
+v -0.448577 -0.390587 -0.242211
+v -0.46141 -0.390446 -0.243598
+v -0.461487 -0.371525 -0.253463
+v -0.448628 -0.371627 -0.251961
+v -0.462887 -0.149571 -0.262828
+v -0.462758 -0.131382 -0.258717
+v -0.449887 -0.13115 -0.260541
+v -0.612278 -0.920841 -0.0735393
+v -0.350786 0.687018 -0.101439
+v -0.716838 -0.572836 0.0565707
+v -0.725997 -0.567402 0.0535906
+v -0.484518 -0.62292 -0.076057
+v -0.484287 -0.603973 -0.0788573
+v -0.48403 -0.585463 -0.0955048
+v -0.422835 -0.409688 -0.225242
+v -0.680948 -0.192512 -0.187888
+v -0.576632 -0.448468 -0.205563
+v 0.566317 -0.419849 -0.279989
+v 0.658623 -0.882947 -0.0226976
+v 0.658418 -0.862112 -0.0358898
+v 0.658289 -0.841752 -0.0491333
+v 0.658212 -0.822189 -0.0575341
+v 0.658187 -0.803281 -0.061028
+v 0.657737 -0.783807 -0.0646247
+v 0.657699 -0.765849 -0.0647403
+v -0.681321 -0.119179 -0.167246
+v -0.681193 -0.1009 -0.163611
+v -0.681475 -0.0825439 -0.155929
+v -0.681578 -0.0643935 -0.147952
+v -0.589079 -0.507055 -0.158395
+v -0.576298 -0.506246 -0.168248
+v -0.575951 -0.525591 -0.149905
+v -0.588771 -0.52631 -0.141812
+v -0.426933 0.552296 -0.0427106
+v -0.4141 0.552373 -0.0480286
+v -0.398313 -0.131112 -0.260259
+v -0.385481 -0.131099 -0.258936
+v -0.385365 -0.149519 -0.260708
+v -0.448243 -0.46667 -0.19566
+v -0.448359 -0.447004 -0.213476
+v -0.448384 -0.428481 -0.222416
+v -0.436541 -0.205512 -0.258717
+v -0.423709 -0.205255 -0.260438
+v -0.44981 -0.149558 -0.263804
+v -0.462437 -0.168132 -0.264562
+v -0.449733 -0.168029 -0.265499
+v -0.634988 0.893352 -0.75163
+v -0.462373 -0.186783 -0.262995
+v -0.449528 -0.186642 -0.26469
+v -0.333933 -0.204112 -0.271434
+v -0.462052 -0.242108 -0.265281
+v -0.449412 -0.205435 -0.260117
+v -0.462013 -0.260695 -0.264947
+v -0.461923 -0.279372 -0.262648
+v -0.461833 -0.298075 -0.258756
+v -0.449039 -0.279398 -0.261389
+v -0.461743 -0.316727 -0.256803
+v -0.448911 -0.316675 -0.257317
+v -0.448808 -0.334748 -0.25864
+v -0.448744 -0.353079 -0.257227
+v -0.461589 -0.353143 -0.257124
+v -0.474229 -0.39042 -0.245332
+v -0.474332 -0.371422 -0.254992
+v 0.10318 -0.298987 -0.45999
+v -0.589683 -0.449162 -0.203174
+v -0.680653 -0.174169 -0.185537
+v -0.57667 -0.467916 -0.194786
+v -0.693794 -0.119731 -0.163174
+v 0.398763 -0.286502 -0.366939
+v 0.645662 -0.882061 -0.0253952
+v 0.64556 -0.861611 -0.0389213
+v 0.645431 -0.841598 -0.0507261
+v 0.645303 -0.822163 -0.0571359
+v 0.645084 -0.803049 -0.0598334
+v 0.64511 -0.784347 -0.0631732
+v 0.644815 -0.765567 -0.0684783
+v 0.154497 -0.0257677 -0.26943
+v 0.153649 -0.0357356 -0.269764
+v -0.693781 -0.211344 -0.184882
+v -0.693717 -0.156096 -0.176212
+v -0.693627 -0.174452 -0.180977
+v -0.693524 -0.192872 -0.184124
+v -0.681706 -0.0460375 -0.139911
+v -0.576015 -0.546169 -0.120733
+v -0.588552 -0.546349 -0.113809
+v -0.31943 -0.539991 -0.186103
+v -0.332199 -0.539926 -0.187708
+v -0.333085 -0.353207 -0.247002
+v -0.333175 -0.33453 -0.253618
+v -0.12959 -0.930719 0.267401
+v -0.436824 -0.168004 -0.265577
+v -0.436888 -0.149481 -0.264061
+v -0.423953 -0.149494 -0.263804
+v -0.423863 -0.167991 -0.265397
+v -0.436952 -0.131048 -0.262083
+v -0.424068 -0.130855 -0.261427
+v -0.437016 -0.112872 -0.256932
+v -0.424184 -0.11264 -0.25751
+v 0.283168 -0.265538 -0.40708
+v 0.643312 -0.351088 -0.2232
+v 0.643068 -0.332847 -0.223033
+v 0.593536 -0.840404 -0.0585617
+v -0.437106 -0.0947341 -0.248993
+v -0.43726 -0.0765194 -0.239757
+v -0.424364 -0.0764167 -0.241299
+v 0.647101 -0.936255 0.0538346
+v -0.42421 -0.0946185 -0.250637
+v -0.436644 -0.186591 -0.264485
+v -0.423798 -0.186539 -0.264498
+v -0.437337 -0.0586388 -0.230124
+v -0.424428 -0.0585617 -0.231524
+v -0.437286 -0.0405398 -0.226411
+v -0.424338 -0.0405655 -0.22758
+v -0.43726 -0.0222224 -0.224446
+v -0.424441 -0.0220811 -0.224664
+v -0.437337 -0.0039692 -0.219539
+v -0.448166 -0.485591 -0.183611
+v 0.397979 -0.0373798 -0.219886
+v -0.512855 -0.390972 -0.242404
+v -0.680923 -0.155813 -0.179667
+v -0.576426 -0.486824 -0.18293
+v -0.693652 -0.137997 -0.169519
+v -0.615771 -0.356393 -0.222635
+v 0.632843 -0.901971 -0.011124
+v 0.632843 -0.881997 -0.0272192
+v 0.632637 -0.861367 -0.0404113
+v 0.632522 -0.841457 -0.0523317
+v 0.632316 -0.821906 -0.0586773
+v 0.632355 -0.803576 -0.0602958
+v 0.632368 -0.784527 -0.0659734
+v -0.693293 -0.229905 -0.187028
+v -0.602528 -0.430459 -0.207888
+v -0.516644 0.532682 0.00421326
+v -0.503696 0.532733 -0.00241492
+v -0.693113 -0.248325 -0.189905
+v -0.681873 -0.0277458 -0.132024
+v -0.576028 -0.56807 -0.0869113
+v -0.589066 -0.569149 -0.0807455
+v 0.384813 -0.0190496 -0.220734
+v -0.474794 -0.26067 -0.266244
+v -0.47482 -0.279295 -0.264343
+v -0.33121 -0.72838 -0.124214
+v -0.446984 -0.562971 -0.131639
+v -0.332481 -0.483407 -0.212333
+v -0.332584 -0.464936 -0.215608
+v -0.332648 -0.446464 -0.219012
+v -0.398506 -0.0944772 -0.252217
+v -0.411005 -0.167927 -0.265294
+v -0.411082 -0.149506 -0.263341
+v -0.433831 -0.694404 -0.0980867
+v -0.421024 -0.693441 -0.107823
+v -0.42105 -0.7124 -0.101516
+v -0.433715 -0.675444 -0.104317
+v -0.433882 -0.656754 -0.109262
+v -0.421229 -0.674815 -0.112872
+v -0.411184 -0.131138 -0.261479
+v -0.421204 -0.655894 -0.119256
+v 0.630672 -0.368943 -0.228466
+v 0.630235 -0.350792 -0.22767
+v 0.630454 -0.332642 -0.226771
+v -0.175833 -0.966724 0.608931
+v -0.184041 -0.96684 0.629291
+v -0.189115 -0.967212 0.606516
+v -0.411506 -0.0404242 -0.227824
+v -0.411493 -0.0585746 -0.232795
+v -0.411441 -0.0765066 -0.242519
+v -0.411428 -0.0943359 -0.251228
+v -0.433741 -0.713132 -0.0931284
+v -0.448012 -0.504563 -0.177381
+v -0.452829 0.571115 -0.0323573
+v -0.45261 0.552155 -0.0304434
+v -0.474602 -0.316868 -0.255634
+v -0.589195 -0.487132 -0.177856
+v -0.680923 -0.137599 -0.173116
+v -0.503247 0.475841 -0.00191395
+v 0.619933 -0.901483 -0.0142968
+v 0.619946 -0.881688 -0.0286835
+v 0.619728 -0.861059 -0.0437254
+v 0.619676 -0.841483 -0.0544898
+v 0.618816 -0.802215 -0.0670268
+v -0.5164 0.494942 -0.0019011
+v -0.503105 0.456894 -0.00043674
+v -0.503324 0.437806 -0.00100193
+v -0.693036 -0.285243 -0.193103
+v -0.693293 -0.266823 -0.190483
+v -0.681758 -0.00967251 -0.123662
+v -0.575823 -0.588173 -0.0639696
+v -0.588295 -0.587672 -0.0598077
+v -0.426971 0.53308 -0.034541
+v 0.302526 -0.960571 0.336084
+v 0.300098 -0.948998 0.348403
+v -0.33112 -0.74698 -0.120836
+v -0.421075 -0.750153 -0.0904052
+v -0.331351 -0.70996 -0.126436
+v -0.320471 -0.316393 -0.254375
+v -0.333368 -0.297664 -0.25751
+v -0.333432 -0.278871 -0.26049
+v -0.411287 -0.112666 -0.257458
+v -0.630466 0.064766 -0.114169
+v -0.630171 0.0825567 -0.103739
+v -0.615823 -0.375096 -0.218075
+v -0.616131 -0.319758 -0.225011
+v -0.603067 -0.33787 -0.22627
+v 0.61766 -0.350535 -0.231485
+v 0.617133 -0.332256 -0.232294
+v 0.616966 -0.313978 -0.233746
+v 0.617403 -0.295301 -0.234825
+v -0.861014 0.09607 -0.00520235
+v -0.630107 0.10081 -0.0967122
+v -0.537865 -0.505334 -0.179963
+v -0.732805 0.118665 -0.081786
+v -0.732574 0.0808098 -0.0717924
+v -0.732702 0.0998337 -0.0784462
+v -0.41094 -0.186488 -0.264729
+v -0.45306 0.590074 -0.0324986
+v -0.447845 -0.524602 -0.162069
+v -0.474679 -0.298165 -0.258948
+v -0.588308 -0.608392 -0.0360439
+v -0.575386 -0.607441 -0.0410022
+v -0.693254 -0.303778 -0.19372
+v 0.606985 -0.880776 -0.0331922
+v 0.606985 -0.861329 -0.0461788
+v -0.693074 -0.322289 -0.194966
+v -0.692676 -0.340439 -0.195904
+v -0.681655 0.00851643 -0.116905
+v -0.398146 -0.167965 -0.263611
+v -0.385301 -0.167991 -0.262173
+v -0.498815 -0.586118 -0.085357
+v -0.757429 -0.26934 -0.158961
+v -0.336707 -0.971246 -0.318576
+v 0.293907 -0.972543 -0.176417
+v -0.56624 0.102377 -0.11729
+v -0.394794 -0.913314 -0.135633
+v -0.394717 -0.931682 -0.138845
+v 0.604468 -0.331807 -0.239179
+v 0.604326 -0.313477 -0.240734
+v -0.397093 -0.409585 -0.225242
+v -0.397222 -0.390651 -0.235056
+v -0.384184 -0.409328 -0.226463
+v -0.397273 -0.371961 -0.243817
+v -0.384415 -0.372141 -0.240387
+v -0.384325 -0.390728 -0.233399
+v -0.396965 -0.428892 -0.214285
+v -0.384107 -0.428892 -0.214414
+v -0.383875 -0.447504 -0.205563
+v -0.396785 -0.447569 -0.205628
+v -0.396554 -0.466477 -0.195595
+v -0.38376 -0.46649 -0.197612
+v -0.396335 -0.485449 -0.185422
+v -0.383695 -0.485372 -0.191369
+v -0.396091 -0.523099 -0.174272
+v -0.383516 -0.522804 -0.179873
+v -0.383323 -0.541416 -0.174799
+v -0.906743 0.021092 0.294928
+v -0.396451 -0.561031 -0.162442
+v -0.383516 -0.560389 -0.168851
+v -0.383284 -0.579336 -0.158704
+v -0.410863 -0.205204 -0.261427
+v -0.111773 -0.92955 0.223675
+v -0.410658 -0.260772 -0.259976
+v -0.410632 -0.279295 -0.260053
+v -0.447639 -0.54396 -0.147194
+v -0.745547 -0.139603 -0.142313
+v -0.446753 -0.63863 -0.107579
+v -0.629888 -0.0991015 -0.191433
+v -0.630415 -0.0805914 -0.18406
+v -0.681694 0.0267953 -0.108838
+v -0.681925 0.0450613 -0.0979454
+v -0.69283 -0.359 -0.193129
+v 0.59441 -0.882074 -0.0349906
+v 0.593729 -0.859402 -0.0509059
+v 0.463195 -0.325346 -0.332513
+v -0.013327 -0.924823 0.262725
+v -0.026198 -0.924373 0.259681
+v -0.0175274 -0.924335 0.238229
+v -0.453497 0.609085 -0.0312141
+v -0.616465 -0.264356 -0.220515
+v -0.616183 -0.245923 -0.219655
+v -0.550671 -0.485796 -0.190676
+v -0.396464 -0.50473 -0.178216
+v -0.383695 -0.504204 -0.184998
+v -0.396271 -0.542046 -0.168415
+v 0.414229 -0.897141 -0.264125
+v 0.591468 -0.331126 -0.248762
+v -0.381884 -0.785323 -0.105486
+v -0.369219 -0.784745 -0.110868
+v -0.369 -0.803538 -0.112037
+v -0.358904 -0.334697 -0.253797
+v -0.371749 -0.334517 -0.254838
+v -0.358994 -0.316136 -0.25864
+v -0.382694 -0.692195 -0.120964
+v -0.382591 -0.673029 -0.128492
+v -0.369745 -0.691629 -0.125383
+v -0.368898 -0.822022 -0.115454
+v -0.382565 -0.710923 -0.116044
+v -0.369707 -0.710525 -0.119089
+v -0.382629 -0.654134 -0.134799
+v -0.36999 -0.654198 -0.1353
+v -0.369951 -0.672708 -0.131343
+v -0.382655 -0.729767 -0.11169
+v -0.369604 -0.729369 -0.114413
+v -0.369591 -0.747995 -0.111292
+v -0.38236 -0.748598 -0.104843
+v -0.382963 -0.635804 -0.138896
+v -0.370118 -0.635354 -0.141825
+v -0.383284 -0.617294 -0.1446
+v -0.370092 -0.616253 -0.149686
+v -0.382963 -0.597794 -0.153154
+v -0.370195 -0.597602 -0.154786
+v -0.395911 -0.617589 -0.13914
+v -0.396297 -0.598976 -0.146269
+v -0.396438 -0.580055 -0.154478
+v -0.119802 -0.928548 0.244292
+v -0.401139 0.552489 -0.0530896
+v -0.410401 -0.316405 -0.259077
+v -0.410465 -0.297728 -0.260747
+v -0.446804 -0.657692 -0.0996281
+v -0.488256 -0.187092 -0.258602
+v -0.488333 -0.168672 -0.256893
+v -0.475334 -0.186989 -0.260194
+v -0.497055 -0.605913 -0.0678103
+v -0.511532 -0.606388 -0.0625309
+v -0.681205 0.0814135 -0.0863461
+v -0.681244 0.100347 -0.0875792
+v -0.692175 -0.377343 -0.187195
+v 0.581359 -0.880764 -0.0408609
+v 0.581179 -0.860738 -0.0512527
+v -0.549798 -0.606593 -0.0515225
+v -0.69152 -0.414749 -0.170354
+v -0.692548 -0.396714 -0.17652
+v -0.681347 0.0629163 -0.0902125
+v -0.308101 -0.240618 -0.27778
+v -0.475026 -0.242147 -0.265358
+v -0.330863 -0.765438 -0.120489
+v -0.332096 -0.559079 -0.17819
+v -0.332006 -0.578026 -0.168068
+v -0.370478 -0.579156 -0.160425
+v 0.57888 -0.438577 -0.272975
+v 0.179507 -0.0725502 -0.271228
+v -0.74565 0.118446 -0.0786518
+v -0.745547 0.0995511 -0.073732
+v -0.745419 0.0805015 -0.0669882
+v 0.578944 -0.330432 -0.259077
+v 0.579072 -0.312295 -0.257767
+v -0.407459 -0.87736 -0.123777
+v -0.371826 -0.316264 -0.259077
+v -0.371903 -0.297446 -0.262327
+v -0.359071 -0.297394 -0.262044
+v -0.381704 -0.822433 -0.11187
+v -0.381782 -0.804026 -0.10704
+v -0.537595 -0.544962 -0.132178
+v -0.537556 -0.567377 -0.0969692
+v -0.615913 -0.338037 -0.224587
+v -0.560896 -0.908201 -0.0887995
+v -0.561038 -0.91885 -0.0914971
+v -0.732715 0.137419 -0.0829806
+v -0.55071 -0.505488 -0.178241
+v -0.537608 -0.524178 -0.164664
+v -0.370593 -0.559875 -0.173604
+v -0.401229 0.571564 -0.0616317
+v -0.388307 0.571796 -0.0681315
+v -0.388243 0.552669 -0.0581507
+v -0.446997 -0.619991 -0.112692
+v -0.488564 -0.150239 -0.254016
+v -0.475835 -0.149982 -0.260361
+v -0.446445 -0.676292 -0.0944001
+v -0.475475 -0.168402 -0.261646
+v -0.497389 -0.624436 -0.0583433
+v -0.651327 -0.95912 -0.0633659
+v -0.681449 0.119256 -0.0911888
+v -0.602091 -0.508173 -0.148877
+v -0.60177 -0.487081 -0.172679
+v 0.568796 -0.901727 -0.0278615
+v 0.568321 -0.880237 -0.0440208
+v 0.568539 -0.861174 -0.0539246
+v -0.652291 -0.531012 -0.0795509
+v -0.691417 -0.433657 -0.16063
+v -0.447241 -0.58283 -0.119294
+v -0.446894 -0.601378 -0.115672
+v -0.487986 -0.223804 -0.263264
+v -0.47509 -0.223765 -0.263457
+v -0.614436 -0.487582 -0.16415
+v -0.614911 -0.468442 -0.184279
+v -0.410735 -0.242339 -0.259064
+v -0.410838 -0.223983 -0.257651
+v 0.566304 -0.455854 -0.2846
+v 0.566561 -0.437858 -0.281813
+v 0.565611 -0.311743 -0.266668
+v -0.358788 -0.353567 -0.245782
+v -0.371647 -0.353515 -0.2474
+v -0.359199 -0.27891 -0.262892
+v -0.372006 -0.27882 -0.263842
+v -0.359379 -0.260413 -0.263547
+v -0.371531 -0.372411 -0.237355
+v -0.372263 -0.242018 -0.261505
+v -0.359392 -0.241736 -0.264498
+v -0.372173 -0.2604 -0.263226
+v -0.372417 -0.223598 -0.260271
+v -0.359559 -0.223328 -0.263277
+v -0.372469 -0.186462 -0.261839
+v -0.359533 -0.186385 -0.262494
+v -0.359598 -0.204805 -0.263264
+v -0.372443 -0.204972 -0.261864
+v -0.331441 -0.691218 -0.12889
+v -0.370478 -0.540736 -0.18117
+v -0.39586 -0.636163 -0.135865
+v -0.401409 0.590601 -0.0683755
+v -0.388551 0.590742 -0.0749009
+v -0.410298 -0.334787 -0.257792
+v -0.446548 -0.695277 -0.0881316
+v -0.488642 -0.131883 -0.250663
+v -0.475758 -0.131523 -0.255647
+v -0.573844 -0.919364 -0.0865388
+v -0.681475 0.138125 -0.0939248
+v -0.691161 -0.452707 -0.14582
+v 0.55581 -0.900661 -0.0343483
+v 0.555874 -0.880815 -0.0468211
+v 0.556349 -0.861945 -0.0570203
+v 0.347279 -0.285461 -0.384755
+v -0.488243 -0.205422 -0.260721
+v -0.613729 -0.526953 -0.121388
+v -0.614577 -0.508224 -0.141851
+v -0.601487 -0.527017 -0.131883
+v -0.615348 -0.412026 -0.209083
+v -0.61563 -0.39367 -0.212885
+v 0.553973 -0.528931 -0.281338
+v 0.554114 -0.510382 -0.286681
+v 0.553729 -0.491744 -0.291216
+v 0.553896 -0.473298 -0.294902
+v 0.553163 -0.455045 -0.295609
+v 0.553536 -0.437036 -0.293001
+v 0.553279 -0.419052 -0.291152
+v -0.960282 0.0682471 0.315018
+v 0.553009 -0.292603 -0.275455
+v -0.358699 -0.372257 -0.237137
+v -0.358621 -0.390703 -0.233605
+v -0.371467 -0.390908 -0.232359
+v -0.358532 -0.409367 -0.22898
+v -0.371364 -0.409765 -0.22812
+v -0.358403 -0.428365 -0.219166
+v -0.371133 -0.447582 -0.207863
+v -0.37121 -0.428622 -0.215865
+v -0.358416 -0.447273 -0.213258
+v -0.358352 -0.465706 -0.209905
+v -0.370221 -0.463086 -0.204343
+v -0.372482 -0.167991 -0.261376
+v -0.359636 -0.167991 -0.260079
+v -0.370709 -0.522251 -0.186449
+v -0.395372 -0.673351 -0.125242
+v -0.39559 -0.654609 -0.132127
+v -0.40155 0.609561 -0.0700454
+v -0.388757 0.609728 -0.0783306
+v -0.410093 -0.37209 -0.245923
+v -0.410221 -0.353104 -0.253579
+v -0.446779 -0.71434 -0.0820943
+v -0.488719 -0.113719 -0.244215
+v -0.47586 -0.11327 -0.249199
+v 0.516002 -0.690473 -0.307054
+v -0.681488 0.156841 -0.0934624
+v -0.689144 -0.490318 -0.105409
+v -0.691006 -0.472193 -0.127849
+v 0.540665 -0.400337 -0.298204
+v 0.541179 -0.54676 -0.28627
+v 0.540472 -0.527865 -0.292038
+v 0.541179 -0.509599 -0.296392
+v 0.540691 -0.490986 -0.300734
+v 0.541063 -0.472681 -0.303072
+v 0.540819 -0.454505 -0.302866
+v 0.540562 -0.436483 -0.300978
+v 0.540665 -0.418397 -0.299706
+v -0.344093 -0.710037 -0.124111
+v -0.344158 -0.69118 -0.128299
+v -0.344106 -0.728521 -0.122531
+v -0.347189 -0.0759799 -0.24916
+v -0.360047 -0.0760699 -0.248968
+v -0.347228 -0.0578681 -0.243894
+v -0.363015 0.590858 -0.0850744
+v -0.350079 0.590999 -0.0899042
+v -0.372533 -0.149519 -0.259334
+v -0.359713 -0.149648 -0.257124
+v -0.3583 -0.484255 -0.206745
+v -0.370966 -0.50369 -0.191742
+v -0.401679 0.628803 -0.0700711
+v -0.389039 0.628957 -0.0785875
+v -0.395282 -0.692207 -0.11878
+v -0.410003 -0.390818 -0.237355
+v -0.48895 -0.0954663 -0.235043
+v -0.476117 -0.0950167 -0.240002
+v -0.446637 -0.733094 -0.0771103
+v -0.681732 0.175647 -0.0927174
+v 0.333637 -0.0735265 -0.244819
+v 0.333676 -0.0550164 -0.242339
+v 0.346418 -0.0551834 -0.240169
+v 0.359418 -0.0551834 -0.235994
+v -0.168151 -0.967932 0.589227
+v -0.181433 -0.96842 0.586748
+v 0.529657 -0.767558 -0.26022
+v 0.529528 -0.748714 -0.266707
+v 0.410838 -0.0375982 -0.214902
+v 0.516015 -0.672156 -0.308865
+v 0.131658 -0.930822 -0.306977
+v 0.118864 -0.93095 -0.307452
+v 0.528102 -0.583164 -0.285756
+v 0.528847 -0.564936 -0.288313
+v 0.528346 -0.545874 -0.29769
+v 0.528244 -0.527158 -0.304267
+v 0.528308 -0.508725 -0.307773
+v 0.528295 -0.490395 -0.309597
+v 0.527897 -0.47209 -0.310766
+v 0.527653 -0.453979 -0.310445
+v 0.527755 -0.436021 -0.307581
+v 0.527871 -0.418076 -0.304703
+v 0.527987 -0.399977 -0.303483
+v 0.52764 -0.381865 -0.302956
+v 0.0201478 -0.919955 0.357857
+v 0.283618 -0.9765 -0.223341
+v -0.344466 -0.653736 -0.138344
+v -0.331685 -0.653569 -0.137856
+v -0.331621 -0.672297 -0.133
+v -0.344363 -0.672657 -0.132024
+v -0.359752 -0.131202 -0.256816
+v -0.359867 -0.112666 -0.256032
+v -0.347009 -0.11264 -0.255827
+v -0.360086 -0.0580222 -0.242275
+v -0.346829 -0.167772 -0.261864
+v -0.346855 -0.149583 -0.257189
+v -0.347074 -0.0942588 -0.2539
+v -0.359957 -0.0942459 -0.254029
+v -0.37094 -0.484704 -0.199667
+v -0.363297 0.609882 -0.0918953
+v -0.350169 0.6101 -0.0980482
+v -0.37261 -0.13115 -0.257471
+v -0.358108 -0.50297 -0.199924
+v -0.38936 0.648276 -0.0771232
+v -0.395385 -0.711244 -0.112795
+v -0.409926 -0.409752 -0.225525
+v -0.488847 -0.0775728 -0.226797
+v -0.476002 -0.0771874 -0.231626
+v -0.681745 0.194555 -0.0936936
+v -0.52895 0.269096 -0.0648944
+v 0.516195 -0.786029 -0.254337
+v 0.51658 -0.766672 -0.269751
+v 0.517184 -0.7482 -0.277047
+v 0.515578 -0.581725 -0.304048
+v 0.451416 -0.968844 -0.00376367
+v 0.436862 -0.971503 -0.0042261
+v 0.449117 -0.965555 -0.0313682
+v 0.514859 -0.562765 -0.311601
+v 0.514576 -0.544307 -0.314646
+v 0.515257 -0.526246 -0.315506
+v 0.514795 -0.5078 -0.318229
+v 0.515527 -0.489753 -0.317921
+v 0.514987 -0.471525 -0.318807
+v 0.515116 -0.453555 -0.31593
+v 0.514717 -0.43561 -0.313682
+v 0.514666 -0.417575 -0.312128
+v 0.515103 -0.399502 -0.309957
+v 0.514884 -0.381505 -0.308056
+v -0.344543 -0.63475 -0.144381
+v -0.307947 -0.259257 -0.275737
+v -0.346534 -0.222879 -0.26907
+v -0.346829 -0.204497 -0.266758
+v -0.346791 -0.186077 -0.26496
+v 0.00940918 -0.922164 0.10212
+v 0.00526015 -0.921689 0.0775342
+v -0.357221 -0.653813 -0.138305
+v -0.346945 -0.131163 -0.255673
+v -0.35726 -0.634853 -0.144535
+v -0.357401 -0.616305 -0.150072
+v -0.344607 -0.61606 -0.149635
+v -0.523709 0.494788 -0.000937707
+v -0.363361 0.629265 -0.0950552
+v -0.350529 0.629304 -0.101645
+v -0.372713 -0.112705 -0.256957
+v -0.357992 -0.521532 -0.192936
+v -0.363567 0.667699 -0.0932826
+v -0.488783 -0.0595508 -0.220078
+v -0.476015 -0.0592425 -0.223521
+v -0.446522 -0.769909 -0.0755432
+v -0.681963 0.213553 -0.0958773
+v -0.52958 0.287478 -0.0623125
+v 0.50394 -0.786363 -0.260104
+v 0.503683 -0.766016 -0.277818
+v 0.504313 -0.747237 -0.290175
+v 0.503208 -0.726825 -0.306836
+v 0.50308 -0.70793 -0.314967
+v 0.50308 -0.689638 -0.316739
+v 0.503272 -0.671462 -0.317202
+v 0.503003 -0.653466 -0.315301
+v 0.502604 -0.599092 -0.313541
+v 0.502193 -0.362841 -0.315095
+v 0.502977 -0.580582 -0.319026
+v 0.502553 -0.561802 -0.325243
+v 0.502476 -0.54351 -0.326887
+v 0.50227 -0.52536 -0.32672
+v 0.50254 -0.507325 -0.325654
+v 0.50227 -0.489162 -0.325397
+v 0.502219 -0.471153 -0.323868
+v 0.502219 -0.453221 -0.320773
+v 0.502116 -0.435212 -0.319206
+v 0.502193 -0.416984 -0.319514
+v 0.501821 -0.398911 -0.318923
+v 0.501936 -0.380966 -0.316046
+v -0.346675 -0.241466 -0.268171
+v -0.357157 -0.672695 -0.131883
+v -0.344723 -0.597512 -0.156982
+v -0.35708 -0.710217 -0.122685
+v -0.356977 -0.691501 -0.127194
+v -0.357632 -0.578462 -0.166745
+v -0.344787 -0.578013 -0.167927
+v -0.357453 -0.597383 -0.156481
+v -0.363477 0.648559 -0.0949139
+v -0.350632 0.648585 -0.103199
+v -0.357799 -0.540569 -0.184895
+v -0.372815 -0.094323 -0.253887
+v -0.376284 0.648366 -0.0867314
+v -0.394922 -0.749099 -0.0996538
+v -0.395487 -0.730448 -0.105152
+v -0.409707 -0.447556 -0.207477
+v -0.409848 -0.428725 -0.215647
+v -0.446085 -0.78811 -0.078215
+v -0.488552 -0.0414132 -0.217625
+v -0.475938 -0.041015 -0.220078
+v -0.682015 0.232217 -0.09765
+v -0.730531 -0.360452 -0.17074
+v -0.407421 -0.950269 -0.140386
+v -0.464595 0.456882 0.00497113
+v 0.491236 -0.806197 -0.245319
+v 0.491121 -0.785888 -0.266745
+v 0.491185 -0.765952 -0.284973
+v 0.490645 -0.745438 -0.303791
+v 0.490401 -0.726003 -0.316688
+v 0.490671 -0.707506 -0.322147
+v 0.490453 -0.689137 -0.323676
+v 0.490658 -0.671026 -0.322712
+v 0.490774 -0.653081 -0.319886
+v 0.490376 -0.635161 -0.317536
+v 0.490427 -0.617152 -0.317716
+v 0.490414 -0.598578 -0.322687
+v 0.490093 -0.579837 -0.328891
+v 0.489926 -0.561224 -0.333644
+v 0.489708 -0.542752 -0.336778
+v 0.489618 -0.524602 -0.336855
+v 0.489258 -0.506644 -0.334774
+v 0.489849 -0.488674 -0.331216
+v 0.489412 -0.47078 -0.328814
+v 0.489412 -0.452861 -0.32577
+v 0.489515 -0.434929 -0.322905
+v 0.489348 -0.416779 -0.323034
+v 0.489232 -0.398525 -0.324331
+v 0.489502 -0.380555 -0.321775
+v 0.488886 -0.362379 -0.322353
+v 0.488796 -0.344241 -0.322327
+v -0.387562 -0.50229 0.546349
+v -0.346406 -0.260104 -0.265718
+v -0.356733 -0.728868 -0.119102
+v -0.345763 -0.390715 -0.234041
+v -0.345622 -0.409007 -0.229905
+v -0.35094 0.667801 -0.101709
+v -0.357786 -0.55949 -0.176828
+v -0.375834 0.609882 -0.0863846
+v -0.37622 0.629111 -0.0867443
+v -0.488719 -0.0228903 -0.216328
+v -0.476027 -0.0225692 -0.21855
+v -0.446098 -0.806556 -0.0815419
+v -0.562553 -0.60685 -0.0461146
+v -0.682053 0.250869 -0.09607
+v -0.358069 -0.838284 -0.124676
+v 0.478173 -0.785195 -0.27304
+v 0.477929 -0.764681 -0.294106
+v 0.478031 -0.745246 -0.310818
+v 0.477672 -0.725541 -0.323342
+v 0.477492 -0.706761 -0.329713
+v 0.477839 -0.688713 -0.329109
+v 0.477762 -0.670589 -0.327619
+v 0.477325 -0.652721 -0.325127
+v 0.477222 -0.634712 -0.323457
+v 0.477184 -0.616266 -0.326836
+v 0.477402 -0.598 -0.330689
+v 0.477312 -0.5794 -0.335648
+v 0.477338 -0.560877 -0.340696
+v 0.477325 -0.542316 -0.344241
+v 0.476862 -0.523985 -0.345166
+v 0.476516 -0.506002 -0.343072
+v 0.476079 -0.488314 -0.339077
+v 0.476297 -0.470459 -0.3348
+v 0.476593 -0.452501 -0.330766
+v 0.476323 -0.434569 -0.32866
+v 0.476721 -0.416457 -0.328313
+v 0.476516 -0.398191 -0.329533
+v 0.476464 -0.380144 -0.32794
+v 0.476657 -0.361929 -0.328467
+v 0.475925 -0.343766 -0.328865
+v -0.346354 -0.279 -0.261582
+v -0.407369 -0.931824 -0.138537
+v -0.345866 -0.372257 -0.239295
+v -0.394768 -0.767558 -0.0989473
+v -0.381987 -0.766967 -0.104432
+v -0.409437 -0.486195 -0.181286
+v -0.409553 -0.466747 -0.194272
+v -0.445931 -0.824925 -0.087682
+v -0.488847 -0.00441878 -0.211845
+v -0.331929 -0.597178 -0.158331
+v -0.5629 -0.587441 -0.0686838
+v -0.682066 0.269417 -0.0911888
+v -0.690159 -0.929691 0.00904309
+v 0.465045 -0.804373 -0.262661
+v 0.465494 -0.785079 -0.276521
+v 0.465366 -0.764976 -0.297972
+v 0.465302 -0.74513 -0.316174
+v 0.464968 -0.725079 -0.330343
+v 0.464839 -0.706414 -0.335172
+v 0.464942 -0.688315 -0.333965
+v 0.464736 -0.67028 -0.332102
+v 0.464762 -0.6524 -0.329097
+v 0.464544 -0.634365 -0.328775
+v 0.464223 -0.615765 -0.333168
+v 0.464197 -0.597204 -0.338165
+v 0.464094 -0.578629 -0.343111
+v 0.464569 -0.560479 -0.346027
+v 0.464531 -0.541982 -0.349431
+v 0.464197 -0.523613 -0.350484
+v 0.463786 -0.505501 -0.349842
+v 0.46367 -0.48762 -0.346515
+v 0.463657 -0.469842 -0.341788
+v 0.463426 -0.452026 -0.338255
+v 0.463632 -0.434043 -0.335571
+v 0.463542 -0.415905 -0.335596
+v 0.463079 -0.397703 -0.33647
+v 0.463092 -0.379668 -0.335031
+v 0.463323 -0.361454 -0.335712
+v 0.463028 -0.343355 -0.335301
+v -0.346239 -0.297446 -0.260361
+v 0.462733 -0.163495 -0.272179
+v 0.449772 -0.145126 -0.270586
+v -0.758277 -0.0127939 -0.078549
+v -0.345571 -0.428031 -0.222365
+v -0.345956 -0.353605 -0.246065
+v -0.616131 -0.282776 -0.222879
+v -0.394614 -0.950398 -0.138781
+v -0.488796 0.0136674 -0.204947
+v -0.445918 -0.842986 -0.0958259
+v -0.563298 -0.568122 -0.0905337
+v -0.682028 0.288069 -0.0888509
+v -0.630479 -0.0621969 -0.172846
+v -0.746575 0.324947 -0.0677975
+v -0.702683 -0.931425 0.0230958
+v 0.451737 -0.803615 -0.271717
+v 0.452456 -0.784321 -0.282764
+v 0.452328 -0.764141 -0.3041
+v 0.452328 -0.744693 -0.320965
+v 0.452264 -0.725066 -0.334273
+v 0.451968 -0.706042 -0.340028
+v 0.451827 -0.687827 -0.339861
+v 0.451776 -0.669946 -0.336714
+v 0.45175 -0.652092 -0.333605
+v 0.451621 -0.63398 -0.333464
+v 0.451429 -0.615431 -0.338165
+v 0.451544 -0.596934 -0.343573
+v 0.45139 -0.578488 -0.346669
+v 0.451544 -0.560196 -0.349058
+v 0.45148 -0.541789 -0.352436
+v 0.451043 -0.523279 -0.354749
+v 0.451108 -0.50509 -0.355083
+v 0.450697 -0.487248 -0.352783
+v 0.450812 -0.469393 -0.348287
+v 0.450581 -0.451628 -0.344691
+v 0.450607 -0.433644 -0.341672
+v 0.450889 -0.415443 -0.342404
+v 0.450786 -0.397164 -0.344061
+v 0.450363 -0.379052 -0.34347
+v 0.450465 -0.361004 -0.342212
+v 0.450298 -0.342867 -0.342109
+v -0.524621 -0.983295 -0.114516
+v -0.343759 -0.747044 -0.12036
+v -0.343618 -0.76558 -0.118678
+v -0.346059 -0.334915 -0.252821
+v -0.346136 -0.316277 -0.257368
+v -0.334408 -0.0576369 -0.244356
+v -0.345468 -0.446708 -0.217728
+v -0.642952 0.00951837 -0.136276
+v -0.643158 0.0279 -0.128414
+v -0.63021 0.0282597 -0.136353
+v -0.318981 -0.635059 -0.139757
+v -0.409283 -0.504897 -0.174516
+v -0.445635 -0.861046 -0.106475
+v -0.527357 -0.151266 -0.237882
+v -0.563093 -0.545758 -0.125563
+v -0.550607 -0.5473 -0.123251
+v -0.68222 0.307015 -0.0864489
+v 0.439662 -0.858978 -0.273926
+v 0.439611 -0.840031 -0.278961
+v 0.43956 -0.821393 -0.280657
+v 0.439431 -0.802715 -0.282263
+v 0.43938 -0.783422 -0.290432
+v 0.439444 -0.763756 -0.30726
+v 0.439367 -0.744192 -0.323856
+v 0.439354 -0.724847 -0.337459
+v 0.439149 -0.705823 -0.343496
+v 0.438943 -0.68748 -0.344704
+v 0.438853 -0.669587 -0.341415
+v 0.43902 -0.651847 -0.337163
+v 0.439007 -0.633774 -0.33733
+v 0.43875 -0.615136 -0.343509
+v 0.438532 -0.596369 -0.349765
+v 0.438327 -0.577884 -0.352706
+v 0.438532 -0.559837 -0.353541
+v 0.438583 -0.541416 -0.357112
+v 0.438198 -0.522958 -0.359655
+v 0.438249 -0.504756 -0.359912
+v 0.437967 -0.486798 -0.357934
+v 0.438057 -0.468995 -0.353361
+v 0.437684 -0.451242 -0.349559
+v 0.437954 -0.433272 -0.34699
+v 0.437928 -0.414993 -0.34875
+v 0.438198 -0.396701 -0.351075
+v 0.43771 -0.378551 -0.350407
+v 0.437453 -0.360606 -0.348429
+v 0.437646 -0.342507 -0.347401
+v -0.343477 -0.784038 -0.118832
+v -0.344813 -0.558925 -0.177689
+v -0.333291 -0.316354 -0.256071
+v 0.436682 -0.145512 -0.27092
+v 0.0552027 -0.91822 -0.00978812
+v -0.345327 -0.465141 -0.21408
+v -0.616067 -0.301197 -0.224703
+v -0.394717 -0.785888 -0.100553
+v 0.0901033 -0.978542 -0.235185
+v 0.0772709 -0.978054 -0.238165
+v -0.409206 -0.542714 -0.162108
+v -0.409142 -0.523741 -0.168068
+v -0.445713 -0.878721 -0.116173
+v -0.563298 -0.524833 -0.158228
+v -0.550363 -0.524024 -0.164446
+v -0.682451 0.325949 -0.0858451
+v 0.427151 -0.878246 -0.269366
+v 0.426971 -0.858682 -0.279154
+v 0.426984 -0.839697 -0.284254
+v 0.426881 -0.820866 -0.287465
+v 0.426856 -0.802266 -0.289199
+v 0.426869 -0.783101 -0.299244
+v 0.426393 -0.762934 -0.313297
+v 0.42656 -0.744115 -0.325564
+v 0.426406 -0.724693 -0.33873
+v 0.426342 -0.705836 -0.345474
+v 0.426188 -0.687223 -0.348262
+v 0.426021 -0.669227 -0.346348
+v 0.425802 -0.651411 -0.342648
+v 0.425841 -0.63326 -0.343008
+v 0.4257 -0.614558 -0.349495
+v 0.425841 -0.596099 -0.355095
+v 0.425661 -0.577614 -0.358127
+v 0.425468 -0.55931 -0.359463
+v 0.425597 -0.540967 -0.363239
+v 0.425391 -0.522482 -0.366258
+v 0.425545 -0.504409 -0.36514
+v 0.425006 -0.4864 -0.364164
+v 0.425199 -0.468545 -0.3599
+v 0.425263 -0.450767 -0.355275
+v 0.42498 -0.432707 -0.354916
+v 0.424685 -0.414299 -0.357857
+v 0.424942 -0.396149 -0.358512
+v 0.424839 -0.378127 -0.356894
+v 0.424505 -0.360182 -0.354736
+v 0.424723 -0.342135 -0.353772
+v -0.345211 -0.50229 -0.206206
+v -0.345185 -0.521455 -0.196687
+v -0.345327 -0.483715 -0.211279
+v -0.345005 -0.540363 -0.186578
+v -0.407305 -0.859556 -0.118164
+v -0.434113 -0.637962 -0.115993
+v -0.421306 -0.637075 -0.125717
+v -0.445738 -0.896666 -0.122634
+v -0.563478 -0.505642 -0.174773
+v -0.421088 -0.731308 -0.095158
+v -0.682606 0.344691 -0.0824925
+v -0.529631 0.325153 -0.0544898
+v -0.477428 0.456894 0.003404
+v 0.414524 -0.87813 -0.274966
+v 0.414344 -0.858451 -0.284626
+v 0.414139 -0.839325 -0.289276
+v 0.413638 -0.820147 -0.29313
+v 0.41419 -0.801726 -0.297407
+v 0.413689 -0.781534 -0.313374
+v 0.413664 -0.762394 -0.321685
+v 0.413419 -0.743871 -0.329161
+v 0.413445 -0.724462 -0.339835
+v 0.41333 -0.705477 -0.348005
+v 0.413163 -0.687018 -0.350972
+v 0.413265 -0.668945 -0.34988
+v 0.413227 -0.651115 -0.346772
+v 0.413265 -0.633029 -0.348185
+v 0.413163 -0.614314 -0.355262
+v 0.413021 -0.595752 -0.360092
+v 0.412803 -0.577255 -0.362931
+v 0.412777 -0.558989 -0.364794
+v 0.412533 -0.540389 -0.369302
+v 0.412418 -0.521866 -0.374132
+v 0.412469 -0.503844 -0.372873
+v 0.412096 -0.485938 -0.370548
+v 0.412109 -0.46816 -0.36595
+v 0.412379 -0.450279 -0.361813
+v 0.412173 -0.43209 -0.363201
+v 0.412456 -0.41385 -0.365551
+v 0.411878 -0.395597 -0.366284
+v 0.412122 -0.377613 -0.363702
+v 0.412161 -0.359694 -0.360709
+v 0.411929 -0.341634 -0.360413
+v 0.39902 -0.304896 -0.367247
+v 0.185338 -0.934971 0.149352
+v -0.398211 -0.149506 -0.261993
+v -0.394614 -0.80445 -0.103623
+v -0.407408 -0.841444 -0.110238
+v -0.394704 -0.840892 -0.113938
+v -0.409039 -0.561468 -0.155492
+v -0.563709 -0.486708 -0.186527
+v -0.809067 0.0598976 -0.0252025
+v 0.401473 -0.896884 -0.269353
+v 0.401473 -0.877501 -0.279475
+v 0.401229 -0.857848 -0.288916
+v 0.401075 -0.838618 -0.295185
+v 0.401242 -0.820134 -0.297497
+v 0.401589 -0.801482 -0.304845
+v 0.400921 -0.78075 -0.323316
+v 0.400793 -0.761829 -0.328236
+v 0.400741 -0.743255 -0.333284
+v 0.400561 -0.724154 -0.342905
+v 0.400638 -0.705502 -0.350394
+v 0.400471 -0.686941 -0.353053
+v 0.400613 -0.668829 -0.352257
+v 0.400343 -0.650897 -0.349944
+v 0.400279 -0.632824 -0.351679
+v 0.400125 -0.61389 -0.359655
+v 0.400073 -0.595341 -0.364665
+v 0.399958 -0.577024 -0.366232
+v 0.399701 -0.558565 -0.369033
+v 0.399791 -0.540081 -0.374492
+v 0.399752 -0.521519 -0.379591
+v 0.399585 -0.503343 -0.379347
+v 0.399213 -0.485488 -0.376997
+v 0.399482 -0.467697 -0.371345
+v 0.399534 -0.449894 -0.36681
+v 0.399405 -0.43191 -0.368326
+v 0.399046 -0.413259 -0.372616
+v 0.398981 -0.395147 -0.372732
+v 0.399058 -0.377228 -0.369765
+v 0.39902 -0.359334 -0.366682
+v 0.398917 -0.341235 -0.366618
+v 0.398699 -0.322995 -0.367992
+v -0.306688 -0.539849 -0.184047
+v -0.356296 -0.82147 -0.119243
+v 0.369887 -0.965504 0.447106
+v 0.381525 -0.968073 0.451782
+v 0.36069 -0.966621 0.46938
+v -0.39473 -0.822651 -0.108928
+v -0.407562 -0.823191 -0.104047
+v -0.408731 -0.580158 -0.148594
+v 0.0257227 -0.918657 -0.182801
+v 0.0288184 -0.929383 -0.196353
+v -0.433895 -0.732182 -0.0870526
+v -0.563709 -0.467363 -0.197676
+v -0.452572 0.51385 -0.020758
+v -0.809312 0.0789215 -0.0341556
+v 0.388525 -0.93438 -0.262044
+v 0.38832 -0.915202 -0.266501
+v 0.388782 -0.896807 -0.273104
+v 0.388474 -0.876897 -0.283894
+v 0.388243 -0.857295 -0.293271
+v 0.388333 -0.838451 -0.298782
+v 0.388538 -0.820031 -0.301248
+v 0.388525 -0.800802 -0.312667
+v 0.387947 -0.780095 -0.329546
+v 0.38814 -0.761585 -0.333541
+v 0.38796 -0.742933 -0.338345
+v 0.388166 -0.724231 -0.3469
+v 0.387523 -0.704821 -0.355686
+v 0.387832 -0.686825 -0.355763
+v 0.387613 -0.668611 -0.35516
+v 0.387498 -0.650679 -0.353271
+v 0.387549 -0.632657 -0.353811
+v 0.387254 -0.613992 -0.361531
+v 0.387382 -0.595328 -0.36681
+v 0.386958 -0.576754 -0.369007
+v 0.387177 -0.558719 -0.371884
+v 0.387536 -0.539901 -0.378898
+v 0.386984 -0.521301 -0.383034
+v 0.386354 -0.502983 -0.384717
+v 0.38674 -0.48509 -0.381159
+v 0.386727 -0.467338 -0.376406
+v 0.38665 -0.449662 -0.371525
+v 0.386753 -0.43173 -0.372115
+v 0.386791 -0.413041 -0.377215
+v 0.38611 -0.39471 -0.37918
+v 0.3862 -0.376778 -0.37629
+v 0.386226 -0.359013 -0.371692
+v 0.38629 -0.341107 -0.370484
+v 0.385918 -0.322661 -0.373066
+v 0.385892 -0.304395 -0.374877
+v -0.630338 0.0465899 -0.12686
+v -0.642926 -0.00874765 -0.14275
+v -0.630274 0.0100193 -0.143007
+v 0.166507 -0.0357613 -0.26803
+v 0.372212 -0.0371101 -0.227824
+v 0.385006 -0.0373027 -0.224305
+v 0.307985 -0.0917925 -0.251151
+v -0.407575 -0.804707 -0.10072
+v -0.409001 -0.599452 -0.139359
+v -0.408667 -0.617795 -0.137303
+v -0.496914 -0.898541 -0.106372
+v -0.563966 -0.448224 -0.20713
+v -0.80971 0.0976628 -0.0382405
+v 0.375731 -0.915215 -0.270535
+v 0.37586 -0.896422 -0.276431
+v 0.375719 -0.877013 -0.286168
+v 0.375552 -0.857372 -0.295609
+v 0.375629 -0.838592 -0.301132
+v 0.375462 -0.81971 -0.304035
+v 0.375166 -0.799517 -0.319745
+v 0.375269 -0.780056 -0.333258
+v 0.375102 -0.761033 -0.337998
+v 0.375115 -0.742484 -0.344973
+v 0.373817 -0.72337 -0.353824
+v 0.375025 -0.704847 -0.358551
+v 0.374627 -0.686286 -0.36076
+v 0.374755 -0.668405 -0.358384
+v 0.37464 -0.650447 -0.356598
+v 0.37464 -0.632413 -0.356804
+v 0.374473 -0.613735 -0.364768
+v 0.374408 -0.594891 -0.371383
+v 0.374203 -0.576561 -0.372629
+v 0.374203 -0.558693 -0.373284
+v 0.374473 -0.54026 -0.378024
+v 0.37374 -0.521069 -0.385025
+v 0.373933 -0.502803 -0.387697
+v 0.37392 -0.484897 -0.384537
+v 0.373509 -0.467145 -0.380503
+v 0.373779 -0.449341 -0.376342
+v 0.37383 -0.431255 -0.376637
+v 0.373625 -0.412591 -0.382983
+v 0.373535 -0.394312 -0.384665
+v 0.373483 -0.37638 -0.381557
+v 0.373329 -0.358666 -0.376457
+v 0.373381 -0.340914 -0.373657
+v 0.373227 -0.322584 -0.375057
+v 0.373085 -0.304331 -0.37665
+v 0.373047 -0.285923 -0.376842
+v -0.407639 -0.786158 -0.0976628
+v -0.439739 0.53308 -0.0308287
+v -0.563954 -0.429739 -0.214285
+v 0.0130316 -0.298268 -0.475957
+v -0.809299 0.116828 -0.0444576
+v 0.362989 -0.915009 -0.274016
+v 0.362963 -0.896281 -0.278024
+v 0.36277 -0.876717 -0.287272
+v 0.362706 -0.857385 -0.297497
+v 0.362552 -0.838053 -0.303406
+v 0.362552 -0.819684 -0.305602
+v 0.362334 -0.799119 -0.324575
+v 0.362449 -0.779941 -0.336765
+v 0.362218 -0.760634 -0.342815
+v 0.362385 -0.742099 -0.350099
+v 0.362308 -0.723254 -0.358281
+v 0.362115 -0.70459 -0.36148
+v 0.362 -0.68617 -0.363162
+v 0.361781 -0.668058 -0.362687
+v 0.361614 -0.650088 -0.360657
+v 0.361602 -0.631989 -0.360979
+v 0.361332 -0.612888 -0.370201
+v 0.361293 -0.594301 -0.376997
+v 0.361499 -0.576356 -0.376367
+v 0.361293 -0.558347 -0.374286
+v 0.361396 -0.540363 -0.375263
+v 0.360985 -0.520967 -0.385141
+v 0.360831 -0.502482 -0.39173
+v 0.360792 -0.484627 -0.388724
+v 0.360612 -0.466824 -0.385256
+v 0.361178 -0.44884 -0.383201
+v 0.361088 -0.430639 -0.384896
+v 0.360548 -0.412154 -0.389007
+v 0.360638 -0.394004 -0.389405
+v 0.360548 -0.375982 -0.387812
+v 0.36042 -0.358243 -0.382828
+v 0.360664 -0.340516 -0.378885
+v 0.360484 -0.322353 -0.378589
+v 0.360137 -0.304164 -0.379643
+v 0.360137 -0.285769 -0.379925
+v -0.356592 -0.747365 -0.117342
+v -0.356643 -0.765798 -0.115749
+v -0.356374 -0.78427 -0.115698
+v -0.356374 -0.802972 -0.115967
+v 0.359289 -0.0370587 -0.230881
+v -0.407613 -0.767969 -0.095736
+v -0.408667 -0.636523 -0.132499
+v -0.564185 -0.411101 -0.221286
+v -0.703646 -0.923063 0.0288248
+v -0.809389 0.135736 -0.0497498
+v 0.350054 -0.933082 -0.276559
+v 0.350028 -0.914662 -0.276996
+v 0.350028 -0.896049 -0.279385
+v 0.349912 -0.876859 -0.287452
+v 0.349771 -0.857064 -0.298358
+v 0.349707 -0.838181 -0.303534
+v 0.349707 -0.819761 -0.307555
+v 0.349488 -0.798913 -0.327889
+v 0.349424 -0.779363 -0.341235
+v 0.349386 -0.760326 -0.347786
+v 0.349399 -0.741687 -0.354684
+v 0.349347 -0.722728 -0.362751
+v 0.349103 -0.704166 -0.365898
+v 0.349167 -0.686055 -0.364922
+v 0.349077 -0.66793 -0.364845
+v 0.348769 -0.649882 -0.364023
+v 0.348885 -0.631835 -0.364717
+v 0.348641 -0.612682 -0.375635
+v 0.348474 -0.593941 -0.381955
+v 0.348397 -0.575816 -0.382019
+v 0.348294 -0.557974 -0.378705
+v 0.348255 -0.540003 -0.377241
+v 0.348255 -0.521301 -0.385924
+v 0.34814 -0.502303 -0.395417
+v 0.348294 -0.484281 -0.394286
+v 0.348088 -0.466027 -0.395712
+v 0.347896 -0.447928 -0.395507
+v 0.347986 -0.429778 -0.395866
+v 0.347831 -0.411679 -0.395789
+v 0.347395 -0.393657 -0.395237
+v 0.347703 -0.375648 -0.392719
+v 0.347652 -0.357767 -0.389572
+v 0.347574 -0.339899 -0.386387
+v 0.347536 -0.321929 -0.384922
+v 0.347292 -0.303843 -0.384537
+v 0.346393 -0.0369688 -0.233977
+v 0.346341 -0.0186128 -0.230843
+v -0.158158 -0.92833 0.375044
+v -0.407755 -0.749831 -0.0955305
+v -0.408436 -0.655149 -0.127425
+v -0.439739 0.552245 -0.0374569
+v -0.564236 -0.392424 -0.226039
+v -0.809543 0.154619 -0.0514968
+v -0.809941 0.173463 -0.0520363
+v 0.337388 -0.933108 -0.279167
+v 0.337183 -0.914521 -0.278409
+v 0.337221 -0.896114 -0.279565
+v 0.337041 -0.876871 -0.287465
+v 0.3369 -0.857462 -0.297227
+v 0.336836 -0.838207 -0.303393
+v 0.336836 -0.81953 -0.310715
+v 0.336746 -0.799311 -0.32848
+v 0.336643 -0.779453 -0.343188
+v 0.336656 -0.760275 -0.351589
+v 0.33654 -0.741328 -0.359681
+v 0.336528 -0.722535 -0.366528
+v 0.336322 -0.703935 -0.369508
+v 0.336219 -0.685721 -0.369495
+v 0.336142 -0.667724 -0.367825
+v 0.335911 -0.649651 -0.367119
+v 0.337003 -0.632271 -0.368814
+v 0.336296 -0.612978 -0.379026
+v 0.335847 -0.593787 -0.385886
+v 0.335705 -0.575456 -0.387376
+v 0.335474 -0.55764 -0.383612
+v 0.335217 -0.53958 -0.381531
+v 0.335192 -0.520684 -0.38988
+v 0.335076 -0.501866 -0.399861
+v 0.33514 -0.483703 -0.401852
+v 0.335667 -0.465616 -0.404614
+v 0.33496 -0.446965 -0.40848
+v 0.334703 -0.428982 -0.406592
+v 0.334703 -0.411139 -0.403458
+v 0.335012 -0.393169 -0.400927
+v 0.334832 -0.375211 -0.399168
+v 0.334935 -0.357253 -0.39629
+v 0.334511 -0.339424 -0.394055
+v 0.334626 -0.321505 -0.391306
+v 0.334459 -0.303419 -0.391114
+v -0.808143 -0.490048 0.265692
+v 0.333689 -0.0367761 -0.236212
+v 0.333547 -0.0184715 -0.232757
+v -0.408256 -0.730679 -0.101671
+v -0.408243 -0.692837 -0.11431
+v -0.4085 -0.674237 -0.119564
+v -0.439894 0.571243 -0.040938
+v -0.439996 0.590203 -0.0426464
+v -0.440382 0.609214 -0.0412976
+v -0.564557 -0.374068 -0.229931
+v -0.810147 0.19232 -0.0522804
+v 0.324427 -0.932748 -0.281736
+v 0.324363 -0.914431 -0.280182
+v 0.324312 -0.89596 -0.28085
+v 0.32417 -0.876781 -0.286925
+v 0.324093 -0.857244 -0.296547
+v 0.323991 -0.838181 -0.303175
+v 0.324016 -0.819594 -0.312513
+v 0.323888 -0.799093 -0.32988
+v 0.323785 -0.77944 -0.343059
+v 0.323785 -0.760339 -0.353438
+v 0.323631 -0.741495 -0.361903
+v 0.323528 -0.722253 -0.369418
+v 0.323412 -0.703678 -0.372809
+v 0.323361 -0.685489 -0.372848
+v 0.323258 -0.667506 -0.371139
+v 0.323387 -0.649715 -0.368763
+v 0.323477 -0.632027 -0.372205
+v 0.323143 -0.612939 -0.381634
+v 0.323104 -0.593645 -0.389598
+v 0.322873 -0.575084 -0.392283
+v 0.322642 -0.557255 -0.388647
+v 0.322513 -0.539271 -0.3869
+v 0.322513 -0.520646 -0.393683
+v 0.32182 -0.501044 -0.405924
+v 0.322295 -0.483227 -0.408403
+v 0.322359 -0.464833 -0.411974
+v 0.322192 -0.446477 -0.415173
+v 0.322166 -0.428339 -0.415186
+v 0.321999 -0.410394 -0.41358
+v 0.322051 -0.392411 -0.411486
+v 0.322218 -0.374646 -0.406233
+v 0.321858 -0.356894 -0.402469
+v 0.321691 -0.339077 -0.399013
+v 0.321524 -0.321145 -0.397189
+v 0.32173 -0.302918 -0.397934
+v -0.397979 -0.242275 -0.259115
+v 0.320946 -0.0918439 -0.247002
+v 0.320805 -0.0733338 -0.248274
+v 0.320689 -0.0550421 -0.244934
+v 0.320625 -0.0368917 -0.238524
+v 0.320702 -0.0183431 -0.235955
+v -0.408166 -0.711565 -0.109506
+v -0.564442 -0.355468 -0.232641
+v -0.80989 0.211292 -0.0550421
+v 0.311556 -0.951451 -0.277792
+v 0.311595 -0.932684 -0.283573
+v 0.311466 -0.914148 -0.2832
+v 0.311402 -0.895626 -0.283136
+v 0.311376 -0.87718 -0.286206
+v 0.311248 -0.857706 -0.295442
+v 0.311145 -0.838374 -0.303393
+v 0.311197 -0.819479 -0.314016
+v 0.310978 -0.798849 -0.331216
+v 0.310953 -0.779466 -0.342969
+v 0.310811 -0.759992 -0.35444
+v 0.310657 -0.74084 -0.364023
+v 0.310593 -0.722163 -0.371049
+v 0.310516 -0.703627 -0.374363
+v 0.310503 -0.685438 -0.374672
+v 0.310477 -0.667429 -0.373143
+v 0.310413 -0.64951 -0.371293
+v 0.31022 -0.631655 -0.375083
+v 0.310118 -0.612823 -0.383265
+v 0.310079 -0.59335 -0.392167
+v 0.310041 -0.574891 -0.395571
+v 0.309732 -0.556921 -0.393284
+v 0.309617 -0.53877 -0.393272
+v 0.309655 -0.520196 -0.400285
+v 0.309437 -0.501198 -0.409714
+v 0.309295 -0.482675 -0.414595
+v 0.309462 -0.464537 -0.416984
+v 0.309514 -0.446246 -0.418898
+v 0.309321 -0.428134 -0.418667
+v 0.309373 -0.410073 -0.417395
+v 0.309154 -0.392154 -0.415443
+v 0.30873 -0.374363 -0.412976
+v 0.308872 -0.356521 -0.408699
+v 0.308962 -0.338705 -0.404242
+v 0.309064 -0.320798 -0.401416
+v 0.30909 -0.302674 -0.401865
+v -0.369463 -0.766312 -0.111189
+v 0.307947 -0.0732567 -0.251318
+v 0.307947 -0.0548366 -0.247144
+v 0.307831 -0.0367632 -0.2404
+v 0.308152 -0.017855 -0.237805
+v -0.564544 -0.337086 -0.23435
+v -0.0840917 -0.926262 0.1567
+v -0.601667 -0.569124 -0.073732
+v -0.810211 0.230008 -0.053886
+v 0.298711 -0.932363 -0.286553
+v 0.298621 -0.913866 -0.286502
+v 0.298647 -0.89569 -0.284099
+v 0.29848 -0.877051 -0.287696
+v 0.298428 -0.857745 -0.295442
+v 0.298377 -0.838695 -0.305718
+v 0.298338 -0.818644 -0.320041
+v 0.29812 -0.798412 -0.335994
+v 0.298184 -0.779337 -0.344665
+v 0.297902 -0.759697 -0.355609
+v 0.297825 -0.741007 -0.364447
+v 0.297683 -0.722137 -0.370638
+v 0.297645 -0.703678 -0.374235
+v 0.297645 -0.685361 -0.375918
+v 0.297722 -0.667416 -0.374723
+v 0.297529 -0.649278 -0.374119
+v 0.297465 -0.631205 -0.37778
+v 0.297362 -0.612361 -0.386001
+v 0.297144 -0.593106 -0.395186
+v 0.297144 -0.574673 -0.398731
+v 0.297028 -0.556702 -0.397048
+v 0.2969 -0.538501 -0.398577
+v 0.296746 -0.519669 -0.406592
+v 0.296836 -0.501185 -0.413747
+v 0.296681 -0.482585 -0.418513
+v 0.296463 -0.464178 -0.421339
+v 0.296463 -0.446066 -0.42166
+v 0.296386 -0.428044 -0.42026
+v 0.29636 -0.41006 -0.418692
+v 0.296592 -0.392038 -0.416419
+v 0.296527 -0.374042 -0.414916
+v 0.296168 -0.356149 -0.413978
+v 0.296168 -0.338345 -0.409431
+v 0.296091 -0.321017 -0.406027
+v 0.295898 -0.302455 -0.405899
+v -0.537454 -0.982832 -0.117509
+v -0.559548 -0.983385 -0.0979454
+v 0.295294 -0.0729099 -0.252821
+v 0.295076 -0.0548366 -0.248608
+v 0.295037 -0.0366091 -0.241093
+v 0.29496 -0.018266 -0.239257
+v 0.295191 0.000398204 -0.240169
+v -0.491198 0.551834 -0.00797693
+v -0.50412 0.55177 0.000539503
+v -0.49148 0.570806 -0.0064098
+v -0.564609 -0.31882 -0.234298
+v -0.56746 0.325654 -0.0684911
+v -0.810352 0.248646 -0.0471037
+v 0.285814 -0.93208 -0.289507
+v 0.28566 -0.913635 -0.289058
+v 0.285724 -0.895433 -0.286887
+v 0.285647 -0.876846 -0.288801
+v 0.285622 -0.858053 -0.296084
+v 0.285519 -0.838374 -0.308762
+v 0.285442 -0.817847 -0.327992
+v 0.285056 -0.797269 -0.345205
+v 0.285288 -0.778849 -0.349354
+v 0.284157 -0.759941 -0.355494
+v 0.284954 -0.741045 -0.362276
+v 0.284851 -0.722612 -0.367876
+v 0.284838 -0.703987 -0.372681
+v 0.284954 -0.685695 -0.374774
+v 0.284928 -0.667365 -0.376252
+v 0.285018 -0.649176 -0.378217
+v 0.284517 -0.630383 -0.383663
+v 0.284722 -0.612066 -0.391191
+v 0.284337 -0.592721 -0.400118
+v 0.284183 -0.574313 -0.403317
+v 0.284273 -0.556484 -0.400593
+v 0.284183 -0.538436 -0.400593
+v 0.283798 -0.519181 -0.411037
+v 0.283785 -0.500645 -0.417947
+v 0.283721 -0.482341 -0.421403
+v 0.283759 -0.464126 -0.423676
+v 0.283566 -0.44586 -0.42473
+v 0.283464 -0.427903 -0.42306
+v 0.283464 -0.410009 -0.42017
+v 0.283515 -0.392077 -0.417498
+v 0.283476 -0.374068 -0.415995
+v 0.283335 -0.355918 -0.417369
+v 0.283065 -0.338063 -0.415057
+v 0.283309 -0.320233 -0.409726
+v 0.283078 -0.302224 -0.40929
+v 0.283104 -0.28383 -0.409855
+v 0.162037 -0.957912 -0.191896
+v 0.161228 -0.942948 -0.181735
+v 0.147881 -0.943474 -0.183855
+v 0.279071 -0.917552 -0.109352
+v 0.282128 -0.0366219 -0.241196
+v 0.282128 -0.018266 -0.239513
+v -0.452752 0.533003 -0.0258961
+v -0.491031 0.532836 -0.00797693
+v -0.564737 -0.3004 -0.232821
+v -0.564878 -0.282044 -0.229982
+v -0.564866 -0.263637 -0.228184
+v -0.567396 0.306836 -0.0716125
+v -0.810725 0.267606 -0.0426207
+v 0.273008 -0.931978 -0.29137
+v 0.272892 -0.913532 -0.291036
+v 0.272815 -0.895163 -0.28943
+v 0.272841 -0.876717 -0.290317
+v 0.272776 -0.857873 -0.297446
+v 0.272738 -0.838477 -0.312372
+v 0.272635 -0.817333 -0.334594
+v 0.272327 -0.797051 -0.350394
+v 0.271954 -0.777821 -0.356046
+v 0.272314 -0.759684 -0.357587
+v 0.272275 -0.741431 -0.361839
+v 0.272083 -0.722933 -0.366541
+v 0.272018 -0.704115 -0.372629
+v 0.27189 -0.68522 -0.378692
+v 0.271916 -0.666697 -0.38383
+v 0.27207 -0.648521 -0.385963
+v 0.27171 -0.629921 -0.390227
+v 0.271595 -0.611141 -0.398423
+v 0.271505 -0.592194 -0.406682
+v 0.271556 -0.574082 -0.407234
+v 0.271453 -0.556214 -0.403895
+v 0.271132 -0.538141 -0.40315
+v 0.271119 -0.519464 -0.411769
+v 0.270952 -0.500594 -0.419604
+v 0.270914 -0.482302 -0.423381
+v 0.270811 -0.463882 -0.426502
+v 0.270708 -0.445629 -0.428095
+v 0.270683 -0.427633 -0.426682
+v 0.270618 -0.409778 -0.423561
+v 0.270657 -0.391897 -0.420696
+v 0.270644 -0.373939 -0.419232
+v 0.270644 -0.355789 -0.419463
+v 0.27031 -0.337818 -0.418667
+v 0.270323 -0.320028 -0.414132
+v 0.270297 -0.30216 -0.411088
+v 0.270182 -0.283791 -0.411204
+v 0.269899 -0.265744 -0.408814
+v -0.0356393 -0.927996 -0.34031
+v -0.0356007 -0.946531 -0.338448
+v -0.511262 -0.982717 -0.112371
+v -0.487408 -0.979056 -0.134477
+v 0.661976 -0.899261 0.354376
+v 0.646883 -0.902896 0.354569
+v 0.269205 -0.0183559 -0.239385
+v 0.269103 0.000102762 -0.24153
+v -0.567396 0.288133 -0.076224
+v -0.475128 -0.980571 -0.130675
+v -0.810532 0.28618 -0.0387414
+v 0.260406 -0.950899 -0.288685
+v 0.260137 -0.931695 -0.294517
+v 0.260021 -0.913224 -0.29426
+v 0.260085 -0.895176 -0.290329
+v 0.25997 -0.876756 -0.290304
+v 0.259892 -0.857616 -0.298602
+v 0.259931 -0.838939 -0.312693
+v 0.259751 -0.816717 -0.340966
+v 0.259314 -0.796331 -0.35647
+v 0.259289 -0.777397 -0.363034
+v 0.259353 -0.759067 -0.36365
+v 0.259314 -0.741071 -0.364357
+v 0.259147 -0.722253 -0.370343
+v 0.259083 -0.703408 -0.378397
+v 0.259006 -0.684552 -0.386631
+v 0.258801 -0.665785 -0.392861
+v 0.258801 -0.647442 -0.396419
+v 0.258749 -0.629201 -0.398114
+v 0.258736 -0.610588 -0.404884
+v 0.258659 -0.591834 -0.411525
+v 0.258634 -0.573722 -0.411807
+v 0.258569 -0.55597 -0.407106
+v 0.258313 -0.538051 -0.404974
+v 0.258133 -0.519233 -0.412655
+v 0.258043 -0.500427 -0.420953
+v 0.258017 -0.482033 -0.426284
+v 0.25794 -0.463677 -0.429521
+v 0.25794 -0.445436 -0.431615
+v 0.257734 -0.42735 -0.431191
+v 0.257709 -0.409521 -0.428108
+v 0.257606 -0.391705 -0.424794
+v 0.257773 -0.373644 -0.423972
+v 0.257542 -0.355596 -0.423548
+v 0.257478 -0.3376 -0.421955
+v 0.257298 -0.319822 -0.418461
+v 0.257413 -0.301954 -0.414222
+v 0.257298 -0.28365 -0.414158
+v 0.257208 -0.265564 -0.410947
+v 0.256373 -0.0184972 -0.239064
+v 0.256257 1.28453e-05 -0.240246
+v -0.491044 0.513838 -0.00838798
+v -0.490735 0.494801 -0.0065511
+v -0.567435 0.269379 -0.0789215
+v -0.810712 0.305089 -0.0371743
+v 0.247407 -0.950591 -0.291396
+v 0.24724 -0.931554 -0.295776
+v 0.247253 -0.913095 -0.296521
+v 0.247111 -0.894816 -0.294324
+v 0.247176 -0.87664 -0.292449
+v 0.247047 -0.857411 -0.299989
+v 0.246932 -0.837835 -0.316752
+v 0.246816 -0.816524 -0.34419
+v 0.246765 -0.796524 -0.358923
+v 0.246636 -0.777269 -0.367093
+v 0.246418 -0.758656 -0.368236
+v 0.246443 -0.740711 -0.36708
+v 0.246302 -0.721996 -0.373503
+v 0.246264 -0.703075 -0.383419
+v 0.246109 -0.684141 -0.391332
+v 0.246097 -0.665643 -0.396663
+v 0.246225 -0.64721 -0.401994
+v 0.245878 -0.628559 -0.406322
+v 0.245711 -0.609985 -0.41105
+v 0.245853 -0.591539 -0.416534
+v 0.24557 -0.573363 -0.416059
+v 0.245544 -0.555662 -0.411358
+v 0.245467 -0.537858 -0.408249
+v 0.245313 -0.519335 -0.412912
+v 0.245326 -0.500723 -0.42184
+v 0.245236 -0.482058 -0.428365
+v 0.245185 -0.463651 -0.431679
+v 0.244979 -0.445218 -0.434467
+v 0.245095 -0.427196 -0.433683
+v 0.244722 -0.409251 -0.432501
+v 0.244838 -0.39146 -0.428352
+v 0.244953 -0.373336 -0.428827
+v 0.244542 -0.355198 -0.429701
+v 0.244388 -0.337279 -0.427941
+v 0.244414 -0.319514 -0.423317
+v 0.244568 -0.301646 -0.419001
+v 0.244504 -0.283419 -0.417549
+v 0.24426 -0.265358 -0.415507
+v 0.243438 1.28453e-05 -0.239218
+v -0.067714 -0.914804 0.473812
+v -0.0816126 -0.916461 0.472399
+v -0.490414 0.475738 -0.00154144
+v -0.565033 -0.245153 -0.226848
+v -0.811174 0.323933 -0.0325628
+v 0.234587 -0.950526 -0.29313
+v 0.234446 -0.931477 -0.297754
+v 0.234317 -0.912864 -0.298974
+v 0.234279 -0.894701 -0.296084
+v 0.234279 -0.876358 -0.294941
+v 0.234279 -0.85804 -0.299462
+v 0.234061 -0.837706 -0.318268
+v 0.233945 -0.816409 -0.345795
+v 0.233804 -0.796139 -0.361762
+v 0.233727 -0.777012 -0.370189
+v 0.233598 -0.758438 -0.371627
+v 0.233585 -0.740621 -0.36866
+v 0.233547 -0.722124 -0.373824
+v 0.23347 -0.703075 -0.385385
+v 0.233354 -0.684205 -0.393426
+v 0.233418 -0.665759 -0.398936
+v 0.233213 -0.646953 -0.404974
+v 0.233277 -0.628482 -0.410253
+v 0.233418 -0.609664 -0.416496
+v 0.233084 -0.591076 -0.421184
+v 0.232827 -0.572965 -0.421377
+v 0.232609 -0.555379 -0.415854
+v 0.232686 -0.537627 -0.411705
+v 0.232583 -0.519233 -0.416727
+v 0.232391 -0.500222 -0.426079
+v 0.232314 -0.481763 -0.431229
+v 0.232262 -0.463394 -0.434595
+v 0.232198 -0.445179 -0.436342
+v 0.232147 -0.427055 -0.436586
+v 0.232159 -0.409084 -0.435199
+v 0.23207 -0.391139 -0.433413
+v 0.231838 -0.372976 -0.434672
+v 0.23171 -0.354736 -0.436278
+v 0.231761 -0.336739 -0.434916
+v 0.23189 -0.318897 -0.43051
+v 0.231761 -0.301145 -0.425629
+v 0.231684 -0.283098 -0.422469
+v 0.0131472 -0.923654 0.197355
+v 0.00452797 -0.923693 0.218897
+v -0.000250483 -0.924245 0.195197
+v 0.102062 -0.0175724 -0.266463
+v -0.565071 -0.226617 -0.226809
+v -0.567306 0.250663 -0.0792041
+v -0.567152 0.231858 -0.0809382
+v 0.221716 -0.950321 -0.294478
+v 0.221626 -0.931387 -0.299527
+v 0.221472 -0.912748 -0.300541
+v 0.221357 -0.894469 -0.298782
+v 0.221447 -0.876255 -0.296791
+v 0.221472 -0.857848 -0.300991
+v 0.221318 -0.838271 -0.318833
+v 0.221061 -0.815959 -0.348776
+v 0.220933 -0.79592 -0.365089
+v 0.220894 -0.776794 -0.373567
+v 0.220843 -0.758348 -0.373657
+v 0.22065 -0.740364 -0.371396
+v 0.22074 -0.722253 -0.374145
+v 0.220612 -0.70328 -0.383753
+v 0.220509 -0.684372 -0.393747
+v 0.220483 -0.665733 -0.400542
+v 0.220368 -0.646941 -0.406798
+v 0.220175 -0.628109 -0.412796
+v 0.220188 -0.609625 -0.418166
+v 0.220072 -0.591141 -0.421403
+v 0.219931 -0.572887 -0.422854
+v 0.219764 -0.555148 -0.419206
+v 0.219854 -0.537422 -0.415121
+v 0.219764 -0.519027 -0.420067
+v 0.219545 -0.500003 -0.429341
+v 0.219507 -0.481596 -0.434582
+v 0.219353 -0.463189 -0.437601
+v 0.219301 -0.444974 -0.439425
+v 0.219263 -0.426875 -0.43954
+v 0.219301 -0.408917 -0.438346
+v 0.219199 -0.390844 -0.438256
+v 0.218788 -0.372372 -0.442315
+v 0.21889 -0.354196 -0.444434
+v 0.218595 -0.336174 -0.444113
+v 0.218788 -0.318448 -0.438204
+v 0.218749 -0.300824 -0.431808
+v 0.218081 -0.0726915 -0.264806
+v -0.0430382 -0.922421 0.0917154
+v 0.220046 -0.912273 -0.0298782
+v 0.206636 -0.912838 -0.0320362
+v 0.215949 -0.912055 -0.0548237
+v -0.490466 0.437845 0.0024663
+v -0.490222 0.456869 0.00127168
+v -0.56475 -0.208338 -0.22433
+v -0.566972 0.213116 -0.0844321
+v 0.208871 -0.950218 -0.296123
+v 0.208755 -0.931233 -0.300747
+v 0.208627 -0.912671 -0.301993
+v 0.208601 -0.894302 -0.301094
+v 0.208524 -0.875972 -0.299706
+v 0.208653 -0.857976 -0.301055
+v 0.208511 -0.838657 -0.319206
+v 0.208229 -0.815933 -0.350497
+v 0.2081 -0.795882 -0.366785
+v 0.207959 -0.776627 -0.37462
+v 0.207882 -0.758078 -0.376239
+v 0.207869 -0.740146 -0.37507
+v 0.207779 -0.721739 -0.378358
+v 0.207586 -0.70283 -0.386168
+v 0.207638 -0.684526 -0.394004
+v 0.207484 -0.665425 -0.401403
+v 0.207394 -0.646825 -0.408275
+v 0.207445 -0.628135 -0.414942
+v 0.207368 -0.609702 -0.41841
+v 0.207355 -0.59132 -0.420452
+v 0.20724 -0.57299 -0.421994
+v 0.20706 -0.554981 -0.421518
+v 0.206944 -0.537216 -0.418127
+v 0.206983 -0.519014 -0.421968
+v 0.206726 -0.499952 -0.431037
+v 0.206726 -0.481583 -0.436676
+v 0.206623 -0.463176 -0.439926
+v 0.206597 -0.444897 -0.441673
+v 0.206507 -0.426824 -0.441621
+v 0.206366 -0.408725 -0.441352
+v 0.206225 -0.3906 -0.443073
+v 0.206482 -0.37209 -0.448635
+v 0.206212 -0.353721 -0.451409
+v 0.205917 -0.335686 -0.45096
+v 0.205698 -0.318075 -0.445822
+v 0.206122 -0.300349 -0.437164
+v -0.375731 0.590884 -0.0815034
+v -0.564737 -0.19002 -0.220991
+v -0.565649 -0.171395 -0.219526
+v -0.566818 0.194362 -0.0875022
+v 0.195987 -0.949987 -0.297202
+v 0.195897 -0.931066 -0.302083
+v 0.195794 -0.912504 -0.304087
+v 0.195717 -0.894046 -0.303945
+v 0.195794 -0.875895 -0.301762
+v 0.195692 -0.857462 -0.303483
+v 0.195486 -0.836357 -0.327388
+v 0.195319 -0.815484 -0.351704
+v 0.195204 -0.795766 -0.366425
+v 0.195139 -0.776717 -0.3748
+v 0.195088 -0.75804 -0.378294
+v 0.195101 -0.739953 -0.378667
+v 0.195024 -0.721443 -0.383663
+v 0.194857 -0.702561 -0.391435
+v 0.194895 -0.684115 -0.396701
+v 0.19469 -0.665399 -0.403163
+v 0.19451 -0.646298 -0.412527
+v 0.194446 -0.627647 -0.419258
+v 0.194292 -0.609098 -0.423933
+v 0.194369 -0.591115 -0.423304
+v 0.194369 -0.573067 -0.422122
+v 0.19433 -0.555045 -0.422148
+v 0.194125 -0.537011 -0.421531
+v 0.193983 -0.518513 -0.426014
+v 0.194099 -0.500337 -0.432257
+v 0.193855 -0.48148 -0.438166
+v 0.193701 -0.463047 -0.441069
+v 0.193701 -0.444846 -0.443099
+v 0.193829 -0.426772 -0.443856
+v 0.193752 -0.408686 -0.443728
+v 0.193752 -0.390523 -0.445565
+v 0.193482 -0.372 -0.449868
+v 0.192994 -0.353541 -0.45376
+v 0.1932 -0.335416 -0.454634
+v 0.193033 -0.317613 -0.451101
+v 0.193046 -0.300092 -0.443188
+v -0.615219 -0.449573 -0.196148
+v -0.615348 -0.430703 -0.204369
+v -0.613716 -0.568135 -0.0678746
+v -0.613819 -0.548212 -0.0890179
+v -0.601179 -0.547557 -0.0989987
+v 0.723903 -0.880764 0.350484
+v 0.708386 -0.885876 0.351794
+v 0.713601 -0.892029 0.335044
+v -0.565559 -0.153026 -0.217779
+v -0.566279 0.157034 -0.093244
+v -0.566651 0.175621 -0.0906493
+v -0.306148 -0.63538 -0.136802
+v 0.183142 -0.950128 -0.2976
+v 0.18309 -0.931233 -0.302995
+v 0.182975 -0.912376 -0.305847
+v 0.182923 -0.893943 -0.305988
+v 0.182846 -0.8756 -0.304536
+v 0.182795 -0.856897 -0.308056
+v 0.182718 -0.836344 -0.332642
+v 0.182538 -0.815856 -0.353849
+v 0.182422 -0.796062 -0.36699
+v 0.182268 -0.776537 -0.376008
+v 0.182243 -0.75795 -0.379823
+v 0.182153 -0.739517 -0.383124
+v 0.182204 -0.720994 -0.390189
+v 0.182063 -0.702252 -0.396624
+v 0.181986 -0.683845 -0.399938
+v 0.181909 -0.665284 -0.406759
+v 0.181806 -0.646414 -0.414813
+v 0.181716 -0.627544 -0.423034
+v 0.181433 -0.608739 -0.428648
+v 0.181498 -0.590755 -0.428108
+v 0.181395 -0.572939 -0.424396
+v 0.18151 -0.555007 -0.423638
+v 0.181254 -0.536677 -0.426207
+v 0.180843 -0.518051 -0.432077
+v 0.181215 -0.499926 -0.435212
+v 0.181112 -0.481557 -0.4385
+v 0.180894 -0.463291 -0.442045
+v 0.180804 -0.44464 -0.44604
+v 0.180624 -0.426271 -0.448943
+v 0.180676 -0.408198 -0.449483
+v 0.180688 -0.390163 -0.449804
+v 0.180239 -0.37164 -0.453645
+v 0.180406 -0.353336 -0.457832
+v 0.180342 -0.33507 -0.459579
+v 0.180097 -0.317382 -0.455738
+v 0.180085 -0.299899 -0.447749
+v 0.1802 -0.281954 -0.440362
+v 0.1667 -0.0907006 -0.278923
+v 0.17943 -0.0542457 -0.267927
+v -0.565739 -0.134452 -0.218319
+v 0.170322 -0.95 -0.299154
+v 0.170245 -0.931079 -0.304228
+v 0.170142 -0.912286 -0.307465
+v 0.170091 -0.893814 -0.307812
+v 0.17004 -0.875535 -0.306399
+v 0.17013 -0.857282 -0.310882
+v 0.169796 -0.835612 -0.338936
+v 0.16968 -0.81533 -0.358666
+v 0.169218 -0.796344 -0.367812
+v 0.1695 -0.777063 -0.375519
+v 0.169423 -0.75786 -0.381403
+v 0.169423 -0.739427 -0.386862
+v 0.169282 -0.720506 -0.394775
+v 0.169128 -0.701918 -0.399437
+v 0.169089 -0.68364 -0.403188
+v 0.169025 -0.664975 -0.409714
+v 0.168806 -0.646016 -0.417498
+v 0.169025 -0.627493 -0.425269
+v 0.168678 -0.608649 -0.430741
+v 0.168652 -0.590537 -0.431101
+v 0.168639 -0.572862 -0.426567
+v 0.168383 -0.554801 -0.425655
+v 0.168344 -0.536317 -0.430831
+v 0.168267 -0.517691 -0.437537
+v 0.168164 -0.499464 -0.439181
+v 0.16819 -0.481442 -0.439823
+v 0.168113 -0.462996 -0.444576
+v 0.1681 -0.444512 -0.449945
+v 0.167907 -0.425963 -0.454351
+v 0.167817 -0.407735 -0.455995
+v 0.167702 -0.389662 -0.455982
+v 0.167676 -0.371486 -0.457883
+v 0.167689 -0.353117 -0.461827
+v 0.167393 -0.334928 -0.462611
+v 0.167214 -0.317305 -0.458654
+v 0.167162 -0.299796 -0.450767
+v 0.167316 -0.281787 -0.4436
+v 0.166571 -0.0725631 -0.273759
+v 0.166636 -0.0541686 -0.268492
+v -0.565816 -0.0604885 -0.208402
+v -0.56597 -0.0423638 -0.200284
+v 0.15749 -0.950269 -0.299848
+v 0.157374 -0.931143 -0.304408
+v 0.157284 -0.912157 -0.309045
+v 0.157233 -0.893712 -0.309726
+v 0.157207 -0.875458 -0.308249
+v 0.157233 -0.857244 -0.312539
+v 0.156848 -0.834675 -0.343291
+v 0.156783 -0.814764 -0.361377
+v 0.156681 -0.795689 -0.369649
+v 0.156629 -0.777012 -0.375147
+v 0.157631 -0.757731 -0.383329
+v 0.156514 -0.73917 -0.390009
+v 0.156514 -0.72048 -0.396766
+v 0.156308 -0.701867 -0.401338
+v 0.156321 -0.683614 -0.404909
+v 0.156102 -0.664487 -0.414299
+v 0.156102 -0.64581 -0.422944
+v 0.156 -0.626992 -0.429431
+v 0.155858 -0.608572 -0.432591
+v 0.155769 -0.590434 -0.432642
+v 0.155691 -0.572643 -0.429328
+v 0.155846 -0.554724 -0.42947
+v 0.15546 -0.53579 -0.437292
+v 0.155524 -0.517511 -0.441236
+v 0.155357 -0.499258 -0.442598
+v 0.15528 -0.481172 -0.442623
+v 0.155242 -0.462816 -0.447633
+v 0.155088 -0.444113 -0.454184
+v 0.155139 -0.42568 -0.459515
+v 0.154972 -0.407414 -0.460928
+v 0.154779 -0.389341 -0.460491
+v 0.154985 -0.371537 -0.460427
+v 0.154677 -0.352937 -0.464422
+v 0.154484 -0.334813 -0.465334
+v 0.154574 -0.316919 -0.460016
+v 0.154471 -0.29945 -0.453105
+v 0.154458 -0.281697 -0.445205
+v 0.15433 -0.263765 -0.441763
+v -0.566112 0.0122287 -0.179141
+v -0.566176 -0.00593453 -0.185897
+v 0.153777 -0.0725117 -0.274324
+v 0.1537 -0.0542971 -0.269417
+v -0.565803 -0.0786774 -0.215133
+v 0.144619 -0.949974 -0.300824
+v 0.144555 -0.93104 -0.306052
+v 0.144426 -0.912042 -0.310497
+v 0.144362 -0.893429 -0.312154
+v 0.14431 -0.875368 -0.309739
+v 0.144349 -0.857347 -0.314633
+v 0.144041 -0.834726 -0.346874
+v 0.143925 -0.815098 -0.361865
+v 0.143861 -0.79592 -0.370163
+v 0.143771 -0.777141 -0.375352
+v 0.143745 -0.757834 -0.385153
+v 0.143745 -0.738746 -0.394864
+v 0.14354 -0.720133 -0.399514
+v 0.14354 -0.702034 -0.401904
+v 0.143476 -0.683537 -0.406862
+v 0.143206 -0.664153 -0.417228
+v 0.143154 -0.645463 -0.425822
+v 0.143065 -0.626735 -0.431975
+v 0.142962 -0.608353 -0.435764
+v 0.142885 -0.590229 -0.435623
+v 0.142923 -0.572579 -0.43173
+v 0.14282 -0.55457 -0.433259
+v 0.142641 -0.53561 -0.440671
+v 0.142602 -0.51728 -0.4441
+v 0.142602 -0.499232 -0.444499
+v 0.142409 -0.480992 -0.445796
+v 0.142345 -0.462572 -0.450883
+v 0.142551 -0.444216 -0.456869
+v 0.14214 -0.425423 -0.462392
+v 0.14196 -0.40708 -0.465167
+v 0.141934 -0.389123 -0.463831
+v 0.142101 -0.371332 -0.462212
+v 0.141741 -0.352925 -0.465308
+v 0.141652 -0.334736 -0.466927
+v 0.141587 -0.317086 -0.462212
+v 0.141574 -0.299462 -0.454479
+v 0.141523 -0.281659 -0.448057
+v -0.565919 -0.0242776 -0.193566
+v -0.565713 -0.0972004 -0.218396
+v -0.565585 -0.115839 -0.219603
+v 0.140829 -0.0542072 -0.271306
+v 0.140791 -0.0356457 -0.271537
+v -0.385006 -0.260438 -0.263136
+v 0.131619 -0.912132 -0.310882
+v 0.131542 -0.893493 -0.312475
+v 0.13144 -0.875189 -0.311049
+v 0.131401 -0.856987 -0.315712
+v 0.131208 -0.835047 -0.347144
+v 0.131106 -0.815317 -0.362199
+v 0.131003 -0.795612 -0.371229
+v 0.130964 -0.777436 -0.375879
+v 0.130939 -0.757898 -0.38699
+v 0.130861 -0.738463 -0.398166
+v 0.130656 -0.719889 -0.402584
+v 0.130643 -0.7017 -0.404678
+v 0.13054 -0.683485 -0.406541
+v 0.130386 -0.664487 -0.416111
+v 0.130258 -0.645476 -0.425552
+v 0.130155 -0.626851 -0.432424
+v 0.130155 -0.608443 -0.436239
+v 0.130027 -0.590164 -0.437151
+v 0.129988 -0.572348 -0.434133
+v 0.129924 -0.554198 -0.436226
+v 0.129834 -0.535585 -0.442649
+v 0.129898 -0.517486 -0.444833
+v 0.129744 -0.499168 -0.446079
+v 0.129577 -0.480761 -0.449033
+v 0.129718 -0.462431 -0.454826
+v 0.129641 -0.444113 -0.458436
+v 0.129397 -0.4255 -0.46288
+v 0.12914 -0.407003 -0.467016
+v 0.129076 -0.38893 -0.466901
+v 0.129089 -0.371101 -0.464833
+v 0.129025 -0.35295 -0.464974
+v 0.12887 -0.33471 -0.467595
+v 0.128755 -0.316958 -0.463946
+v 0.128729 -0.299385 -0.456162
+v 0.128678 -0.281569 -0.44974
+v 0.433972 -0.969242 -0.0310085
+v 0.127997 -0.0541558 -0.272911
+v 0.127894 -0.0357356 -0.272641
+v 0.728296 -0.921034 0.176661
+v -0.173778 -0.969653 0.566966
+v 0.118736 -0.911785 -0.313451
+v 0.118671 -0.893365 -0.313862
+v 0.118569 -0.874945 -0.311717
+v 0.11853 -0.856563 -0.316585
+v 0.118363 -0.834687 -0.348429
+v 0.118222 -0.814944 -0.365179
+v 0.118106 -0.796241 -0.370574
+v 0.118093 -0.77723 -0.377112
+v 0.118093 -0.757795 -0.388583
+v 0.117836 -0.737962 -0.402225
+v 0.117862 -0.719709 -0.406143
+v 0.117682 -0.701186 -0.408904
+v 0.117669 -0.68319 -0.40947
+v 0.117605 -0.664783 -0.414852
+v 0.117425 -0.645772 -0.424344
+v 0.117361 -0.626915 -0.432437
+v 0.117271 -0.608366 -0.437716
+v 0.117168 -0.590087 -0.438628
+v 0.117143 -0.572284 -0.435931
+v 0.117014 -0.554095 -0.437318
+v 0.116924 -0.535443 -0.443908
+v 0.116834 -0.5171 -0.447093
+v 0.116783 -0.498783 -0.450587
+v 0.116924 -0.480427 -0.456342
+v 0.116603 -0.461827 -0.460542
+v 0.116526 -0.443612 -0.4622
+v 0.116475 -0.425385 -0.464101
+v 0.116359 -0.407067 -0.46735
+v 0.116244 -0.388866 -0.468686
+v 0.116166 -0.370947 -0.467312
+v 0.116141 -0.35295 -0.466092
+v 0.116077 -0.334697 -0.467929
+v 0.115922 -0.316842 -0.465693
+v 0.115948 -0.29918 -0.458128
+v 0.115781 -0.281505 -0.452733
+v 0.115139 -0.0542457 -0.27277
+v 0.114998 -0.0357485 -0.27146
+v -0.3978 -0.260528 -0.262596
+v 0.105929 -0.911888 -0.314016
+v 0.105826 -0.893249 -0.315455
+v 0.105762 -0.875124 -0.312488
+v 0.105685 -0.857218 -0.316161
+v 0.105543 -0.834456 -0.348095
+v 0.105376 -0.815047 -0.363278
+v 0.105286 -0.795972 -0.371717
+v 0.105197 -0.776909 -0.37814
+v 0.105197 -0.75768 -0.39006
+v 0.105338 -0.738168 -0.405154
+v 0.105055 -0.719465 -0.409637
+v 0.10503 -0.701212 -0.411384
+v 0.104811 -0.682946 -0.412848
+v 0.104721 -0.664564 -0.416046
+v 0.104657 -0.64608 -0.422944
+v 0.104554 -0.62721 -0.43114
+v 0.104541 -0.608469 -0.438127
+v 0.104362 -0.590177 -0.439129
+v 0.104297 -0.572219 -0.437434
+v 0.104374 -0.554198 -0.438384
+v 0.104118 -0.535675 -0.444537
+v 0.10404 -0.517049 -0.448905
+v 0.103976 -0.498423 -0.456971
+v 0.103938 -0.479849 -0.462315
+v 0.103938 -0.461711 -0.464486
+v 0.103732 -0.44342 -0.465963
+v 0.103578 -0.425321 -0.465655
+v 0.103475 -0.40726 -0.465526
+v 0.10345 -0.389046 -0.467749
+v 0.103398 -0.370985 -0.468198
+v 0.103257 -0.352912 -0.467517
+v 0.103244 -0.334646 -0.469508
+v 0.103167 -0.281106 -0.453773
+v 0.102204 -0.0360054 -0.270792
+v 0.0930192 -0.911759 -0.315301
+v 0.0929807 -0.893172 -0.317022
+v 0.0929807 -0.87533 -0.313579
+v 0.0928394 -0.856935 -0.317266
+v 0.0926724 -0.835458 -0.343689
+v 0.0925183 -0.815689 -0.360426
+v 0.0924026 -0.79646 -0.370574
+v 0.0923513 -0.776729 -0.379501
+v 0.0922999 -0.757577 -0.391512
+v 0.092287 -0.737975 -0.406669
+v 0.0920944 -0.71917 -0.412437
+v 0.0919916 -0.700929 -0.41412
+v 0.0919274 -0.68265 -0.415584
+v 0.0919145 -0.664551 -0.417832
+v 0.0917989 -0.645887 -0.424306
+v 0.0906685 -0.626863 -0.432745
+v 0.0916833 -0.608366 -0.439283
+v 0.0914264 -0.589933 -0.441737
+v 0.0914649 -0.571975 -0.440735
+v 0.0914906 -0.553825 -0.4427
+v 0.0914264 -0.535546 -0.445937
+v 0.0915163 -0.517229 -0.451358
+v 0.0912851 -0.499258 -0.457318
+v 0.0910154 -0.479746 -0.463741
+v 0.0909768 -0.461416 -0.467376
+v 0.0908355 -0.443176 -0.468802
+v 0.0907456 -0.425205 -0.467633
+v 0.0906685 -0.407299 -0.465526
+v 0.0905658 -0.389097 -0.467338
+v 0.0906172 -0.371036 -0.468147
+v 0.0905015 -0.352822 -0.46947
+v 0.0905786 -0.334504 -0.471679
+v 0.0892812 -0.0360054 -0.268158
+v -0.39252 -0.973404 -0.191793
+v 0.0801996 -0.911682 -0.317086
+v 0.0801739 -0.893249 -0.317818
+v 0.0800712 -0.874919 -0.315853
+v 0.0800455 -0.85691 -0.31715
+v 0.0798271 -0.835497 -0.341865
+v 0.0796858 -0.815664 -0.360234
+v 0.0795959 -0.796344 -0.370163
+v 0.079506 -0.776961 -0.379823
+v 0.0793647 -0.758001 -0.392167
+v 0.0794161 -0.737783 -0.407941
+v 0.0792491 -0.719375 -0.413053
+v 0.0791206 -0.700801 -0.415481
+v 0.0790949 -0.682586 -0.417241
+v 0.0790821 -0.664346 -0.42103
+v 0.0790307 -0.645707 -0.427671
+v 0.0788894 -0.626606 -0.436869
+v 0.0787738 -0.608122 -0.442238
+v 0.0786325 -0.589715 -0.445282
+v 0.0787353 -0.571641 -0.445899
+v 0.0784398 -0.553414 -0.446837
+v 0.0783114 -0.535045 -0.450125
+v 0.078427 -0.516535 -0.457164
+v 0.0783627 -0.498256 -0.462315
+v 0.0780545 -0.479618 -0.464961
+v 0.0783114 -0.461467 -0.468095
+v 0.0779774 -0.443086 -0.470459
+v 0.0778361 -0.425025 -0.470035
+v 0.0778104 -0.407234 -0.467261
+v 0.0776948 -0.389046 -0.468751
+v 0.0775663 -0.370702 -0.471795
+v 0.0775406 -0.352501 -0.473786
+v 0.0774122 -0.334363 -0.475276
+v -0.462347 -0.981047 -0.127721
+v -0.639895 -0.951657 0.474313
+v 0.0673158 -0.911554 -0.318473
+v 0.0672901 -0.893121 -0.319039
+v 0.0672516 -0.874855 -0.317703
+v 0.067213 -0.856589 -0.318204
+v 0.0670075 -0.835497 -0.341762
+v 0.0668662 -0.815664 -0.360118
+v 0.0667506 -0.796293 -0.369919
+v 0.0666221 -0.777359 -0.3785
+v 0.066468 -0.758232 -0.390587
+v 0.0663524 -0.738116 -0.406374
+v 0.0663138 -0.719388 -0.412784
+v 0.066301 -0.700968 -0.415956
+v 0.0662882 -0.682676 -0.419604
+v 0.0661212 -0.663794 -0.425308
+v 0.0660313 -0.645001 -0.433477
+v 0.0660056 -0.626285 -0.441994
+v 0.0659156 -0.607737 -0.446939
+v 0.0658129 -0.589368 -0.450253
+v 0.0656973 -0.571269 -0.450112
+v 0.0656459 -0.553221 -0.450253
+v 0.0655431 -0.534596 -0.456766
+v 0.0654918 -0.515752 -0.466824
+v 0.0653761 -0.49737 -0.470035
+v 0.0651578 -0.479258 -0.469611
+v 0.0652862 -0.46121 -0.470729
+v 0.0651449 -0.443021 -0.472129
+v 0.0651192 -0.425051 -0.470947
+v 0.0650165 -0.407157 -0.469097
+v 0.0649137 -0.388853 -0.472257
+v 0.0649266 -0.370548 -0.476137
+v 0.0648109 -0.352334 -0.477614
+v 0.0647467 -0.334183 -0.477575
+v 0.0840018 -0.921226 0.163058
+v -0.440729 -0.981612 -0.146449
+v 0.0713621 -0.972479 -0.220348
+v -0.105877 -0.926891 0.245653
+v 0.0544962 -0.930167 -0.316637
+v 0.0543806 -0.9114 -0.319809
+v 0.0543806 -0.892851 -0.321916
+v 0.0544962 -0.874765 -0.319809
+v 0.0543549 -0.856396 -0.319617
+v 0.0541494 -0.83619 -0.338949
+v 0.0539695 -0.815753 -0.360169
+v 0.0539181 -0.796293 -0.369803
+v 0.0538411 -0.776974 -0.37963
+v 0.0536484 -0.758168 -0.388339
+v 0.0535456 -0.738682 -0.401249
+v 0.0534814 -0.719529 -0.410793
+v 0.0534429 -0.701071 -0.416021
+v 0.0533786 -0.682342 -0.422366
+v 0.053263 -0.663408 -0.430176
+v 0.0532759 -0.64486 -0.439052
+v 0.053263 -0.626247 -0.446091
+v 0.0531474 -0.607608 -0.45078
+v 0.0531346 -0.589355 -0.45254
+v 0.053096 -0.571256 -0.45263
+v 0.0531089 -0.55299 -0.456072
+v 0.0529547 -0.5343 -0.464088
+v 0.052685 -0.515777 -0.468879
+v 0.0526978 -0.49737 -0.472296
+v 0.0524281 -0.479078 -0.473311
+v 0.0523895 -0.461005 -0.473722
+v 0.0522868 -0.442919 -0.47376
+v 0.0522226 -0.424987 -0.47227
+v 0.0521969 -0.406978 -0.472617
+v 0.0519913 -0.388506 -0.476766
+v 0.0519913 -0.370227 -0.480517
+v 0.0519143 -0.352128 -0.480735
+v 0.0518886 -0.334106 -0.479322
+v 0.0515931 -0.316251 -0.478256
+v -0.0517601 -0.0733466 -0.273952
+v 0.0459669 0.841483 -0.334337
+v 0.0461082 0.860596 -0.340657
+v 0.379444 -0.974675 -0.109185
+v 0.371236 -0.973275 -0.0879646
+v 0.367189 -0.973147 -0.113039
+v 0.0415995 -0.929897 -0.319719
+v 0.0415995 -0.911194 -0.323509
+v 0.0415995 -0.892594 -0.325423
+v 0.0415224 -0.874315 -0.323958
+v 0.0415481 -0.856165 -0.322969
+v 0.0413169 -0.835882 -0.340272
+v 0.0411628 -0.815535 -0.359745
+v 0.0410086 -0.796498 -0.370073
+v 0.0409701 -0.776845 -0.38112
+v 0.0408159 -0.758155 -0.388198
+v 0.0406746 -0.739067 -0.397947
+v 0.0406104 -0.72003 -0.407761
+v 0.0405333 -0.701199 -0.416059
+v 0.0405205 -0.682368 -0.42428
+v 0.0404563 -0.663472 -0.434184
+v 0.0403278 -0.64459 -0.442187
+v 0.040225 -0.625823 -0.448429
+v 0.0401094 -0.6073 -0.4534
+v 0.0400452 -0.588893 -0.456445
+v 0.0400324 -0.570717 -0.458539
+v 0.0400195 -0.552425 -0.462045
+v 0.0400452 -0.53421 -0.465693
+v 0.0399553 -0.515803 -0.46902
+v 0.0397369 -0.497357 -0.471962
+v 0.0395057 -0.478886 -0.476201
+v 0.0394929 -0.460799 -0.476676
+v 0.0393644 -0.442752 -0.476381
+v 0.0393516 -0.424935 -0.473696
+v 0.0395314 -0.407093 -0.474505
+v 0.0392617 -0.388403 -0.480928
+v 0.0390947 -0.370022 -0.483677
+v 0.0389534 -0.351948 -0.483137
+v 0.0389277 -0.334081 -0.480543
+v 0.0388249 -0.316187 -0.478654
+v -0.10354 -0.923821 0.382238
+v -0.108331 -0.92436 0.358615
+v -0.628283 -0.981535 -0.0666157
+v -0.614872 -0.980957 -0.0644192
+v 0.402796 -0.972389 -0.130932
+v 0.393381 -0.973083 -0.107926
+v 0.0337253 0.803679 -0.305988
+v 0.0336226 0.822677 -0.315802
+v 0.0331473 0.841483 -0.324408
+v 0.0329931 0.860455 -0.330972
+v 0.0331987 0.879569 -0.335596
+v 0.0287028 -0.892324 -0.328583
+v 0.0286771 -0.874007 -0.327234
+v 0.0287028 -0.855856 -0.326206
+v 0.0284973 -0.836537 -0.339527
+v 0.0283046 -0.815933 -0.358384
+v 0.0281633 -0.796511 -0.369957
+v 0.0281248 -0.776781 -0.380889
+v 0.028022 -0.757744 -0.389251
+v 0.0277908 -0.739157 -0.398024
+v 0.0277266 -0.720095 -0.407723
+v 0.0276367 -0.701366 -0.416188
+v 0.0275853 -0.682368 -0.425937
+v 0.0275467 -0.663267 -0.435379
+v 0.0273284 -0.64495 -0.441249
+v 0.0273669 -0.626285 -0.445706
+v 0.027277 -0.607313 -0.453221
+v 0.0272128 -0.588713 -0.45999
+v 0.0271357 -0.570383 -0.463381
+v 0.0270586 -0.552181 -0.465064
+v 0.0270843 -0.53394 -0.468879
+v 0.0269302 -0.51552 -0.471679
+v 0.0268274 -0.497164 -0.475379
+v 0.0266861 -0.478783 -0.478153
+v 0.0266476 -0.460697 -0.478719
+v 0.0264934 -0.442687 -0.477896
+v 0.026532 -0.424974 -0.474081
+v 0.0265577 -0.407453 -0.475803
+v 0.0263778 -0.388301 -0.482803
+v 0.0262365 -0.369932 -0.485488
+v 0.0261723 -0.351935 -0.484216
+v 0.0260438 -0.334003 -0.482084
+v 0.0259925 -0.3162 -0.478911
+v 0.27198 -0.976551 0.0869113
+v 0.130913 -0.91551 -0.0208736
+v 0.117502 -0.916088 -0.0230573
+v 0.330246 -0.974149 0.0487479
+v 0.322012 -0.972851 0.0698527
+v 0.315705 -0.976821 0.0483112
+v 0.313612 -0.964194 0.341595
+v 0.311209 -0.952607 0.353965
+v 0.719176 -0.873339 0.366245
+v 0.703531 -0.878143 0.36735
+v 0.0208287 0.803525 -0.296354
+v 0.0210727 0.822793 -0.307247
+v 0.0210085 0.841765 -0.315378
+v 0.0204048 0.860519 -0.320914
+v 0.0206488 0.879543 -0.327067
+v 0.0201222 0.89849 -0.327594
+v 0.0157933 -0.891888 -0.333246
+v 0.0159474 -0.873763 -0.330805
+v 0.0159089 -0.855548 -0.329687
+v 0.0156006 -0.836409 -0.339398
+v 0.0154722 -0.816267 -0.355083
+v 0.0153052 -0.796922 -0.366772
+v 0.0152409 -0.777346 -0.378011
+v 0.014984 -0.758386 -0.388442
+v 0.0149198 -0.73926 -0.398012
+v 0.0149712 -0.719953 -0.407222
+v 0.0148042 -0.701276 -0.415751
+v 0.01474 -0.682214 -0.425411
+v 0.0146501 -0.663575 -0.434402
+v 0.014573 -0.644795 -0.44035
+v 0.0144574 -0.626452 -0.443895
+v 0.014406 -0.607801 -0.450408
+v 0.0143546 -0.589111 -0.459091
+v 0.0143032 -0.570331 -0.465192
+v 0.0141619 -0.551911 -0.467967
+v 0.0141106 -0.533761 -0.470202
+v 0.013995 -0.515482 -0.473606
+v 0.0139436 -0.4971 -0.47701
+v 0.0138151 -0.478719 -0.47972
+v 0.0137894 -0.460594 -0.480748
+v 0.0137124 -0.442662 -0.478963
+v 0.0136353 -0.424858 -0.475661
+v 0.0135582 -0.406875 -0.475661
+v 0.0137124 -0.388416 -0.480144
+v 0.0133527 -0.369842 -0.486336
+v 0.0132628 -0.351846 -0.485899
+v 0.0131857 -0.333939 -0.483767
+v 0.0131215 -0.316046 -0.480735
+v -0.680114 -0.972877 -0.0383689
+v -0.689336 -0.973969 -0.0160438
+v -0.225763 -0.969537 0.555765
+v 0.307523 -0.975562 0.0693518
+v 0.154111 -0.920802 0.270047
+v 0.140765 -0.921393 0.267876
+v 0.149384 -0.921368 0.246386
+v 0.00838156 0.784591 -0.276392
+v 0.00811181 0.803538 -0.288017
+v 0.0081375 0.822626 -0.297651
+v 0.00802189 0.841598 -0.304164
+v 0.00789344 0.860545 -0.310741
+v 0.00744385 0.879466 -0.314402
+v 0.00704565 0.898464 -0.316367
+v 0.00296084 -0.891605 -0.336572
+v 0.00284523 -0.873352 -0.334684
+v 0.00296084 -0.855227 -0.332526
+v 0.00279385 -0.83646 -0.337754
+v 0.00265255 -0.816576 -0.351717
+v 0.00247272 -0.797166 -0.363239
+v 0.00216443 -0.778207 -0.373772
+v 0.00204882 -0.75872 -0.385115
+v 0.00202313 -0.739658 -0.394864
+v 0.00180476 -0.720942 -0.403368
+v 0.00186899 -0.701713 -0.412655
+v 0.00181761 -0.682676 -0.422341
+v 0.00174054 -0.663665 -0.432219
+v 0.001702 -0.644911 -0.4385
+v 0.0015607 -0.626645 -0.442109
+v 0.00148363 -0.608276 -0.445578
+v 0.00138087 -0.589381 -0.455469
+v 0.00140656 -0.570318 -0.464679
+v 0.00129095 -0.552027 -0.468507
+v 0.00123957 -0.533581 -0.47105
+v 0.0011625 -0.515764 -0.472334
+v 0.00107258 -0.497152 -0.47683
+v 0.000982665 -0.478796 -0.479952
+v 0.000905593 -0.460607 -0.481249
+v 0.000841367 -0.442585 -0.480517
+v 0.000802831 -0.42482 -0.477421
+v 0.000700069 -0.406926 -0.475559
+v 0.000571616 -0.388365 -0.479785
+v 0.000507389 -0.370047 -0.485295
+v 0.000417472 -0.351871 -0.486516
+v 0.000301864 -0.333862 -0.484306
+v 0.000199102 -0.315994 -0.481018
+v 0.000237638 -0.298499 -0.476856
+v -0.672779 -0.973648 -0.0397947
+v -0.0618565 -0.925606 0.207105
+v -0.0752156 -0.92621 0.204908
+v -0.0660184 -0.925105 0.182557
+v -0.0869691 -0.918041 0.449662
+v -0.0944451 -0.916011 0.469329
+v -0.100354 -0.918644 0.44744
+v -0.0923384 -0.919621 0.426901
+v -0.00454081 0.784398 -0.268441
+v -0.00472065 0.803435 -0.27995
+v -0.00457935 0.822664 -0.28934
+v -0.00481056 0.841585 -0.296007
+v -0.0048491 0.860545 -0.30085
+v -0.00514454 0.879479 -0.304279
+v -0.00556844 0.898439 -0.306258
+v -0.00971747 -0.910076 -0.336752
+v -0.00994868 -0.891335 -0.339488
+v -0.00994868 -0.873056 -0.338255
+v -0.00988446 -0.854919 -0.335596
+v -0.0100514 -0.836383 -0.337228
+v -0.0102441 -0.816999 -0.348634
+v -0.0104753 -0.797693 -0.360349
+v -0.0106937 -0.778502 -0.370356
+v -0.0107451 -0.758952 -0.381582
+v -0.0108479 -0.740082 -0.389791
+v -0.0106937 -0.720775 -0.398988
+v -0.0110277 -0.702201 -0.407748
+v -0.0110791 -0.68319 -0.417498
+v -0.0111561 -0.664205 -0.427312
+v -0.0112075 -0.645296 -0.435404
+v -0.0112332 -0.626735 -0.440183
+v -0.0114002 -0.608507 -0.443792
+v -0.0115543 -0.58992 -0.450677
+v -0.0114901 -0.570742 -0.461724
+v -0.0115672 -0.552078 -0.468262
+v -0.0116443 -0.533863 -0.469997
+v -0.0116571 -0.515752 -0.471962
+v -0.0118113 -0.497229 -0.476805
+v -0.0118498 -0.478821 -0.479849
+v -0.0119269 -0.460748 -0.480324
+v -0.0120168 -0.442623 -0.480671
+v -0.012081 -0.424755 -0.478693
+v -0.0121324 -0.406849 -0.477164
+v -0.012248 -0.388532 -0.479952
+v -0.0123636 -0.370201 -0.483651
+v -0.0124921 -0.352077 -0.483985
+v -0.0125563 -0.334119 -0.482212
+v -0.0126719 -0.3162 -0.479245
+v -0.0126205 -0.298627 -0.475302
+v -0.0126334 -0.280978 -0.468622
+v -0.587756 -0.967739 0.297202
+v -0.6066 -0.962858 0.311627
+v -0.580755 -0.953468 0.282571
+v -0.0481121 -0.923988 0.138652
+v -0.0614712 -0.924579 0.136494
+v 0.0529804 -0.915561 -0.108273
+v -0.0168466 0.746517 -0.240233
+v -0.0171292 0.765361 -0.250406
+v -0.017142 0.784539 -0.2632
+v -0.0173347 0.803525 -0.273104
+v -0.017309 0.822613 -0.281106
+v -0.0175017 0.841547 -0.28767
+v -0.0175788 0.860545 -0.292552
+v -0.0181825 0.879453 -0.293168
+v -0.0182853 0.898426 -0.294774
+v -0.0227683 -0.928317 -0.337253
+v -0.0228454 -0.909576 -0.340542
+v -0.0227298 -0.891053 -0.343111
+v -0.0227298 -0.872787 -0.341775
+v -0.0227683 -0.854636 -0.33882
+v -0.0228711 -0.836537 -0.335969
+v -0.0230894 -0.817308 -0.345436
+v -0.0233206 -0.797988 -0.356958
+v -0.0234619 -0.778695 -0.36681
+v -0.0237702 -0.759709 -0.375352
+v -0.0236289 -0.740467 -0.384665
+v -0.0236418 -0.72152 -0.392681
+v -0.0237317 -0.702535 -0.402443
+v -0.0238344 -0.68355 -0.412308
+v -0.0240785 -0.664898 -0.420876
+v -0.02404 -0.645797 -0.430382
+v -0.0241427 -0.627159 -0.437048
+v -0.024284 -0.608713 -0.442238
+v -0.0245666 -0.590408 -0.447646
+v -0.0243996 -0.57114 -0.458577
+v -0.0245666 -0.55254 -0.465604
+v -0.0244896 -0.533876 -0.469778
+v -0.0247593 -0.51597 -0.470934
+v -0.0247208 -0.49764 -0.474223
+v -0.0246951 -0.478873 -0.479579
+v -0.0248235 -0.460838 -0.48053
+v -0.0248621 -0.442636 -0.481249
+v -0.024952 -0.424717 -0.479965
+v -0.0250419 -0.406721 -0.47913
+v -0.0251447 -0.388583 -0.480466
+v -0.0252474 -0.370368 -0.482328
+v -0.0253373 -0.352282 -0.482187
+v -0.0254401 -0.334389 -0.479053
+v -0.0254786 -0.316585 -0.47561
+v -0.0254786 -0.298872 -0.472142
+v -0.0517087 -0.091587 -0.281376
+v 0.0284459 -0.919389 -0.0141298
+v 0.0185422 -0.921342 0.00938991
+v 0.0150226 -0.91998 -0.016275
+v -0.629195 -0.117701 -0.193694
+v -0.240072 -0.965054 0.593812
+v 0.68854 -0.882099 0.367761
+v 0.673485 -0.88585 0.368056
+v -0.0296791 0.746402 -0.235416
+v -0.0299231 0.765323 -0.245461
+v -0.0299103 0.784488 -0.256611
+v -0.0301415 0.803486 -0.26654
+v -0.0302057 0.822484 -0.273117
+v -0.0302571 0.841534 -0.279398
+v -0.0307195 0.860468 -0.281518
+v -0.030681 0.879453 -0.282982
+v -0.0354851 -0.90955 -0.342982
+v -0.0356007 -0.890783 -0.346258
+v -0.0357292 -0.872465 -0.345795
+v -0.0356778 -0.854418 -0.341698
+v -0.0357934 -0.83655 -0.3362
+v -0.0359476 -0.817744 -0.34121
+v -0.0361402 -0.798297 -0.35367
+v -0.0362687 -0.779144 -0.361813
+v -0.0364357 -0.759992 -0.370034
+v -0.0365256 -0.741109 -0.378166
+v -0.0365513 -0.722214 -0.386258
+v -0.0363458 -0.702766 -0.397074
+v -0.0367568 -0.68423 -0.40586
+v -0.0368853 -0.665309 -0.415802
+v -0.036744 -0.64617 -0.425179
+v -0.0370394 -0.627673 -0.432257
+v -0.0371679 -0.609073 -0.438924
+v -0.0372192 -0.590408 -0.445424
+v -0.037322 -0.571654 -0.453696
+v -0.0374248 -0.552874 -0.462161
+v -0.0374505 -0.534377 -0.467068
+v -0.0374248 -0.515777 -0.471666
+v -0.0375532 -0.497498 -0.475237
+v -0.0375789 -0.478975 -0.479875
+v -0.0376688 -0.460748 -0.481699
+v -0.0377331 -0.442662 -0.481827
+v -0.0377973 -0.424627 -0.481429
+v -0.0378744 -0.406579 -0.481763
+v -0.0380028 -0.38848 -0.482174
+v -0.0381441 -0.370394 -0.482444
+v -0.038067 -0.352424 -0.481429
+v -0.0382983 -0.334556 -0.47746
+v -0.0384524 -0.316688 -0.4729
+v -0.0384524 -0.299064 -0.467749
+v 0.0623318 -0.914778 -0.131048
+v -0.564557 -0.632181 -5.13812e-05
+v -0.614834 -0.962562 0.332205
+v 0.0604821 -0.91709 -0.0574956
+v -0.0256713 -0.922395 0.0485295
+v 0.269771 -0.909126 0.445745
+v -0.0424858 0.746389 -0.23205
+v -0.0427684 0.765207 -0.240669
+v -0.0426143 0.784565 -0.251434
+v -0.0430253 0.803396 -0.260104
+v -0.0431666 0.822433 -0.266617
+v -0.0430382 0.841483 -0.27119
+v -0.0431795 0.860429 -0.272886
+v -0.0484717 -0.927752 -0.343804
+v -0.0483047 -0.909293 -0.346463
+v -0.0482791 -0.890642 -0.348776
+v -0.0484974 -0.872286 -0.347979
+v -0.0486002 -0.854302 -0.344293
+v -0.0485745 -0.83637 -0.338384
+v -0.0489085 -0.818014 -0.338397
+v -0.0491012 -0.798965 -0.347607
+v -0.0490241 -0.77953 -0.356675
+v -0.0491654 -0.760532 -0.363239
+v -0.0492039 -0.741636 -0.371358
+v -0.049448 -0.723036 -0.378153
+v -0.0495636 -0.704076 -0.388018
+v -0.0495379 -0.684821 -0.399219
+v -0.0499489 -0.666247 -0.407954
+v -0.0498719 -0.647159 -0.417536
+v -0.0499232 -0.628289 -0.425629
+v -0.0502187 -0.609792 -0.432681
+v -0.0500645 -0.590858 -0.440375
+v -0.0501288 -0.572078 -0.448661
+v -0.05036 -0.553375 -0.45719
+v -0.0502315 -0.53448 -0.465013
+v -0.0503215 -0.515996 -0.470151
+v -0.0505784 -0.497794 -0.47403
+v -0.0505398 -0.479194 -0.478564
+v -0.0505398 -0.460812 -0.481557
+v -0.0507582 -0.442739 -0.482071
+v -0.0507068 -0.424666 -0.481776
+v -0.0507967 -0.406618 -0.48202
+v -0.0508866 -0.388519 -0.482148
+v -0.0509637 -0.370458 -0.482058
+v -0.0509637 -0.352539 -0.480157
+v -0.0512335 -0.334671 -0.47606
+v -0.0511436 -0.316983 -0.472206
+v -0.0511564 -0.299437 -0.465578
+v -0.0518244 -0.0552476 -0.268826
+v 0.00343612 -0.91903 0.399913
+v 0.222384 -0.91569 0.349161
+v 0.214317 -0.914688 0.36979
+v 0.209012 -0.916294 0.346964
+v 0.80637 -0.88341 0.179539
+v 0.298762 -0.968535 -0.0105845
+v 0.287715 -0.972492 0.0147978
+v 0.278287 -0.965697 0.00667955
+v -0.0551898 0.727185 -0.217291
+v -0.0552797 0.746415 -0.228582
+v -0.0553311 0.765464 -0.238332
+v -0.0555366 0.784437 -0.246643
+v -0.0558706 0.803319 -0.253682
+v -0.0558321 0.822382 -0.259899
+v -0.0558578 0.841457 -0.262995
+v -0.0561404 0.860442 -0.263264
+v -0.061073 -0.927739 -0.346386
+v -0.06124 -0.908972 -0.349071
+v -0.0612656 -0.890449 -0.351113
+v -0.0612785 -0.872106 -0.349893
+v -0.0613299 -0.854007 -0.345564
+v -0.0614326 -0.83619 -0.340169
+v -0.0616253 -0.818168 -0.335879
+v -0.0617666 -0.799209 -0.341878
+v -0.062152 -0.78048 -0.349084
+v -0.0618951 -0.761071 -0.356534
+v -0.0621777 -0.742625 -0.361775
+v -0.062152 -0.723704 -0.36979
+v -0.0623575 -0.704834 -0.379784
+v -0.0623703 -0.685605 -0.391049
+v -0.0625116 -0.666632 -0.40094
+v -0.0624603 -0.647583 -0.410536
+v -0.0628585 -0.629111 -0.417601
+v -0.0628199 -0.61019 -0.425565
+v -0.0626272 -0.591115 -0.435006
+v -0.0632695 -0.573016 -0.440838
+v -0.0632695 -0.554056 -0.450626
+v -0.0633594 -0.535289 -0.458962
+v -0.0632567 -0.516368 -0.466862
+v -0.0633594 -0.497909 -0.471962
+v -0.0635393 -0.479553 -0.475533
+v -0.0635264 -0.461159 -0.478693
+v -0.0637962 -0.44306 -0.479348
+v -0.0639246 -0.425 -0.479387
+v -0.0636549 -0.406772 -0.480209
+v -0.0639118 -0.388814 -0.479322
+v -0.0637705 -0.370677 -0.480157
+v -0.0637063 -0.352796 -0.478089
+v -0.0639632 -0.334954 -0.473889
+v -0.0639889 -0.317189 -0.470523
+v -0.0640402 -0.299578 -0.463985
+v -0.60028 -0.446978 0.543459
+v -0.0645412 -0.0915227 -0.283033
+v -0.0646054 -0.0734237 -0.2753
+v 0.195615 -0.916885 0.344716
+v 0.292186 -0.956551 -0.0228646
+v -0.0679837 0.727275 -0.215467
+v -0.0680737 0.746389 -0.226771
+v -0.0682663 0.76531 -0.235339
+v -0.0692683 0.78436 -0.243251
+v -0.0686517 0.803306 -0.248621
+v -0.0688958 0.822343 -0.252115
+v -0.0687288 0.841418 -0.254915
+v -0.0687031 0.86034 -0.254786
+v -0.115267 -0.914585 0.48685
+v -0.073854 -0.946056 -0.347799
+v -0.074021 -0.927469 -0.348943
+v -0.0741238 -0.908895 -0.350433
+v -0.0741238 -0.890359 -0.352475
+v -0.0741623 -0.872067 -0.351139
+v -0.0742266 -0.853968 -0.346887
+v -0.0742908 -0.836229 -0.341338
+v -0.0742137 -0.818477 -0.334337
+v -0.0743807 -0.799941 -0.335326
+v -0.0747789 -0.780943 -0.342186
+v -0.0747404 -0.76188 -0.348454
+v -0.074933 -0.743383 -0.353464
+v -0.0748303 -0.724385 -0.36139
+v -0.0749587 -0.705412 -0.371191
+v -0.0749716 -0.686196 -0.382572
+v -0.0749074 -0.666954 -0.393773
+v -0.0752285 -0.648302 -0.40225
+v -0.0752799 -0.629471 -0.410407
+v -0.0755625 -0.61091 -0.417241
+v -0.0757937 -0.592322 -0.424023
+v -0.0758065 -0.573401 -0.43376
+v -0.0758322 -0.554442 -0.44351
+v -0.0761533 -0.535842 -0.452167
+v -0.0761405 -0.516998 -0.460286
+v -0.0762561 -0.498372 -0.466965
+v -0.0763589 -0.479836 -0.471885
+v -0.076346 -0.461467 -0.475212
+v -0.0766928 -0.443407 -0.475867
+v -0.0766928 -0.425282 -0.475764
+v -0.0766158 -0.407234 -0.475392
+v -0.0763203 -0.389097 -0.476124
+v -0.0767442 -0.371062 -0.475533
+v -0.0767442 -0.353143 -0.473773
+v -0.0767828 -0.335301 -0.470498
+v -0.0767956 -0.317497 -0.467132
+v -0.0768598 -0.299822 -0.462225
+v -0.0774122 -0.0914714 -0.284652
+v 0.0936358 -0.919184 0.0697757
+v 0.0802895 -0.919775 0.0676176
+v 0.0889601 -0.919775 0.045999
+v -0.0808804 0.727082 -0.212294
+v -0.0809061 0.746286 -0.223572
+v -0.0812658 0.765117 -0.230779
+v -0.08133 0.784205 -0.238845
+v -0.0815098 0.803294 -0.243765
+v -0.0814585 0.822343 -0.246707
+v -0.0817411 0.841341 -0.246964
+v -0.081831 0.860391 -0.245345
+v -0.0868406 -0.927392 -0.350651
+v -0.086892 -0.908792 -0.352308
+v -0.0869819 -0.890256 -0.353862
+v -0.0870333 -0.872093 -0.352295
+v -0.0870847 -0.853968 -0.348108
+v -0.0871489 -0.836165 -0.341634
+v -0.0871618 -0.818644 -0.333207
+v -0.0872517 -0.800442 -0.330163
+v -0.0875728 -0.781662 -0.333772
+v -0.08756 -0.762677 -0.340233
+v -0.0876627 -0.744102 -0.345205
+v -0.0877398 -0.725361 -0.351666
+v -0.0883564 -0.593067 -0.413837
+v -0.0886004 -0.574223 -0.423856
+v -0.0886261 -0.555289 -0.433644
+v -0.0887803 -0.536432 -0.443574
+v -0.0893069 -0.518025 -0.450831
+v -0.0888573 -0.49886 -0.459849
+v -0.0891656 -0.48044 -0.46518
+v -0.0894097 -0.462135 -0.468892
+v -0.0891528 -0.443689 -0.471615
+v -0.0891785 -0.425629 -0.471525
+v -0.089384 -0.407684 -0.470254
+v -0.0894482 -0.389611 -0.470382
+v -0.0896024 -0.371486 -0.4706
+v -0.089718 -0.353503 -0.469162
+v -0.0895638 -0.335648 -0.466978
+v -0.0896024 -0.317831 -0.463767
+v -0.089551 -0.300285 -0.458564
+v -0.0902446 -0.0914971 -0.284703
+v -0.0668405 -0.920507 -0.199552
+v -0.093533 0.708097 -0.198922
+v -0.0936101 0.727185 -0.210367
+v -0.0937643 0.746235 -0.220284
+v -0.0938542 0.765297 -0.228402
+v -0.0942524 0.784154 -0.23408
+v -0.0942395 0.803281 -0.238614
+v -0.0942395 0.822305 -0.240091
+v -0.0943038 0.841277 -0.240053
+v -0.0943423 0.860262 -0.238383
+v -0.819267 0.0613748 0.629407
+v -0.83576 0.0715355 0.639066
+v -0.530402 -0.612156 0.384678
+v -0.526278 -0.618694 0.368121
+v -0.099763 -0.927109 -0.353246
+v -0.0997502 -0.908715 -0.353888
+v -0.099763 -0.890256 -0.354505
+v -0.0998401 -0.872042 -0.352745
+v -0.0999171 -0.854007 -0.348172
+v -0.0999557 -0.836357 -0.341428
+v -0.100123 -0.818759 -0.33051
+v -0.100341 -0.800917 -0.324228
+v -0.100521 -0.782458 -0.325898
+v -0.10038 -0.763486 -0.332038
+v -0.10142 -0.537165 -0.433529
+v -0.101536 -0.518282 -0.443368
+v -0.101805 -0.499746 -0.450215
+v -0.101767 -0.481069 -0.456612
+v -0.101767 -0.462572 -0.461403
+v -0.101638 -0.444242 -0.464422
+v -0.101998 -0.42631 -0.463304
+v -0.102049 -0.408146 -0.464987
+v -0.102255 -0.39006 -0.465308
+v -0.102396 -0.371974 -0.465501
+v -0.102345 -0.353901 -0.465308
+v -0.102538 -0.33602 -0.462379
+v -0.10255 -0.318178 -0.459001
+v -0.10273 -0.30049 -0.452797
+v -0.103103 -0.0914971 -0.283598
+v 0.407472 -0.967932 0.387311
+v 0.00574827 -0.920867 0.00638411
+v 0.00220297 -0.919505 -0.0193065
+v -0.00360311 -0.921791 0.0291074
+v -0.016397 -0.921329 0.0261145
+v -0.10652 0.726954 -0.207362
+v -0.106622 0.746145 -0.217073
+v -0.106815 0.765143 -0.223829
+v -0.107033 0.784154 -0.23056
+v -0.107149 0.803178 -0.232269
+v -0.107239 0.822202 -0.232166
+v -0.107033 0.8412 -0.231678
+v -0.107252 0.860237 -0.228685
+v -0.112737 -0.872003 -0.354106
+v -0.112775 -0.854199 -0.349097
+v -0.112801 -0.836678 -0.34094
+v -0.112814 -0.81935 -0.328172
+v -0.112236 -0.802125 -0.318769
+v -0.113289 -0.783216 -0.317639
+v 0.0700775 -0.92287 0.161671
+v -0.114317 -0.500273 -0.441596
+v -0.114574 -0.48193 -0.446785
+v -0.114484 -0.463253 -0.453118
+v -0.114612 -0.445064 -0.454878
+v -0.114946 -0.427183 -0.453696
+v -0.114869 -0.408686 -0.458397
+v -0.114728 -0.390266 -0.461069
+v -0.115152 -0.372398 -0.460401
+v -0.115165 -0.354338 -0.460337
+v -0.115357 -0.336457 -0.457344
+v -0.115293 -0.318666 -0.453889
+v -0.115113 -0.301171 -0.448596
+v 0.170772 -0.957874 0.63028
+v 0.175383 -0.965209 0.61475
+v -0.251749 -0.962472 0.589124
+v -0.809132 -0.472823 0.283855
+v 0.442887 -0.966699 0.370214
+v 0.434216 -0.966737 0.391692
+v 0.429527 -0.967302 0.368005
+v 0.42561 -0.966776 0.413259
+v 0.412212 -0.967379 0.411037
+v 0.420844 -0.967328 0.389546
+v 0.416939 -0.966814 0.434711
+v 0.403015 -0.968471 0.433362
+v 0.407716 -0.967932 0.45701
+v 0.393818 -0.969576 0.455674
+v 0.398557 -0.969036 0.479335
+v 0.38516 -0.969627 0.477126
+v 0.3899 -0.969088 0.500787
+v 0.376553 -0.969692 0.498526
+v 0.381293 -0.969152 0.522174
+v 0.367896 -0.969756 0.520016
+v 0.372687 -0.969216 0.543626
+v 0.358699 -0.970873 0.542239
+v 0.365147 -0.967161 0.563382
+v 0.351235 -0.968818 0.56202
+v 0.359366 -0.961946 0.58062
+v 0.345442 -0.963603 0.579233
+v 0.355834 -0.95244 0.594557
+v 0.340818 -0.956268 0.594814
+v 0.476439 -0.968715 0.285615
+v 0.467794 -0.968728 0.307221
+v 0.454409 -0.969332 0.305037
+v 0.326277 -0.958979 0.594262
+v 0.30936 -0.950102 0.605964
+v 0.466471 -0.963012 0.278435
+v 0.43288 -0.968882 0.323573
+v 0.419534 -0.969486 0.321402
+v 0.785214 -0.880661 0.268775
+v 0.776607 -0.879363 0.289906
+v 0.767526 -0.888599 0.27277
+v 0.383798 -0.971811 0.0574056
+v 0.376887 -0.976846 0.0366605
+v 0.492495 -0.955009 0.253129
+v 0.225313 -0.93411 0.296572
+v 0.222924 -0.922549 0.308942
+v 0.215358 -0.92842 0.289353
+v 0.0140335 -0.961997 0.668007
+v -0.075023 -0.966634 0.674519
+v -0.0810859 -0.962665 0.691784
+v -0.0882408 -0.967135 0.672053
+v 0.375423 -0.974573 -0.134233
+v -0.0845413 -0.953609 0.705297
+v -0.0943551 -0.963179 0.68933
+v 0.0347273 -0.969101 0.611089
+v 0.192313 -0.91533 0.389084
+v 0.178954 -0.915934 0.386849
+v 0.187021 -0.916936 0.366207
+v 0.01939 -0.966532 0.650717
+v 0.0270458 -0.967816 0.630922
+v 0.502296 -0.952877 0.229841
+v 0.264915 -0.925478 0.34338
+v 0.276052 -0.9291 0.348917
+v 0.26137 -0.916011 0.357433
+v 0.20038 -0.916332 0.368416
+v 0.176976 -0.969884 0.57317
+v 0.168383 -0.969974 0.594493
+v 0.163591 -0.970488 0.570922
+v 0.361884 -0.973982 -0.0650229
+v 0.770416 -0.875561 0.308351
+v 0.752998 -0.883384 0.311935
+v 0.760576 -0.885593 0.291986
+v 0.793717 -0.881393 0.247246
+v 0.775939 -0.889755 0.251678
+v 0.0689728 -0.927713 -0.189931
+v 0.110656 -0.921021 0.307825
+v 0.161433 -0.966878 0.61335
+v 0.155023 -0.970578 0.592258
+v 0.814501 -0.876602 0.198601
+v 0.510427 -0.953943 0.209083
+v 0.302308 -0.977399 0.0461403
+v 0.311672 -0.976577 0.0233271
+v 0.107676 -0.970064 0.604834
+v 0.0999685 -0.968728 0.624705
+v 0.0949075 -0.969525 0.601661
+v 0.277311 -0.942781 0.338204
+v 0.268627 -0.950745 0.320349
+v 0.0832183 -0.915703 -0.0780994
+v 0.217747 -0.939968 0.276996
+v 0.220175 -0.951554 0.264639
+v 0.240059 -0.970938 0.23959
+v 0.228434 -0.968368 0.23494
+v 0.234831 -0.972582 0.216687
+v 0.438185 -0.967264 0.346489
+v -0.0204304 -0.968022 0.643408
+v -0.0286129 -0.968099 0.663755
+v -0.0337125 -0.96851 0.641006
+v 0.150194 -0.919402 0.104792
+v 0.140919 -0.920468 0.127271
+v 0.1374 -0.91894 0.101825
+v 0.247034 -0.974097 0.220528
+v 0.0909383 -0.953879 0.655316
+v 0.0906942 -0.936204 0.659439
+v 0.156269 -0.960597 0.629728
+v 0.141896 -0.963205 0.628944
+v 0.147509 -0.968548 0.61195
+v 0.186674 -0.967688 0.550126
+v 0.266765 -0.938118 0.331845
+v 0.0949203 -0.962344 0.640749
+v 0.0805978 -0.964862 0.639837
+v 0.0867379 -0.969216 0.622278
+v 0.076102 -0.957424 0.655162
+v 0.203553 -0.970103 -0.196456
+v 0.201639 -0.95727 -0.184625
+v 0.188241 -0.957797 -0.186758
+v -0.0509637 -0.967662 0.614057
+v -0.0636677 -0.967135 0.610884
+v 0.0355365 -0.916242 0.427119
+v 0.0274568 -0.915253 0.447646
+v 0.0221132 -0.916846 0.42491
+v 0.0710538 -0.921766 0.300426
+v 0.0194285 -0.914277 0.46825
+v 0.0140977 -0.915857 0.445488
+v 0.00662175 -0.913827 0.465192
+v 0.107111 -0.912697 0.461788
+v 0.115203 -0.913699 0.441197
+v 0.0841817 -0.97298 -0.217381
+v 0.082242 -0.96016 -0.205563
+v 0.0688444 -0.960674 -0.20767
+v 0.0243483 -0.919094 -0.0390112
+v 0.0209186 -0.917771 -0.0648174
+v 0.177451 -0.917463 0.0380092
+v 0.168164 -0.918349 0.060694
+v 0.164645 -0.917 0.0350034
+v 0.767269 -0.897758 0.233682
+v 0.758984 -0.896846 0.254812
+v 0.750352 -0.904823 0.236829
+v 0.22372 -0.961021 0.250599
+v 0.159468 -0.918349 0.0823384
+v 0.15591 -0.916833 0.056879
+v 0.28715 -0.932723 0.35444
+v -0.0806235 -0.968034 0.652528
+v 0.132236 -0.920481 0.148877
+v 0.118902 -0.921072 0.146706
+v 0.1281 -0.920006 0.124227
+v 0.0395828 -0.916139 -0.110392
+v 0.0495122 -0.914303 -0.134092
+v 0.105685 -0.921599 0.214414
+v 0.0964489 -0.922691 0.236765
+v 0.0923256 -0.922202 0.212191
+v 0.234818 -0.964643 0.256122
+v 0.230734 -0.95623 0.271023
+v 0.516863 -0.958156 0.190766
+v 0.0653376 -0.918028 -0.175531
+v 0.45157 -0.966673 0.34866
+v 0.446252 -0.968291 0.325757
+v 0.153341 -0.921907 0.201106
+v 0.162024 -0.921894 0.179487
+v 0.0836678 -0.922241 0.233707
+v -0.19415 -0.96788 0.583626
+v -0.00140656 -0.912851 0.485694
+v -0.00889537 -0.910822 0.505411
+v -0.0142133 -0.912401 0.482636
+v 0.655746 -0.862061 0.389713
+v 0.657043 -0.875805 0.379001
+v 0.750891 -0.895831 0.275686
+v 0.734038 -0.902703 0.278499
+v 0.742182 -0.903769 0.257638
+v 0.16336 -0.912877 0.42726
+v 0.155306 -0.911888 0.447826
+v 0.107278 -0.919466 0.35218
+v 0.0986712 -0.919531 0.373593
+v 0.0939312 -0.92007 0.34997
+v 0.263785 -0.912735 -0.0687223
+v 0.802028 -0.881817 0.22564
+v 0.811482 -0.873031 0.242802
+v 0.802324 -0.87339 0.265307
+v 0.585726 -0.953558 0.0571744
+v 0.56949 -0.959377 0.0592939
+v 0.301023 -0.971156 0.0879261
+v 0.570106 -0.965864 0.089339
+v 0.556118 -0.967495 0.0880545
+v 0.294344 -0.953892 0.606221
+v 0.300201 -0.92639 0.604628
+v 0.238736 -0.910719 -0.0755432
+v 0.234677 -0.910552 -0.100592
+v -0.722208 0.489958 -0.32884
+v 0.118312 -0.91682 -0.166103
+v 0.111825 -0.912337 -0.147464
+v 0.104927 -0.917385 -0.168235
+v -0.0222802 -0.924874 0.214504
+v -0.0308865 -0.924926 0.235981
+v -0.0356136 -0.925478 0.21232
+v -0.199738 -0.969589 0.561378
+v -0.207419 -0.968368 0.58116
+v -0.213033 -0.970077 0.558937
+v -0.214895 -0.960019 0.638912
+v -0.0443099 -0.925517 0.233797
+v -0.00495186 -0.95709 0.681623
+v -0.000481699 -0.96404 0.666376
+v 0.00558128 -0.968047 0.649047
+v -0.0793775 -0.925696 0.180348
+v 0.0360118 -0.921085 0.0364421
+v 0.0231665 -0.920622 0.0334492
+v 0.198158 -0.912671 0.41105
+v 0.184259 -0.914328 0.409675
+v 0.559586 -0.968767 0.113861
+v 0.545636 -0.970385 0.11255
+v 0.548552 -0.972723 0.139192
+v 0.535142 -0.973314 0.137059
+v 0.539792 -0.972517 0.161093
+v 0.528642 -0.968895 0.155569
+v 0.532701 -0.969165 0.180515
+v 0.521577 -0.96553 0.174991
+v 0.317003 -0.967996 0.577268
+v 0.311775 -0.961715 0.593684
+v 0.303656 -0.968587 0.575071
+v 0.297825 -0.963372 0.59231
+v 0.311698 -0.969589 0.554531
+v 0.324504 -0.970038 0.557563
+v -0.186482 -0.969113 0.563806
+v 0.0479836 -0.923487 0.181029
+v 0.0351897 -0.923025 0.178062
+v 0.0444255 -0.921946 0.155621
+v 0.176527 -0.927148 0.140515
+v 0.146687 -0.911952 0.469239
+v 0.0915035 -0.967251 0.576189
+v 0.0821778 -0.968985 0.598424
+v 0.760487 -0.902485 0.212898
+v -0.0228068 -0.912479 0.504037
+v 0.0572194 -0.922408 0.158691
+v 0.000134876 -0.923243 0.124497
+v -0.0121324 -0.921727 0.120656
+v -0.004027 -0.922755 0.0999621
+v 0.108228 -0.944091 -0.191125
+v 0.121664 -0.943564 -0.189006
+v 0.107997 -0.928137 -0.181825
+v 0.0312333 -0.922498 0.22329
+v 0.0220233 -0.923603 0.245615
+v 0.0173219 -0.924142 0.221915
+v 0.332507 -0.971027 0.536946
+v 0.319161 -0.971631 0.534801
+v 0.328371 -0.970501 0.512515
+v 0.34173 -0.969897 0.514724
+v 0.526856 -0.963898 0.197997
+v 0.51929 -0.961805 0.217972
+v 0.510003 -0.962845 0.240413
+v 0.498532 -0.968112 0.266219
+v 0.349527 -0.962986 0.463857
+v 0.338082 -0.96833 0.489444
+v 0.350349 -0.969833 0.493324
+v 0.359867 -0.959762 0.439926
+v 0.378506 -0.965453 0.425655
+v 0.368538 -0.959724 0.418448
+v 0.146096 -0.91894 0.0801932
+v 0.103565 -0.917719 -0.0243804
+v 0.0907328 -0.917244 -0.0273733
+v 0.10011 -0.916409 -0.0501866
+v 0.110026 -0.914547 -0.0738348
+v 0.314935 -0.969447 0.0892363
+v 0.0854533 -0.918413 0.0202699
+v 0.0721071 -0.918991 0.0181247
+v 0.0814456 -0.918105 -0.00465
+v 0.172262 -0.918824 0.0853827
+v 0.162988 -0.919865 0.107823
+v 0.489836 -0.968124 0.287812
+v 0.374884 -0.963873 0.400285
+v -0.118967 -0.927533 0.313053
+v -0.776261 0.0604757 0.662047
+v 0.481731 -0.967084 0.308531
+v 0.473047 -0.967097 0.330124
+v 0.459675 -0.9677 0.32794
+v 0.464929 -0.966069 0.350882
+v 0.456875 -0.965042 0.371525
+v 0.447639 -0.966133 0.393914
+v 0.381268 -0.96806 0.382109
+v 0.402745 -0.968497 0.363586
+v 0.398069 -0.969062 0.339874
+v 0.38936 -0.969088 0.361441
+v 0.10255 -0.920019 0.328506
+v 0.0664937 -0.921342 0.136289
+v 0.0530703 -0.92192 0.134118
+v -0.00677589 -0.914418 0.462983
+v 0.000738605 -0.916461 0.443227
+v -0.0838734 -0.926249 0.226386
+v -0.0924669 -0.9263 0.247901
+v -0.0972453 -0.92684 0.224215
+v 0.0761405 -0.919312 0.0430189
+v 0.406149 -0.970077 0.31918
+v 0.43956 -0.965119 0.414569
+v 0.430311 -0.966223 0.436907
+v -0.0307452 -0.923937 0.0955819
+v -0.0343419 -0.922408 0.0701353
+v -0.0394286 -0.923962 0.117149
+v 0.420574 -0.968381 0.460067
+v 0.412456 -0.967379 0.480722
+v 0.403259 -0.968484 0.502983
+v 0.395192 -0.967495 0.523561
+v 0.386624 -0.967559 0.545
+v 0.501423 -0.971901 0.0810667
+v 0.488988 -0.961984 0.117393
+v 0.49378 -0.969563 0.101349
+v 0.379662 -0.964438 0.563947
+v 0.525289 -0.968446 0.058703
+v -0.622836 -0.966493 0.490678
+v 0.0115287 -0.920019 0.379334
+v -0.101728 -0.927405 0.270149
+v -0.116205 -0.930102 0.269661
+v 0.374421 -0.958156 0.580376
+v 0.512174 -0.958747 0.166912
+v 0.795015 -0.870372 0.284986
+v 0.795374 -0.886916 0.20487
+v 0.511892 -0.969024 0.0565193
+v 0.786267 -0.887238 0.227375
+v 0.243078 -0.910333 0.441339
+v 0.22968 -0.910924 0.439155
+v 0.787166 -0.86856 0.305525
+v -0.587756 -0.464036 0.537987
+v -0.492264 -0.503394 0.524897
+v -0.492521 -0.48843 0.535097
+v 0.21654 -0.918362 0.327118
+v 0.122679 -0.915728 0.421454
+v 0.0434749 -0.968381 0.589689
+v 0.168652 -0.911284 0.450086
+v 0.394832 -0.97271 -0.18153
+v 0.780667 -0.864129 0.323766
+v 0.763274 -0.872093 0.327362
+v -0.695194 0.486862 -0.396945
+v -0.712252 0.48369 -0.321389
+v 0.251646 -0.910282 0.419874
+v 0.238287 -0.910873 0.417678
+v 0.246341 -0.911875 0.397074
+v 0.775387 -0.857899 0.340452
+v 0.757905 -0.865709 0.343984
+v 0.172236 -0.919659 0.295943
+v 0.155537 -0.918683 0.338127
+v 0.163591 -0.919685 0.317497
+v 0.265043 -0.909678 0.422084
+v 0.131298 -0.915677 0.400028
+v -0.694821 0.480966 -0.365744
+v -0.704288 0.47922 -0.342456
+v 0.000545925 -0.922267 0.053719
+v 0.770056 -0.85154 0.357035
+v 0.752728 -0.85953 0.360683
+v 0.60082 -0.949846 0.0568019
+v 0.585174 -0.962138 0.0889537
+v 0.572997 -0.968176 0.116019
+v 0.563607 -0.968998 0.138806
+v 0.553125 -0.971927 0.163264
+v 0.544942 -0.970681 0.184394
+v 0.537402 -0.968574 0.204356
+v 0.528115 -0.969627 0.226835
+v 0.321563 -0.974727 -0.000333978
+v -0.692458 0.477267 -0.337793
+v 0.296013 -0.917347 0.605553
+v 0.282218 -0.935318 0.608585
+v 0.519997 -0.968574 0.247593
+v 0.511326 -0.968574 0.269237
+v 0.503182 -0.967534 0.290008
+v 0.495681 -0.96544 0.309906
+v 0.486985 -0.965453 0.331511
+v 0.478918 -0.964412 0.352192
+v 0.470812 -0.963397 0.372938
+v 0.228755 -0.91253 -0.0518693
+v 0.225351 -0.911297 -0.0776627
+v 0.461564 -0.964489 0.395301
+v 0.0114002 -0.913301 0.488776
+v 0.00393708 -0.911271 0.508481
+v 0.0911823 -0.917475 0.393426
+v 0.0777719 -0.918079 0.391165
+v 0.0858644 -0.919068 0.370561
+v 0.390195 -0.968022 0.43033
+v 0.137888 -0.954727 0.643511
+v 0.259147 -0.97569 0.154452
+v 0.254472 -0.976281 0.130688
+v 0.331454 -0.972903 -0.0240336
+v 0.452906 -0.964528 0.416817
+v 0.319186 -0.971374 -0.0278358
+v 0.444274 -0.964566 0.43832
+v 0.434524 -0.966724 0.461454
+v 0.425289 -0.967829 0.483741
+v 0.417196 -0.96684 0.504358
+v 0.409142 -0.965838 0.524974
+v 0.123 -0.921547 0.171266
+v 0.110206 -0.921098 0.168273
+v 0.697365 -0.897912 0.337035
+v 0.681758 -0.902768 0.33823
+v 0.687615 -0.908137 0.320786
+v 0.188588 -0.940764 -0.178293
+v 0.201973 -0.940212 -0.17616
+v 0.187805 -0.925838 -0.168119
+v 0.710274 -0.906441 0.30049
+v 0.703248 -0.903166 0.319591
+v 0.694064 -0.912312 0.302455
+v 0.190155 -0.970668 -0.198614
+v 0.196141 -0.976281 -0.216443
+v 0.208909 -0.976769 -0.213463
+v 0.40051 -0.965876 0.546426
+v 0.39419 -0.961702 0.564525
+v 0.389489 -0.95438 0.580119
+v -0.154908 -0.967456 0.591642
+v 0.259314 -0.975613 0.224395
+v 0.254575 -0.976178 0.200682
+v -0.143643 -0.925632 0.375571
+v 0.290811 -0.96815 0.572027
+v 0.42796 -0.967469 -0.155724
+v 0.417581 -0.969563 -0.130932
+v 0.406778 -0.97253 -0.105781
+v 0.397414 -0.973198 -0.0828265
+v 0.384595 -0.972723 -0.0858194
+v 0.298326 -0.97018 0.552284
+v 0.765933 -0.843152 0.372051
+v 0.14151 -0.91348 -0.116455
+v 0.128691 -0.912992 -0.1195
+v 0.138068 -0.91226 -0.142326
+v 0.760923 -0.835278 0.387478
+v 0.210104 -0.914136 -0.00620428
+v -0.107611 -0.963654 0.686941
+v 0.38805 -0.973905 -0.0599233
+v 0.379302 -0.973584 -0.0378551
+v 0.375256 -0.97343 -0.0628906
+v 0.369334 -0.975382 -0.0141427
+v 0.339405 -0.964939 0.0661019
+v 0.307189 -0.967932 0.320375
+v 0.0686132 -0.944746 -0.198421
+v 0.279841 -0.956666 0.605643
+v 0.0956525 -0.959595 -0.203418
+v 0.283952 -0.965016 0.590935
+v 0.103745 -0.968767 0.580055
+v 0.138774 -0.917732 0.380259
+v 0.252391 -0.964553 0.282879
+v 0.241267 -0.960892 0.277394
+v 0.245403 -0.969332 0.262532
+v 0.344055 -0.948779 0.450061
+v 0.117939 -0.916281 0.397806
+v 0.125428 -0.918323 0.378037
+v 0.227676 -0.914084 0.371987
+v 0.219044 -0.914136 0.39349
+v 0.134034 -0.918272 0.356585
+v 0.147406 -0.917681 0.358795
+v 0.248807 -0.955074 0.296893
+v 0.246405 -0.943461 0.309315
+v 0.238274 -0.950398 0.290548
+v 0.244542 -0.930834 0.320811
+v 0.234009 -0.926172 0.31444
+v 0.235872 -0.938786 0.302956
+v 0.353265 -0.947649 0.427748
+v 0.176154 -0.913339 0.430279
+v 0.517518 -0.965273 0.150046
+v 0.306919 -0.970115 0.530909
+v 0.315525 -0.970051 0.509509
+v 0.3606 -0.975112 0.00782279
+v 0.350683 -0.976949 0.0315095
+v 0.343631 -0.973571 0.0509188
+v 0.0132628 -0.969319 0.629201
+v 0.0214452 -0.969589 0.608649
+v 0.0996346 -0.910655 0.481545
+v 0.0862626 -0.911258 0.479309
+v 0.0782214 -0.910282 0.499862
+v 0.27609 -0.976654 0.182069
+v 0.266842 -0.977694 0.204523
+v 0.0943294 -0.912247 0.458757
+v 0.271556 -0.977129 0.228299
+v 0.280214 -0.977116 0.206668
+v 0.26462 -0.973995 0.247311
+v 0.251761 -0.973519 0.244266
+v 0.257593 -0.970835 0.266373
+v 0.359097 -0.952903 0.410459
+v -0.0347401 -0.923397 0.140874
+v 0.211556 -0.912068 0.413272
+v 0.205685 -0.914739 0.391242
+v 0.363772 -0.96025 0.394762
+v 0.202898 -0.912132 0.434711
+v 0.189564 -0.912735 0.432527
+v 0.194857 -0.91113 0.455327
+v 0.18151 -0.911734 0.453118
+v 0.173418 -0.910744 0.473696
+v 0.241588 -0.920327 0.334016
+v 0.229912 -0.917771 0.329341
+v 0.376553 -0.968625 0.358371
+v 0.369052 -0.966544 0.378268
+v -0.101009 -0.966609 0.668867
+v 0.235217 -0.916152 0.352167
+v 0.142114 -0.919274 0.335905
+v 0.150797 -0.919235 0.314479
+v -0.23135 -0.971246 0.533581
+v 0.339585 -0.959313 -0.107117
+v 0.325969 -0.94386 -0.0999493
+v 0.310349 -0.963564 -0.0367761
+v 0.307266 -0.945324 -0.0541815
+v 0.331364 -0.950501 -0.116918
+v 0.101793 -0.91429 0.439027
+v 0.109859 -0.915279 0.418423
+v 0.0579516 -0.950385 0.666709
+v 0.384672 -0.96964 0.337716
+v 0.170875 -0.914932 0.407466
+v 0.393317 -0.969627 0.316136
+v 0.128806 -0.970732 0.586979
+v 0.115999 -0.97027 0.583973
+v 0.139108 -0.967456 0.563189
+v 0.180303 -0.920674 0.2753
+v 0.187252 -0.923808 0.256238
+v 0.0668148 -0.966365 0.638167
+v 0.073443 -0.969692 0.619863
+v 0.113752 -0.967238 0.62635
+v 0.120906 -0.969589 0.607236
+v 0.108703 -0.960828 0.642432
+v 0.191928 -0.931156 0.24058
+v 0.175602 -0.921239 0.251549
+v -0.422886 -0.559631 0.49746
+v -0.434589 -0.556972 0.492694
+v -0.552598 -0.953956 0.60414
+v -0.844071 0.006975 0.414543
+v -0.854668 0.0117278 0.408313
+v -0.526073 -0.673094 0.164535
+v -0.515527 -0.677782 0.170842
+v 0.297105 -0.975857 -0.221466
+v -0.951432 0.0572643 0.533607
+v 0.2876 -0.976628 -0.198139
+v 0.724648 -0.838772 0.406297
+v 0.281652 -0.971015 -0.180258
+v 0.279122 -0.959171 -0.167554
+v 0.266302 -0.958657 -0.170534
+v 0.158851 -0.92025 0.293798
+v 0.482681 -0.965941 0.0958259
+v 0.487485 -0.973519 0.0797308
+v 0.498507 -0.969602 0.0543998
+v 0.262128 -0.978272 0.180746
+v 0.273688 -0.973044 0.154953
+v 0.598572 -0.96156 0.0911631
+v 0.221626 -0.909922 0.459746
+v 0.200727 -0.914971 0.0165704
+v 0.187381 -0.915549 0.0144124
+v 0.197272 -0.91366 -0.00923577
+v 0.105762 -0.950334 0.655457
+v 0.271042 -0.962318 0.307979
+v 0.276309 -0.968638 0.291421
+v -0.897777 0.0784848 0.624962
+v -0.897328 0.0606427 0.611616
+v -0.908541 0.0642522 0.606272
+v -0.77409 -0.528777 0.124779
+v -0.224966 -0.94228 0.642278
+v -0.954219 0.0717281 0.336791
+v 0.278338 -0.944181 -0.157355
+v 0.266097 -0.942665 -0.161208
+v 0.166944 -0.921265 0.273091
+v 0.0668919 -0.920366 0.0654339
+v 0.0535328 -0.920956 0.0633016
+v 0.0627814 -0.919903 0.0408095
+v 0.0121581 -0.917578 -0.0428776
+v 0.587473 -0.965504 0.116481
+v 0.576426 -0.96946 0.141863
+v 0.567088 -0.970295 0.1646
+v 0.557749 -0.971143 0.187362
+v 0.550235 -0.969036 0.207362
+v 0.540922 -0.970077 0.229841
+v 0.533382 -0.96797 0.249803
+v 0.525251 -0.966917 0.270599
+v 0.517145 -0.965876 0.291383
+v 0.50904 -0.964836 0.312077
+v 0.501525 -0.962742 0.332012
+v 0.493381 -0.961702 0.352745
+v 0.484171 -0.962781 0.375121
+v 0.475514 -0.962819 0.396637
+v 0.466869 -0.962858 0.418166
+v 0.727667 -0.849524 0.393297
+v -0.0439759 -0.924489 0.163251
+v -0.50087 -0.954431 0.616382
+v -0.937854 0.0355815 0.276893
+v -0.942299 0.044008 0.292295
+v -0.946204 0.0534364 0.306887
+v -0.95034 0.0621712 0.322211
+v 0.193238 -0.913416 -0.0341813
+v 0.277529 -0.929242 -0.147169
+v 0.2653 -0.927726 -0.151022
+v -0.947154 0.0488121 0.518513
+v 0.181408 -0.926493 0.234221
+v 0.457646 -0.963963 0.440504
+v -0.0260824 -0.923371 0.119346
+v 0.448461 -0.965054 0.462829
+v 0.439239 -0.966172 0.485116
+v 0.114368 -0.921573 0.192821
+v 0.100983 -0.922164 0.190637
+v 0.431172 -0.96517 0.505707
+v 0.422514 -0.965221 0.527171
+v 0.414498 -0.964194 0.547813
+v 0.409232 -0.957925 0.564255
+v -0.801656 -0.485809 0.286065
+v 0.227715 -0.945697 0.284189
+v 0.337838 -0.969435 0.55976
+v 0.33094 -0.966326 0.578681
+v -0.54967 -0.638591 0.312976
+v -0.544968 -0.645258 0.297189
+v 0.0399039 -0.922472 0.201735
+v 0.026532 -0.923063 0.199577
+v -0.931804 0.0390754 0.298666
+v -0.935941 0.0477845 0.313978
+v -0.940128 0.0564551 0.329289
+v -0.944418 0.0649458 0.344639
+v 0.183347 -0.915279 -0.010546
+v 0.174587 -0.915086 0.0114195
+v 0.273868 -0.919492 -0.132705
+v 0.261639 -0.917976 -0.136584
+v 0.195486 -0.940623 0.22654
+v 0.181202 -0.970424 0.597525
+v 0.0430253 -0.918285 0.407389
+v 0.0296405 -0.918876 0.405154
+v -0.113739 -0.919248 0.445218
+v 0.308332 -0.973751 0.279257
+v 0.0612528 -0.96097 0.655007
+v 0.127753 -0.920995 0.195004
+v 0.119044 -0.921021 0.216585
+v -0.0767699 -0.922626 0.386643
+v 0.242384 -0.974675 0.196803
+v -0.160303 -0.924733 0.417511
+v 0.199057 -0.950102 0.2125
+v 0.677031 -0.89533 0.353939
+v 0.203746 -0.957476 0.196777
+v 0.345545 -0.937681 0.417292
+v 0.339739 -0.932453 0.434582
+v 0.0948304 -0.917527 -0.00245345
+v -0.929839 0.0598462 0.375198
+v -0.921245 0.0342327 0.304973
+v -0.925446 0.0428904 0.320323
+v -0.929903 0.0512656 0.335725
+v -0.934463 0.0590498 0.351794
+v 0.267381 -0.914983 -0.114092
+v 0.190798 -0.941239 0.202763
+v 0.186636 -0.932774 0.217676
+v 0.280625 -0.912748 0.381634
+v 0.273598 -0.917514 0.361287
+v 0.160072 -0.911348 0.471487
+v 0.613639 -0.957848 0.0907906
+v 0.349694 -0.946095 0.402443
+v 0.600858 -0.964913 0.118665
+v 0.110425 -0.921046 0.238126
+v 0.353252 -0.955575 0.388378
+v 0.35681 -0.965029 0.374389
+v 0.590389 -0.967816 0.143174
+v 0.581038 -0.968651 0.165974
+v 0.571699 -0.969499 0.188749
+v 0.56362 -0.968433 0.209558
+v 0.363182 -0.969216 0.356213
+v 0.555437 -0.967379 0.230342
+v 0.371274 -0.970244 0.335532
+v 0.740628 -0.873789 0.347671
+v 0.746485 -0.879029 0.330214
+v 0.201202 -0.925272 -0.165974
+v 0.547319 -0.966326 0.251126
+v 0.539252 -0.96526 0.271948
+v 0.294125 -0.969653 0.527852
+v 0.531648 -0.963166 0.291897
+v 0.523594 -0.9621 0.312642
+v 0.516041 -0.960006 0.332526
+v 0.509605 -0.955819 0.350779
+v 0.502116 -0.953725 0.370625
+v 0.379379 -0.971259 0.314825
+v 0.493407 -0.953776 0.392193
+v 0.482514 -0.958015 0.41701
+v 0.473844 -0.958079 0.438538
+v 0.471005 -0.963359 0.0911374
+v 0.233316 -0.9542 0.616677
+v -0.919396 0.0463715 0.342045
+v -0.924328 0.0531795 0.358949
+v -0.475693 -0.599901 0.43087
+v -0.936313 0.0639054 0.393811
+v 0.195486 -0.948587 0.187028
+v 0.10905 -0.959043 -0.201273
+v 0.121831 -0.959505 -0.19828
+v 0.136411 -0.920969 0.17345
+v -0.152262 -0.925709 0.396971
+v 0.462938 -0.962331 0.463343
+v 0.454293 -0.962395 0.484859
+v 0.445661 -0.962447 0.50631
+v 0.484004 -0.972261 0.0539374
+v 0.475218 -0.972004 0.0759414
+v 0.43762 -0.961432 0.52694
+v 0.430684 -0.958323 0.545848
+v 0.42489 -0.953083 0.563138
+v 0.192159 -0.930295 0.0998208
+v 0.184054 -0.929242 0.120579
+v -0.110348 -0.927469 0.291614
+v -0.124837 -0.930167 0.2911
+v 0.0138922 -0.921676 0.0558899
+v 0.265352 -0.959351 0.605091
+v 0.276925 -0.969807 0.570627
+v 0.270015 -0.966699 0.589522
+v 0.284915 -0.970783 0.550074
+v -0.0366797 -0.920828 0.393272
+v -0.0447466 -0.919839 0.41385
+v -0.0494865 -0.920378 0.39024
+v 0.0590948 -0.920263 0.366181
+v 0.0510408 -0.919274 0.386759
+v 0.0462752 -0.919813 0.363111
+v 0.819472 -0.86612 0.261787
+v 0.356977 -0.97298 0.0530896
+v -0.909428 0.0399232 0.349893
+v -0.91454 0.0470138 0.36613
+v -0.920539 0.0522932 0.383882
+v -0.928272 0.05422 0.403381
+v -0.938009 0.0516509 0.426477
+v -0.594885 -0.951592 0.570973
+v 0.200753 -0.954894 0.170508
+v 0.209565 -0.962729 0.179385
+v 0.206584 -0.960147 0.153116
+v 0.216013 -0.966955 0.161119
+v -0.206353 -0.953327 0.656883
+v -0.0136224 -0.924849 0.192988
+v -0.0264164 -0.924386 0.189982
+v 0.0844 -0.92025 0.0922549
+v 0.0757423 -0.920263 0.113861
+v 0.0710538 -0.920841 0.0900841
+v 0.0878169 -0.922729 0.258242
+v 0.399624 -0.975498 0.0160181
+v 0.386187 -0.976063 0.0138344
+v 0.217709 -0.97718 -0.235608
+v 0.204324 -0.97772 -0.237728
+v 0.0744192 -0.92332 0.256097
+v 0.811508 -0.864142 0.282352
+v 0.303579 -0.928098 -0.0707391
+v 0.312353 -0.928407 -0.0927944
+v 0.062319 -0.920854 0.11169
+v 0.154291 -0.919877 0.129442
+v 0.00822741 -0.91849 0.423497
+v 0.804238 -0.861303 0.302083
+v 0.796864 -0.858233 0.321698
+v -0.0701674 -0.924617 0.157997
+v 0.0696793 -0.923885 0.232384
+v 0.692663 -0.890564 0.352835
+v 0.0383368 -0.917463 -0.0377138
+v 0.363477 -0.977424 0.0344896
+v 0.284928 -0.976525 0.230432
+v -0.00767507 -0.921457 0.00423895
+v -0.575386 -0.465308 0.541532
+v -0.904534 0.0411178 0.373207
+v -0.911098 0.0454467 0.391165
+v -0.920064 0.0447145 0.412861
+v -0.929813 0.0422225 0.435648
+v -0.942042 0.0423253 0.501891
+v -0.54326 -0.664205 0.106719
+v 0.734642 -0.917604 0.126475
+v -0.432777 -0.970013 0.578462
+v 0.222924 -0.970077 0.142043
+v 0.711006 -0.920918 0.0772388
+v 0.291363 -0.934084 -0.0436355
+v 0.212969 -0.964348 0.13485
+v -0.0933147 -0.967508 0.64933
+v -0.0280477 -0.920751 0.371897
+v -0.0414582 -0.921355 0.369662
+v -0.0339694 -0.923397 0.349906
+v 0.2853 -0.920083 0.365988
+v 0.0582855 -0.914598 -0.15607
+v 0.295525 -0.973288 0.276277
+v 0.282667 -0.972826 0.273232
+v 0.289668 -0.975973 0.254183
+v 0.791457 -0.851797 0.338358
+v 0.787385 -0.843512 0.353413
+v 0.782542 -0.835921 0.369045
+v 0.256617 -0.967302 0.587313
+v 0.26408 -0.969358 0.567569
+v 0.631237 -0.950578 0.0868342
+v 0.431711 -0.967816 -0.129956
+v 0.321935 -0.943705 -0.124985
+v 0.317722 -0.935022 -0.109737
+v 0.221113 -0.965414 0.114066
+v 0.230477 -0.972184 0.12212
+v 0.228717 -0.967649 0.0938606
+v 0.239289 -0.972325 0.100232
+v 0.237452 -0.967778 0.0719722
+v 0.247471 -0.973532 0.0792041
+v 0.248473 -0.963757 0.046744
+v 0.256784 -0.972659 0.0565065
+v 0.261267 -0.956615 0.0188826
+v 0.267227 -0.969692 0.0320233
+v 0.276296 -0.945285 -0.0123829
+v 0.421936 -0.968831 -0.106141
+v 0.334999 -0.960212 -0.131343
+v 0.401486 -0.97334 -0.0577653
+v 0.3927 -0.973031 -0.0356971
+v 0.382732 -0.974817 -0.0120232
+v -0.0214195 -0.923834 0.283367
+v -0.03483 -0.924425 0.281184
+v 0.373381 -0.975588 0.0108543
+v 0.272147 -0.970334 0.547056
+v 0.615425 -0.962228 0.119179
+v 0.281318 -0.969203 0.524795
+v 0.604943 -0.965131 0.143675
+v 0.276309 -0.976551 0.251986
+v 0.233007 -0.912479 0.394839
+v 0.241048 -0.91348 0.374171
+v -0.894746 0.0349135 0.380375
+v -0.901733 0.0383047 0.399168
+v -0.911534 0.0357099 0.422186
+v -0.921181 0.033295 0.445077
+v -0.929299 0.0340272 0.465526
+v -0.936249 0.0370458 0.484499
+v -0.670736 -0.979659 -0.0303277
+v -0.0398268 -0.924977 0.187811
+v -0.0311563 -0.924939 0.166257
+v 0.224902 -0.911477 0.415507
+v 0.332019 -0.922485 0.4241
+v 0.595039 -0.967007 0.167259
+v 0.585701 -0.967855 0.190059
+v 0.336746 -0.929858 0.408429
+v 0.577531 -0.966788 0.210868
+v 0.569413 -0.965722 0.231729
+v 0.561282 -0.964682 0.252487
+v 0.3397 -0.940327 0.395263
+v -0.133456 -0.930231 0.312513
+v 0.553754 -0.962562 0.272462
+v 0.546188 -0.960456 0.292398
+v 0.539792 -0.95623 0.310664
+v 0.533369 -0.952042 0.328891
+v 0.526972 -0.947816 0.347157
+v 0.250811 -0.962087 0.604525
+v 0.658392 -0.88946 0.368133
+v 0.259135 -0.913609 -0.0928715
+v 0.252108 -0.910166 -0.0734109
+v 0.242179 -0.911965 -0.0496985
+v 0.232262 -0.913802 -0.0260503
+v 0.222346 -0.915664 -0.00236353
+v 0.213007 -0.916486 0.0203726
+v 0.202538 -0.919454 0.0448172
+v 0.191427 -0.915831 0.0392938
+v 0.181536 -0.917758 0.0628649
+v 0.193161 -0.920327 0.0675663
+v 0.324479 -0.955575 -0.137753
+v 0.183925 -0.921393 0.0900584
+v 0.411942 -0.970565 -0.0823512
+v 0.34462 -0.975562 -0.163623
+v 0.33866 -0.969974 -0.145781
+v 0.332327 -0.97402 -0.167451
+v 0.519997 -0.944682 0.366207
+v 0.345108 -0.962434 0.369713
+v 0.342141 -0.951939 0.38288
+v 0.51193 -0.943654 0.386913
+v 0.208267 -0.910539 0.457498
+v -0.885356 0.0282211 0.387735
+v -0.89278 0.0303149 0.407979
+v -0.902556 0.0276945 0.430754
+v -0.91183 0.026153 0.452758
+v -0.919884 0.0269366 0.473246
+v -0.926897 0.0298782 0.492193
+v -0.932986 0.0343226 0.510369
+v -0.937983 0.0414646 0.526259
+v -0.942106 0.0501352 0.541378
+v -0.944971 0.0610537 0.554904
+v 0.124028 -0.919531 0.0996153
+v 0.111157 -0.919068 0.0966095
+v 0.119879 -0.919068 0.0749652
+v 0.0563716 -0.917681 0.409585
+v 0.216886 -0.910475 0.436111
+v 0.350362 -0.968754 0.353194
+v 0.502116 -0.945799 0.410125
+v 0.49175 -0.949011 0.434107
+v 0.358454 -0.969781 0.332475
+v 0.366586 -0.970809 0.311781
+v 0.483118 -0.949049 0.455584
+v 0.471609 -0.954406 0.481249
+v 0.462411 -0.95551 0.50351
+v 0.459277 -0.960777 0.0864232
+v 0.454332 -0.954496 0.524178
+v 0.233431 -0.919287 0.00317279
+v 0.222371 -0.923269 0.0284652
+v 0.248807 -0.949139 0.614994
+v 0.255679 -0.934483 0.326335
+v 0.248576 -0.915549 0.354389
+v 0.175242 -0.921406 0.111664
+v 0.166546 -0.921406 0.133321
+v 0.253277 -0.94219 -0.164201
+v 0.241588 -0.939621 -0.16889
+v 0.202602 -0.912633 -0.0569817
+v 0.241228 -0.956641 -0.177368
+v 0.212506 -0.910822 -0.0806813
+v 0.22128 -0.911117 -0.10275
+v 0.230079 -0.911451 -0.124766
+v 0.248807 -0.917488 -0.139577
+v 0.236591 -0.91596 -0.143392
+v 0.252481 -0.927238 -0.154028
+v 0.240252 -0.925722 -0.157856
+v 0.248524 -0.976166 -0.206193
+v 0.157875 -0.921406 0.154863
+v 0.145094 -0.920944 0.151883
+v 0.256797 -0.97763 -0.227516
+v 0.353676 -0.975755 -0.186231
+v 0.340728 -0.975343 -0.189096
+v 0.326996 -0.967405 -0.150483
+v 0.364119 -0.973661 -0.211074
+v 0.350555 -0.974187 -0.212936
+v -0.0522226 -0.917809 0.433542
+v -0.0581057 -0.920443 0.411602
+v 0.123565 -0.957296 0.642586
+v 0.463542 -0.969447 0.0712143
+v 0.446894 -0.952402 0.543921
+v 0.441615 -0.946159 0.560376
+v 0.470016 -0.973892 0.0525886
+v 0.151876 -0.967919 0.566246
+v -0.875157 0.022505 0.394877
+v -0.882722 0.0243804 0.414903
+v -0.892536 0.0217342 0.437729
+v -0.901669 0.0203341 0.459759
+v -0.909865 0.0209764 0.480209
+v -0.917405 0.0228646 0.499952
+v -0.923172 0.0282211 0.51737
+v -0.928413 0.0345025 0.533979
+v -0.932536 0.0431602 0.549085
+v -0.935645 0.053886 0.562663
+v 0.0644127 -0.91867 0.388981
+v 0.0482919 -0.916692 0.430125
+v 0.439226 -0.934534 0.572708
+v 0.482245 -0.96788 0.0255108
+v 0.777892 -0.827571 0.383381
+v 0.26986 -0.972363 0.270201
+v 0.264054 -0.96711 0.287593
+v 0.259944 -0.958696 0.302468
+v 0.257503 -0.947109 0.3148
+v 0.253817 -0.921843 0.33787
+v 0.344941 -0.965915 -0.124124
+v 0.0951901 -0.927649 -0.184805
+v 0.24259 -0.970565 -0.188389
+v 0.198132 -0.914508 -0.152384
+v 0.1853 -0.91402 -0.15539
+v 0.172365 -0.91253 -0.0871425
+v 0.158967 -0.913095 -0.0892877
+v 0.16774 -0.913391 -0.111317
+v 0.191067 -0.91104 -0.132872
+v 0.177631 -0.911605 -0.135043
+v 0.180509 -0.913866 -0.108337
+v 0.162962 -0.913301 -0.0643036
+v 0.14959 -0.913879 -0.0664616
+v 0.153084 -0.91515 -0.0406682
+v 0.140264 -0.914688 -0.0436869
+v 0.144298 -0.914932 -0.0187413
+v 0.134998 -0.91578 0.00404627
+v 0.125094 -0.917707 0.0276174
+v 0.149205 -0.921419 0.176494
+v 0.139982 -0.922498 0.198909
+v 0.131285 -0.922524 0.220425
+v 0.122628 -0.922562 0.241967
+v 0.114535 -0.921534 0.262635
+v 0.101163 -0.922138 0.260464
+v 0.0925568 -0.914906 -0.100913
+v 0.27311 -0.91068 0.401493
+v -0.079673 -0.926763 0.250894
+v -0.0883178 -0.926814 0.272397
+v -0.865112 0.0165961 0.402019
+v -0.872729 0.0184587 0.421891
+v -0.882504 0.0158511 0.444679
+v -0.891098 0.0155428 0.466002
+v -0.899781 0.0150804 0.487209
+v -0.906705 0.0181376 0.506182
+v -0.912652 0.0233014 0.523587
+v -0.918381 0.0286193 0.540967
+v -0.922402 0.0373927 0.555957
+v -0.925536 0.0480543 0.56956
+v -0.797532 -0.516895 0.223367
+v -0.79251 -0.523266 0.207092
+v 0.216373 -0.970604 -0.193489
+v 0.229783 -0.970051 -0.191344
+v 0.214459 -0.957745 -0.181645
+v -0.0200322 -0.921753 0.351242
+v 0.0408545 -0.914649 0.449868
+v 0.142217 -0.970128 0.589239
+v -0.0740596 -0.925195 0.343252
+v -0.0869049 -0.924746 0.340221
+v 0.67784 -0.91822 0.304434
+v 0.127573 -0.965735 0.628007
+v 0.777635 -0.89524 0.209314
+v 0.422373 -0.974149 -0.00470138
+v 0.0750872 -0.915497 0.434556
+v 0.0617152 -0.916088 0.432347
+v 0.0697435 -0.917077 0.411807
+v 0.0805721 -0.920661 0.347786
+v 0.0730448 -0.918619 0.367555
+v 0.0672002 -0.921265 0.345551
+v 0.0975793 -0.972402 -0.215223
+v 0.103488 -0.97799 -0.233027
+v 0.111709 -0.979428 -0.254324
+v 0.164246 -0.91217 -0.137226
+v 0.154934 -0.912915 -0.11431
+v 0.171337 -0.915639 -0.156713
+v 0.173829 -0.92743 -0.169429
+v 0.174613 -0.942395 -0.179603
+v 0.174844 -0.958349 -0.18889
+v 0.115755 -0.918593 0.0503536
+v 0.102332 -0.919184 0.048157
+v 0.662194 -0.922986 0.305628
+v 0.684841 -0.921329 0.285345
+v 0.668604 -0.927225 0.287311
+v -0.137143 -0.967302 0.617769
+v -0.145312 -0.967418 0.638064
+v -0.149873 -0.966776 0.614596
+v 0.255872 -0.910783 0.44437
+v 0.017309 -0.910667 0.510703
+v 0.00902382 -0.923166 0.172808
+v 0.024785 -0.912697 0.490973
+v 0.72538 -0.910693 0.260503
+v 0.24223 -0.974765 0.126834
+v 0.717249 -0.909614 0.281351
+v 0.701064 -0.915472 0.283342
+v -0.847937 0.00634558 0.390792
+v -0.862247 0.0135518 0.428108
+v -0.871932 0.0110598 0.450947
+v -0.880552 0.0107515 0.472219
+v -0.889274 0.0102377 0.493426
+v -0.896326 0.013449 0.51177
+v -0.90253 0.0174953 0.530549
+v -0.907886 0.0237124 0.54721
+v -0.911958 0.0323958 0.562226
+v -0.915093 0.0431217 0.575855
+v -0.9177 0.0543228 0.589034
+v 0.227407 -0.925221 -0.160849
+v 0.223733 -0.915484 -0.146424
+v 0.214574 -0.92472 -0.163829
+v 0.0354081 -0.922999 0.247811
+v -0.0386965 -0.923937 0.326271
+v -0.0521069 -0.92454 0.324074
+v -0.0434364 -0.924476 0.302648
+v 0.0327876 -0.913673 0.470459
+v -0.0648623 -0.924078 0.321017
+v 0.134188 -0.969113 0.609664
+v -0.804405 -0.512527 0.172474
+v -0.0306553 -0.924939 0.30568
+v 0.0129545 -0.923693 0.127528
+v 0.31943 -0.96946 0.324215
+v 0.105942 -0.921573 0.284164
+v 0.0978619 -0.920571 0.304819
+v 0.0891785 -0.92061 0.326309
+v 0.0758065 -0.921213 0.324061
+v 0.216681 -0.912003 -0.126886
+v 0.204452 -0.910488 -0.130752
+v 0.210939 -0.914996 -0.149417
+v -0.0573221 -0.925067 0.161067
+v -0.675297 0.0214902 0.60152
+v 0.15853 -0.91515 -0.159693
+v 0.150849 -0.912735 -0.139359
+v 0.145107 -0.915716 -0.161851
+v 0.0711051 -0.915073 -0.153077
+v 0.0971939 -0.920712 0.0952993
+v 0.136025 -0.921958 0.244189
+v 0.106455 -0.919646 0.0727815
+v 0.0879839 -0.921779 0.117689
+v 0.0792748 -0.921791 0.139282
+v 0.057669 -0.921432 0.0879132
+v 0.0448237 -0.920969 0.0848946
+v -0.0177586 -0.924348 0.16844
+v -0.0219333 -0.923859 0.143906
+v 0.0670203 -0.914508 0.455109
+v 0.0541879 -0.914059 0.452077
+v 0.70863 -0.917591 0.263329
+v -0.852215 0.0076558 0.435096
+v -0.860808 0.0073732 0.456381
+v -0.870006 0.00598591 0.478436
+v -0.878008 0.00675663 0.498911
+v -0.884996 0.00977527 0.517807
+v -0.890866 0.0148235 0.535289
+v -0.896107 0.0212847 0.551821
+v -0.900976 0.028478 0.567801
+v -0.904187 0.0391268 0.581481
+v -0.90691 0.0503407 0.594763
+v 0.0262237 -0.924091 0.270175
+v 0.228409 -0.956153 -0.180361
+v -0.0148171 -0.966596 0.665412
+v -0.00713556 -0.967521 0.645874
+v 0.370413 -0.972389 0.0552733
+v 0.0657487 -0.923371 0.277587
+v 0.0382726 -0.918824 0.383753
+v 0.0757423 -0.914226 -0.128915
+v 0.047701 -0.916615 -0.0605142
+v -0.0197111 -0.960892 0.681636
+v -0.54159 -0.631924 0.33146
+v -0.0707455 -0.952055 0.707018
+v -0.0864424 -0.941124 0.715367
+v -0.0667891 -0.960135 0.692734
+v 0.505854 -0.962665 0.145396
+v 0.299392 -0.975061 0.0194478
+v 0.309861 -0.972158 -0.00500967
+v -0.0341749 -0.963102 0.6803
+v -0.0479836 -0.964618 0.67863
+v -0.157554 -0.965864 0.634108
+v 0.132698 -0.919518 0.0780095
+v -0.828734 -0.00714199 0.405783
+v 0.0488314 -0.921534 0.0394736
+v 0.0406746 -0.920494 0.0602573
+v 0.0586966 -0.919582 0.0159282
+v 0.068626 -0.917642 -0.00763011
+v 0.0645284 -0.91736 -0.0325757
+v 0.0779388 -0.916782 -0.0303663
+v 0.0738797 -0.916512 -0.0553504
+v 0.0181311 -0.923089 0.290818
+v -0.0668919 -0.927212 0.253939
+v -0.0570781 -0.925067 0.230817
+v 0.00947341 -0.92314 0.312269
+v -0.0382212 -0.968201 0.617217
+v -0.834206 0.000166989 0.422186
+v -0.841643 0.0028645 0.441364
+v -0.850237 0.00259475 0.462598
+v -0.858856 0.00229931 0.483895
+v -0.867475 0.00199102 0.505128
+v -0.873307 0.00720621 0.522534
+v -0.879768 0.0111626 0.540697
+v -0.884996 0.0176237 0.557306
+v -0.889864 0.02474 0.573286
+v -0.893358 0.0346438 0.587493
+v -0.895876 0.046577 0.600286
+v 0.722092 -0.924797 0.154786
+v 0.692394 -0.923474 0.26532
+v 0.00924219 -0.968034 0.604667
+v 0.000520235 -0.968792 0.626016
+v 0.249912 -0.976769 0.176893
+v 0.664352 -0.929344 0.0501352
+v 0.14196 -0.918464 0.0555431
+v 0.129127 -0.918002 0.0524859
+v 0.137914 -0.918169 0.0306232
+v 0.238197 -0.974187 0.172204
+v 0.245724 -0.976281 0.152255
+v 0.114741 -0.920597 0.122082
+v 0.114766 -0.914598 -0.120797
+v 0.101895 -0.914136 -0.123764
+v 0.124079 -0.913866 -0.143636
+v -0.636054 -0.408108 0.548443
+v 0.0872517 -0.915934 -0.0531667
+v -0.100238 -0.925337 0.338037
+v 0.105993 -0.914328 -0.098806
+v 0.0960122 -0.916165 -0.0751193
+v 0.163938 -0.970706 -0.203714
+v 0.150579 -0.971284 -0.205872
+v -0.185634 -0.948972 0.678887
+v -0.196257 -0.943693 0.67258
+v -0.195422 -0.95709 0.662548
+v -0.183758 -0.959698 0.667455
+v -0.129448 -0.968523 0.597987
+v -0.0484717 -0.925016 0.209288
+v 0.119365 -0.913763 -0.0966223
+v 0.00141941 -0.922151 0.332873
+v -0.011914 -0.922742 0.330689
+v -0.0464293 -0.96797 0.637808
+v -0.101895 -0.913994 0.489008
+v -0.107252 -0.915561 0.466323
+v -0.824263 -0.00583177 0.429161
+v -0.831097 -0.0019011 0.447569
+v -0.839113 -0.00109185 0.468083
+v -0.847192 -0.000269751 0.488597
+v -0.855182 0.000513812 0.509033
+v -0.861618 0.00462431 0.527248
+v -0.86804 0.00867058 0.545386
+v -0.873333 0.0148749 0.56202
+v -0.878098 0.0222609 0.577948
+v -0.881746 0.0319206 0.592297
+v -0.884778 0.0428391 0.605784
+v -0.886126 0.057046 0.616947
+v -0.887 0.0722805 0.627493
+v -0.060238 -0.916833 0.454107
+v 0.121433 -0.927572 -0.17968
+v 0.646009 -0.945825 0.0867443
+v 0.630531 -0.95849 0.118768
+v 0.619458 -0.962447 0.144124
+v 0.061073 -0.923924 0.253874
+v 0.0395699 -0.9235 0.272359
+v 0.123809 -0.97235 -0.210098
+v 0.110977 -0.971888 -0.213116
+v -0.163142 -0.967251 0.612168
+v 0.135255 -0.958966 -0.196148
+v 0.135049 -0.942999 -0.186848
+v -0.843108 -0.432514 0.276803
+v -0.0526079 -0.924515 0.184767
+v 0.137181 -0.971837 -0.208004
+v 0.142551 -0.978439 -0.22496
+v 0.15135 -0.978837 -0.247079
+v -0.105672 -0.920211 0.424704
+v -0.0749459 -0.92621 0.274543
+v -0.0540594 -0.967058 0.657397
+v 0.381306 -0.973365 -0.183444
+v 0.445057 -0.965401 -0.0564037
+v -0.81138 -0.0226848 0.422572
+v -0.886448 0.0787545 0.631847
+v -0.814501 -0.0118947 0.436291
+v -0.820346 -0.00707776 0.454454
+v -0.827256 -0.00499682 0.474441
+v -0.83549 -0.00285166 0.493259
+v -0.842992 -0.000950552 0.512964
+v -0.849916 0.0020424 0.531898
+v -0.855786 0.00725759 0.549316
+v -0.861155 0.0132692 0.566054
+v -0.866383 0.0198331 0.582573
+v -0.870006 0.02948 0.596934
+v -0.8726 0.0412719 0.609843
+v -0.874514 0.054387 0.621738
+v -0.875067 0.0701096 0.631462
+v 0.70055 -0.924527 0.244472
+v 0.179853 -0.913994 -0.0363393
+v 0.166443 -0.914572 -0.0384974
+v 0.176385 -0.912723 -0.0621841
+v 0.207908 -0.911682 -0.104843
+v 0.19853 -0.912427 -0.0819787
+v 0.19451 -0.912247 -0.107053
+v -0.00438667 -0.923757 0.170637
+v 0.608976 -0.965376 0.168607
+v 0.60019 -0.965157 0.190573
+v 0.591507 -0.965131 0.21223
+v 0.171106 -0.913776 -0.014361
+v 0.160598 -0.916705 0.0100707
+v 0.157104 -0.915394 -0.0157226
+v 0.0809446 -0.912851 0.45656
+v 0.064888 -0.910886 0.497614
+v 0.0729292 -0.911862 0.477113
+v 0.289462 -0.976936 0.043096
+v -0.681205 0.0524859 0.667506
+v -0.101921 -0.919531 -0.111741
+v 0.131709 -0.916268 -0.163996
+v 0.134818 -0.927007 -0.177522
+v -0.764096 -0.54265 0.161825
+v -0.772304 -0.53317 0.151433
+v 0.00925504 -0.922254 0.0321132
+v 0.0511564 -0.917938 -0.0347337
+v -0.105543 -0.92693 0.315262
+v 0.709247 -0.92454 0.222827
+v 0.362578 -0.974072 -0.137252
+v -0.06124 -0.965106 0.676228
+v 0.215962 -0.938632 -0.174876
+v 0.228794 -0.939145 -0.171896
+v -0.80461 -0.0186771 0.443818
+v -0.810198 -0.0123443 0.460697
+v -0.818059 -0.0114323 0.481352
+v -0.824379 -0.00652541 0.498706
+v -0.831328 -0.00351961 0.517653
+v -0.8377 0.000590884 0.535854
+v -0.844097 0.00467569 0.553966
+v -0.849453 0.01088 0.570665
+v -0.853564 0.0193836 0.585758
+v -0.85743 0.0285808 0.600556
+v -0.860372 0.0398204 0.613787
+v -0.862196 0.0531538 0.625412
+v -0.862453 0.0697371 0.634712
+v 0.354909 -0.971618 -0.116892
+v 0.300818 -0.971657 0.299193
+v 0.583376 -0.964078 0.233052
+v 0.575797 -0.961971 0.252975
+v 0.568282 -0.959852 0.27295
+v 0.0884591 -0.914893 0.436766
+v -0.799421 -0.498025 0.274478
+v -0.780821 -0.524949 0.142763
+v -0.788618 -0.523266 0.162377
+v -0.795426 -0.520196 0.181221
+v -0.801604 -0.516021 0.199166
+v -0.170785 -0.966352 0.631732
+v -0.178954 -0.96648 0.651989
+v -0.826036 -0.426464 0.343059
+v -0.804212 -0.474467 0.298422
+v -0.0916705 -0.925285 0.316585
+v -0.0174118 -0.923346 0.0977527
+v -0.096937 -0.926865 0.293798
+v 0.148639 -0.958439 -0.194028
+v 0.160997 -0.926955 -0.172422
+v 0.147637 -0.927533 -0.17458
+v -0.142165 -0.967996 0.59484
+v 0.314164 -0.971079 0.301351
+v 0.147753 -0.916242 0.00707776
+v 0.189757 -0.912157 -0.0600132
+v -0.800975 -0.0195505 0.468699
+v -0.807423 -0.01544 0.486721
+v -0.813242 -0.010212 0.504204
+v -0.819652 -0.00608867 0.522367
+v -0.825998 -0.00197818 0.540543
+v -0.831855 0.00322417 0.557936
+v -0.837186 0.00940276 0.574673
+v -0.841348 0.0179449 0.589766
+v -0.844456 0.0286322 0.603421
+v -0.847 0.0405911 0.616227
+v -0.848965 0.0537961 0.628045
+v -0.849774 0.0693646 0.637923
+v 0.561847 -0.955639 0.291241
+v 0.555463 -0.951413 0.309507
+v 0.549592 -0.946159 0.326926
+v 0.0483818 -0.922498 0.11029
+v 0.0355494 -0.922035 0.107297
+v 0.0167952 -0.918426 0.402135
+v -0.802105 -0.509817 0.238897
+v -0.805728 -0.500697 0.252783
+v -0.77978 -0.53114 0.171125
+v -0.786473 -0.528019 0.189969
+v -0.816479 -0.457138 0.303599
+v -0.820307 -0.448057 0.317561
+v -0.823095 -0.436869 0.329983
+v -0.71662 -0.452977 0.478744
+v -0.789889 -0.0233399 0.474056
+v -0.795785 -0.018099 0.491487
+v -0.802092 -0.0138858 0.50965
+v -0.807937 -0.00865773 0.527055
+v -0.813782 -0.00345539 0.544461
+v -0.819652 0.00177265 0.561879
+v -0.825021 0.00778425 0.578668
+v -0.829119 0.0166475 0.593568
+v -0.831136 0.0295699 0.605707
+v -0.833075 0.0427492 0.617563
+v -0.834565 0.0565964 0.62924
+v 0.717326 -0.917604 0.241671
+v 0.095948 -0.916936 0.417023
+v 0.289758 -0.93077 -0.143341
+v 0.543774 -0.940892 0.344331
+v 0.537377 -0.936705 0.362533
+v 0.530992 -0.932492 0.380786
+v 0.520601 -0.93569 0.404807
+v -0.732921 -0.564371 0.0724089
+v -0.770711 -0.538642 0.179744
+v -0.776595 -0.533902 0.197085
+v -0.782645 -0.529149 0.214247
+v -0.787757 -0.522983 0.230573
+v -0.79269 -0.516098 0.246116
+v -0.796608 -0.507775 0.260785
+v -0.807937 -0.466066 0.313027
+v -0.811611 -0.456869 0.326939
+v -0.813949 -0.445385 0.339167
+v -0.816877 -0.434248 0.351653
+v -0.820628 -0.425141 0.365603
+v -0.0710666 -0.926711 0.229417
+v -0.778303 -0.0261916 0.478834
+v -0.783582 -0.0197818 0.49552
+v -0.789851 -0.015363 0.513542
+v -0.795708 -0.0101221 0.531012
+v -0.802118 -0.0060116 0.549162
+v -0.80795 -0.000796408 0.56658
+v -0.812895 0.00602444 0.582843
+v -0.816929 0.0150547 0.597627
+v -0.818727 0.0287092 0.608996
+v -0.818188 0.0465514 0.618154
+v 0.236899 -0.963744 0.603138
+v -0.0976178 -0.921188 0.404177
+v 0.511673 -0.937154 0.427247
+v 0.242667 -0.968972 0.585887
+v 0.250117 -0.971015 0.566208
+v -0.725239 -0.574352 0.0828393
+v -0.695477 -0.960314 0.146758
+v -0.755515 -0.551474 0.171485
+v -0.760448 -0.544461 0.186976
+v -0.766781 -0.539721 0.204227
+v -0.772458 -0.534352 0.220618
+v -0.778072 -0.529021 0.237715
+v -0.782825 -0.522508 0.253952
+v -0.786948 -0.514364 0.268634
+v -0.790236 -0.504987 0.282442
+v -0.792895 -0.494454 0.295455
+v -0.795773 -0.484126 0.308557
+v -0.79978 -0.47516 0.322571
+v -0.803107 -0.465051 0.335725
+v -0.805163 -0.4534 0.347876
+v -0.807719 -0.441377 0.359591
+v -0.810994 -0.431885 0.373374
+v -0.814193 -0.422353 0.387106
+v 0.0624346 -0.921804 0.321929
+v 0.412443 -0.97596 0.0189725
+v 0.409515 -0.973686 -0.00770718
+v -0.00412976 -0.923731 0.240413
+v -0.0461853 -0.921894 0.346052
+v -0.0601224 -0.923538 0.344691
+v -0.765779 -0.0445603 0.473221
+v -0.52913 -0.67046 0.138434
+v -0.766935 -0.0294029 0.484011
+v -0.771264 -0.0209378 0.499322
+v -0.777661 -0.0168145 0.517473
+v -0.784071 -0.0126783 0.535713
+v -0.789877 -0.00747596 0.553119
+v -0.79594 -0.00276174 0.570665
+v -0.800641 0.00454724 0.586773
+v -0.804739 0.0135133 0.601635
+v -0.806087 0.0278101 0.612785
+v -0.804854 0.047412 0.620454
+v -0.806678 0.0607069 0.632104
+v 0.104529 -0.916872 0.395597
+v 0.211928 -0.926249 0.0528712
+v 0.201446 -0.929229 0.0772902
+v 0.259327 -0.969884 0.544011
+v 0.461782 -0.932851 0.552669
+v -0.536118 -0.480748 0.541288
+v 0.268486 -0.968741 0.521789
+v -0.709491 -0.584949 0.0715612
+v -0.717211 -0.583588 0.0923192
+v -0.737558 -0.573298 0.148222
+v -0.742632 -0.567056 0.164612
+v -0.747179 -0.55976 0.180207
+v -0.751675 -0.553003 0.196597
+v -0.757147 -0.547004 0.212924
+v -0.762593 -0.54062 0.228492
+v -0.767911 -0.534621 0.244806
+v -0.772574 -0.527466 0.260297
+v -0.776993 -0.520093 0.275711
+v -0.780782 -0.511757 0.290381
+v -0.784071 -0.501737 0.303534
+v -0.787423 -0.492335 0.317369
+v -0.791033 -0.483163 0.331293
+v -0.794116 -0.472964 0.344382
+v -0.796351 -0.461416 0.35656
+v -0.798714 -0.449264 0.368249
+v -0.801168 -0.438551 0.381056
+v -0.804122 -0.427504 0.393593
+v -0.806871 -0.416971 0.406528
+v -0.594615 -0.973763 0.346194
+v -0.00884399 -0.924283 0.216687
+v 0.144709 -0.921933 0.222622
+v -0.0628842 -0.920969 0.387992
+v 0.120675 -0.918876 0.354363
+v 0.137413 -0.919826 0.312231
+v 0.146019 -0.919788 0.290753
+v 0.162243 -0.92183 0.249379
+v -0.0413426 -0.967585 0.660569
+v -0.756248 -0.0342713 0.490382
+v -0.758984 -0.0223894 0.503266
+v -0.764867 -0.0171613 0.520684
+v -0.771277 -0.013038 0.538847
+v -0.777635 -0.00892748 0.557023
+v -0.783557 -0.00429033 0.57475
+v -0.788387 0.00310856 0.590742
+v -0.792099 0.0127682 0.605168
+v -0.793884 0.0263329 0.616703
+v -0.793794 0.0436355 0.626003
+v -0.796415 0.0550549 0.638809
+v 0.0243354 -0.920468 0.38234
+v 0.112634 -0.917874 0.375018
+v -0.701026 -0.593299 0.080206
+v -0.709234 -0.592862 0.10185
+v -0.717031 -0.59159 0.12248
+v -0.723287 -0.587313 0.140566
+v -0.728797 -0.581841 0.157804
+v -0.733833 -0.574981 0.173399
+v -0.738585 -0.567916 0.18898
+v -0.743685 -0.562264 0.206154
+v -0.748797 -0.555495 0.22171
+v -0.752921 -0.547287 0.236379
+v -0.757519 -0.540042 0.251871
+v -0.762349 -0.533041 0.267413
+v -0.766806 -0.525642 0.282828
+v -0.771148 -0.517845 0.2976
+v -0.774873 -0.509342 0.312179
+v -0.778277 -0.500042 0.326001
+v -0.781874 -0.49087 0.339887
+v -0.785047 -0.480761 0.352963
+v -0.787539 -0.469444 0.365256
+v -0.78944 -0.457639 0.377279
+v -0.791803 -0.444858 0.388455
+v -0.794154 -0.433362 0.400683
+v -0.796505 -0.421891 0.412899
+v -0.798611 -0.409572 0.424576
+v 0.185698 -0.911952 -0.0850102
+v -0.0166668 -0.923281 0.307054
+v 0.436592 -0.966056 -0.106038
+v 0.426522 -0.967906 -0.0819658
+v 0.415436 -0.971734 -0.0564422
+v -0.745201 -0.0378422 0.495546
+v -0.746241 -0.022749 0.506387
+v -0.751572 -0.0163906 0.523112
+v -0.757956 -0.0122801 0.541288
+v -0.76488 -0.0092743 0.560209
+v -0.77075 -0.0047913 0.577987
+v -0.775451 0.00287735 0.593851
+v -0.779151 0.012871 0.607955
+v -0.781039 0.0261402 0.619786
+v -0.782889 0.039358 0.631642
+v -0.78574 0.0503279 0.64495
+v 0.322064 -0.916743 0.41692
+v 0.250387 -0.975947 0.105807
+v -0.684442 -0.602945 0.0693004
+v -0.693434 -0.603408 0.0906107
+v -0.701385 -0.602239 0.111305
+v -0.708797 -0.600582 0.132075
+v -0.715233 -0.596972 0.151022
+v -0.720011 -0.589252 0.165807
+v -0.723865 -0.580749 0.180566
+v -0.729106 -0.574455 0.196803
+v -0.735323 -0.570601 0.215043
+v -0.740397 -0.56441 0.231254
+v -0.74398 -0.555161 0.245075
+v -0.748014 -0.54685 0.259732
+v -0.752381 -0.539246 0.275095
+v -0.756736 -0.531436 0.289906
+v -0.761219 -0.523985 0.305268
+v -0.765265 -0.515996 0.320053
+v -0.769093 -0.507081 0.333978
+v -0.7726 -0.497884 0.347825
+v -0.775811 -0.488391 0.361505
+v -0.778598 -0.477344 0.373901
+v -0.780628 -0.465025 0.385423
+v -0.782388 -0.452463 0.39683
+v -0.784083 -0.439155 0.40771
+v -0.786074 -0.426746 0.419283
+v -0.788143 -0.414415 0.430947
+v -0.789877 -0.401788 0.442315
+v 0.0227683 -0.921573 0.104304
+v 0.0329546 -0.920404 0.360927
+v 0.326727 -0.924091 0.401223
+v 0.331595 -0.947238 0.376547
+v 0.329732 -0.934598 0.388082
+v 0.405494 -0.973507 -0.032717
+v -0.737635 -0.0145409 0.524692
+v -0.744635 -0.0115222 0.543677
+v -0.75102 -0.00741174 0.56184
+v -0.756864 -0.00265898 0.579528
+v -0.762169 0.00403342 0.59597
+v -0.765817 0.0136802 0.610331
+v -0.768361 0.0255621 0.623177
+v -0.772985 0.0355558 0.636022
+v -0.774655 0.0470395 0.65037
+v 0.799074 -0.828522 0.365847
+v 0.33401 -0.958812 0.36419
+v 0.346508 -0.96937 0.538385
+v -0.665097 -0.60739 0.0542585
+v -0.674834 -0.609432 0.0761084
+v -0.684314 -0.611102 0.0996024
+v -0.692959 -0.611077 0.120977
+v -0.699947 -0.607917 0.139975
+v -0.706112 -0.603601 0.158151
+v -0.710673 -0.596638 0.174606
+v -0.714128 -0.587261 0.18853
+v -0.720602 -0.584037 0.207516
+v -0.727577 -0.581185 0.226116
+v -0.731816 -0.573119 0.240734
+v -0.73522 -0.563767 0.254517
+v -0.738316 -0.553645 0.267478
+v -0.74249 -0.544769 0.281659
+v -0.746652 -0.536638 0.296354
+v -0.751264 -0.52992 0.312475
+v -0.75558 -0.522033 0.327208
+v -0.75978 -0.51403 0.34189
+v -0.763081 -0.504615 0.355635
+v -0.766357 -0.494608 0.368776
+v -0.769003 -0.484062 0.381685
+v -0.771354 -0.472681 0.393888
+v -0.773114 -0.460196 0.405256
+v -0.774449 -0.44595 0.415455
+v -0.776029 -0.432553 0.426323
+v -0.777661 -0.4199 0.437614
+v -0.726202 -0.462521 0.462097
+v 0.33812 -0.967238 0.349328
+v 0.345121 -0.970372 0.330317
+v -0.723723 -0.013038 0.526696
+v -0.730185 -0.00854212 0.544576
+v -0.737095 -0.00552348 0.563485
+v -0.742978 -0.000295442 0.580929
+v -0.748245 0.00616574 0.59746
+v -0.752471 0.0146308 0.612618
+v -0.756145 0.0240721 0.627133
+v -0.759742 0.0339116 0.641327
+v -0.762953 0.0444319 0.655149
+v -0.764867 0.0575855 0.667159
+v 0.396104 -0.974252 -0.00985234
+v 0.353201 -0.9714 0.309585
+v 0.354537 -0.970359 0.517755
+v -0.645508 -0.611243 0.0381891
+v -0.656273 -0.615226 0.0618758
+v -0.666009 -0.617306 0.0849845
+v -0.675952 -0.619876 0.109236
+v -0.684083 -0.618938 0.129789
+v -0.691238 -0.616022 0.148787
+v -0.696774 -0.609997 0.165306
+v -0.701848 -0.604525 0.183405
+v -0.706472 -0.59782 0.19977
+v -0.71337 -0.594416 0.217998
+v -0.719356 -0.589625 0.234876
+v -0.723274 -0.581327 0.249507
+v -0.726421 -0.571719 0.263213
+v -0.729337 -0.560736 0.275622
+v -0.732561 -0.551179 0.289379
+v -0.736723 -0.542907 0.3041
+v -0.741373 -0.53579 0.319604
+v -0.74574 -0.527967 0.334376
+v -0.749697 -0.519669 0.348904
+v -0.753229 -0.51001 0.362212
+v -0.756273 -0.500324 0.375841
+v -0.759382 -0.490164 0.388904
+v -0.76172 -0.47877 0.40112
+v -0.763634 -0.466361 0.412591
+v -0.765021 -0.452874 0.423304
+v -0.766036 -0.439104 0.433773
+v -0.767539 -0.424935 0.444216
+v 0.451814 -0.96684 0.0665386
+v 0.836312 -0.858361 0.258165
+v -0.709337 -0.0096982 0.527222
+v -0.715746 -0.00556201 0.54545
+v -0.722143 -0.00143867 0.563626
+v -0.729067 0.00156713 0.582573
+v -0.733845 0.00899171 0.59845
+v -0.739176 0.0148877 0.61538
+v -0.743955 0.0224022 0.631167
+v -0.747641 0.0320619 0.645592
+v -0.750647 0.0431217 0.658977
+v -0.752689 0.0561083 0.671115
+v 0.829325 -0.855844 0.278036
+v -0.711263 -0.966827 0.042428
+v 0.821938 -0.852812 0.297664
+v 0.660974 -0.940558 0.0862305
+v -0.626138 -0.615637 0.0231986
+v -0.635951 -0.617782 0.0463458
+v -0.645752 -0.620145 0.0681443
+v -0.656876 -0.624808 0.0927045
+v -0.666241 -0.626966 0.116057
+v -0.673832 -0.624371 0.137021
+v -0.681745 -0.622843 0.156828
+v -0.687461 -0.617409 0.174118
+v -0.693293 -0.612746 0.192217
+v -0.698803 -0.607428 0.209481
+v -0.704879 -0.60256 0.226527
+v -0.710069 -0.596574 0.24284
+v -0.714166 -0.588918 0.258152
+v -0.717159 -0.578668 0.271139
+v -0.719767 -0.567454 0.28347
+v -0.722721 -0.557088 0.296521
+v -0.726588 -0.548597 0.311113
+v -0.731238 -0.540941 0.326026
+v -0.73558 -0.533529 0.341377
+v -0.7396 -0.525347 0.355982
+v -0.743068 -0.51561 0.369225
+v -0.746305 -0.506105 0.382893
+v -0.749157 -0.495726 0.395841
+v -0.751713 -0.484537 0.408198
+v -0.753846 -0.472977 0.420208
+v -0.755438 -0.459682 0.431075
+v -0.756427 -0.445925 0.441506
+v 0.0524152 -0.923962 0.275377
+v 0.468808 -0.968458 0.0233656
+v 0.456657 -0.974457 0.050482
+v 0.647345 -0.951605 0.115903
+v 0.633421 -0.960803 0.145486
+v 0.622926 -0.963718 0.169956
+v -0.701283 -0.0025819 0.546311
+v -0.707718 0.00154144 0.564551
+v -0.714693 0.00454724 0.583459
+v -0.720486 0.00976243 0.600864
+v -0.726382 0.0144895 0.618552
+v -0.731148 0.0221196 0.634339
+v -0.73477 0.0319463 0.648572
+v -0.737327 0.0437768 0.661533
+v -0.73987 0.0558642 0.674198
+v -0.656735 -0.96463 0.189263
+v 0.614153 -0.963513 0.191857
+v -0.682721 -0.971747 0.144561
+v -0.678803 -0.978658 -0.00964682
+v -0.687834 -0.979441 0.0123315
+v -0.695566 -0.9779 0.0324858
+v -0.702773 -0.975369 0.0518051
+v 0.606009 -0.962447 0.212744
+v -0.616195 -0.621366 0.0303663
+v -0.626407 -0.624564 0.053141
+v -0.63748 -0.629188 0.0777783
+v -0.646574 -0.630422 0.100116
+v -0.655823 -0.631089 0.123597
+v -0.663273 -0.62906 0.143379
+v -0.671713 -0.628559 0.164047
+v -0.678405 -0.625104 0.18293
+v -0.683839 -0.619053 0.199359
+v -0.689118 -0.613453 0.216546
+v -0.694847 -0.60834 0.233682
+v -0.700114 -0.602303 0.250047
+v -0.704121 -0.594082 0.264626
+v -0.707358 -0.584525 0.278332
+v -0.710082 -0.573478 0.290715
+v -0.712998 -0.563112 0.303689
+v -0.716646 -0.553966 0.317664
+v -0.720628 -0.545527 0.332192
+v -0.725123 -0.538282 0.347632
+v -0.729324 -0.530344 0.362366
+v -0.732779 -0.521057 0.376085
+v -0.736003 -0.511089 0.389315
+v -0.738727 -0.500568 0.402199
+v -0.741771 -0.489817 0.414877
+v -0.743634 -0.477974 0.426721
+v -0.745509 -0.465526 0.438153
+v -0.746678 -0.451936 0.448763
+v 0.151285 -0.917578 0.0328197
+v 0.0577203 -0.922357 0.298216
+v 0.599034 -0.959274 0.231858
+v 0.591468 -0.957167 0.251832
+v -0.686344 0.0015029 0.546439
+v -0.693254 0.00453439 0.565411
+v -0.700216 0.00755304 0.584358
+v -0.706665 0.0116507 0.60256
+v -0.712419 0.0163649 0.620184
+v -0.717236 0.0239436 0.636099
+v -0.720885 0.0337061 0.650357
+v -0.723955 0.0445732 0.663896
+v -0.726498 0.0567634 0.676459
+v 0.583889 -0.955048 0.271819
+v -0.659034 -0.982229 -0.0256135
+v -0.668232 -0.983333 -0.00331409
+v -0.676157 -0.98201 0.0170586
+v -0.684442 -0.981458 0.0379579
+v -0.692162 -0.979929 0.0580864
+v -0.698315 -0.975433 0.0758001
+v 0.576914 -0.951888 0.290907
+v 0.571108 -0.946609 0.308326
+v 0.565212 -0.941368 0.325757
+v -0.607396 -0.629702 0.037778
+v -0.617814 -0.63258 0.0617987
+v -0.626844 -0.633813 0.0841624
+v -0.635489 -0.633607 0.106834
+v -0.644609 -0.634789 0.128029
+v -0.65328 -0.634815 0.150585
+v -0.661668 -0.634326 0.171125
+v -0.668604 -0.63064 0.189404
+v -0.673961 -0.625039 0.206565
+v -0.679009 -0.618732 0.222904
+v -0.684879 -0.614095 0.240798
+v -0.689953 -0.607904 0.257047
+v -0.694141 -0.599811 0.271742
+v -0.697223 -0.589663 0.284819
+v -0.699985 -0.579105 0.297741
+v -0.702901 -0.568764 0.310766
+v -0.706254 -0.559271 0.324588
+v -0.710017 -0.55028 0.338551
+v -0.714526 -0.542817 0.353888
+v -0.718701 -0.534968 0.368634
+v -0.722246 -0.525784 0.382456
+v -0.725368 -0.5157 0.395558
+v -0.728322 -0.505411 0.40857
+v -0.731097 -0.494916 0.421429
+v -0.73337 -0.483497 0.433554
+v -0.735348 -0.471204 0.445077
+v -0.736556 -0.457639 0.455674
+v 0.243951 -0.977129 -0.230509
+v 0.560267 -0.93578 0.342661
+v 0.553831 -0.931271 0.36076
+v -0.670801 0.00670525 0.545822
+v -0.677776 0.00972389 0.564756
+v -0.684725 0.0127425 0.583729
+v -0.690904 0.0162493 0.602175
+v -0.697275 0.0203855 0.620351
+v -0.702683 0.0266026 0.637178
+v -0.707538 0.0345795 0.652747
+v -0.710634 0.0455751 0.666119
+v 0.546831 -0.928047 0.379874
+v -0.63703 -0.981586 -0.0449585
+v -0.646754 -0.983744 -0.0217342
+v -0.655399 -0.983796 -0.000295442
+v -0.664429 -0.984592 0.0217086
+v -0.672175 -0.983038 0.04185
+v -0.679908 -0.981509 0.0619786
+v -0.687153 -0.979004 0.0812979
+v -0.694359 -0.976525 0.100566
+v 0.538802 -0.923333 0.401544
+v 0.531314 -0.923359 0.41954
+v -0.586818 -0.632451 0.0194606
+v -0.597351 -0.634969 0.0463587
+v -0.606561 -0.636073 0.0686581
+v -0.615193 -0.636125 0.0900969
+v -0.624969 -0.638296 0.113206
+v -0.634127 -0.639426 0.135505
+v -0.642169 -0.63845 0.156058
+v -0.650813 -0.638501 0.177458
+v -0.657955 -0.635778 0.196443
+v -0.663402 -0.629856 0.212962
+v -0.668887 -0.624333 0.230046
+v -0.67414 -0.618296 0.246437
+v -0.679253 -0.612053 0.262699
+v -0.683286 -0.603819 0.277381
+v -0.686575 -0.594262 0.291087
+v -0.689529 -0.583922 0.304112
+v -0.692496 -0.573658 0.317163
+v -0.695952 -0.564243 0.330972
+v -0.69951 -0.555097 0.344858
+v -0.703903 -0.547569 0.360182
+v -0.708026 -0.539387 0.374762
+v -0.711687 -0.530447 0.388686
+v -0.714719 -0.520273 0.401737
+v -0.717609 -0.509933 0.414685
+v -0.720294 -0.498924 0.42717
+v -0.722721 -0.48807 0.43972
+v -0.724764 -0.475867 0.451332
+v -0.661552 0.0158126 0.563485
+v -0.66827 0.0184587 0.582547
+v -0.692419 0.0383175 0.653196
+v -0.696183 0.0481827 0.667493
+v -0.625316 -0.984168 -0.0401929
+v -0.633948 -0.984207 -0.0187413
+v -0.643158 -0.985311 0.00359668
+v -0.6517 -0.985183 0.0248813
+v -0.65942 -0.983629 0.0449971
+v -0.667191 -0.9821 0.0651128
+v -0.675464 -0.981586 0.0859479
+v -0.682631 -0.979107 0.105254
+v 0.857571 -0.845208 0.249314
+v -0.576362 -0.637975 0.0270779
+v -0.586548 -0.640454 0.0513427
+v -0.596285 -0.642265 0.0745541
+v -0.605739 -0.642946 0.0981252
+v -0.614949 -0.64405 0.120348
+v -0.623003 -0.643061 0.140977
+v -0.632175 -0.644192 0.163212
+v -0.639689 -0.642136 0.182994
+v -0.646626 -0.639028 0.201915
+v -0.653293 -0.63547 0.220078
+v -0.658032 -0.628379 0.235647
+v -0.663132 -0.622136 0.251986
+v -0.668591 -0.616587 0.268981
+v -0.672278 -0.607634 0.282956
+v -0.676003 -0.598822 0.29733
+v -0.679202 -0.589239 0.310985
+v -0.682002 -0.578385 0.323522
+v -0.685213 -0.568713 0.337163
+v -0.689054 -0.559875 0.351203
+v -0.6931 -0.551667 0.365847
+v -0.696851 -0.542765 0.37981
+v -0.700679 -0.534262 0.394274
+v -0.703698 -0.524037 0.407286
+v -0.706703 -0.51385 0.42035
+v -0.709427 -0.50324 0.433169
+v -0.711893 -0.491975 0.445424
+v -0.714012 -0.479862 0.4571
+v -0.715695 -0.467248 0.468365
+v -0.528064 -0.653916 0.285474
+v 0.0397112 -0.922511 0.131934
+v 0.0269302 -0.922061 0.128851
+v 0.363143 -0.970295 0.496317
+v 0.37234 -0.969178 0.474107
+v 0.814552 -0.849755 0.317305
+v 0.00429675 -0.923718 0.14907
+v -0.602631 -0.982485 -0.0605656
+v -0.612496 -0.984631 -0.0372
+v -0.621141 -0.984682 -0.0157098
+v -0.62976 -0.984721 0.00576754
+v -0.638932 -0.985761 0.0280284
+v -0.64669 -0.98422 0.0481313
+v -0.655001 -0.983667 0.0690178
+v -0.662721 -0.982164 0.0891078
+v -0.670454 -0.980674 0.109159
+v -0.677146 -0.977219 0.127618
+v 0.807693 -0.845233 0.335622
+v -0.566099 -0.64238 0.0332565
+v -0.576221 -0.644975 0.0576625
+v -0.585444 -0.645463 0.0813493
+v -0.595232 -0.647621 0.104445
+v -0.603864 -0.647673 0.125884
+v -0.612445 -0.647763 0.147336
+v -0.621102 -0.647814 0.168762
+v -0.629156 -0.646812 0.189327
+v -0.635823 -0.643318 0.207593
+v -0.641757 -0.63836 0.224857
+v -0.646986 -0.632168 0.241222
+v -0.651867 -0.62554 0.257471
+v -0.657069 -0.61949 0.273823
+v -0.661552 -0.612014 0.289122
+v -0.665046 -0.602753 0.302995
+v -0.66836 -0.593209 0.316688
+v -0.671469 -0.583099 0.329803
+v -0.674796 -0.573581 0.343509
+v -0.678444 -0.564499 0.357472
+v -0.68213 -0.555546 0.371435
+v -0.686087 -0.547133 0.38595
+v -0.689581 -0.537884 0.399746
+v -0.692856 -0.528353 0.413336
+v -0.695669 -0.517601 0.425937
+v -0.698521 -0.507132 0.438808
+v -0.700949 -0.49579 0.451037
+v -0.703094 -0.483715 0.462778
+v -0.704866 -0.471166 0.474133
+v -0.705984 -0.45746 0.484589
+v -0.0681893 -0.922562 0.36523
+v -0.0553953 -0.923012 0.368275
+v -0.00852285 -0.923269 0.146051
+v 0.267869 -0.976268 0.0620428
+v 0.259109 -0.976088 0.0838926
+v -0.590941 -0.985054 -0.0558642
+v -0.599663 -0.985093 -0.0341685
+v -0.608925 -0.986185 -0.0118434
+v -0.616953 -0.985183 0.00877334
+v -0.62615 -0.986288 0.0310599
+v -0.633935 -0.984798 0.0512527
+v -0.642258 -0.984258 0.0721135
+v -0.649953 -0.982742 0.0922035
+v -0.657724 -0.981252 0.112268
+v -0.664905 -0.978799 0.131562
+v 0.802786 -0.838091 0.351781
+v -0.555668 -0.646273 0.039936
+v -0.564532 -0.646928 0.0637384
+v -0.574911 -0.650139 0.0876692
+v -0.584069 -0.651257 0.109956
+v -0.592714 -0.651334 0.131433
+v -0.601899 -0.652451 0.153681
+v -0.610556 -0.652503 0.175094
+v -0.618032 -0.650447 0.194837
+v -0.62457 -0.646786 0.212975
+v -0.630299 -0.641417 0.230329
+v -0.635656 -0.635572 0.246668
+v -0.640075 -0.627878 0.262083
+v -0.645097 -0.621468 0.277908
+v -0.650467 -0.615701 0.294671
+v -0.653883 -0.606247 0.308441
+v -0.656607 -0.596754 0.323226
+v -0.660704 -0.587467 0.335943
+v -0.664237 -0.578321 0.349829
+v -0.667474 -0.568327 0.363047
+v -0.671109 -0.55931 0.376971
+v -0.675014 -0.550832 0.391448
+v -0.678379 -0.541455 0.405154
+v -0.681604 -0.531513 0.418371
+v -0.684776 -0.521802 0.431846
+v -0.687397 -0.510755 0.444255
+v -0.689837 -0.499412 0.45647
+v -0.692021 -0.487826 0.468429
+v -0.693691 -0.474737 0.479528
+v -0.69486 -0.461056 0.49001
+v -0.695245 -0.445552 0.499361
+v -0.0735843 -0.917437 0.451872
+v 0.23514 -0.976718 -0.208376
+v 0.221729 -0.977245 -0.210457
+v -0.568321 -0.983385 -0.0762754
+v -0.578738 -0.986557 -0.0520363
+v -0.587448 -0.986609 -0.0303534
+v -0.596054 -0.986647 -0.00885041
+v -0.604185 -0.985645 0.011792
+v -0.612804 -0.985697 0.0332565
+v -0.621205 -0.985388 0.054387
+v -0.628925 -0.983847 0.0745156
+v -0.636696 -0.982331 0.0945542
+v -0.644391 -0.980854 0.114631
+v -0.652676 -0.980366 0.135428
+v -0.65933 -0.976936 0.153887
+v -0.664429 -0.970501 0.170008
+v 0.67748 -0.934341 0.0835073
+v -0.602322 -0.972505 0.366014
+v -0.553485 -0.65055 0.0692875
+v -0.563799 -0.653774 0.0932055
+v -0.573549 -0.655945 0.116327
+v -0.582708 -0.657063 0.138562
+v -0.591943 -0.65818 0.16081
+v -0.599445 -0.656125 0.180592
+v -0.60633 -0.653042 0.1995
+v -0.612701 -0.648867 0.217638
+v -0.618636 -0.644025 0.234992
+v -0.62371 -0.637576 0.251267
+v -0.628951 -0.631513 0.267555
+v -0.633806 -0.624834 0.283239
+v -0.638045 -0.616921 0.298139
+v -0.642657 -0.609664 0.313849
+v -0.645791 -0.599721 0.327041
+v -0.649413 -0.590614 0.340953
+v -0.653254 -0.582072 0.355352
+v -0.656401 -0.572078 0.368596
+v -0.660345 -0.56369 0.383111
+v -0.663787 -0.554365 0.396881
+v -0.667307 -0.545154 0.410703
+v -0.670467 -0.535161 0.423856
+v -0.673421 -0.524859 0.436843
+v -0.675939 -0.513632 0.449187
+v -0.678559 -0.502868 0.461776
+v -0.680679 -0.490793 0.473516
+v -0.682169 -0.477498 0.48446
+v -0.683094 -0.463497 0.494467
+v -0.683209 -0.447273 0.503638
+v -0.025286 -0.923333 0.328467
+v 0.663582 -0.945774 0.113835
+v 0.649079 -0.956011 0.144266
+v 0.218852 -0.957 0.616472
+v 0.638032 -0.95998 0.169596
+v 0.222949 -0.965414 0.601751
+v 0.629259 -0.959762 0.191523
+v 0.621706 -0.95763 0.211511
+v 0.612971 -0.95763 0.233181
+v 0.60597 -0.95447 0.25232
+v 0.59843 -0.952338 0.272333
+v 0.592573 -0.947071 0.289764
+v 0.586715 -0.941804 0.307182
+v -0.546163 -0.982807 -0.0958002
+v -0.556041 -0.9849 -0.0724089
+v -0.565328 -0.985979 -0.0498269
+v -0.574037 -0.986018 -0.0281826
+v -0.582721 -0.986056 -0.0066924
+v -0.591327 -0.986108 0.0147978
+v -0.599959 -0.986159 0.0362494
+v -0.607923 -0.984977 0.0566991
+v -0.616195 -0.984425 0.0775984
+v -0.623954 -0.982922 0.0977013
+v -0.632226 -0.982421 0.118536
+v -0.639432 -0.979955 0.137804
+v -0.647165 -0.978503 0.157817
+v -0.652753 -0.973057 0.174735
+v 0.580331 -0.937591 0.325436
+v -0.553266 -0.65845 0.0995382
+v -0.562463 -0.659567 0.121812
+v -0.571596 -0.660698 0.14406
+v -0.580254 -0.660762 0.165512
+v -0.587743 -0.658707 0.185281
+v -0.595245 -0.656652 0.205062
+v -0.601552 -0.652503 0.223136
+v -0.606793 -0.646221 0.23959
+v -0.612149 -0.640531 0.256058
+v -0.617403 -0.634416 0.272385
+v -0.62213 -0.627441 0.287953
+v -0.626369 -0.619593 0.302828
+v -0.63116 -0.612567 0.31864
+v -0.634654 -0.603292 0.332501
+v -0.638341 -0.594352 0.346463
+v -0.641732 -0.584898 0.360195
+v -0.645316 -0.57579 0.374119
+v -0.649221 -0.567287 0.388596
+v -0.652663 -0.557974 0.402353
+v -0.656247 -0.548828 0.416188
+v -0.65933 -0.538706 0.429238
+v -0.66213 -0.528224 0.442122
+v -0.664571 -0.516908 0.454338
+v -0.666729 -0.504949 0.466182
+v -0.668951 -0.493259 0.478089
+v -0.670608 -0.480581 0.489187
+v -0.670993 -0.465128 0.498565
+v -0.671225 -0.44947 0.507775
+v -0.671469 -0.433773 0.516959
+v -0.521307 -0.626953 0.353991
+v -0.533472 -0.625219 0.349983
+v 0.229295 -0.969589 0.583665
+v 0.237901 -0.969512 0.562316
+v 0.575142 -0.931862 0.34243
+v 0.5694 -0.92639 0.35963
+v 0.245968 -0.970475 0.541763
+v 0.563594 -0.921111 0.377048
+v 0.557557 -0.915523 0.394261
+v 0.311518 -0.912068 0.410561
+v 0.303464 -0.911053 0.431178
+v -0.533908 -0.984322 -0.0919723
+v -0.543247 -0.985376 -0.0693775
+v -0.551943 -0.985388 -0.0476561
+v -0.561269 -0.98648 -0.0251768
+v -0.569336 -0.985478 -0.00453439
+v -0.577929 -0.985517 0.0170072
+v -0.5866 -0.985568 0.0384331
+v -0.594641 -0.984579 0.0590627
+v -0.602926 -0.984027 0.0799491
+v -0.611224 -0.9835 0.100836
+v -0.618944 -0.98201 0.120874
+v -0.627204 -0.981522 0.141748
+v -0.634423 -0.979069 0.160952
+v -0.641038 -0.975639 0.179436
+v -0.551327 -0.663203 0.127335
+v -0.559959 -0.663267 0.148774
+v -0.56913 -0.664384 0.171009
+v -0.577184 -0.663395 0.191613
+v -0.583568 -0.659221 0.209764
+v -0.589349 -0.654005 0.227041
+v -0.595155 -0.64879 0.244279
+v -0.600486 -0.643113 0.260734
+v -0.605675 -0.636883 0.27706
+v -0.610248 -0.629535 0.292487
+v -0.614667 -0.622111 0.307478
+v -0.618546 -0.613479 0.321967
+v -0.623016 -0.605926 0.337215
+v -0.62669 -0.596972 0.351203
+v -0.630222 -0.587749 0.365051
+v -0.634089 -0.579143 0.379437
+v -0.637711 -0.570151 0.393426
+v -0.641308 -0.56107 0.407337
+v -0.644725 -0.55168 0.421017
+v -0.647718 -0.541442 0.434081
+v -0.650492 -0.530832 0.446849
+v -0.652894 -0.519451 0.459065
+v -0.655065 -0.507518 0.47087
+v -0.656876 -0.494994 0.482238
+v -0.658456 -0.482135 0.493157
+v -0.658957 -0.466875 0.502842
+v -0.659394 -0.451833 0.512103
+v -0.659433 -0.435494 0.521275
+v 0.320471 -0.94359 0.371011
+v 0.316219 -0.919415 0.394877
+v 0.318608 -0.930989 0.382507
+v 0.322346 -0.956255 0.359476
+v -0.52114 -0.984798 -0.0889537
+v -0.530427 -0.985838 -0.0663717
+v -0.539124 -0.985851 -0.0446246
+v -0.54728 -0.984849 -0.0238023
+v -0.556478 -0.985941 -0.00147721
+v -0.564544 -0.984926 0.019178
+v -0.573189 -0.984977 0.0406682
+v -0.581873 -0.985042 0.0620556
+v -0.590196 -0.984605 0.0830705
+v -0.597916 -0.983089 0.103212
+v -0.606189 -0.982588 0.124009
+v -0.613922 -0.981098 0.144099
+v -0.621616 -0.979659 0.164112
+v -0.628874 -0.977219 0.183341
+v -0.540241 -0.666825 0.132885
+v -0.5494 -0.667955 0.155107
+v -0.557492 -0.666954 0.175724
+v -0.565482 -0.665977 0.19634
+v -0.571841 -0.661815 0.214427
+v -0.577672 -0.656575 0.231742
+v -0.58344 -0.651359 0.248993
+v -0.588758 -0.645592 0.265422
+v -0.593344 -0.63818 0.280824
+v -0.598019 -0.631051 0.296341
+v -0.602785 -0.624217 0.311948
+v -0.606369 -0.615136 0.325924
+v -0.611417 -0.608636 0.34198
+v -0.614962 -0.599413 0.355828
+v -0.618931 -0.590999 0.370368
+v -0.622798 -0.582457 0.384794
+v -0.626459 -0.573491 0.398769
+v -0.630389 -0.564487 0.412193
+v -0.633241 -0.554583 0.425912
+v -0.636452 -0.544859 0.439399
+v -0.63906 -0.533748 0.451782
+v -0.641334 -0.5222 0.463792
+v -0.643209 -0.509791 0.475289
+v -0.645007 -0.497216 0.486541
+v -0.646318 -0.483767 0.497267
+v -0.646831 -0.468494 0.50694
+v -0.647024 -0.452758 0.516111
+v -0.647564 -0.437793 0.52554
+v -0.647641 -0.421454 0.534814
+v 0.33225 -0.96991 0.32726
+v 0.32584 -0.965709 0.345461
+v 0.234048 -0.973712 0.147605
+v 0.226546 -0.971618 0.167477
+v 0.277799 -0.974367 0.0384074
+v 0.340368 -0.970938 0.306566
+v 0.440163 -0.964284 0.0618244
+v -0.497903 -0.982139 -0.110277
+v -0.508873 -0.986313 -0.0850744
+v -0.517608 -0.986313 -0.0633787
+v -0.525777 -0.985273 -0.0424922
+v -0.535013 -0.986365 -0.0199359
+v -0.543093 -0.98535 0.000706491
+v -0.55175 -0.985401 0.0221838
+v -0.560408 -0.98544 0.0436226
+v -0.568449 -0.984451 0.0642779
+v -0.57694 -0.984194 0.0854469
+v -0.585187 -0.983667 0.106308
+v -0.593433 -0.983153 0.127194
+v -0.601154 -0.981689 0.147194
+v -0.608899 -0.980225 0.167246
+v -0.616606 -0.978799 0.187207
+v 0.848104 -0.847147 0.271562
+v -0.537736 -0.670525 0.159808
+v -0.546343 -0.670589 0.18126
+v -0.553806 -0.668546 0.201016
+v -0.56019 -0.664372 0.219141
+v -0.565957 -0.659156 0.236431
+v -0.571211 -0.652875 0.252834
+v -0.576465 -0.646799 0.269173
+v -0.581783 -0.640942 0.285615
+v -0.586458 -0.634057 0.301222
+v -0.590055 -0.625142 0.315249
+v -0.594718 -0.61773 0.330599
+v -0.599252 -0.610409 0.345962
+v -0.603234 -0.601918 0.360503
+v -0.607152 -0.593376 0.37498
+v -0.610877 -0.584589 0.388994
+v -0.614821 -0.576112 0.403484
+v -0.61852 -0.567287 0.417472
+v -0.621899 -0.557781 0.431127
+v -0.624789 -0.547402 0.444062
+v -0.627255 -0.536124 0.456316
+v -0.629477 -0.524435 0.468185
+v -0.631096 -0.511487 0.479348
+v -0.632804 -0.498757 0.490523
+v -0.63414 -0.485347 0.501249
+v -0.635027 -0.470896 0.51141
+v -0.635181 -0.455109 0.52044
+v -0.63545 -0.439463 0.52974
+v -0.635617 -0.423651 0.538847
+v -0.506188 -0.505141 0.523305
+v 0.839074 -0.845503 0.294196
+v 0.833037 -0.840506 0.312128
+v 0.444402 -0.972941 0.0466156
+v 0.454306 -0.971117 0.0229032
+v 0.464826 -0.968279 -0.00161851
+v -0.485584 -0.983667 -0.106372
+v -0.49545 -0.985735 -0.0829164
+v -0.504184 -0.985722 -0.0611565
+v -0.513497 -0.986789 -0.0386387
+v -0.522206 -0.986814 -0.0169815
+v -0.530312 -0.985812 0.0036866
+v -0.538918 -0.985851 0.0252153
+v -0.547011 -0.984849 0.045832
+v -0.55563 -0.9849 0.0672837
+v -0.56362 -0.983796 0.0877719
+v -0.571879 -0.983256 0.108697
+v -0.580151 -0.982742 0.129493
+v -0.588475 -0.982254 0.150329
+v -0.596157 -0.980803 0.17038
+v -0.603363 -0.978375 0.189622
+v -0.610556 -0.975947 0.2088
+v -0.563157 -0.949409 0.597987
+v -0.534705 -0.673158 0.185949
+v -0.541577 -0.670062 0.204895
+v -0.548501 -0.666954 0.223816
+v -0.55432 -0.661713 0.241106
+v -0.559535 -0.655444 0.257523
+v -0.564737 -0.649381 0.2739
+v -0.569567 -0.642753 0.289572
+v -0.572971 -0.635662 0.305808
+v -0.578327 -0.627403 0.319822
+v -0.582374 -0.619208 0.334479
+v -0.586536 -0.611025 0.349148
+v -0.591545 -0.604397 0.365153
+v -0.595591 -0.596202 0.379771
+v -0.599214 -0.587133 0.39367
+v -0.605405 -0.578527 0.407055
+v -0.606754 -0.569663 0.422096
+v -0.609747 -0.55949 0.435147
+v -0.612753 -0.549201 0.448185
+v -0.615476 -0.538513 0.460825
+v -0.617454 -0.526323 0.472463
+v -0.61924 -0.513683 0.483677
+v -0.620588 -0.500299 0.494441
+v -0.621989 -0.486901 0.505283
+v -0.623209 -0.473311 0.515867
+v -0.623414 -0.457575 0.524936
+v -0.623646 -0.441865 0.534159
+v -0.623466 -0.424794 0.543343
+v 0.69486 -0.92788 0.0797051
+v 0.679715 -0.939248 0.11169
+v 0.665881 -0.949126 0.141375
+v 0.441037 -0.965273 -0.0814906
+v 0.430517 -0.968047 -0.056879
+v 0.652586 -0.957257 0.17011
+v -0.472816 -0.984142 -0.103366
+v -0.482681 -0.986198 -0.0798721
+v -0.491403 -0.986198 -0.0581892
+v -0.5001 -0.986198 -0.0364678
+v -0.508256 -0.985183 -0.0156199
+v -0.517479 -0.986275 0.00671809
+v -0.525585 -0.98526 0.027399
+v -0.533626 -0.984258 0.0480029
+v -0.542271 -0.984309 0.0694931
+v -0.551417 -0.985363 0.0916897
+v -0.559188 -0.983834 0.111793
+v -0.567422 -0.98332 0.132653
+v -0.575142 -0.981843 0.152692
+v -0.583427 -0.981381 0.173501
+v -0.591134 -0.979942 0.193489
+v 0.644327 -0.956011 0.191177
+v 0.637339 -0.952826 0.210393
+v -0.484493 -0.607917 0.41331
+v -0.523568 -0.676793 0.191433
+v -0.529901 -0.672631 0.209584
+v -0.536811 -0.669523 0.228505
+v -0.542643 -0.664282 0.245808
+v -0.547306 -0.65696 0.261389
+v -0.552534 -0.650884 0.277741
+v -0.557325 -0.644346 0.293489
+v -0.562065 -0.63705 0.308981
+v -0.56606 -0.628803 0.32365
+v -0.570132 -0.620595 0.338332
+v -0.57432 -0.612644 0.353053
+v -0.579419 -0.606195 0.369135
+v -0.583414 -0.597846 0.383702
+v -0.586831 -0.589651 0.398615
+v -0.59143 -0.581173 0.412796
+v -0.594564 -0.571243 0.426001
+v -0.597955 -0.561738 0.43963
+v -0.601012 -0.551628 0.452745
+v -0.603389 -0.54026 0.46491
+v -0.605341 -0.528032 0.476548
+v -0.606998 -0.515199 0.487582
+v -0.608373 -0.501802 0.498372
+v -0.609773 -0.488442 0.509239
+v -0.611109 -0.474955 0.520029
+v -0.611738 -0.460119 0.529637
+v -0.612008 -0.444499 0.538937
+v 0.629233 -0.951747 0.231228
+v 0.621064 -0.950706 0.251999
+v 0.614063 -0.947533 0.271151
+v 0.419482 -0.971888 -0.0314068
+v 0.607075 -0.944386 0.29024
+v 0.601231 -0.939107 0.307709
+v -0.44954 -0.981535 -0.124651
+v -0.460549 -0.985658 -0.0994997
+v -0.469245 -0.98562 -0.0777654
+v -0.478006 -0.985607 -0.0559798
+v -0.487293 -0.98666 -0.0334492
+v -0.495437 -0.985645 -0.0126012
+v -0.503555 -0.984631 0.00809254
+v -0.5122 -0.984669 0.0295699
+v -0.520254 -0.983667 0.0501866
+v -0.529425 -0.984772 0.0725117
+v -0.537492 -0.983783 0.093077
+v -0.546433 -0.984412 0.114914
+v -0.554718 -0.983898 0.135788
+v -0.562438 -0.982421 0.155826
+v -0.570697 -0.981946 0.176623
+v -0.57843 -0.980507 0.196636
+v -0.586112 -0.979094 0.216662
+v 0.59599 -0.932761 0.324331
+v 0.590929 -0.927071 0.341312
+v 0.586253 -0.919749 0.357035
+v -0.511892 -0.679362 0.196122
+v -0.518815 -0.676254 0.215069
+v -0.525186 -0.672092 0.233168
+v -0.530376 -0.66581 0.249674
+v -0.53563 -0.659529 0.266103
+v -0.540254 -0.652387 0.281659
+v -0.553819 -0.63028 0.327478
+v -0.55798 -0.622329 0.342276
+v -0.561988 -0.614057 0.356945
+v -0.567101 -0.607595 0.372963
+v -0.571211 -0.5994 0.38762
+v -0.575283 -0.591256 0.402263
+v -0.579304 -0.582881 0.416779
+v -0.582772 -0.573568 0.430574
+v -0.586921 -0.563485 0.443099
+v -0.588796 -0.553183 0.456676
+v -0.591121 -0.541686 0.468763
+v -0.593022 -0.529303 0.480209
+v -0.594679 -0.516394 0.491153
+v -0.596092 -0.50315 0.502097
+v -0.597493 -0.489791 0.513003
+v -0.598918 -0.476496 0.52396
+v -0.599805 -0.46202 0.534197
+v 0.0831412 -0.916486 0.413953
+v 0.579599 -0.914893 0.374916
+v 0.574769 -0.907315 0.39051
+v -0.438404 -0.985144 -0.119127
+v -0.447164 -0.98508 -0.097316
+v -0.455912 -0.985042 -0.075556
+v -0.465147 -0.986082 -0.052974
+v -0.473317 -0.985029 -0.0321132
+v -0.482065 -0.985054 -0.0104047
+v -0.490697 -0.985093 0.0111112
+v -0.498776 -0.984091 0.031715
+v -0.50746 -0.98413 0.0531795
+v -0.516041 -0.984194 0.074644
+v -0.524685 -0.984245 0.0960957
+v -0.533163 -0.984001 0.11729
+v -0.541397 -0.983487 0.138125
+v -0.549695 -0.982986 0.159012
+v -0.557929 -0.982524 0.179821
+v -0.565649 -0.981085 0.199796
+v -0.573369 -0.979672 0.21977
+v -0.518173 -0.667326 0.253489
+v -0.523388 -0.661045 0.269944
+v -0.545688 -0.623755 0.346117
+v -0.549811 -0.615547 0.360773
+v -0.554898 -0.609111 0.376894
+v -0.559034 -0.601031 0.391589
+v -0.563106 -0.592888 0.406233
+v -0.567036 -0.584333 0.420683
+v -0.570582 -0.575033 0.434415
+v -0.573562 -0.564846 0.447492
+v -0.576478 -0.554493 0.460414
+v -0.578816 -0.542907 0.47236
+v -0.58028 -0.529856 0.483458
+v -0.581988 -0.517036 0.494531
+v -0.583388 -0.503793 0.505488
+v -0.584801 -0.490421 0.516394
+v -0.586446 -0.477575 0.527351
+v -0.0655431 -0.918413 0.431371
+v -0.414588 -0.981522 -0.141311
+v -0.425044 -0.984566 -0.116995
+v -0.434319 -0.985555 -0.0942973
+v -0.443066 -0.985517 -0.0725502
+v -0.451788 -0.985491 -0.0508288
+v -0.460523 -0.985491 -0.0290946
+v -0.469245 -0.985517 -0.00738605
+v -0.477877 -0.985555 0.0140913
+v -0.485995 -0.984554 0.0347337
+v -0.494627 -0.984592 0.0562496
+v -0.503234 -0.984643 0.0777269
+v -0.511892 -0.984708 0.0991529
+v -0.520421 -0.984579 0.120438
+v -0.528167 -0.983076 0.140476
+v -0.536966 -0.983564 0.162133
+v -0.545212 -0.983102 0.182904
+v -0.552894 -0.981663 0.202917
+v -0.561192 -0.981239 0.223727
+v -0.568385 -0.978825 0.242892
+v -0.575026 -0.975459 0.261248
+v -0.581629 -0.972106 0.279616
+v -0.596516 -0.968446 0.318589
+v -0.53807 -0.617936 0.365397
+v -0.542707 -0.610794 0.38085
+v -0.547267 -0.603408 0.396175
+v -0.5508 -0.594249 0.410022
+v -0.554846 -0.585913 0.424588
+v -0.558366 -0.57669 0.43841
+v -0.561372 -0.56649 0.451435
+v -0.564223 -0.55588 0.464216
+v -0.566112 -0.543613 0.475751
+v -0.567936 -0.531037 0.487055
+v -0.569336 -0.517807 0.497999
+v -0.570749 -0.504422 0.508866
+v -0.572367 -0.491512 0.519836
+v -0.573832 -0.478282 0.530896
+v -0.121754 -0.918272 0.465745
+v -0.329411 -0.979338 -0.317048
+v -0.33988 -0.982203 -0.292475
+v -0.349193 -0.982999 -0.26961
+v -0.358532 -0.983821 -0.246848
+v -0.366765 -0.982575 -0.225795
+v -0.3755 -0.982396 -0.203893
+v -0.384261 -0.982241 -0.181966
+v -0.392456 -0.98106 -0.16099
+v -0.402912 -0.984091 -0.136635
+v -0.411608 -0.984001 -0.114798
+v -0.420921 -0.984977 -0.0921779
+v -0.429656 -0.984939 -0.0704308
+v -0.437838 -0.98386 -0.0494672
+v -0.447113 -0.9849 -0.0269494
+v -0.455835 -0.984926 -0.00522804
+v -0.463966 -0.983911 0.0154015
+v -0.472598 -0.983963 0.0369045
+v -0.48123 -0.984001 0.0584333
+v -0.489875 -0.984053 0.0798592
+v -0.499098 -0.98517 0.102146
+v -0.507152 -0.984181 0.122763
+v -0.515385 -0.983654 0.143662
+v -0.523658 -0.983153 0.164458
+v -0.531892 -0.982678 0.185319
+v -0.540203 -0.982229 0.206064
+v -0.548462 -0.981805 0.226848
+v -0.556169 -0.980404 0.246784
+v -0.563337 -0.978028 0.265949
+v -0.570517 -0.975665 0.285089
+v -0.578186 -0.974342 0.30496
+v -0.586394 -0.974046 0.32559
+v -0.609978 -0.971271 0.385796
+v -0.618212 -0.971066 0.40631
+v -0.625341 -0.968857 0.425256
+v -0.637249 -0.96034 0.460093
+v -0.535026 -0.604924 0.400067
+v -0.53721 -0.595829 0.414621
+v -0.542643 -0.587544 0.428545
+v -0.546163 -0.578167 0.442264
+v -0.54913 -0.567955 0.455314
+v -0.551545 -0.556574 0.46753
+v -0.553831 -0.544923 0.479464
+v -0.555655 -0.532438 0.490819
+v -0.557107 -0.519271 0.501879
+v -0.558571 -0.506028 0.512913
+v -0.560241 -0.493157 0.523908
+v -0.561718 -0.479939 0.534968
+v -0.307805 -0.980135 -0.336059
+v -0.318287 -0.982961 -0.311434
+v -0.327574 -0.983731 -0.288608
+v -0.336977 -0.984528 -0.265821
+v -0.345738 -0.984309 -0.243817
+v -0.35446 -0.984104 -0.221915
+v -0.362681 -0.982884 -0.200862
+v -0.371415 -0.982729 -0.178986
+v -0.380728 -0.983642 -0.156263
+v -0.390105 -0.984566 -0.133591
+v -0.398789 -0.984476 -0.111767
+v -0.407549 -0.984399 -0.090007
+v -0.416271 -0.984361 -0.0682085
+v -0.425032 -0.984335 -0.0465
+v -0.433741 -0.984322 -0.0247657
+v -0.442476 -0.984335 -0.00307003
+v -0.45112 -0.984374 0.018433
+v -0.459752 -0.984425 0.0399746
+v -0.467845 -0.98341 0.0605656
+v -0.477029 -0.984515 0.082865
+v -0.486278 -0.985633 0.105164
+v -0.494332 -0.984631 0.125794
+v -0.503182 -0.985221 0.147554
+v -0.510915 -0.983731 0.167644
+v -0.518648 -0.982254 0.187644
+v -0.527421 -0.982807 0.209224
+v -0.535167 -0.981368 0.229237
+v -0.542874 -0.979981 0.249212
+v -0.551108 -0.979595 0.26988
+v -0.558854 -0.978234 0.289777
+v -0.566497 -0.976911 0.3097
+v -0.574204 -0.9756 0.329533
+v -0.582425 -0.975331 0.350099
+v -0.590081 -0.974072 0.369945
+v -0.59775 -0.972839 0.389739
+v -0.605983 -0.972633 0.410215
+v -0.614204 -0.972453 0.43069
+v -0.620781 -0.969255 0.448892
+v -0.628822 -0.967405 0.467826
+v -0.522283 -0.605463 0.403201
+v -0.526342 -0.597229 0.417819
+v -0.530376 -0.588931 0.43236
+v -0.533382 -0.578796 0.445501
+v -0.536388 -0.568494 0.458487
+v -0.539201 -0.557781 0.47123
+v -0.541127 -0.545591 0.482803
+v -0.542977 -0.533093 0.49421
+v -0.544814 -0.52062 0.505642
+v -0.546368 -0.507646 0.516908
+v -0.547717 -0.49421 0.527788
+v -0.5494 -0.481326 0.53877
+v 0.169513 -0.923975 0.159603
+v 0.230567 -0.977668 -0.232603
+v 0.350336 -0.972543 -0.141106
+v -0.294947 -0.980636 -0.333066
+v -0.305981 -0.984489 -0.307581
+v -0.314768 -0.98422 -0.285641
+v -0.323579 -0.983975 -0.26365
+v -0.332314 -0.983757 -0.241697
+v -0.341088 -0.983552 -0.21977
+v -0.349848 -0.983372 -0.197882
+v -0.358018 -0.982164 -0.176816
+v -0.367896 -0.984117 -0.153283
+v -0.376656 -0.983988 -0.131459
+v -0.38602 -0.984952 -0.108813
+v -0.394164 -0.983834 -0.087849
+v -0.402886 -0.983783 -0.0660505
+v -0.412212 -0.984798 -0.0434556
+v -0.420369 -0.983731 -0.022582
+v -0.429078 -0.983744 -0.000899171
+v -0.437723 -0.983783 0.0206039
+v -0.446971 -0.984888 0.0429932
+v -0.455038 -0.983873 0.0636228
+v -0.463683 -0.983924 0.0850616
+v -0.472868 -0.985042 0.107361
+v -0.481474 -0.985093 0.128838
+v -0.489913 -0.98481 0.149905
+v -0.498186 -0.984309 0.170765
+v -0.506432 -0.983821 0.191536
+v -0.514717 -0.983372 0.212358
+v -0.522951 -0.982948 0.233129
+v -0.530684 -0.981535 0.253078
+v -0.538918 -0.981162 0.27381
+v -0.54606 -0.978799 0.292963
+v -0.553767 -0.977463 0.312796
+v -0.561462 -0.976153 0.332655
+v -0.569708 -0.975883 0.353284
+v -0.577891 -0.975626 0.373875
+v -0.585559 -0.974393 0.393657
+v -0.593755 -0.974187 0.414171
+v -0.601976 -0.974008 0.434672
+v -0.609079 -0.971837 0.453606
+v -0.616234 -0.969666 0.472514
+v -0.5136 -0.597846 0.420979
+v -0.517672 -0.589548 0.435571
+v -0.521089 -0.580029 0.449174
+v -0.523632 -0.569034 0.461699
+v -0.526484 -0.558411 0.474467
+v -0.528899 -0.546978 0.486644
+v -0.530736 -0.53457 0.498076
+v -0.53238 -0.521519 0.509111
+v -0.533061 -0.507107 0.519438
+v -0.534641 -0.493837 0.529971
+v -0.283258 -0.983205 -0.328351
+v -0.292597 -0.98395 -0.3055
+v -0.301383 -0.98368 -0.283496
+v -0.310169 -0.983423 -0.261505
+v -0.318917 -0.983192 -0.239578
+v -0.32769 -0.982986 -0.217612
+v -0.336438 -0.982807 -0.195711
+v -0.345763 -0.98368 -0.173026
+v -0.354537 -0.983552 -0.151138
+v -0.363284 -0.983423 -0.129314
+v -0.371441 -0.98228 -0.108337
+v -0.381358 -0.984297 -0.0848175
+v -0.390067 -0.984245 -0.0630833
+v -0.398802 -0.984207 -0.0413233
+v -0.407511 -0.984194 -0.0196148
+v -0.415706 -0.983166 0.00129738
+v -0.424338 -0.983205 0.0228261
+v -0.434126 -0.98535 0.045999
+v -0.442206 -0.984348 0.0666414
+v -0.450838 -0.984387 0.0880931
+v -0.45947 -0.984451 0.109545
+v -0.468128 -0.984502 0.130984
+v -0.476644 -0.984387 0.152268
+v -0.485469 -0.984875 0.173861
+v -0.493677 -0.984387 0.194735
+v -0.501975 -0.983937 0.215506
+v -0.510723 -0.984515 0.237086
+v -0.518455 -0.983102 0.257009
+v -0.52561 -0.980726 0.2762
+v -0.533343 -0.979364 0.296097
+v -0.541038 -0.978028 0.316007
+v -0.548732 -0.976705 0.335879
+v -0.556914 -0.976422 0.35647
+v -0.565135 -0.976178 0.376997
+v -0.572804 -0.974932 0.39683
+v -0.580498 -0.973725 0.416599
+v -0.588706 -0.973545 0.437048
+v -0.596876 -0.973378 0.457537
+v -0.604519 -0.972235 0.47719
+v -0.611186 -0.969062 0.495379
+v -0.617249 -0.9649 0.512733
+v -0.500806 -0.59827 0.4241
+v -0.504891 -0.590074 0.438744
+v -0.507858 -0.579811 0.451808
+v -0.511288 -0.570074 0.46527
+v -0.513728 -0.558912 0.477652
+v -0.516195 -0.547698 0.489997
+v -0.51843 -0.535662 0.501455
+v -0.518815 -0.520684 0.51141
+v -0.519573 -0.506092 0.521365
+v -0.261049 -0.982986 -0.348275
+v -0.270413 -0.983706 -0.325359
+v -0.279816 -0.984451 -0.302481
+v -0.288589 -0.984168 -0.280477
+v -0.296771 -0.982884 -0.259398
+v -0.305506 -0.98264 -0.23742
+v -0.314305 -0.982434 -0.215467
+v -0.323053 -0.982241 -0.193553
+v -0.331788 -0.982074 -0.171665
+v -0.341152 -0.982974 -0.148954
+v -0.349912 -0.982858 -0.127156
+v -0.358609 -0.982755 -0.105319
+v -0.367382 -0.982678 -0.0835458
+v -0.37672 -0.983667 -0.0609252
+v -0.385404 -0.983629 -0.0391525
+v -0.394152 -0.983616 -0.0174054
+v -0.402873 -0.983629 0.00432887
+v -0.411506 -0.983654 0.0258319
+v -0.420202 -0.983706 0.0473092
+v -0.429939 -0.985851 0.0705078
+v -0.437479 -0.983796 0.0903024
+v -0.446663 -0.9849 0.112589
+v -0.454178 -0.982845 0.132319
+v -0.461628 -0.98079 0.15214
+v -0.471609 -0.983462 0.175467
+v -0.479393 -0.981984 0.195518
+v -0.488706 -0.983513 0.217895
+v -0.497505 -0.984078 0.239449
+v -0.505161 -0.982678 0.259372
+v -0.513407 -0.982293 0.280105
+v -0.520562 -0.979929 0.299244
+v -0.528321 -0.97858 0.319167
+v -0.536015 -0.977257 0.339039
+v -0.543658 -0.975973 0.358859
+v -0.551879 -0.975716 0.379424
+v -0.559573 -0.97447 0.399245
+v -0.568282 -0.975279 0.420504
+v -0.575925 -0.974085 0.44026
+v -0.583607 -0.972916 0.459952
+v -0.591275 -0.971772 0.479643
+v -0.598918 -0.970642 0.499258
+v -0.606073 -0.96851 0.518166
+v -0.611597 -0.963577 0.534608
+v -0.471647 -0.608263 0.416342
+v -0.488513 -0.599618 0.427864
+v -0.492097 -0.590447 0.441801
+v -0.495501 -0.580941 0.45543
+v -0.498481 -0.570562 0.468404
+v -0.50096 -0.559464 0.480812
+v -0.503388 -0.54807 0.493067
+v -0.505199 -0.535366 0.504178
+v -0.504942 -0.51913 0.513221
+v -0.57396 -0.96007 0.583408
+v -0.24828 -0.983487 -0.345269
+v -0.257002 -0.983166 -0.323213
+v -0.266392 -0.983898 -0.300374
+v -0.275166 -0.983629 -0.278383
+v -0.283374 -0.982331 -0.257266
+v -0.292147 -0.982087 -0.235287
+v -0.301473 -0.982922 -0.212513
+v -0.309694 -0.981689 -0.191421
+v -0.318403 -0.981509 -0.169532
+v -0.327189 -0.981368 -0.147695
+v -0.335937 -0.981239 -0.12582
+v -0.345237 -0.982177 -0.103186
+v -0.35401 -0.9821 -0.081375
+v -0.363297 -0.983089 -0.0587544
+v -0.372032 -0.983051 -0.0369559
+v -0.381345 -0.984078 -0.0143739
+v -0.389476 -0.983038 0.00648688
+v -0.398159 -0.983076 0.0280027
+v -0.407395 -0.984168 0.050315
+v -0.416567 -0.98526 0.0726915
+v -0.424685 -0.984258 0.0933082
+v -0.433265 -0.984284 0.114773
+v -0.439072 -0.979056 0.132037
+v -0.443131 -0.970706 0.146783
+v -0.484236 -0.983654 0.241787
+v -0.492469 -0.98323 0.262571
+v -0.50069 -0.982845 0.283265
+v -0.507845 -0.980482 0.302391
+v -0.515565 -0.979146 0.322327
+v -0.523247 -0.977823 0.342186
+v -0.530389 -0.975523 0.361261
+v -0.539162 -0.976268 0.382623
+v -0.546844 -0.975022 0.402366
+v -0.555 -0.974804 0.422919
+v -0.562695 -0.973609 0.442636
+v -0.570877 -0.973455 0.463099
+v -0.579047 -0.973314 0.483574
+v -0.586703 -0.972196 0.503189
+v -0.593857 -0.970064 0.522071
+v -0.600473 -0.967174 0.540055
+v -0.604866 -0.960225 0.554955
+v -0.478905 -0.590344 0.444447
+v -0.482257 -0.580864 0.45814
+v -0.485739 -0.571218 0.471666
+v -0.488218 -0.559952 0.483998
+v -0.490594 -0.548404 0.49606
+v -0.491378 -0.533825 0.505938
+v -0.490992 -0.517396 0.514788
+v -0.234844 -0.982948 -0.343162
+v -0.244748 -0.984695 -0.31936
+v -0.253598 -0.984399 -0.297369
+v -0.262372 -0.984117 -0.27539
+v -0.270567 -0.982819 -0.254234
+v -0.278775 -0.981535 -0.233168
+v -0.28751 -0.981317 -0.211202
+v -0.295705 -0.980071 -0.190123
+v -0.304479 -0.979891 -0.168222
+v -0.313766 -0.980777 -0.145524
+v -0.322539 -0.980661 -0.123687
+v -0.331287 -0.980546 -0.101838
+v -0.340599 -0.981509 -0.0791656
+v -0.349887 -0.982498 -0.0565707
+v -0.358634 -0.98246 -0.0347851
+v -0.367395 -0.982447 -0.013038
+v -0.376117 -0.982447 0.00864489
+v -0.3848 -0.982485 0.0301864
+v -0.394588 -0.984631 0.0533594
+v -0.402617 -0.983629 0.0740018
+v -0.411814 -0.984695 0.0963526
+v -0.418185 -0.980494 0.114464
+v -0.423465 -0.974252 0.130894
+v -0.479149 -0.982819 0.264947
+v -0.486882 -0.981406 0.284896
+v -0.495128 -0.981047 0.305564
+v -0.502823 -0.979698 0.325461
+v -0.510491 -0.978375 0.34532
+v -0.517685 -0.976076 0.364434
+v -0.525867 -0.975806 0.385025
+v -0.533587 -0.97456 0.404768
+v -0.54123 -0.973327 0.42455
+v -0.549965 -0.974149 0.445847
+v -0.558135 -0.973995 0.466284
+v -0.566368 -0.973853 0.486721
+v -0.574011 -0.972723 0.506374
+v -0.581654 -0.971618 0.526066
+v -0.588783 -0.969769 0.544718
+v -0.593742 -0.963821 0.560415
+v -0.469476 -0.581031 0.461005
+v -0.472482 -0.570896 0.474261
+v -0.47536 -0.560248 0.487004
+v -0.477261 -0.547852 0.498475
+v -0.476901 -0.531461 0.507325
+v -0.477106 -0.515585 0.51624
+v -0.478365 -0.501647 0.526413
+v 0.697532 -0.93113 0.107104
+v 0.683248 -0.941175 0.137663
+v 0.669927 -0.949319 0.166398
+v -0.222012 -0.983449 -0.340182
+v -0.230836 -0.983115 -0.318101
+v -0.240175 -0.983847 -0.295211
+v -0.248961 -0.983564 -0.273271
+v -0.257156 -0.982254 -0.252076
+v -0.265377 -0.98097 -0.230971
+v -0.273534 -0.979698 -0.209892
+v -0.281177 -0.977412 -0.189687
+v -0.288769 -0.975112 -0.169481
+v -0.29699 -0.97393 -0.14844
+v -0.306906 -0.975896 -0.124895
+v -0.316181 -0.976808 -0.102197
+v -0.326084 -0.978837 -0.0787288
+v -0.335384 -0.979826 -0.0561083
+v -0.345288 -0.981882 -0.0326527
+v -0.354023 -0.981856 -0.0108928
+v -0.362706 -0.981856 0.0108543
+v -0.371981 -0.982948 0.0332179
+v -0.3806 -0.982986 0.0547081
+v -0.390375 -0.985132 0.077881
+v -0.398493 -0.984091 0.0985363
+v -0.402552 -0.975703 0.113283
+v -0.406059 -0.966262 0.127207
+v -0.473086 -0.979993 0.286514
+v -0.482373 -0.981612 0.308711
+v -0.489541 -0.979261 0.327825
+v -0.496683 -0.976911 0.346964
+v -0.504942 -0.976628 0.367581
+v -0.512585 -0.975343 0.387376
+v -0.520858 -0.975099 0.407979
+v -0.528475 -0.973879 0.42771
+v -0.536169 -0.972672 0.447466
+v -0.544891 -0.973519 0.468725
+v -0.553061 -0.973378 0.489175
+v -0.560729 -0.972248 0.508841
+v -0.568899 -0.972158 0.529213
+v -0.576002 -0.970308 0.547916
+v -0.581539 -0.965376 0.564371
+v 0.660036 -0.951194 0.189995
+v 0.653023 -0.948022 0.209173
+v -0.459547 -0.570819 0.476843
+v -0.461949 -0.559079 0.488609
+v -0.463272 -0.545604 0.499284
+v -0.461923 -0.527762 0.507659
+v -0.463195 -0.513863 0.517794
+v -0.464505 -0.500106 0.528263
+v 0.644892 -0.946942 0.230034
+v 0.6373 -0.944836 0.250034
+v 0.629182 -0.943783 0.270805
+v 0.622734 -0.939569 0.289109
+v -0.209205 -0.983937 -0.337202
+v -0.218595 -0.984656 -0.314273
+v -0.226777 -0.983308 -0.293104
+v -0.235563 -0.983012 -0.271074
+v -0.243772 -0.981702 -0.249957
+v -0.251363 -0.979364 -0.229712
+v -0.25848 -0.976011 -0.210303
+v -0.265506 -0.972672 -0.190958
+v -0.271402 -0.967251 -0.173296
+v -0.277902 -0.962896 -0.154786
+v -0.287214 -0.96377 -0.132063
+v -0.295988 -0.963667 -0.1102
+v -0.309835 -0.972967 -0.0807712
+v -0.331312 -0.980238 -0.0313168
+v -0.341165 -0.982318 -0.00789986
+v -0.349887 -0.982318 0.0138087
+v -0.358544 -0.982357 0.0353374
+v -0.36832 -0.984502 0.0585617
+v -0.37699 -0.984541 0.0800519
+v -0.383965 -0.981381 0.0990372
+v -0.386354 -0.969846 0.111292
+v -0.469656 -0.982164 0.311897
+v -0.476798 -0.979814 0.330998
+v -0.483414 -0.976474 0.349328
+v -0.491647 -0.976166 0.369996
+v -0.499342 -0.974894 0.389765
+v -0.507537 -0.974637 0.410394
+v -0.515231 -0.973404 0.430112
+v -0.523414 -0.973211 0.450677
+v -0.531596 -0.973044 0.471114
+v -0.539792 -0.97289 0.491577
+v -0.548025 -0.972774 0.512039
+v -0.555617 -0.97167 0.531641
+v -0.563825 -0.97185 0.55186
+v -0.569862 -0.967945 0.569085
+v 0.616362 -0.935343 0.307375
+v 0.610492 -0.930064 0.324819
+v 0.605945 -0.923192 0.34085
+v -0.446111 -0.570087 0.478988
+v -0.447498 -0.556638 0.48974
+v -0.447665 -0.5408 0.49859
+v -0.447421 -0.524461 0.507672
+v -0.448307 -0.510395 0.518411
+v -0.450131 -0.497717 0.52956
+v 0.60186 -0.914701 0.355802
+v 0.596516 -0.908175 0.372282
+v 0.591455 -0.900198 0.387722
+v -0.195782 -0.98341 -0.335082
+v -0.205159 -0.984104 -0.312154
+v -0.213945 -0.983796 -0.29015
+v -0.222731 -0.9835 -0.268107
+v -0.230348 -0.981137 -0.247824
+v -0.236861 -0.976731 -0.229301
+v -0.24223 -0.970231 -0.21241
+v -0.247522 -0.963718 -0.195595
+v -0.251749 -0.955163 -0.180438
+v -0.257067 -0.948715 -0.163636
+v -0.261845 -0.941201 -0.147644
+v -0.270605 -0.941059 -0.125768
+v -0.279366 -0.940944 -0.103944
+v -0.327806 -0.98174 -0.00570331
+v -0.336553 -0.981728 0.0160309
+v -0.345725 -0.982819 0.0383689
+v -0.355513 -0.984965 0.0615547
+v -0.363631 -0.983937 0.0822613
+v -0.371158 -0.981856 0.102043
+v -0.372404 -0.968201 0.11264
+v -0.463555 -0.979364 0.333361
+v -0.470671 -0.977026 0.352514
+v -0.478417 -0.975716 0.372359
+v -0.486072 -0.974431 0.392193
+v -0.49378 -0.97316 0.412039
+v -0.502527 -0.973956 0.433336
+v -0.510196 -0.972736 0.453066
+v -0.518327 -0.972569 0.47358
+v -0.526548 -0.972415 0.494004
+v -0.534743 -0.972299 0.514441
+v -0.542887 -0.972196 0.534814
+v -0.55053 -0.971361 0.554287
+v -0.557634 -0.969512 0.573003
+v -0.562142 -0.962562 0.587878
+v -0.43455 -0.540504 0.501583
+v -0.433792 -0.523189 0.509984
+v -0.434293 -0.508057 0.519066
+v -0.435912 -0.495906 0.530639
+v -0.183013 -0.983911 -0.332115
+v -0.1918 -0.983577 -0.31006
+v -0.200547 -0.983256 -0.287966
+v -0.209333 -0.982961 -0.265988
+v -0.215807 -0.978503 -0.2474
+v -0.221164 -0.971978 -0.230535
+v -0.225968 -0.964451 -0.214542
+v -0.229 -0.953789 -0.201106
+v -0.232057 -0.943102 -0.187631
+v -0.236257 -0.934547 -0.172474
+v -0.241588 -0.928086 -0.155634
+v -0.247458 -0.922691 -0.137984
+v -0.256822 -0.923577 -0.115287
+v -0.264979 -0.922395 -0.0942331
+v -0.323156 -0.981137 0.0181504
+v -0.332918 -0.983282 0.0413875
+v -0.342141 -0.984374 0.0637127
+v -0.350812 -0.984399 0.0852799
+v -0.357144 -0.980225 0.103392
+v -0.358968 -0.967611 0.114837
+v -0.457954 -0.977579 0.355661
+v -0.464595 -0.974252 0.374029
+v -0.472842 -0.973969 0.394633
+v -0.48105 -0.973712 0.415199
+v -0.488693 -0.972479 0.434993
+v -0.496901 -0.972273 0.455443
+v -0.505084 -0.972094 0.475957
+v -0.513805 -0.972954 0.49719
+v -0.521988 -0.972839 0.517614
+v -0.529644 -0.971708 0.537255
+v -0.537813 -0.971888 0.557473
+v -0.544955 -0.970038 0.576189
+v -0.549952 -0.964104 0.591847
+v -0.423362 -0.544242 0.507158
+v -0.422874 -0.527197 0.515084
+v -0.421679 -0.508712 0.522585
+v -0.422758 -0.495006 0.532887
+v -0.178967 -0.984065 -0.307028
+v -0.187779 -0.983757 -0.285024
+v -0.195923 -0.982408 -0.263868
+v -0.201845 -0.976898 -0.246116
+v -0.205518 -0.967277 -0.231819
+v -0.209128 -0.957643 -0.217509
+v -0.211633 -0.945889 -0.204857
+v -0.214651 -0.935228 -0.191433
+v -0.218287 -0.925632 -0.177137
+v -0.225326 -0.922292 -0.15774
+v -0.234086 -0.922113 -0.135839
+v -0.242885 -0.921958 -0.113912
+v -0.25162 -0.921817 -0.0921136
+v -0.310875 -0.982652 0.0220297
+v -0.320111 -0.983744 0.0443933
+v -0.328795 -0.983783 0.0659221
+v -0.33744 -0.983809 0.0874636
+v -0.344337 -0.9807 0.106385
+v -0.345596 -0.96702 0.117021
+v -0.445237 -0.978144 0.358821
+v -0.451339 -0.973789 0.376406
+v -0.459573 -0.973507 0.396984
+v -0.467768 -0.97325 0.417601
+v -0.475989 -0.973018 0.43814
+v -0.483632 -0.971798 0.457883
+v -0.49238 -0.972633 0.47913
+v -0.50105 -0.973481 0.500363
+v -0.509245 -0.973365 0.520813
+v -0.516901 -0.972248 0.54044
+v -0.525045 -0.972428 0.560646
+v -0.5322 -0.970565 0.579361
+v -0.537672 -0.965645 0.595803
+v 0.357401 -0.976063 -0.160643
+v -0.412084 -0.531795 0.52098
+v -0.410491 -0.512206 0.527865
+v 0.370876 -0.975472 -0.158627
+v -0.165557 -0.983526 -0.304909
+v -0.174317 -0.983205 -0.282892
+v -0.182577 -0.981856 -0.261723
+v -0.187304 -0.97429 -0.245705
+v -0.190374 -0.96359 -0.23223
+v -0.192301 -0.950835 -0.220464
+v -0.194767 -0.939081 -0.20785
+v -0.196706 -0.926326 -0.196058
+v -0.202615 -0.920879 -0.178357
+v -0.211414 -0.920674 -0.15643
+v -0.220162 -0.920494 -0.134516
+v -0.229475 -0.92138 -0.111793
+v -0.238826 -0.92228 -0.0891078
+v -0.248152 -0.923217 -0.0663973
+v -0.306714 -0.983153 0.0465642
+v -0.315975 -0.984245 0.0689279
+v -0.324042 -0.98323 0.0896345
+v -0.330991 -0.980083 0.108594
+v -0.333393 -0.96851 0.120874
+v -0.438635 -0.974342 0.379553
+v -0.446265 -0.973057 0.399399
+v -0.455013 -0.973789 0.420748
+v -0.462668 -0.972543 0.440517
+v -0.470876 -0.972338 0.461043
+v -0.479085 -0.972158 0.481545
+v -0.487318 -0.972004 0.50202
+v -0.49545 -0.971862 0.522482
+v -0.503683 -0.97176 0.542868
+v -0.511814 -0.971939 0.563099
+v -0.51947 -0.971105 0.582534
+v -0.524454 -0.96517 0.598218
+v -0.399688 -0.516664 0.533619
+v -0.0529804 -0.958606 0.69443
+v -0.15275 -0.984027 -0.301942
+v -0.161498 -0.983693 -0.279873
+v -0.16914 -0.981317 -0.259616
+v -0.173392 -0.972659 -0.244382
+v -0.175833 -0.96097 -0.231806
+v -0.177785 -0.948176 -0.220027
+v -0.178556 -0.933288 -0.209905
+v -0.181575 -0.922626 -0.19643
+v -0.1881 -0.918233 -0.177882
+v -0.197426 -0.919068 -0.155094
+v -0.206199 -0.918876 -0.13318
+v -0.215499 -0.919762 -0.110482
+v -0.224838 -0.920661 -0.0877334
+v -0.234151 -0.921586 -0.0650871
+v -0.293881 -0.983616 0.0496085
+v -0.30259 -0.983654 0.0711244
+v -0.311248 -0.983693 0.0926146
+v -0.318172 -0.980546 0.111626
+v -0.320561 -0.968998 0.123893
+v -0.425841 -0.974907 0.3827
+v -0.433535 -0.973596 0.402546
+v -0.441242 -0.972325 0.422392
+v -0.449451 -0.972081 0.442944
+v -0.457633 -0.971862 0.463497
+v -0.465828 -0.971683 0.483972
+v -0.474563 -0.97253 0.505218
+v -0.482758 -0.972402 0.525655
+v -0.490401 -0.971271 0.545296
+v -0.498571 -0.971438 0.565578
+v -0.506163 -0.970616 0.584975
+v -0.511172 -0.964669 0.600659
+v -0.139378 -0.983487 -0.299822
+v -0.148151 -0.983153 -0.277792
+v -0.155216 -0.979711 -0.258306
+v -0.159378 -0.971079 -0.243123
+v -0.161331 -0.958323 -0.23137
+v -0.162088 -0.943436 -0.221273
+v -0.163424 -0.929614 -0.210316
+v -0.167072 -0.91998 -0.195968
+v -0.175268 -0.918709 -0.174889
+v -0.184028 -0.91849 -0.152987
+v -0.193354 -0.919351 -0.130187
+v -0.202731 -0.920224 -0.107451
+v -0.212044 -0.921123 -0.0847404
+v -0.220791 -0.921008 -0.062942
+v -0.230079 -0.921946 -0.04027
+v -0.289193 -0.983063 0.0732824
+v -0.297863 -0.983102 0.0948111
+v -0.305352 -0.981034 0.114619
+v -0.308306 -0.970539 0.127734
+v -0.413651 -0.976461 0.386643
+v -0.419752 -0.972132 0.40419
+v -0.428526 -0.972864 0.42559
+v -0.436181 -0.971618 0.445372
+v -0.444916 -0.972402 0.46667
+v -0.452058 -0.970192 0.485616
+v -0.46132 -0.972055 0.507659
+v -0.469464 -0.971914 0.528109
+v -0.477685 -0.971798 0.548533
+v -0.485289 -0.970963 0.567968
+v -0.492919 -0.970115 0.587441
+v -0.497402 -0.96314 0.60238
+v 0.377594 -0.973018 -0.209224
+v 0.368384 -0.972954 -0.186218
+v -0.126507 -0.983975 -0.296829
+v -0.13528 -0.983642 -0.274787
+v -0.141793 -0.979171 -0.256174
+v -0.145454 -0.969512 -0.241864
+v -0.146764 -0.955664 -0.23092
+v -0.148164 -0.941843 -0.219989
+v -0.148331 -0.92594 -0.21074
+v -0.153097 -0.918387 -0.194658
+v -0.161909 -0.918143 -0.172769
+v -0.170682 -0.917925 -0.150829
+v -0.180598 -0.919826 -0.127207
+v -0.189886 -0.9207 -0.104484
+v -0.198659 -0.920545 -0.0825696
+v -0.207959 -0.92147 -0.0598976
+v -0.216707 -0.921368 -0.0380863
+v -0.275795 -0.982473 0.075479
+v -0.284478 -0.982511 0.0970077
+v -0.293098 -0.982537 0.118498
+v -0.296078 -0.972042 0.131587
+v -0.400407 -0.975999 0.389046
+v -0.40701 -0.972684 0.407363
+v -0.415205 -0.972402 0.42798
+v -0.422899 -0.971143 0.447749
+v -0.431133 -0.970925 0.46834
+v -0.439316 -0.970732 0.488853
+v -0.447498 -0.970565 0.509329
+v -0.45622 -0.971426 0.530485
+v -0.464402 -0.971323 0.550935
+v -0.472572 -0.971477 0.571192
+v -0.479149 -0.9686 0.589124
+v -0.484146 -0.962627 0.604834
+v -0.113122 -0.983436 -0.294748
+v -0.121895 -0.983102 -0.272641
+v -0.128986 -0.979659 -0.253194
+v -0.132043 -0.968921 -0.239693
+v -0.132801 -0.954084 -0.229635
+v -0.133623 -0.939197 -0.219539
+v -0.134343 -0.924335 -0.209443
+v -0.139699 -0.917822 -0.192525
+v -0.148498 -0.917578 -0.170611
+v -0.157837 -0.9184 -0.147798
+v -0.167727 -0.920301 -0.124188
+v -0.177066 -0.921175 -0.101426
+v -0.185852 -0.921021 -0.0796023
+v -0.194587 -0.920892 -0.0577396
+v -0.203887 -0.92183 -0.035042
+v -0.2132 -0.922793 -0.0124214
+v -0.271633 -0.982974 0.100026
+v -0.280304 -0.982999 0.121542
+v -0.284388 -0.974598 0.136314
+v -0.285609 -0.960957 0.146937
+v -0.387125 -0.975549 0.391448
+v -0.393766 -0.972222 0.409778
+v -0.401974 -0.971939 0.430395
+v -0.409643 -0.970681 0.450189
+v -0.418403 -0.971464 0.471512
+v -0.426573 -0.971271 0.492026
+v -0.434756 -0.971092 0.512463
+v -0.442977 -0.97095 0.532913
+v -0.451698 -0.97185 0.554108
+v -0.45929 -0.970989 0.57362
+v -0.46534 -0.967097 0.590781
+v -0.0997502 -0.982896 -0.292603
+v -0.108523 -0.982563 -0.270535
+v -0.115614 -0.979107 -0.251061
+v -0.118068 -0.967354 -0.238434
+v -0.119442 -0.953545 -0.227516
+v -0.119044 -0.936551 -0.219089
+v -0.120405 -0.922729 -0.208107
+v -0.126931 -0.918297 -0.189545
+v -0.135666 -0.918053 -0.167605
+v -0.144991 -0.918876 -0.144831
+v -0.15433 -0.919723 -0.12203
+v -0.164234 -0.92165 -0.0984207
+v -0.173033 -0.921496 -0.0765965
+v -0.181767 -0.921355 -0.0547467
+v -0.19108 -0.922292 -0.0320747
+v -0.199815 -0.922202 -0.0102505
+v -0.258287 -0.982383 0.10221
+v -0.267484 -0.983475 0.124522
+v -0.272712 -0.977155 0.141029
+v -0.273984 -0.9635 0.151639
+v -0.374383 -0.976088 0.39462
+v -0.380458 -0.97176 0.412193
+v -0.388679 -0.97149 0.432758
+v -0.396939 -0.971233 0.453349
+v -0.405121 -0.971002 0.473914
+v -0.41333 -0.970796 0.494416
+v -0.421486 -0.970616 0.514942
+v -0.430221 -0.97149 0.536111
+v -0.437864 -0.970347 0.555803
+v -0.446586 -0.971516 0.576818
+v -0.452084 -0.96657 0.593273
+v -0.0869434 -0.983397 -0.28961
+v -0.095113 -0.98201 -0.268364
+v -0.101638 -0.977501 -0.249764
+v -0.104118 -0.965774 -0.23715
+v -0.104914 -0.950873 -0.227053
+v -0.105107 -0.934958 -0.217805
+v -0.107059 -0.922164 -0.205949
+v -0.113533 -0.917732 -0.187374
+v -0.122833 -0.918529 -0.164625
+v -0.131658 -0.91831 -0.142621
+v -0.141523 -0.920199 -0.119025
+v -0.151465 -0.922113 -0.0954663
+v -0.1602 -0.921958 -0.0735779
+v -0.168935 -0.92183 -0.051728
+v -0.177695 -0.921714 -0.0298525
+v -0.18643 -0.921624 -0.00807969
+v -0.244851 -0.981792 0.104355
+v -0.253547 -0.98183 0.125871
+v -0.261023 -0.979762 0.145679
+v -0.263412 -0.968227 0.157959
+v -0.355038 -0.980006 0.379424
+v -0.360574 -0.974637 0.396265
+v -0.367215 -0.971297 0.414608
+v -0.375988 -0.972029 0.435944
+v -0.38367 -0.970758 0.455764
+v -0.392379 -0.971541 0.477062
+v -0.40006 -0.970321 0.496818
+v -0.408757 -0.971156 0.518115
+v -0.416952 -0.971002 0.538578
+v -0.425134 -0.970873 0.559002
+v -0.0735329 -0.982858 -0.287478
+v -0.0823319 -0.982498 -0.26541
+v -0.0882022 -0.976962 -0.247632
+v -0.0907456 -0.965209 -0.235018
+v -0.0909254 -0.949293 -0.225769
+v -0.0911438 -0.933365 -0.216495
+v -0.0936486 -0.921612 -0.203816
+v -0.100701 -0.91822 -0.184394
+v -0.109461 -0.917964 -0.162467
+v -0.118825 -0.918786 -0.139616
+v -0.128164 -0.919633 -0.116879
+v -0.138055 -0.921534 -0.0932697
+v -0.147355 -0.922434 -0.0705592
+v -0.156141 -0.922292 -0.0486965
+v -0.165467 -0.92323 -0.0259989
+v -0.174202 -0.923127 -0.00420041
+v -0.182307 -0.9221 0.0165191
+v -0.24074 -0.982293 0.128915
+v -0.249385 -0.982331 0.150367
+v -0.252905 -0.972851 0.164356
+v -0.255268 -0.961342 0.17661
+v -0.341768 -0.979557 0.381788
+v -0.347305 -0.974187 0.398615
+v -0.354472 -0.971862 0.417755
+v -0.362205 -0.970552 0.437614
+v -0.370914 -0.971297 0.458975
+v -0.379123 -0.971066 0.479502
+v -0.387292 -0.97086 0.500029
+v -0.395539 -0.970681 0.520504
+v -0.403734 -0.970514 0.540954
+v -0.411891 -0.970385 0.561417
+v -0.0601353 -0.982306 -0.285371
+v -0.0694866 -0.982999 -0.262429
+v -0.074856 -0.976422 -0.245525
+v -0.0772966 -0.964656 -0.232872
+v -0.0775278 -0.948754 -0.223637
+v -0.0777462 -0.9328 -0.214362
+v -0.0808419 -0.9221 -0.200823
+v -0.0873159 -0.917655 -0.182223
+v -0.0960764 -0.917411 -0.160258
+v -0.106006 -0.919261 -0.136635
+v -0.115897 -0.921149 -0.113039
+v -0.124683 -0.920969 -0.0911117
+v -0.134009 -0.921856 -0.0683755
+v -0.143309 -0.922768 -0.0456907
+v -0.152095 -0.922639 -0.0238666
+v -0.16083 -0.922549 -0.00205525
+v -0.169513 -0.922562 0.0195634
+v -0.22733 -0.981702 0.131086
+v -0.236578 -0.982807 0.153386
+v -0.242346 -0.977579 0.170688
+v -0.244196 -0.964952 0.182146
+v -0.32742 -0.97709 0.382674
+v -0.333496 -0.972723 0.400272
+v -0.341768 -0.972402 0.420889
+v -0.349938 -0.972106 0.441519
+v -0.357131 -0.969833 0.46062
+v -0.36584 -0.970604 0.481904
+v -0.373548 -0.96937 0.501699
+v -0.382771 -0.97122 0.523677
+v -0.390465 -0.970038 0.543382
+v -0.398635 -0.969884 0.563857
+v -0.490684 -0.678797 0.237998
+f 1 2 3
+f 4 5 6
+f 7 8 9
+f 9 10 11
+f 12 13 14
+f 15 16 17
+f 18 19 20
+f 21 22 23
+f 24 25 26
+f 24 27 28
+f 26 29 30
+f 31 32 33
+f 34 35 32
+f 36 37 38
+f 38 39 40
+f 40 41 42
+f 43 44 45
+f 45 46 47
+f 48 49 33
+f 50 31 51
+f 52 53 54
+f 55 52 56
+f 57 58 27
+f 59 60 30
+f 21 61 62
+f 63 64 65
+f 17 66 67
+f 68 69 70
+f 71 72 73
+f 74 75 1
+f 1 3 76
+f 1 4 6
+f 71 9 11
+f 14 77 68
+f 16 18 17
+f 20 21 63
+f 23 24 61
+f 26 30 27
+f 24 26 27
+f 31 33 51
+f 31 34 32
+f 36 38 47
+f 32 36 47
+f 40 42 43
+f 32 47 48
+f 53 51 54
+f 30 57 27
+f 21 62 78
+f 18 63 65
+f 77 17 67
+f 12 68 70
+f 74 7 9
+f 1 6 7
+f 1 76 4
+f 71 73 9
+f 21 78 63
+f 29 79 30
+f 53 50 51
+f 32 48 33
+f 40 43 45
+f 52 80 56
+f 73 74 9
+f 74 1 7
+f 18 20 63
+f 24 28 61
+f 38 40 47
+f 40 45 47
+f 55 56 60
+f 12 70 71
+f 21 23 61
+f 52 54 80
+f 12 14 68
+f 18 65 17
+f 59 55 60
+f 77 67 68
+f 79 59 30
+f 77 15 17
+f 11 12 71
+f 81 82 83
+f 84 85 86
+f 85 87 88
+f 89 90 91
+f 90 92 93
+f 90 94 92
+f 95 96 97
+f 98 99 100
+f 101 102 103
+f 104 105 106
+f 106 105 107
+f 105 108 109
+f 110 111 112
+f 111 113 114
+f 113 115 116
+f 115 117 118
+f 81 84 82
+f 84 87 85
+f 87 90 89
+f 90 119 94
+f 119 96 95
+f 96 101 98
+f 98 101 99
+f 120 105 104
+f 105 110 108
+f 110 113 111
+f 120 115 113
+f 81 96 87
+f 81 87 84
+f 90 96 119
+f 96 102 101
+f 120 113 110
+f 120 110 105
+f 81 102 96
+f 87 96 90
+f 120 117 115
+f 117 102 81
+f 102 117 120
+f 121 122 123
+f 124 125 126
+f 124 127 125
+f 128 129 130
+f 129 131 132
+f 133 134 135
+f 136 137 138
+f 139 140 141
+f 140 142 143
+f 133 140 136
+f 144 145 146
+f 145 147 148
+f 149 150 151
+f 149 152 150
+f 153 122 121
+f 124 154 127
+f 154 129 128
+f 129 133 131
+f 133 136 134
+f 136 140 137
+f 155 140 139
+f 133 142 140
+f 156 144 157
+f 145 149 147
+f 152 158 159
+f 153 124 122
+f 124 129 154
+f 133 149 145
+f 137 140 155
+f 133 145 142
+f 149 158 152
+f 158 129 153
+f 153 129 124
+f 142 145 156
+f 156 145 144
+f 158 133 129
+f 133 158 149
+f 160 161 162
+f 163 164 165
+f 165 166 167
+f 167 168 169
+f 170 171 172
+f 172 173 174
+f 174 175 176
+f 176 177 178
+f 179 180 181
+f 182 183 184
+f 182 184 180
+f 185 186 187
+f 187 188 189
+f 189 190 191
+f 192 193 194
+f 194 195 196
+f 196 197 198
+f 198 199 160
+f 162 163 165
+f 169 170 172
+f 176 178 187
+f 200 179 181
+f 179 182 180
+f 178 201 185
+f 191 192 194
+f 169 194 196
+f 160 162 165
+f 174 189 191
+f 176 187 189
+f 200 181 185
+f 196 198 167
+f 198 160 165
+f 174 176 189
+f 201 200 185
+f 169 191 194
+f 198 165 167
+f 172 174 191
+f 178 185 187
+f 169 172 191
+f 167 169 196
+f 202 203 204
+f 205 206 207
+f 208 209 210
+f 211 208 210
+f 212 213 214
+f 215 216 217
+f 218 219 220
+f 221 222 223
+f 224 225 226
+f 227 228 229
+f 230 231 232
+f 233 230 232
+f 234 235 236
+f 237 238 236
+f 239 240 235
+f 241 242 243
+f 234 239 235
+f 244 245 246
+f 247 241 243
+f 248 249 247
+f 250 244 246
+f 239 251 252
+f 249 248 253
+f 240 239 252
+f 251 254 255
+f 252 251 255
+f 254 256 257
+f 255 254 257
+f 256 258 259
+f 257 256 259
+f 258 260 261
+f 259 258 261
+f 260 262 263
+f 264 265 266
+f 261 260 263
+f 244 250 243
+f 267 268 269
+f 270 271 272
+f 242 244 243
+f 273 274 275
+f 276 277 272
+f 278 279 280
+f 271 281 272
+f 282 249 253
+f 283 284 285
+f 268 282 253
+f 249 241 247
+f 268 286 269
+f 286 268 253
+f 262 287 288
+f 289 290 291
+f 263 262 288
+f 287 292 293
+f 288 287 293
+f 292 294 295
+f 293 292 295
+f 294 296 297
+f 295 294 297
+f 296 298 299
+f 297 296 299
+f 298 300 301
+f 299 298 301
+f 300 302 303
+f 301 300 303
+f 304 305 306
+f 307 308 309
+f 310 311 312
+f 313 314 281
+f 315 316 317
+f 318 319 320
+f 321 322 323
+f 324 325 326
+f 327 328 329
+f 330 331 332
+f 333 334 335
+f 336 337 338
+f 339 340 341
+f 342 343 344
+f 345 346 347
+f 348 349 350
+f 351 289 291
+f 352 310 353
+f 302 354 355
+f 356 357 358
+f 303 302 355
+f 354 359 360
+f 355 354 360
+f 359 361 362
+f 360 359 362
+f 361 363 364
+f 362 361 364
+f 365 366 367
+f 368 369 370
+f 371 372 373
+f 374 267 265
+f 375 376 377
+f 267 269 265
+f 363 378 379
+f 380 381 382
+f 364 363 379
+f 383 384 385
+f 379 378 386
+f 387 388 389
+f 390 391 392
+f 393 394 395
+f 396 397 398
+f 399 400 401
+f 402 403 404
+f 405 406 407
+f 408 409 410
+f 411 304 306
+f 412 413 414
+f 415 416 417
+f 418 419 420
+f 421 422 423
+f 305 424 425
+f 426 427 428
+f 429 430 431
+f 432 433 434
+f 435 436 434
+f 436 437 434
+f 438 439 440
+f 441 442 443
+f 444 438 445
+f 446 367 447
+f 448 449 450
+f 451 159 158
+f 225 224 452
+f 453 454 455
+f 456 457 458
+f 459 460 461
+f 310 312 353
+f 306 305 425
+f 462 463 464
+f 424 465 466
+f 467 468 469
+f 470 471 472
+f 473 474 475
+f 476 477 478
+f 479 480 481
+f 482 483 484
+f 485 482 484
+f 486 487 488
+f 489 490 491
+f 492 493 494
+f 495 496 497
+f 498 499 500
+f 501 498 500
+f 502 503 504
+f 505 506 507
+f 508 509 510
+f 481 511 512
+f 513 514 515
+f 516 508 510
+f 517 380 382
+f 518 519 520
+f 519 521 520
+f 381 522 523
+f 500 499 524
+f 525 526 527
+f 528 529 530
+f 531 532 533
+f 425 424 466
+f 375 534 376
+f 535 536 537
+f 538 539 540
+f 541 538 540
+f 542 543 544
+f 545 546 547
+f 465 548 549
+f 550 551 552
+f 422 553 554
+f 555 556 557
+f 558 559 560
+f 561 562 563
+f 564 565 210
+f 209 564 210
+f 566 567 568
+f 569 570 571
+f 572 573 574
+f 575 573 572
+f 576 227 229
+f 576 229 577
+f 578 579 231
+f 580 581 582
+f 583 584 585
+f 416 586 587
+f 588 415 417
+f 277 270 272
+f 466 465 549
+f 589 590 591
+f 592 593 594
+f 595 325 596
+f 597 598 325
+f 599 600 601
+f 548 602 603
+f 604 605 606
+f 607 608 609
+f 445 438 440
+f 610 604 606
+f 611 612 613
+f 614 615 616
+f 617 618 619
+f 620 621 622
+f 623 352 624
+f 625 626 627
+f 311 628 312
+f 271 313 281
+f 629 630 631
+f 352 353 624
+f 632 633 634
+f 469 629 631
+f 635 636 637
+f 468 629 469
+f 638 639 640
+f 641 642 643
+f 644 645 646
+f 647 648 649
+f 650 651 652
+f 653 654 655
+f 230 578 231
+f 549 548 603
+f 656 236 657
+f 658 659 660
+f 661 239 234
+f 662 661 234
+f 661 663 251
+f 239 661 251
+f 504 481 512
+f 664 665 666
+f 509 667 668
+f 510 509 668
+f 521 669 670
+f 429 671 430
+f 672 673 674
+f 520 521 670
+f 675 254 251
+f 663 675 251
+f 676 677 678
+f 679 680 681
+f 586 682 683
+f 684 685 581
+f 313 686 687
+f 314 313 687
+f 687 686 688
+f 686 502 688
+f 689 690 691
+f 502 504 692
+f 693 694 695
+f 696 697 698
+f 699 700 701
+f 702 703 704
+f 705 706 707
+f 343 708 709
+f 710 711 712
+f 551 713 552
+f 714 715 716
+f 700 717 701
+f 483 718 719
+f 720 721 722
+f 675 723 256
+f 484 483 719
+f 254 675 256
+f 724 258 256
+f 723 724 256
+f 724 725 260
+f 258 724 260
+f 726 727 728
+f 481 480 511
+f 729 730 521
+f 417 416 587
+f 731 732 733
+f 734 277 276
+f 591 735 736
+f 735 737 736
+f 738 739 740
+f 741 324 326
+f 742 743 744
+f 687 745 746
+f 747 599 748
+f 749 750 751
+f 752 753 615
+f 609 747 748
+f 754 755 756
+f 608 747 609
+f 605 757 758
+f 759 760 761
+f 762 763 764
+f 765 685 684
+f 602 766 767
+f 768 769 770
+f 771 772 773
+f 774 775 776
+f 603 602 767
+f 777 771 773
+f 553 778 554
+f 388 779 389
+f 780 781 782
+f 783 784 785
+f 786 787 788
+f 789 786 788
+f 790 791 792
+f 793 794 795
+f 796 797 767
+f 798 799 800
+f 511 498 501
+f 801 802 803
+f 804 805 496
+f 512 511 501
+f 806 807 808
+f 503 481 504
+f 809 810 811
+f 493 495 497
+f 667 812 813
+f 668 667 813
+f 814 815 816
+f 691 817 818
+f 819 820 821
+f 822 823 824
+f 825 826 827
+f 725 828 262
+f 260 725 262
+f 828 829 287
+f 262 828 287
+f 829 830 292
+f 831 379 832
+f 287 829 292
+f 587 586 683
+f 833 834 835
+f 836 837 838
+f 682 839 840
+f 202 625 203
+f 841 771 777
+f 842 843 844
+f 612 845 613
+f 846 847 848
+f 849 846 848
+f 850 814 851
+f 852 516 853
+f 854 696 698
+f 816 855 851
+f 856 857 858
+f 859 371 373
+f 860 861 814
+f 850 860 814
+f 790 792 861
+f 860 790 861
+f 862 863 864
+f 791 800 792
+f 865 664 666
+f 866 862 864
+f 867 868 869
+f 584 870 871
+f 830 872 294
+f 292 830 294
+f 872 873 296
+f 294 872 296
+f 873 874 298
+f 296 873 298
+f 379 386 832
+f 874 875 300
+f 519 729 521
+f 876 877 878
+f 879 342 344
+f 730 880 669
+f 881 882 883
+f 733 734 276
+f 884 885 886
+f 737 887 888
+f 889 890 891
+f 892 893 894
+f 314 687 746
+f 895 896 897
+f 749 898 750
+f 421 423 899
+f 900 749 751
+f 898 901 750
+f 898 902 903
+f 901 898 903
+f 904 905 906
+f 755 907 756
+f 908 765 684
+f 909 910 911
+f 912 913 914
+f 915 916 917
+f 469 631 918
+f 919 920 921
+f 467 469 922
+f 766 796 767
+f 923 924 925
+f 926 927 928
+f 929 930 931
+f 932 933 934
+f 935 936 937
+f 938 930 939
+f 799 940 941
+f 942 943 944
+f 945 946 947
+f 861 792 948
+f 791 798 800
+f 949 945 947
+f 798 945 949
+f 799 798 949
+f 508 516 947
+f 946 508 947
+f 812 950 951
+f 813 812 951
+f 950 862 866
+f 951 950 866
+f 952 953 954
+f 955 841 777
+f 956 957 739
+f 958 959 960
+f 961 962 963
+f 964 965 966
+f 298 874 300
+f 875 967 302
+f 300 875 302
+f 968 360 969
+f 967 970 354
+f 683 682 840
+f 971 972 973
+f 974 273 275
+f 839 729 519
+f 428 592 594
+f 975 976 797
+f 796 975 797
+f 593 590 589
+f 977 978 979
+f 980 981 982
+f 983 977 979
+f 984 985 986
+f 510 668 987
+f 449 233 232
+f 988 947 852
+f 847 989 990
+f 991 949 988
+f 516 510 853
+f 940 799 991
+f 947 516 852
+f 800 799 941
+f 949 947 988
+f 992 780 993
+f 799 949 991
+f 863 415 588
+f 394 994 395
+f 995 996 997
+f 864 863 588
+f 998 355 968
+f 360 362 969
+f 302 967 354
+f 970 999 359
+f 354 970 359
+f 999 1000 361
+f 1001 303 998
+f 355 360 968
+f 311 1002 1003
+f 521 730 669
+f 1004 1005 1006
+f 1007 1008 1009
+f 1010 1011 1012
+f 882 895 897
+f 1013 1014 1015
+f 223 575 572
+f 1016 1017 1018
+f 1019 1020 1021
+f 1012 1022 1023
+f 1024 1025 527
+f 1026 1027 1028
+f 1029 1030 1031
+f 980 982 562
+f 409 1032 1033
+f 902 1034 1035
+f 903 902 1035
+f 1035 1034 1036
+f 1034 1037 1036
+f 1038 905 1039
+f 1037 1040 1041
+f 910 1038 911
+f 911 1038 1039
+f 1042 1043 1044
+f 1045 888 1046
+f 42 1047 1048
+f 1049 1050 1051
+f 1052 1053 1054
+f 1055 1056 1057
+f 763 1058 1059
+f 1060 1061 1062
+f 1063 1064 1065
+f 1066 365 1067
+f 1068 1069 1070
+f 1071 1066 1067
+f 800 941 1072
+f 1073 1068 1070
+f 814 861 815
+f 792 800 1072
+f 851 814 816
+f 792 1072 948
+f 1074 854 1075
+f 861 948 815
+f 1076 789 1077
+f 855 816 1078
+f 789 788 1077
+f 854 698 1075
+f 1079 992 993
+f 690 817 691
+f 1080 1081 1082
+f 821 820 1083
+f 1084 1085 1086
+f 1087 1088 1089
+f 359 999 361
+f 1000 1090 363
+f 361 1000 363
+f 1090 1091 378
+f 362 364 1092
+f 363 1090 378
+f 1093 1094 1095
+f 969 362 1092
+f 1096 1097 1098
+f 1099 1100 1101
+f 594 593 589
+f 732 734 733
+f 1102 1103 1104
+f 590 735 591
+f 594 589 1105
+f 1106 740 739
+f 428 594 1107
+f 1108 428 1107
+f 1109 1083 1110
+f 1111 426 1108
+f 324 597 325
+f 1112 1113 598
+f 1114 738 1115
+f 1116 1117 1118
+f 1119 956 738
+f 1119 1120 956
+f 1114 1119 738
+f 1120 1121 956
+f 1073 1070 1121
+f 1120 1073 1121
+f 1122 1123 1124
+f 1125 732 731
+f 285 284 339
+f 1124 1125 731
+f 840 839 519
+f 1126 1127 1128
+f 301 303 1001
+f 1129 301 1001
+f 1130 1131 1132
+f 1133 1134 1135
+f 1136 1137 1138
+f 1139 1140 1141
+f 299 301 1129
+f 1142 299 1129
+f 1143 1144 1145
+f 692 504 1146
+f 1147 1006 1148
+f 340 1149 341
+f 1150 1151 1152
+f 1020 1153 1021
+f 1154 1151 1150
+f 1018 1154 1150
+f 1155 1156 1157
+f 1151 1158 1152
+f 1159 971 1160
+f 1161 1162 1163
+f 1164 1165 1166
+f 1167 1168 1169
+f 1170 1171 1172
+f 1173 1174 1143
+f 1101 1175 1176
+f 1177 980 562
+f 1178 1179 1180
+f 1181 1182 980
+f 1041 1040 1183
+f 1184 1122 1185
+f 1036 1037 1041
+f 1186 1187 1188
+f 1189 910 909
+f 1040 1186 1183
+f 1190 736 1045
+f 1046 1189 909
+f 1191 591 1190
+f 888 1189 1046
+f 1105 589 1191
+f 736 888 1045
+f 1107 594 1105
+f 591 736 1190
+f 1192 958 1193
+f 589 591 1191
+f 1194 1195 1196
+f 1197 958 1192
+f 1194 1196 1069
+f 1195 1198 1197
+f 1068 1194 1069
+f 1195 1199 1196
+f 1199 1195 1197
+f 1198 959 958
+f 1197 1198 958
+f 959 819 960
+f 960 819 821
+f 820 1200 1083
+f 1083 1200 1201
+f 1202 427 426
+f 1121 1203 957
+f 738 956 739
+f 1204 1205 1206
+f 1207 1208 1179
+f 1209 1210 1211
+f 297 299 1142
+f 613 845 1212
+f 364 379 831
+f 303 355 998
+f 1213 1214 1215
+f 1092 364 831
+f 1216 1217 1218
+f 1219 1220 1221
+f 736 737 888
+f 284 340 339
+f 983 979 1222
+f 887 1223 1189
+f 1224 1225 1226
+f 1227 983 1222
+f 1228 1229 1230
+f 1231 1224 1232
+f 1232 1224 1226
+f 1230 1231 1232
+f 1201 426 1111
+f 1110 1201 1111
+f 1233 821 1109
+f 426 428 1108
+f 1193 960 1233
+f 1083 1201 1110
+f 960 821 1233
+f 821 1083 1109
+f 614 752 615
+f 748 599 601
+f 1038 1234 905
+f 1235 1116 1236
+f 1123 1125 1124
+f 341 1149 974
+f 623 624 537
+f 335 402 404
+f 628 311 1003
+f 1237 342 879
+f 295 297 1238
+f 1239 295 1238
+f 1211 1210 1240
+f 1241 1242 1243
+f 1244 1245 472
+f 1242 1246 1243
+f 293 295 1239
+f 1247 293 1239
+f 1248 1249 1250
+f 996 1251 1252
+f 1158 1253 1254
+f 1255 1256 1257
+f 1152 1158 1254
+f 1253 1258 1259
+f 1260 1261 1262
+f 1263 1249 1248
+f 1262 1263 1248
+f 1249 1264 1250
+f 377 376 1265
+f 1266 1097 924
+f 1267 1268 1269
+f 1270 1271 1272
+f 867 1273 1274
+f 1275 1276 926
+f 1277 1278 1279
+f 1280 1281 1282
+f 1283 1284 1285
+f 1286 1287 531
+f 1288 1184 1185
+f 1221 1289 1290
+f 1291 1292 1288
+f 1122 1124 1293
+f 1294 1295 1296
+f 1297 1298 1299
+f 1183 1186 1188
+f 1300 1294 1296
+f 1187 1294 1300
+f 1188 1187 1300
+f 1295 1301 1302
+f 1296 1295 1302
+f 1301 1303 1304
+f 1302 1301 1304
+f 1303 1229 1228
+f 1304 1303 1228
+f 1305 1197 1192
+f 1229 1231 1230
+f 1199 1197 1305
+f 958 960 1193
+f 1196 1199 1306
+f 1306 1199 1305
+f 1196 1307 1308
+f 1307 1196 1306
+f 1069 1308 1309
+f 1069 1196 1308
+f 956 1121 957
+f 1070 1069 1309
+f 1310 492 753
+f 1070 1309 1203
+f 1311 1312 1313
+f 1314 1315 1316
+f 1317 1318 1319
+f 1320 1321 1322
+f 1323 1324 1325
+f 1326 288 1247
+f 1327 1328 1329
+f 504 512 1146
+f 1238 297 1142
+f 1330 1331 1332
+f 1333 283 285
+f 1334 1335 1336
+f 688 502 692
+f 888 887 1189
+f 1337 1338 1339
+f 1340 1341 1342
+f 1223 1343 910
+f 688 1344 745
+f 365 1345 1067
+f 1346 1048 1347
+f 687 688 745
+f 1348 1349 1350
+f 1351 1352 1144
+f 1353 1354 1355
+f 1356 1357 1358
+f 1359 1360 1361
+f 1362 1363 1364
+f 1225 1360 1359
+f 1365 1366 1367
+f 1226 1225 1359
+f 1360 1368 1361
+f 1369 1370 1371
+f 1128 1372 1373
+f 1374 804 495
+f 1375 1376 437
+f 1377 1378 1379
+f 1008 1007 1380
+f 518 520 1381
+f 1382 518 1381
+f 512 501 608
+f 536 623 537
+f 1383 263 1326
+f 288 293 1247
+f 1384 261 1383
+f 263 288 1326
+f 981 1385 982
+f 1386 1387 1388
+f 1329 1389 1390
+f 1391 1392 1393
+f 328 1394 1395
+f 259 261 1384
+f 1396 1147 1148
+f 1397 1398 1399
+f 1400 1017 1016
+f 1157 1400 1016
+f 1401 1402 1260
+f 1261 1263 1262
+f 1023 1029 1031
+f 1403 1404 1405
+f 1406 658 1407
+f 1408 1409 1410
+f 1411 1412 1413
+f 1414 1415 653
+f 1416 1417 1418
+f 1419 1182 1181
+f 1420 1421 1422
+f 1423 1424 1425
+f 1426 1427 1420
+f 1421 1423 1422
+f 1428 1429 1426
+f 1427 1421 1420
+f 803 1419 1181
+f 1430 1431 1428
+f 1432 1286 531
+f 918 1292 1291
+f 1433 918 1291
+f 922 918 1433
+f 1434 1435 535
+f 1292 1184 1288
+f 900 751 1436
+f 1437 1438 1439
+f 1440 1436 1441
+f 1435 536 535
+f 1442 1441 1443
+f 1442 1440 1441
+f 1444 1319 1445
+f 1446 1442 1443
+f 1438 1297 1439
+f 1447 1448 1449
+f 1280 1450 1451
+f 281 1452 1453
+f 1454 1280 1451
+f 742 744 1455
+f 272 281 1453
+f 314 746 1452
+f 752 1310 753
+f 281 314 1452
+f 1456 1457 1458
+f 1459 1438 1437
+f 1460 1461 1462
+f 1281 1463 1464
+f 1313 1314 1316
+f 1465 1466 1467
+f 1468 1469 1470
+f 1312 1314 1313
+f 1471 1472 1473
+f 1474 482 485
+f 1475 1474 485
+f 1182 981 980
+f 1476 255 1477
+f 257 259 1478
+f 1479 535 537
+f 403 1480 1481
+f 1482 1483 1484
+f 1485 1486 1487
+f 1189 1223 910
+f 1488 1489 923
+f 1490 1060 1491
+f 1343 1234 1038
+f 688 692 1492
+f 1061 1065 1062
+f 1493 276 1453
+f 1344 688 1492
+f 1423 1169 1424
+f 1494 1495 1496
+f 1497 1498 1499
+f 1500 326 1501
+f 1502 1497 1499
+f 1503 1504 1505
+f 1446 1443 1506
+f 1507 1508 1509
+f 1510 1511 1512
+f 1513 1446 1506
+f 1450 1280 1282
+f 1514 1459 1437
+f 1502 1499 1515
+f 326 325 595
+f 1516 1517 493
+f 1518 1519 1520
+f 1521 1522 1523
+f 1524 1525 1526
+f 1527 1528 1529
+f 1530 1527 1529
+f 1146 512 608
+f 409 1033 410
+f 1531 252 1476
+f 255 257 1477
+f 1532 1533 1534
+f 753 492 1535
+f 493 497 494
+f 1536 1537 1538
+f 252 255 1476
+f 1539 1024 527
+f 1478 259 1384
+f 261 263 1383
+f 1540 1541 1542
+f 501 500 747
+f 1543 1544 1545
+f 1546 1547 1548
+f 1549 1550 1551
+f 1552 1553 1554
+f 1555 1556 1557
+f 1558 1503 1559
+f 216 566 217
+f 1560 1561 1562
+f 1563 1564 1565
+f 1566 743 1514
+f 1567 1568 1563
+f 635 637 1569
+f 1568 1570 1571
+f 1572 1571 1570
+f 1570 1573 1572
+f 1572 1574 1575
+f 1576 1577 1578
+f 1579 1580 636
+f 1429 1427 1426
+f 1011 1022 1012
+f 1581 1582 1583
+f 1581 1584 1585
+f 1586 1587 1588
+f 1585 1588 1581
+f 1298 1286 1432
+f 1589 1590 1591
+f 1592 1593 1594
+f 1299 1298 1432
+f 1595 1592 1594
+f 1593 1596 1597
+f 1594 1593 1597
+f 1598 1599 1429
+f 1596 1598 1431
+f 1597 1596 1431
+f 1349 1600 1350
+f 1431 1598 1429
+f 1601 1602 1603
+f 1604 1605 1606
+f 1607 1490 1608
+f 442 441 1609
+f 1610 1611 1612
+f 338 1613 1222
+f 1143 1351 1144
+f 1614 1615 1616
+f 564 1617 1618
+f 1490 1491 1608
+f 1619 1620 1621
+f 1622 1623 1624
+f 1625 1626 1627
+f 1467 1625 1627
+f 1628 1312 1311
+f 1629 1628 1311
+f 1630 1494 1496
+f 1631 1632 1633
+f 758 757 1634
+f 1635 1636 1637
+f 757 1638 1634
+f 1639 1640 1641
+f 236 235 237
+f 1642 1643 1644
+f 500 524 599
+f 1477 257 1478
+f 520 670 1645
+f 747 500 599
+f 910 1343 1038
+f 1646 1647 1648
+f 712 1649 1650
+f 1234 1651 905
+f 1652 1653 1495
+f 1050 1610 1051
+f 1654 733 1493
+f 1655 1656 1657
+f 621 912 622
+f 1494 1652 1495
+f 1658 1659 1660
+f 1661 1557 1662
+f 1169 1416 1424
+f 1663 1664 1665
+f 1167 1169 1423
+f 1421 1167 1423
+f 1429 1599 1427
+f 1666 1167 1421
+f 1599 1666 1427
+f 1427 1666 1421
+f 406 1667 1372
+f 1668 1669 1670
+f 1671 1672 1673
+f 1674 1502 1515
+f 1374 1675 804
+f 1517 495 493
+f 1676 1677 1678
+f 1679 1680 1681
+f 1682 1683 1684
+f 1685 1682 1684
+f 1686 1687 1653
+f 617 619 787
+f 450 449 232
+f 235 1688 237
+f 1689 1690 1691
+f 1652 1686 1653
+f 1692 1693 1687
+f 1694 1695 1696
+f 1697 1698 1699
+f 1700 1701 237
+f 1702 1703 1704
+f 1705 1011 1010
+f 1706 1707 1708
+f 608 501 747
+f 1709 1710 1711
+f 1149 273 974
+f 1662 1556 610
+f 1712 1713 432
+f 1617 1714 1715
+f 1686 1692 1687
+f 1716 1717 1718
+f 1719 1447 1720
+f 1721 1722 1567
+f 1723 1724 1725
+f 1722 1726 1568
+f 1567 1722 1568
+f 1726 1727 1570
+f 1568 1726 1570
+f 1727 1728 1573
+f 1570 1727 1573
+f 1728 1729 1730
+f 1573 1728 1730
+f 1731 1732 1733
+f 1729 1734 1730
+f 1735 1585 1736
+f 1734 1735 1736
+f 1737 1588 1585
+f 1735 1737 1585
+f 1738 1589 1588
+f 1737 1738 1588
+f 1739 1740 1741
+f 1738 1590 1589
+f 1742 1743 1744
+f 1745 1746 1747
+f 1748 1749 1750
+f 1751 1752 1753
+f 1597 1431 1430
+f 1754 1755 1756
+f 1757 1758 1759
+f 1760 1761 1595
+f 1692 1762 1763
+f 531 1287 532
+f 1764 1765 1766
+f 1767 1768 1769
+f 1770 1771 1772
+f 1773 1774 1775
+f 1434 535 532
+f 1776 1777 1778
+f 1779 1557 1661
+f 1780 1028 1781
+f 1782 1779 1661
+f 1783 1784 1785
+f 1786 1787 1627
+f 1626 1786 1627
+f 1788 1628 1629
+f 1789 1788 1629
+f 1790 1791 1792
+f 1792 1793 1794
+f 422 554 423
+f 1795 1796 1797
+f 1798 1799 955
+f 1799 841 955
+f 240 1800 1688
+f 993 780 782
+f 1801 1802 1803
+f 235 240 1688
+f 1804 518 1382
+f 599 524 600
+f 436 1375 437
+f 1381 520 1645
+f 1805 1806 1807
+f 1808 1745 1809
+f 1693 1692 1763
+f 1810 1811 1812
+f 731 733 1654
+f 1055 1057 1144
+f 1813 1814 908
+f 276 272 1453
+f 1815 1816 1817
+f 1818 1814 1813
+f 1819 1820 1821
+f 1822 1820 1819
+f 1823 1824 1825
+f 1821 1823 1825
+f 1826 1597 1430
+f 1431 1429 1428
+f 1827 1828 1829
+f 1830 1827 1829
+f 1831 1032 1832
+f 1032 1026 1033
+f 1833 1834 1668
+f 1835 1369 1371
+f 1836 1446 1513
+f 1837 1838 1839
+f 1840 1841 754
+f 1675 1455 804
+f 1842 1843 1844
+f 1680 1845 1681
+f 1683 1527 1530
+f 1684 1683 1530
+f 1846 377 784
+f 1847 1848 1849
+f 1850 226 228
+f 1851 1852 1853
+f 1051 1610 1612
+f 1854 1855 1856
+f 1857 1858 1859
+f 570 1854 1856
+f 1860 1861 1862
+f 1863 1864 1865
+f 1866 1867 1868
+f 1869 1870 1871
+f 1835 1371 1872
+f 1873 1874 1875
+f 1876 1877 1878
+f 1879 1872 1376
+f 1880 1881 1882
+f 1762 1883 1884
+f 1885 1886 1887
+f 1888 1889 1890
+f 1891 1892 1893
+f 743 1566 744
+f 1894 1895 1896
+f 1897 1898 1899
+f 1695 1694 1726
+f 1722 1695 1726
+f 1694 1900 1727
+f 1726 1694 1727
+f 1900 1901 1728
+f 1727 1900 1728
+f 1901 1902 1729
+f 1728 1901 1729
+f 1903 1734 1729
+f 1902 1903 1729
+f 1904 1735 1734
+f 1903 1904 1734
+f 1905 1737 1735
+f 1904 1905 1735
+f 1906 1738 1737
+f 1905 1906 1737
+f 1907 1590 1738
+f 1906 1907 1738
+f 1908 1909 1590
+f 1907 1908 1590
+f 1910 1911 1909
+f 1908 1910 1909
+f 1912 1913 1911
+f 1910 1912 1911
+f 1914 1754 1915
+f 1912 1756 1913
+f 1916 1917 1918
+f 1756 1915 1754
+f 1919 1920 1760
+f 1921 1922 1923
+f 1924 1925 1919
+f 1761 1592 1595
+f 1825 1824 1924
+f 1920 1761 1760
+f 1926 1927 1928
+f 1925 1920 1919
+f 1929 1930 1931
+f 1932 1933 1934
+f 1935 1936 1787
+f 1786 1935 1787
+f 1937 1788 1789
+f 1938 1937 1789
+f 1939 1940 1794
+f 1941 1942 1943
+f 573 1944 574
+f 217 566 568
+f 213 1945 1946
+f 240 252 1531
+f 227 1850 228
+f 1947 1948 1614
+f 1800 240 1531
+f 1528 1949 1950
+f 1763 1762 1884
+f 433 435 434
+f 1951 1804 1382
+f 440 439 1952
+f 1030 1953 1954
+f 1340 1955 1956
+f 601 600 1957
+f 1124 731 1958
+f 1959 1960 1961
+f 1962 1818 1813
+f 743 1459 1514
+f 1963 1964 1965
+f 1966 1967 1968
+f 1969 1822 1970
+f 1971 1969 1970
+f 1970 1822 1819
+f 1820 1823 1821
+f 1344 1492 1972
+f 1883 1973 1974
+f 1975 1344 1972
+f 1884 1883 1974
+f 1830 1829 1976
+f 1977 1830 1976
+f 1071 1978 1066
+f 1979 1980 1981
+f 1982 1897 1899
+f 1983 1984 1985
+f 1986 1442 1446
+f 1836 1986 1446
+f 1987 1988 1989
+f 1841 755 754
+f 1990 1991 1992
+f 1993 1994 1995
+f 1996 1997 1998
+f 1999 1682 1685
+f 817 793 818
+f 357 2000 690
+f 1058 208 211
+f 2001 859 2002
+f 1448 576 577
+f 2003 2004 2005
+f 2006 2007 2008
+f 2009 2010 2011
+f 2012 2013 2014
+f 2015 2016 2017
+f 2018 2019 2020
+f 1867 1866 2021
+f 1352 1055 1144
+f 1375 1879 1376
+f 2022 1655 1657
+f 2023 2024 2025
+f 1439 1297 1299
+f 1060 1062 1491
+f 1814 765 908
+f 1958 731 1654
+f 1963 2026 2027
+f 2028 2029 2030
+f 2031 366 365
+f 1964 1963 2027
+f 1696 2032 1694
+f 1895 1695 1722
+f 2032 2033 1900
+f 1694 2032 1900
+f 2034 1901 1900
+f 2033 2034 1900
+f 2034 2035 1902
+f 1901 2034 1902
+f 2036 1903 1902
+f 2035 2036 1902
+f 2037 1904 1903
+f 2036 2037 1903
+f 2037 2038 1905
+f 1904 2037 1905
+f 2038 2039 1906
+f 1905 2038 1906
+f 2040 1907 1906
+f 2039 2040 1906
+f 2041 1908 1907
+f 2040 2041 1907
+f 2042 1910 1908
+f 2041 2042 1908
+f 2043 1912 1910
+f 2042 2043 1910
+f 2044 1756 1912
+f 2043 2044 1912
+f 2045 1915 1756
+f 2044 2045 1756
+f 2046 1921 1915
+f 2045 2046 1915
+f 2047 2048 2049
+f 2046 2050 1921
+f 745 1344 2051
+f 2052 2053 2054
+f 2055 2056 2057
+f 623 2058 352
+f 2059 2060 2061
+f 2062 2063 2064
+f 2065 2066 1936
+f 2067 2068 2069
+f 2070 2071 2072
+f 2073 2070 2072
+f 2074 1941 1943
+f 817 2075 793
+f 2076 2077 579
+f 578 2076 579
+f 2078 329 660
+f 1350 1600 658
+f 2079 661 662
+f 2080 2081 2082
+f 2079 2083 663
+f 661 2079 663
+f 2083 2084 675
+f 2085 2086 2087
+f 663 2083 675
+f 2084 2088 723
+f 675 2084 723
+f 2088 2089 724
+f 723 2088 724
+f 2090 531 533
+f 2075 2091 793
+f 2091 2092 794
+f 793 2091 794
+f 2089 2093 725
+f 1973 2094 2095
+f 724 2089 725
+f 540 539 1939
+f 1059 1058 211
+f 772 2096 2097
+f 304 2098 2099
+f 1529 1528 1950
+f 2100 783 785
+f 1952 1521 1523
+f 1949 1804 1951
+f 2101 444 2102
+f 2103 2104 2105
+f 1448 577 1449
+f 612 2106 845
+f 1287 2107 532
+f 2108 1349 1348
+f 1974 1973 2095
+f 1293 1124 1958
+f 2109 1965 1828
+f 2110 2111 2112
+f 2113 2114 2115
+f 2109 1963 1965
+f 2116 420 2117
+f 2118 2119 2120
+f 2121 2122 2123
+f 534 1831 1832
+f 2124 2125 2126
+f 2127 2128 2129
+f 2130 2131 2132
+f 2133 2134 2135
+f 1977 1976 2136
+f 2137 1977 2136
+f 460 2138 2139
+f 2140 2141 1555
+f 2142 1359 1168
+f 2143 2144 2145
+f 2146 1440 1442
+f 1986 2146 1442
+f 2147 2148 2149
+f 2150 1812 2151
+f 2152 2153 1576
+f 2094 2154 2155
+f 2156 2157 1996
+f 1997 1999 1998
+f 696 337 336
+f 2158 2159 860
+f 2160 204 2161
+f 1171 2160 2161
+f 2093 2162 828
+f 725 2093 828
+f 2057 2163 2164
+f 2165 2166 2167
+f 2168 2169 2170
+f 2171 2012 2014
+f 1715 1714 1049
+f 2172 2173 2174
+f 2175 2176 2177
+f 1056 1044 1057
+f 2178 2179 2180
+f 2181 2182 2183
+f 2184 2185 654
+f 733 276 1493
+f 2026 1969 1971
+f 1081 2186 2187
+f 2188 2189 2190
+f 2027 2026 1971
+f 2191 2192 2193
+f 1673 2194 2195
+f 2196 2197 2032
+f 1696 2196 2032
+f 2197 2198 2033
+f 2032 2197 2033
+f 2198 2199 2034
+f 2033 2198 2034
+f 2200 2035 2034
+f 2199 2200 2034
+f 2200 2201 2036
+f 2035 2200 2036
+f 2201 2202 2037
+f 2036 2201 2037
+f 2202 2203 2038
+f 2037 2202 2038
+f 2203 2204 2039
+f 2038 2203 2039
+f 2204 2205 2040
+f 2039 2204 2040
+f 2205 2206 2041
+f 2040 2205 2041
+f 2207 2042 2041
+f 2206 2207 2041
+f 2208 2043 2042
+f 2207 2208 2042
+f 2209 2044 2043
+f 2208 2209 2043
+f 2210 2045 2044
+f 2209 2210 2044
+f 2211 2046 2045
+f 2210 2211 2045
+f 2212 2050 2046
+f 2211 2212 2046
+f 2213 2214 2050
+f 2212 2213 2050
+f 2215 2216 2213
+f 2213 2216 2214
+f 2217 2218 2219
+f 2060 2220 2061
+f 2221 2073 2222
+f 2069 2221 2222
+f 2068 2223 2221
+f 2224 2070 2073
+f 2165 1941 2166
+f 2223 2224 2221
+f 2225 2226 2227
+f 2162 2228 829
+f 2229 2230 686
+f 828 2162 829
+f 2231 2232 2233
+f 313 2229 686
+f 2234 2235 372
+f 567 2236 2237
+f 2238 2239 2240
+f 2228 2241 830
+f 2242 2243 2244
+f 1378 1377 2245
+f 2095 2094 2155
+f 2071 1937 1938
+f 2065 2068 2067
+f 2221 2224 2073
+f 2072 2071 1938
+f 2246 2247 1631
+f 2065 2248 2068
+f 829 2228 830
+f 2154 2249 2250
+f 2241 2251 872
+f 830 2241 872
+f 2252 2253 2254
+f 495 804 496
+f 791 2255 798
+f 2159 790 860
+f 853 987 2256
+f 2257 853 2256
+f 2106 616 845
+f 1950 1949 1951
+f 2258 1045 2259
+f 990 644 646
+f 2260 2261 2111
+f 2102 444 445
+f 1228 1230 2262
+f 2263 2264 2265
+f 2266 2267 2268
+f 1185 1122 1293
+f 2234 2269 2235
+f 420 419 2117
+f 2270 2271 2272
+f 1827 2109 1828
+f 2273 1420 2274
+f 2275 488 2276
+f 2277 1324 2278
+f 2155 2154 2250
+f 2279 2280 352
+f 2281 2282 2283
+f 2284 2285 2286
+f 2287 2288 2289
+f 2290 2135 2291
+f 2292 2293 2170
+f 2294 2295 2296
+f 2137 2136 2297
+f 488 2298 2276
+f 2299 2300 2301
+f 1226 1359 2142
+f 2302 1226 2142
+f 2303 900 1440
+f 2146 2303 1440
+f 909 911 2304
+f 2305 909 2304
+f 2306 2307 2308
+f 2249 2309 2310
+f 987 2157 2156
+f 2256 987 2156
+f 2255 791 790
+f 2159 2255 790
+f 2311 2312 2313
+f 2314 2315 2316
+f 2317 2318 2319
+f 2007 2320 2321
+f 2322 2323 2324
+f 2325 2326 2327
+f 2328 2329 2330
+f 2331 2332 1881
+f 2333 2181 2183
+f 565 564 1618
+f 2334 2335 2336
+f 2337 2338 2339
+f 2340 2341 2342
+f 2343 2344 2182
+f 2345 2346 2347
+f 2348 2349 2350
+f 2346 2351 2352
+f 2353 2354 2355
+f 2356 2355 2357
+f 2358 2359 2360
+f 2361 2362 2196
+f 2363 2364 2365
+f 2366 2197 2196
+f 2362 2366 2196
+f 2366 2367 2198
+f 2197 2366 2198
+f 2368 2199 2198
+f 2367 2368 2198
+f 2369 2200 2199
+f 2368 2369 2199
+f 2369 2370 2201
+f 2200 2369 2201
+f 2370 2371 2202
+f 2201 2370 2202
+f 2371 2372 2203
+f 2202 2371 2203
+f 2372 2373 2204
+f 2203 2372 2204
+f 2373 2374 2205
+f 2204 2373 2205
+f 2374 2375 2206
+f 2205 2374 2206
+f 2375 2376 2207
+f 2206 2375 2207
+f 2376 2377 2208
+f 2207 2376 2208
+f 2377 2378 2209
+f 2208 2377 2209
+f 2378 2379 2210
+f 2209 2378 2210
+f 2380 2211 2210
+f 2379 2380 2210
+f 2381 2212 2211
+f 2380 2381 2211
+f 2382 2213 2212
+f 2381 2382 2212
+f 2215 2383 2384
+f 2382 2215 2213
+f 2385 2386 2387
+f 2388 2389 2390
+f 2073 2072 2391
+f 2222 2073 2391
+f 2392 2248 1935
+f 2248 2223 2068
+f 2393 2394 2395
+f 2250 2249 2310
+f 2396 2397 2398
+f 2399 2400 2401
+f 2251 2402 873
+f 872 2251 873
+f 2402 2403 874
+f 873 2402 874
+f 2403 2404 875
+f 874 2403 875
+f 2404 2405 967
+f 875 2404 967
+f 2405 2406 970
+f 967 2405 970
+f 2230 503 502
+f 1455 2407 805
+f 2408 2409 2410
+f 524 499 2411
+f 2412 2413 2414
+f 2413 2415 2414
+f 2392 1935 1786
+f 2416 2417 2418
+f 2066 2065 2067
+f 2419 2392 1786
+f 1935 2065 1936
+f 2068 2221 2069
+f 2420 2421 1625
+f 2419 1786 1626
+f 2422 2423 2424
+f 2425 2426 2427
+f 2406 2428 999
+f 970 2406 999
+f 2429 2430 2431
+f 2432 2429 2431
+f 2433 2434 798
+f 2434 945 798
+f 680 988 2435
+f 852 853 2257
+f 769 762 2436
+f 2437 2438 1009
+f 1190 1045 2258
+f 2439 1190 2258
+f 2440 2441 902
+f 2442 2108 1348
+f 2443 1302 2444
+f 1304 1228 2445
+f 2446 2294 2447
+f 1171 2161 1172
+f 2448 2449 2450
+f 2301 2300 2275
+f 2136 1976 2451
+f 2131 2450 2132
+f 1426 1420 2273
+f 2452 1426 2273
+f 2309 2453 2454
+f 2455 2456 2457
+f 2458 2459 2460
+f 2461 2462 2463
+f 2464 2465 2466
+f 2467 2468 2469
+f 2470 2471 2472
+f 849 1524 2473
+f 2295 2137 2297
+f 2474 2475 2476
+f 2477 2478 2479
+f 2480 2481 2482
+f 1359 1361 1168
+f 2269 2477 2479
+f 2483 749 900
+f 1232 1226 2302
+f 2484 2485 2486
+f 2303 2483 900
+f 1056 1042 1044
+f 1046 909 2305
+f 2157 1997 1996
+f 2487 2488 2489
+f 2255 2433 798
+f 2490 2491 2492
+f 2493 2494 2495
+f 2496 1698 1697
+f 2497 2498 2499
+f 2500 2501 2502
+f 2503 2504 2505
+f 2506 2507 2055
+f 2508 2311 2313
+f 2509 2510 2511
+f 2173 2512 2513
+f 2508 2313 2514
+f 2515 2508 2514
+f 2516 2517 2518
+f 2519 2340 2342
+f 2520 2521 2346
+f 2345 2520 2346
+f 2521 2522 2351
+f 2346 2521 2351
+f 2522 2523 2361
+f 2351 2522 2361
+f 2523 2524 2362
+f 2361 2523 2362
+f 2525 2366 2362
+f 2524 2525 2362
+f 2526 2367 2366
+f 2525 2526 2366
+f 2526 2527 2368
+f 2367 2526 2368
+f 2527 2528 2369
+f 2368 2527 2369
+f 2529 2530 2528
+f 2369 2528 2370
+f 2531 2370 2528
+f 2532 2533 2534
+f 2371 2535 2536
+f 2371 2536 2372
+f 2536 2537 2372
+f 2372 2537 2373
+f 2538 2539 2374
+f 2373 2538 2374
+f 2539 2540 2375
+f 2374 2539 2375
+f 2540 2541 2376
+f 2375 2540 2376
+f 2541 2542 2377
+f 2376 2541 2377
+f 2542 2543 2378
+f 2377 2542 2378
+f 2544 2379 2378
+f 2543 2544 2378
+f 2545 2380 2379
+f 2544 2545 2379
+f 2546 2381 2380
+f 2545 2546 2380
+f 2547 2382 2381
+f 2546 2547 2381
+f 2383 2547 2548
+f 2549 2547 2550
+f 2551 2552 1321
+f 1320 2551 1321
+f 2072 1938 2553
+f 1629 1311 2554
+f 2555 2556 2557
+f 2556 2558 1466
+f 2424 2425 2427
+f 2559 2560 2561
+f 2562 2563 2564
+f 2565 2503 2505
+f 2566 2567 2568
+f 2248 2065 1935
+f 2569 2555 1204
+f 2428 2570 1000
+f 2391 2072 2553
+f 2571 2229 313
+f 686 2230 502
+f 1957 2572 2573
+f 271 2571 313
+f 2574 2575 2576
+f 2577 2574 2576
+f 2578 2579 2580
+f 2581 2582 2583
+f 2584 2585 2586
+f 2587 2588 2589
+f 2590 2591 2592
+f 2593 2594 2595
+f 1789 1629 2596
+f 2597 2577 2576
+f 2421 2419 1626
+f 2598 2599 1317
+f 2600 2578 2601
+f 2579 2602 2580
+f 999 2428 1000
+f 2570 2603 1090
+f 2604 2429 2432
+f 1000 2570 1090
+f 2434 2605 946
+f 2430 1136 1138
+f 988 852 2435
+f 945 2434 946
+f 625 2606 203
+f 2435 852 2257
+f 2607 1191 2439
+f 1061 1063 1065
+f 898 2440 902
+f 1045 1046 2259
+f 1302 1304 2444
+f 2441 2608 1034
+f 2609 2447 2482
+f 2444 1304 2445
+f 2610 2611 2612
+f 2613 2295 2294
+f 1829 2282 2281
+f 328 327 2614
+f 2615 1428 2452
+f 1976 1829 2281
+f 2271 2616 2272
+f 1420 1422 2274
+f 2452 2273 2617
+f 2130 2132 2618
+f 2619 2620 2621
+f 2622 2452 2617
+f 2623 2120 2624
+f 2625 2623 2624
+f 849 848 1524
+f 2113 1265 2114
+f 1318 2243 2242
+f 2626 2627 2628
+f 2295 2297 2296
+f 2629 2630 2631
+f 2614 2632 2291
+f 2633 2634 2635
+f 2636 1232 2302
+f 2078 327 329
+f 2440 898 749
+f 2445 1228 2262
+f 2259 1046 2305
+f 2483 2440 749
+f 2637 2638 1378
+f 2639 2640 2641
+f 2642 2643 2644
+f 2645 2646 2647
+f 2648 2649 2650
+f 2651 2652 2653
+f 2654 2655 2505
+f 2504 2654 2505
+f 2654 2656 2657
+f 2658 2659 2660
+f 2012 2171 2661
+f 2662 2663 2664
+f 2665 2666 2667
+f 2668 2669 2670
+f 2671 2672 2673
+f 2674 2675 2676
+f 2677 2678 2521
+f 2520 2677 2521
+f 2678 2679 2522
+f 2521 2678 2522
+f 2680 2523 2522
+f 2679 2680 2522
+f 2680 2681 2524
+f 2523 2680 2524
+f 2682 2525 2524
+f 2681 2682 2524
+f 2682 2683 2526
+f 2525 2682 2526
+f 2683 2529 2527
+f 2526 2683 2527
+f 2530 2684 2685
+f 2527 2529 2528
+f 2686 2687 2688
+f 2686 2689 2687
+f 2690 2686 2688
+f 2689 2691 2687
+f 2692 2693 2691
+f 2689 2692 2691
+f 2694 2695 2696
+f 2697 2698 2696
+f 2538 2699 2539
+f 2537 2700 2538
+f 2701 2702 2703
+f 2539 2704 2540
+f 2705 1621 2541
+f 2540 2705 2541
+f 1621 2706 2542
+f 2541 1621 2542
+f 2706 2707 2543
+f 2542 2706 2543
+f 2707 2708 2544
+f 2543 2707 2544
+f 2708 2709 2545
+f 2544 2708 2545
+f 2709 2550 2546
+f 2545 2709 2546
+f 2710 2549 2711
+f 2546 2550 2547
+f 2712 2713 2714
+f 2715 2716 2717
+f 2552 2718 2719
+f 1321 2552 2719
+f 2596 1629 2554
+f 2720 2721 2722
+f 2723 2724 1027
+f 1026 2723 1027
+f 697 336 2725
+f 2478 1674 2726
+f 2727 2728 2520
+f 1861 2015 1862
+f 2460 2729 2730
+f 2556 2731 2557
+f 2569 1204 2575
+f 1938 1789 2732
+f 2553 1938 2732
+f 2733 2573 2734
+f 2735 2736 2737
+f 2573 2738 1807
+f 2738 2573 2733
+f 780 2739 781
+f 2740 2741 2742
+f 2743 2744 2745
+f 2746 2747 2748
+f 2749 2750 2751
+f 2752 2753 2754
+f 2602 2579 2755
+f 2756 2757 2758
+f 2759 2760 2761
+f 2655 2654 2657
+f 2762 2763 2637
+f 1445 2242 2764
+f 2765 2766 2767
+f 2768 2769 2770
+f 2771 1959 1961
+f 2603 2772 1091
+f 1090 2603 1091
+f 2772 2773 2774
+f 1091 2772 2774
+f 2775 2776 2777
+f 2776 2604 2777
+f 2605 2778 946
+f 2778 508 946
+f 940 991 2285
+f 991 988 680
+f 1342 1071 1067
+f 763 2779 764
+f 1105 1191 2607
+f 2780 1105 2607
+f 2781 1037 1034
+f 902 2441 1034
+f 2782 1300 2783
+f 1296 1302 2443
+f 2784 2137 2295
+f 2446 2613 2294
+f 2785 2786 2787
+f 1978 2031 1066
+f 1829 1828 2282
+f 1828 2788 2282
+f 1430 1428 2615
+f 2789 1430 2615
+f 2134 2133 2790
+f 2791 2130 2618
+f 2792 2789 2793
+f 2615 2452 2622
+f 1256 2794 1257
+f 2795 2796 2797
+f 2401 2798 2799
+f 1284 2800 2801
+f 2802 2803 2804
+f 2617 2273 2805
+f 2806 2807 2808
+f 2809 2810 2811
+f 1503 1505 2631
+f 2812 2813 2814
+f 2294 2296 2480
+f 2296 2815 2816
+f 2817 2818 2819
+f 2820 2821 2822
+f 1230 1232 2636
+f 1603 2823 2824
+f 2825 2826 1461
+f 2262 1230 2636
+f 2827 2828 2829
+f 2830 2827 2829
+f 2831 2832 2833
+f 2827 2834 2828
+f 2835 2836 2837
+f 2838 2128 2127
+f 2656 2839 2494
+f 2657 2656 2494
+f 2839 2840 2496
+f 2841 2842 2843
+f 2494 2839 2496
+f 220 2844 2845
+f 2846 2012 2661
+f 2847 2848 2849
+f 309 2508 2515
+f 2850 2851 2677
+f 2852 2853 2854
+f 2851 2855 2678
+f 2677 2851 2678
+f 2855 2856 2679
+f 2678 2855 2679
+f 2856 2857 2680
+f 2679 2856 2680
+f 2858 2681 2680
+f 2857 2858 2680
+f 2858 2859 2682
+f 2681 2858 2682
+f 2859 2860 2683
+f 2682 2859 2683
+f 2860 2684 2529
+f 2683 2860 2529
+f 2861 2862 2863
+f 2529 2684 2530
+f 2864 2865 2866
+f 2867 2868 2869
+f 2870 2871 2872
+f 2873 2864 2866
+f 2692 2874 2693
+f 2874 2875 2693
+f 2876 2877 2694
+f 2695 2878 2696
+f 2879 2880 2881
+f 2882 2883 2884
+f 2865 2885 2886
+f 2887 2888 2886
+f 2889 2890 2891
+f 2892 2893 2894
+f 2895 2896 2897
+f 2898 2899 2705
+f 1620 2900 2707
+f 2706 1620 2707
+f 2900 2901 2708
+f 2707 2900 2708
+f 2901 2902 2709
+f 2708 2901 2709
+f 2902 2903 2550
+f 2709 2902 2550
+f 2904 2905 2906
+f 2550 2903 2549
+f 2907 2908 2712
+f 2909 2910 2714
+f 2911 2563 2562
+f 2719 2718 2912
+f 2913 2721 2720
+f 1085 2913 2720
+f 2914 2915 762
+f 2915 2916 1058
+f 2917 2918 2919
+f 2920 2921 2922
+f 2923 2924 2925
+f 2647 1576 2153
+f 2926 2927 2928
+f 2929 2930 2931
+f 2759 2932 2933
+f 2574 2569 2575
+f 2555 2557 1204
+f 1311 1313 2934
+f 2554 1311 2934
+f 2935 2738 2936
+f 2936 2738 2937
+f 2938 1532 2939
+f 2935 1807 2738
+f 2940 2941 2942
+f 2943 2759 2761
+f 2944 2945 2125
+f 2124 2944 2125
+f 2944 2946 2947
+f 2945 2944 2947
+f 2948 2949 2950
+f 2951 933 2952
+f 2953 2954 2955
+f 2956 2957 2958
+f 2959 2960 2961
+f 2962 2963 2964
+f 2421 1626 1625
+f 1620 2706 1621
+f 2965 2966 2967
+f 2968 2969 2970
+f 2971 2746 2972
+f 1399 2973 2974
+f 2975 2976 2977
+f 2978 2979 1396
+f 2974 2978 1396
+f 2979 2980 1147
+f 2981 2776 2775
+f 1396 2979 1147
+f 2778 2982 509
+f 2777 2604 2432
+f 991 679 2285
+f 508 2778 509
+f 1602 1888 1890
+f 679 991 680
+f 2983 1107 2780
+f 1719 1720 978
+f 2608 2781 1034
+f 1191 1190 2439
+f 1300 1296 2783
+f 2781 2984 1040
+f 2613 2784 2295
+f 2783 1296 2443
+f 1032 409 1832
+f 2985 1977 2137
+f 1965 2986 2788
+f 2300 488 2275
+f 2987 1826 2789
+f 1828 1965 2788
+f 2988 2290 2291
+f 1428 1426 2452
+f 2789 2615 2793
+f 2989 2990 2991
+f 2992 2176 2175
+f 2793 2615 2622
+f 2993 2994 2992
+f 2995 2415 2996
+f 2997 2998 2399
+f 2999 3000 3001
+f 3002 3003 3004
+f 3005 3006 3007
+f 3008 2809 2811
+f 2273 2274 2805
+f 3009 3010 3011
+f 3012 3013 3014
+f 3015 3016 3017
+f 1422 1425 3018
+f 1559 1503 2631
+f 2297 3019 2815
+f 2826 2825 3020
+f 3021 2514 3022
+f 3023 3024 3025
+f 1497 3026 1498
+f 3027 2827 2830
+f 3028 3027 2830
+f 3029 2834 2827
+f 3027 3029 2827
+f 3029 3030 3031
+f 3032 3033 3034
+f 3035 3036 3037
+f 3038 3039 3040
+f 2840 3041 1698
+f 2496 2840 1698
+f 3042 3043 3044
+f 3045 3046 3047
+f 3048 3049 3050
+f 3051 309 2515
+f 3052 3053 3054
+f 2848 3055 3056
+f 3057 3058 2851
+f 2850 2677 2728
+f 3058 3059 2855
+f 2851 3058 2855
+f 3059 3060 2856
+f 2855 3059 2856
+f 3061 2857 2856
+f 3060 3061 2856
+f 3061 3062 2858
+f 2857 3061 2858
+f 3062 3063 2859
+f 2858 3062 2859
+f 3063 3064 2860
+f 2859 3063 2860
+f 3064 3065 2684
+f 2860 3064 2684
+f 3066 3067 3068
+f 3069 3064 3070
+f 3071 3072 3073
+f 3074 3075 3076
+f 3077 3078 3079
+f 3080 3081 2873
+f 2874 3082 2875
+f 3082 3083 3084
+f 3085 2877 3086
+f 2877 2695 2694
+f 2880 3087 3088
+f 2884 2879 2881
+f 2864 3089 2865
+f 2885 3090 2886
+f 2946 3091 3092
+f 3093 3094 3095
+f 3096 3097 3098
+f 3099 3100 3101
+f 1620 3102 2900
+f 3103 3104 3105
+f 3106 3107 2901
+f 2900 3106 2901
+f 3107 3108 2902
+f 2901 3107 2902
+f 3108 3109 2903
+f 2902 3108 2903
+f 2949 3110 3111
+f 2903 3109 2711
+f 3112 2908 2907
+f 2713 3113 2714
+f 3114 3115 3116
+f 3117 3118 3119
+f 2721 3120 2722
+f 3121 3122 3123
+f 3124 3125 3126
+f 3127 3124 3126
+f 3128 3129 3130
+f 1100 3131 1101
+f 3104 2953 2955
+f 3132 3133 3134
+f 3135 3136 3137
+f 3138 3139 3140
+f 3141 3142 1102
+f 3143 3144 3145
+f 1313 1316 1084
+f 1084 1316 1085
+f 2934 1313 1084
+f 1316 2913 1085
+f 3146 3147 3148
+f 3149 2551 1320
+f 3150 1004 1147
+f 3151 2774 2773
+f 3152 2942 3153
+f 2942 2941 3154
+f 3155 3156 3157
+f 3158 3159 3139
+f 1180 1179 3160
+f 3161 1797 3162
+f 3163 3045 3047
+f 3164 3165 3166
+f 3167 3168 3169
+f 3170 3171 3172
+f 3173 3174 3175
+f 3176 3177 3067
+f 3178 3135 3137
+f 2980 3150 1147
+f 2736 3179 3180
+f 3181 2981 2775
+f 584 3182 585
+f 3183 369 368
+f 2517 3184 1130
+f 453 455 3185
+f 920 3186 921
+f 3187 1474 1475
+f 1765 3187 1475
+f 3188 3189 582
+f 3189 3188 835
+f 3190 832 514
+f 2310 2309 2454
+f 3191 3192 812
+f 2982 3191 667
+f 941 940 2285
+f 3193 941 2285
+f 3194 442 1609
+f 3041 3195 3196
+f 3197 1108 2983
+f 1107 1105 2780
+f 2984 3198 1186
+f 1037 2781 1040
+f 1188 1300 2782
+f 3199 1188 2782
+f 3200 1830 1977
+f 2784 2985 2137
+f 626 420 627
+f 1341 3201 1071
+f 1965 1964 2986
+f 1964 3202 2986
+f 3203 3204 2987
+f 1826 1430 2789
+f 3205 3206 1178
+f 3207 3208 3209
+f 882 897 883
+f 2987 2789 2792
+f 3210 3211 2993
+f 2458 3212 3213
+f 3211 3214 2994
+f 2993 3211 2994
+f 3214 3215 3216
+f 2994 3214 3216
+f 3217 2897 2896
+f 3218 383 3219
+f 3220 3221 2799
+f 2744 3222 3223
+f 3224 3225 2993
+f 3226 3227 3228
+f 2274 1422 3018
+f 3229 3230 3231
+f 2296 2297 2815
+f 3232 3233 3234
+f 2632 2988 2291
+f 2136 2451 3019
+f 3235 3236 3237
+f 3233 3026 3238
+f 3239 3027 3028
+f 3240 3239 3028
+f 3241 3029 3027
+f 3239 3241 3027
+f 3242 3030 3029
+f 3241 3242 3029
+f 3242 3243 3244
+f 3030 3242 3244
+f 1698 3041 3196
+f 3245 3246 3247
+f 3164 3166 3248
+f 3249 3250 3251
+f 3252 3253 3254
+f 3255 3256 3257
+f 3258 3259 3054
+f 3260 3261 3262
+f 3263 3058 3057
+f 3264 3265 2850
+f 3266 3059 3058
+f 3263 3266 3058
+f 3267 3060 3059
+f 3266 3267 3059
+f 3268 3061 3060
+f 3267 3268 3060
+f 3268 3269 3062
+f 3061 3268 3062
+f 3269 3270 3063
+f 3062 3269 3063
+f 3270 3070 3064
+f 3063 3270 3064
+f 3271 3272 3273
+f 3274 3275 3070
+f 3276 3271 3273
+f 3272 3277 3278
+f 3279 3280 3071
+f 1485 3281 3282
+f 3283 3284 3077
+f 3285 3286 3287
+f 3288 3289 3290
+f 3291 3292 3293
+f 3294 3085 3295
+f 2877 2876 3086
+f 3087 3296 3297
+f 2881 2880 3088
+f 3081 3298 2864
+f 3089 2885 2865
+f 3299 3158 3300
+f 2955 3301 3105
+f 3138 3302 3303
+f 3304 3305 1323
+f 3306 3126 3307
+f 2414 2415 2652
+f 3308 3309 1961
+f 3310 3311 3312
+f 3313 3314 2762
+f 3107 3315 3108
+f 3102 3316 3106
+f 2900 3102 3106
+f 3317 3318 3319
+f 3320 3321 3322
+f 3323 3112 2907
+f 3324 2277 3325
+f 3121 3326 3327
+f 2908 2713 2712
+f 3328 3329 3330
+f 3331 3121 3123
+f 3124 3332 3333
+f 3125 3124 3333
+f 3334 3335 3336
+f 3337 1180 3160
+f 3338 3339 3340
+f 3341 3342 3343
+f 3344 3152 3345
+f 2942 3346 3153
+f 3347 3348 3349
+f 3120 3347 3350
+f 3351 3352 2749
+f 3353 3354 3355
+f 3356 3351 2749
+f 2750 3149 1320
+f 3357 3358 3359
+f 2722 3120 3350
+f 3360 3361 3362
+f 3346 2942 3154
+f 2947 2946 3092
+f 3363 3364 3365
+f 3366 3367 3368
+f 2022 1657 3369
+f 3370 3371 3372
+f 3168 3172 3169
+f 3373 3374 3375
+f 3376 3377 3171
+f 3168 3170 3172
+f 2105 3378 3379
+f 3170 3376 3171
+f 2906 3380 3381
+f 3382 3383 3384
+f 615 753 3385
+f 492 494 1535
+f 3386 693 695
+f 3387 831 3190
+f 3388 969 3389
+f 1092 831 3387
+f 3390 1639 1641
+f 3391 1689 1691
+f 581 3391 1691
+f 2442 1348 3392
+f 1690 3188 1691
+f 3393 396 398
+f 3394 3395 645
+f 710 3396 3397
+f 968 969 3388
+f 3398 968 3388
+f 812 3192 950
+f 667 3191 812
+f 948 1072 823
+f 941 3193 3399
+f 597 1112 598
+f 224 2299 452
+f 1111 1108 3197
+f 3400 1111 3197
+f 3198 3401 1187
+f 1040 2984 1186
+f 3402 1041 3403
+f 1183 1188 3199
+f 3404 1827 1830
+f 2985 3200 1977
+f 420 2116 627
+f 886 885 3405
+f 1964 2027 3202
+f 2027 3406 3202
+f 3407 3204 3203
+f 3408 3407 3203
+f 3409 3410 3411
+f 3412 3413 2825
+f 3414 2987 2792
+f 3415 3408 3416
+f 3417 3210 3225
+f 3418 3419 3420
+f 3421 3422 3214
+f 3211 3421 3214
+f 3422 3423 3215
+f 3214 3422 3215
+f 3423 3424 3425
+f 3215 3423 3425
+f 3426 3226 3425
+f 3424 3426 3425
+f 3427 3227 3226
+f 3426 3427 3226
+f 3428 3429 3227
+f 3427 3428 3227
+f 3430 2813 2128
+f 3428 1858 3429
+f 2297 2136 3019
+f 3431 3432 3433
+f 2646 3434 3435
+f 1976 2281 2451
+f 3436 3239 3240
+f 3437 3436 3240
+f 3438 3241 3239
+f 3436 3438 3239
+f 3439 3242 3241
+f 3438 3439 3241
+f 3440 3243 3242
+f 3439 3440 3242
+f 3441 3442 3443
+f 3243 3440 3444
+f 3371 3445 3372
+f 3446 3447 3448
+f 3374 3449 3375
+f 3450 3451 3452
+f 3453 3167 3169
+f 3454 3263 3455
+f 3456 3457 3458
+f 3459 3266 3263
+f 3460 3461 3462
+f 3463 3267 3266
+f 3459 3463 3266
+f 3464 3268 3267
+f 3463 3464 3267
+f 3464 3465 3269
+f 3268 3464 3269
+f 3466 3467 3468
+f 3269 3465 3270
+f 3469 3470 3471
+f 3472 3473 3474
+f 3475 3476 3477
+f 3046 3475 3477
+f 3478 3271 3276
+f 3479 3478 3276
+f 3480 3481 3482
+f 3483 3484 3485
+f 3486 3284 3487
+f 3284 3078 3077
+f 3293 3288 3290
+f 3488 3489 3490
+f 3491 3294 3492
+f 3085 3086 3295
+f 3296 3493 3494
+f 3088 3087 3297
+f 3495 3496 3497
+f 3298 3089 2864
+f 3498 3499 3495
+f 3500 3298 3081
+f 3501 3502 3498
+f 3496 3500 3497
+f 3503 3502 3504
+f 3499 3496 3495
+f 3505 3506 3504
+f 3502 3499 3498
+f 2466 3507 3508
+f 3502 3501 3504
+f 3509 3510 3511
+f 3506 3503 3504
+f 3512 3513 3514
+f 3274 3270 3515
+f 3113 2909 2714
+f 1759 1758 3516
+f 3122 3121 3327
+f 3326 3517 3518
+f 3519 3520 3521
+f 3522 3523 3524
+f 3525 3526 3527
+f 3528 3529 3530
+f 3531 3532 3533
+f 3145 3534 3535
+f 3536 3537 3538
+f 3539 3540 3541
+f 3542 3543 3544
+f 3545 3519 3546
+f 3547 2516 3548
+f 3350 3347 3349
+f 3549 3354 3550
+f 3354 3551 3355
+f 3352 3149 2750
+f 2749 3352 2750
+f 1930 3552 3553
+f 3357 3554 3555
+f 3374 3556 3449
+f 3358 3357 3555
+f 3556 3557 3558
+f 3556 3558 3449
+f 3559 3560 3561
+f 3562 3563 3564
+f 3557 3565 3558
+f 3566 3567 3568
+f 3569 3570 3446
+f 3447 3453 3448
+f 3152 3153 3345
+f 3571 3572 3573
+f 3574 3525 3575
+f 3528 3344 3529
+f 3576 3577 3578
+f 3579 3580 3581
+f 2453 3582 3583
+f 2454 2453 3583
+f 3584 3585 3586
+f 3587 3588 1095
+f 831 832 3190
+f 3389 1092 3387
+f 509 2982 667
+f 2188 2190 3589
+f 3590 998 3398
+f 2096 1174 2097
+f 1174 1351 1143
+f 1611 992 1079
+f 1033 1026 1028
+f 1076 1077 1855
+f 998 968 3398
+f 1854 1076 1855
+f 3591 3592 862
+f 969 1092 3389
+f 1072 3399 823
+f 950 3591 862
+f 442 448 443
+f 1072 941 3399
+f 3593 1110 3400
+f 3594 3595 1115
+f 1186 3198 1187
+f 1108 1107 2983
+f 1041 1183 3403
+f 3401 3593 1294
+f 3200 3404 1830
+f 3403 1183 3199
+f 3582 3596 3597
+f 3598 2109 1827
+f 2027 1971 3599
+f 3600 534 1832
+f 3601 3602 3408
+f 3406 2027 3599
+f 3603 3604 3605
+f 3204 1826 2987
+f 3408 3203 3416
+f 2815 3606 3607
+f 3203 2987 3414
+f 3416 3203 3414
+f 3608 3609 3610
+f 3420 3608 3610
+f 3611 3422 3421
+f 3417 3211 3210
+f 3611 3612 3423
+f 3422 3611 3423
+f 3612 3613 3424
+f 3423 3612 3424
+f 3614 3426 3424
+f 3613 3614 3424
+f 3615 3427 3426
+f 3614 3615 3426
+f 3616 3428 3427
+f 3615 3616 3427
+f 3617 1858 3428
+f 3616 3617 3428
+f 3618 1859 1858
+f 3617 3618 1858
+f 3619 3437 1859
+f 3618 3619 1859
+f 3620 3436 3437
+f 3619 3620 3437
+f 3621 3438 3436
+f 3620 3621 3436
+f 3622 3439 3438
+f 3621 3622 3438
+f 3623 3440 3439
+f 3622 3623 3439
+f 3624 3625 3626
+f 3627 3628 3629
+f 3630 3631 3632
+f 3633 3170 3168
+f 3448 3453 3169
+f 3246 3634 2517
+f 3635 3636 2686
+f 3637 3638 3639
+f 3640 3641 3642
+f 2698 3643 3644
+f 3645 3646 3647
+f 3648 3649 3650
+f 3651 3652 1538
+f 3653 3654 3655
+f 3656 3657 3658
+f 2641 3659 2639
+f 3660 3661 3662
+f 2869 3656 3663
+f 3664 3665 3666
+f 3123 3122 3667
+f 3668 3669 3256
+f 3670 3668 3671
+f 3672 3478 3479
+f 3673 3672 3479
+f 3674 3675 3676
+f 3272 3677 3277
+f 3678 3486 3165
+f 3284 3283 3487
+f 3679 3680 3681
+f 3682 3683 3684
+f 3685 3322 1796
+f 3294 3295 3492
+f 3493 3686 3687
+f 3297 3296 3494
+f 3688 3689 3690
+f 3497 3500 3081
+f 1404 1403 3691
+f 3692 3693 3694
+f 3695 3696 3697
+f 2219 3698 3699
+f 2868 3700 3657
+f 3656 2868 3657
+f 3701 3702 3703
+f 1057 1044 3704
+f 3583 3582 3597
+f 1884 3705 3706
+f 2890 2889 3707
+f 3708 3709 3710
+f 3711 3712 3513
+f 2123 3713 3714
+f 1745 3715 1746
+f 1162 3716 1163
+f 3327 3326 3518
+f 3517 3351 3356
+f 3717 3718 3719
+f 1797 3161 3720
+f 3721 3574 3722
+f 3526 3528 3530
+f 1884 1974 3723
+f 3574 3575 3722
+f 1763 1884 3706
+f 1763 3706 3724
+f 3725 3726 3727
+f 3728 3729 3730
+f 3693 3721 3731
+f 3543 3545 3546
+f 3732 3733 3734
+f 3735 3736 3737
+f 3091 3738 3739
+f 3740 3741 965
+f 3742 3633 3168
+f 2913 3743 2721
+f 3744 3745 3453
+f 3742 3168 3167
+f 3447 3746 3453
+f 3745 3742 3167
+f 3570 3747 3447
+f 3748 2149 3749
+f 818 793 795
+f 3745 3167 3453
+f 3331 3123 3750
+f 3751 2914 762
+f 3349 3348 3752
+f 2968 3753 3754
+f 3694 3693 3755
+f 3526 3530 3527
+f 3756 3757 3730
+f 3758 3756 3730
+f 365 367 1345
+f 3759 3760 3761
+f 3762 1001 3590
+f 2005 3759 3761
+f 1129 1001 3762
+f 3763 1129 3762
+f 3192 3591 950
+f 1001 998 3590
+f 3764 1238 3765
+f 1142 1129 3763
+f 3766 3767 3768
+f 3769 3770 3771
+f 659 3772 660
+f 3773 3774 3775
+f 3776 2079 2080
+f 3092 3091 3739
+f 1239 1238 3764
+f 3777 1239 3764
+f 862 3592 863
+f 3592 3778 863
+f 816 815 321
+f 948 823 822
+f 322 1119 1114
+f 3772 2078 660
+f 1109 1110 3593
+f 3401 1109 3593
+f 3593 3400 1295
+f 1187 3401 1294
+f 3779 1035 3780
+f 1036 1041 3402
+f 3781 1963 2109
+f 3404 3598 1827
+f 2107 1434 532
+f 3782 601 1806
+f 1970 1819 3783
+f 1971 1970 3784
+f 3609 3785 3786
+f 3787 3602 3601
+f 3019 3788 3606
+f 2816 2815 3607
+f 3789 3786 3790
+f 3601 3408 3415
+f 3609 3786 3789
+f 3791 3792 3793
+f 3610 3609 3789
+f 3786 3601 3790
+f 3314 3313 3794
+f 3795 1501 2263
+f 3796 3612 3611
+f 3797 3796 3611
+f 3796 3798 3613
+f 3612 3796 3613
+f 3798 3799 3614
+f 3613 3798 3614
+f 3800 3615 3614
+f 3799 3800 3614
+f 3801 3616 3615
+f 3800 3801 3615
+f 3802 3617 3616
+f 3801 3802 3616
+f 3803 3618 3617
+f 3802 3803 3617
+f 3804 3619 3618
+f 3803 3804 3618
+f 3805 3620 3619
+f 3804 3805 3619
+f 3806 3621 3620
+f 3805 3806 3620
+f 3807 3622 3621
+f 3806 3807 3621
+f 3808 3623 3622
+f 3807 3808 3622
+f 3809 3810 3811
+f 3812 3813 99
+f 3746 3744 3453
+f 3814 3815 3816
+f 3747 3746 3447
+f 3570 3447 3446
+f 3817 3818 3819
+f 3575 3527 3820
+f 3821 3822 3823
+f 2696 2698 3644
+f 3824 3825 3087
+f 3826 3648 3650
+f 3827 3828 3650
+f 3829 3830 3831
+f 3832 3833 3834
+f 3835 3148 3836
+f 3837 3838 3839
+f 3840 3841 3842
+f 3843 3844 3177
+f 3845 3846 3847
+f 3848 3845 3847
+f 3849 3850 3851
+f 3852 3853 3854
+f 3855 3856 3857
+f 3858 3859 3860
+f 3861 3862 3863
+f 3864 3865 3866
+f 3867 3678 3164
+f 3486 3487 3165
+f 3868 3869 3870
+f 2769 3871 3872
+f 3873 3874 3875
+f 3491 3492 3876
+f 3686 1404 3691
+f 3494 3493 3687
+f 3877 3878 3879
+f 1264 1403 1405
+f 3880 3877 3881
+f 3882 3883 3884
+f 3885 3886 3881
+f 3878 3884 3879
+f 3887 3886 3888
+f 3877 3879 3881
+f 3889 3887 3890
+f 3886 3880 3881
+f 3891 3892 3893
+f 3886 3885 3888
+f 3894 3889 3890
+f 3887 3888 3890
+f 3895 3716 3712
+f 3896 3897 3898
+f 2998 3899 2400
+f 3712 3716 1162
+f 3900 3901 3355
+f 3719 3902 3903
+f 3904 3905 3906
+f 3907 3908 3909
+f 3910 3694 3911
+f 3525 3527 3575
+f 3912 3913 3757
+f 3756 3912 3757
+f 3914 3915 3913
+f 3912 3914 3913
+f 3916 3917 3915
+f 3914 3916 3915
+f 3910 3911 3519
+f 3694 3755 3911
+f 1707 1706 962
+f 3545 3910 3519
+f 3918 3919 3920
+f 3921 3922 3923
+f 3924 3823 3925
+f 3926 3747 3570
+f 2873 3927 3928
+f 3929 3930 3931
+f 3932 3933 3934
+f 3935 3936 3937
+f 2934 1084 3938
+f 3939 2719 3940
+f 3941 3942 2552
+f 2551 3941 2552
+f 3551 3900 3355
+f 3943 3331 3750
+f 3944 3945 3946
+f 3947 3948 3949
+f 3950 3951 3531
+f 3721 3722 3731
+f 3952 3953 3917
+f 3916 3952 3917
+f 3954 2083 2079
+f 3776 3954 2079
+f 3954 3955 2084
+f 1247 1239 3777
+f 2083 3954 2084
+f 3765 1142 3763
+f 3956 1247 3777
+f 3955 3957 2088
+f 3958 1326 3956
+f 2084 3955 2088
+f 3957 3959 2089
+f 2088 3957 2089
+f 3959 3960 2093
+f 2089 3959 2093
+f 1326 1247 3956
+f 3960 3961 2162
+f 3778 3962 415
+f 1238 1142 3765
+f 815 822 321
+f 863 3778 415
+f 323 322 1114
+f 815 948 822
+f 3198 1233 3401
+f 824 1120 1119
+f 1294 3593 1295
+f 1110 1111 3400
+f 1035 1036 3780
+f 3400 3197 1301
+f 3598 3781 2109
+f 3780 1036 3402
+f 1898 3963 3964
+f 3781 3965 2026
+f 3599 1971 3784
+f 3596 3966 3967
+f 3786 3787 3601
+f 3784 1970 3783
+f 2815 3019 3606
+f 3602 3407 3408
+f 3968 3969 3970
+f 2451 3971 3788
+f 3972 3973 3974
+f 3790 3601 3415
+f 3975 3976 3977
+f 3978 3979 3977
+f 3607 3980 3411
+f 3607 3606 3980
+f 3981 3982 3983
+f 3606 3984 3980
+f 3985 3796 3797
+f 3986 3987 3988
+f 3989 3798 3796
+f 3985 3989 3796
+f 3990 3799 3798
+f 3989 3990 3798
+f 3990 3991 3800
+f 3799 3990 3800
+f 3991 3992 3801
+f 3800 3991 3801
+f 3993 3802 3801
+f 3992 3993 3801
+f 3994 3803 3802
+f 3993 3994 3802
+f 3995 3804 3803
+f 3994 3995 3803
+f 3996 3805 3804
+f 3995 3996 3804
+f 3997 3806 3805
+f 3996 3997 3805
+f 3998 3807 3806
+f 3997 3998 3806
+f 3999 3808 3807
+f 3998 3999 3807
+f 4000 4001 4002
+f 4003 4004 4005
+f 3075 4006 3076
+f 4007 4008 4009
+f 4010 4011 4012
+f 4008 4013 4014
+f 3934 4015 4016
+f 4017 4018 4019
+f 4020 4021 4022
+f 4023 4024 4025
+f 2883 4026 2879
+f 4027 3571 4028
+f 4029 4030 3828
+f 3827 4029 3828
+f 4031 4032 4033
+f 4014 3096 4034
+f 4032 4035 4036
+f 4009 4014 4034
+f 4037 4038 4039
+f 4038 3469 4039
+f 4040 4041 4042
+f 4040 4043 4044
+f 4045 4046 4047
+f 4048 4049 4050
+f 4051 4052 4053
+f 4054 4055 4056
+f 4057 4058 4059
+f 4060 4061 4062
+f 4063 3867 4064
+f 3678 3165 3164
+f 3871 2769 4065
+f 2769 4066 4065
+f 4067 4068 4069
+f 4070 4067 4069
+f 4071 4072 3883
+f 3687 3686 3691
+f 2875 3873 4067
+f 3878 3882 3884
+f 2687 2691 4071
+f 2693 2875 4067
+f 2693 4067 4070
+f 2691 2693 4070
+f 4073 4074 3084
+f 2875 4074 3873
+f 4075 3489 3488
+f 3931 4075 3488
+f 4076 4077 4078
+f 3489 3679 3490
+f 3872 3085 3294
+f 4079 3491 4073
+f 4080 3457 4081
+f 4082 4083 4084
+f 4085 4086 4087
+f 3716 4086 1163
+f 4088 4089 4090
+f 4091 4092 4093
+f 4094 4095 2574
+f 4096 4097 4098
+f 4099 2143 4100
+f 3693 3731 3755
+f 4101 4102 3953
+f 3952 4101 3953
+f 4103 4104 4102
+f 4101 4103 4102
+f 4103 4105 4106
+f 4104 4103 4106
+f 4105 4107 4108
+f 4106 4105 4108
+f 1940 4109 1794
+f 4110 4111 4112
+f 4113 4114 4115
+f 4116 4117 4108
+f 4118 4119 4120
+f 1758 4121 4122
+f 4107 4116 4108
+f 4123 2720 4124
+f 4125 2934 3938
+f 4126 4127 4117
+f 3942 4128 2718
+f 3943 3750 3901
+f 3900 3943 3901
+f 4129 4130 4131
+f 4132 4133 4134
+f 4135 4136 4137
+f 3532 4138 3533
+f 4139 4140 4141
+f 2093 3960 2162
+f 3961 4142 2228
+f 2162 3961 2228
+f 4142 4143 2241
+f 2228 4142 2241
+f 4143 4144 2251
+f 4145 1477 4146
+f 2241 4143 2251
+f 4147 1476 4145
+f 1477 1478 4146
+f 4144 4148 2402
+f 2251 4144 2402
+f 4148 4149 2403
+f 2402 4148 2403
+f 4149 4150 2404
+f 4151 268 267
+f 2403 4149 2404
+f 4152 1531 4147
+f 1476 1477 4145
+f 4153 4154 839
+f 3962 4155 416
+f 816 321 1078
+f 323 4156 4157
+f 4158 1073 1120
+f 322 824 1119
+f 2984 1193 3198
+f 1233 1109 3401
+f 3197 2983 1303
+f 1295 3400 1301
+f 881 883 4159
+f 903 1035 3779
+f 4160 4161 4162
+f 1489 1266 924
+f 4163 2927 2926
+f 4164 4165 4166
+f 4167 4168 4169
+f 4170 4171 4169
+f 4168 4172 4170
+f 4173 4174 3281
+f 4172 4175 4176
+f 4177 4178 4179
+f 4175 4180 4181
+f 4176 4175 4181
+f 4180 4182 4183
+f 4181 4180 4183
+f 4182 4184 3975
+f 4183 4182 3975
+f 3205 1180 4185
+f 4184 4186 3975
+f 4187 4188 4189
+f 4186 4190 3976
+f 4191 3985 4192
+f 4190 4191 4192
+f 4193 3989 3985
+f 4191 4193 3985
+f 4194 3990 3989
+f 4193 4194 3989
+f 4195 3991 3990
+f 4194 4195 3990
+f 4196 3992 3991
+f 4195 4196 3991
+f 4197 3993 3992
+f 4196 4197 3992
+f 4198 3994 3993
+f 4197 4198 3993
+f 4199 3995 3994
+f 4198 4199 3994
+f 4200 3996 3995
+f 4199 4200 3995
+f 4201 3997 3996
+f 4200 4201 3996
+f 4202 3998 3997
+f 4201 4202 3997
+f 4203 4204 4205
+f 4202 4203 3998
+f 4206 4207 3643
+f 4208 4209 4210
+f 4008 4014 4009
+f 4211 4212 4213
+f 4013 4214 4215
+f 4013 4215 4014
+f 4018 4216 4217
+f 4218 4219 3376
+f 4024 4220 4221
+f 4222 4223 4224
+f 4225 4226 4227
+f 3259 4228 3054
+f 4229 4230 4231
+f 4232 4226 4225
+f 4102 4104 4233
+f 4234 4235 4030
+f 3875 3876 4236
+f 3876 4237 4236
+f 4238 4239 3470
+f 4240 4241 4051
+f 4242 4243 4244
+f 4245 4242 4244
+f 4246 3848 4247
+f 4248 3665 4249
+f 4250 4251 4252
+f 4253 4254 4255
+f 3864 4256 4059
+f 4257 4258 4259
+f 4260 4063 4261
+f 3867 3164 4064
+f 4065 4066 4262
+f 4066 4263 4262
+f 4067 3873 4068
+f 3873 3875 4068
+f 2687 4071 3882
+f 3882 4071 3883
+f 4264 4140 4265
+f 2688 2687 3882
+f 4266 4264 4267
+f 4267 4264 4265
+f 4268 4266 4269
+f 4269 4266 4267
+f 4270 4268 4271
+f 4271 4268 4269
+f 3173 4272 4273
+f 4274 4270 4271
+f 4275 4276 4277
+f 4278 3173 4273
+f 4278 4273 4279
+f 4276 4278 4279
+f 4270 4274 4272
+f 3173 4270 4272
+f 4280 3637 4281
+f 3572 4282 4283
+f 4284 837 4285
+f 4286 4287 3844
+f 4288 4289 4290
+f 2910 4291 4292
+f 3597 3596 3967
+f 3543 3546 3544
+f 4116 4126 4117
+f 4293 4294 4127
+f 4126 4293 4127
+f 4295 4296 4294
+f 4293 4295 4294
+f 4295 4297 4298
+f 4296 4295 4298
+f 4299 4300 4301
+f 3311 4299 4301
+f 4299 4302 4303
+f 4300 4299 4303
+f 4302 4304 4305
+f 2719 2912 3940
+f 2718 4306 2912
+f 4307 4308 4309
+f 4130 3944 4310
+f 3326 4311 3517
+f 4312 4313 4314
+f 4150 4315 2405
+f 2404 4150 2405
+f 4315 4316 2406
+f 1384 1383 4317
+f 4318 1384 4317
+f 2405 4315 2406
+f 1478 1384 4318
+f 4316 4319 2428
+f 2406 4316 2428
+f 4319 4320 2570
+f 2428 4319 2570
+f 1800 1531 4321
+f 4322 2603 2570
+f 4320 4322 2570
+f 4323 2772 2603
+f 4322 4323 2603
+f 4324 2773 2772
+f 4323 4324 2772
+f 4325 4326 4327
+f 4324 4328 2773
+f 4329 1688 4321
+f 1531 4152 4321
+f 4154 4330 729
+f 682 4153 839
+f 1500 4331 326
+f 4332 4333 4334
+f 4335 1068 1073
+f 824 4158 1120
+f 2781 1192 2984
+f 1193 1233 3198
+f 2983 2780 1229
+f 1301 3197 1303
+f 890 4159 891
+f 3965 903 3779
+f 4336 4337 4338
+f 4339 1705 4340
+f 4341 4342 4343
+f 4344 3725 4345
+f 4346 4347 4168
+f 4348 4167 4349
+f 4347 4350 4172
+f 4168 4347 4172
+f 4350 4351 4175
+f 4172 4350 4175
+f 4351 4352 4180
+f 4175 4351 4180
+f 4352 4353 4182
+f 4180 4352 4182
+f 4353 4354 4184
+f 4182 4353 4184
+f 4355 4186 4184
+f 4354 4355 4184
+f 4356 4190 4186
+f 4355 4356 4186
+f 4357 4191 4190
+f 4356 4357 4190
+f 4358 4193 4191
+f 4357 4358 4191
+f 4359 4194 4193
+f 4358 4359 4193
+f 4360 4195 4194
+f 4359 4360 4194
+f 4361 4196 4195
+f 4360 4361 4195
+f 4361 4362 4197
+f 4196 4361 4197
+f 4363 4198 4197
+f 4362 4363 4197
+f 4364 4199 4198
+f 4363 4364 4198
+f 4365 4200 4199
+f 4364 4365 4199
+f 4366 4201 4200
+f 4365 4366 4200
+f 4367 4202 4201
+f 4366 4367 4201
+f 4368 4203 4202
+f 4367 4368 4202
+f 3006 4369 3007
+f 4370 4371 4372
+f 4373 4212 4374
+f 4375 4376 4377
+f 1322 4378 4379
+f 4380 4381 4382
+f 4383 3684 4384
+f 4385 3754 876
+f 4217 4222 4224
+f 3639 3638 4386
+f 4387 530 3245
+f 4388 4389 4390
+f 4391 4392 4393
+f 4394 4395 4396
+f 4397 4398 4399
+f 4400 4401 3928
+f 4402 3688 3690
+f 4403 1405 1404
+f 3038 3040 4404
+f 3865 4405 3866
+f 3490 3681 4406
+f 3931 3488 4287
+f 3665 4248 4054
+f 4049 3666 4050
+f 4251 4253 4252
+f 4407 4408 4409
+f 4410 4257 4411
+f 4412 4413 4258
+f 4414 4415 4261
+f 4063 4064 4261
+f 4416 3886 3887
+f 3889 4417 3887
+f 4070 4069 4072
+f 3874 3876 3875
+f 4418 2688 3878
+f 2691 4070 4071
+f 4141 4419 4139
+f 4140 4139 4265
+f 4247 4420 4421
+f 4422 4423 4424
+f 3854 4425 3850
+f 4052 4426 4053
+f 3858 3673 4427
+f 4297 4428 4429
+f 3673 3479 4430
+f 4427 3673 4430
+f 3479 3276 4431
+f 3276 3273 4432
+f 4433 4434 4435
+f 4430 3479 4431
+f 4248 4436 4055
+f 4243 3852 4437
+f 4041 3674 3676
+f 4438 4244 4439
+f 4059 4440 3865
+f 4441 4442 4443
+f 4444 4445 4446
+f 3738 4447 4448
+f 4449 4450 4451
+f 4452 3732 3734
+f 4298 4297 4429
+f 4428 4453 4454
+f 4303 4302 4305
+f 4455 4456 4305
+f 4304 4455 4305
+f 4457 4458 4456
+f 4455 4457 4456
+f 4459 4460 4458
+f 4461 4462 4463
+f 4457 4459 4458
+f 4464 4465 4466
+f 4467 4468 4469
+f 1531 1476 4147
+f 237 1688 4151
+f 1383 1326 3958
+f 4317 1383 3958
+f 4146 1478 4318
+f 415 3962 416
+f 374 4470 4471
+f 1688 4329 4151
+f 4472 1399 4473
+f 2974 1396 1148
+f 4474 1397 4472
+f 1399 2974 4473
+f 4475 4476 1004
+f 237 4151 1700
+f 3868 4477 4478
+f 4479 915 319
+f 4480 4481 1159
+f 4482 4483 3651
+f 4484 4485 4486
+f 348 4487 349
+f 1850 224 226
+f 2448 2001 2449
+f 4488 4489 880
+f 839 4154 729
+f 443 448 450
+f 337 1613 338
+f 4490 4491 4492
+f 4158 4335 1073
+f 4493 4494 4495
+f 4496 4497 4498
+f 2182 4499 4500
+f 4501 4502 4503
+f 4504 4505 4506
+f 3035 4507 3036
+f 4508 4509 4510
+f 4510 4346 4511
+f 4509 4512 4346
+f 4513 4514 4515
+f 4512 4516 4347
+f 4346 4512 4347
+f 4516 4517 4350
+f 4347 4516 4350
+f 4517 4518 4351
+f 4350 4517 4351
+f 4518 4519 4352
+f 4351 4518 4352
+f 4519 4520 4353
+f 4352 4519 4353
+f 4520 4521 4354
+f 4353 4520 4354
+f 4522 4355 4354
+f 4521 4522 4354
+f 4523 4356 4355
+f 4522 4523 4355
+f 4524 4357 4356
+f 4523 4524 4356
+f 4525 4358 4357
+f 4524 4525 4357
+f 4526 4359 4358
+f 4525 4526 4358
+f 4527 4360 4359
+f 4526 4527 4359
+f 4527 4528 4361
+f 4360 4527 4361
+f 4529 4362 4361
+f 4528 4529 4361
+f 4530 4363 4362
+f 4529 4530 4362
+f 4531 4364 4363
+f 4530 4531 4363
+f 4532 4365 4364
+f 4531 4532 4364
+f 4533 4366 4365
+f 4532 4533 4365
+f 4534 4367 4366
+f 4533 4534 4366
+f 4535 4536 4537
+f 4534 4535 4367
+f 4429 4428 4454
+f 3259 4538 4228
+f 4224 4223 4539
+f 4376 4540 4377
+f 4541 4542 4543
+f 1137 1136 1160
+f 4544 4545 4546
+f 4547 4548 4549
+f 4550 4551 4552
+f 4377 4540 4553
+f 2417 4554 2418
+f 4555 4556 4557
+f 4558 4559 4560
+f 4561 3674 4562
+f 4563 4564 3271
+f 4542 4565 4566
+f 4567 4568 4544
+f 4569 4271 4570
+f 4269 4267 4571
+f 3449 3558 3486
+f 3558 3565 3284
+f 4572 4573 4542
+f 4565 1093 4566
+f 3666 3665 4054
+f 4046 4574 4047
+f 4575 4576 4577
+f 3640 4578 4579
+f 4410 4412 4257
+f 4580 4581 4582
+f 4583 4584 4414
+f 4415 4260 4261
+f 4585 3880 3886
+f 4586 4416 3887
+f 4587 4418 3877
+f 4071 4070 4072
+f 3842 3841 4588
+f 2688 3882 3878
+f 4589 4590 4591
+f 3841 3066 4588
+f 2422 4592 2122
+f 4593 4589 4591
+f 3864 3866 4594
+f 4595 4594 4596
+f 3277 3861 3863
+f 3862 4597 4598
+f 3187 1765 4599
+f 4600 4601 4602
+f 4603 4604 4605
+f 4606 4603 4605
+f 4406 3681 4040
+f 4567 4544 4607
+f 3674 4561 3675
+f 3676 3675 4608
+f 4609 4610 4611
+f 4612 4613 3682
+f 3922 4614 3923
+f 4615 4616 4460
+f 3731 3722 4617
+f 4618 4619 4128
+f 3527 4129 3820
+f 4620 4621 3967
+f 4453 4622 4623
+f 4454 4453 4623
+f 4459 4615 4460
+f 4624 4625 4616
+f 4615 4624 4616
+f 1691 3188 582
+f 4626 1213 1215
+f 1688 1800 4321
+f 4627 4628 4629
+f 4155 4630 586
+f 586 4630 682
+f 416 4155 586
+f 4630 4153 682
+f 2092 2802 794
+f 4631 4632 1889
+f 615 3385 4633
+f 616 615 4633
+f 1025 1290 4634
+f 4635 722 4636
+f 2348 2350 4637
+f 2779 763 1059
+f 357 2167 2000
+f 4638 3180 4639
+f 2960 4640 4641
+f 4642 4643 468
+f 899 4644 704
+f 2160 202 204
+f 4645 629 468
+f 730 4488 880
+f 859 373 2002
+f 618 4646 619
+f 880 4468 669
+f 3405 2268 981
+f 2300 486 488
+f 4647 4648 4649
+f 3016 4650 932
+f 4651 4496 4498
+f 4652 4653 4654
+f 4655 4508 4656
+f 2183 2182 4500
+f 4657 4658 4508
+f 4655 4657 4508
+f 4658 4659 4509
+f 4508 4658 4509
+f 4659 4660 4512
+f 4509 4659 4512
+f 4661 4516 4512
+f 4660 4661 4512
+f 4662 4517 4516
+f 4661 4662 4516
+f 4663 4518 4517
+f 4662 4663 4517
+f 4663 4664 4519
+f 4518 4663 4519
+f 4664 4665 4520
+f 4519 4664 4520
+f 4665 4666 4521
+f 4520 4665 4521
+f 4667 4522 4521
+f 4666 4667 4521
+f 4668 4523 4522
+f 4667 4668 4522
+f 4669 4524 4523
+f 4668 4669 4523
+f 4670 4525 4524
+f 4669 4670 4524
+f 4671 4526 4525
+f 4670 4671 4525
+f 4672 4527 4526
+f 4671 4672 4526
+f 4673 4528 4527
+f 4672 4673 4527
+f 4673 4674 4529
+f 4528 4673 4529
+f 4675 4530 4529
+f 4674 4675 4529
+f 4676 4531 4530
+f 4675 4676 4530
+f 4677 4532 4531
+f 4676 4677 4531
+f 4678 4533 4532
+f 4677 4678 4532
+f 4679 4534 4533
+f 4678 4679 4533
+f 4680 4681 4682
+f 4679 4536 4534
+f 4556 4683 4684
+f 3951 3532 3531
+f 4683 4685 4686
+f 4557 4556 4684
+f 4213 4212 4687
+f 4684 4683 4686
+f 4436 4688 4689
+f 4690 1322 4379
+f 4691 4692 4693
+f 4694 4695 4696
+f 4697 4698 4699
+f 3936 4700 3291
+f 4701 4702 4703
+f 4685 3095 4686
+f 4704 4705 4706
+f 4588 3066 4707
+f 4401 3080 3928
+f 4708 4568 4567
+f 3636 4259 4709
+f 3558 3284 3486
+f 4274 4271 4569
+f 4710 4272 4711
+f 4712 4713 4714
+f 4462 4715 4463
+f 4439 3849 4716
+f 4717 4718 4719
+f 4231 4720 4229
+f 4721 4722 4723
+f 4724 2881 4725
+f 2881 3088 4725
+f 3631 4227 4583
+f 4584 4415 4414
+f 4587 3877 3880
+f 4416 4585 3886
+f 3176 3067 3066
+f 4418 3878 3877
+f 4576 4726 4727
+f 4728 4241 4240
+f 4591 3099 4729
+f 4730 4731 4732
+f 4570 4269 4571
+f 3078 3565 3287
+f 4733 4734 4735
+f 4235 4736 4737
+f 3125 3333 4738
+f 3654 2464 3655
+f 4739 4740 4741
+f 4742 3126 4743
+f 4215 4744 3096
+f 4745 4746 4747
+f 4610 4609 4748
+f 4749 4750 4280
+f 4609 4749 4748
+f 4748 4749 4280
+f 4751 3932 4752
+f 4753 4609 4611
+f 4754 4755 4756
+f 4757 4758 4759
+f 3942 4618 4128
+f 4760 4761 4762
+f 4763 4764 4765
+f 3966 4620 3967
+f 4622 4766 2871
+f 4623 4622 2871
+f 4620 4767 4768
+f 4621 4620 4768
+f 4769 4770 2270
+f 4771 4772 1123
+f 4330 4488 730
+f 729 4330 730
+f 4773 283 1333
+f 697 696 336
+f 4774 4775 4776
+f 1332 4773 1333
+f 4777 4778 4779
+f 1876 4780 1877
+f 4781 4782 4783
+f 2606 625 627
+f 4780 4784 1877
+f 4785 2117 4786
+f 1027 768 770
+f 1028 1027 770
+f 1607 1608 4646
+f 2436 4787 1781
+f 4788 2975 4789
+f 2975 2977 4790
+f 4791 4792 4768
+f 4767 4791 4768
+f 1331 4773 1332
+f 4793 4794 4795
+f 1182 3405 981
+f 358 690 689
+f 400 4796 4797
+f 4798 4799 4800
+f 4801 2820 2822
+f 4802 4803 4654
+f 4804 4805 4806
+f 4807 4808 4809
+f 4810 4811 4812
+f 4813 4814 4815
+f 4816 4817 4658
+f 4657 4816 4658
+f 4817 4818 4659
+f 4658 4817 4659
+f 4819 4660 4659
+f 4818 4819 4659
+f 4820 4661 4660
+f 4819 4820 4660
+f 4821 4662 4661
+f 4820 4821 4661
+f 4822 4663 4662
+f 4821 4822 4662
+f 4823 4664 4663
+f 4822 4823 4663
+f 4823 4824 4665
+f 4664 4823 4665
+f 4824 4825 4666
+f 4665 4824 4666
+f 4826 4667 4666
+f 4825 4826 4666
+f 4827 4668 4667
+f 4826 4827 4667
+f 4828 4669 4668
+f 4827 4828 4668
+f 4829 4670 4669
+f 4828 4829 4669
+f 4830 4671 4670
+f 4829 4830 4670
+f 4831 4672 4671
+f 4830 4831 4671
+f 4832 4673 4672
+f 4831 4832 4672
+f 4833 4674 4673
+f 4832 4833 4673
+f 4834 4675 4674
+f 4833 4834 4674
+f 4835 4676 4675
+f 4834 4835 4675
+f 4836 4677 4676
+f 4835 4836 4676
+f 4837 4678 4677
+f 4836 4837 4677
+f 4838 4679 4678
+f 4837 4838 4678
+f 4838 4839 4536
+f 4679 4838 4536
+f 4840 4841 4842
+f 3672 4843 4844
+f 3490 4845 4287
+f 4846 4564 4563
+f 4611 4847 4848
+f 4849 4850 4851
+f 4852 4007 4853
+f 3884 3883 3298
+f 3662 4854 3633
+f 4855 4856 4857
+f 4858 4583 2969
+f 4859 4860 4861
+f 4862 3297 4863
+f 4040 4562 4041
+f 4406 4040 4044
+f 4864 4865 4866
+f 4867 4868 4545
+f 4713 4708 4567
+f 3375 3678 3867
+f 4718 4716 4719
+f 4790 2977 4869
+f 4421 4870 4871
+f 4029 4234 4030
+f 4872 4736 4235
+f 4873 4874 4875
+f 4876 4873 4875
+f 4043 4042 4877
+f 3854 3853 4425
+f 3648 4706 3649
+f 4706 4878 3649
+f 3630 4225 3631
+f 4227 4584 4583
+f 4879 4880 3571
+f 4585 4587 3880
+f 4881 4882 3669
+f 4883 4884 4885
+f 4072 4069 2885
+f 4886 4887 4888
+f 4889 4890 4891
+f 4892 4273 4710
+f 4893 4894 4792
+f 4232 4430 4226
+f 4895 4896 4897
+f 3163 3047 4898
+f 4089 4899 4090
+f 1204 2557 1205
+f 3866 4900 4901
+f 4902 3935 4903
+f 4904 4905 4906
+f 4907 4908 4909
+f 4546 4902 4910
+f 4906 4907 4909
+f 3638 4911 4386
+f 1482 1484 4912
+f 4913 4914 4915
+f 4916 4751 4917
+f 4918 4919 4920
+f 4921 432 4922
+f 4923 4924 4925
+f 3771 4926 4927
+f 3816 3815 4715
+f 4110 4928 4929
+f 4766 4930 4931
+f 2871 4766 4931
+f 4932 4771 4933
+f 3760 1074 1075
+f 4933 4771 1123
+f 744 1566 4934
+f 4935 4936 4937
+f 721 712 722
+f 447 358 689
+f 2156 1996 4938
+f 1331 1330 1003
+f 1612 1611 1079
+f 4939 4940 4941
+f 1002 1331 1003
+f 3761 3760 1075
+f 270 1562 271
+f 4942 4943 4944
+f 4945 4946 4947
+f 4331 741 326
+f 175 174 4948
+f 4949 3776 4950
+f 4951 4950 2080
+f 4952 3954 3776
+f 1560 1562 277
+f 1562 2571 271
+f 4953 4954 4955
+f 2286 679 681
+f 4956 4957 4958
+f 4959 4960 4961
+f 4962 4963 4964
+f 4965 4966 4967
+f 4799 4961 4968
+f 2417 2416 4969
+f 4970 4971 3869
+f 4972 4804 4973
+f 4974 4975 4816
+f 4976 4657 4977
+f 4975 4978 4817
+f 4816 4975 4817
+f 4978 4979 4818
+f 4817 4978 4818
+f 4979 4980 4819
+f 4818 4979 4819
+f 4980 4981 4820
+f 4819 4980 4820
+f 4982 4821 4820
+f 4981 4982 4820
+f 4983 4822 4821
+f 4982 4983 4821
+f 4984 4823 4822
+f 4983 4984 4822
+f 4985 4824 4823
+f 4984 4985 4823
+f 4986 4825 4824
+f 4985 4986 4824
+f 4986 4987 4826
+f 4825 4986 4826
+f 4988 4827 4826
+f 4987 4988 4826
+f 4989 4828 4827
+f 4988 4989 4827
+f 4990 4829 4828
+f 4989 4990 4828
+f 4991 4830 4829
+f 4990 4991 4829
+f 4992 4831 4830
+f 4991 4992 4830
+f 4993 4832 4831
+f 4992 4993 4831
+f 4994 4833 4832
+f 4993 4994 4832
+f 4995 4834 4833
+f 4994 4995 4833
+f 4996 4835 4834
+f 4995 4996 4834
+f 4997 4836 4835
+f 4996 4997 4835
+f 4998 4837 4836
+f 4997 4998 4836
+f 4999 4838 4837
+f 4998 4999 4837
+f 5000 4839 4838
+f 4999 5000 4838
+f 5000 5001 5002
+f 4839 5000 5002
+f 5003 4233 4094
+f 5004 5005 5006
+f 4930 5007 5008
+f 5009 2357 5010
+f 5011 5012 5013
+f 5014 5015 5016
+f 4442 5017 5018
+f 5012 4728 5013
+f 5019 4726 4575
+f 4244 4437 4439
+f 5020 5021 5022
+f 5023 5020 5022
+f 5024 5025 5026
+f 5027 5028 5029
+f 4568 4867 4544
+f 5030 5031 1094
+f 4259 4258 4709
+f 3176 3843 3177
+f 4716 3851 5032
+f 4068 2887 3090
+f 3891 3894 3892
+f 5033 3671 5034
+f 5035 5036 5037
+f 5038 4876 4875
+f 4875 4898 5039
+f 3853 5040 5041
+f 3501 5042 5043
+f 5044 5045 3935
+f 3567 5046 3630
+f 4225 4227 3631
+f 5013 4728 4240
+f 4027 4879 3571
+f 5012 5047 4728
+f 5048 5049 5050
+f 3089 3883 2885
+f 4725 3088 4862
+f 3689 5051 5052
+f 5053 5054 5055
+f 4310 5056 5057
+f 5058 5059 3913
+f 3849 3854 3850
+f 401 4797 5060
+f 5061 5062 5063
+f 2412 5064 5065
+f 5066 5067 5063
+f 5067 5068 5063
+f 5067 5069 5068
+f 5069 5070 5068
+f 5069 5071 5070
+f 5071 5072 5070
+f 5073 5074 4882
+f 5075 3666 4049
+f 5076 5077 5078
+f 4574 5079 4881
+f 5080 5081 5082
+f 5083 5084 5085
+f 5086 5087 5088
+f 3498 3495 5089
+f 4701 5090 4702
+f 3664 5091 5092
+f 4931 4930 5008
+f 3301 5093 3692
+f 2001 2002 2449
+f 5007 5094 5095
+f 250 246 3191
+f 243 250 2778
+f 523 5096 4489
+f 4488 523 4489
+f 5097 2156 4938
+f 5098 2435 5099
+f 1174 1173 2097
+f 786 617 787
+f 2466 2465 3507
+f 990 646 1525
+f 734 5100 277
+f 1562 270 277
+f 4949 4952 3776
+f 4952 5101 3955
+f 3954 4952 3955
+f 5101 5102 3957
+f 3955 5101 3957
+f 5102 5103 3959
+f 3957 5102 3959
+f 5103 1393 3960
+f 744 4934 2407
+f 5100 1560 277
+f 5104 5105 5106
+f 5107 5108 5109
+f 5110 5111 5112
+f 5113 5114 5115
+f 3329 4956 4958
+f 5116 5117 5118
+f 4961 4960 5119
+f 4960 5120 5119
+f 4806 4805 5121
+f 5122 2128 2838
+f 5123 5124 4975
+f 4976 5125 4974
+f 5124 5126 4978
+f 4975 5124 4978
+f 5126 5127 4979
+f 4978 5126 4979
+f 5127 5128 4980
+f 4979 5127 4980
+f 5128 5129 4981
+f 4980 5128 4981
+f 5129 5130 4982
+f 4981 5129 4982
+f 5131 4983 4982
+f 5130 5131 4982
+f 5132 4984 4983
+f 5131 5132 4983
+f 5133 4985 4984
+f 5132 5133 4984
+f 5134 4986 4985
+f 5133 5134 4985
+f 5135 4987 4986
+f 5134 5135 4986
+f 5135 5136 4988
+f 4987 5135 4988
+f 5137 4989 4988
+f 5136 5137 4988
+f 5137 5138 4990
+f 4989 5137 4990
+f 5139 4991 4990
+f 5138 5139 4990
+f 5140 4992 4991
+f 5139 5140 4991
+f 5140 5141 4993
+f 4992 5140 4993
+f 5142 4994 4993
+f 5141 5142 4993
+f 5143 4995 4994
+f 5142 5143 4994
+f 5144 4996 4995
+f 5143 5144 4995
+f 5145 4997 4996
+f 5144 5145 4996
+f 5146 4998 4997
+f 5145 5146 4997
+f 5147 4999 4998
+f 5146 5147 4998
+f 5148 5000 4999
+f 5147 5148 4999
+f 5149 5001 5000
+f 5148 5149 5000
+f 5149 5150 5005
+f 5001 5149 5005
+f 5150 5151 5152
+f 5005 5150 5152
+f 4577 5153 5154
+f 5155 2424 2423
+f 5156 5157 5158
+f 3830 5159 3831
+f 5160 5161 5085
+f 3927 5156 5158
+f 4430 4431 4226
+f 5162 5163 5164
+f 5165 5166 5167
+f 5168 5169 5170
+f 5171 5172 5031
+f 5173 4852 4853
+f 4408 5174 4238
+f 4857 5175 5074
+f 5176 5177 5178
+f 4036 4035 5179
+f 4277 2697 2878
+f 5008 5007 5095
+f 5036 5180 4380
+f 5181 5035 5037
+f 4243 5182 5183
+f 5094 5184 5185
+f 4902 5044 3935
+f 5186 4561 4562
+f 4283 5187 3567
+f 5046 4225 3630
+f 4392 5188 5189
+f 5190 5191 5192
+f 5047 5193 4728
+f 3481 5194 4883
+f 4131 4310 5057
+f 4069 3090 2885
+f 5195 5196 5197
+f 5198 4739 4741
+f 5199 5200 5201
+f 3372 4063 4260
+f 5074 5014 5194
+f 5062 5066 5063
+f 5202 5203 3468
+f 3327 5204 5205
+f 3292 3288 3293
+f 5201 5206 4218
+f 3487 5207 5208
+f 5209 5210 5211
+f 5212 3127 3306
+f 4243 4242 5182
+f 3668 5213 3671
+f 5214 5215 4720
+f 5216 4876 5038
+f 3165 3487 5208
+f 4736 5217 5218
+f 5219 5220 5221
+f 5222 4611 4848
+f 5223 4231 4230
+f 5224 5225 5226
+f 5227 5228 3925
+f 5095 5094 5185
+f 5229 5230 5231
+f 2131 2448 2450
+f 3959 5103 3960
+f 246 5232 3192
+f 2982 250 3191
+f 2257 2256 5233
+f 5233 2256 5097
+f 5099 2257 5233
+f 2256 2156 5097
+f 3655 2464 3206
+f 762 764 2436
+f 546 5234 547
+f 5235 5236 5237
+f 5238 1514 5239
+f 804 1455 805
+f 1393 5240 3961
+f 3960 1393 3961
+f 5240 5241 4142
+f 3961 5240 4142
+f 5241 5242 4143
+f 1439 1299 5243
+f 4142 5241 4143
+f 5242 5244 4144
+f 4143 5242 4144
+f 5244 5245 4148
+f 5246 5247 5248
+f 5249 5250 5251
+f 5252 5253 5254
+f 5107 5109 5255
+f 4651 4498 5256
+f 5257 5258 5259
+f 5260 5261 5262
+f 5263 5264 5265
+f 5266 5267 5268
+f 5269 5268 5120
+f 5123 4974 5270
+f 5271 4804 4806
+f 5272 5273 5124
+f 5123 5272 5124
+f 5273 5274 5126
+f 5124 5273 5126
+f 5274 5275 5127
+f 5126 5274 5127
+f 5275 5276 5128
+f 5127 5275 5128
+f 5276 5277 5129
+f 5128 5276 5129
+f 5277 5278 5130
+f 5129 5277 5130
+f 5278 5279 5131
+f 5130 5278 5131
+f 5279 5280 5132
+f 5131 5279 5132
+f 5281 5133 5132
+f 5280 5281 5132
+f 5282 5134 5133
+f 5281 5282 5133
+f 5283 5135 5134
+f 5282 5283 5134
+f 5283 5284 5136
+f 5135 5283 5136
+f 5285 5137 5136
+f 5284 5285 5136
+f 5286 5138 5137
+f 5285 5286 5137
+f 5287 5139 5138
+f 5286 5287 5138
+f 5287 5288 5140
+f 5139 5287 5140
+f 5289 5141 5140
+f 5288 5289 5140
+f 5289 5290 5142
+f 5141 5289 5142
+f 5291 5143 5142
+f 5290 5291 5142
+f 5292 5144 5143
+f 5291 5292 5143
+f 5293 5145 5144
+f 5292 5293 5144
+f 5294 5146 5145
+f 5293 5294 5145
+f 5295 5147 5146
+f 5294 5295 5146
+f 5296 5148 5147
+f 5295 5296 5147
+f 5297 5149 5148
+f 5296 5297 5148
+f 5297 5298 5150
+f 5149 5297 5150
+f 5298 5299 5151
+f 5150 5298 5151
+f 5300 5301 5151
+f 5299 5300 5151
+f 5302 5013 5303
+f 5304 1116 1118
+f 4544 4867 4545
+f 4006 5305 5306
+f 5031 878 1094
+f 5305 5171 5306
+f 5307 5308 4013
+f 5309 3079 5310
+f 2355 5311 4483
+f 3632 3631 4858
+f 5312 3640 4579
+f 3248 3166 5313
+f 5314 1354 1353
+f 3097 3930 3929
+f 1322 3939 5315
+f 4885 4056 5316
+f 5317 5318 5319
+f 5037 5036 4380
+f 5200 5202 5201
+f 4244 4243 4437
+f 4561 4612 3675
+f 5320 2768 5321
+f 3571 4880 3572
+f 5187 5046 3567
+f 5322 4254 4253
+f 4880 4282 3572
+f 5323 3827 3649
+f 5324 5322 4253
+f 4911 4909 4010
+f 3297 3494 4863
+f 5184 5325 5326
+f 5327 4224 5328
+f 4881 5073 4882
+f 5329 3482 5330
+f 3951 3950 4095
+f 5014 5016 5331
+f 4032 5332 4033
+f 3945 4132 4134
+f 4856 4400 5175
+f 5314 5333 1354
+f 5313 5160 5085
+f 4857 4856 5175
+f 5334 5335 5166
+f 5160 4864 5161
+f 5336 5337 5338
+f 5339 5340 5341
+f 4414 4261 5342
+f 4264 5080 4140
+f 5343 5038 5344
+f 5092 4019 3845
+f 5022 5021 5345
+f 5346 5347 5348
+f 4030 5349 5017
+f 5350 2869 3663
+f 5185 5184 5326
+f 5351 5352 4696
+f 5353 5354 5355
+f 5356 5357 5358
+f 5232 5359 3591
+f 3191 246 3192
+f 5360 1951 5361
+f 1951 1382 5361
+f 4335 5362 1194
+f 5363 5364 1651
+f 5365 5366 5367
+f 5365 5367 5368
+f 535 1479 533
+f 5369 5370 5371
+f 5239 1437 5372
+f 1566 1514 5373
+f 4144 5244 4148
+f 5245 5374 4149
+f 4148 5245 4149
+f 5374 5375 4150
+f 1514 1437 5239
+f 1299 1432 5376
+f 4149 5374 4150
+f 5376 1432 2090
+f 5375 5377 4315
+f 5378 5379 2854
+f 5380 3017 5381
+f 5382 5383 5384
+f 5385 5107 5255
+f 4150 5375 4315
+f 5386 5387 5388
+f 5384 5383 5389
+f 4493 4495 4803
+f 5390 5391 5392
+f 5393 5394 5395
+f 5396 5397 5398
+f 5399 5400 5401
+f 5402 5403 5404
+f 5405 5104 5406
+f 5269 5266 5268
+f 5407 5408 5272
+f 5270 5409 5272
+f 5408 5410 5273
+f 5272 5408 5273
+f 5410 5411 5274
+f 5273 5410 5274
+f 5411 5412 5275
+f 5274 5411 5275
+f 5412 5413 5276
+f 5275 5412 5276
+f 5413 5414 5277
+f 5276 5413 5277
+f 5414 5415 5278
+f 5277 5414 5278
+f 5415 5416 5279
+f 5278 5415 5279
+f 5416 5417 5280
+f 5279 5416 5280
+f 5417 5418 5281
+f 5280 5417 5281
+f 5419 5282 5281
+f 5418 5419 5281
+f 5419 5420 5283
+f 5282 5419 5283
+f 5420 5421 5284
+f 5283 5420 5284
+f 5421 5422 5285
+f 5284 5421 5285
+f 5422 5423 5286
+f 5285 5422 5286
+f 5423 5424 5287
+f 5286 5423 5287
+f 5424 5425 5288
+f 5287 5424 5288
+f 5426 5289 5288
+f 5425 5426 5288
+f 5426 5427 5290
+f 5289 5426 5290
+f 5428 5291 5290
+f 5427 5428 5290
+f 5429 5292 5291
+f 5428 5429 5291
+f 5430 5293 5292
+f 5429 5430 5292
+f 5431 5294 5293
+f 5430 5431 5293
+f 5432 5295 5294
+f 5431 5432 5294
+f 5433 5296 5295
+f 5432 5433 5295
+f 5434 5297 5296
+f 5433 5434 5296
+f 5434 5435 5298
+f 5297 5434 5298
+f 5435 5436 5299
+f 5298 5435 5299
+f 5437 5300 5299
+f 5436 5437 5299
+f 5438 3836 1536
+f 5439 5440 5441
+f 5442 5443 5444
+f 4874 3163 4898
+f 5445 4279 4892
+f 3495 3497 4401
+f 5446 5447 5448
+f 4588 4707 5449
+f 5342 3248 5313
+f 5450 5026 5451
+f 5452 5453 5454
+f 3296 5455 3493
+f 4572 4542 4541
+f 5328 5456 5457
+f 5458 5459 5460
+f 4737 5461 5462
+f 5463 5464 5465
+f 4381 5317 5319
+f 4845 5466 3844
+f 5467 5468 4076
+f 5469 5470 5471
+f 4797 1579 635
+f 4044 4043 5472
+f 4282 5187 4283
+f 3504 3501 5043
+f 4590 4044 5472
+f 3638 4906 4911
+f 4704 4706 3648
+f 2872 4931 5473
+f 4011 4908 943
+f 4882 5074 5194
+f 4865 5024 5450
+f 3822 3662 3633
+f 5016 5474 4048
+f 4787 5475 5476
+f 5477 5478 5479
+f 4684 4686 5055
+f 5480 4872 4234
+f 5481 4385 5172
+f 5084 5313 5085
+f 3928 5015 5175
+f 4400 3928 5175
+f 3445 3375 3867
+f 5026 4031 5451
+f 5338 5337 4029
+f 5482 5483 5176
+f 4423 5011 5484
+f 4240 4051 5485
+f 5486 5465 5487
+f 5465 5222 5487
+f 5021 5488 5345
+f 5489 5490 5491
+f 3661 5201 4218
+f 1469 5061 5492
+f 5493 5494 5495
+f 5020 5496 5497
+f 5326 5325 5498
+f 5499 4433 5500
+f 3195 5501 5502
+f 5503 5351 4696
+f 5504 5505 5352
+f 5359 5506 3592
+f 2802 2804 794
+f 5009 2356 2357
+f 5507 5508 4285
+f 5509 5510 5511
+f 3896 5512 3897
+f 5513 5514 1365
+f 5515 5513 1365
+f 5516 5370 5514
+f 5513 5516 5514
+f 585 3182 5517
+f 5518 1480 5519
+f 5377 5520 4316
+f 4315 5377 4316
+f 5520 5521 4319
+f 4316 5520 4319
+f 1437 1439 5372
+f 514 5522 515
+f 5372 1439 5243
+f 5523 2416 5524
+f 5521 1390 4320
+f 5234 2981 3181
+f 4319 5521 4320
+f 1390 5525 4322
+f 4320 1390 4322
+f 5525 5526 4323
+f 4322 5525 4323
+f 5526 5527 4324
+f 5528 5529 5530
+f 5531 5532 5533
+f 5534 5535 5536
+f 5537 1724 1723
+f 5538 5539 5540
+f 5541 5542 5543
+f 5544 5545 5546
+f 4802 4493 4803
+f 5547 5402 5404
+f 5548 2845 5549
+f 5266 5405 4507
+f 5403 5261 5260
+f 5409 5407 5272
+f 4507 5405 5406
+f 5550 5408 5407
+f 5551 5550 5407
+f 5552 5410 5408
+f 5550 5552 5408
+f 5552 5553 5411
+f 5410 5552 5411
+f 5553 5554 5412
+f 5411 5553 5412
+f 5554 5555 5413
+f 5412 5554 5413
+f 5555 5556 5414
+f 5413 5555 5414
+f 5556 5557 5415
+f 5414 5556 5415
+f 5557 5558 5416
+f 5415 5557 5416
+f 5558 5559 5417
+f 5416 5558 5417
+f 5559 5560 5418
+f 5417 5559 5418
+f 5560 5561 5419
+f 5418 5560 5419
+f 5561 5562 5420
+f 5419 5561 5420
+f 5562 5563 5421
+f 5420 5562 5421
+f 5563 5564 5422
+f 5421 5563 5422
+f 5564 5565 5423
+f 5422 5564 5423
+f 5565 5566 5424
+f 5423 5565 5424
+f 5566 5567 5425
+f 5424 5566 5425
+f 5567 5568 5426
+f 5425 5567 5426
+f 5568 5569 5427
+f 5426 5568 5427
+f 5570 5428 5427
+f 5569 5570 5427
+f 5570 5571 5429
+f 5428 5570 5429
+f 5571 5572 5430
+f 5429 5571 5430
+f 5573 5431 5430
+f 5572 5573 5430
+f 5574 5432 5431
+f 5573 5574 5431
+f 5574 5575 5433
+f 5432 5574 5433
+f 5576 5434 5433
+f 5575 5576 5433
+f 5577 5435 5434
+f 5576 5577 5434
+f 5577 5578 5436
+f 5435 5577 5436
+f 5578 5579 5437
+f 5436 5578 5437
+f 5580 5581 4872
+f 5582 5579 5583
+f 2884 2881 4724
+f 5480 5580 4872
+f 2882 2884 5584
+f 5179 2882 5584
+f 5585 5586 5587
+f 5588 4547 4549
+f 3098 5589 5590
+f 5591 3485 5592
+f 5593 5327 3846
+f 3951 4104 3532
+f 4106 4108 4138
+f 4914 5594 3840
+f 4065 4262 2878
+f 5595 5596 5597
+f 4753 4611 5222
+f 5486 5463 5465
+f 5017 5598 5018
+f 5592 4541 5599
+f 4442 5018 4443
+f 5591 5592 5600
+f 4700 3936 3935
+f 5601 5602 5603
+f 4904 4906 3638
+f 3501 3498 5604
+f 5605 5606 5607
+f 3637 4904 3638
+f 5474 5608 4049
+f 5581 5217 4736
+f 3490 3679 3681
+f 5194 5014 5331
+f 5609 5319 5610
+f 4611 4610 4847
+f 5611 5612 5613
+f 5303 4240 5485
+f 5613 5612 5614
+f 4431 4432 5615
+f 4628 5616 4629
+f 5617 5612 5618
+f 5619 3450 5620
+f 5621 5622 5623
+f 5203 5624 5625
+f 3946 5626 5056
+f 5316 4056 4689
+f 5174 5627 4238
+f 4576 4727 5153
+f 5600 5599 5628
+f 5081 5629 5630
+f 5610 5486 5487
+f 5631 4255 5449
+f 4226 4431 5615
+f 5632 5633 5634
+f 5635 5636 5637
+f 1697 1699 3450
+f 3196 3195 5502
+f 5638 5639 5640
+f 5603 5638 5640
+f 5639 5641 5642
+f 5640 5639 5642
+f 5641 5643 5644
+f 5351 5504 5352
+f 5645 5646 5505
+f 5506 5647 3778
+f 5648 1469 5492
+f 5649 2364 5650
+f 5651 5649 5650
+f 5652 5515 2364
+f 5649 5652 2364
+f 5653 5513 5515
+f 5652 5653 5515
+f 5654 5516 5513
+f 5653 5654 5513
+f 5655 5519 5516
+f 5654 5655 5516
+f 4323 5526 4324
+f 5655 5518 5519
+f 5656 2364 5515
+f 5657 4328 4324
+f 2995 5658 5659
+f 5527 5657 4324
+f 4791 4893 4792
+f 5660 5209 5211
+f 547 5234 3181
+f 532 535 533
+f 681 680 5098
+f 1432 531 2090
+f 4793 3387 5661
+f 1475 485 5662
+f 5663 5664 3709
+f 4002 4001 5665
+f 5666 5252 5667
+f 221 223 5668
+f 5669 5670 5671
+f 5672 2316 5673
+f 5405 5674 5104
+f 5675 5246 5248
+f 5404 5403 5260
+f 5398 5544 5546
+f 4960 5269 5120
+f 5261 5676 5262
+f 5677 175 5678
+f 5267 5266 4507
+f 5679 5680 5551
+f 5049 5681 5682
+f 5683 5550 5551
+f 5684 5683 5551
+f 5685 5552 5550
+f 5683 5685 5550
+f 5686 5553 5552
+f 5685 5686 5552
+f 5686 5687 5554
+f 5553 5686 5554
+f 5687 5688 5555
+f 5554 5687 5555
+f 5688 5689 5556
+f 5555 5688 5556
+f 5689 5690 5557
+f 5556 5689 5557
+f 5690 5691 5558
+f 5557 5690 5558
+f 5692 5559 5558
+f 5691 5692 5558
+f 5692 5693 5560
+f 5559 5692 5560
+f 5693 5694 5561
+f 5560 5693 5561
+f 5694 5695 5562
+f 5561 5694 5562
+f 5696 5563 5562
+f 5695 5696 5562
+f 5696 5697 5564
+f 5563 5696 5564
+f 5697 5698 5565
+f 5564 5697 5565
+f 5698 5699 5566
+f 5565 5698 5566
+f 5699 5700 5567
+f 5566 5699 5567
+f 5700 5701 5568
+f 5567 5700 5568
+f 5701 5702 5569
+f 5568 5701 5569
+f 5702 5703 5570
+f 5569 5702 5570
+f 5703 5704 5571
+f 5570 5703 5571
+f 5704 5705 5572
+f 5571 5704 5572
+f 5705 5706 5573
+f 5572 5705 5573
+f 5707 5574 5573
+f 5706 5707 5573
+f 5708 5575 5574
+f 5707 5708 5574
+f 5708 5709 5576
+f 5575 5708 5576
+f 5709 5710 5577
+f 5576 5709 5577
+f 5710 5583 5578
+f 5577 5710 5578
+f 5711 5579 5582
+f 5578 5583 5579
+f 4216 5712 4222
+f 4249 4247 5713
+f 2218 5714 3698
+f 5712 4216 5715
+f 3885 3881 3496
+f 4548 5716 4549
+f 2877 3871 2695
+f 3499 3885 3496
+f 4382 5609 5717
+f 4424 5718 4870
+f 5017 5349 5598
+f 3677 3861 3277
+f 3099 5472 3100
+f 4050 4054 4056
+f 5464 5719 5222
+f 4602 4601 5720
+f 3684 5591 4384
+f 5719 4753 5222
+f 3840 5594 3843
+f 3843 4286 3844
+f 5603 5640 5721
+f 4384 5591 5600
+f 3753 5722 876
+f 4545 5044 4902
+f 4750 4904 3637
+f 4906 4909 4911
+f 4905 4907 4906
+f 5723 3471 5724
+f 5608 5075 4049
+f 4048 5474 4049
+f 5725 4278 4276
+f 3661 4218 4854
+f 3675 4612 3682
+f 5726 5712 5715
+f 3637 3639 4281
+f 2866 5727 5156
+f 5728 3249 3251
+f 3370 3372 3251
+f 5729 5730 1364
+f 5731 3305 3304
+f 3650 3828 4442
+f 5732 5733 5608
+f 5734 5735 5736
+f 5737 3383 5738
+f 5739 5740 5737
+f 5741 5742 5739
+f 5091 3664 5075
+f 5742 5740 5739
+f 5489 4090 5743
+f 5740 3383 5737
+f 5744 5745 5746
+f 3166 5160 5313
+f 5747 5748 5749
+f 5501 5750 5751
+f 5642 5641 5644
+f 5752 4788 5753
+f 5754 5009 5010
+f 5755 2219 3699
+f 4928 4110 4112
+f 5756 5757 4722
+f 5758 5759 5760
+f 5761 5762 4894
+f 5763 5764 5765
+f 5504 5645 5505
+f 5766 5767 5646
+f 5748 5768 5749
+f 5749 5768 5741
+f 5769 5649 5651
+f 5650 2364 2363
+f 5770 5652 5649
+f 5769 5770 5649
+f 5770 5771 5653
+f 5652 5770 5653
+f 5772 5773 5774
+f 5775 5776 5777
+f 2149 2148 5778
+f 5779 5780 5781
+f 5644 5782 5783
+f 5645 5766 5646
+f 5784 5785 5786
+f 5787 5788 5789
+f 5790 3389 4793
+f 3387 3190 5661
+f 5791 3388 5790
+f 3389 3387 4793
+f 3398 3388 5791
+f 522 3398 5791
+f 381 3590 522
+f 3388 3389 5790
+f 404 403 1481
+f 5792 5793 4474
+f 4183 3972 4181
+f 5108 5794 5795
+f 5667 5252 5796
+f 5797 5674 5405
+f 5798 5799 5800
+f 5676 5397 5396
+f 5801 5802 5803
+f 5804 5805 5806
+f 5807 5808 5809
+f 4805 5810 5121
+f 5811 2837 5812
+f 5813 5814 5815
+f 5816 4387 5817
+f 5814 5818 5815
+f 5819 5813 5815
+f 5820 5821 5683
+f 5822 5823 4812
+f 5824 5685 5683
+f 5821 5824 5683
+f 5825 5686 5685
+f 5824 5825 5685
+f 5826 5687 5686
+f 5825 5826 5686
+f 5827 5688 5687
+f 5826 5827 5687
+f 5827 5828 5689
+f 5688 5827 5689
+f 5828 5829 5690
+f 5689 5828 5690
+f 5829 5830 5691
+f 5690 5829 5691
+f 5830 5831 5692
+f 5691 5830 5692
+f 5832 5693 5692
+f 5831 5832 5692
+f 5833 5694 5693
+f 5832 5833 5693
+f 5834 5695 5694
+f 5833 5834 5694
+f 5835 5696 5695
+f 5834 5835 5695
+f 5835 5836 5697
+f 5696 5835 5697
+f 5836 5837 5698
+f 5697 5836 5698
+f 5837 5838 5699
+f 5698 5837 5699
+f 5838 5839 5700
+f 5699 5838 5700
+f 5839 5840 5701
+f 5700 5839 5701
+f 5840 5841 5702
+f 5701 5840 5702
+f 5841 5842 5703
+f 5702 5841 5703
+f 5842 5843 5704
+f 5703 5842 5704
+f 5843 5844 5705
+f 5704 5843 5705
+f 5844 5845 5706
+f 5705 5844 5706
+f 5845 5846 5707
+f 5706 5845 5707
+f 5847 5708 5707
+f 5846 5847 5707
+f 5848 5709 5708
+f 5847 5848 5708
+f 5848 5849 5710
+f 5709 5848 5710
+f 5849 5850 5583
+f 5710 5849 5583
+f 5851 5852 5853
+f 5583 5850 5582
+f 4420 4424 4421
+f 4884 4050 4056
+f 4874 4898 4875
+f 3482 4883 4885
+f 3842 4588 5854
+f 4255 4254 5854
+f 5855 5856 5857
+f 5858 5859 3861
+f 5856 5035 5181
+f 5857 5856 5181
+f 5180 5317 4381
+f 4380 5180 4381
+f 5318 5463 5486
+f 5319 5318 5486
+f 3067 5860 5861
+f 5465 5464 5222
+f 5862 5863 5379
+f 5045 5864 4700
+f 5865 5866 5867
+f 3746 3837 3744
+f 4413 5868 4709
+f 3477 3476 5869
+f 5870 4686 5871
+f 2056 2163 2057
+f 5872 4905 4904
+f 4280 4750 3637
+f 5873 5748 5072
+f 4750 5872 4904
+f 5202 5200 5203
+f 5331 5016 4048
+f 5336 5874 5337
+f 5875 5876 5877
+f 3174 5725 5878
+f 4381 5319 5609
+f 5879 5880 5881
+f 4270 3175 4268
+f 5882 5883 5884
+f 5885 5886 5887
+f 5888 5889 5890
+f 5072 5748 5747
+f 5891 5892 5767
+f 5766 5891 5767
+f 5893 5894 5892
+f 5891 5893 5892
+f 5895 5877 5894
+f 5893 5895 5894
+f 5896 5897 5877
+f 5895 5896 5877
+f 5070 5072 5883
+f 5898 5899 5897
+f 5095 5185 5900
+f 2957 2956 5899
+f 5896 5898 5897
+f 5063 5068 5888
+f 5898 5901 5902
+f 5763 5903 5764
+f 2214 2216 5904
+f 3702 3001 5905
+f 3739 3738 4448
+f 5906 5907 5908
+f 5909 5910 5911
+f 5912 5913 5914
+f 5915 5916 5917
+f 5899 5898 5902
+f 5918 5919 5920
+f 5921 5922 5923
+f 5472 4877 3100
+f 5502 5501 5751
+f 5447 4865 5450
+f 5924 5770 5769
+f 5925 5926 5769
+f 5927 5928 5771
+f 5770 5927 5771
+f 5929 5754 5930
+f 5931 5932 5933
+f 5768 5742 5741
+f 5934 4015 5935
+f 5936 1982 5937
+f 5938 5901 3920
+f 5750 5939 5940
+f 1397 1399 4472
+f 3150 4475 1004
+f 5941 5942 4476
+f 5943 916 915
+f 5944 2473 5945
+f 5946 5947 5948
+f 5949 4485 4484
+f 5950 348 350
+f 4487 3187 4599
+f 5951 5952 5953
+f 3188 5954 835
+f 5955 5956 5957
+f 5958 5955 5957
+f 5266 5797 5405
+f 5794 5798 5800
+f 5959 44 5960
+f 5674 5105 5104
+f 5961 5962 5963
+f 5964 5965 5966
+f 5805 5967 5968
+f 4961 5119 4968
+f 5969 5970 5971
+f 5968 5967 5972
+f 2240 5969 5971
+f 5973 5974 5970
+f 563 558 560
+f 5975 4325 4327
+f 5976 5977 5820
+f 5683 5684 5820
+f 5978 5979 5824
+f 5821 5978 5824
+f 5980 5825 5824
+f 5979 5980 5824
+f 5981 5826 5825
+f 5980 5981 5825
+f 5982 5827 5826
+f 5981 5982 5826
+f 5983 5828 5827
+f 5982 5983 5827
+f 5984 5829 5828
+f 5983 5984 5828
+f 5985 5830 5829
+f 5984 5985 5829
+f 5985 5986 5831
+f 5830 5985 5831
+f 5987 5832 5831
+f 5986 5987 5831
+f 5988 5833 5832
+f 5987 5988 5832
+f 5989 5834 5833
+f 5988 5989 5833
+f 5989 5990 5835
+f 5834 5989 5835
+f 5990 5991 5836
+f 5835 5990 5836
+f 5991 5992 5837
+f 5836 5991 5837
+f 5992 5993 5838
+f 5837 5992 5838
+f 5993 5994 5839
+f 5838 5993 5839
+f 5994 5995 5840
+f 5839 5994 5840
+f 5995 5996 5841
+f 5840 5995 5841
+f 5996 5997 5842
+f 5841 5996 5842
+f 5997 5998 5843
+f 5842 5997 5843
+f 5998 5999 5844
+f 5843 5998 5844
+f 5999 6000 5845
+f 5844 5999 5845
+f 6000 6001 5846
+f 5845 6000 5846
+f 6001 6002 5847
+f 5846 6001 5847
+f 6002 6003 5848
+f 5847 6002 5848
+f 6003 6004 5849
+f 5848 6003 5849
+f 6004 5852 5850
+f 5849 6004 5850
+f 6005 6006 5851
+f 5850 5852 5851
+f 4882 5194 3481
+f 3101 3100 6007
+f 3668 4881 3669
+f 3669 4882 3481
+f 5322 6008 6009
+f 5193 6010 4241
+f 3837 3839 3744
+f 4427 4430 4232
+f 3066 3068 4707
+f 3098 3097 6011
+f 4726 5216 4727
+f 5335 6012 4416
+f 6013 4577 5154
+f 4409 3470 3469
+f 3851 6014 6015
+f 6016 5324 4251
+f 6017 6018 6019
+f 3850 4425 6020
+f 6021 2867 2869
+f 1658 3933 5628
+f 6022 6023 6024
+f 3883 4072 2885
+f 6025 5872 4750
+f 6026 4423 5484
+f 6027 5768 5748
+f 4749 6025 4750
+f 5189 6028 4879
+f 5071 5873 5072
+f 3080 2873 3928
+f 6010 6029 4052
+f 3174 6030 3175
+f 5021 5020 5497
+f 6031 5923 6032
+f 4064 3248 5342
+f 4249 5713 4436
+f 6033 6034 6035
+f 6036 4121 6037
+f 5473 5008 6038
+f 6039 5938 6040
+f 3373 3375 3445
+f 6041 5381 6042
+f 6043 1354 5333
+f 3371 3373 3445
+f 5715 4216 4017
+f 4223 6044 4539
+f 3649 3827 3650
+f 4211 4376 4375
+f 3826 4441 5456
+f 6045 6046 6047
+f 6048 6049 5215
+f 6050 6045 6047
+f 6051 6052 6046
+f 6053 6054 6055
+f 1717 1716 4124
+f 6056 6057 6058
+f 6059 2753 6060
+f 2739 6061 781
+f 5855 6062 5856
+f 3256 3669 3480
+f 4590 5472 4591
+f 4054 4248 4055
+f 5610 6063 6064
+f 2922 5043 6065
+f 6066 6067 6068
+f 5207 6069 5024
+f 6070 6071 6072
+f 5927 6072 5928
+f 5038 4875 5344
+f 4173 6073 3230
+f 5778 5779 5781
+f 5883 5072 5747
+f 6074 4003 1982
+f 5936 6074 1982
+f 6075 1897 1982
+f 4003 6075 1982
+f 1214 6076 6077
+f 5919 6078 5920
+f 6079 3958 6080
+f 753 1535 3385
+f 6081 1133 6082
+f 4511 6083 4510
+f 4800 6084 3212
+f 4494 6085 6086
+f 2730 4800 3212
+f 4799 4968 6084
+f 6087 6088 5972
+f 4804 5271 4973
+f 6089 4972 6090
+f 5967 6091 5972
+f 5810 6092 6093
+f 6094 6095 3328
+f 6096 6097 6098
+f 6099 6100 6101
+f 3057 3265 3455
+f 6102 6103 650
+f 6104 6105 5979
+f 5978 6104 5979
+f 6105 6106 5980
+f 5979 6105 5980
+f 6106 6107 5981
+f 5980 6106 5981
+f 6108 5982 5981
+f 6107 6108 5981
+f 6109 5983 5982
+f 6108 6109 5982
+f 6110 5984 5983
+f 6109 6110 5983
+f 6111 5985 5984
+f 6110 6111 5984
+f 6111 6112 5986
+f 5985 6111 5986
+f 6113 5987 5986
+f 6112 6113 5986
+f 6114 5988 5987
+f 6113 6114 5987
+f 6115 5989 5988
+f 6114 6115 5988
+f 6115 6116 5990
+f 5989 6115 5990
+f 6116 6117 5991
+f 5990 6116 5991
+f 6117 6118 5992
+f 5991 6117 5992
+f 6119 5993 5992
+f 6118 6119 5992
+f 6120 5994 5993
+f 6119 6120 5993
+f 6121 5995 5994
+f 6120 6121 5994
+f 6122 5996 5995
+f 6121 6122 5995
+f 6122 6123 5997
+f 5996 6122 5997
+f 6123 6124 5998
+f 5997 6123 5998
+f 6124 6125 5999
+f 5998 6124 5999
+f 6125 6126 6000
+f 5999 6125 6000
+f 6126 6127 6001
+f 6000 6126 6001
+f 6127 6128 6002
+f 6001 6127 6002
+f 6128 6129 6003
+f 6002 6128 6003
+f 6130 6004 6003
+f 6129 6130 6003
+f 6131 5852 6004
+f 6130 6131 6004
+f 6131 6132 5853
+f 5852 6131 5853
+f 2922 3505 5043
+f 5751 5750 5940
+f 6133 4371 6134
+f 3088 3297 4862
+f 3295 3086 6135
+f 5336 6136 5874
+f 5172 4385 876
+f 6137 6138 6139
+f 6140 6141 5717
+f 5609 6064 5717
+f 3884 3298 3500
+f 3687 3691 6142
+f 6143 6062 4606
+f 6144 4704 6044
+f 6145 6025 4749
+f 6146 2752 6147
+f 6148 6145 4609
+f 4609 6145 4749
+f 5318 6149 5463
+f 4753 6148 4609
+f 5317 6150 5318
+f 6151 6152 5464
+f 6153 6154 5740
+f 6149 6151 5463
+f 6155 6156 6157
+f 5873 6027 5748
+f 5727 6158 6159
+f 6160 6161 6162
+f 6069 5309 5025
+f 3644 3643 4878
+f 6163 6164 6165
+f 4261 4064 5342
+f 6032 6166 6151
+f 6032 6167 6166
+f 2835 6168 2836
+f 4025 4024 4221
+f 6169 6170 6171
+f 6172 4855 6173
+f 5090 6172 6173
+f 6174 6175 6176
+f 3641 3640 5312
+f 6177 6178 6179
+f 6180 5312 6178
+f 4214 6179 4215
+f 6181 3648 3826
+f 4216 4222 4217
+f 4539 6044 6182
+f 6150 6031 6149
+f 6182 6181 3826
+f 6183 2579 2578
+f 6184 6185 6186
+f 5778 5781 1979
+f 6187 5765 6188
+f 966 6189 3697
+f 6190 2787 6191
+f 6192 6193 6194
+f 6195 6196 6197
+f 2907 2712 4097
+f 2753 6198 6060
+f 6199 6200 6201
+f 4853 4007 4009
+f 2873 2866 3927
+f 4546 4607 4544
+f 6031 6032 6149
+f 6202 5613 5488
+f 4848 6203 6204
+f 6205 5348 6206
+f 6207 6208 3075
+f 5194 5331 4883
+f 6209 6210 5601
+f 6211 6074 6212
+f 6213 6214 6215
+f 6216 6217 6074
+f 6211 6216 6074
+f 6217 4004 4003
+f 6074 6217 4003
+f 4386 4911 6218
+f 4005 6219 6220
+f 6075 4003 4005
+f 4643 4645 468
+f 4645 6221 630
+f 629 4645 630
+f 6221 6222 4932
+f 630 6221 4932
+f 6222 6223 4771
+f 4932 6222 4771
+f 6224 4772 4771
+f 6223 6224 4771
+f 4893 5761 4894
+f 797 976 6225
+f 6226 6227 5762
+f 2116 2117 4785
+f 5761 6226 5762
+f 3956 3777 6228
+f 6229 6230 6231
+f 6226 6232 6233
+f 6080 3956 6228
+f 6082 1135 6234
+f 6235 6236 6237
+f 5969 5973 5970
+f 4800 4799 6084
+f 2183 4500 6238
+f 6239 6238 5974
+f 6240 6241 6242
+f 6243 6244 6245
+f 6246 6247 6248
+f 5806 5805 5968
+f 6249 6250 6096
+f 5534 6251 6252
+f 6253 6254 6255
+f 6256 6257 6258
+f 1871 6259 6260
+f 6261 6262 6263
+f 6264 6265 6105
+f 6104 6264 6105
+f 6265 6266 6106
+f 6105 6265 6106
+f 6266 6267 6107
+f 6106 6266 6107
+f 6268 6108 6107
+f 6267 6268 6107
+f 6269 6109 6108
+f 6268 6269 6108
+f 6270 6110 6109
+f 6269 6270 6109
+f 6271 6111 6110
+f 6270 6271 6110
+f 6271 6272 6112
+f 6111 6271 6112
+f 6273 6113 6112
+f 6272 6273 6112
+f 6274 6114 6113
+f 6273 6274 6113
+f 6275 6115 6114
+f 6274 6275 6114
+f 6275 6276 6116
+f 6115 6275 6116
+f 6277 6117 6116
+f 6276 6277 6116
+f 6277 6278 6118
+f 6117 6277 6118
+f 6279 6119 6118
+f 6278 6279 6118
+f 6280 6120 6119
+f 6279 6280 6119
+f 6281 6121 6120
+f 6280 6281 6120
+f 6282 6122 6121
+f 6281 6282 6121
+f 6283 6123 6122
+f 6282 6283 6122
+f 6284 6124 6123
+f 6283 6284 6123
+f 6284 6285 6125
+f 6124 6284 6125
+f 6285 6286 6126
+f 6125 6285 6126
+f 6286 6287 6127
+f 6126 6286 6127
+f 6287 6288 6128
+f 6127 6287 6128
+f 6288 6289 6129
+f 6128 6288 6129
+f 6289 6290 6130
+f 6129 6289 6130
+f 6290 6291 6131
+f 6130 6290 6131
+f 6291 6292 6132
+f 6131 6291 6132
+f 1898 1897 6293
+f 5523 5524 6294
+f 6295 4252 5631
+f 3086 6296 6135
+f 4277 4279 5445
+f 2695 4065 2878
+f 6146 6297 6198
+f 3888 3885 3499
+f 6298 6299 6300
+f 6301 6302 3639
+f 5463 6151 5464
+f 6152 6303 5719
+f 6303 6148 4753
+f 5464 6152 5719
+f 3821 6304 3822
+f 5719 6303 4753
+f 5740 6154 3383
+f 5733 5075 5608
+f 5474 5157 5608
+f 6305 6306 6307
+f 1746 6308 6309
+f 6310 6311 5483
+f 6312 6313 6155
+f 5742 6153 5740
+f 6314 5733 5732
+f 6156 3629 6157
+f 6206 5348 6315
+f 6136 6316 5874
+f 4739 4131 4740
+f 6317 6318 6319
+f 3484 4573 4572
+f 4273 4272 4710
+f 3683 3483 3485
+f 3497 3081 3080
+f 5580 4853 4009
+f 4250 4252 6295
+f 4432 6320 6321
+f 4393 4027 4028
+f 5068 5070 5889
+f 6322 6323 2883
+f 6324 5080 4264
+f 6325 6326 3292
+f 3559 6327 6328
+f 4220 6031 6150
+f 6329 1669 6330
+f 1206 1205 6331
+f 2485 6329 2486
+f 6332 6330 1669
+f 2485 2484 6333
+f 6330 2486 6329
+f 6331 6334 5588
+f 3219 6335 6336
+f 3870 2753 6059
+f 6337 6338 4478
+f 6339 6340 6055
+f 3530 4130 4129
+f 5081 5219 6341
+f 3675 3682 4608
+f 3171 6342 6343
+f 3172 3171 6343
+f 4731 3045 3163
+f 4596 4594 6012
+f 4002 5665 2997
+f 4370 5588 4549
+f 3883 3089 3298
+f 5042 3501 5604
+f 6344 6345 6216
+f 6211 6346 6216
+f 6345 6347 6217
+f 6216 6345 6217
+f 4221 4220 6150
+f 1595 1594 3204
+f 6348 6349 6350
+f 4597 6351 6352
+f 3227 6353 3228
+f 6220 6354 6355
+f 6335 6356 6357
+f 6358 6359 6360
+f 3958 3956 6080
+f 4318 4317 6361
+f 3762 3590 381
+f 3590 3398 522
+f 6362 3763 380
+f 380 3762 381
+f 6363 3765 6362
+f 3763 3762 380
+f 6364 3764 6363
+f 3765 3763 6362
+f 3777 3764 6364
+f 6228 3777 6364
+f 6365 6366 6367
+f 3764 3765 6363
+f 1489 924 923
+f 6227 6226 6233
+f 1133 1135 6082
+f 2961 2960 4641
+f 6368 6369 6370
+f 5973 6239 5974
+f 6371 6372 2240
+f 5121 5810 6093
+f 2847 2849 6373
+f 6374 5819 6375
+f 6376 6377 6378
+f 3230 3229 4173
+f 6379 6380 6250
+f 6381 6382 6383
+f 6384 6385 6386
+f 6387 6388 6389
+f 6390 6391 6264
+f 6392 6393 6394
+f 6391 6395 6265
+f 6264 6391 6265
+f 6395 6396 6266
+f 6265 6395 6266
+f 6396 6397 6267
+f 6266 6396 6267
+f 6397 6398 6268
+f 6267 6397 6268
+f 6398 6399 6269
+f 6268 6398 6269
+f 6400 6270 6269
+f 6399 6400 6269
+f 6400 6401 6271
+f 6270 6400 6271
+f 6402 6272 6271
+f 6401 6402 6271
+f 6403 6273 6272
+f 6402 6403 6272
+f 6403 6404 6274
+f 6273 6403 6274
+f 6404 6405 6275
+f 6274 6404 6275
+f 6405 6406 6276
+f 6275 6405 6276
+f 6406 6407 6277
+f 6276 6406 6277
+f 6407 6408 6278
+f 6277 6407 6278
+f 6409 6279 6278
+f 6408 6409 6278
+f 6410 6280 6279
+f 6409 6410 6279
+f 6411 6281 6280
+f 6410 6411 6280
+f 6412 6282 6281
+f 6411 6412 6281
+f 6413 6283 6282
+f 6412 6413 6282
+f 6414 6284 6283
+f 6413 6414 6283
+f 6414 6415 6285
+f 6284 6414 6285
+f 6415 6416 6286
+f 6285 6415 6286
+f 6416 6417 6287
+f 6286 6416 6287
+f 6417 6418 6288
+f 6287 6417 6288
+f 6419 6289 6288
+f 6418 6419 6288
+f 6420 6290 6289
+f 6419 6420 6289
+f 6421 6291 6290
+f 6420 6421 6290
+f 6421 6422 6292
+f 6291 6421 6292
+f 6423 6424 6425
+f 3219 383 6426
+f 5880 6033 5881
+f 5713 4421 4871
+f 6427 3824 2880
+f 5231 4417 3889
+f 5035 6428 5036
+f 4025 4221 5180
+f 4221 6150 5317
+f 5036 4025 5180
+f 6150 6149 5318
+f 5180 4221 5317
+f 6429 6430 4714
+f 5083 5085 6431
+f 2998 6432 3899
+f 3826 3650 4441
+f 6206 6433 6434
+f 6435 6206 6434
+f 3839 5227 3925
+f 6433 6206 6436
+f 6206 6315 6436
+f 3292 6326 3288
+f 5073 4857 5074
+f 6313 6156 6155
+f 6437 3748 6438
+f 6159 6314 5732
+f 4874 6439 3163
+f 2218 6440 5714
+f 3172 6343 6441
+f 3822 3633 3742
+f 4718 6442 4439
+f 3169 3172 6441
+f 6443 1425 1424
+f 6444 6445 3641
+f 6446 3446 6447
+f 6447 3448 6441
+f 4751 6448 3932
+f 3448 3169 6441
+f 5584 2884 4724
+f 5208 4864 5160
+f 2948 3110 2949
+f 6449 5344 5887
+f 3476 6450 5869
+f 6451 6452 5351
+f 6453 6451 4695
+f 6452 6454 5504
+f 5351 6452 5504
+f 6455 5645 5504
+f 6454 6455 5504
+f 6456 5766 5645
+f 6302 6457 6458
+f 6455 6456 5645
+f 6459 6302 6458
+f 3568 3630 3632
+f 6460 6177 4214
+f 6458 6461 6462
+f 6463 6464 6332
+f 6465 6466 6467
+f 6464 6468 6330
+f 6332 6464 6330
+f 1810 2486 6330
+f 6468 1810 6330
+f 3719 3718 3902
+f 1811 1245 1812
+f 6469 6470 6471
+f 1740 1739 6472
+f 2575 1206 6473
+f 6474 6475 6476
+f 6477 5891 5766
+f 6456 6477 5766
+f 3569 3446 6446
+f 6478 3569 6446
+f 4035 6322 2882
+f 4032 6479 4035
+f 6480 6481 5607
+f 6482 6483 6484
+f 4606 4605 6143
+f 6213 2640 6214
+f 6485 6486 6345
+f 6487 6488 6344
+f 6486 6489 6347
+f 6345 6486 6347
+f 6489 6490 6219
+f 5939 6491 6492
+f 6493 6220 6219
+f 6490 6493 6219
+f 6494 6354 6220
+f 6493 6494 6220
+f 6495 4318 6361
+f 6496 6497 6498
+f 4317 3958 6079
+f 6361 4317 6079
+f 6499 6500 6501
+f 6502 6503 6504
+f 606 605 758
+f 6505 6506 3390
+f 1641 1640 620
+f 622 912 914
+f 913 1815 6507
+f 685 3391 581
+f 419 538 541
+f 3186 6508 6509
+f 4581 6510 6511
+f 6512 6513 4891
+f 1198 2286 959
+f 6514 4933 1184
+f 1308 2483 2303
+f 5099 5233 1200
+f 6515 6234 1135
+f 6516 6517 6518
+f 6519 6520 6521
+f 6522 6234 6515
+f 6523 2847 6373
+f 6524 6525 6526
+f 6527 6528 6529
+f 6530 6531 6532
+f 6533 6534 6535
+f 6536 6257 6256
+f 6537 5865 6538
+f 6534 1177 6539
+f 6540 6391 6390
+f 6541 6542 6543
+f 6544 6395 6391
+f 6540 6544 6391
+f 6544 6545 6396
+f 6395 6544 6396
+f 6545 6546 6397
+f 6396 6545 6397
+f 6546 6547 6398
+f 6397 6546 6398
+f 6548 6399 6398
+f 6547 6548 6398
+f 6549 6400 6399
+f 6548 6549 6399
+f 6550 6401 6400
+f 6549 6550 6400
+f 6550 6551 6402
+f 6401 6550 6402
+f 6551 6552 6403
+f 6402 6551 6403
+f 6552 6553 6404
+f 6403 6552 6404
+f 6553 6554 6405
+f 6404 6553 6405
+f 6554 6555 6406
+f 6405 6554 6406
+f 6555 6556 6407
+f 6406 6555 6407
+f 6556 6557 6408
+f 6407 6556 6408
+f 6558 6409 6408
+f 6557 6558 6408
+f 6559 6410 6409
+f 6558 6559 6409
+f 6559 6560 6411
+f 6410 6559 6411
+f 6561 6412 6411
+f 6560 6561 6411
+f 6562 6413 6412
+f 6561 6562 6412
+f 6562 6563 6414
+f 6413 6562 6414
+f 6563 6564 6415
+f 6414 6563 6415
+f 6565 6416 6415
+f 6564 6565 6415
+f 6566 6417 6416
+f 6565 6566 6416
+f 6567 6418 6417
+f 6566 6567 6417
+f 6568 6419 6418
+f 6567 6568 6418
+f 6569 6420 6419
+f 6568 6569 6419
+f 6569 6570 6421
+f 6420 6569 6421
+f 6570 6571 6422
+f 6421 6570 6422
+f 6572 5003 6573
+f 6571 6423 6422
+f 6574 6575 776
+f 4055 4436 4689
+f 3496 3881 3500
+f 3502 3888 3499
+f 5856 6143 5035
+f 6428 4025 5036
+f 6155 6157 6576
+f 6577 6155 6576
+f 2401 2400 2798
+f 6578 6310 3289
+f 4559 4557 5054
+f 3828 5017 4442
+f 6326 6578 3288
+f 3650 4442 4441
+f 5600 5592 5599
+f 4053 4426 4250
+f 3672 4844 6579
+f 4426 4251 4250
+f 3840 3843 3176
+f 5075 3664 3666
+f 6580 6581 6582
+f 4104 3951 4233
+f 6172 5042 4855
+f 5606 6480 5607
+f 6583 6584 6585
+f 4868 6586 5044
+f 6587 5893 5891
+f 6588 3569 6478
+f 6477 6587 5891
+f 6589 5895 5893
+f 6587 6589 5893
+f 6590 5896 5895
+f 6591 6588 6592
+f 6589 6590 5895
+f 6593 5898 5896
+f 6590 6593 5896
+f 3918 5901 5898
+f 3446 3448 6447
+f 3838 5227 3839
+f 6594 6595 3458
+f 6140 5717 6596
+f 4056 4055 4689
+f 5717 6597 6596
+f 3631 4583 4858
+f 3890 3888 3503
+f 6598 4717 6599
+f 457 6600 6601
+f 6435 6205 6206
+f 4597 5181 6351
+f 3629 6602 6603
+f 5208 5207 4864
+f 6604 6605 6463
+f 6463 1668 6606
+f 6607 6608 6468
+f 6464 6607 6468
+f 6608 6609 1810
+f 6468 6608 1810
+f 1245 1811 6610
+f 6609 1811 1810
+f 6611 6612 4807
+f 6613 6614 5755
+f 6476 6615 6616
+f 2599 6617 1318
+f 6618 3735 3737
+f 6593 3918 5898
+f 3369 6619 6620
+f 4374 4211 4375
+f 4210 6621 6622
+f 6623 4232 5046
+f 4855 5604 4856
+f 4379 4378 6624
+f 6625 1355 6142
+f 6626 6627 6628
+f 6472 1739 6629
+f 6630 6631 6486
+f 6485 6630 6486
+f 6631 6632 6489
+f 6486 6631 6489
+f 6632 6633 6490
+f 6489 6632 6490
+f 6634 6493 6490
+f 6633 6634 6490
+f 6635 6494 6493
+f 6634 6635 6493
+f 6636 6496 6494
+f 6635 6636 6494
+f 783 1846 784
+f 6637 6638 6639
+f 2117 419 541
+f 1066 2031 365
+f 6309 6640 6641
+f 1522 929 931
+f 6642 6643 6233
+f 773 772 2097
+f 6232 6642 6233
+f 1633 429 431
+f 1292 6514 1184
+f 4933 1123 1122
+f 681 5098 819
+f 1184 4933 1122
+f 1309 1308 2303
+f 959 681 819
+f 6644 6645 6646
+f 1307 2440 2483
+f 1443 2784 2613
+f 6647 6648 6649
+f 1925 2782 1920
+f 1506 1443 2613
+f 2058 2279 352
+f 1920 2783 1761
+f 3787 1919 3602
+f 1492 6650 6651
+f 6652 6653 6654
+f 6535 6534 6539
+f 6540 6390 6655
+f 6652 6656 6653
+f 6657 6540 6655
+f 6658 6657 6655
+f 6659 6544 6540
+f 6657 6659 6540
+f 6660 6545 6544
+f 6659 6660 6544
+f 6661 6546 6545
+f 6660 6661 6545
+f 6662 6547 6546
+f 6661 6662 6546
+f 6662 6663 6548
+f 6547 6662 6548
+f 6664 6549 6548
+f 6663 6664 6548
+f 6665 6550 6549
+f 6664 6665 6549
+f 6666 6551 6550
+f 6665 6666 6550
+f 6667 6552 6551
+f 6666 6667 6551
+f 6667 6668 6553
+f 6552 6667 6553
+f 6668 6669 6554
+f 6553 6668 6554
+f 6669 6670 6555
+f 6554 6669 6555
+f 6671 6556 6555
+f 6670 6671 6555
+f 6672 6557 6556
+f 6671 6672 6556
+f 6672 6673 6558
+f 6557 6672 6558
+f 6673 6674 6559
+f 6558 6673 6559
+f 6674 6675 6560
+f 6559 6674 6560
+f 6675 6676 6561
+f 6560 6675 6561
+f 6676 6677 6562
+f 6561 6676 6562
+f 6677 6678 6563
+f 6562 6677 6563
+f 6679 6564 6563
+f 6678 6679 6563
+f 6680 6565 6564
+f 6679 6680 6564
+f 6681 6566 6565
+f 6680 6681 6565
+f 6682 6567 6566
+f 6681 6682 6566
+f 6683 6568 6567
+f 6682 6683 6567
+f 6684 6569 6568
+f 6683 6684 6568
+f 6684 6685 6570
+f 6569 6684 6570
+f 6685 6686 6571
+f 6570 6685 6571
+f 6686 6687 6423
+f 6571 6686 6423
+f 6687 6688 6689
+f 6690 6437 6438
+f 6691 5855 5859
+f 5301 6692 6693
+f 6642 6694 6695
+f 6143 6428 5035
+f 4375 4377 6027
+f 6157 6603 6696
+f 6027 4377 6153
+f 5873 4375 6027
+f 4553 6697 6154
+f 6153 4553 6154
+f 6698 6699 6641
+f 5045 4700 3935
+f 4378 6700 6624
+f 4038 4409 3469
+f 6311 4725 6701
+f 4862 4863 5333
+f 6326 5179 6578
+f 4725 4862 6701
+f 5179 5584 6578
+f 5584 4724 6310
+f 5042 5604 4855
+f 6008 4913 4915
+f 4864 4866 5161
+f 6592 6588 6478
+f 3304 1323 1325
+f 6702 6703 965
+f 6643 6642 6695
+f 5889 5882 6704
+f 6705 6706 3347
+f 4546 4545 4902
+f 6707 5082 5630
+f 4702 5079 4046
+f 4598 6352 6708
+f 4216 4018 4017
+f 5589 3098 6011
+f 2866 5156 3927
+f 5715 4017 6314
+f 6709 3518 6710
+f 3837 3746 3747
+f 5181 5037 6351
+f 6711 6065 4701
+f 5348 6207 6315
+f 6439 4732 3163
+f 1644 3920 3919
+f 6712 6460 4214
+f 6157 3629 6603
+f 6713 4591 4729
+f 6027 6153 5742
+f 5473 6038 6714
+f 6715 6716 6608
+f 6464 6605 6607
+f 6716 6717 6609
+f 6608 6716 6609
+f 6717 6610 1811
+f 6609 6717 1811
+f 6718 6719 4388
+f 472 6720 470
+f 1317 2599 1318
+f 6721 6067 6066
+f 6694 6722 6723
+f 2923 6724 2924
+f 4109 1790 1792
+f 3047 3046 5885
+f 6186 6725 6726
+f 6158 5715 6314
+f 4207 5336 5338
+f 4562 3674 4041
+f 2245 3313 2637
+f 6727 6630 6485
+f 6701 4862 5333
+f 6728 6729 6630
+f 6730 6728 6630
+f 6729 6731 6631
+f 6630 6729 6631
+f 6731 6732 6632
+f 6631 6731 6632
+f 6733 6633 6632
+f 6732 6733 6632
+f 6734 6634 6633
+f 6733 6734 6633
+f 6735 6635 6634
+f 6734 6735 6634
+f 6736 6636 6635
+f 6735 6736 6635
+f 6737 6738 6739
+f 6736 6737 6636
+f 4306 6740 2912
+f 6741 6742 1580
+f 1068 4335 1194
+f 6438 3748 6743
+f 5362 2284 1194
+f 2284 1195 1194
+f 1195 2284 1198
+f 2284 2286 1198
+f 5098 5099 820
+f 2286 681 959
+f 1308 1307 2483
+f 819 5098 820
+f 1224 2439 1225
+f 1306 2441 2440
+f 1441 2985 2784
+f 6744 6745 6746
+f 1824 3199 1925
+f 1443 1441 2784
+f 1972 1492 6651
+f 2783 2443 1761
+f 3785 1924 3787
+f 6650 607 6747
+f 3783 6748 3419
+f 1760 1595 3407
+f 5541 5543 6749
+f 6750 3783 3419
+f 6751 6752 6658
+f 928 6753 6754
+f 6755 6657 6658
+f 6752 6755 6658
+f 6756 6659 6657
+f 6755 6756 6657
+f 6757 6660 6659
+f 6756 6757 6659
+f 6758 6661 6660
+f 6757 6758 6660
+f 6759 6662 6661
+f 6758 6759 6661
+f 6760 6663 6662
+f 6759 6760 6662
+f 6761 6664 6663
+f 6760 6761 6663
+f 6762 6665 6664
+f 6761 6762 6664
+f 6763 6666 6665
+f 6762 6763 6665
+f 6764 6667 6666
+f 6763 6764 6666
+f 6764 6765 6668
+f 6667 6764 6668
+f 6765 6766 6669
+f 6668 6765 6669
+f 6766 6767 6670
+f 6669 6766 6670
+f 6768 6671 6670
+f 6767 6768 6670
+f 6769 6672 6671
+f 6768 6769 6671
+f 6769 6770 6673
+f 6672 6769 6673
+f 6770 6771 6674
+f 6673 6770 6674
+f 6771 6772 6675
+f 6674 6771 6675
+f 6772 6773 6676
+f 6675 6772 6676
+f 6773 6774 6677
+f 6676 6773 6677
+f 6775 6678 6677
+f 6774 6775 6677
+f 6776 6679 6678
+f 6775 6776 6678
+f 6777 6680 6679
+f 6776 6777 6679
+f 6778 6681 6680
+f 6777 6778 6680
+f 6779 6682 6681
+f 6778 6779 6681
+f 6780 6683 6682
+f 6779 6780 6682
+f 6781 6684 6683
+f 6780 6781 6683
+f 6782 6685 6684
+f 6781 6782 6684
+f 6783 6686 6685
+f 6782 6783 6685
+f 6783 6784 6687
+f 6686 6783 6687
+f 6784 6785 6688
+f 6687 6784 6688
+f 6786 2819 2950
+f 6787 6788 6789
+f 6576 6157 6696
+f 6790 6791 1792
+f 5071 4374 5873
+f 4377 4553 6153
+f 4866 6792 6318
+f 4578 3640 6793
+f 4584 6321 4415
+f 5615 6321 4584
+f 6578 5584 6310
+f 3505 3504 5043
+f 6794 6795 6796
+f 4724 4725 6311
+f 6797 6798 6799
+f 6800 6801 6802
+f 4239 6803 4916
+f 6804 6805 6806
+f 6807 6808 6809
+f 6810 6811 4683
+f 5480 5874 5580
+f 5046 4232 4225
+f 6205 5346 5348
+f 4600 6696 4601
+f 6577 6576 6812
+f 3475 4719 3476
+f 6208 6813 5305
+f 6576 6696 4600
+f 5312 4579 6814
+f 6044 6181 6182
+f 6815 3717 3719
+f 5079 6173 5073
+f 3603 6816 3604
+f 5333 4863 6043
+f 6310 4724 6311
+f 6315 6207 3075
+f 4865 5207 5024
+f 4594 3866 4901
+f 5334 4596 5335
+f 6182 3826 5456
+f 6304 3662 3822
+f 3289 6310 5483
+f 5768 6027 5742
+f 5224 6715 6817
+f 6715 6608 6607
+f 6818 6716 5224
+f 6716 6818 6717
+f 6819 6820 6610
+f 6717 6819 6610
+f 6820 470 6720
+f 6610 6820 6720
+f 6821 6822 3685
+f 760 6823 6824
+f 3523 6616 6825
+f 6826 6721 6066
+f 4493 6827 4494
+f 6828 6474 3522
+f 4109 1792 1794
+f 4917 4751 4752
+f 6322 2883 2882
+f 5350 3663 6829
+f 4014 4215 3096
+f 2690 2688 4418
+f 4692 6830 6831
+f 6832 6730 6833
+f 4033 5332 6586
+f 6834 6835 6729
+f 6728 6834 6729
+f 6835 6836 6731
+f 6729 6835 6731
+f 6836 6837 6732
+f 6731 6836 6732
+f 6837 6838 6733
+f 6732 6837 6733
+f 6839 6734 6733
+f 6838 6839 6733
+f 6840 6735 6734
+f 6839 6840 6734
+f 6841 6736 6735
+f 6840 6841 6735
+f 6842 6841 6843
+f 5940 6492 6844
+f 820 5099 1200
+f 5233 5097 1202
+f 1513 1106 1836
+f 1200 5233 1202
+f 1192 1193 2984
+f 957 1986 1836
+f 1192 2781 2608
+f 1305 1192 2608
+f 1307 1306 2440
+f 1306 1305 2608
+f 2258 2259 1360
+f 2441 1306 2608
+f 1436 3200 2985
+f 1225 2258 1360
+f 1823 3403 1824
+f 1441 1436 2985
+f 6651 6650 6747
+f 2782 2783 1920
+f 6845 1825 3785
+f 607 609 6846
+f 6748 6845 3608
+f 1919 1760 3602
+f 2451 2281 3971
+f 3419 6748 3608
+f 1894 6847 1895
+f 2282 6848 2283
+f 6849 6850 6752
+f 6751 6849 6752
+f 6850 6851 6755
+f 6752 6850 6755
+f 6852 6756 6755
+f 6851 6852 6755
+f 6853 6757 6756
+f 6852 6853 6756
+f 6854 6758 6757
+f 6853 6854 6757
+f 6855 6759 6758
+f 6854 6855 6758
+f 6856 6760 6759
+f 6855 6856 6759
+f 6857 6761 6760
+f 6856 6857 6760
+f 6858 6762 6761
+f 6857 6858 6761
+f 6859 6763 6762
+f 6858 6859 6762
+f 6860 6764 6763
+f 6859 6860 6763
+f 6860 6861 6765
+f 6764 6860 6765
+f 6861 6862 6766
+f 6765 6861 6766
+f 6862 6863 6767
+f 6766 6862 6767
+f 6864 6768 6767
+f 6863 6864 6767
+f 6865 6769 6768
+f 6864 6865 6768
+f 6865 6866 6770
+f 6769 6865 6770
+f 6866 6867 6771
+f 6770 6866 6771
+f 6867 6868 6772
+f 6771 6867 6772
+f 6868 6869 6773
+f 6772 6868 6773
+f 6869 6870 6774
+f 6773 6869 6774
+f 6871 6775 6774
+f 6870 6871 6774
+f 6872 6776 6775
+f 6871 6872 6775
+f 6873 6777 6776
+f 6872 6873 6776
+f 6874 6778 6777
+f 6873 6874 6777
+f 6875 6779 6778
+f 6874 6875 6778
+f 6876 6780 6779
+f 6875 6876 6779
+f 6876 6877 6781
+f 6780 6876 6781
+f 6877 6878 6782
+f 6781 6877 6782
+f 6878 6879 6783
+f 6782 6878 6783
+f 6880 6784 6783
+f 6879 6880 6783
+f 6880 6881 6785
+f 6784 6880 6785
+f 6882 6883 6884
+f 6885 6886 6887
+f 6888 6889 6890
+f 6308 6640 6309
+f 6167 6891 6892
+f 6893 6894 6895
+f 5085 5161 6317
+f 3640 3642 6793
+f 4867 5448 4868
+f 5448 5451 4868
+f 6896 6810 4556
+f 5451 4033 4868
+f 3231 6897 6898
+f 6899 6800 6802
+f 5306 5171 5031
+f 6882 6900 6901
+f 6902 6903 6904
+f 2698 4206 3643
+f 385 384 6905
+f 6906 3814 3816
+f 4873 6907 4874
+f 5306 5031 5030
+f 4856 5089 4400
+f 6315 3075 3074
+f 5731 4861 3305
+f 6178 5312 6814
+f 6908 6909 6013
+f 6910 6599 3045
+f 5332 4036 6325
+f 4556 6810 4683
+f 4706 6911 4878
+f 6325 4036 6326
+f 4241 4052 4051
+f 5450 5024 5026
+f 5720 6912 6913
+f 5157 5732 5608
+f 3288 6578 3289
+f 30 60 6914
+f 4885 4884 4056
+f 6062 6143 5856
+f 6915 6916 6917
+f 5084 5083 2970
+f 6918 6919 6820
+f 4695 6451 5503
+f 6919 6920 470
+f 6820 6919 470
+f 6920 6921 471
+f 470 6920 471
+f 3909 3908 2062
+f 2129 1636 1635
+f 6922 6474 6828
+f 6923 6924 6925
+f 1942 6926 6927
+f 6903 6928 6929
+f 3250 3370 3251
+f 5082 4141 4140
+f 4731 6910 3045
+f 6598 6442 4717
+f 6930 4851 6931
+f 5615 4432 6321
+f 6932 6834 6728
+f 5446 5448 4867
+f 6933 6934 6835
+f 6834 6933 6835
+f 6935 6836 6835
+f 6934 6935 6835
+f 6936 6837 6836
+f 6935 6936 6836
+f 6936 6937 6838
+f 6837 6936 6838
+f 6938 6839 6838
+f 6937 6938 6838
+f 6939 6840 6839
+f 6938 6939 6839
+f 6940 4965 6941
+f 6939 6942 6840
+f 1309 2303 2146
+f 1203 1309 2146
+f 739 957 1836
+f 1203 2146 1986
+f 2607 2439 1224
+f 957 1203 1986
+f 1303 2983 1229
+f 2780 2607 1231
+f 1231 2607 1224
+f 1229 2780 1231
+f 2259 2305 1368
+f 2439 2258 1225
+f 751 3404 3200
+f 1360 2259 1368
+f 3780 3402 1820
+f 1436 751 3200
+f 6747 607 6846
+f 3199 2782 1925
+f 6748 1821 6845
+f 609 748 6943
+f 6944 6945 6946
+f 1924 1919 3787
+f 6947 6948 6949
+f 2238 6950 6951
+f 6952 6953 6954
+f 6955 6956 6957
+f 6958 6959 6849
+f 6960 6954 6961
+f 6959 6962 6850
+f 6849 6959 6850
+f 6962 6963 6851
+f 6850 6962 6851
+f 6963 6964 6852
+f 6851 6963 6852
+f 6965 6853 6852
+f 6964 6965 6852
+f 6966 6854 6853
+f 6965 6966 6853
+f 6967 6855 6854
+f 6966 6967 6854
+f 6968 6856 6855
+f 6967 6968 6855
+f 6969 6857 6856
+f 6968 6969 6856
+f 6970 6858 6857
+f 6969 6970 6857
+f 6971 6859 6858
+f 6970 6971 6858
+f 6972 6860 6859
+f 6971 6972 6859
+f 6972 6973 6861
+f 6860 6972 6861
+f 6973 6974 6862
+f 6861 6973 6862
+f 6974 6975 6863
+f 6862 6974 6863
+f 6976 6864 6863
+f 6975 6976 6863
+f 6977 6865 6864
+f 6976 6977 6864
+f 6977 6978 6866
+f 6865 6977 6866
+f 6978 6979 6867
+f 6866 6978 6867
+f 6979 6980 6868
+f 6867 6979 6868
+f 6980 6981 6869
+f 6868 6980 6869
+f 6982 6870 6869
+f 6981 6982 6869
+f 6983 6871 6870
+f 6982 6983 6870
+f 6984 6872 6871
+f 6983 6984 6871
+f 6985 6873 6872
+f 6984 6985 6872
+f 6986 6874 6873
+f 6985 6986 6873
+f 6986 6987 6875
+f 6874 6986 6875
+f 6987 6988 6876
+f 6875 6987 6876
+f 6988 6989 6877
+f 6876 6988 6877
+f 6989 6990 6878
+f 6877 6989 6878
+f 6990 6991 6879
+f 6878 6990 6879
+f 6992 6880 6879
+f 6991 6992 6879
+f 6993 6881 6880
+f 6992 6993 6880
+f 6994 6470 6881
+f 6993 6994 6881
+f 4755 6471 6470
+f 6994 4755 6470
+f 4755 4754 6995
+f 6471 4755 6995
+f 6996 6997 6998
+f 4582 3110 2948
+f 4000 384 383
+f 4033 6586 4868
+f 6166 6999 6152
+f 7000 7001 4555
+f 6135 7002 7003
+f 6442 4718 4717
+f 3557 7004 3285
+f 2868 3656 2869
+f 7005 6135 7003
+f 7006 4438 6442
+f 6321 5728 4415
+f 2288 7007 7008
+f 1362 7009 1363
+f 2748 2747 7010
+f 6451 5351 5503
+f 5172 876 878
+f 6149 6032 6151
+f 6811 7011 4685
+f 4683 6811 4685
+f 4036 5179 6326
+f 5332 5864 6586
+f 4392 4391 7012
+f 5455 7013 3493
+f 7014 7015 7016
+f 5209 7017 7018
+f 7019 6312 6577
+f 6312 6155 6577
+f 6009 3842 5854
+f 3848 3847 4420
+f 4248 4249 4436
+f 4247 4421 5713
+f 7020 7021 6918
+f 7022 6918 6819
+f 7023 7024 6920
+f 6919 7023 6920
+f 7024 7025 6921
+f 6920 7024 6921
+f 2573 1807 1957
+f 7025 761 6921
+f 6474 6476 3522
+f 7026 7027 7028
+f 7029 7030 6928
+f 7031 6041 6042
+f 7032 2237 6929
+f 4717 4719 3475
+f 7033 6454 6452
+f 6151 6166 6152
+f 6303 7034 6148
+f 3175 7035 7036
+f 3494 3687 7037
+f 6834 6932 7038
+f 4568 5446 4867
+f 7039 7040 7041
+f 6933 7042 6934
+f 7043 7044 6935
+f 6934 7043 6935
+f 7045 6936 6935
+f 7044 7045 6935
+f 7046 6937 6936
+f 7045 7046 6936
+f 7047 6938 6937
+f 7046 7047 6937
+f 7048 6939 6938
+f 7047 7048 6938
+f 7049 6942 6939
+f 7048 7049 6939
+f 7050 7051 7052
+f 3709 7053 3710
+f 1879 1835 1872
+f 7054 7055 7056
+f 1504 7057 1505
+f 7058 7059 7060
+f 3781 901 3965
+f 1506 2613 2446
+f 750 901 3598
+f 901 903 3965
+f 750 3598 3404
+f 751 750 3404
+f 1822 3780 1820
+f 901 3781 3598
+f 6846 609 6943
+f 3402 3403 1823
+f 1819 1821 6748
+f 748 601 3782
+f 6845 3785 3609
+f 1825 1924 3785
+f 7061 7062 3003
+f 7063 5368 6944
+f 7064 5170 7065
+f 7066 7067 7068
+f 7069 7070 6958
+f 6945 7069 6958
+f 7070 7071 6959
+f 6958 7070 6959
+f 7071 7072 6962
+f 6959 7071 6962
+f 7072 7073 6963
+f 6962 7072 6963
+f 7073 7074 6964
+f 6963 7073 6964
+f 7074 7075 6965
+f 6964 7074 6965
+f 7075 7076 6966
+f 6965 7075 6966
+f 7077 6967 6966
+f 7076 7077 6966
+f 7078 6968 6967
+f 7077 7078 6967
+f 7079 6969 6968
+f 7078 7079 6968
+f 7080 6970 6969
+f 7079 7080 6969
+f 7081 6971 6970
+f 7080 7081 6970
+f 7082 6972 6971
+f 7081 7082 6971
+f 7082 7083 6973
+f 6972 7082 6973
+f 7083 7084 6974
+f 6973 7083 6974
+f 7085 6975 6974
+f 7084 7085 6974
+f 7086 6976 6975
+f 7085 7086 6975
+f 7086 7087 6977
+f 6976 7086 6977
+f 7087 7088 6978
+f 6977 7087 6978
+f 7089 6979 6978
+f 7088 7089 6978
+f 7089 7090 6980
+f 6979 7089 6980
+f 7091 6981 6980
+f 7090 7091 6980
+f 7092 6982 6981
+f 7091 7092 6981
+f 7092 7093 6983
+f 6982 7092 6983
+f 7094 6984 6983
+f 7093 7094 6983
+f 7095 6985 6984
+f 7094 7095 6984
+f 7095 7096 6986
+f 6985 7095 6986
+f 7096 7097 6987
+f 6986 7096 6987
+f 7097 7098 6988
+f 6987 7097 6988
+f 7098 7099 6989
+f 6988 7098 6989
+f 7099 7100 6990
+f 6989 7099 6990
+f 7101 6991 6990
+f 7100 7101 6990
+f 7102 6992 6991
+f 7101 7102 6991
+f 7103 6993 6992
+f 7102 7103 6992
+f 7104 6994 6993
+f 7103 7104 6993
+f 4756 4755 6994
+f 7104 4756 6994
+f 1462 1461 2826
+f 7105 2147 7106
+f 2909 7107 4291
+f 911 1039 7108
+f 6049 4699 7109
+f 7110 7111 3319
+f 7112 6302 6301
+f 7113 7114 3280
+f 7033 7115 6455
+f 6454 7033 6455
+f 7115 7116 6456
+f 6455 7115 6456
+f 7117 6477 6456
+f 7116 7117 6456
+f 7118 6587 6477
+f 6999 7034 6303
+f 7034 7119 6148
+f 7011 3093 3095
+f 4685 7011 3095
+f 5864 5332 6325
+f 6319 6318 4708
+f 2880 3824 3087
+f 4705 2876 6911
+f 5067 7120 5069
+f 4374 4375 5873
+f 4373 4374 5071
+f 5069 4373 5071
+f 1658 7121 1659
+f 4236 5726 2888
+f 3669 3481 3480
+f 5472 3099 4591
+f 5712 7003 4222
+f 4222 7003 4223
+f 7122 7123 7024
+f 6919 7021 7023
+f 7123 7124 7025
+f 7024 7123 7025
+f 7124 759 761
+f 7025 7124 761
+f 7125 7126 3185
+f 7127 640 639
+f 6790 7128 7129
+f 7130 7131 7132
+f 6904 6903 6929
+f 7133 2165 2167
+f 7117 7118 6477
+f 7134 6589 6587
+f 6148 7119 6145
+f 6152 6999 6303
+f 7035 5220 7036
+f 7135 7136 4726
+f 6792 5446 4568
+f 4708 6792 4568
+f 4433 5499 7137
+f 7138 6469 7139
+f 7140 7141 7044
+f 7142 7043 7042
+f 7141 7143 7045
+f 7044 7141 7045
+f 7143 7144 7046
+f 7045 7143 7046
+f 7145 7047 7046
+f 7144 7145 7046
+f 7146 7048 7047
+f 7145 7146 7047
+f 7146 7147 7049
+f 7048 7146 7049
+f 7147 7050 7052
+f 7049 7147 7052
+f 7050 7148 7051
+f 7149 7051 7150
+f 7151 7152 7153
+f 4927 4926 3548
+f 1963 3781 2026
+f 3965 3779 1969
+f 3779 3780 1822
+f 2026 3965 1969
+f 1820 3402 1823
+f 1969 3779 1822
+f 6943 748 3782
+f 3403 3199 1824
+f 3783 1819 6748
+f 601 1957 1806
+f 3608 6845 3609
+f 1821 1825 6845
+f 3019 2451 3788
+f 3785 3787 3786
+f 5940 5939 6492
+f 2281 2283 3971
+f 7154 7155 7069
+f 7156 7157 7068
+f 7155 7158 7070
+f 7069 7155 7070
+f 7158 7159 7071
+f 7070 7158 7071
+f 7159 7160 7072
+f 7071 7159 7072
+f 7160 7161 7073
+f 7072 7160 7073
+f 7161 7162 7074
+f 7073 7161 7074
+f 7162 7163 7075
+f 7074 7162 7075
+f 7164 7076 7075
+f 7163 7164 7075
+f 7165 7077 7076
+f 7164 7165 7076
+f 7166 7078 7077
+f 7165 7166 7077
+f 7167 7079 7078
+f 7166 7167 7078
+f 7168 7080 7079
+f 7167 7168 7079
+f 7169 7081 7080
+f 7168 7169 7080
+f 7169 7170 7082
+f 7081 7169 7082
+f 7170 7171 7083
+f 7082 7170 7083
+f 7171 7172 7084
+f 7083 7171 7084
+f 7173 7085 7084
+f 7172 7173 7084
+f 7174 7086 7085
+f 7173 7174 7085
+f 7174 7175 7087
+f 7086 7174 7087
+f 7176 7088 7087
+f 7175 7176 7087
+f 7177 7089 7088
+f 7176 7177 7088
+f 7177 7178 7090
+f 7089 7177 7090
+f 7178 7179 7091
+f 7090 7178 7091
+f 7179 7180 7092
+f 7091 7179 7092
+f 7180 7181 7093
+f 7092 7180 7093
+f 7181 7182 7094
+f 7093 7181 7094
+f 7182 7183 7095
+f 7094 7182 7095
+f 7183 7184 7096
+f 7095 7183 7096
+f 7184 7185 7097
+f 7096 7184 7097
+f 7185 7186 7098
+f 7097 7185 7098
+f 7186 7187 7099
+f 7098 7186 7099
+f 7187 7188 7100
+f 7099 7187 7100
+f 7188 7189 7101
+f 7100 7188 7101
+f 7190 7102 7101
+f 7189 7190 7101
+f 7191 7103 7102
+f 7190 7191 7102
+f 7192 7104 7103
+f 7191 7192 7103
+f 7193 4756 7104
+f 7192 7193 7104
+f 7193 7194 7195
+f 7193 7195 4756
+f 7196 7197 7198
+f 7199 7200 7201
+f 7202 7203 6580
+f 7198 7199 7201
+f 7204 7205 7206
+f 7207 7208 7209
+f 3257 3480 5329
+f 7118 7134 6587
+f 7210 6590 6589
+f 7134 7210 6589
+f 7211 6593 6590
+f 7210 7211 6590
+f 7212 3701 3703
+f 7213 7214 4907
+f 7211 3919 6593
+f 6008 4915 3842
+f 4905 7213 4907
+f 3642 6435 6793
+f 3853 5041 4425
+f 2876 2694 6911
+f 6435 6434 6793
+f 4712 6319 4713
+f 2777 7215 7216
+f 5066 7217 5067
+f 7120 4373 5069
+f 3122 3327 5205
+f 3567 3630 3568
+f 4437 3852 3854
+f 5158 5157 5474
+f 5183 5040 3853
+f 1941 2074 2166
+f 7218 7219 7122
+f 7023 7122 7024
+f 7220 7221 7124
+f 7123 7220 7124
+f 7221 7222 759
+f 7124 7221 759
+f 7223 640 7224
+f 7222 7225 759
+f 7226 7227 7228
+f 3553 7229 7230
+f 7231 2226 2225
+f 7232 7233 7234
+f 2227 7235 7236
+f 3001 3000 7237
+f 7238 7239 7240
+f 7214 7241 4908
+f 7242 7213 4905
+f 7243 7244 7245
+f 3177 5860 3067
+f 4614 1637 7246
+f 4970 7247 4971
+f 7248 7249 7140
+f 7043 7140 7044
+f 7249 7250 7141
+f 7140 7249 7141
+f 7250 7251 7143
+f 7141 7250 7143
+f 7251 7252 7144
+f 7143 7251 7144
+f 7253 7145 7144
+f 7252 7253 7144
+f 7254 7146 7145
+f 7253 7254 7145
+f 7254 7255 7147
+f 7146 7254 7147
+f 7255 7256 7050
+f 7147 7255 7050
+f 7256 7257 7148
+f 7050 7256 7148
+f 7257 7152 7151
+f 7148 7257 7151
+f 7152 7258 7153
+f 7259 7260 6360
+f 7258 7261 7262
+f 7262 7261 7263
+f 7261 7264 7263
+f 4397 7265 4398
+f 7264 7266 3433
+f 7266 3431 3433
+f 7266 7267 3431
+f 7268 3431 7267
+f 7267 7269 7268
+f 7268 7270 7271
+f 7269 7272 7270
+f 7270 7273 7271
+f 7272 7274 7154
+f 7270 7272 7154
+f 7274 7275 7155
+f 7154 7274 7155
+f 7275 7276 7158
+f 7155 7275 7158
+f 7277 7159 7158
+f 7276 7277 7158
+f 7278 7160 7159
+f 7277 7278 7159
+f 7278 7279 7161
+f 7160 7278 7161
+f 7279 7280 7162
+f 7161 7279 7162
+f 7280 7281 7163
+f 7162 7280 7163
+f 7282 7164 7163
+f 7281 7282 7163
+f 7283 7165 7164
+f 7282 7283 7164
+f 7283 7284 7166
+f 7165 7283 7166
+f 7285 7167 7166
+f 7284 7285 7166
+f 7286 7168 7167
+f 7285 7286 7167
+f 7287 7169 7168
+f 7286 7287 7168
+f 7287 7288 7170
+f 7169 7287 7170
+f 7288 7289 7171
+f 7170 7288 7171
+f 7290 7172 7171
+f 7289 7290 7171
+f 7291 7173 7172
+f 7290 7291 7172
+f 7291 7292 7174
+f 7173 7291 7174
+f 7292 7293 7175
+f 7174 7292 7175
+f 7294 7176 7175
+f 7293 7294 7175
+f 7295 7177 7176
+f 7294 7295 7176
+f 7295 7296 7178
+f 7177 7295 7178
+f 7296 7297 7179
+f 7178 7296 7179
+f 7297 7298 7180
+f 7179 7297 7180
+f 7298 7299 7181
+f 7180 7298 7181
+f 7299 7300 7182
+f 7181 7299 7182
+f 7300 7301 7183
+f 7182 7300 7183
+f 7301 7302 7184
+f 7183 7301 7184
+f 7302 7303 7185
+f 7184 7302 7185
+f 7303 7304 7186
+f 7185 7303 7186
+f 7304 7305 7187
+f 7186 7304 7187
+f 7305 7306 7188
+f 7187 7305 7188
+f 7306 7307 7189
+f 7188 7306 7189
+f 7308 7190 7189
+f 7307 7308 7189
+f 7309 7191 7190
+f 7308 7309 7190
+f 7310 7192 7191
+f 7309 7310 7191
+f 7311 7193 7192
+f 7310 7311 7192
+f 7312 7313 7195
+f 7311 7194 7193
+f 7314 7315 7196
+f 7197 7199 7198
+f 7316 7317 7318
+f 3720 3685 1795
+f 7319 7320 7321
+f 7322 7323 7324
+f 4255 5854 5449
+f 7325 7326 7327
+f 5326 5498 7328
+f 5008 5095 6038
+f 7329 7330 7331
+f 5185 5326 5907
+f 5907 5326 7328
+f 2247 2246 7332
+f 7119 7333 6145
+f 7334 7242 5872
+f 3921 3923 7335
+f 7336 7337 4372
+f 6318 6792 4708
+f 5161 6318 6317
+f 6319 4708 4713
+f 7338 4433 7137
+f 6010 5018 6029
+f 7217 7120 5067
+f 7339 7340 7341
+f 7342 7343 7344
+f 3045 6599 3046
+f 4878 5323 3649
+f 1632 429 1633
+f 4718 4439 4716
+f 4401 3497 3080
+f 3081 2864 2873
+f 7345 7219 7346
+f 7347 7348 3508
+f 7349 7350 7222
+f 7221 7349 7222
+f 7350 7224 7225
+f 7222 7350 7225
+f 7351 7352 7353
+f 7223 7354 370
+f 7355 7356 7357
+f 2422 2424 7358
+f 6695 6694 6723
+f 7359 7360 7361
+f 2675 2995 7362
+f 3641 6445 3642
+f 7333 7334 6025
+f 6145 7333 6025
+f 7363 7364 7365
+f 7366 7367 7245
+f 7368 7369 7365
+f 7369 7368 7248
+f 7370 7371 7249
+f 7248 7370 7249
+f 7372 7250 7249
+f 7371 7372 7249
+f 7373 7251 7250
+f 7372 7373 7250
+f 7374 7252 7251
+f 7373 7374 7251
+f 7374 7375 7253
+f 7252 7374 7253
+f 7375 7376 7254
+f 7253 7375 7254
+f 7376 7377 7255
+f 7254 7376 7255
+f 7377 7378 7256
+f 7255 7377 7256
+f 7378 7379 7257
+f 7256 7378 7257
+f 7379 7380 7152
+f 7257 7379 7152
+f 7380 7381 7258
+f 7152 7380 7258
+f 7381 7382 7261
+f 7258 7381 7261
+f 7382 7383 7264
+f 7261 7382 7264
+f 7383 7384 7266
+f 7264 7383 7266
+f 7384 7385 7267
+f 7266 7384 7267
+f 7385 7386 7269
+f 7267 7385 7269
+f 7386 7387 7272
+f 7269 7386 7272
+f 7387 7388 7274
+f 7272 7387 7274
+f 7388 7389 7275
+f 7274 7388 7275
+f 7389 7390 7276
+f 7275 7389 7276
+f 7391 7277 7276
+f 7390 7391 7276
+f 7392 7278 7277
+f 7391 7392 7277
+f 7393 7279 7278
+f 7392 7393 7278
+f 7393 7394 7280
+f 7279 7393 7280
+f 7394 7395 7281
+f 7280 7394 7281
+f 7396 7282 7281
+f 7395 7396 7281
+f 7397 7283 7282
+f 7396 7397 7282
+f 7398 7284 7283
+f 7397 7398 7283
+f 7398 7399 7285
+f 7284 7398 7285
+f 7399 7400 7286
+f 7285 7399 7286
+f 7401 7287 7286
+f 7400 7401 7286
+f 7401 7402 7288
+f 7287 7401 7288
+f 7402 7403 7289
+f 7288 7402 7289
+f 7403 7404 7290
+f 7289 7403 7290
+f 7405 7291 7290
+f 7404 7405 7290
+f 7405 7406 7292
+f 7291 7405 7292
+f 7406 7407 7293
+f 7292 7406 7293
+f 7408 7294 7293
+f 7407 7408 7293
+f 7409 7295 7294
+f 7408 7409 7294
+f 7409 7410 7296
+f 7295 7409 7296
+f 7410 7411 7297
+f 7296 7410 7297
+f 7411 7412 7298
+f 7297 7411 7298
+f 7412 7413 7299
+f 7298 7412 7299
+f 7413 7414 7300
+f 7299 7413 7300
+f 7414 7415 7301
+f 7300 7414 7301
+f 7415 7416 7302
+f 7301 7415 7302
+f 7416 7417 7303
+f 7302 7416 7303
+f 7417 7418 7304
+f 7303 7417 7304
+f 7418 7419 7305
+f 7304 7418 7305
+f 7419 7420 7306
+f 7305 7419 7306
+f 7420 7421 7307
+f 7306 7420 7307
+f 7422 7308 7307
+f 7421 7422 7307
+f 7423 7309 7308
+f 7422 7423 7308
+f 7424 7310 7309
+f 7423 7424 7309
+f 7425 7311 7310
+f 7424 7425 7310
+f 7426 7427 7428
+f 7425 7429 7311
+f 7315 7197 7196
+f 4092 7430 4093
+f 7431 7432 7433
+f 3162 7434 7435
+f 7436 7437 7438
+f 7439 4166 7440
+f 7441 7325 7327
+f 2763 7442 7443
+f 7444 6147 2752
+f 7445 3581 3580
+f 3642 6445 6435
+f 4214 6177 6179
+f 7446 7447 7448
+f 6445 6205 6435
+f 6439 4903 4732
+f 5872 7242 4905
+f 2694 2696 3644
+f 7449 7450 7451
+f 5493 5498 5325
+f 6911 2694 3644
+f 5343 7452 5154
+f 6476 6616 3523
+f 5193 4443 6010
+f 5213 3256 3255
+f 5860 3177 4593
+f 7453 5725 4276
+f 5331 4048 4884
+f 7454 5047 5012
+f 4567 4607 7455
+f 4848 4847 6203
+f 6457 7112 7456
+f 7457 7456 5497
+f 7458 7459 7350
+f 7460 7461 7349
+f 7459 7462 7224
+f 7350 7459 7224
+f 7354 7223 7224
+f 7462 7354 7224
+f 7463 7464 7465
+f 6699 7466 7467
+f 7468 7469 7470
+f 7471 5756 4721
+f 7472 7473 7474
+f 6177 6180 6178
+f 1019 1021 7475
+f 1402 1261 1260
+f 6025 7334 5872
+f 3778 5647 3962
+f 3233 3232 7476
+f 4340 1705 1010
+f 890 881 4159
+f 7477 7478 7371
+f 7370 7477 7371
+f 7478 7479 7372
+f 7371 7478 7372
+f 7479 7480 7373
+f 7372 7479 7373
+f 7480 7481 7374
+f 7373 7480 7374
+f 7481 7482 7375
+f 7374 7481 7375
+f 7482 7483 7376
+f 7375 7482 7376
+f 7484 7377 7376
+f 7483 7484 7376
+f 7484 7485 7378
+f 7377 7484 7378
+f 7485 7486 7379
+f 7378 7485 7379
+f 7486 7487 7380
+f 7379 7486 7380
+f 7487 7488 7381
+f 7380 7487 7381
+f 7488 7489 7382
+f 7381 7488 7382
+f 7489 7490 7383
+f 7382 7489 7383
+f 7490 7491 7384
+f 7383 7490 7384
+f 7491 7492 7385
+f 7384 7491 7385
+f 7492 7493 7386
+f 7385 7492 7386
+f 7493 7494 7387
+f 7386 7493 7387
+f 7494 7495 7388
+f 7387 7494 7388
+f 7495 7496 7389
+f 7388 7495 7389
+f 7497 7390 7389
+f 7496 7497 7389
+f 7498 7391 7390
+f 7497 7498 7390
+f 7499 7392 7391
+f 7498 7499 7391
+f 7500 7393 7392
+f 7499 7500 7392
+f 7501 7394 7393
+f 7500 7501 7393
+f 7501 7502 7395
+f 7394 7501 7395
+f 7502 7503 7396
+f 7395 7502 7396
+f 7504 7397 7396
+f 7503 7504 7396
+f 7504 7505 7398
+f 7397 7504 7398
+f 7505 7506 7399
+f 7398 7505 7399
+f 7506 7507 7400
+f 7399 7506 7400
+f 7507 7508 7401
+f 7400 7507 7401
+f 7509 7402 7401
+f 7508 7509 7401
+f 7509 7510 7403
+f 7402 7509 7403
+f 7511 7404 7403
+f 7510 7511 7403
+f 7511 7512 7405
+f 7404 7511 7405
+f 7513 7406 7405
+f 7512 7513 7405
+f 7514 7407 7406
+f 7513 7514 7406
+f 7514 7515 7408
+f 7407 7514 7408
+f 7515 7516 7409
+f 7408 7515 7409
+f 7516 7517 7410
+f 7409 7516 7410
+f 7517 7518 7411
+f 7410 7517 7411
+f 7518 7519 7412
+f 7411 7518 7412
+f 7519 7520 7413
+f 7412 7519 7413
+f 7520 7521 7414
+f 7413 7520 7414
+f 7521 7522 7415
+f 7414 7521 7415
+f 7522 7523 7416
+f 7415 7522 7416
+f 7523 7524 7417
+f 7416 7523 7417
+f 7524 7525 7418
+f 7417 7524 7418
+f 7525 7526 7419
+f 7418 7525 7419
+f 7526 7527 7420
+f 7419 7526 7420
+f 7527 7528 7421
+f 7420 7527 7421
+f 7528 7529 7422
+f 7421 7528 7422
+f 7529 7530 7423
+f 7422 7529 7423
+f 7530 7531 7424
+f 7423 7530 7424
+f 7532 7425 7424
+f 7531 7532 7424
+f 7532 7533 7427
+f 7532 7427 7425
+f 7534 7315 7535
+f 7536 4091 7537
+f 7538 7539 7540
+f 7209 7538 7540
+f 7541 3323 4096
+f 2712 2714 4097
+f 2466 7542 7543
+f 5064 7544 5065
+f 3561 7545 7546
+f 4700 6325 3292
+f 7534 7535 6134
+f 7547 1739 7548
+f 7549 7550 7551
+f 4557 4684 5054
+f 5483 6311 5177
+f 5161 4866 6318
+f 3825 5455 3296
+f 6889 7552 6890
+f 3522 6476 3523
+f 5018 5598 6029
+f 5462 5461 7553
+f 2922 6065 6711
+f 6323 6322 7554
+f 4420 3847 4422
+f 6016 4251 4426
+f 7555 6327 7556
+f 7553 6016 4426
+f 7557 5048 5050
+f 4847 7555 7556
+f 7461 7458 7349
+f 5610 5487 6063
+f 7558 7559 7462
+f 7459 7558 7462
+f 7559 7560 7354
+f 7462 7559 7354
+f 1159 368 972
+f 7560 972 7354
+f 7561 7541 7562
+f 3736 7563 3737
+f 1118 7564 5304
+f 7565 7566 2426
+f 7567 1876 1878
+f 1403 7568 7569
+f 1846 375 377
+f 7570 7571 7572
+f 2276 2298 351
+f 265 2158 266
+f 785 784 2802
+f 7573 1950 5360
+f 7574 7575 7478
+f 7477 7574 7478
+f 7575 7576 7479
+f 7478 7575 7479
+f 7576 7577 7480
+f 7479 7576 7480
+f 7577 7578 7481
+f 7480 7577 7481
+f 7578 7579 7482
+f 7481 7578 7482
+f 7579 7580 7483
+f 7482 7579 7483
+f 7580 7581 7484
+f 7483 7580 7484
+f 7582 7485 7484
+f 7581 7582 7484
+f 7583 7486 7485
+f 7582 7583 7485
+f 7584 7487 7486
+f 7583 7584 7486
+f 7585 7488 7487
+f 7584 7585 7487
+f 7586 7489 7488
+f 7585 7586 7488
+f 7586 7587 7490
+f 7489 7586 7490
+f 7587 7588 7491
+f 7490 7587 7491
+f 7588 7589 7492
+f 7491 7588 7492
+f 7589 7590 7493
+f 7492 7589 7493
+f 7590 7591 7494
+f 7493 7590 7494
+f 7591 7592 7495
+f 7494 7591 7495
+f 7592 7593 7496
+f 7495 7592 7496
+f 7593 7594 7497
+f 7496 7593 7497
+f 7594 7595 7498
+f 7497 7594 7498
+f 7595 7596 7499
+f 7498 7595 7499
+f 7597 7500 7499
+f 7596 7597 7499
+f 7598 7501 7500
+f 7597 7598 7500
+f 7599 7502 7501
+f 7598 7599 7501
+f 7600 7503 7502
+f 7599 7600 7502
+f 7601 7504 7503
+f 7600 7601 7503
+f 7601 7602 7505
+f 7504 7601 7505
+f 7602 7603 7506
+f 7505 7602 7506
+f 7603 7604 7507
+f 7506 7603 7507
+f 7604 7605 7508
+f 7507 7604 7508
+f 7606 7509 7508
+f 7605 7606 7508
+f 7607 7510 7509
+f 7606 7607 7509
+f 7608 7511 7510
+f 7607 7608 7510
+f 7608 7609 7512
+f 7511 7608 7512
+f 7610 7513 7512
+f 7609 7610 7512
+f 7611 7514 7513
+f 7610 7611 7513
+f 7612 7515 7514
+f 7611 7612 7514
+f 7613 7516 7515
+f 7612 7613 7515
+f 7614 7517 7516
+f 7613 7614 7516
+f 7614 7615 7518
+f 7517 7614 7518
+f 7616 7519 7518
+f 7615 7616 7518
+f 7616 7617 7520
+f 7519 7616 7520
+f 7617 7618 7521
+f 7520 7617 7521
+f 7618 7619 7522
+f 7521 7618 7522
+f 7619 7620 7523
+f 7522 7619 7523
+f 7620 7621 7524
+f 7523 7620 7524
+f 7621 7622 7525
+f 7524 7621 7525
+f 7622 7623 7526
+f 7525 7622 7526
+f 7623 7624 7527
+f 7526 7623 7527
+f 7624 7625 7528
+f 7527 7624 7528
+f 7625 7626 7529
+f 7528 7625 7529
+f 7626 7627 7530
+f 7529 7626 7530
+f 7627 7628 7531
+f 7530 7627 7531
+f 7628 7629 7532
+f 7531 7628 7532
+f 2253 7630 7533
+f 7629 7533 7532
+f 7315 7314 7535
+f 4091 4093 7537
+f 7631 7632 7633
+f 7634 7110 3319
+f 6023 3116 7635
+f 7434 7636 7435
+f 2425 2424 5155
+f 7238 7637 7638
+f 3565 3557 3285
+f 7639 528 4387
+f 4907 7214 4908
+f 944 943 7640
+f 6204 7641 7642
+f 6063 6204 7642
+f 2879 6427 2880
+f 4392 4027 4393
+f 7643 7644 7645
+f 5030 1094 1093
+f 7646 7647 7648
+f 7649 4913 5322
+f 7650 7651 1100
+f 7647 3671 5033
+f 3481 4883 3482
+f 3466 3468 5203
+f 3665 4246 4249
+f 4052 6029 4426
+f 7555 7652 7653
+f 6327 7555 7653
+f 5349 4737 5462
+f 6907 4910 6439
+f 1164 1630 1496
+f 7654 7459 7458
+f 7655 7656 7560
+f 7559 7655 7560
+f 7656 973 972
+f 7560 7656 972
+f 6160 7657 7658
+f 1160 971 7659
+f 7660 7661 7234
+f 6023 7635 6024
+f 7662 7663 7664
+f 4242 7665 5182
+f 367 356 358
+f 329 1395 1407
+f 534 3600 376
+f 4146 4318 6495
+f 918 631 1292
+f 7666 7667 7668
+f 7669 2672 3509
+f 3281 7670 6073
+f 7671 7672 7576
+f 7575 7671 7576
+f 7672 7673 7577
+f 7576 7672 7577
+f 7673 7674 7578
+f 7577 7673 7578
+f 7674 7675 7579
+f 7578 7674 7579
+f 7675 7676 7580
+f 7579 7675 7580
+f 7677 7581 7580
+f 7676 7677 7580
+f 7678 7582 7581
+f 7677 7678 7581
+f 7679 7583 7582
+f 7678 7679 7582
+f 7680 7584 7583
+f 7679 7680 7583
+f 7681 7585 7584
+f 7680 7681 7584
+f 7682 7586 7585
+f 7681 7682 7585
+f 7683 7587 7586
+f 7682 7683 7586
+f 7684 7588 7587
+f 7683 7684 7587
+f 7684 7685 7589
+f 7588 7684 7589
+f 7686 7590 7589
+f 7685 7686 7589
+f 7687 7591 7590
+f 7686 7687 7590
+f 7688 7592 7591
+f 7687 7688 7591
+f 7689 7593 7592
+f 7688 7689 7592
+f 7689 7690 7594
+f 7593 7689 7594
+f 7690 7691 7595
+f 7594 7690 7595
+f 7692 7596 7595
+f 7691 7692 7595
+f 7693 7597 7596
+f 7692 7693 7596
+f 7694 7598 7597
+f 7693 7694 7597
+f 7695 7599 7598
+f 7694 7695 7598
+f 7696 7600 7599
+f 7695 7696 7599
+f 7697 7601 7600
+f 7696 7697 7600
+f 7697 7698 7602
+f 7601 7697 7602
+f 7698 7699 7603
+f 7602 7698 7603
+f 7699 7700 7604
+f 7603 7699 7604
+f 7700 7701 7605
+f 7604 7700 7605
+f 7702 7606 7605
+f 7701 7702 7605
+f 7703 7607 7606
+f 7702 7703 7606
+f 7703 7704 7608
+f 7607 7703 7608
+f 7704 7705 7609
+f 7608 7704 7609
+f 7705 7706 7610
+f 7609 7705 7610
+f 7707 7611 7610
+f 7706 7707 7610
+f 7708 7612 7611
+f 7707 7708 7611
+f 7709 7613 7612
+f 7708 7709 7612
+f 7710 7614 7613
+f 7709 7710 7613
+f 7711 7615 7614
+f 7710 7711 7614
+f 7712 7616 7615
+f 7711 7712 7615
+f 7713 7617 7616
+f 7712 7713 7616
+f 7713 7714 7618
+f 7617 7713 7618
+f 7714 7715 7619
+f 7618 7714 7619
+f 7715 7716 7620
+f 7619 7715 7620
+f 7716 7717 7621
+f 7620 7716 7621
+f 7717 7718 7622
+f 7621 7717 7622
+f 7718 7719 7623
+f 7622 7718 7623
+f 7719 7720 7624
+f 7623 7719 7624
+f 7720 7721 7625
+f 7624 7720 7625
+f 7721 7722 7626
+f 7625 7721 7626
+f 7722 7723 7627
+f 7626 7722 7627
+f 7723 7724 7628
+f 7627 7723 7628
+f 2254 7629 7628
+f 7724 2254 7628
+f 2253 2252 7725
+f 2254 2253 7629
+f 7726 7534 6134
+f 7727 7536 7728
+f 7729 3830 7730
+f 7203 7729 7730
+f 7109 4699 7731
+f 7732 7733 7734
+f 7735 7736 7737
+f 7738 7739 7740
+f 6296 6144 7002
+f 4880 7741 4282
+f 7005 7003 5712
+f 6204 6203 7641
+f 4574 3670 4047
+f 4227 5615 4584
+f 6203 7742 7641
+f 4565 5030 1093
+f 4226 5615 4227
+f 3477 5869 5886
+f 7743 5030 4565
+f 5461 6016 7553
+f 3682 4613 3683
+f 4901 4587 4585
+f 7744 7745 3634
+f 3847 7454 4422
+f 4884 4048 4050
+f 7652 7746 6462
+f 7653 7652 6462
+f 5497 6202 5021
+f 7641 7742 3557
+f 7747 2534 7748
+f 4431 3276 4432
+f 7749 7750 7656
+f 7655 7749 7656
+f 7750 7751 973
+f 7656 7750 973
+f 7659 7752 1160
+f 7751 7659 973
+f 7753 7754 7755
+f 5903 7756 5764
+f 2579 7757 2755
+f 7758 2923 2925
+f 7759 2122 4592
+f 7760 7761 7474
+f 245 4146 6495
+f 242 4147 244
+f 366 356 367
+f 2298 289 351
+f 1523 1522 931
+f 274 7762 7763
+f 6504 6503 7009
+f 7764 7765 473
+f 7766 2054 7767
+f 7768 7769 7770
+f 7771 7772 7674
+f 7673 7771 7674
+f 7772 7773 7675
+f 7674 7772 7675
+f 7774 7676 7675
+f 7773 7774 7675
+f 7774 7775 7677
+f 7676 7774 7677
+f 7776 7678 7677
+f 7775 7776 7677
+f 7777 7679 7678
+f 7776 7777 7678
+f 7778 7680 7679
+f 7777 7778 7679
+f 7779 7681 7680
+f 7778 7779 7680
+f 7780 7682 7681
+f 7779 7780 7681
+f 7781 7683 7682
+f 7780 7781 7682
+f 7782 7684 7683
+f 7781 7782 7683
+f 7783 7685 7684
+f 7782 7783 7684
+f 7784 7686 7685
+f 7783 7784 7685
+f 7784 7785 7687
+f 7686 7784 7687
+f 7786 7688 7687
+f 7785 7786 7687
+f 7786 7787 7689
+f 7688 7786 7689
+f 7787 7788 7690
+f 7689 7787 7690
+f 7788 7789 7691
+f 7690 7788 7691
+f 7789 7790 7692
+f 7691 7789 7692
+f 7791 7693 7692
+f 7790 7791 7692
+f 7792 7694 7693
+f 7791 7792 7693
+f 7793 7695 7694
+f 7792 7793 7694
+f 7794 7696 7695
+f 7793 7794 7695
+f 7795 7697 7696
+f 7794 7795 7696
+f 7795 7796 7698
+f 7697 7795 7698
+f 7796 7797 7699
+f 7698 7796 7699
+f 7797 7798 7700
+f 7699 7797 7700
+f 7798 7799 7701
+f 7700 7798 7701
+f 7800 7702 7701
+f 7799 7800 7701
+f 7800 7801 7703
+f 7702 7800 7703
+f 7802 7704 7703
+f 7801 7802 7703
+f 7802 7803 7705
+f 7704 7802 7705
+f 7803 7804 7706
+f 7705 7803 7706
+f 7805 7707 7706
+f 7804 7805 7706
+f 7806 7708 7707
+f 7805 7806 7707
+f 7807 7709 7708
+f 7806 7807 7708
+f 7808 7710 7709
+f 7807 7808 7709
+f 7809 7711 7710
+f 7808 7809 7710
+f 7810 7712 7711
+f 7809 7810 7711
+f 7811 7713 7712
+f 7810 7811 7712
+f 7811 7812 7714
+f 7713 7811 7714
+f 7813 7715 7714
+f 7812 7813 7714
+f 7814 7716 7715
+f 7813 7814 7715
+f 7815 7717 7716
+f 7814 7815 7716
+f 7815 7816 7718
+f 7717 7815 7718
+f 7816 7817 7719
+f 7718 7816 7719
+f 7817 7818 7720
+f 7719 7817 7720
+f 7818 7819 7721
+f 7720 7818 7721
+f 7819 7820 7722
+f 7721 7819 7722
+f 7820 7821 7723
+f 7722 7820 7723
+f 7821 7822 7724
+f 7723 7821 7724
+f 7823 2254 7724
+f 7822 7823 7724
+f 2252 811 810
+f 7823 2252 2254
+f 7824 7825 7826
+f 6440 7827 7828
+f 4746 7829 4747
+f 2803 2115 2804
+f 3944 3946 4310
+f 6051 7830 6052
+f 7831 4703 4045
+f 2924 7832 6702
+f 5453 4139 5454
+f 7833 3315 7834
+f 5347 7835 6207
+f 7836 7837 7665
+f 7838 7556 3559
+f 6203 7556 7838
+f 7839 7840 7012
+f 3681 3680 4562
+f 4612 6433 4613
+f 4573 7743 4565
+f 5461 7841 6016
+f 7841 7649 5324
+f 7842 7843 7844
+f 3177 4589 4593
+f 3666 4054 4050
+f 5040 5595 5041
+f 6296 4705 6144
+f 7845 7115 7033
+f 7742 7838 7846
+f 5864 6325 4700
+f 3273 3278 6320
+f 7004 7742 7846
+f 3859 7847 7848
+f 7849 5614 7850
+f 7851 7852 7751
+f 7750 7851 7751
+f 7852 7752 7659
+f 7751 7852 7659
+f 5903 6019 7756
+f 1137 7853 1138
+f 2925 2924 6702
+f 7854 7855 7856
+f 6466 7857 7858
+f 5930 3147 3146
+f 4147 4145 244
+f 7859 7860 7861
+f 4145 4146 245
+f 244 4145 245
+f 7667 7862 7668
+f 2269 2479 2235
+f 275 274 7763
+f 7763 7762 1488
+f 5097 4938 427
+f 1202 5097 427
+f 1020 889 1153
+f 325 598 596
+f 7863 7864 7772
+f 7865 7866 4951
+f 7864 7867 7773
+f 7772 7864 7773
+f 7867 7868 7774
+f 7773 7867 7774
+f 7868 7869 7775
+f 7774 7868 7775
+f 7870 7776 7775
+f 7869 7870 7775
+f 7871 7777 7776
+f 7870 7871 7776
+f 7872 7778 7777
+f 7871 7872 7777
+f 7873 7779 7778
+f 7872 7873 7778
+f 7874 7780 7779
+f 7873 7874 7779
+f 7875 7781 7780
+f 7874 7875 7780
+f 7876 7782 7781
+f 7875 7876 7781
+f 7877 7783 7782
+f 7876 7877 7782
+f 7878 7784 7783
+f 7877 7878 7783
+f 7879 7785 7784
+f 7878 7879 7784
+f 7880 7786 7785
+f 7879 7880 7785
+f 7881 7787 7786
+f 7880 7881 7786
+f 7881 7882 7788
+f 7787 7881 7788
+f 7882 7883 7789
+f 7788 7882 7789
+f 7883 7884 7790
+f 7789 7883 7790
+f 7884 7885 7791
+f 7790 7884 7791
+f 7886 7792 7791
+f 7885 7886 7791
+f 7887 7793 7792
+f 7886 7887 7792
+f 7888 7794 7793
+f 7887 7888 7793
+f 7889 7795 7794
+f 7888 7889 7794
+f 7890 7796 7795
+f 7889 7890 7795
+f 7891 7797 7796
+f 7890 7891 7796
+f 7892 7798 7797
+f 7891 7892 7797
+f 7893 7799 7798
+f 7892 7893 7798
+f 7893 7894 7800
+f 7799 7893 7800
+f 7894 7895 7801
+f 7800 7894 7801
+f 7896 7802 7801
+f 7895 7896 7801
+f 7896 7897 7803
+f 7802 7896 7803
+f 7897 7898 7804
+f 7803 7897 7804
+f 7899 7805 7804
+f 7898 7899 7804
+f 7900 7806 7805
+f 7899 7900 7805
+f 7901 7807 7806
+f 7900 7901 7806
+f 7902 7808 7807
+f 7901 7902 7807
+f 7903 7809 7808
+f 7902 7903 7808
+f 7904 7810 7809
+f 7903 7904 7809
+f 7905 7811 7810
+f 7904 7905 7810
+f 7906 7812 7811
+f 7905 7906 7811
+f 7907 7813 7812
+f 7906 7907 7812
+f 7908 7814 7813
+f 7907 7908 7813
+f 7909 7815 7814
+f 7908 7909 7814
+f 7910 7816 7815
+f 7909 7910 7815
+f 7911 7817 7816
+f 7910 7911 7816
+f 7911 7912 7818
+f 7817 7911 7818
+f 7912 7913 7819
+f 7818 7912 7819
+f 7913 7914 7820
+f 7819 7913 7820
+f 7914 7915 7821
+f 7820 7914 7821
+f 7916 7822 7821
+f 7915 7916 7821
+f 7917 7823 7822
+f 7916 7917 7822
+f 7918 811 7917
+f 7823 7917 2252
+f 3359 3358 7919
+f 3555 7824 7826
+f 3333 3332 7920
+f 7921 7922 7923
+f 2964 2756 2758
+f 7924 2583 2757
+f 7925 7926 7927
+f 7928 7929 7930
+f 7832 7931 6703
+f 7932 1250 1405
+f 4845 4406 5466
+f 4287 4845 3844
+f 6314 4017 5733
+f 7742 6203 7838
+f 6327 7653 6328
+f 4700 3292 3291
+f 3047 5885 5039
+f 6436 3074 3483
+f 3074 3076 3484
+f 4913 6008 5322
+f 7649 5322 5324
+f 5876 7933 5625
+f 5201 5202 7934
+f 7935 7936 6317
+f 7647 4047 3671
+f 7937 7938 7939
+f 7121 1658 5628
+f 6182 5456 5328
+f 7665 7837 7940
+f 7838 3559 3561
+f 5881 6033 6035
+f 5488 5613 7849
+f 7846 7838 3561
+f 7941 7852 7851
+f 7942 7749 7943
+f 7941 7944 7752
+f 7852 7941 7752
+f 1138 7853 7945
+f 7752 7944 1137
+f 7929 5642 7946
+f 2196 7947 2361
+f 2753 3870 2754
+f 7948 7949 2822
+f 7950 1139 1141
+f 249 4321 241
+f 1651 5364 7951
+f 266 850 7952
+f 4152 4147 242
+f 269 2159 2158
+f 265 269 2158
+f 631 6514 1292
+f 7953 7954 6424
+f 4938 7955 592
+f 427 4938 592
+f 739 1836 1106
+f 1113 1112 2442
+f 7772 7771 7863
+f 1463 1456 7956
+f 7957 7958 7867
+f 7864 7957 7867
+f 7958 7959 7868
+f 7867 7958 7868
+f 7959 7960 7869
+f 7868 7959 7869
+f 7961 7870 7869
+f 7960 7961 7869
+f 7962 7871 7870
+f 7961 7962 7870
+f 7963 7872 7871
+f 7962 7963 7871
+f 7964 7873 7872
+f 7963 7964 7872
+f 7965 7874 7873
+f 7964 7965 7873
+f 7966 7875 7874
+f 7965 7966 7874
+f 7967 7876 7875
+f 7966 7967 7875
+f 7968 7877 7876
+f 7967 7968 7876
+f 7969 7878 7877
+f 7968 7969 7877
+f 7970 7879 7878
+f 7969 7970 7878
+f 7971 7880 7879
+f 7970 7971 7879
+f 7972 7881 7880
+f 7971 7972 7880
+f 7973 7882 7881
+f 7972 7973 7881
+f 7974 7883 7882
+f 7973 7974 7882
+f 7975 7884 7883
+f 7974 7975 7883
+f 7976 7885 7884
+f 7975 7976 7884
+f 7977 7886 7885
+f 7976 7977 7885
+f 7978 7887 7886
+f 7977 7978 7886
+f 7979 7888 7887
+f 7978 7979 7887
+f 7980 7889 7888
+f 7979 7980 7888
+f 7981 7890 7889
+f 7980 7981 7889
+f 7982 7891 7890
+f 7981 7982 7890
+f 7983 7892 7891
+f 7982 7983 7891
+f 7983 7984 7893
+f 7892 7983 7893
+f 7984 7985 7894
+f 7893 7984 7894
+f 7986 7895 7894
+f 7985 7986 7894
+f 7986 7987 7896
+f 7895 7986 7896
+f 7987 7988 7897
+f 7896 7987 7897
+f 7988 7989 7898
+f 7897 7988 7898
+f 7990 7899 7898
+f 7989 7990 7898
+f 7991 7900 7899
+f 7990 7991 7899
+f 7992 7901 7900
+f 7991 7992 7900
+f 7993 7902 7901
+f 7992 7993 7901
+f 7994 7903 7902
+f 7993 7994 7902
+f 7995 7904 7903
+f 7994 7995 7903
+f 7996 7905 7904
+f 7995 7996 7904
+f 7997 7906 7905
+f 7996 7997 7905
+f 7998 7907 7906
+f 7997 7998 7906
+f 7999 7908 7907
+f 7998 7999 7907
+f 8000 7909 7908
+f 7999 8000 7908
+f 8001 7910 7909
+f 8000 8001 7909
+f 8002 7911 7910
+f 8001 8002 7910
+f 8002 8003 7912
+f 7911 8002 7912
+f 8004 7913 7912
+f 8003 8004 7912
+f 8005 7914 7913
+f 8004 8005 7913
+f 8005 8006 7915
+f 7914 8005 7915
+f 8006 8007 7916
+f 7915 8006 7916
+f 8007 7918 7917
+f 7916 8007 7917
+f 8008 8009 6174
+f 8010 8011 7918
+f 3358 3555 7826
+f 8012 3358 7826
+f 8013 7922 7921
+f 7920 8013 7921
+f 8014 8015 8016
+f 7922 8014 7923
+f 3857 6337 3855
+f 8017 8018 8019
+f 4138 8020 8021
+f 3554 8022 3555
+f 4713 4567 7455
+f 8023 7453 4275
+f 3278 3277 8024
+f 4860 2277 2278
+f 4252 4253 4255
+f 7556 6327 3559
+f 4613 6436 3483
+f 4254 6009 5854
+f 3871 4065 2695
+f 4425 8025 6020
+f 6012 4585 4416
+f 5598 5462 6029
+f 6012 4901 4585
+f 2059 2061 8026
+f 4730 8027 4731
+f 5090 6173 4702
+f 5472 4043 4877
+f 3122 5205 3667
+f 4131 5057 4740
+f 8028 6218 8029
+f 6461 6328 7653
+f 3560 6328 8030
+f 5614 8031 7850
+f 6320 3278 3249
+f 5182 7940 5183
+f 8032 8033 4540
+f 8034 7945 7853
+f 7944 8034 7853
+f 2351 2361 2352
+f 8035 8036 8037
+f 336 338 8038
+f 5642 5644 7946
+f 8039 3194 2477
+f 245 6495 5232
+f 3018 5183 8040
+f 241 4152 242
+f 4329 4321 282
+f 286 2255 2159
+f 269 286 2159
+f 922 469 918
+f 8041 1713 1712
+f 7955 8042 593
+f 592 7955 593
+f 8043 8044 8045
+f 8046 8047 2456
+f 1464 1463 7956
+f 1517 1374 495
+f 8048 7957 7864
+f 3026 3233 1498
+f 8049 8050 8051
+f 5664 1808 1809
+f 8052 8053 7960
+f 7959 8052 7960
+f 8054 7961 7960
+f 8053 8054 7960
+f 8055 7962 7961
+f 8054 8055 7961
+f 8056 7963 7962
+f 8055 8056 7962
+f 8057 7964 7963
+f 8056 8057 7963
+f 8058 7965 7964
+f 8057 8058 7964
+f 8059 7966 7965
+f 8058 8059 7965
+f 8060 7967 7966
+f 8059 8060 7966
+f 8061 7968 7967
+f 8060 8061 7967
+f 8062 7969 7968
+f 8061 8062 7968
+f 8063 7970 7969
+f 8062 8063 7969
+f 8064 7971 7970
+f 8063 8064 7970
+f 8065 7972 7971
+f 8064 8065 7971
+f 8066 7973 7972
+f 8065 8066 7972
+f 8067 7974 7973
+f 8066 8067 7973
+f 8068 7975 7974
+f 8067 8068 7974
+f 8069 7976 7975
+f 8068 8069 7975
+f 8070 7977 7976
+f 8069 8070 7976
+f 8071 7978 7977
+f 8070 8071 7977
+f 8072 7979 7978
+f 8071 8072 7978
+f 8073 7980 7979
+f 8072 8073 7979
+f 8074 7981 7980
+f 8073 8074 7980
+f 8075 7982 7981
+f 8074 8075 7981
+f 8076 7983 7982
+f 8075 8076 7982
+f 8076 8077 7984
+f 7983 8076 7984
+f 8078 7985 7984
+f 8077 8078 7984
+f 8078 8079 7986
+f 7985 8078 7986
+f 8079 8080 7987
+f 7986 8079 7987
+f 8080 8081 7988
+f 7987 8080 7988
+f 8081 8082 7989
+f 7988 8081 7989
+f 8083 7990 7989
+f 8082 8083 7989
+f 8084 7991 7990
+f 8083 8084 7990
+f 8085 7992 7991
+f 8084 8085 7991
+f 8086 7993 7992
+f 8085 8086 7992
+f 8087 7994 7993
+f 8086 8087 7993
+f 8088 7995 7994
+f 8087 8088 7994
+f 8089 7996 7995
+f 8088 8089 7995
+f 8090 7997 7996
+f 8089 8090 7996
+f 8091 7998 7997
+f 8090 8091 7997
+f 8092 7999 7998
+f 8091 8092 7998
+f 8093 8000 7999
+f 8092 8093 7999
+f 8094 8001 8000
+f 8093 8094 8000
+f 8095 8002 8001
+f 8094 8095 8001
+f 8095 8096 8003
+f 8002 8095 8003
+f 8096 8097 8004
+f 8003 8096 8004
+f 8098 8005 8004
+f 8097 8098 8004
+f 8099 8006 8005
+f 8098 8099 8005
+f 8010 8007 8006
+f 8099 8010 8006
+f 8100 4081 3457
+f 8007 8010 7918
+f 8101 8008 8102
+f 8103 5605 5607
+f 8104 8105 8106
+f 7825 7824 8107
+f 8008 6174 8102
+f 4740 5915 5913
+f 3881 3879 3500
+f 8108 8109 8110
+f 1538 8111 5536
+f 4883 5331 4884
+f 8112 8113 8114
+f 8115 8116 7845
+f 3305 4860 2278
+f 4223 7002 6044
+f 8024 3863 8117
+f 3863 4598 8117
+f 4208 7646 7648
+f 3847 3846 7454
+f 8118 4752 4016
+f 3076 7743 4573
+f 8119 5457 5047
+f 8120 7557 8121
+f 7454 8119 5047
+f 5047 5457 5193
+f 6173 5079 4702
+f 4601 6912 5720
+f 5153 4727 5343
+f 4042 5174 4408
+f 6167 6892 6166
+f 5609 5610 6064
+f 6298 8122 8123
+f 3871 2877 3085
+f 8024 8117 3250
+f 4432 3273 6320
+f 8040 2805 2274
+f 4263 4275 4262
+f 8124 8125 7945
+f 8034 8124 7945
+f 2432 2431 8126
+f 8127 8128 8129
+f 5640 5642 7929
+f 5721 5640 7929
+f 8130 2566 2568
+f 8131 8132 8133
+f 8134 8135 8136
+f 8137 4328 8011
+f 4321 4152 241
+f 4329 282 268
+f 286 253 2433
+f 2255 286 2433
+f 7762 1489 1488
+f 8135 8138 8136
+f 8042 8139 590
+f 593 8042 590
+f 1501 326 595
+f 1447 1449 1720
+f 1675 742 1455
+f 692 1146 6650
+f 8140 2447 2609
+f 8141 8142 8143
+f 5514 5370 5369
+f 2443 2444 1592
+f 5155 6365 8144
+f 8052 8145 8053
+f 8146 8054 8053
+f 8147 8146 8053
+f 8148 8055 8054
+f 8146 8148 8054
+f 8149 8056 8055
+f 8148 8149 8055
+f 8150 8057 8056
+f 8149 8150 8056
+f 8151 8058 8057
+f 8150 8151 8057
+f 8152 8059 8058
+f 8151 8152 8058
+f 8153 8060 8059
+f 8152 8153 8059
+f 8154 8061 8060
+f 8153 8154 8060
+f 8155 8062 8061
+f 8154 8155 8061
+f 8156 8063 8062
+f 8155 8156 8062
+f 8157 8064 8063
+f 8156 8157 8063
+f 8158 8065 8064
+f 8157 8158 8064
+f 8159 8066 8065
+f 8158 8159 8065
+f 8160 8067 8066
+f 8159 8160 8066
+f 8161 8068 8067
+f 8160 8161 8067
+f 8162 8069 8068
+f 8161 8162 8068
+f 8163 8070 8069
+f 8162 8163 8069
+f 8163 8164 8071
+f 8070 8163 8071
+f 8165 8072 8071
+f 8164 8165 8071
+f 8166 8073 8072
+f 8165 8166 8072
+f 8167 8074 8073
+f 8166 8167 8073
+f 8168 8075 8074
+f 8167 8168 8074
+f 8169 8076 8075
+f 8168 8169 8075
+f 8170 8077 8076
+f 8169 8170 8076
+f 8171 8078 8077
+f 8170 8171 8077
+f 8171 8172 8079
+f 8078 8171 8079
+f 8172 8173 8080
+f 8079 8172 8080
+f 8173 8174 8081
+f 8080 8173 8081
+f 8175 8082 8081
+f 8174 8175 8081
+f 8176 8083 8082
+f 8175 8176 8082
+f 8177 8084 8083
+f 8176 8177 8083
+f 8178 8085 8084
+f 8177 8178 8084
+f 8179 8086 8085
+f 8178 8179 8085
+f 8180 8087 8086
+f 8179 8180 8086
+f 8181 8088 8087
+f 8180 8181 8087
+f 8182 8089 8088
+f 8181 8182 8088
+f 8183 8090 8089
+f 8182 8183 8089
+f 8184 8091 8090
+f 8183 8184 8090
+f 8185 8092 8091
+f 8184 8185 8091
+f 8186 8093 8092
+f 8185 8186 8092
+f 8187 8094 8093
+f 8186 8187 8093
+f 8188 8095 8094
+f 8187 8188 8094
+f 8189 8096 8095
+f 8188 8189 8095
+f 8190 8097 8096
+f 8189 8190 8096
+f 8191 8098 8097
+f 8190 8191 8097
+f 8192 8099 8098
+f 8191 8192 8098
+f 8192 8193 8010
+f 8099 8192 8010
+f 7643 8194 8195
+f 8010 8193 8011
+f 4752 3934 4016
+f 4231 5214 4720
+f 4030 4235 5349
+f 8196 4053 8197
+f 3126 3125 4743
+f 4326 8198 8199
+f 5039 5885 5887
+f 4041 3676 5174
+f 8200 8201 7116
+f 7115 8200 7116
+f 8201 8202 7117
+f 8203 8204 8205
+f 3879 3884 3500
+f 1403 7569 3691
+f 5032 3851 6015
+f 3928 3927 5015
+f 5456 4441 5457
+f 5074 5175 5014
+f 6433 6436 4613
+f 3483 3074 3484
+f 4744 8206 4075
+f 6793 5186 3680
+f 5462 7553 6029
+f 5457 4443 5193
+f 5084 5342 5313
+f 4589 5466 4590
+f 4047 3670 3671
+f 3046 3477 5885
+f 8207 8208 7745
+f 5487 6204 6063
+f 7642 7641 3556
+f 6596 6597 3371
+f 3278 8024 3249
+f 7742 7004 3557
+f 4276 4279 4277
+f 5614 8209 8031
+f 2805 8040 7940
+f 4275 4277 4262
+f 8035 8126 8210
+f 8125 8035 8210
+f 4001 7041 8211
+f 7215 2777 8212
+f 2235 2479 8213
+f 3238 2633 2635
+f 7105 7106 8214
+f 7473 7760 7474
+f 1643 8215 1644
+f 4151 4329 268
+f 4321 249 282
+f 248 2434 2433
+f 253 248 2433
+f 8216 8217 8218
+f 5460 5735 8219
+f 8139 8220 735
+f 590 8139 735
+f 1112 2108 2442
+f 1341 1071 1342
+f 1492 692 6650
+f 1516 493 492
+f 3026 2633 3238
+f 1600 659 658
+f 1761 2443 1592
+f 2444 2445 1593
+f 8221 8222 8223
+f 2058 623 536
+f 8224 8225 8146
+f 8147 8224 8146
+f 8226 8148 8146
+f 8225 8226 8146
+f 8227 8149 8148
+f 8226 8227 8148
+f 8228 8150 8149
+f 8227 8228 8149
+f 8229 8151 8150
+f 8228 8229 8150
+f 8230 8152 8151
+f 8229 8230 8151
+f 8231 8153 8152
+f 8230 8231 8152
+f 8232 8154 8153
+f 8231 8232 8153
+f 8233 8155 8154
+f 8232 8233 8154
+f 8234 8156 8155
+f 8233 8234 8155
+f 8235 8157 8156
+f 8234 8235 8156
+f 8236 8158 8157
+f 8235 8236 8157
+f 8237 8159 8158
+f 8236 8237 8158
+f 8238 8160 8159
+f 8237 8238 8159
+f 8239 8161 8160
+f 8238 8239 8160
+f 8240 8162 8161
+f 8239 8240 8161
+f 8241 8163 8162
+f 8240 8241 8162
+f 8241 8242 8164
+f 8163 8241 8164
+f 8243 8165 8164
+f 8242 8243 8164
+f 8244 8166 8165
+f 8243 8244 8165
+f 8245 8167 8166
+f 8244 8245 8166
+f 8246 8168 8167
+f 8245 8246 8167
+f 8247 8169 8168
+f 8246 8247 8168
+f 8248 8170 8169
+f 8247 8248 8169
+f 8248 8249 8171
+f 8170 8248 8171
+f 8249 8250 8172
+f 8171 8249 8172
+f 8251 8173 8172
+f 8250 8251 8172
+f 8252 8174 8173
+f 8251 8252 8173
+f 8253 8175 8174
+f 8252 8253 8174
+f 8253 8254 8176
+f 8175 8253 8176
+f 8254 8255 8177
+f 8176 8254 8177
+f 8256 8178 8177
+f 8255 8256 8177
+f 8257 8179 8178
+f 8256 8257 8178
+f 8258 8180 8179
+f 8257 8258 8179
+f 8259 8181 8180
+f 8258 8259 8180
+f 8260 8182 8181
+f 8259 8260 8181
+f 8261 8183 8182
+f 8260 8261 8182
+f 8262 8184 8183
+f 8261 8262 8183
+f 8263 8185 8184
+f 8262 8263 8184
+f 8264 8186 8185
+f 8263 8264 8185
+f 8265 8187 8186
+f 8264 8265 8186
+f 8266 8188 8187
+f 8265 8266 8187
+f 8267 8189 8188
+f 8266 8267 8188
+f 8268 8190 8189
+f 8267 8268 8189
+f 8269 8191 8190
+f 8268 8269 8190
+f 8270 8192 8191
+f 8269 8270 8191
+f 8270 8271 8193
+f 8192 8270 8193
+f 8272 7561 8273
+f 8193 8271 8137
+f 3484 3076 4573
+f 6434 6433 4612
+f 8274 3353 8275
+f 4039 3469 5723
+f 8276 8277 8278
+f 8279 4617 8280
+f 8281 5198 8282
+f 8283 8284 8021
+f 7116 8201 7117
+f 8285 7118 7117
+f 8286 8287 8288
+f 7003 7002 4223
+f 8202 8285 7117
+f 4259 3636 3635
+f 5089 3495 4401
+f 8289 4031 5026
+f 8290 5481 5171
+f 4865 5447 4866
+f 6159 5732 5157
+f 4561 6434 4612
+f 4578 6793 3680
+f 7841 5324 6016
+f 4443 5018 6010
+f 4265 5453 8291
+f 5079 4574 4046
+f 3676 4608 5174
+f 3846 8119 7454
+f 6623 4427 4232
+f 2697 4277 5445
+f 5868 2874 2692
+f 8292 8293 649
+f 7642 3556 3374
+f 5319 5486 5610
+f 7850 8031 7932
+f 8294 7642 3374
+f 5613 5614 7849
+f 5171 5481 5172
+f 6308 8295 6640
+f 8035 8125 8296
+f 8297 7215 8212
+f 8126 8297 8212
+f 7757 2964 2758
+f 2775 8298 8299
+f 2755 7757 2758
+f 8300 8301 1549
+f 3970 3969 8302
+f 2605 247 2778
+f 539 1940 1939
+f 248 247 2605
+f 250 2982 2778
+f 2434 248 2605
+f 247 243 2778
+f 7569 8303 3691
+f 1381 1645 5364
+f 8220 8304 737
+f 735 8220 737
+f 2194 954 6512
+f 1063 216 1064
+f 1146 608 607
+f 7956 1456 1458
+f 8305 8306 8307
+f 2477 3194 2478
+f 1592 2444 1593
+f 2445 2262 1596
+f 8308 8309 8310
+f 1435 2058 536
+f 1378 2245 2637
+f 8311 383 385
+f 8312 8226 8225
+f 8313 8312 8225
+f 8314 8227 8226
+f 8312 8314 8226
+f 8315 8228 8227
+f 8314 8315 8227
+f 8316 8229 8228
+f 8315 8316 8228
+f 8317 8230 8229
+f 8316 8317 8229
+f 8318 8231 8230
+f 8317 8318 8230
+f 8319 8232 8231
+f 8318 8319 8231
+f 8320 8233 8232
+f 8319 8320 8232
+f 8321 8234 8233
+f 8320 8321 8233
+f 8322 8235 8234
+f 8321 8322 8234
+f 8323 8236 8235
+f 8322 8323 8235
+f 8324 8237 8236
+f 8323 8324 8236
+f 8325 8238 8237
+f 8324 8325 8237
+f 8326 8239 8238
+f 8325 8326 8238
+f 8327 8240 8239
+f 8326 8327 8239
+f 8328 8241 8240
+f 8327 8328 8240
+f 8329 8242 8241
+f 8328 8329 8241
+f 8330 8243 8242
+f 8329 8330 8242
+f 8331 8244 8243
+f 8330 8331 8243
+f 8332 8245 8244
+f 8331 8332 8244
+f 8333 8246 8245
+f 8332 8333 8245
+f 8333 8334 8247
+f 8246 8333 8247
+f 8334 8335 8248
+f 8247 8334 8248
+f 8335 8336 8249
+f 8248 8335 8249
+f 8336 8337 8250
+f 8249 8336 8250
+f 8338 8251 8250
+f 8337 8338 8250
+f 8339 8252 8251
+f 8338 8339 8251
+f 8340 8253 8252
+f 8339 8340 8252
+f 8340 8341 8254
+f 8253 8340 8254
+f 8341 8342 8255
+f 8254 8341 8255
+f 8343 8256 8255
+f 8342 8343 8255
+f 8344 8257 8256
+f 8343 8344 8256
+f 8345 8258 8257
+f 8344 8345 8257
+f 8346 8259 8258
+f 8345 8346 8258
+f 8347 8260 8259
+f 8346 8347 8259
+f 8348 8261 8260
+f 8347 8348 8260
+f 8349 8262 8261
+f 8348 8349 8261
+f 8350 8263 8262
+f 8349 8350 8262
+f 8351 8264 8263
+f 8350 8351 8263
+f 8352 8265 8264
+f 8351 8352 8264
+f 8353 8266 8265
+f 8352 8353 8265
+f 8354 8267 8266
+f 8353 8354 8266
+f 8355 8268 8267
+f 8354 8355 8267
+f 8356 8269 8268
+f 8355 8356 8268
+f 8357 8270 8269
+f 8356 8357 8269
+f 8358 8359 8360
+f 8270 8357 8271
+f 8361 8362 8363
+f 5731 8364 8365
+f 8366 3667 4444
+f 8367 392 8368
+f 8275 3355 8369
+f 3750 8370 8369
+f 7330 8371 8372
+f 6339 8373 6340
+f 6063 7642 8294
+f 8374 8375 8376
+f 8377 7134 7118
+f 8285 8377 7118
+f 8378 7210 7134
+f 8377 8378 7134
+f 8303 6142 3691
+f 6064 8294 6597
+f 8379 3856 3855
+f 4958 4957 8380
+f 5156 6159 5157
+f 5165 5334 5166
+f 4579 4578 3679
+f 6793 6434 4561
+f 8381 8382 7761
+f 2578 2580 2601
+f 4383 4384 6803
+f 4415 5728 4260
+f 7924 2581 2583
+f 4246 5092 3848
+f 5485 4051 8196
+f 3485 3484 4572
+f 4053 4250 8197
+f 6702 7832 6703
+f 4258 4413 4709
+f 3451 8383 3452
+f 7641 3557 3556
+f 8294 3374 3373
+f 6902 8384 6903
+f 4384 5600 6448
+f 8385 8386 6698
+f 5021 6202 5488
+f 8387 8388 7215
+f 8297 8387 7215
+f 8299 8389 8390
+f 7215 8388 7216
+f 8391 3740 6703
+f 2594 8392 8393
+f 5484 5011 5302
+f 8394 8395 4155
+f 3962 8394 4155
+f 1950 1951 5360
+f 1529 1950 7573
+f 1382 1381 5363
+f 5361 1382 5363
+f 5363 1381 5364
+f 8396 8397 8398
+f 8304 7573 887
+f 737 8304 887
+f 977 1719 978
+f 1714 1050 1049
+f 1310 1516 492
+f 439 1521 1952
+f 327 2632 2614
+f 1613 1227 1222
+f 1593 2445 1596
+f 2262 2636 1598
+f 7858 2594 8393
+f 3784 3783 6750
+f 3602 1760 3407
+f 8399 8312 8313
+f 8400 8401 3456
+f 8402 8314 8312
+f 8399 8402 8312
+f 8403 8315 8314
+f 8402 8403 8314
+f 8404 8316 8315
+f 8403 8404 8315
+f 8405 8317 8316
+f 8404 8405 8316
+f 8406 8318 8317
+f 8405 8406 8317
+f 8407 8319 8318
+f 8406 8407 8318
+f 8408 8320 8319
+f 8407 8408 8319
+f 8409 8321 8320
+f 8408 8409 8320
+f 8410 8322 8321
+f 8409 8410 8321
+f 8411 8323 8322
+f 8410 8411 8322
+f 8412 8324 8323
+f 8411 8412 8323
+f 8413 8325 8324
+f 8412 8413 8324
+f 8414 8326 8325
+f 8413 8414 8325
+f 8415 8327 8326
+f 8414 8415 8326
+f 8416 8328 8327
+f 8415 8416 8327
+f 8417 8329 8328
+f 8416 8417 8328
+f 8417 8418 8330
+f 8329 8417 8330
+f 8418 8419 8331
+f 8330 8418 8331
+f 8419 8420 8332
+f 8331 8419 8332
+f 8420 8421 8333
+f 8332 8420 8333
+f 8421 8422 8334
+f 8333 8421 8334
+f 8422 8423 8335
+f 8334 8422 8335
+f 8423 8424 8336
+f 8335 8423 8336
+f 8424 8425 8337
+f 8336 8424 8337
+f 8426 8338 8337
+f 8425 8426 8337
+f 8427 8339 8338
+f 8426 8427 8338
+f 8428 8340 8339
+f 8427 8428 8339
+f 8428 8429 8341
+f 8340 8428 8341
+f 8429 8430 8342
+f 8341 8429 8342
+f 8431 8343 8342
+f 8430 8431 8342
+f 8431 8432 8344
+f 8343 8431 8344
+f 8432 8433 8345
+f 8344 8432 8345
+f 8434 8346 8345
+f 8433 8434 8345
+f 8435 8347 8346
+f 8434 8435 8346
+f 8436 8348 8347
+f 8435 8436 8347
+f 8437 8349 8348
+f 8436 8437 8348
+f 8438 8350 8349
+f 8437 8438 8349
+f 8439 8351 8350
+f 8438 8439 8350
+f 8440 8352 8351
+f 8439 8440 8351
+f 8440 8441 8353
+f 8352 8440 8353
+f 8442 8354 8353
+f 8441 8442 8353
+f 8443 8355 8354
+f 8442 8443 8354
+f 8444 8356 8355
+f 8443 8444 8355
+f 5522 8357 8356
+f 8444 5522 8356
+f 8445 514 832
+f 6430 7732 8446
+f 5205 5204 4444
+f 2217 8447 2218
+f 8448 8449 8450
+f 5204 3735 4444
+f 8451 8452 8453
+f 1320 4690 8454
+f 8455 8456 8457
+f 7331 7330 8458
+f 6064 6063 8294
+f 7563 6162 3737
+f 4447 8459 8460
+f 8461 7211 7210
+f 8378 8461 7210
+f 8462 5441 5440
+f 5717 6064 6597
+f 4686 5870 5055
+f 4220 8463 6031
+f 5041 5595 5597
+f 4596 6012 5335
+f 6300 5165 5167
+f 4034 3096 3098
+f 5186 6793 4561
+f 5041 5597 8025
+f 4019 5593 3845
+f 3069 3070 3275
+f 6450 3476 6015
+f 3101 6007 8464
+f 3851 3850 6014
+f 8465 6007 4037
+f 6007 4038 4037
+f 4573 4565 4542
+f 3681 4562 4040
+f 8466 7951 775
+f 5324 4253 4251
+f 6597 8294 3373
+f 6597 3373 3371
+f 6188 8467 8468
+f 6311 6701 5177
+f 4045 4702 4046
+f 4593 8469 8470
+f 8037 8387 8297
+f 2427 2426 8471
+f 8472 8389 8298
+f 8388 8472 8298
+f 4448 4447 8460
+f 8473 8474 3016
+f 8459 8475 8476
+f 4155 8395 4630
+f 8395 8477 4630
+f 8304 1529 7573
+f 1530 1529 8304
+f 1223 5360 1343
+f 1343 5361 1234
+f 7573 5360 1223
+f 5361 5363 1234
+f 887 7573 1223
+f 5360 5361 1343
+f 8478 8479 1955
+f 1042 1170 1043
+f 1457 1841 1840
+f 2106 614 616
+f 3194 1609 2478
+f 367 446 1345
+f 1596 2262 1598
+f 2636 2302 1599
+f 8480 3784 6750
+f 3202 3406 8481
+f 8482 8483 8313
+f 1293 1958 1029
+f 8484 8402 8399
+f 8485 8484 8399
+f 8486 8403 8402
+f 8484 8486 8402
+f 8487 8404 8403
+f 8486 8487 8403
+f 8488 8405 8404
+f 8487 8488 8404
+f 8489 8406 8405
+f 8488 8489 8405
+f 8490 8407 8406
+f 8489 8490 8406
+f 8491 8408 8407
+f 8490 8491 8407
+f 8492 8409 8408
+f 8491 8492 8408
+f 8493 8410 8409
+f 8492 8493 8409
+f 8494 8411 8410
+f 8493 8494 8410
+f 8495 8412 8411
+f 8494 8495 8411
+f 8496 8413 8412
+f 8495 8496 8412
+f 8496 8497 8414
+f 8413 8496 8414
+f 8497 8498 8415
+f 8414 8497 8415
+f 8499 8416 8415
+f 8498 8499 8415
+f 8500 8501 8502
+f 8416 8499 8417
+f 7770 8503 8504
+f 8505 8506 3015
+f 8507 8508 8509
+f 2343 2519 2344
+f 8419 8510 8420
+f 8418 8511 8419
+f 1972 6651 8512
+f 8510 8513 8420
+f 8513 8514 8421
+f 8223 8214 5065
+f 8515 8516 8517
+f 8514 8518 8422
+f 8518 8519 8423
+f 2992 8520 2176
+f 8521 8425 8424
+f 8522 8521 8424
+f 8521 8523 8426
+f 8425 8521 8426
+f 8523 8524 8427
+f 8426 8523 8427
+f 8524 8525 8428
+f 8427 8524 8428
+f 8525 8526 8429
+f 8428 8525 8429
+f 8526 8527 8430
+f 8429 8526 8430
+f 8527 8528 8431
+f 8430 8527 8431
+f 8528 8529 8432
+f 8431 8528 8432
+f 8529 8530 8433
+f 8432 8529 8433
+f 8530 8531 8434
+f 8433 8530 8434
+f 8532 8435 8434
+f 8531 8532 8434
+f 8533 8436 8435
+f 8532 8533 8435
+f 8534 8437 8436
+f 8533 8534 8436
+f 8535 8438 8437
+f 8534 8535 8437
+f 8536 8439 8438
+f 8535 8536 8438
+f 8537 8440 8439
+f 8536 8537 8439
+f 8538 8441 8440
+f 8537 8538 8440
+f 8539 8442 8441
+f 8538 8539 8441
+f 8540 8443 8442
+f 8539 8540 8442
+f 8541 8444 8443
+f 8540 8541 8443
+f 515 5522 8444
+f 8541 515 8444
+f 8542 8543 8544
+f 8126 8212 2432
+f 7760 8381 7761
+f 6709 3736 3735
+f 8545 8546 3525
+f 2715 2717 8547
+f 8548 6705 3120
+f 7939 7938 8549
+f 8457 8550 8551
+f 8550 8552 8551
+f 534 8553 1831
+f 8554 8555 8556
+f 6640 6698 6641
+f 6491 8557 8558
+f 8559 8560 8561
+f 8418 8417 8562
+f 5466 4044 4590
+f 8561 8563 8559
+f 5880 7056 6033
+f 4421 4424 4870
+f 3930 4744 4075
+f 4594 4901 6012
+f 5217 3098 5590
+f 3096 4744 3930
+f 6165 3542 8564
+f 5217 5590 5218
+f 6916 6580 6582
+f 5178 5314 1353
+f 6448 5628 3932
+f 5153 5343 5154
+f 4245 4244 4438
+f 3488 3490 4287
+f 5599 7121 5628
+f 5743 4899 8365
+f 5487 4848 6204
+f 4877 4042 4408
+f 3249 8024 3250
+f 4847 7556 6203
+f 8117 6708 3250
+f 6708 3370 3250
+f 6708 6596 3370
+f 6596 3371 3370
+f 1100 7651 3131
+f 8565 8472 8566
+f 4001 8211 5665
+f 8389 8567 8390
+f 8460 8459 8476
+f 468 467 1844
+f 8568 418 420
+f 8569 8562 8417
+f 8220 1530 8304
+f 1684 1530 8220
+f 1234 5363 1651
+f 8570 8571 8572
+f 1618 1617 1715
+f 1655 7567 1656
+f 5356 8573 8574
+f 1983 8575 8576
+f 216 215 1064
+f 5357 5356 8577
+f 1458 1457 1840
+f 6650 1146 607
+f 452 2299 2301
+f 3201 1978 1071
+f 1598 2636 1599
+f 2302 2142 1666
+f 8578 8579 8382
+f 3406 3599 8580
+f 3204 1594 1826
+f 1022 1293 1029
+f 8581 3406 8580
+f 8485 5251 8484
+f 8582 8583 8584
+f 8585 8486 8484
+f 8586 8585 8484
+f 8587 8487 8486
+f 8585 8587 8486
+f 8588 8488 8487
+f 8587 8588 8487
+f 8589 8489 8488
+f 8588 8589 8488
+f 8590 8490 8489
+f 8589 8590 8489
+f 8591 8491 8490
+f 8590 8591 8490
+f 8591 8592 8492
+f 8491 8591 8492
+f 8592 8593 8493
+f 8492 8592 8493
+f 8593 8594 8494
+f 8493 8593 8494
+f 8594 8595 8495
+f 8494 8594 8495
+f 8595 8596 8496
+f 8495 8595 8496
+f 8596 8597 8497
+f 8496 8596 8497
+f 8597 8598 8498
+f 8497 8597 8498
+f 8599 8600 8601
+f 6786 2950 8602
+f 8603 1241 1243
+f 3782 1806 1805
+f 8604 8605 8606
+f 8607 8604 8606
+f 8608 8609 8508
+f 8610 8507 8509
+f 8611 8612 3926
+f 1496 8613 1165
+f 8614 8615 274
+f 273 8614 274
+f 3713 7467 4076
+f 2304 911 7108
+f 8616 8515 8517
+f 8617 8618 8619
+f 8620 8621 8622
+f 8621 8623 8622
+f 8624 8625 8626
+f 376 3600 8627
+f 8628 8523 8521
+f 8629 8630 8631
+f 8632 8524 8523
+f 8628 8632 8523
+f 8632 8633 8525
+f 8524 8632 8525
+f 8633 8634 8526
+f 8525 8633 8526
+f 8634 8635 8527
+f 8526 8634 8527
+f 8635 8636 8528
+f 8527 8635 8528
+f 8636 8637 8529
+f 8528 8636 8529
+f 8637 8638 8530
+f 8529 8637 8530
+f 8639 8531 8530
+f 8638 8639 8530
+f 8640 8532 8531
+f 8639 8640 8531
+f 8641 8533 8532
+f 8640 8641 8532
+f 8642 8534 8533
+f 8641 8642 8533
+f 8643 8535 8534
+f 8642 8643 8534
+f 8644 8536 8535
+f 8643 8644 8535
+f 8645 8537 8536
+f 8644 8645 8536
+f 8646 8538 8537
+f 8645 8646 8537
+f 8647 8539 8538
+f 8646 8647 8538
+f 8648 8540 8539
+f 8647 8648 8539
+f 8649 8541 8540
+f 8648 8649 8540
+f 8649 513 515
+f 8541 8649 515
+f 8650 8651 8652
+f 8653 8654 3190
+f 8381 8578 8382
+f 8655 8656 8579
+f 8657 8658 8659
+f 8660 8657 8659
+f 7857 6466 6465
+f 2721 8548 3120
+f 1988 7932 1989
+f 8661 3364 3363
+f 8662 8663 8664
+f 1008 8665 8666
+f 7434 8667 7636
+f 4117 4127 8020
+f 5443 4047 7647
+f 4268 7036 4266
+f 4423 6026 5718
+f 4424 4423 5718
+f 4233 3951 4095
+f 3643 4207 5323
+f 964 6702 965
+f 5885 3477 5886
+f 8206 6814 4075
+f 3010 8668 3011
+f 5592 4572 4541
+f 8669 8670 3317
+f 5343 5344 6449
+f 5213 3668 3256
+f 4608 5627 5174
+f 7006 4245 4438
+f 4716 3849 3851
+f 8671 8672 8673
+f 4861 4860 3305
+f 5305 8290 5171
+f 8674 8675 4024
+f 4023 8674 4024
+f 6812 4600 8676
+f 8677 6812 8676
+f 6035 6034 8677
+f 8469 4593 6713
+f 5860 8470 5861
+f 4593 4591 6713
+f 8678 8679 8680
+f 5508 4284 4285
+f 8681 8682 8683
+f 8683 8684 8681
+f 8685 8686 8687
+f 4294 8688 8283
+f 2953 8689 8690
+f 468 8691 4642
+f 4630 8477 4153
+f 6724 7246 8692
+f 8693 8694 8695
+f 8696 3320 8502
+f 8697 8698 390
+f 8699 6305 8700
+f 8701 8574 8702
+f 8703 8701 8702
+f 8577 5356 8574
+f 8701 8577 8574
+f 1440 900 1436
+f 8704 8705 5357
+f 618 1607 4646
+f 2138 460 8706
+f 1599 2302 1666
+f 2142 1168 1167
+f 8707 808 807
+f 1453 1452 8708
+f 8709 311 310
+f 3599 3784 8480
+f 8580 3599 8480
+f 1958 1654 1030
+f 1029 1958 1030
+f 8710 8586 5250
+f 8586 8484 5251
+f 8710 8711 8585
+f 8585 8711 8587
+f 8712 8713 8588
+f 8587 8712 8588
+f 8713 8714 8589
+f 8588 8713 8589
+f 8714 8715 8590
+f 8589 8714 8590
+f 8715 8716 8591
+f 8590 8715 8591
+f 8716 8717 8592
+f 8591 8716 8592
+f 8717 8718 8593
+f 8592 8717 8593
+f 8718 8719 8594
+f 8593 8718 8594
+f 8719 8720 8595
+f 8594 8719 8595
+f 8721 8722 8723
+f 8595 8720 8596
+f 8724 8725 8726
+f 8596 8727 8597
+f 8728 8729 8730
+f 4463 2904 3381
+f 8731 8732 2629
+f 8600 8610 8601
+f 8575 1983 8702
+f 8733 3782 1805
+f 8734 8735 8736
+f 8737 8734 8736
+f 8738 8739 8617
+f 8507 8608 8508
+f 1043 8740 8741
+f 2606 627 8742
+f 8743 6846 8744
+f 6943 3782 8733
+f 8745 8746 8747
+f 8746 8748 8747
+f 8616 8517 8749
+f 8618 8616 8749
+f 8750 8751 8623
+f 8621 8750 8623
+f 6594 3458 4080
+f 627 8752 8742
+f 8615 8753 7762
+f 274 8615 7762
+f 4284 6906 8754
+f 1887 1886 8755
+f 8756 8757 8633
+f 8632 8756 8633
+f 8757 8758 8634
+f 8633 8757 8634
+f 8758 8759 8635
+f 8634 8758 8635
+f 8759 8760 8636
+f 8635 8759 8636
+f 8760 8761 8637
+f 8636 8760 8637
+f 8762 8638 8637
+f 8761 8762 8637
+f 8763 8639 8638
+f 8762 8763 8638
+f 8764 8640 8639
+f 8763 8764 8639
+f 8765 8641 8640
+f 8764 8765 8640
+f 8766 8642 8641
+f 8765 8766 8641
+f 8767 8643 8642
+f 8766 8767 8642
+f 8768 8644 8643
+f 8767 8768 8643
+f 8769 8645 8644
+f 8768 8769 8644
+f 8770 8646 8645
+f 8769 8770 8645
+f 8771 8647 8646
+f 8770 8771 8646
+f 8772 8648 8647
+f 8771 8772 8647
+f 8773 8649 8648
+f 8772 8773 8648
+f 8774 513 8649
+f 8773 8774 8649
+f 5661 8654 8775
+f 8774 8654 513
+f 8578 8655 8579
+f 8776 8777 8778
+f 8657 8779 8780
+f 8546 8781 3526
+f 8371 8662 8664
+f 8663 8782 8783
+f 5214 6048 5215
+f 8784 3948 6024
+f 8785 8786 8787
+f 8788 8789 8790
+f 8791 2395 8792
+f 8793 8794 8795
+f 6217 6347 4004
+f 3841 3176 3066
+f 7036 6324 4266
+f 8675 8463 4220
+f 8463 5923 6031
+f 8122 6298 8796
+f 6158 6314 6159
+f 5727 6159 5156
+f 7019 6577 6034
+f 6814 3489 4075
+f 6814 4579 3489
+f 3845 5593 3846
+f 4542 4566 4543
+f 4916 6803 4751
+f 3841 3840 3176
+f 5013 4240 5303
+f 6007 8465 8464
+f 3480 3482 5329
+f 3664 5092 4246
+f 8797 8798 2329
+f 2415 5659 2652
+f 2373 2537 2538
+f 7002 6144 6044
+f 4564 3677 3272
+f 2886 5727 2866
+f 3866 4405 4900
+f 4237 5712 5726
+f 8799 8800 8801
+f 5016 5158 5474
+f 6913 8802 8803
+f 2756 7924 2757
+f 8804 6453 4695
+f 388 2891 779
+f 8805 8806 8807
+f 8808 2817 6786
+f 8809 8810 8811
+f 5079 5073 4881
+f 3476 5032 6015
+f 3171 8812 6342
+f 4407 4409 4038
+f 4727 5216 5038
+f 930 8813 939
+f 7955 1998 8042
+f 8814 8703 8815
+f 1985 8815 8703
+f 8816 8701 8703
+f 8814 8816 8703
+f 8817 8577 8701
+f 8816 8817 8701
+f 8818 5357 8577
+f 8817 8818 8577
+f 8819 8820 8821
+f 8818 8704 5357
+f 1666 2142 1167
+f 6637 8822 8823
+f 1422 1423 1425
+f 746 745 8824
+f 746 8824 8825
+f 3202 8481 3792
+f 2986 3202 3792
+f 1030 1654 1953
+f 1654 1493 1953
+f 1331 8826 4773
+f 1011 1185 1022
+f 3792 8481 8827
+f 8481 8828 8827
+f 8829 8830 8712
+f 8829 8712 8711
+f 8831 8832 8833
+f 8713 8834 8714
+f 8835 3987 8834
+f 8714 3987 8715
+f 3987 3986 8715
+f 8715 3986 8716
+f 5209 3231 5210
+f 8836 8837 5512
+f 8838 7040 7039
+f 8717 8839 8718
+f 8840 8726 8839
+f 8718 8726 8719
+f 8841 920 919
+f 8840 8724 8726
+f 8842 8843 8844
+f 8845 8846 8847
+f 8848 8849 8850
+f 8851 8852 8853
+f 8730 8854 8855
+f 8854 8856 8855
+f 8857 8858 8859
+f 8860 8861 8862
+f 8863 8864 8656
+f 6361 6079 5506
+f 8736 8735 8865
+f 8735 8866 8865
+f 8738 8617 8867
+f 8868 8738 8867
+f 1345 8869 8870
+f 8871 2462 2461
+f 8755 8872 8873
+f 6499 6501 8874
+f 8875 8876 8303
+f 8748 8877 8878
+f 8618 8749 8619
+f 8879 8746 8745
+f 8880 8881 8751
+f 8750 8880 8751
+f 8882 8883 8884
+f 4219 8885 8886
+f 8825 8824 8887
+f 2051 8888 8889
+f 8890 8891 8892
+f 2490 8893 2491
+f 6906 3816 8754
+f 8516 8894 8895
+f 8896 8758 8757
+f 8897 8896 8757
+f 8896 8898 8759
+f 8758 8896 8759
+f 8898 8899 8760
+f 8759 8898 8760
+f 8899 8900 8761
+f 8760 8899 8761
+f 8900 8901 8762
+f 8761 8900 8762
+f 8902 8763 8762
+f 8901 8902 8762
+f 8903 8764 8763
+f 8902 8903 8763
+f 8904 8765 8764
+f 8903 8904 8764
+f 8905 8766 8765
+f 8904 8905 8765
+f 8906 8767 8766
+f 8905 8906 8766
+f 8907 8768 8767
+f 8906 8907 8767
+f 8908 8769 8768
+f 8907 8908 8768
+f 8909 8770 8769
+f 8908 8909 8769
+f 8910 8771 8770
+f 8909 8910 8770
+f 8911 8772 8771
+f 8910 8911 8771
+f 8911 8912 8773
+f 8772 8911 8773
+f 8913 8774 8773
+f 8912 8913 8773
+f 8775 8654 8774
+f 8913 8775 8774
+f 8777 4308 4307
+f 8914 8915 7466
+f 8655 8863 8656
+f 8916 8917 8864
+f 8664 8663 8783
+f 8918 7039 8919
+f 7563 6160 6162
+f 8112 8114 8920
+f 8921 8922 8923
+f 8924 8805 8807
+f 3093 6447 3094
+f 6180 3641 5312
+f 8463 5738 5921
+f 4468 6574 669
+f 4863 3494 7037
+f 5604 3498 5089
+f 8925 8926 6598
+f 8027 6910 4731
+f 3097 3096 3930
+f 4579 3679 3489
+f 5332 4032 4036
+f 5580 4009 5581
+f 4035 2882 5179
+f 4009 4034 5581
+f 4051 4053 8196
+f 2886 2888 5727
+f 4877 4408 4407
+f 4241 6010 4052
+f 6492 6491 8558
+f 7452 5343 6449
+f 4598 4597 6352
+f 6351 6141 6140
+f 2356 2353 2355
+f 8927 4283 3566
+f 4608 3682 3684
+f 3930 4075 3931
+f 6011 3097 3929
+f 5483 5177 5176
+f 8364 5731 3304
+f 8928 8929 8930
+f 3290 3289 5482
+f 8931 8932 8933
+f 5911 2818 5909
+f 2645 8934 2646
+f 8935 8936 8937
+f 6436 6315 3074
+f 7055 6215 6312
+f 6811 6478 7011
+f 6447 6441 3094
+f 4024 8675 4220
+f 6446 6447 3093
+f 8938 8939 8940
+f 1685 1684 8139
+f 8941 8942 8943
+f 8863 8916 8864
+f 8944 8816 8814
+f 8945 8944 8814
+f 8946 8817 8816
+f 8944 8946 8816
+f 8947 8818 8817
+f 8946 8947 8817
+f 8948 8704 8818
+f 8947 8948 8818
+f 8949 8823 8704
+f 8948 8949 8704
+f 8950 6359 8951
+f 8952 8953 8941
+f 1452 746 8825
+f 745 2051 8824
+f 3406 8581 8481
+f 2788 3791 6848
+f 2280 8709 310
+f 1493 1453 8708
+f 3189 994 394
+f 311 8709 1002
+f 8481 8581 8828
+f 8581 8954 8828
+f 8955 8956 8957
+f 8958 8959 8960
+f 2616 8961 3014
+f 8962 8963 8558
+f 8964 8965 8966
+f 8967 8968 3309
+f 1768 3715 1745
+f 8969 2805 7940
+f 8970 3415 8971
+f 3416 3414 8972
+f 3420 3610 8973
+f 8974 3418 8975
+f 3920 1644 8976
+f 595 596 8977
+f 2725 8038 8978
+f 8979 8980 8981
+f 8982 8983 283
+f 8984 1818 1962
+f 8866 8970 8985
+f 8971 8972 8986
+f 8973 8987 8734
+f 8856 8974 8988
+f 8989 8990 8991
+f 8992 8993 3013
+f 936 1391 937
+f 2582 8994 8995
+f 8848 8850 8877
+f 8866 8985 8879
+f 8996 8880 8750
+f 8997 8996 8750
+f 633 632 8998
+f 8999 1340 9000
+f 9001 6747 8743
+f 9002 9003 9004
+f 7568 8875 8303
+f 8607 8606 6625
+f 9005 8879 8745
+f 8865 8879 9005
+f 8867 9006 8881
+f 8880 8867 8881
+f 2547 2383 2382
+f 9007 9008 8917
+f 8824 2051 8889
+f 1975 9009 8888
+f 9010 9011 9012
+f 9013 9014 9015
+f 8517 8516 8895
+f 8516 9016 9017
+f 9018 8897 9019
+f 8749 8517 9020
+f 4187 8898 8896
+f 3978 3797 9021
+f 4187 4189 8899
+f 8898 4187 8899
+f 4189 9022 8900
+f 8899 4189 8900
+f 9023 8901 8900
+f 9022 9023 8900
+f 9024 8902 8901
+f 9023 9024 8901
+f 9025 8903 8902
+f 9024 9025 8902
+f 9026 8904 8903
+f 9025 9026 8903
+f 9027 8905 8904
+f 9026 9027 8904
+f 9028 8906 8905
+f 9027 9028 8905
+f 9029 8907 8906
+f 9028 9029 8906
+f 9030 8908 8907
+f 9029 9030 8907
+f 9031 8909 8908
+f 9030 9031 8908
+f 9032 8910 8909
+f 9031 9032 8909
+f 9033 8911 8910
+f 9032 9033 8910
+f 9034 8912 8911
+f 9033 9034 8911
+f 9035 8913 8912
+f 9034 9035 8912
+f 9036 8775 8913
+f 9035 9036 8913
+f 4795 4794 8775
+f 9036 4795 8775
+f 9037 8777 4307
+f 7843 9038 9039
+f 9040 9041 9042
+f 9043 9044 9045
+f 9046 538 419
+f 4931 5008 5473
+f 418 9046 419
+f 7004 7846 9047
+f 9048 2924 6724
+f 6441 6343 3094
+f 6810 6592 6811
+f 4569 4852 5173
+f 3287 3079 3078
+f 6812 6576 4600
+f 3932 5628 3933
+f 6165 6164 3542
+f 4578 3680 3679
+f 9049 9050 9051
+f 9052 2472 9053
+f 9054 8016 4402
+f 3875 4236 2887
+f 2888 5726 6158
+f 5726 5715 6158
+f 6479 4032 4031
+f 5177 5314 5178
+f 8916 9007 8917
+f 4610 7555 4847
+f 3071 7114 5334
+f 3071 5334 5165
+f 3643 5323 4878
+f 4082 4404 4083
+f 8119 5328 5457
+f 3683 3485 5591
+f 3449 3486 3678
+f 4440 4259 3635
+f 3375 3449 3678
+f 4711 4274 4569
+f 4271 4269 4570
+f 9055 9056 9057
+f 9058 8937 9059
+f 9060 3286 9047
+f 9061 9062 8935
+f 9059 8937 8936
+f 4237 7005 5712
+f 2887 4236 2888
+f 3493 7013 3686
+f 7011 6446 3093
+f 6584 6592 6810
+f 1713 433 432
+f 3077 3079 5309
+f 9063 9064 9065
+f 8945 8953 9066
+f 9067 8944 8945
+f 9066 9067 8945
+f 9068 8946 8944
+f 9067 9068 8944
+f 9069 8947 8946
+f 9068 9069 8946
+f 9070 8948 8947
+f 9069 9070 8947
+f 9070 9071 8949
+f 8948 9070 8949
+f 9072 6638 8949
+f 9071 9072 8949
+f 1344 1975 2051
+f 9073 9074 9075
+f 2986 3792 3791
+f 2282 2788 6848
+f 1953 1493 8708
+f 8709 9076 1002
+f 834 833 9077
+f 9078 1213 4626
+f 8954 8581 9079
+f 8581 8580 9079
+f 3791 3793 9080
+f 6848 3791 9080
+f 2625 2624 9081
+f 1890 9082 2729
+f 9083 479 503
+f 446 9084 8869
+f 6333 8984 1962
+f 4086 8951 1163
+f 3790 3415 8970
+f 9085 3790 8970
+f 3610 3789 8987
+f 8975 3420 8973
+f 8475 9086 9087
+f 1501 595 9088
+f 9089 9090 8862
+f 9091 9092 9093
+f 7940 5182 7665
+f 4773 8982 283
+f 8972 8849 8848
+f 8985 8971 8986
+f 8855 8856 8988
+f 8974 8975 9094
+f 2263 1501 9088
+f 9090 9093 8862
+f 6643 9095 9096
+f 8937 9058 7844
+f 8853 8604 8607
+f 8748 8848 8877
+f 9097 8620 8609
+f 8608 9097 8609
+f 8213 2726 9098
+f 3022 9099 221
+f 6747 9001 9100
+f 6651 6747 9100
+f 8876 8607 8303
+f 8606 7836 6625
+f 9101 8865 9005
+f 9102 9103 9104
+f 8617 8619 9006
+f 8867 8617 9006
+f 9105 9106 9107
+f 9108 3209 9109
+f 9110 9111 6499
+f 720 722 4635
+f 7765 1545 473
+f 5183 3018 5040
+f 8894 8516 9017
+f 9016 9102 9112
+f 9113 890 889
+f 8619 8749 9114
+f 2113 377 1265
+f 487 9115 2298
+f 1767 8821 3715
+f 9116 4187 8896
+f 1176 1175 3713
+f 9117 9118 3655
+f 9119 9023 9022
+f 9120 9119 9022
+f 9121 9024 9023
+f 9119 9121 9023
+f 9122 9025 9024
+f 9121 9122 9024
+f 9123 9026 9025
+f 9122 9123 9025
+f 9124 9027 9026
+f 9123 9124 9026
+f 9125 9028 9027
+f 9124 9125 9027
+f 9126 9029 9028
+f 9125 9126 9028
+f 9127 9030 9029
+f 9126 9127 9029
+f 9128 9031 9030
+f 9127 9128 9030
+f 9129 9032 9031
+f 9128 9129 9031
+f 9130 9033 9032
+f 9129 9130 9032
+f 9131 9034 9033
+f 9130 9131 9033
+f 9132 9035 9034
+f 9131 9132 9034
+f 9133 9036 9035
+f 9132 9133 9035
+f 9134 4795 9036
+f 9133 9134 9036
+f 9135 9136 9137
+f 7340 4925 4924
+f 9042 9043 9045
+f 9138 8858 9139
+f 4119 4623 2870
+f 2871 4931 2872
+f 9140 9141 9008
+f 9007 9140 9008
+f 3087 3825 3296
+f 8926 6442 6598
+f 6478 6446 7011
+f 7001 6896 4555
+f 6069 3283 5309
+f 3283 3077 5309
+f 3876 3492 4237
+f 4207 5338 5323
+f 9142 9143 9144
+f 6173 4855 4857
+f 6179 8206 4744
+f 6208 5305 4006
+f 4069 4068 3090
+f 4068 3875 2887
+f 7136 9145 5216
+f 5216 9145 4876
+f 2414 2652 5064
+f 4726 7136 5216
+f 9146 9147 9148
+f 7241 8803 7640
+f 3892 3890 3503
+f 9140 9149 9150
+f 4417 4586 3887
+f 6202 5611 5613
+f 4541 4543 7121
+f 4441 4443 5457
+f 4440 3635 4405
+f 3470 4239 4916
+f 9151 3938 4618
+f 4736 5218 4737
+f 9152 6043 7037
+f 3831 5159 9153
+f 5381 3017 9154
+f 9155 7842 9058
+f 1767 8819 8821
+f 8937 9039 8935
+f 8027 8925 6598
+f 5344 4875 5039
+f 3927 5158 5015
+f 9156 9157 9158
+f 3933 5935 3934
+f 3487 3283 5207
+f 9159 9066 9160
+f 1170 1172 1043
+f 9161 9067 9066
+f 9159 9161 9066
+f 9162 9068 9067
+f 9161 9162 9067
+f 9163 9069 9068
+f 9162 9163 9068
+f 9164 9070 9069
+f 9163 9164 9069
+f 9165 9071 9070
+f 9164 9165 9070
+f 9073 9072 9071
+f 9165 9073 9071
+f 9166 9167 9168
+f 9072 9073 9075
+f 1452 8825 8708
+f 2788 2986 3791
+f 9169 9170 9171
+f 9172 1710 1709
+f 8580 8480 9173
+f 1987 9174 9175
+f 6848 9080 9176
+f 9079 8580 9173
+f 2803 2113 2115
+f 3792 8827 3793
+f 9177 9178 1994
+f 9179 2625 9081
+f 9180 9181 922
+f 1291 1288 1705
+f 9182 2617 8969
+f 9183 9184 9185
+f 8827 8828 9186
+f 3415 3416 8971
+f 2630 1559 2631
+f 9080 3793 9187
+f 2949 3111 9188
+f 3980 8600 8599
+f 9189 9190 9191
+f 8038 9192 9193
+f 8986 8972 8848
+f 9194 9195 9196
+f 8988 8974 9094
+f 8849 8851 8850
+f 8981 8980 9197
+f 8975 8973 9198
+f 9199 935 9200
+f 9201 9202 9203
+f 8850 8853 8876
+f 9204 8207 7745
+f 9205 8621 8620
+f 8876 8853 8607
+f 9206 1113 9207
+f 9097 9205 8620
+f 9208 1550 8301
+f 1674 1515 9209
+f 2459 9210 9211
+f 6747 6846 8743
+f 1646 1648 9212
+f 9213 9214 9010
+f 9215 9216 9217
+f 8515 9218 9016
+f 8213 9098 9219
+f 1113 2442 9207
+f 4485 9220 4486
+f 9221 5950 9222
+f 1806 1957 1807
+f 9051 9223 9049
+f 6816 9224 3604
+f 1354 6043 9152
+f 9017 9016 9112
+f 9102 9104 9225
+f 8517 8895 9020
+f 9006 8619 9226
+f 9227 9228 1850
+f 806 808 3701
+f 8824 8889 8887
+f 9229 9230 8844
+f 9231 8218 8217
+f 9232 9233 9234
+f 9235 9236 9119
+f 9120 9235 9119
+f 9237 9121 9119
+f 9236 9237 9119
+f 9238 9122 9121
+f 9237 9238 9121
+f 9239 9123 9122
+f 9238 9239 9122
+f 9240 9124 9123
+f 9239 9240 9123
+f 9241 9125 9124
+f 9240 9241 9124
+f 9242 9126 9125
+f 9241 9242 9125
+f 9243 9127 9126
+f 9242 9243 9126
+f 9244 9128 9127
+f 9243 9244 9127
+f 9245 9129 9128
+f 9244 9245 9128
+f 9246 9130 9129
+f 9245 9246 9129
+f 9247 9131 9130
+f 9246 9247 9130
+f 9248 9132 9131
+f 9247 9248 9131
+f 9249 9133 9132
+f 9248 9249 9132
+f 9250 9134 9133
+f 9249 9250 9133
+f 9251 9252 9253
+f 9250 9254 9134
+f 9041 9043 9042
+f 9255 9256 8506
+f 9257 8277 8276
+f 4118 4454 4119
+f 4623 2871 2870
+f 9258 9259 2935
+f 9260 278 280
+f 9261 9262 9263
+f 9264 9265 9266
+f 6592 6478 6811
+f 9263 9267 9268
+f 3283 6069 5207
+f 9269 8023 4263
+f 4610 4748 7555
+f 7652 4748 7746
+f 5337 4234 4029
+f 3924 3821 3823
+f 6179 6178 8206
+f 6178 6814 8206
+f 5212 3306 9270
+f 3372 3445 4063
+f 6607 9271 6715
+f 4413 8112 5868
+f 9272 9273 9274
+f 6890 7552 6644
+f 5720 6913 7214
+f 7214 6913 7241
+f 7213 5720 7214
+f 6913 8803 7241
+f 5323 5338 3827
+f 4705 6911 4706
+f 4915 4914 3840
+f 5599 4541 7121
+f 4031 4033 5451
+f 4215 6179 4744
+f 3828 4030 5017
+f 3532 4106 4138
+f 4382 4381 5609
+f 5337 5480 4234
+f 3492 7005 4237
+f 3256 3480 3257
+f 1536 1538 9275
+f 3033 5438 9276
+f 9141 9140 9150
+f 2770 2769 3872
+f 3670 4574 3668
+f 4422 7454 5012
+f 9277 9278 9279
+f 7013 9280 3686
+f 7453 4276 4275
+f 4715 2905 2904
+f 9281 9282 9159
+f 9283 9284 9160
+f 9285 9161 9159
+f 9282 9285 9159
+f 9286 9162 9161
+f 9285 9286 9161
+f 9286 9287 9163
+f 9162 9286 9163
+f 9287 9288 9164
+f 9163 9287 9164
+f 9289 9165 9164
+f 9288 9289 9164
+f 9290 9073 9165
+f 9289 9290 9165
+f 9291 9292 9293
+f 9073 9290 9294
+f 2473 9295 5945
+f 9149 9296 3579
+f 8480 6750 9297
+f 8841 9298 920
+f 2283 9176 9299
+f 9173 8480 9297
+f 9300 9301 9302
+f 2283 6848 9176
+f 8965 9303 8966
+f 1265 9304 2114
+f 3516 9305 1759
+f 9306 9307 9308
+f 9309 9310 9311
+f 8821 8820 8295
+f 8827 9186 9312
+f 8973 3610 8987
+f 9080 9187 9313
+f 8954 9314 9315
+f 9150 9149 3579
+f 9176 9080 9313
+f 9316 8755 8873
+f 2817 8808 9317
+f 8969 7940 7837
+f 9318 9319 9320
+f 8868 9186 8738
+f 8970 8971 8985
+f 2790 2725 8978
+f 9094 8975 9198
+f 2862 9321 2863
+f 2726 1674 9209
+f 8865 8866 8879
+f 9322 9323 2971
+f 8997 8750 8621
+f 8877 8850 8876
+f 9324 9325 9326
+f 9205 8997 8621
+f 684 581 580
+f 8557 8962 8558
+f 8606 8605 7836
+f 9327 9328 9329
+f 9330 9331 9332
+f 9333 9334 9335
+f 8516 8515 9016
+f 9103 9215 9104
+f 9218 9103 9102
+f 9016 9218 9102
+f 8609 9336 9113
+f 8508 8609 9113
+f 9337 7463 9338
+f 1342 1067 9000
+f 9296 9339 3580
+f 3653 9118 9340
+f 7037 6142 9152
+f 9061 9341 9062
+f 9112 9102 9225
+f 9104 9217 9342
+f 8749 9020 9114
+f 8881 9006 9343
+f 4631 9344 4632
+f 9345 9346 1408
+f 9347 9348 9349
+f 8708 8825 8887
+f 1532 2938 9350
+f 1834 1833 9351
+f 9352 9353 9236
+f 9354 2989 8963
+f 9355 9237 9236
+f 9353 9355 9236
+f 9356 9238 9237
+f 9355 9356 9237
+f 9357 9239 9238
+f 9356 9357 9238
+f 9358 9240 9239
+f 9357 9358 9239
+f 9359 9241 9240
+f 9358 9359 9240
+f 9360 9242 9241
+f 9359 9360 9241
+f 9361 9243 9242
+f 9360 9361 9242
+f 9362 9244 9243
+f 9361 9362 9243
+f 9363 9245 9244
+f 9362 9363 9244
+f 9364 9246 9245
+f 9363 9364 9245
+f 9365 9247 9246
+f 9364 9365 9246
+f 9366 9248 9247
+f 9365 9366 9247
+f 9367 9249 9248
+f 9366 9367 9248
+f 9368 9250 9249
+f 9367 9368 9249
+f 9369 9254 9250
+f 9368 9369 9250
+f 4469 4489 9370
+f 9369 9370 9254
+f 4309 9257 8276
+f 845 616 1212
+f 9371 4429 4118
+f 4454 4623 4119
+f 3579 9296 3580
+f 9372 5762 9373
+f 5734 9374 5735
+f 9375 9267 9262
+f 1770 9376 1771
+f 7456 5611 6202
+f 5874 5480 5337
+f 4748 7652 7555
+f 5627 4608 4383
+f 3852 5183 3853
+f 5080 5082 4140
+f 8027 3293 8925
+f 9377 9378 9379
+f 8454 4690 7657
+f 4378 1322 5315
+f 3849 4439 3854
+f 6599 4717 3475
+f 5492 9380 5648
+f 6909 6908 9381
+f 4247 3848 4420
+f 6029 7553 4426
+f 4602 5720 7213
+f 7242 4602 7213
+f 4483 3652 3651
+f 9382 3627 6156
+f 4898 3047 5039
+f 5200 5624 5203
+f 3492 3295 7005
+f 5448 5450 5451
+f 5762 6227 9373
+f 3291 3293 8027
+f 4704 6181 6044
+f 5034 5213 3255
+f 4439 4437 3854
+f 9383 9384 2592
+f 6428 4023 4025
+f 5327 5328 8119
+f 9385 4680 9386
+f 5459 5736 5735
+f 4042 4041 5174
+f 3665 3664 4246
+f 8676 4600 4602
+f 9387 5479 5478
+f 5874 4853 5580
+f 7648 7647 5033
+f 5790 9254 9370
+f 4422 5012 5011
+f 7449 2076 578
+f 9388 9389 7650
+f 6306 7065 2153
+f 9390 2970 5083
+f 9391 9392 9286
+f 9285 9391 9286
+f 9392 9393 9287
+f 9286 9392 9287
+f 9394 9288 9287
+f 9393 9394 9287
+f 9395 9289 9288
+f 9394 9395 9288
+f 9396 9290 9289
+f 9395 9396 9289
+f 9397 9293 9292
+f 9290 9396 9291
+f 6750 3419 3418
+f 9398 2627 2626
+f 3788 9399 3984
+f 9297 6750 3418
+f 9090 9091 9093
+f 3971 2283 9299
+f 1290 9400 9401
+f 2272 2616 3014
+f 2030 9172 1328
+f 9402 9403 9404
+f 3789 3790 9085
+f 9214 9011 9010
+f 3793 8827 9312
+f 8987 3789 9085
+f 9176 9313 9405
+f 8828 9315 9186
+f 9406 7017 2418
+f 3793 9312 9187
+f 936 9407 1392
+f 9408 8964 8966
+f 8850 8851 8853
+f 9407 9409 9410
+f 9314 8739 8738
+f 8605 8969 7837
+f 1410 8981 9197
+f 9315 9314 8738
+f 9189 9411 2627
+f 1504 9219 7057
+f 8985 8986 8746
+f 283 8983 284
+f 8868 8867 8880
+f 8879 8985 8746
+f 9412 9413 9414
+f 8996 8868 8880
+f 1954 1953 9415
+f 2791 2618 9092
+f 8747 8748 8878
+f 5595 6443 5596
+f 9416 8737 9417
+f 2973 2978 2974
+f 9104 9215 9217
+f 9216 8737 9416
+f 9217 9216 9416
+f 8737 8736 9417
+f 8509 8508 9418
+f 9219 9098 3338
+f 8620 8622 9336
+f 8609 8620 9336
+f 2990 8955 8957
+f 9419 9420 1448
+f 2051 1975 8888
+f 9421 1995 942
+f 9051 9422 9223
+f 9423 8878 7568
+f 9217 9416 9424
+f 9342 9217 9424
+f 8619 9114 9226
+f 8751 8881 9425
+f 9325 9426 9326
+f 9415 8708 8887
+f 7340 4924 7341
+f 1242 7764 1246
+f 9427 8693 8300
+f 1554 1553 9353
+f 9352 1554 9353
+f 9428 9355 9353
+f 1553 9428 9353
+f 9428 9429 9356
+f 9355 9428 9356
+f 9429 9430 9357
+f 9356 9429 9357
+f 9431 9358 9357
+f 9430 9431 9357
+f 9432 9359 9358
+f 9431 9432 9358
+f 9433 9360 9359
+f 9432 9433 9359
+f 9434 9361 9360
+f 9433 9434 9360
+f 9435 9362 9361
+f 9434 9435 9361
+f 9436 9363 9362
+f 9435 9436 9362
+f 9437 9364 9363
+f 9436 9437 9363
+f 9438 9365 9364
+f 9437 9438 9364
+f 9439 9366 9365
+f 9438 9439 9365
+f 9440 9367 9366
+f 9439 9440 9366
+f 9441 9368 9367
+f 9440 9441 9367
+f 4467 9369 9368
+f 9441 4467 9368
+f 880 4469 4468
+f 4467 4469 9369
+f 5745 7322 9442
+f 7323 9443 7324
+f 9444 4298 9371
+f 4429 4454 4118
+f 9445 9446 9447
+f 9448 3758 9449
+f 8205 9450 8201
+f 2705 2540 2704
+f 9451 9269 9452
+f 7743 5306 5030
+f 4604 8674 4023
+f 3485 4572 5592
+f 5308 6712 4013
+f 2969 4414 5342
+f 5024 6069 5025
+f 4852 5307 4008
+f 4245 5178 4242
+f 5178 1353 4242
+f 8803 8802 9147
+f 6599 3475 3046
+f 5627 4383 4239
+f 6448 5600 5628
+f 4574 4881 3668
+f 9453 9454 9455
+f 8676 4602 7242
+f 7334 8676 7242
+f 5349 5462 5598
+f 4539 6182 5328
+f 3127 3126 3306
+f 4719 4716 5032
+f 4403 1404 3686
+f 3295 6135 7005
+f 3937 3936 4730
+f 3293 3290 8925
+f 6181 4704 3648
+f 6324 5219 5080
+f 8198 2972 8199
+f 3663 3656 3658
+f 4752 3932 3934
+f 5228 3924 3925
+f 9450 9456 8202
+f 8201 9450 8202
+f 9457 9448 9449
+f 9456 9458 8285
+f 8202 9456 8285
+f 5089 4401 4400
+f 3823 3822 3742
+f 7114 4595 4596
+f 7114 4596 5334
+f 4420 4422 4424
+f 4748 4280 7746
+f 3850 6020 6014
+f 385 6905 5779
+f 9459 9460 9391
+f 9461 9390 5083
+f 9460 9462 9392
+f 9391 9460 9392
+f 9462 9463 9393
+f 9392 9462 9393
+f 9463 9464 9394
+f 9393 9463 9394
+f 9465 9395 9394
+f 9464 9465 9394
+f 9465 9466 9396
+f 9395 9465 9396
+f 9467 9468 9469
+f 9396 9466 9292
+f 3606 3788 3984
+f 3419 3608 3420
+f 2290 2133 2135
+f 3971 9299 9399
+f 1705 1288 1011
+f 9091 2791 9092
+f 9470 9471 8813
+f 9472 9473 3536
+f 2622 2617 9182
+f 9398 9189 2627
+f 8828 8954 9315
+f 2617 2805 8969
+f 9299 9405 9474
+f 9079 8729 9314
+f 9475 9408 8966
+f 9299 9176 9405
+f 1391 936 1392
+f 6600 9476 6601
+f 8852 9182 8604
+f 9477 997 9478
+f 8729 8728 8739
+f 8853 8852 8604
+f 9479 8507 8610
+f 9314 8729 8739
+f 9480 664 865
+f 9474 9405 8608
+f 8986 8848 8748
+f 9319 9480 9320
+f 9209 9481 9482
+f 8746 8986 8748
+f 409 408 9483
+f 8739 8618 8617
+f 1355 7836 1353
+f 1265 376 8627
+f 8877 8876 8875
+f 6846 6943 8744
+f 8736 8865 9101
+f 8878 8877 8875
+f 9098 9482 3338
+f 9417 8736 9101
+f 9484 8509 9485
+f 2726 9209 9098
+f 9484 9485 9486
+f 8508 9113 9418
+f 9487 9484 9486
+f 8509 9418 9485
+f 3600 1832 8627
+f 9488 9337 463
+f 9489 9490 8478
+f 9491 227 576
+f 1972 8512 9009
+f 1975 1972 9009
+f 8691 1844 1843
+f 908 684 9492
+f 9416 9417 9493
+f 9494 9101 9495
+f 9496 1504 1503
+f 8622 882 881
+f 3119 9497 9498
+f 2091 1943 2092
+f 8753 1266 1489
+f 8893 9212 2491
+f 1547 2490 2492
+f 7444 1176 9499
+f 9500 7064 6305
+f 1552 9501 9428
+f 1553 1552 9428
+f 9501 9502 9429
+f 9428 9501 9429
+f 9502 9503 9430
+f 9429 9502 9430
+f 9503 9504 9431
+f 9430 9503 9431
+f 9505 9432 9431
+f 9504 9505 9431
+f 9506 9433 9432
+f 9505 9506 9432
+f 9507 9434 9433
+f 9506 9507 9433
+f 9508 9435 9434
+f 9507 9508 9434
+f 9509 9436 9435
+f 9508 9509 9435
+f 9510 9437 9436
+f 9509 9510 9436
+f 9511 9438 9437
+f 9510 9511 9437
+f 9512 9439 9438
+f 9511 9512 9438
+f 9513 9440 9439
+f 9512 9513 9439
+f 9514 9441 9440
+f 9513 9514 9440
+f 9515 4467 9441
+f 9514 9515 9441
+f 6073 7670 9516
+f 9515 4468 4467
+f 9517 9518 9519
+f 9520 9419 9521
+f 4296 4298 9522
+f 4298 4429 9371
+f 9523 3756 3758
+f 9448 9523 3758
+f 9524 8377 8285
+f 9458 9524 8285
+f 3518 3356 6710
+f 4545 4868 5044
+f 3635 2686 2690
+f 4605 4604 4023
+f 8962 9354 8963
+f 7343 9525 7344
+f 3075 6208 4006
+f 4008 5307 4013
+f 5482 5176 7006
+f 8723 9526 9527
+f 4242 1353 7665
+f 5590 7649 7841
+f 9528 3154 8456
+f 4910 4902 4903
+f 3660 5199 3661
+f 3154 9529 8456
+f 5881 6035 7119
+f 8677 8676 7334
+f 7034 5881 7119
+f 6035 8677 7333
+f 6803 4384 6448
+f 6442 4438 4439
+f 3251 3372 4260
+f 4571 4267 8291
+f 4730 3291 8027
+f 5218 7841 5461
+f 5222 4848 5487
+f 5589 4913 7649
+f 6207 7835 6208
+f 6712 4214 4013
+f 9530 3912 3756
+f 4043 4040 4042
+f 5618 5612 9531
+f 5230 8796 5231
+f 9523 9530 3756
+f 8109 8108 1218
+f 9532 8378 8377
+f 4732 4731 3163
+f 9524 9532 8377
+f 6813 8290 5305
+f 3662 3661 4854
+f 4104 4106 3532
+f 9533 5681 5049
+f 4266 6324 4264
+f 4583 4414 2969
+f 2460 2823 2729
+f 5083 6431 9461
+f 9534 9535 9462
+f 9460 9534 9462
+f 9535 9536 9463
+f 9462 9535 9463
+f 9536 9537 9464
+f 9463 9536 9464
+f 9538 9465 9464
+f 9537 9538 9464
+f 9538 9539 9466
+f 9465 9538 9466
+f 9540 9541 9542
+f 9466 9539 9468
+f 9543 2990 2989
+f 3788 3971 9399
+f 4339 1291 1705
+f 2133 2725 2790
+f 9544 9545 3186
+f 1185 1293 1022
+f 2793 2622 8852
+f 9546 9547 9318
+f 8954 9079 9314
+f 8852 2622 9182
+f 9399 9474 9479
+f 9079 9173 8854
+f 9548 9549 9550
+f 9399 9299 9474
+f 914 913 6507
+f 9483 9551 9552
+f 9182 8969 8605
+f 1392 9407 9410
+f 9312 9186 8996
+f 8604 9182 8605
+f 8600 9479 8610
+f 8729 8854 8730
+f 340 9553 1149
+f 9474 8608 8507
+f 8605 7837 7836
+f 9554 8614 273
+f 9219 3338 7057
+f 9555 9556 9557
+f 9420 9491 576
+f 8601 9484 9487
+f 9558 2928 2927
+f 9227 1850 227
+f 9559 9560 9561
+f 6426 8311 7105
+f 9560 9562 9563
+f 3147 5010 9564
+f 9565 9566 9567
+f 9568 9562 9569
+f 9570 9571 9572
+f 9573 9574 9575
+f 9576 9570 9577
+f 9578 9572 9571
+f 9579 9580 9459
+f 9572 9577 9570
+f 6909 9581 6013
+f 9577 9582 9576
+f 596 598 9206
+f 9583 9584 9585
+f 1953 8708 9415
+f 9111 9586 6500
+f 6651 9100 8512
+f 9492 684 580
+f 8745 8747 9587
+f 9588 8745 9587
+f 9005 8745 9588
+f 9495 9005 9588
+f 5949 9589 9590
+f 9418 9113 889
+f 3116 3119 9498
+f 3119 3118 9591
+f 9592 8309 9593
+f 2186 9594 2187
+f 9595 9596 9597
+f 9225 9342 1151
+f 9598 9594 1967
+f 9599 4758 4757
+f 2458 2730 3212
+f 9600 9601 9502
+f 9501 9600 9502
+f 9601 9602 9503
+f 9502 9601 9503
+f 9602 9603 9504
+f 9503 9602 9504
+f 9604 9505 9504
+f 9603 9604 9504
+f 9605 9506 9505
+f 9604 9605 9505
+f 9606 9507 9506
+f 9605 9606 9506
+f 9607 9508 9507
+f 9606 9607 9507
+f 9608 9509 9508
+f 9607 9608 9508
+f 9609 9510 9509
+f 9608 9609 9509
+f 9610 9511 9510
+f 9609 9610 9510
+f 9611 9512 9511
+f 9610 9611 9511
+f 9612 9513 9512
+f 9611 9612 9512
+f 9613 9514 9513
+f 9612 9613 9513
+f 6575 9515 9514
+f 9613 6575 9514
+f 2676 9614 2674
+f 6575 6574 9515
+f 9615 9227 9491
+f 9616 9228 9227
+f 4296 9522 8688
+f 4294 4296 8688
+f 9617 3914 3912
+f 9530 9617 3912
+f 9618 8461 8378
+f 6910 6598 6599
+f 9532 9618 8378
+f 4017 5091 5733
+f 4709 5868 2692
+f 5619 5620 9619
+f 2319 2325 2327
+f 8197 4250 6295
+f 5011 5013 5302
+f 4252 4255 5631
+f 5330 4885 5316
+f 4913 5589 4914
+f 4737 5218 5461
+f 3636 2689 2686
+f 4405 2690 4900
+f 9620 9621 9622
+f 3100 4877 4407
+f 3382 5921 5738
+f 8675 5738 8463
+f 7333 8677 7334
+f 7119 6035 7333
+f 6907 6439 4874
+f 9145 8800 4876
+f 5453 9623 8291
+f 9624 9582 9625
+f 6701 5333 5314
+f 9626 7934 8885
+f 6011 3929 5594
+f 5590 5589 7649
+f 5854 4588 5449
+f 8291 6712 5308
+f 3684 3683 5591
+f 9627 9628 9629
+f 9630 2957 9631
+f 4022 6891 4020
+f 9632 9633 9634
+f 8198 2971 2972
+f 8569 8417 8499
+f 9618 1642 8461
+f 9635 9636 9637
+f 9638 3916 3914
+f 8358 8360 2747
+f 4910 4903 6439
+f 4570 5307 4852
+f 9639 9640 9641
+f 5176 5178 4245
+f 8926 5482 7006
+f 9642 9643 9535
+f 8111 8367 5536
+f 9643 9644 9536
+f 9535 9643 9536
+f 9644 9645 9537
+f 9536 9644 9537
+f 9645 9646 9538
+f 9537 9645 9538
+f 9646 9647 9539
+f 9538 9646 9539
+f 9541 9648 9649
+f 9539 9647 9540
+f 1288 1185 1011
+f 1603 2729 2823
+f 9320 9480 865
+f 8826 1331 1002
+f 2792 2793 8851
+f 284 9650 340
+f 8729 9079 8854
+f 8851 2793 8852
+f 3984 9479 8600
+f 9173 9297 8856
+f 1265 8627 9552
+f 3984 9399 9479
+f 9651 9652 9653
+f 9654 9655 9656
+f 9657 9658 9659
+f 7736 9660 9661
+f 9187 9312 8997
+f 9210 9662 9663
+f 9479 9474 8507
+f 9186 9315 8738
+f 9011 9664 9012
+f 9405 9097 8608
+f 9665 9666 9667
+f 8744 6943 8733
+f 9487 9486 9203
+f 1534 9668 1532
+f 2116 9669 8752
+f 8610 8509 9484
+f 581 1691 582
+f 9670 4160 4162
+f 9671 9672 9559
+f 7066 672 7067
+f 9672 9673 9560
+f 9559 9672 9560
+f 9673 9674 9562
+f 9560 9673 9562
+f 9674 9675 9569
+f 9562 9674 9569
+f 9675 9676 9578
+f 9569 9675 9578
+f 9677 9572 9578
+f 9676 9677 9578
+f 9678 9577 9572
+f 9677 9678 9572
+f 9679 9582 9577
+f 9678 9679 9577
+f 9680 9583 9582
+f 9679 9680 9582
+f 889 891 1153
+f 9681 9682 9683
+f 8747 8878 9423
+f 3634 3184 2517
+f 9587 8747 9423
+f 8878 8875 7568
+f 9101 9005 9495
+f 9424 9416 9493
+f 9336 881 890
+f 9113 9336 890
+f 9497 3119 9591
+f 9486 9485 1019
+f 3797 3977 4192
+f 7194 7429 7426
+f 9494 9495 1402
+f 1154 9225 1151
+f 9684 9685 9600
+f 9686 9687 9688
+f 9689 9601 9600
+f 9685 9689 9600
+f 9690 9602 9601
+f 9689 9690 9601
+f 9691 9603 9602
+f 9690 9691 9602
+f 9692 9604 9603
+f 9691 9692 9603
+f 9693 9605 9604
+f 9692 9693 9604
+f 9694 9606 9605
+f 9693 9694 9605
+f 9695 9607 9606
+f 9694 9695 9606
+f 9696 9608 9607
+f 9695 9696 9607
+f 9697 9609 9608
+f 9696 9697 9608
+f 9698 9610 9609
+f 9697 9698 9609
+f 9699 9611 9610
+f 9698 9699 9610
+f 9700 9612 9611
+f 9699 9700 9611
+f 9701 9613 9612
+f 9700 9701 9612
+f 9702 6575 9613
+f 9701 9702 9613
+f 3003 7062 3004
+f 9703 9704 9705
+f 8915 5468 5467
+f 9706 9707 9040
+f 4298 9444 9522
+f 3720 1795 1797
+f 9617 9638 3914
+f 4127 8283 8020
+f 9708 3952 3916
+f 9354 9543 2989
+f 4793 9254 5790
+f 9638 9708 3916
+f 4917 4752 8118
+f 9709 4703 9710
+f 6138 5619 9619
+f 9711 9712 9713
+f 3445 3867 4063
+f 9714 7012 9715
+f 8291 9623 6712
+f 5594 3929 4286
+f 5218 5590 7841
+f 4709 2692 2689
+f 9716 693 3386
+f 6479 6322 4035
+f 3823 3742 3745
+f 5739 5737 8674
+f 4604 5739 8674
+f 5879 5881 7034
+f 6999 5879 7034
+f 5019 7135 4726
+f 8800 6907 4873
+f 4876 8800 4873
+f 4239 4383 6803
+f 2883 2879 2884
+f 5177 6701 5314
+f 5589 6011 4914
+f 4914 6011 5594
+f 4571 8291 5308
+f 9623 6460 6712
+f 6007 4407 4038
+f 4272 4274 4711
+f 3506 3892 3503
+f 3888 3502 3503
+f 4127 4294 8283
+f 9717 410 9718
+f 9719 4101 3952
+f 1693 1763 3724
+f 9708 9719 3952
+f 9720 5473 6714
+f 4279 4273 4892
+f 4807 4809 5669
+f 9721 8955 2990
+f 4570 4571 5307
+f 6316 4710 5173
+f 9642 9535 9534
+f 3290 5482 8926
+f 9722 9723 9643
+f 9642 9722 9643
+f 9723 9724 9644
+f 9643 9723 9644
+f 9724 9725 9645
+f 9644 9724 9645
+f 9725 9726 9646
+f 9645 9725 9646
+f 9726 9727 9647
+f 9646 9726 9647
+f 9728 9648 9729
+f 9647 9727 9541
+f 9553 9554 1149
+f 9076 8826 1002
+f 8971 3416 8972
+f 8826 8982 4773
+f 8854 9173 8856
+f 8849 2792 8851
+f 3411 3980 8599
+f 9297 3418 8974
+f 9730 9731 9732
+f 3980 3984 8600
+f 9650 9553 340
+f 3012 8992 3013
+f 1415 9733 2184
+f 9734 9735 9736
+f 8987 9085 8735
+f 9737 1968 9738
+f 9405 9313 9097
+f 9186 8868 8996
+f 5116 5118 9739
+f 9313 9205 9097
+f 9220 9214 9213
+f 9740 9398 2626
+f 8730 8855 9218
+f 1328 9172 1709
+f 5438 1536 9276
+f 8601 8610 9484
+f 9741 9742 7157
+f 3000 9743 7237
+f 9742 9744 9671
+f 9559 7066 9671
+f 9744 9745 9672
+f 9671 9744 9672
+f 9745 9746 9673
+f 9672 9745 9673
+f 9746 9747 9674
+f 9673 9746 9674
+f 9747 9748 9675
+f 9674 9747 9675
+f 9748 9749 9676
+f 9675 9748 9676
+f 9750 9677 9676
+f 9749 9750 9676
+f 9751 9678 9677
+f 9750 9751 9677
+f 9752 9679 9678
+f 9751 9752 9678
+f 9753 9680 9679
+f 9752 9753 9679
+f 9754 9681 9680
+f 9753 9754 9680
+f 9682 8626 9755
+f 9754 9682 9681
+f 9225 9104 9342
+f 8626 9756 8624
+f 9417 9101 9494
+f 9493 9417 9494
+f 8623 895 882
+f 8622 8623 882
+f 9485 1020 1019
+f 8754 8208 8207
+f 3718 9757 3902
+f 9342 9424 1158
+f 7762 8753 1489
+f 9424 9493 1253
+f 1158 9424 1253
+f 2894 9685 9684
+f 6484 6483 9688
+f 2894 9758 9689
+f 9685 2894 9689
+f 9759 9690 9689
+f 9758 9759 9689
+f 9759 9760 9691
+f 9690 9759 9691
+f 9760 9761 9692
+f 9691 9760 9692
+f 9761 9762 9693
+f 9692 9761 9693
+f 9763 9694 9693
+f 9762 9763 9693
+f 9764 9695 9694
+f 9763 9764 9694
+f 9765 9696 9695
+f 9764 9765 9695
+f 9766 9697 9696
+f 9765 9766 9696
+f 9767 9698 9697
+f 9766 9767 9697
+f 9768 9699 9698
+f 9767 9768 9698
+f 9769 9700 9699
+f 9768 9769 9699
+f 9770 9701 9700
+f 9769 9770 9700
+f 774 9702 9701
+f 9770 774 9701
+f 9771 4000 3218
+f 9772 9597 9773
+f 9151 4618 3942
+f 3941 9151 3942
+f 8667 9774 7636
+f 9108 3207 3209
+f 4108 4117 8020
+f 4138 4108 8020
+f 9775 4103 4101
+f 9719 9775 4101
+f 9775 9776 4105
+f 5880 4021 7056
+f 6141 4382 5717
+f 9777 9778 9779
+f 6352 6351 6140
+f 9779 5165 6300
+f 4608 3684 4383
+f 4896 7453 8023
+f 4391 4393 5346
+f 9714 9715 6460
+f 4903 3935 3937
+f 4217 4224 5327
+f 4006 5306 7743
+f 5874 6316 4853
+f 3925 3823 3745
+f 9637 9231 9635
+f 8674 5737 8675
+f 5737 5738 8675
+f 5733 5091 5075
+f 7951 5364 1645
+f 6892 5879 6999
+f 6166 6892 6999
+f 9780 6021 2869
+f 928 6754 9781
+f 3636 4709 2689
+f 3482 4885 5330
+f 3929 3931 4286
+f 3936 3291 4730
+f 4391 6444 9782
+f 7012 4391 9782
+f 9783 4729 8464
+f 4436 5713 4688
+f 2958 5897 2956
+f 5897 5899 2956
+f 6034 6812 8677
+f 8918 8838 7039
+f 4371 7726 6134
+f 6352 6140 6708
+f 4262 4277 2878
+f 5894 5877 5624
+f 6156 3627 3629
+f 6250 6249 6379
+f 4560 9784 5633
+f 876 3754 3753
+f 4569 4570 4852
+f 4571 5308 5307
+f 9785 9786 9722
+f 392 391 9787
+f 9786 9788 9723
+f 9722 9786 9723
+f 9788 9789 9724
+f 9723 9788 9724
+f 9790 9725 9724
+f 9789 9790 9724
+f 9790 9791 9726
+f 9725 9790 9726
+f 9791 9729 9727
+f 9726 9791 9727
+f 9792 9793 9728
+f 9727 9729 9648
+f 3414 2792 8849
+f 8983 9650 284
+f 8856 9297 8974
+f 8972 3414 8849
+f 7339 4733 4735
+f 3418 3420 8975
+f 1572 1575 9794
+f 9795 3983 9796
+f 1149 9554 273
+f 8961 3012 3014
+f 4486 9220 9213
+f 6507 1815 1817
+f 8734 8987 8735
+f 9471 9797 8813
+f 9187 8997 9205
+f 9085 8970 8866
+f 1832 9483 8627
+f 9313 9187 9205
+f 9798 8051 9799
+f 9800 9801 9802
+f 9803 9804 8049
+f 6894 9805 6895
+f 9804 9806 9807
+f 9808 9809 9810
+f 9806 9811 9741
+f 9807 9806 9741
+f 9811 9812 9742
+f 9741 9811 9742
+f 9812 9813 9744
+f 9742 9812 9744
+f 9813 9814 9745
+f 9744 9813 9745
+f 9814 9815 9746
+f 9745 9814 9746
+f 9816 9747 9746
+f 9815 9816 9746
+f 9817 9748 9747
+f 9816 9817 9747
+f 9818 9749 9748
+f 9817 9818 9748
+f 9818 9819 9750
+f 9749 9818 9750
+f 9819 9820 9751
+f 9750 9819 9751
+f 9820 9821 9752
+f 9751 9820 9752
+f 9822 9753 9752
+f 9821 9822 9752
+f 9823 9754 9753
+f 9822 9823 9753
+f 9824 9682 9754
+f 9823 9824 9754
+f 9756 8626 9682
+f 9824 9756 9682
+f 8751 9425 895
+f 9825 8624 9826
+f 8623 8751 895
+f 8881 9343 9425
+f 6161 6160 7658
+f 7568 8303 7569
+f 7658 7657 6624
+f 7657 4379 6624
+f 9493 9494 1258
+f 6825 9827 9828
+f 1253 9493 1258
+f 1151 9342 1158
+f 9829 2892 9830
+f 9830 2892 9684
+f 9831 9758 2894
+f 9832 9833 8127
+f 9831 9834 9759
+f 9758 9831 9759
+f 9834 9835 9760
+f 9759 9834 9760
+f 9835 9836 9761
+f 9760 9835 9761
+f 9837 9762 9761
+f 9836 9837 9761
+f 9838 9763 9762
+f 9837 9838 9762
+f 9839 9764 9763
+f 9838 9839 9763
+f 9840 9765 9764
+f 9839 9840 9764
+f 9841 9766 9765
+f 9840 9841 9765
+f 9842 9767 9766
+f 9841 9842 9766
+f 9843 9768 9767
+f 9842 9843 9767
+f 9844 9769 9768
+f 9843 9844 9768
+f 9845 9770 9769
+f 9844 9845 9769
+f 9846 774 9770
+f 9845 9846 9770
+f 5745 9442 5746
+f 9340 9118 9847
+f 5051 9151 3941
+f 5052 5051 3941
+f 7636 9774 3696
+f 9848 5214 4231
+f 4102 4233 5003
+f 3953 4102 5003
+f 4103 9775 4105
+f 9849 4107 4105
+f 5724 4917 8118
+f 6135 6296 7002
+f 4236 4237 5726
+f 5892 5894 5200
+f 5877 5876 5624
+f 4282 7848 5187
+f 392 9787 8368
+f 8290 3566 5481
+f 7835 3573 6813
+f 3632 4858 3754
+f 6813 8927 8290
+f 5042 6172 6065
+f 3076 4006 7743
+f 9850 9851 5053
+f 6445 6444 6205
+f 5447 5450 5448
+f 5199 5201 3661
+f 5091 4019 5092
+f 9776 9849 4105
+f 6891 6167 9852
+f 9853 9854 9855
+f 4408 4238 4409
+f 5747 5749 9620
+f 3925 3745 3744
+f 3839 3925 3744
+f 5091 4017 4019
+f 4019 4018 5593
+f 6444 4391 5346
+f 7012 9782 9715
+f 5159 9706 9153
+f 2878 2697 2696
+f 5892 5200 5199
+f 5767 5892 5199
+f 2876 4705 6296
+f 3086 2876 6296
+f 6910 8027 6598
+f 3937 4730 4732
+f 5468 4077 4076
+f 5767 5199 3660
+f 4234 4872 4235
+f 5857 5181 4597
+f 9623 9714 6460
+f 6065 6172 5090
+f 7006 5176 4245
+f 4711 4569 5173
+f 9856 9857 9786
+f 9858 5534 6252
+f 9857 9859 9788
+f 9786 9857 9788
+f 9859 9860 9789
+f 9788 9859 9789
+f 9860 9861 9790
+f 9789 9860 9790
+f 9861 9862 9791
+f 9790 9861 9791
+f 9862 9863 9729
+f 9791 9862 9729
+f 9863 9864 9728
+f 9729 9863 9728
+f 9864 9865 9792
+f 3510 807 9866
+f 9865 9867 9868
+f 9869 9870 9868
+f 9867 9871 9869
+f 9868 9867 9869
+f 9871 9872 9873
+f 9869 9871 9873
+f 9872 9874 9875
+f 9875 9874 9876
+f 9874 9877 9876
+f 8735 9085 8866
+f 9877 9878 9879
+f 9879 9880 9881
+f 9878 9882 9883
+f 9884 9883 9882
+f 9882 9885 9884
+f 9799 9886 9884
+f 9885 9887 9803
+f 9884 9885 9803
+f 9887 9888 9804
+f 9803 9887 9804
+f 9888 9889 9806
+f 9804 9888 9806
+f 9889 9890 9811
+f 9806 9889 9811
+f 9890 9891 9812
+f 9811 9890 9812
+f 9891 9892 9813
+f 9812 9891 9813
+f 9892 9893 9814
+f 9813 9892 9814
+f 9893 9894 9815
+f 9814 9893 9815
+f 9895 9816 9815
+f 9894 9895 9815
+f 9896 9817 9816
+f 9895 9896 9816
+f 9896 9897 9818
+f 9817 9896 9818
+f 9897 9898 9819
+f 9818 9897 9819
+f 9899 9820 9819
+f 9898 9899 9819
+f 9899 9900 9821
+f 9820 9899 9821
+f 9901 9822 9821
+f 9900 9901 9821
+f 9902 9823 9822
+f 9901 9902 9822
+f 9903 9824 9823
+f 9902 9903 9823
+f 9904 9756 9824
+f 9903 9904 9824
+f 9826 8624 9756
+f 9904 9826 9756
+f 1498 3233 7476
+f 3835 9905 3148
+f 9906 9907 9908
+f 9098 9209 9482
+f 7561 962 7541
+f 3323 2907 4096
+f 9423 7568 1264
+f 1263 9587 1249
+f 1017 9112 1154
+f 9495 9588 1261
+f 9909 9910 9911
+f 8895 8894 9912
+f 9913 9914 9831
+f 181 9915 9916
+f 9914 9917 9834
+f 9831 9914 9834
+f 9918 9835 9834
+f 9917 9918 9834
+f 9919 9836 9835
+f 9918 9919 9835
+f 9920 9837 9836
+f 9919 9920 9836
+f 9921 9838 9837
+f 9920 9921 9837
+f 9922 9839 9838
+f 9921 9922 9838
+f 9923 9840 9839
+f 9922 9923 9839
+f 9924 9841 9840
+f 9923 9924 9840
+f 9925 9842 9841
+f 9924 9925 9841
+f 9926 9843 9842
+f 9925 9926 9842
+f 9927 9844 9843
+f 9926 9927 9843
+f 9928 9845 9844
+f 9927 9928 9844
+f 9929 9846 9845
+f 9928 9929 9845
+f 8466 775 9846
+f 9929 8466 9846
+f 3690 3689 5052
+f 1651 7951 906
+f 5223 9848 4231
+f 9930 6048 5214
+f 3953 5003 6572
+f 3917 3953 6572
+f 9931 4116 4107
+f 9849 9931 4107
+f 3174 3173 4278
+f 5203 5625 3466
+f 5646 3660 6304
+f 5505 5646 6304
+f 4206 5445 6136
+f 7741 7848 4282
+f 6427 8561 3824
+f 8561 9932 3824
+f 8927 3566 8290
+f 3566 3568 5481
+f 5031 5172 878
+f 5044 6586 5045
+f 6316 5173 4853
+f 4084 4083 1471
+f 3469 3471 5723
+f 6173 4857 5073
+f 4900 2690 4418
+f 3844 5466 4589
+f 6892 4022 5879
+f 4022 5880 5879
+f 5749 5741 4603
+f 9620 5749 4603
+f 5669 5671 9933
+f 9934 7202 6916
+f 5593 4217 5327
+f 4018 4217 5593
+f 5346 4393 5347
+f 4393 4028 5347
+f 3573 3572 8927
+f 5445 4892 6136
+f 5505 6304 3821
+f 5894 5624 5200
+f 4728 5193 4241
+f 6009 6008 3842
+f 5092 3845 3848
+f 5204 3327 6709
+f 5646 5767 3660
+f 5352 3821 3924
+f 3862 5857 4597
+f 6304 3660 3662
+f 5347 4028 7835
+f 3573 8927 6813
+f 9856 9786 9785
+f 8925 3290 8926
+f 9935 9936 9857
+f 9856 9935 9857
+f 9936 9937 9859
+f 9857 9936 9859
+f 9937 9938 9860
+f 9859 9937 9860
+f 9938 9939 9861
+f 9860 9938 9861
+f 9939 9940 9862
+f 9861 9939 9862
+f 9940 9941 9863
+f 9862 9940 9863
+f 9941 9942 9864
+f 9863 9941 9864
+f 9943 9865 9864
+f 9942 9943 9864
+f 9943 9944 9867
+f 9865 9943 9867
+f 9944 9945 9871
+f 9867 9944 9871
+f 9663 5929 9946
+f 9871 9945 9872
+f 9198 8973 8734
+f 9543 9721 2990
+f 3898 2819 2818
+f 9947 9911 9910
+f 6898 5237 5236
+f 2996 9948 7362
+f 9949 9882 9878
+f 9950 9949 9878
+f 9951 9885 9882
+f 9949 9951 9882
+f 9952 9887 9885
+f 9951 9952 9885
+f 9953 9888 9887
+f 9952 9953 9887
+f 9954 9889 9888
+f 9953 9954 9888
+f 9955 9890 9889
+f 9954 9955 9889
+f 9955 9956 9891
+f 9890 9955 9891
+f 9956 9957 9892
+f 9891 9956 9892
+f 9957 9958 9893
+f 9892 9957 9893
+f 9958 9959 9894
+f 9893 9958 9894
+f 9959 9960 9895
+f 9894 9959 9895
+f 9961 9896 9895
+f 9960 9961 9895
+f 9961 9962 9897
+f 9896 9961 9897
+f 9963 9898 9897
+f 9962 9963 9897
+f 9963 9964 9899
+f 9898 9963 9899
+f 9964 9965 9900
+f 9899 9964 9900
+f 9966 9901 9900
+f 9965 9966 9900
+f 9967 9902 9901
+f 9966 9967 9901
+f 9968 9903 9902
+f 9967 9968 9902
+f 9969 9904 9903
+f 9968 9969 9903
+f 9970 9826 9904
+f 9969 9970 9904
+f 9971 9972 9826
+f 9970 9971 9826
+f 5930 5754 3147
+f 4950 4951 7866
+f 9973 7111 7110
+f 7731 9973 7110
+f 9773 9596 9974
+f 8104 8106 7111
+f 1402 9495 1261
+f 1258 9494 1402
+f 9975 9976 9167
+f 837 8207 838
+f 9167 9166 9913
+f 9913 9166 9914
+f 9977 9917 9914
+f 6502 3443 6503
+f 9978 9918 9917
+f 9977 9978 9917
+f 9979 9919 9918
+f 9978 9979 9918
+f 9980 9920 9919
+f 9979 9980 9919
+f 9981 9921 9920
+f 9980 9981 9920
+f 9982 9922 9921
+f 9981 9982 9921
+f 9983 9923 9922
+f 9982 9983 9922
+f 9984 9924 9923
+f 9983 9984 9923
+f 9985 9925 9924
+f 9984 9985 9924
+f 9986 9926 9925
+f 9985 9986 9925
+f 9987 9927 9926
+f 9986 9987 9926
+f 9988 9928 9927
+f 9987 9988 9927
+f 9989 9929 9928
+f 9988 9989 9928
+f 9990 8466 9929
+f 9989 9990 9929
+f 906 905 1651
+f 9990 906 8466
+f 9848 9930 5214
+f 9991 9992 6048
+f 3917 6572 9993
+f 3915 3917 9993
+f 9994 4126 4116
+f 9931 9994 4116
+f 9995 4293 4126
+f 3897 4582 2948
+f 9137 9996 9997
+f 4696 3924 5228
+f 3671 5213 5034
+f 4694 5228 5227
+f 2865 2886 2866
+f 4872 5581 4736
+f 6136 5336 4207
+f 7835 6813 6208
+f 4206 6136 4207
+f 5348 5347 6207
+f 9998 9999 6742
+f 2640 6213 2641
+f 2640 10000 10001
+f 3865 4440 4405
+f 6809 10002 6807
+f 3067 5861 3068
+f 4727 5038 5343
+f 6803 6448 4751
+f 5741 5739 4604
+f 4603 5741 4604
+f 5338 4029 3827
+f 10003 7125 8218
+f 5043 5042 6065
+f 4224 4539 5328
+f 5481 3568 4385
+f 4028 3573 7835
+f 4283 3567 3566
+f 5445 4206 2698
+f 4701 6065 5090
+f 5352 5505 3821
+f 3277 3863 8024
+f 8204 5490 9456
+f 9450 8204 9456
+f 5490 10004 9458
+f 4696 5352 3924
+f 4007 4852 4008
+f 2697 5445 2698
+f 4710 4711 5173
+f 2969 5342 5084
+f 4385 3632 3754
+f 8462 10005 9935
+f 9935 10006 10007
+f 10005 10008 9936
+f 9935 10005 9936
+f 10008 10009 9937
+f 9936 10008 9937
+f 10009 10010 9938
+f 9937 10009 9938
+f 10010 10011 9939
+f 9938 10010 9939
+f 10011 10012 9940
+f 9939 10011 9940
+f 10012 10013 9941
+f 9940 10012 9941
+f 10013 10014 9942
+f 9941 10013 9942
+f 10014 10015 9943
+f 9942 10014 9943
+f 10016 10017 9388
+f 9943 10015 9944
+f 10018 10019 10020
+f 6895 9805 10021
+f 1067 8870 9000
+f 2349 2348 9136
+f 9312 8996 8997
+f 9491 9227 227
+f 1044 1043 8741
+f 9304 1265 9552
+f 10022 10023 10024
+f 9732 9731 10025
+f 10026 10027 9949
+f 9950 10026 9949
+f 10028 9951 9949
+f 10027 10028 9949
+f 10029 9952 9951
+f 10028 10029 9951
+f 10030 9953 9952
+f 10029 10030 9952
+f 10031 9954 9953
+f 10030 10031 9953
+f 10031 10032 9955
+f 9954 10031 9955
+f 10032 10033 9956
+f 9955 10032 9956
+f 10033 10034 9957
+f 9956 10033 9957
+f 10034 10035 9958
+f 9957 10034 9958
+f 10035 10036 9959
+f 9958 10035 9959
+f 10036 10037 9960
+f 9959 10036 9960
+f 10037 10038 9961
+f 9960 10037 9961
+f 10038 10039 9962
+f 9961 10038 9962
+f 10040 9963 9962
+f 10039 10040 9962
+f 10040 10041 9964
+f 9963 10040 9964
+f 10042 9965 9964
+f 10041 10042 9964
+f 10043 9966 9965
+f 10042 10043 9965
+f 10044 9967 9966
+f 10043 10044 9966
+f 10045 9968 9967
+f 10044 10045 9967
+f 10046 9969 9968
+f 10045 10046 9968
+f 10047 9970 9969
+f 10046 10047 9969
+f 10047 7768 9971
+f 9970 10047 9971
+f 8503 7770 10048
+f 10049 5930 3146
+f 9973 8104 7111
+f 8105 5190 8106
+f 7920 7921 10050
+f 10051 7920 10050
+f 9017 9112 1017
+f 9588 9587 1263
+f 9114 9020 10052
+f 8894 9017 1400
+f 9114 10052 10053
+f 9226 9114 10053
+f 9425 9343 10054
+f 9226 10053 10055
+f 10056 9978 9977
+f 7450 7449 578
+f 10057 9979 9978
+f 10056 10057 9978
+f 10058 9980 9979
+f 10057 10058 9979
+f 10059 9981 9980
+f 10058 10059 9980
+f 10060 9982 9981
+f 10059 10060 9981
+f 10061 9983 9982
+f 10060 10061 9982
+f 10062 9984 9983
+f 10061 10062 9983
+f 10063 9985 9984
+f 10062 10063 9984
+f 10064 9986 9985
+f 10063 10064 9985
+f 10065 9987 9986
+f 10064 10065 9986
+f 10066 9988 9987
+f 10065 10066 9987
+f 10067 9989 9988
+f 10066 10067 9988
+f 10068 9990 9989
+f 10067 10068 9989
+f 1039 904 10069
+f 10068 904 9990
+f 9930 9991 6048
+f 8280 10070 9992
+f 3915 9993 5058
+f 3913 3915 5058
+f 9994 9995 4126
+f 10071 4295 4293
+f 2754 1099 7444
+f 9456 5490 9458
+f 10004 10072 9524
+f 4694 4696 5228
+f 4550 4694 5227
+f 1979 1981 6743
+f 4026 8563 6427
+f 10073 10074 9280
+f 10074 4403 9280
+f 4028 3571 3573
+f 6323 4026 2883
+f 3572 4283 8927
+f 4026 6427 2879
+f 4613 3483 3683
+f 10075 10076 8699
+f 4409 4238 3470
+f 4719 5032 3476
+f 10001 6809 3627
+f 4729 3099 3101
+f 2640 10001 9382
+f 9382 10001 3627
+f 6323 10077 8563
+f 6214 2640 9382
+f 4858 2969 2968
+f 6586 5864 5045
+f 3825 5023 5455
+f 3568 3632 4385
+f 3633 4854 3170
+f 4892 4710 6316
+f 9458 10004 9524
+f 7458 7461 7654
+f 10072 10078 9532
+f 9524 10072 9532
+f 4854 3376 3170
+f 10078 10079 9618
+f 6136 4892 6316
+f 6444 5346 6205
+f 3754 4858 2968
+f 5022 5345 5455
+f 5440 10080 10005
+f 8462 10007 10081
+f 10080 10082 10008
+f 10005 10080 10008
+f 10082 10083 10009
+f 10008 10082 10009
+f 10083 10084 10010
+f 10009 10083 10010
+f 10084 10085 10011
+f 10010 10084 10011
+f 10085 10086 10012
+f 10011 10085 10012
+f 10086 10087 10013
+f 10012 10086 10013
+f 10087 10088 10014
+f 10013 10087 10014
+f 10088 10089 10015
+f 10014 10088 10015
+f 9215 9094 9216
+f 9728 9864 9792
+f 5781 5780 3221
+f 1687 1693 10090
+f 4625 8682 10091
+f 7340 10092 4925
+f 8558 8963 10093
+f 10094 10095 10096
+f 9218 8855 9103
+f 7129 7128 9475
+f 8988 9094 9215
+f 9103 8988 9215
+f 9307 10097 9308
+f 9094 9198 9216
+f 10098 10099 10027
+f 10027 10099 10028
+f 10100 10101 10029
+f 10028 10100 10029
+f 10101 10102 10030
+f 10029 10101 10030
+f 10102 10103 10031
+f 10030 10102 10031
+f 10103 10104 10032
+f 10031 10103 10032
+f 10104 10105 10033
+f 10032 10104 10033
+f 10105 10106 10034
+f 10033 10105 10034
+f 10106 10107 10035
+f 10034 10106 10035
+f 10107 10108 10036
+f 10035 10107 10036
+f 10108 10109 10037
+f 10036 10108 10037
+f 10109 10110 10038
+f 10037 10109 10038
+f 10110 10111 10039
+f 10038 10110 10039
+f 10112 10040 10039
+f 10111 10112 10039
+f 10113 10041 10040
+f 10112 10113 10040
+f 10113 10114 10042
+f 10041 10113 10042
+f 10114 10115 10043
+f 10042 10114 10043
+f 10115 10116 10044
+f 10043 10115 10044
+f 10117 10045 10044
+f 10116 10117 10044
+f 10118 10046 10045
+f 10117 10118 10045
+f 10119 10047 10046
+f 10118 10119 10046
+f 7769 7768 10047
+f 10119 7769 10047
+f 7770 7769 10120
+f 5754 5010 3147
+f 7731 7110 7634
+f 3442 528 7639
+f 4743 3125 4738
+f 3333 7920 10051
+f 1156 8894 1400
+f 8895 9912 10121
+f 9020 10121 10052
+f 9425 10054 896
+f 895 9425 896
+f 9390 2968 2970
+f 9343 9226 10055
+f 10122 10123 10056
+f 10124 10122 10056
+f 10125 10057 10056
+f 10123 10125 10056
+f 10126 10058 10057
+f 10125 10126 10057
+f 10127 10059 10058
+f 10126 10127 10058
+f 10128 10060 10059
+f 10127 10128 10059
+f 10129 10061 10060
+f 10128 10129 10060
+f 10130 10062 10061
+f 10129 10130 10061
+f 10131 10063 10062
+f 10130 10131 10062
+f 10132 10064 10063
+f 10131 10132 10063
+f 10133 10065 10064
+f 10132 10133 10064
+f 10134 10066 10065
+f 10133 10134 10065
+f 10135 10067 10066
+f 10134 10135 10066
+f 10136 10068 10067
+f 10135 10136 10067
+f 10069 10137 1039
+f 10136 10069 10068
+f 9991 8280 9992
+f 8282 10138 10070
+f 10139 3728 5059
+f 5058 9993 10140
+f 9995 10071 4293
+f 10071 10141 4297
+f 10142 10143 10144
+f 10145 10146 10147
+f 5604 5089 4856
+f 5860 4593 8470
+f 5882 5889 5070
+f 5728 3251 4260
+f 7108 10148 10149
+f 4403 10074 1405
+f 4238 5627 4239
+f 10150 9615 9491
+f 4897 8023 9269
+f 7848 6623 5187
+f 9451 4897 9269
+f 5187 6623 5046
+f 2888 6158 5727
+f 3471 4916 4917
+f 3846 5327 8119
+f 4900 4418 4587
+f 3177 3844 4589
+f 8669 5192 8670
+f 5756 10151 5757
+f 8289 6479 4031
+f 3861 5859 3862
+f 4406 4044 5466
+f 9932 5023 3825
+f 5023 5022 5455
+f 5201 9626 5206
+f 6351 5037 6141
+f 9532 10078 9618
+f 10079 1325 1642
+f 9618 10079 1642
+f 10152 10153 10154
+f 4684 5055 5054
+f 2767 2766 10155
+f 5345 10073 7013
+f 5345 7013 5455
+f 10156 10157 10080
+f 8462 5440 10005
+f 10157 10158 10082
+f 10080 10157 10082
+f 10158 10159 10083
+f 10082 10158 10083
+f 10159 10160 10084
+f 10083 10159 10084
+f 10160 10161 10085
+f 10084 10160 10085
+f 10161 10162 10086
+f 10085 10161 10086
+f 10162 10163 10087
+f 10086 10162 10087
+f 10163 10164 10088
+f 10087 10163 10088
+f 10165 10166 10167
+f 10088 10164 10089
+f 9198 8734 8737
+f 9216 9198 8737
+f 8515 8730 9218
+f 8855 8988 9103
+f 2193 10168 10169
+f 10170 2191 10171
+f 10168 10172 10096
+f 10169 10168 10096
+f 10172 10173 10174
+f 10174 10175 10094
+f 10176 10177 10178
+f 10173 10178 10174
+f 8728 8616 8618
+f 2565 2505 10179
+f 8739 8728 8618
+f 8730 8515 8616
+f 10180 10181 10101
+f 10182 10183 8955
+f 10181 10184 10102
+f 10101 10181 10102
+f 10184 10185 10103
+f 10102 10184 10103
+f 10185 10186 10104
+f 10103 10185 10104
+f 10186 10187 10105
+f 10104 10186 10105
+f 10187 10188 10106
+f 10105 10187 10106
+f 10188 10189 10107
+f 10106 10188 10107
+f 10189 10190 10108
+f 10107 10189 10108
+f 10190 10191 10109
+f 10108 10190 10109
+f 10191 10192 10110
+f 10109 10191 10110
+f 10192 10193 10111
+f 10110 10192 10111
+f 10194 10112 10111
+f 10193 10194 10111
+f 10195 10113 10112
+f 10194 10195 10112
+f 10195 10196 10114
+f 10113 10195 10114
+f 10196 10197 10115
+f 10114 10196 10115
+f 10198 10116 10115
+f 10197 10198 10115
+f 10199 10117 10116
+f 10198 10199 10116
+f 10199 10200 10118
+f 10117 10199 10118
+f 10201 10119 10118
+f 10200 10201 10118
+f 10202 7769 10119
+f 10201 10202 10119
+f 10203 10204 10205
+f 10202 10120 7769
+f 6189 10206 3697
+f 5665 6432 2998
+f 4738 3333 10051
+f 7921 7923 4311
+f 9020 8895 10121
+f 10207 10208 10209
+f 10124 10210 10122
+f 9343 10055 10054
+f 10207 10211 10122
+f 3184 4463 3381
+f 10212 10123 10122
+f 10211 10212 10122
+f 10213 10125 10123
+f 10212 10213 10123
+f 10214 10126 10125
+f 10213 10214 10125
+f 10215 10127 10126
+f 10214 10215 10126
+f 10216 10128 10127
+f 10215 10216 10127
+f 10217 10129 10128
+f 10216 10217 10128
+f 10218 10130 10129
+f 10217 10218 10129
+f 10219 10131 10130
+f 10218 10219 10130
+f 10220 10132 10131
+f 10219 10220 10131
+f 10221 10133 10132
+f 10220 10221 10132
+f 10222 10134 10133
+f 10221 10222 10133
+f 10223 10135 10134
+f 10222 10223 10134
+f 10224 10136 10135
+f 10223 10224 10135
+f 10137 10069 10136
+f 10224 10137 10136
+f 8280 8282 10070
+f 7056 7019 6033
+f 3757 3913 5059
+f 5198 4741 10138
+f 4295 10071 4297
+f 6791 6790 7129
+f 10141 10225 4428
+f 10226 2655 10227
+f 877 5722 3587
+f 9774 964 3696
+f 6321 6320 5728
+f 9743 10228 10152
+f 4405 3635 2690
+f 5037 4380 6141
+f 3159 10229 10230
+f 4297 10141 4428
+f 10225 10231 4453
+f 4425 5041 8025
+f 4286 3931 4287
+f 5859 5857 3862
+f 3565 3078 3284
+f 3289 5483 5482
+f 4122 10232 1758
+f 5713 4871 4688
+f 9280 4403 3686
+f 4235 4737 5349
+f 8926 7006 6442
+f 4267 4265 8291
+f 6313 9382 6156
+f 8796 5167 4417
+f 6320 3249 5728
+f 3824 9932 3825
+f 10233 5009 5754
+f 6141 4380 4382
+f 2955 2954 3301
+f 3140 10234 5093
+f 4428 10225 4453
+f 10231 10235 4622
+f 5315 3939 10236
+f 6140 6596 6708
+f 3471 4917 5724
+f 10073 9280 7013
+f 10237 10238 10157
+f 10156 5440 5439
+f 10238 10239 10158
+f 10157 10238 10158
+f 10239 10240 10159
+f 10158 10239 10159
+f 10240 10241 10160
+f 10159 10240 10160
+f 10241 10242 10161
+f 10160 10241 10161
+f 10242 10243 10162
+f 10161 10242 10162
+f 10243 10244 10163
+f 10162 10243 10163
+f 10244 10245 10164
+f 10163 10244 10164
+f 10245 10246 10167
+f 10164 10245 10167
+f 10246 10247 10165
+f 10166 10165 2192
+f 10247 5953 2193
+f 10248 10249 10250
+f 1237 10251 10252
+f 8728 8730 8616
+f 5952 10253 10172
+f 718 10254 9526
+f 10253 10255 10173
+f 10172 10253 10173
+f 10255 10256 10178
+f 10173 10255 10178
+f 10257 10176 10178
+f 10256 10257 10178
+f 9721 10182 8955
+f 10257 10258 10176
+f 10258 10259 10181
+f 10180 10258 10181
+f 10259 10260 10184
+f 10181 10259 10184
+f 10260 10261 10185
+f 10184 10260 10185
+f 10261 10262 10186
+f 10185 10261 10186
+f 10262 10263 10187
+f 10186 10262 10187
+f 10263 10264 10188
+f 10187 10263 10188
+f 10264 10265 10189
+f 10188 10264 10189
+f 10265 10266 10190
+f 10189 10265 10190
+f 10266 10267 10191
+f 10190 10266 10191
+f 10267 10268 10192
+f 10191 10267 10192
+f 10269 10193 10192
+f 10268 10269 10192
+f 10270 10194 10193
+f 10269 10270 10193
+f 10270 10271 10195
+f 10194 10270 10195
+f 10272 10196 10195
+f 10271 10272 10195
+f 10273 10197 10196
+f 10272 10273 10196
+f 10273 10274 10198
+f 10197 10273 10198
+f 10275 10199 10198
+f 10274 10275 10198
+f 10275 10276 10200
+f 10199 10275 10200
+f 10276 10277 10201
+f 10200 10276 10201
+f 10278 10202 10201
+f 10277 10278 10201
+f 7053 9389 9388
+f 10278 10204 10202
+f 4311 7923 9054
+f 8016 3688 4402
+f 10050 7921 4311
+f 7923 8016 9054
+f 10279 10209 10280
+f 10281 10279 10280
+f 10279 10282 10207
+f 10209 10279 10207
+f 10283 10211 10207
+f 10282 10283 10207
+f 10284 10212 10211
+f 10283 10284 10211
+f 10285 10213 10212
+f 10284 10285 10212
+f 10286 10214 10213
+f 10285 10286 10213
+f 10287 10215 10214
+f 10286 10287 10214
+f 10288 10216 10215
+f 10287 10288 10215
+f 10289 10217 10216
+f 10288 10289 10216
+f 10290 10218 10217
+f 10289 10290 10217
+f 10291 10219 10218
+f 10290 10291 10218
+f 10292 10220 10219
+f 10291 10292 10219
+f 10293 10221 10220
+f 10292 10293 10220
+f 10294 10222 10221
+f 10293 10294 10221
+f 10295 10223 10222
+f 10294 10295 10222
+f 10296 10224 10223
+f 10295 10296 10223
+f 10148 10137 10224
+f 10296 10148 10224
+f 10297 10298 10299
+f 10148 7108 10137
+f 8282 5198 10138
+f 4134 10300 5626
+f 3923 4614 7246
+f 3142 10301 1103
+f 4453 10231 4622
+f 10235 10302 4766
+f 6033 7019 6034
+f 4249 4246 4247
+f 6034 6577 6812
+f 10303 10304 10305
+f 10306 4560 5633
+f 4845 3490 4406
+f 5175 5015 5014
+f 5167 5166 4417
+f 6143 4605 6428
+f 4034 3098 5217
+f 3680 5186 4562
+f 9452 9269 4066
+f 2768 9452 4066
+f 2769 2768 4066
+f 7848 7847 6623
+f 5231 3894 5229
+f 8023 4275 4263
+f 8031 1989 7932
+f 5335 4416 4586
+f 7850 10074 10073
+f 10307 7727 10308
+f 3140 3139 10234
+f 7850 7932 10074
+f 6214 9382 6313
+f 6911 3644 4878
+f 3830 3829 10309
+f 3872 3871 3085
+f 4854 4218 3376
+f 5488 7849 5345
+f 2219 2218 3698
+f 10310 10311 10312
+f 10313 10314 10238
+f 10237 10315 10316
+f 10314 10317 10239
+f 10238 10314 10239
+f 10317 10318 10240
+f 10239 10317 10240
+f 10318 10319 10241
+f 10240 10318 10241
+f 10319 10320 10242
+f 10241 10319 10242
+f 10320 10321 10243
+f 10242 10320 10243
+f 10321 10322 10244
+f 10243 10321 10244
+f 10322 10323 10245
+f 10244 10322 10245
+f 10323 10324 10246
+f 10245 10323 10246
+f 10324 10325 10247
+f 10246 10324 10247
+f 10325 5951 5953
+f 10247 10325 5953
+f 5951 10326 5952
+f 3963 10327 3964
+f 10326 10328 10253
+f 5952 10326 10253
+f 10328 10329 10255
+f 10253 10328 10255
+f 10330 10256 10255
+f 10329 10330 10255
+f 10330 10331 10257
+f 10256 10330 10257
+f 10332 10258 10257
+f 10331 10332 10257
+f 10332 10333 10259
+f 10258 10332 10259
+f 10333 10334 10260
+f 10259 10333 10260
+f 10334 10335 10261
+f 10260 10334 10261
+f 10335 10336 10262
+f 10261 10335 10262
+f 10336 10337 10263
+f 10262 10336 10263
+f 10337 10338 10264
+f 10263 10337 10264
+f 10338 10339 10265
+f 10264 10338 10265
+f 10339 10340 10266
+f 10265 10339 10266
+f 10340 10341 10267
+f 10266 10340 10267
+f 10341 10342 10268
+f 10267 10341 10268
+f 10342 10343 10269
+f 10268 10342 10269
+f 10343 10344 10270
+f 10269 10343 10270
+f 10345 10271 10270
+f 10344 10345 10270
+f 10346 10272 10271
+f 10345 10346 10271
+f 10347 10273 10272
+f 10346 10347 10272
+f 10347 10348 10274
+f 10273 10347 10274
+f 10349 10275 10274
+f 10348 10349 10274
+f 10350 10276 10275
+f 10349 10350 10275
+f 10350 10351 10277
+f 10276 10350 10277
+f 10352 10278 10277
+f 10351 10352 10277
+f 10353 10204 10278
+f 10352 10353 10278
+f 10354 8660 10355
+f 5644 5783 10356
+f 10357 8657 8660
+f 4133 10354 10355
+f 10354 10357 8660
+f 10358 10279 10281
+f 1357 10358 10281
+f 10358 10359 10282
+f 10279 10358 10282
+f 10359 10360 10283
+f 10282 10359 10283
+f 10361 10284 10283
+f 10360 10361 10283
+f 10362 10285 10284
+f 10361 10362 10284
+f 10363 10286 10285
+f 10362 10363 10285
+f 10364 10287 10286
+f 10363 10364 10286
+f 10365 10288 10287
+f 10364 10365 10287
+f 10366 10289 10288
+f 10365 10366 10288
+f 10367 10290 10289
+f 10366 10367 10289
+f 10368 10291 10290
+f 10367 10368 10290
+f 10369 10292 10291
+f 10368 10369 10291
+f 10370 10293 10292
+f 10369 10370 10292
+f 10371 10294 10293
+f 10370 10371 10293
+f 10372 10295 10294
+f 10371 10372 10294
+f 10373 10296 10295
+f 10372 10373 10295
+f 10374 10148 10296
+f 10373 10374 10296
+f 10375 9592 9593
+f 1115 10376 10377
+f 3946 4134 5626
+f 4133 10355 10300
+f 7131 10378 10379
+f 10380 10381 10382
+f 4622 10235 4766
+f 10302 10383 4930
+f 4866 5447 5446
+f 3090 2887 2886
+f 8799 4910 6907
+f 9782 6444 3641
+f 4879 4027 5189
+f 9782 3641 6180
+f 5443 4045 4047
+f 3166 5208 5160
+f 6460 9715 6177
+f 4064 3164 3248
+f 4705 4704 6144
+f 5207 4865 4864
+f 9715 9782 6180
+f 3327 3518 6709
+f 9715 6180 6177
+f 6792 4866 5446
+f 3165 5208 3166
+f 4901 4900 4587
+f 8800 8799 6907
+f 4254 5322 6009
+f 4903 3937 4732
+f 4766 10302 4930
+f 4915 3840 3842
+f 7849 7850 10073
+f 7849 10073 5345
+f 5166 4586 4417
+f 4605 4023 6428
+f 10384 10385 10314
+f 10316 10313 10237
+f 10385 10386 10317
+f 10314 10385 10317
+f 10386 10387 10318
+f 10317 10386 10318
+f 10387 10388 10319
+f 10318 10387 10319
+f 10388 10389 10320
+f 10319 10388 10320
+f 10389 10390 10321
+f 10320 10389 10321
+f 10390 10391 10322
+f 10321 10390 10322
+f 10391 10392 10323
+f 10322 10391 10323
+f 10392 10393 10324
+f 10323 10392 10324
+f 10393 10394 10325
+f 10324 10393 10325
+f 10394 10395 5951
+f 10325 10394 5951
+f 10395 10396 10326
+f 5951 10395 10326
+f 10396 10397 10328
+f 10326 10396 10328
+f 10397 10398 10329
+f 10328 10397 10329
+f 10399 10330 10329
+f 10398 10399 10329
+f 10399 10400 10331
+f 10330 10399 10331
+f 10400 10401 10332
+f 10331 10400 10332
+f 10401 10402 10333
+f 10332 10401 10333
+f 10402 10403 10334
+f 10333 10402 10334
+f 10403 10404 10335
+f 10334 10403 10335
+f 10404 10405 10336
+f 10335 10404 10336
+f 10405 10406 10337
+f 10336 10405 10337
+f 10406 10407 10338
+f 10337 10406 10338
+f 10407 10408 10339
+f 10338 10407 10339
+f 10409 10340 10339
+f 10408 10409 10339
+f 10410 10341 10340
+f 10409 10410 10340
+f 10411 10342 10341
+f 10410 10411 10341
+f 10411 10412 10343
+f 10342 10411 10343
+f 10412 10413 10344
+f 10343 10412 10344
+f 10414 10345 10344
+f 10413 10414 10344
+f 10414 10415 10346
+f 10345 10414 10346
+f 10415 10416 10347
+f 10346 10415 10347
+f 10417 10348 10347
+f 10416 10417 10347
+f 10418 10349 10348
+f 10417 10418 10348
+f 10419 10350 10349
+f 10418 10419 10349
+f 10420 10351 10350
+f 10419 10420 10350
+f 10420 10421 10352
+f 10351 10420 10352
+f 10421 10422 10353
+f 10352 10421 10353
+f 10423 9002 10424
+f 10422 10423 10353
+f 5544 10425 5545
+f 2644 10426 2642
+f 10427 10428 10429
+f 10430 2467 2469
+f 10431 10358 1357
+f 1357 10280 1358
+f 10432 10359 10358
+f 10431 10432 10358
+f 10433 10434 10435
+f 10359 10432 10360
+f 10436 10361 10360
+f 9381 10436 10360
+f 10436 10437 10362
+f 10361 10436 10362
+f 10438 10363 10362
+f 10437 10438 10362
+f 10439 10364 10363
+f 10438 10439 10363
+f 10440 10365 10364
+f 10439 10440 10364
+f 10441 10366 10365
+f 10440 10441 10365
+f 10442 10367 10366
+f 10441 10442 10366
+f 10443 10368 10367
+f 10442 10443 10367
+f 10444 10369 10368
+f 10443 10444 10368
+f 10444 10445 10370
+f 10369 10444 10370
+f 10446 10371 10370
+f 10445 10446 10370
+f 10447 10372 10371
+f 10446 10447 10371
+f 10448 10373 10372
+f 10447 10448 10372
+f 1417 10374 10373
+f 10448 1417 10373
+f 2531 2535 2370
+f 1417 10149 10374
+f 4134 4133 10300
+f 8779 8455 10449
+f 10450 10451 10452
+f 10453 544 677
+f 10383 10454 5007
+f 4930 10383 5007
+f 3273 3272 3278
+f 3852 4243 5183
+f 10454 10455 5094
+f 10456 10457 5491
+f 5489 5743 10004
+f 5490 5489 10004
+f 5743 8365 10072
+f 10004 5743 10072
+f 8365 8364 10078
+f 10072 8365 10078
+f 8364 3304 10079
+f 10078 8364 10079
+f 1323 3305 2278
+f 10079 3304 1325
+f 3126 4742 3307
+f 9993 6572 10458
+f 2716 10459 2717
+f 4423 4422 5011
+f 5015 5158 5016
+f 5166 5335 4586
+f 5581 4034 5217
+f 6622 6621 10385
+f 10460 10384 10313
+f 6621 10461 10386
+f 10385 6621 10386
+f 10462 10387 10386
+f 10461 10462 10386
+f 10462 10463 10388
+f 10387 10462 10388
+f 10463 10464 10389
+f 10388 10463 10389
+f 10464 10465 10390
+f 10389 10464 10390
+f 10465 10466 10391
+f 10390 10465 10391
+f 10466 10467 10392
+f 10391 10466 10392
+f 10467 10468 10393
+f 10392 10467 10393
+f 10468 10469 10394
+f 10393 10468 10394
+f 10469 10470 10395
+f 10394 10469 10395
+f 10470 10471 10396
+f 10395 10470 10396
+f 10471 10472 10397
+f 10396 10471 10397
+f 10472 10473 10398
+f 10397 10472 10398
+f 10474 10399 10398
+f 10473 10474 10398
+f 10475 10400 10399
+f 10474 10475 10399
+f 10475 10476 10401
+f 10400 10475 10401
+f 10476 10477 10402
+f 10401 10476 10402
+f 10477 10478 10403
+f 10402 10477 10403
+f 10478 10479 10404
+f 10403 10478 10404
+f 10479 10480 10405
+f 10404 10479 10405
+f 10480 10481 10406
+f 10405 10480 10406
+f 10482 10407 10406
+f 10481 10482 10406
+f 10482 10483 10408
+f 10407 10482 10408
+f 10484 10409 10408
+f 10483 10484 10408
+f 10485 10410 10409
+f 10484 10485 10409
+f 10486 10411 10410
+f 10485 10486 10410
+f 10486 10487 10412
+f 10411 10486 10412
+f 10487 10488 10413
+f 10412 10487 10413
+f 10489 10414 10413
+f 10488 10489 10413
+f 10489 10490 10415
+f 10414 10489 10415
+f 10491 10416 10415
+f 10490 10491 10415
+f 10492 10417 10416
+f 10491 10492 10416
+f 10492 10493 10418
+f 10417 10492 10418
+f 10493 10494 10419
+f 10418 10493 10419
+f 10495 10420 10419
+f 10494 10495 10419
+f 10496 10421 10420
+f 10495 10496 10420
+f 10497 10422 10421
+f 10496 10497 10421
+f 9003 9002 10497
+f 6689 6688 10498
+f 3159 10499 10229
+f 10500 3508 3507
+f 5007 10454 5094
+f 10455 10501 5184
+f 10502 10431 4760
+f 5094 10455 5184
+f 7643 8195 7644
+f 10503 10504 10505
+f 5344 5039 5887
+f 5594 4286 3843
+f 6908 10506 10436
+f 10432 6909 9381
+f 10506 10507 10437
+f 10436 10506 10437
+f 10508 10438 10437
+f 10507 10508 10437
+f 10509 10439 10438
+f 10508 10509 10438
+f 10510 10440 10439
+f 10509 10510 10439
+f 10511 10441 10440
+f 10510 10511 10440
+f 10511 10512 10442
+f 10441 10511 10442
+f 10513 10443 10442
+f 10512 10513 10442
+f 10514 10444 10443
+f 10513 10514 10443
+f 10515 10445 10444
+f 10514 10515 10444
+f 10516 10446 10445
+f 10515 10516 10445
+f 10516 10517 10447
+f 10446 10516 10447
+f 10518 10448 10447
+f 10517 10518 10447
+f 1418 1417 10448
+f 10518 1418 10448
+f 5736 5459 10519
+f 10518 10520 1418
+f 8457 8551 10521
+f 7448 8551 10522
+f 3139 3159 10230
+f 10499 10523 10229
+f 10501 10524 5325
+f 5184 10501 5325
+f 10525 2108 1112
+f 2954 3140 5093
+f 3175 4270 3173
+f 7041 8836 8211
+f 3863 3862 4598
+f 9269 4263 4066
+f 4210 4209 6621
+f 10526 10527 6622
+f 4209 10528 10461
+f 6621 4209 10461
+f 10528 10529 10462
+f 10461 10528 10462
+f 10529 10530 10463
+f 10462 10529 10463
+f 10531 10464 10463
+f 10530 10531 10463
+f 10531 10532 10465
+f 10464 10531 10465
+f 10532 10533 10466
+f 10465 10532 10466
+f 10533 10534 10467
+f 10466 10533 10467
+f 10534 10535 10468
+f 10467 10534 10468
+f 10535 10536 10469
+f 10468 10535 10469
+f 10537 10470 10469
+f 10536 10537 10469
+f 10538 10471 10470
+f 10537 10538 10470
+f 10538 10539 10472
+f 10471 10538 10472
+f 10539 10540 10473
+f 10472 10539 10473
+f 10540 10541 10474
+f 10473 10540 10474
+f 10542 10475 10474
+f 10541 10542 10474
+f 10542 10543 10476
+f 10475 10542 10476
+f 10543 10544 10477
+f 10476 10543 10477
+f 10544 10545 10478
+f 10477 10544 10478
+f 10545 10546 10479
+f 10478 10545 10479
+f 10546 10547 10480
+f 10479 10546 10480
+f 10547 10548 10481
+f 10480 10547 10481
+f 10549 10482 10481
+f 10548 10549 10481
+f 10550 10483 10482
+f 10549 10550 10482
+f 10551 10484 10483
+f 10550 10551 10483
+f 10552 10485 10484
+f 10551 10552 10484
+f 10552 10553 10486
+f 10485 10552 10486
+f 10553 10554 10487
+f 10486 10553 10487
+f 10554 10555 10488
+f 10487 10554 10488
+f 9783 10489 10488
+f 10555 9783 10488
+f 8464 10490 10489
+f 9783 8464 10489
+f 8464 8465 10491
+f 10490 8464 10491
+f 4037 10492 10491
+f 8465 4037 10491
+f 4037 4039 10493
+f 10492 4037 10493
+f 5723 10494 10493
+f 4039 5723 10493
+f 5724 10495 10494
+f 5723 5724 10494
+f 5724 8118 10496
+f 10495 5724 10496
+f 4016 10497 10496
+f 8118 4016 10496
+f 10449 8457 10521
+f 2564 3441 9999
+f 10556 10557 10558
+f 7735 10559 9660
+f 8977 10560 10561
+f 6058 10524 6056
+f 3139 10230 10234
+f 9088 8977 10562
+f 9381 6908 10436
+f 10563 10564 9581
+f 6013 5154 10506
+f 6908 6013 10506
+f 5154 7452 10507
+f 10506 5154 10507
+f 6449 10508 10507
+f 7452 6449 10507
+f 6449 5887 10509
+f 10508 6449 10509
+f 5887 5886 10510
+f 10509 5887 10510
+f 5886 5869 10511
+f 10510 5886 10511
+f 5869 6450 10512
+f 10511 5869 10512
+f 6450 6015 10513
+f 10512 6450 10513
+f 6015 6014 10514
+f 10513 6015 10514
+f 6020 10515 10514
+f 6014 6020 10514
+f 8025 10516 10515
+f 6020 8025 10515
+f 5597 10517 10516
+f 8025 5597 10516
+f 5596 10518 10517
+f 5597 5596 10517
+f 5596 10520 10518
+f 9004 4015 10565
+f 7557 5050 8121
+f 3328 6095 3329
+f 10521 8551 7447
+f 8022 7824 3555
+f 4111 10566 10567
+f 10568 10569 3360
+f 5086 7135 5087
+f 10570 10571 10572
+f 8476 8475 9087
+f 8117 4598 6708
+f 3376 4219 3377
+f 10573 5212 9270
+f 3470 4916 3471
+f 3100 4407 6007
+f 7847 4427 6623
+f 4208 7648 4209
+f 4210 10527 10574
+f 7648 5033 10528
+f 4209 7648 10528
+f 5033 5034 10529
+f 10528 5033 10529
+f 5034 3255 10530
+f 10529 5034 10530
+f 3255 3257 10531
+f 10530 3255 10531
+f 3257 5329 10532
+f 10531 3257 10532
+f 5329 5330 10533
+f 10532 5329 10533
+f 5330 5316 10534
+f 10533 5330 10534
+f 5316 4689 10535
+f 10534 5316 10535
+f 4688 10536 10535
+f 4689 4688 10535
+f 4871 10537 10536
+f 4688 4871 10536
+f 4870 10538 10537
+f 4871 4870 10537
+f 5718 10539 10538
+f 4870 5718 10538
+f 6026 10540 10539
+f 5718 6026 10539
+f 6026 5484 10541
+f 10540 6026 10541
+f 5484 5302 10542
+f 10541 5484 10542
+f 5302 5303 10543
+f 10542 5302 10543
+f 5303 5485 10544
+f 10543 5303 10544
+f 5485 8196 10545
+f 10544 5485 10545
+f 8196 8197 10546
+f 10545 8196 10546
+f 8197 6295 10547
+f 10546 8197 10547
+f 6295 5631 10548
+f 10547 6295 10548
+f 5631 5449 10549
+f 10548 5631 10549
+f 4707 10550 10549
+f 5449 4707 10549
+f 3068 10551 10550
+f 4707 3068 10550
+f 5861 10552 10551
+f 3068 5861 10551
+f 5861 8470 10553
+f 10552 5861 10553
+f 8470 8469 10554
+f 10553 8470 10554
+f 6713 10555 10554
+f 8469 6713 10554
+f 6713 4729 9783
+f 10555 6713 9783
+f 4729 3101 8464
+f 10146 10575 10576
+f 10577 9088 10562
+f 10147 10146 10576
+f 7758 7246 2923
+f 8116 10578 8205
+f 10579 10580 10581
+f 10582 10583 5639
+f 2464 2466 7543
+f 4112 4111 10567
+f 4461 4463 3184
+f 10584 221 5668
+f 10375 10585 5469
+f 10586 10587 10588
+f 763 2915 1058
+f 5638 10582 5639
+f 5730 10589 1569
+f 2558 2420 1625
+f 10590 6646 3835
+f 10591 10592 10593
+f 10594 6451 10595
+f 10596 10597 10598
+f 10599 10600 10601
+f 10602 10603 10604
+f 10605 10606 10604
+f 10607 10608 10609
+f 10610 10611 10612
+f 10613 10614 6028
+f 4607 4546 8801
+f 10615 10616 10617
+f 10618 10613 10619
+f 10620 10621 10622
+f 10623 10624 10625
+f 10626 10618 10619
+f 10627 10628 9531
+f 5454 4419 10629
+f 10630 10631 10632
+f 10633 8209 5618
+f 10634 9038 10635
+f 4419 10626 10629
+f 8801 10636 4607
+f 10637 10638 10639
+f 10640 10641 10642
+f 10616 10643 10617
+f 10619 10613 6028
+f 5651 5925 5769
+f 10644 10645 10646
+f 10614 10647 6028
+f 3183 4481 10648
+f 10649 10650 10651
+f 10652 10653 10654
+f 832 386 8445
+f 5755 3699 9056
+f 10655 10656 3083
+f 10657 10658 10659
+f 10660 10661 10662
+f 5452 10629 7839
+f 10663 10664 10665
+f 10666 10667 10668
+f 10669 10670 10671
+f 10672 10673 10674
+f 10675 10676 10677
+f 10678 10679 10680
+f 10681 10682 10683
+f 10684 10685 10686
+f 10687 10688 222
+f 10605 10689 10606
+f 10690 10691 10692
+f 10660 10662 10693
+f 10694 2231 10183
+f 10695 10623 10625
+f 4218 5206 4219
+f 10696 10652 10654
+f 10697 10698 10699
+f 10603 10700 10701
+f 8920 10655 3083
+f 10702 10703 10704
+f 10705 10706 10707
+f 10708 10703 10702
+f 10709 10702 10704
+f 10710 10711 10712
+f 10713 7014 10714
+f 2000 2075 817
+f 9771 7041 4000
+f 10715 9622 10716
+f 10717 9778 10576
+f 2996 10718 9948
+f 10575 10717 10576
+f 10719 9258 2935
+f 10720 10721 10722
+f 10723 10724 10725
+f 10726 10727 10728
+f 10729 10630 10730
+f 10731 10726 10728
+f 4061 10732 10733
+f 10734 10735 10736
+f 10681 10737 10738
+f 10739 9117 3205
+f 10182 10694 10183
+f 10740 10741 10742
+f 10743 10744 10745
+f 10746 2232 2231
+f 10747 8124 10748
+f 3357 1465 3554
+f 10749 8547 10750
+f 2100 785 6927
+f 4919 939 10751
+f 10752 10753 10754
+f 3309 2771 1961
+f 10755 315 10756
+f 10757 10758 10759
+f 10760 10761 10762
+f 10763 10764 10765
+f 10766 10767 10760
+f 10768 10769 10762
+f 9174 1987 1989
+f 10761 10770 10762
+f 10771 10765 10772
+f 10771 10763 10765
+f 3562 6627 6626
+f 10773 10771 10772
+f 3563 3562 6626
+f 10774 10775 6628
+f 10776 3072 9778
+f 10717 10776 9778
+f 10777 10767 10766
+f 10778 10777 10766
+f 10779 10780 10781
+f 10782 10783 2059
+f 10784 10785 10786
+f 10787 10788 10789
+f 10790 10791 10792
+f 10731 10728 10793
+f 10794 10795 10796
+f 10790 10792 10797
+f 10798 10799 10800
+f 5902 9631 5899
+f 10801 10802 10803
+f 10804 8680 2921
+f 10694 10746 2231
+f 6218 10627 4386
+f 10776 10805 3073
+f 10770 10768 10762
+f 3072 10776 3073
+f 10806 10807 10808
+f 10809 10810 3073
+f 10811 3002 3004
+f 10812 10813 10814
+f 10815 10816 10817
+f 10777 10778 10818
+f 10819 10815 10817
+f 10820 10821 10816
+f 10815 10820 10816
+f 10822 10823 10821
+f 10824 10825 10826
+f 10820 10822 10821
+f 10827 10828 10829
+f 10767 10761 10760
+f 10830 10831 10786
+f 9522 10832 10833
+f 3546 3521 10834
+f 10835 10836 10837
+f 10838 6023 6022
+f 5744 5746 10839
+f 8885 10790 10797
+f 10834 10840 9234
+f 8885 10797 8886
+f 10791 10793 10792
+f 10841 220 10842
+f 2731 2556 1466
+f 10843 10844 10655
+f 647 10845 10846
+f 10847 10299 10298
+f 10848 10849 10850
+f 10851 10777 10818
+f 10852 10853 10854
+f 10855 10856 10823
+f 10857 10824 10858
+f 10822 10855 10823
+f 10859 10860 10856
+f 10855 10859 10856
+f 10861 10862 10860
+f 10859 10861 10860
+f 10863 10864 10862
+f 10861 10863 10862
+f 10865 10866 10864
+f 10863 10865 10864
+f 10867 10868 10869
+f 10870 10871 10866
+f 9060 10872 10077
+f 10825 10867 10869
+f 10873 10874 10875
+f 10805 10809 3073
+f 10876 10877 10878
+f 10879 10880 10881
+f 10882 7738 7740
+f 8123 10147 6299
+f 9134 9254 4793
+f 10883 10884 10885
+f 10809 10886 10877
+f 10887 4627 2232
+f 7327 7326 3344
+f 10810 10809 10877
+f 10888 10889 10877
+f 10886 10888 10877
+f 10890 10891 10892
+f 10893 10894 10889
+f 10895 10896 10897
+f 10898 10846 10899
+f 8114 10900 10843
+f 10901 10657 10902
+f 10825 10869 10826
+f 10903 10904 10844
+f 10865 10870 10866
+f 7364 7363 10905
+f 10906 10907 10871
+f 10870 10906 10871
+f 10906 10908 10909
+f 10907 10906 10909
+f 10908 10910 10911
+f 10909 10908 10911
+f 10857 10858 10912
+f 10910 10913 10914
+f 10915 10851 10916
+f 10917 10857 10912
+f 10915 10916 10868
+f 10867 10915 10868
+f 1047 10918 10919
+f 10851 10818 10916
+f 10920 5379 5378
+f 10921 10922 573
+f 10880 10784 10881
+f 10874 10923 10875
+f 10888 10893 10889
+f 10894 10924 10878
+f 10925 10926 10927
+f 10928 10929 10930
+f 10931 10449 10932
+f 10933 10934 3721
+f 10746 10887 2232
+f 4229 4720 5339
+f 10935 10936 4627
+f 2013 10937 10938
+f 10939 10940 10894
+f 6197 3907 3909
+f 10810 10941 3279
+f 10942 10943 10944
+f 10945 10898 10899
+f 10810 10877 10941
+f 9278 10946 10841
+f 10583 10947 5641
+f 8798 10948 2329
+f 10949 10950 10951
+f 10952 6377 10953
+f 8208 4462 4461
+f 10911 10910 10914
+f 10954 10955 10956
+f 10957 10679 10678
+f 10914 10913 10680
+f 10958 10959 10960
+f 2732 1789 2596
+f 10887 10935 4627
+f 10961 10962 10963
+f 10964 10965 10936
+f 10824 10826 10858
+f 10893 10939 10894
+f 10966 10967 10940
+f 10952 6378 6377
+f 10935 10964 10936
+f 391 10968 9787
+f 10969 4802 4653
+f 4011 4010 4909
+f 2530 2531 2528
+f 10970 10674 10971
+f 10881 10784 10786
+f 10942 10972 10943
+f 10939 10966 10940
+f 10883 10973 10974
+f 10975 10976 10977
+f 2530 10978 2531
+f 9146 8803 9147
+f 10979 10980 10981
+f 3433 3432 10982
+f 9706 9040 10983
+f 10984 3700 8379
+f 9153 9706 10983
+f 2822 7949 10985
+f 10986 10884 10987
+f 7539 10988 10989
+f 10877 10876 10941
+f 5716 7534 7726
+f 3073 10810 3279
+f 10877 10889 10878
+f 10990 10991 10967
+f 10992 10993 10965
+f 10994 10995 4551
+f 4551 10996 4552
+f 10997 10998 10999
+f 10966 10990 10967
+f 11000 11001 11002
+f 7346 7219 7218
+f 11003 11004 11005
+f 11006 10729 10730
+f 11007 11008 10991
+f 10990 11007 10991
+f 11009 11010 11011
+f 5639 10583 5641
+f 11012 11013 11014
+f 11015 2319 11016
+f 10666 10668 10753
+f 10995 10996 4551
+f 11017 1614 11018
+f 10951 10950 11019
+f 9279 10841 10842
+f 5633 11020 5634
+f 10714 7014 6697
+f 11007 11021 11022
+f 3055 11023 11024
+f 11025 11026 11027
+f 10964 10992 10965
+f 11028 11029 11030
+f 11031 11032 10993
+f 11024 11023 1860
+f 11033 11034 11035
+f 8821 8295 6308
+f 2685 11036 10978
+f 2535 11037 2536
+f 11037 2535 2531
+f 10978 11037 2531
+f 10719 2935 11038
+f 10947 11039 5643
+f 8112 11040 5868
+f 11041 11042 11043
+f 11044 11045 11046
+f 1258 1402 1401
+f 4549 5716 7726
+f 7540 7539 10989
+f 11047 11048 11049
+f 7322 7324 9442
+f 10992 11031 10993
+f 11020 9784 9850
+f 4552 8804 4695
+f 11008 11007 11022
+f 11021 11050 11051
+f 4695 4550 4552
+f 5641 10947 5643
+f 11052 11053 11054
+f 3950 3531 2555
+f 3280 10941 7113
+f 3531 3533 2558
+f 1467 1627 8022
+f 11055 11056 11057
+f 11058 11059 11060
+f 9534 9459 9580
+f 10996 8804 4552
+f 11061 11062 11063
+f 11064 11065 10668
+f 11066 11067 11032
+f 2639 11068 10000
+f 6334 11069 4547
+f 6234 6522 11070
+f 7919 7315 7534
+f 5082 5081 5630
+f 2595 7858 7857
+f 11022 11021 11051
+f 11050 11071 10997
+f 3232 3234 11072
+f 8288 8287 11073
+f 5003 4094 6573
+f 11074 11075 11076
+f 11077 11078 11079
+f 11080 11081 11082
+f 8560 11083 9932
+f 11084 11037 10978
+f 11036 11084 10978
+f 11085 11086 11037
+f 11084 11085 11037
+f 11087 2700 11086
+f 11085 11087 11086
+f 11088 11089 11090
+f 6358 9797 11091
+f 11092 11093 11094
+f 647 649 10845
+f 11095 11096 11097
+f 11098 11099 11100
+f 11101 11102 11103
+f 8777 9037 8778
+f 10801 11104 11105
+f 9461 6431 11106
+f 6341 5629 5081
+f 11107 11108 11109
+f 11110 11111 11112
+f 2191 10169 10171
+f 11113 11114 8695
+f 11115 11116 11117
+f 11118 3079 11119
+f 8455 8457 10449
+f 11051 11050 10997
+f 11120 11121 11122
+f 7247 7650 4971
+f 11123 11124 11125
+f 11126 11127 11128
+f 11129 10671 11130
+f 6932 6728 6832
+f 11128 11125 5221
+f 11131 11132 11133
+f 11134 11135 11136
+f 5871 11137 11138
+f 11139 11140 11141
+f 11142 11143 11144
+f 9060 10077 11119
+f 11071 11145 10998
+f 7930 11146 7928
+f 10997 11071 10998
+f 8667 7758 9774
+f 11145 11147 10773
+f 8545 3525 3574
+f 2714 4288 4097
+f 10315 10156 5439
+f 11148 11149 11150
+f 11151 11152 1784
+f 642 641 11153
+f 11154 11084 11036
+f 11155 11154 11036
+f 11156 11085 11084
+f 11154 11156 11084
+f 11157 11087 11085
+f 11156 11157 11085
+f 6786 2817 2819
+f 11157 2898 11087
+f 10775 10637 10639
+f 11155 11036 2685
+f 11158 11159 11093
+f 9781 11160 11161
+f 4308 9257 4309
+f 8819 11162 10585
+f 5871 11138 11163
+f 11143 11164 11144
+f 11165 10896 10895
+f 5503 4696 4695
+f 2538 2700 2699
+f 11166 11167 11168
+f 11117 11126 11128
+f 11169 4087 3895
+f 11170 11171 11172
+f 11123 11125 11128
+f 2906 9137 9997
+f 11031 11066 11032
+f 10998 11145 10773
+f 8028 10628 6218
+f 6432 3898 3899
+f 6062 5855 10716
+f 11127 11123 11128
+f 3720 6821 3685
+f 11173 11174 11175
+f 11176 773 11177
+f 3454 3459 3263
+f 11178 6461 6458
+f 11179 11180 6603
+f 11181 11182 11183
+f 11184 11185 3367
+f 4022 6892 6891
+f 11186 11187 6743
+f 11075 11077 11079
+f 2872 5473 9720
+f 942 4011 943
+f 5020 5023 5496
+f 11188 11189 3454
+f 5188 10619 5189
+f 11190 11191 3069
+f 3275 11190 3069
+f 11192 11155 11191
+f 11190 11192 11191
+f 11192 11193 11154
+f 11155 11192 11154
+f 11193 11194 11156
+f 11154 11193 11156
+f 11195 11157 11156
+f 11194 11195 11156
+f 11196 2898 11157
+f 11195 11196 11157
+f 2685 2684 3065
+f 11196 2899 2898
+f 10384 10314 10313
+f 11197 3467 3466
+f 11198 9614 11199
+f 11200 11201 8383
+f 11202 3317 11203
+f 11204 11205 8544
+f 11137 11136 11138
+f 11137 11134 11136
+f 9779 3071 5165
+f 11206 11207 11208
+f 10671 10593 11130
+f 11175 11209 11210
+f 4754 11211 11212
+f 11124 11213 11125
+f 10899 11214 11215
+f 11216 11217 11218
+f 11219 11220 11067
+f 11066 11219 11067
+f 11221 5304 7564
+f 11222 2322 2324
+f 2823 11223 11224
+f 7054 11225 7055
+f 5910 5909 2817
+f 7343 7342 11226
+f 3473 3472 11227
+f 11228 3969 3968
+f 7021 7020 11229
+f 11230 11231 3459
+f 9623 5452 9714
+f 11232 11233 11234
+f 11235 11236 11237
+f 11238 6832 11239
+f 11240 3515 11237
+f 11236 11240 11237
+f 11241 3274 3515
+f 11240 11241 3515
+f 11242 3275 3274
+f 11241 11242 3274
+f 11243 11190 3275
+f 11242 11243 3275
+f 11244 11192 11190
+f 11243 11244 11190
+f 11244 11245 11193
+f 11192 11244 11193
+f 11245 11246 11194
+f 11193 11245 11194
+f 11246 11247 11195
+f 11194 11246 11195
+f 11248 11196 11195
+f 11247 11248 11195
+f 11249 2899 11196
+f 11248 11249 11196
+f 11250 1619 2899
+f 11249 11250 2899
+f 7846 3561 7546
+f 11251 7348 2143
+f 8362 8776 11252
+f 399 401 11253
+f 11254 11255 11135
+f 3552 7229 3553
+f 11256 11257 11258
+f 11134 11254 11135
+f 11259 10723 11260
+f 11259 11261 11262
+f 10623 11263 10624
+f 11261 11259 11260
+f 11264 10599 10601
+f 6818 7022 6819
+f 11265 10977 11266
+f 1620 1619 11250
+f 11267 9378 11268
+f 11269 11270 11271
+f 10138 4741 5912
+f 11272 10504 10503
+f 11273 11274 11220
+f 6030 11275 7035
+f 11276 11275 6030
+f 5878 11276 6030
+f 4139 5453 4265
+f 11277 11276 5878
+f 11275 11278 7035
+f 11219 11273 11220
+f 11279 11280 11274
+f 2326 5542 5541
+f 11281 5077 5076
+f 11282 11283 11188
+f 11284 11285 11286
+f 11283 11287 11189
+f 11188 11283 11189
+f 11287 11288 11230
+f 11189 11287 11230
+f 11288 11289 11231
+f 11230 11288 11231
+f 11289 11290 11235
+f 11231 11289 11235
+f 11291 11236 11235
+f 11290 11291 11235
+f 11291 11292 11240
+f 11236 11291 11240
+f 11292 11293 11241
+f 11240 11292 11241
+f 11293 11294 11242
+f 11241 11293 11242
+f 11294 11295 11243
+f 11242 11294 11243
+f 11295 11296 11244
+f 11243 11295 11244
+f 11296 11297 11245
+f 11244 11296 11245
+f 11297 11298 11246
+f 11245 11297 11246
+f 11298 11299 11247
+f 11246 11298 11247
+f 11299 11300 11248
+f 11247 11299 11248
+f 11300 11301 11249
+f 11248 11300 11249
+f 11302 11250 11249
+f 11301 11302 11249
+f 6307 6306 2152
+f 11302 3316 11250
+f 11303 11304 11305
+f 11306 10771 10773
+f 3317 8670 11203
+f 11307 8802 11308
+f 11309 11310 11255
+f 11311 11312 11313
+f 11314 7851 11315
+f 11254 11309 11255
+f 11316 11317 10720
+f 11318 11319 11320
+f 11321 529 528
+f 11322 11316 10720
+f 11323 11324 11325
+f 11326 11327 10737
+f 11328 6932 11238
+f 1706 3112 3323
+f 11329 11330 11331
+f 2770 11332 2768
+f 11263 11333 10624
+f 11334 11265 11266
+f 5210 6898 5304
+f 4205 11335 11336
+f 11326 11337 11327
+f 11338 11339 11340
+f 5219 6324 5220
+f 2355 2354 5311
+f 11093 11341 11342
+f 11343 10768 10770
+f 11344 11345 11346
+f 10904 11167 11347
+f 11275 11115 11278
+f 11348 10825 10824
+f 11349 11350 11351
+f 11117 11128 5221
+f 11352 11353 11354
+f 11355 10708 10702
+f 11356 11357 11358
+f 11359 11360 11361
+f 11273 11279 11274
+f 11279 11362 11363
+f 11364 11365 9489
+f 11366 11367 11368
+f 11369 11283 11282
+f 11367 11369 11282
+f 11370 11287 11283
+f 11369 11370 11283
+f 11371 11288 11287
+f 11370 11371 11287
+f 11371 11372 11289
+f 11288 11371 11289
+f 11372 11373 11290
+f 11289 11372 11290
+f 11373 11374 11291
+f 11290 11373 11291
+f 11374 11375 11292
+f 11291 11374 11292
+f 11375 11376 11293
+f 11292 11375 11293
+f 11376 11377 11294
+f 11293 11376 11294
+f 11377 11378 11295
+f 11294 11377 11295
+f 11378 11379 11296
+f 11295 11378 11296
+f 11379 11380 11297
+f 11296 11379 11297
+f 11380 11381 11298
+f 11297 11380 11298
+f 11381 11382 11299
+f 11298 11381 11299
+f 11382 11383 11300
+f 11299 11382 11300
+f 11383 11384 11301
+f 11300 11383 11301
+f 11384 11385 11302
+f 11301 11384 11302
+f 11386 3316 11302
+f 11385 11386 11302
+f 11387 9627 9629
+f 11388 11389 11390
+f 8126 8035 8297
+f 10502 9634 9633
+f 11391 11311 11313
+f 11392 11393 11394
+f 11395 11396 11310
+f 11397 11398 11399
+f 11400 11319 11318
+f 11401 11400 11318
+f 7933 5875 11402
+f 9809 11403 11404
+f 11405 10707 11406
+f 11407 11408 11409
+f 11410 11022 11411
+f 9086 11412 11413
+f 11147 11306 10773
+f 11414 11113 11415
+f 11051 10997 11416
+f 1645 670 776
+f 10681 11417 10737
+f 7950 1141 11418
+f 11316 11419 11420
+f 5875 2958 11402
+f 11280 11279 11363
+f 11111 11421 11112
+f 11422 11423 11424
+f 4205 4204 11425
+f 11426 10745 11427
+f 11330 11417 11428
+f 11429 11284 11286
+f 11417 10681 11428
+f 11417 11326 10737
+f 11330 11428 11331
+f 11327 11427 10737
+f 11430 10763 10771
+f 11431 11432 11433
+f 11306 11430 10771
+f 11434 11435 10763
+f 11430 11434 10763
+f 11434 11436 8375
+f 11435 11434 8375
+f 11407 11337 10691
+f 11436 11437 11438
+f 8375 11436 11438
+f 11439 11440 11438
+f 11437 11439 11438
+f 10999 10998 10772
+f 11022 11051 11411
+f 5444 5443 7646
+f 11362 11441 11442
+f 11363 11362 11442
+f 11443 11367 11444
+f 11444 11445 11446
+f 11447 11369 11367
+f 11443 11447 11367
+f 11448 11370 11369
+f 11447 11448 11369
+f 11449 11371 11370
+f 11448 11449 11370
+f 11450 11372 11371
+f 11449 11450 11371
+f 11451 11373 11372
+f 11450 11451 11372
+f 11451 11452 11374
+f 11373 11451 11374
+f 11452 11453 11375
+f 11374 11452 11375
+f 11453 11454 11376
+f 11375 11453 11376
+f 11454 11455 11377
+f 11376 11454 11377
+f 11455 11456 11378
+f 11377 11455 11378
+f 11456 11457 11379
+f 11378 11456 11379
+f 11457 11458 11380
+f 11379 11457 11380
+f 11458 11459 11381
+f 11380 11458 11381
+f 11459 11460 11382
+f 11381 11459 11382
+f 11460 11461 11383
+f 11382 11460 11383
+f 11461 11462 11384
+f 11383 11461 11384
+f 11462 11463 11385
+f 11384 11462 11385
+f 11463 11464 11386
+f 11385 11463 11386
+f 5877 5897 5875
+f 11464 11465 11386
+f 3315 3107 7834
+f 11466 11467 2518
+f 11468 218 220
+f 5906 5908 1315
+f 10730 10632 11324
+f 9265 9264 11469
+f 11319 10644 11320
+f 11470 11397 11399
+f 11471 11472 11473
+f 11474 11475 11476
+f 11477 11478 11409
+f 11403 11471 11473
+f 11479 8505 5380
+f 690 2000 817
+f 11480 5763 5765
+f 11481 10820 10815
+f 5924 5926 11482
+f 11483 11484 11485
+f 11486 11487 11488
+f 11489 11172 11490
+f 11491 11400 11401
+f 11487 11492 11493
+f 11013 10994 11494
+f 11495 11349 11496
+f 2957 11497 11402
+f 2958 2957 11402
+f 2957 9630 11497
+f 9630 11498 11497
+f 11499 11500 11501
+f 11502 11503 11498
+f 9630 11502 11498
+f 11504 11501 11503
+f 11504 11499 11501
+f 11502 11504 11503
+f 11486 11488 11500
+f 11499 11486 11500
+f 11329 11331 10675
+f 11487 11505 11488
+f 3355 3901 8369
+f 11506 11329 10675
+f 9593 8309 8914
+f 11507 11508 11509
+f 10690 11407 10691
+f 8799 4546 4910
+f 10689 10690 10692
+f 8542 11510 6018
+f 8695 11511 11415
+f 11337 11407 11409
+f 11512 10822 10820
+f 1551 9427 8300
+f 11481 11512 10820
+f 11513 10855 10822
+f 11512 11513 10822
+f 11514 10859 10855
+f 11515 7055 11225
+f 3306 3307 8107
+f 11441 11516 10806
+f 11442 11441 10806
+f 11517 11443 11518
+f 4331 11364 9489
+f 11519 11447 11443
+f 11517 11519 11443
+f 11520 11448 11447
+f 11519 11520 11447
+f 11521 11449 11448
+f 11520 11521 11448
+f 11522 11450 11449
+f 11521 11522 11449
+f 11523 11451 11450
+f 11522 11523 11450
+f 11523 11524 11452
+f 11451 11523 11452
+f 11524 11525 11453
+f 11452 11524 11453
+f 11525 11526 11454
+f 11453 11525 11454
+f 11526 11527 11455
+f 11454 11526 11455
+f 11527 11528 11456
+f 11455 11527 11456
+f 11528 11529 11457
+f 11456 11528 11457
+f 11529 11530 11458
+f 11457 11529 11458
+f 11530 11531 11459
+f 11458 11530 11459
+f 11531 11532 11460
+f 11459 11531 11460
+f 11532 11533 11461
+f 11460 11532 11461
+f 11533 11534 11462
+f 11461 11533 11462
+f 11534 11535 11463
+f 11462 11534 11463
+f 11535 11536 11464
+f 11463 11535 11464
+f 11536 11537 11465
+f 11464 11536 11465
+f 11537 11538 7833
+f 11465 11537 7833
+f 11539 11540 7833
+f 11538 11539 7833
+f 11541 11542 11543
+f 7330 8662 8371
+f 11397 11544 10705
+f 11545 11546 11440
+f 11547 11548 11549
+f 11550 11551 11552
+f 11471 11553 11554
+f 3130 3129 11555
+f 11556 6788 11557
+f 1943 1942 6927
+f 11513 11514 10855
+f 11558 10861 10859
+f 11514 11558 10859
+f 10998 10773 10772
+f 11559 10863 10861
+f 11472 11471 11554
+f 8301 1550 1549
+f 11560 11474 11476
+f 11553 11561 11562
+f 11309 11395 11310
+f 11563 11491 11401
+f 1931 11564 11565
+f 3716 3895 4087
+f 1929 1931 11566
+f 1787 10573 8022
+f 11567 11568 3179
+f 11566 1931 11565
+f 1093 1095 11569
+f 2750 1320 8454
+f 11570 11568 11567
+f 11571 11570 11567
+f 11351 11570 11571
+f 11496 11351 11571
+f 11572 11573 11495
+f 11349 11351 11496
+f 11574 11575 11576
+f 11577 11573 11572
+f 11505 11487 11493
+f 11578 11574 11576
+f 11578 11576 11493
+f 11492 11578 11493
+f 11579 11580 11575
+f 11574 11579 11575
+f 9810 11581 11580
+f 11579 9810 11580
+f 9809 11404 11581
+f 9810 9809 11581
+f 8695 11114 11582
+f 11403 11473 11404
+f 8693 11582 8300
+f 8693 8695 11582
+f 11338 11340 11583
+f 4005 4004 6219
+f 11558 11559 10861
+f 11584 11585 11586
+f 11516 11587 10807
+f 10806 11516 10807
+f 11588 11517 11589
+f 11590 11591 11592
+f 11593 11519 11517
+f 11588 11593 11517
+f 11594 11520 11519
+f 11593 11594 11519
+f 11595 11521 11520
+f 11594 11595 11520
+f 11596 11522 11521
+f 11595 11596 11521
+f 11597 11523 11522
+f 11596 11597 11522
+f 11597 11598 11524
+f 11523 11597 11524
+f 11598 11599 11525
+f 11524 11598 11525
+f 11599 11600 11526
+f 11525 11599 11526
+f 11600 11601 11527
+f 11526 11600 11527
+f 11601 11602 11528
+f 11527 11601 11528
+f 11602 11603 11529
+f 11528 11602 11529
+f 11603 11604 11530
+f 11529 11603 11530
+f 11604 11605 11531
+f 11530 11604 11531
+f 11605 11606 11532
+f 11531 11605 11532
+f 11606 11607 11533
+f 11532 11606 11533
+f 11607 11608 11534
+f 11533 11607 11534
+f 11608 11609 11535
+f 11534 11608 11535
+f 11609 11610 11536
+f 11535 11609 11536
+f 11610 11611 11537
+f 11536 11610 11537
+f 11611 11612 11538
+f 11537 11611 11538
+f 11613 11539 11538
+f 11612 11613 11538
+f 7007 9255 8506
+f 8679 3506 8680
+f 11614 11615 11616
+f 5220 11278 5221
+f 11617 11548 11618
+f 11548 11550 11549
+f 11619 3129 11620
+f 11621 11622 11623
+f 11624 11625 10727
+f 11626 8037 11627
+f 11628 10865 10863
+f 11559 11628 10863
+f 11629 10870 10865
+f 11628 11629 10865
+f 11630 10906 10870
+f 11631 11632 1945
+f 11629 11630 10870
+f 3130 11555 11633
+f 11439 11545 11440
+f 11474 11560 11634
+f 11635 11555 11619
+f 11398 11397 10705
+f 11475 11491 11563
+f 11636 11637 11396
+f 11395 11636 11396
+f 11636 11638 11637
+f 11638 11639 11637
+f 11640 11641 11642
+f 11643 11644 11639
+f 11638 11643 11639
+f 11645 11640 11642
+f 11645 11642 11644
+f 11643 11645 11644
+f 11646 11647 11641
+f 11640 11646 11641
+f 11648 11649 11647
+f 11646 11648 11647
+f 11649 11648 11650
+f 11648 11651 11650
+f 11652 11577 11572
+f 11651 11653 11654
+f 11655 11577 11652
+f 11573 11349 11495
+f 10651 11655 11656
+f 11656 11655 11652
+f 10646 10651 11657
+f 11657 10651 11656
+f 10644 10646 11658
+f 11658 10646 11657
+f 11476 11475 11563
+f 11320 10644 11658
+f 11561 11555 11635
+f 11659 11617 11660
+f 11554 11553 11562
+f 11562 11561 11635
+f 11308 8802 6912
+f 11661 11173 11662
+f 11663 10908 10906
+f 11630 11663 10906
+f 11587 11664 11665
+f 10807 11587 11665
+f 11666 11588 11667
+f 11667 11588 11589
+f 11668 11593 11588
+f 11666 11668 11588
+f 11669 11594 11593
+f 11668 11669 11593
+f 11670 11595 11594
+f 11669 11670 11594
+f 11671 11596 11595
+f 11670 11671 11595
+f 11672 11597 11596
+f 11671 11672 11596
+f 11672 11673 11598
+f 11597 11672 11598
+f 11673 11674 11599
+f 11598 11673 11599
+f 11674 11675 11600
+f 11599 11674 11600
+f 11675 11676 11601
+f 11600 11675 11601
+f 11676 11677 11602
+f 11601 11676 11602
+f 11677 11678 11603
+f 11602 11677 11603
+f 11678 11679 11604
+f 11603 11678 11604
+f 11679 11680 11605
+f 11604 11679 11605
+f 11680 11681 11606
+f 11605 11680 11606
+f 11681 11682 11607
+f 11606 11681 11607
+f 11682 11683 11608
+f 11607 11682 11608
+f 11683 11684 11609
+f 11608 11683 11609
+f 11684 11685 11610
+f 11609 11684 11610
+f 11685 11686 11611
+f 11610 11685 11611
+f 11686 11687 11612
+f 11611 11686 11612
+f 11687 11688 11613
+f 11612 11687 11613
+f 3872 4079 2770
+f 11689 4087 11169
+f 11690 7351 11691
+f 4754 11212 6995
+f 11692 11693 11694
+f 358 357 690
+f 11695 10960 10959
+f 11696 11697 11698
+f 4924 4923 2353
+f 11624 11699 11625
+f 11663 11700 10910
+f 7730 10309 6581
+f 10908 11663 10910
+f 11700 11701 10913
+f 10769 11702 4089
+f 10910 11700 10913
+f 11545 11703 3562
+f 11704 10733 11705
+f 3128 11706 3129
+f 11707 5928 6072
+f 11549 11550 11552
+f 11620 11706 10733
+f 11544 11708 10706
+f 11709 11474 11634
+f 11710 11711 11712
+f 10705 11544 10706
+f 11713 11714 1672
+f 11712 11715 11391
+f 6019 6018 11716
+f 11510 11717 11718
+f 11719 11720 11721
+f 11722 11723 11724
+f 11725 11726 11719
+f 1558 9496 1503
+f 11727 11728 11725
+f 11720 11729 11721
+f 11730 11731 11727
+f 11726 11720 11719
+f 11732 11733 11730
+f 11728 11726 11725
+f 11733 11731 11730
+f 11731 11728 11727
+f 11734 11735 11736
+f 11737 11738 11739
+f 11650 11651 11654
+f 11740 11734 11736
+f 11740 11736 11654
+f 11653 11740 11654
+f 11741 11742 11735
+f 11734 11741 11735
+f 11743 11744 11742
+f 11741 11743 11742
+f 11470 11399 11744
+f 11743 11470 11744
+f 11745 11746 11747
+f 11659 11660 11748
+f 11749 10720 10722
+f 11173 11175 11662
+f 10762 4089 4088
+f 10760 10762 4088
+f 11701 11750 10678
+f 10913 11701 10678
+f 11664 11751 11752
+f 11665 11664 11752
+f 11753 11666 11754
+f 11755 11754 11667
+f 11756 11668 11666
+f 11753 11756 11666
+f 11757 11669 11668
+f 11756 11757 11668
+f 11758 11670 11669
+f 11757 11758 11669
+f 11759 11671 11670
+f 11758 11759 11670
+f 11760 11672 11671
+f 11759 11760 11671
+f 11760 11761 11673
+f 11672 11760 11673
+f 11761 11762 11674
+f 11673 11761 11674
+f 11762 11763 11675
+f 11674 11762 11675
+f 11763 11764 11676
+f 11675 11763 11676
+f 11764 11765 11677
+f 11676 11764 11677
+f 11765 11766 11678
+f 11677 11765 11678
+f 11766 11767 11679
+f 11678 11766 11679
+f 11767 11768 11680
+f 11679 11767 11680
+f 11768 11769 11681
+f 11680 11768 11681
+f 11769 11770 11682
+f 11681 11769 11682
+f 11770 11771 11683
+f 11682 11770 11683
+f 11771 11772 11684
+f 11683 11771 11684
+f 11772 11773 11685
+f 11684 11772 11685
+f 11773 11774 11686
+f 11685 11773 11686
+f 11774 11775 11687
+f 11686 11774 11687
+f 11775 11169 11688
+f 11687 11775 11688
+f 4077 7747 4078
+f 2999 2961 3000
+f 11776 1163 8951
+f 6488 6485 6344
+f 11777 11778 11779
+f 11780 4687 11781
+f 11782 11783 11784
+f 6345 6344 6485
+f 10818 10778 11785
+f 11786 10818 11785
+f 6132 11787 5853
+f 11750 11788 10957
+f 9211 8359 8358
+f 962 1706 3323
+f 11789 11790 7207
+f 10916 10818 11786
+f 8050 8049 9807
+f 5913 5917 5914
+f 10762 10769 4089
+f 11143 8370 8366
+f 11791 10297 10299
+f 11792 11793 11552
+f 11794 11795 11796
+f 11797 11798 10706
+f 11551 11792 11552
+f 11799 11800 11710
+f 11708 11797 10706
+f 11801 8809 11802
+f 11715 11311 11391
+f 11803 8809 11801
+f 11804 11803 11801
+f 11805 11806 11807
+f 8809 11805 11802
+f 11808 11809 11810
+f 11802 11805 11807
+f 11806 11809 11808
+f 11811 11812 11813
+f 11807 11806 11808
+f 11809 11811 11810
+f 11810 11811 11813
+f 11812 11814 11815
+f 11813 11812 11815
+f 11814 11816 11817
+f 11815 11814 11817
+f 11818 10076 10075
+f 11819 11733 11732
+f 11817 11816 11820
+f 11821 11822 11737
+f 11739 11819 11732
+f 11313 11312 11821
+f 11738 11819 11739
+f 11312 11822 11821
+f 11822 11738 11737
+f 11823 11824 11825
+f 11824 11826 11827
+f 11828 11829 11830
+f 11831 11832 11171
+f 11778 11692 11694
+f 11833 11834 11693
+f 11835 11836 10677
+f 11837 11835 10677
+f 10778 10766 11838
+f 11785 10778 11838
+f 11546 11545 3562
+f 11751 11839 11840
+f 11841 9267 9375
+f 2875 3082 4074
+f 11752 11751 11840
+f 11839 11842 11843
+f 11844 11753 11845
+f 11846 11754 11755
+f 11847 11756 11753
+f 11844 11847 11753
+f 11848 11757 11756
+f 11847 11848 11756
+f 11849 11758 11757
+f 11848 11849 11757
+f 11850 11759 11758
+f 11849 11850 11758
+f 11851 11760 11759
+f 11850 11851 11759
+f 11851 11852 11761
+f 11760 11851 11761
+f 11852 11853 11762
+f 11761 11852 11762
+f 11853 11854 11763
+f 11762 11853 11763
+f 11854 11855 11764
+f 11763 11854 11764
+f 11855 11856 11765
+f 11764 11855 11765
+f 11856 11857 11766
+f 11765 11856 11766
+f 11857 11858 11767
+f 11766 11857 11767
+f 11858 11859 11768
+f 11767 11858 11768
+f 11859 11860 11769
+f 11768 11859 11769
+f 11860 11861 11770
+f 11769 11860 11770
+f 11861 11862 11771
+f 11770 11861 11771
+f 11862 11863 11772
+f 11771 11862 11772
+f 11863 11864 11773
+f 11772 11863 11773
+f 11864 11865 11774
+f 11773 11864 11774
+f 11865 11866 11775
+f 11774 11865 11775
+f 11866 11689 11169
+f 11775 11866 11169
+f 11867 11868 4087
+f 11776 6359 6358
+f 10962 11869 11870
+f 7120 7217 11781
+f 11778 11694 11779
+f 4861 5731 10769
+f 11871 11872 11873
+f 10796 11874 11875
+f 10869 10868 11876
+f 10868 10916 11877
+f 11703 11878 6627
+f 5191 11879 11880
+f 3562 11703 6627
+f 4289 6017 6019
+f 10868 11881 11876
+f 10967 10991 11882
+f 11883 11884 11885
+f 11877 10916 11786
+f 11886 11777 11887
+f 7732 5086 5088
+f 11792 11709 11634
+f 11548 11547 11618
+f 11888 10928 11798
+f 11793 11792 11634
+f 11889 11890 11799
+f 11797 11888 11798
+f 11891 10794 11892
+f 11711 11715 11712
+f 11893 11894 11895
+f 8796 4417 5231
+f 11878 11896 10774
+f 11894 11897 11898
+f 6627 11878 10774
+f 11899 11900 4844
+f 11901 10775 10774
+f 11896 11901 10774
+f 11902 7126 7125
+f 3904 11903 3118
+f 11904 11905 11902
+f 4445 4444 6618
+f 11906 11907 11904
+f 11908 3185 11820
+f 11909 11910 11906
+f 11905 7126 11902
+f 11910 11907 11906
+f 11907 11905 11904
+f 4095 2569 2574
+f 11911 11912 11913
+f 10989 10988 7753
+f 9720 6714 1628
+f 8452 11914 11915
+f 11916 11816 11917
+f 11918 10637 10775
+f 6098 11919 11920
+f 11921 11824 11827
+f 5756 7471 10151
+f 11170 11831 11171
+f 11826 11490 11922
+f 11692 11833 11693
+f 11831 11170 11923
+f 4060 4062 11924
+f 11745 11747 11834
+f 10766 10760 4088
+f 11925 10779 11926
+f 11927 11928 11929
+f 11838 10766 4088
+f 11930 5470 11162
+f 1243 11931 8603
+f 11846 11932 11845
+f 11933 11934 11935
+f 11936 11844 11932
+f 11934 11936 11932
+f 11937 11847 11844
+f 11936 11937 11844
+f 11938 11848 11847
+f 11937 11938 11847
+f 11939 11849 11848
+f 11938 11939 11848
+f 11940 11850 11849
+f 11939 11940 11849
+f 11941 11851 11850
+f 11940 11941 11850
+f 11942 11852 11851
+f 11941 11942 11851
+f 11942 11943 11853
+f 11852 11942 11853
+f 11943 11944 11854
+f 11853 11943 11854
+f 11944 11945 11855
+f 11854 11944 11855
+f 11945 11946 11856
+f 11855 11945 11856
+f 11946 11947 11857
+f 11856 11946 11857
+f 11947 11948 11858
+f 11857 11947 11858
+f 11948 11949 11859
+f 11858 11948 11859
+f 11949 11950 11860
+f 11859 11949 11860
+f 11950 11951 11861
+f 11860 11950 11861
+f 11952 11862 11861
+f 11951 11952 11861
+f 11952 11953 11863
+f 11862 11952 11863
+f 11953 11954 11864
+f 11863 11953 11864
+f 11954 11955 11865
+f 11864 11954 11865
+f 11955 11956 11866
+f 11865 11955 11866
+f 11956 11867 11689
+f 11866 11956 11689
+f 11689 11867 4087
+f 6707 11957 4141
+f 2220 6721 6826
+f 11868 4085 4087
+f 11308 11180 11958
+f 3859 7741 10647
+f 11959 10740 10742
+f 1137 7944 7853
+f 11881 10868 11877
+f 11960 11961 11962
+f 11008 11963 11964
+f 10826 10869 11965
+f 11966 11120 11122
+f 3998 4203 3999
+f 10927 11967 11968
+f 11840 11839 11843
+f 11830 11923 11969
+f 11970 11971 11972
+f 11973 11974 11975
+f 10826 11965 11976
+f 10858 10826 11976
+f 8373 11977 6340
+f 10735 11978 10736
+f 11886 11887 11979
+f 11980 11886 11979
+f 11981 10929 10928
+f 11888 11981 10928
+f 11982 11823 11983
+f 11984 11985 10929
+f 6302 6459 4281
+f 11800 11711 11710
+f 11893 11986 11987
+f 11988 11989 11990
+f 11991 11992 11993
+f 11986 11893 11895
+f 11991 11993 11994
+f 11995 11991 11994
+f 11992 11996 11997
+f 11992 11998 11993
+f 11996 11999 12000
+f 11998 11992 11997
+f 12001 12002 12003
+f 11997 11996 12000
+f 11999 12002 12001
+f 12004 12005 12006
+f 12000 11999 12001
+f 12002 12004 12003
+f 12003 12004 12006
+f 12005 12007 12008
+f 12006 12005 12008
+f 12007 12009 12010
+f 12011 11910 11909
+f 12008 12007 12010
+f 11898 11897 11911
+f 11913 12011 11909
+f 11895 11894 11898
+f 11912 12011 11913
+f 12012 8550 8456
+f 11897 11912 11911
+f 12013 12014 12015
+f 12016 12017 12018
+f 11827 11826 11922
+f 12019 12020 12013
+f 11829 11831 11923
+f 11490 11507 12021
+f 11833 11745 11834
+f 11984 11828 11985
+f 7563 6710 6160
+f 11746 11748 11747
+f 4535 4537 4368
+f 8688 10833 8284
+f 4205 12022 11335
+f 7200 3549 7201
+f 12023 11934 11335
+f 12022 12023 11335
+f 12024 11936 11934
+f 12023 12024 11934
+f 12025 11937 11936
+f 12024 12025 11936
+f 12026 11938 11937
+f 12025 12026 11937
+f 12027 11939 11938
+f 12026 12027 11938
+f 12028 11940 11939
+f 12027 12028 11939
+f 12029 11941 11940
+f 12028 12029 11940
+f 12030 11942 11941
+f 12029 12030 11941
+f 12030 12031 11943
+f 11942 12030 11943
+f 12031 12032 11944
+f 11943 12031 11944
+f 12032 12033 11945
+f 11944 12032 11945
+f 12033 12034 11946
+f 11945 12033 11946
+f 12034 12035 11947
+f 11946 12034 11947
+f 12035 12036 11948
+f 11947 12035 11948
+f 12036 12037 11949
+f 11948 12036 11949
+f 12037 12038 11950
+f 11949 12037 11950
+f 12038 12039 11951
+f 11950 12038 11951
+f 12040 11952 11951
+f 12039 12040 11951
+f 12040 12041 11953
+f 11952 12040 11953
+f 12042 11954 11953
+f 12041 12042 11953
+f 12043 11955 11954
+f 12042 12043 11954
+f 12043 12044 11956
+f 11955 12043 11956
+f 12044 12045 11867
+f 11956 12044 11867
+f 12045 12046 11868
+f 11867 12045 11868
+f 12046 8950 4085
+f 11868 12046 4085
+f 4085 8950 8951
+f 7551 7133 7549
+f 11803 11804 12047
+f 11901 11918 10775
+f 12048 12049 12050
+f 12051 12052 12053
+f 10858 11976 12054
+f 10912 10858 12054
+f 11398 12055 12056
+f 11399 11398 12056
+f 5543 2841 2843
+f 779 8707 844
+f 12057 4774 4776
+f 6469 6471 7139
+f 12058 3048 12059
+f 11094 11342 12060
+f 12061 12062 12063
+f 12064 12065 12066
+f 12067 12068 12069
+f 12070 12066 12071
+f 11752 11840 12072
+f 8782 6021 9780
+f 12073 12074 12075
+f 10869 11876 11965
+f 11980 11979 12076
+f 12077 4681 12078
+f 11832 12079 12080
+f 11777 11779 11887
+f 11823 11825 11983
+f 11171 11832 12080
+f 12081 12082 12083
+f 11824 11921 11825
+f 3696 966 3697
+f 6996 12084 6997
+f 12085 12086 12087
+f 12088 11893 11987
+f 11323 10730 11324
+f 12089 11045 11044
+f 11129 11130 12090
+f 4122 12091 10232
+f 11218 12090 12092
+f 12093 11218 12092
+f 12094 12093 12092
+f 12095 8549 1707
+f 12096 12095 961
+f 529 9204 530
+f 7541 4096 4098
+f 12097 11251 4099
+f 10140 12098 12099
+f 12100 12101 9828
+f 10357 9528 8455
+f 6175 12050 12102
+f 12103 10354 4133
+f 12104 6654 12105
+f 12106 12107 12108
+f 8447 6440 2218
+f 12009 12107 12106
+f 7655 7559 7558
+f 12010 12009 12106
+f 12107 3659 12108
+f 2640 2639 10000
+f 12109 12110 12111
+f 8858 12112 9139
+f 5587 12113 12114
+f 12014 12115 12015
+f 12116 12117 557
+f 11922 11490 12021
+f 12118 12020 12119
+f 11829 11923 11830
+f 11507 11509 12120
+f 11746 11659 11748
+f 11981 11984 10929
+f 5924 5927 5770
+f 11617 11618 11660
+f 11425 12022 4205
+f 3354 3353 3550
+f 11425 12121 12023
+f 12022 11425 12023
+f 12122 12024 12023
+f 12121 12122 12023
+f 12123 12025 12024
+f 12122 12123 12024
+f 12124 12026 12025
+f 12123 12124 12025
+f 12125 12027 12026
+f 12124 12125 12026
+f 12126 12028 12027
+f 12125 12126 12027
+f 12127 12029 12028
+f 12126 12127 12028
+f 12128 12030 12029
+f 12127 12128 12029
+f 12129 12031 12030
+f 12128 12129 12030
+f 12129 12130 12032
+f 12031 12129 12032
+f 12130 12131 12033
+f 12032 12130 12033
+f 12131 12132 12034
+f 12033 12131 12034
+f 12132 12133 12035
+f 12034 12132 12035
+f 12133 12134 12036
+f 12035 12133 12036
+f 12134 12135 12037
+f 12036 12134 12037
+f 12135 12136 12038
+f 12037 12135 12038
+f 12136 12137 12039
+f 12038 12136 12039
+f 12137 12138 12040
+f 12039 12137 12040
+f 12139 12041 12040
+f 12138 12139 12040
+f 12140 12042 12041
+f 12139 12140 12041
+f 12141 12043 12042
+f 12140 12141 12042
+f 12141 12142 12044
+f 12043 12141 12044
+f 12142 12143 12045
+f 12044 12142 12045
+f 12143 12144 12046
+f 12045 12143 12046
+f 12144 12145 8950
+f 12046 12144 8950
+f 2600 12146 12147
+f 12148 7259 12145
+f 7033 6452 10594
+f 12149 12150 2715
+f 12151 12152 12153
+f 12154 12087 12155
+f 12156 12157 10637
+f 11842 12158 12159
+f 12160 12161 12162
+f 12163 12071 12164
+f 7326 7325 12165
+f 9659 9658 12166
+f 12167 12168 931
+f 9087 9086 11413
+f 5916 8009 8008
+f 12160 12162 12169
+f 12170 7204 7206
+f 12161 12163 12164
+f 12171 12160 12169
+f 12161 12164 12162
+f 12172 12171 12169
+f 12163 12070 12071
+f 11918 12156 10637
+f 10599 12173 12174
+f 10700 12172 12169
+f 12175 10597 12176
+f 11116 11052 11126
+f 11411 11051 11416
+f 12177 12178 12179
+f 12180 12181 12182
+f 10727 11625 12183
+f 12184 12076 12185
+f 10621 12186 12187
+f 12079 12186 10621
+f 11035 11034 12188
+f 11982 11983 12189
+f 12015 12115 12190
+f 12115 12191 12190
+f 8781 3528 3526
+f 3529 3944 4130
+f 6024 7635 6721
+f 4850 6931 4851
+f 12192 648 12193
+f 5082 6707 4141
+f 12194 12195 12196
+f 3868 3870 4477
+f 12195 12194 12197
+f 12194 12198 12197
+f 12197 12198 12199
+f 12198 12200 12199
+f 12199 12200 12201
+f 12200 12202 12201
+f 12203 12204 12205
+f 12206 12207 12201
+f 12202 12206 12201
+f 12208 12203 12205
+f 12206 12203 12208
+f 12207 12206 12208
+f 12209 10798 12205
+f 12204 12209 12205
+f 12210 8783 7437
+f 12211 12212 10798
+f 4690 4379 7657
+f 7437 9780 5350
+f 8106 5190 5192
+f 12213 12214 2389
+f 4536 12215 4537
+f 6160 2751 7657
+f 12216 12217 11794
+f 12218 12219 12220
+f 12050 12221 12102
+f 12222 12223 11794
+f 12020 12014 12013
+f 12224 12225 12157
+f 12021 11507 12120
+f 12226 12118 12227
+f 11828 11830 11985
+f 11509 11890 11889
+f 12228 12229 12230
+f 4537 12231 4204
+f 3069 3065 3064
+f 2921 2920 12232
+f 12231 12233 12121
+f 11425 12231 12121
+f 12234 12122 12121
+f 12233 12234 12121
+f 12235 12123 12122
+f 12234 12235 12122
+f 12236 12124 12123
+f 12235 12236 12123
+f 12237 12125 12124
+f 12236 12237 12124
+f 12238 12126 12125
+f 12237 12238 12125
+f 12239 12127 12126
+f 12238 12239 12126
+f 12240 12128 12127
+f 12239 12240 12127
+f 12241 12129 12128
+f 12240 12241 12128
+f 12241 12242 12130
+f 12129 12241 12130
+f 12242 12243 12131
+f 12130 12242 12131
+f 12243 12244 12132
+f 12131 12243 12132
+f 12244 12245 12133
+f 12132 12244 12133
+f 12245 12246 12134
+f 12133 12245 12134
+f 12246 12247 12135
+f 12134 12246 12135
+f 12247 12248 12136
+f 12135 12247 12136
+f 12248 12249 12137
+f 12136 12248 12137
+f 12249 12250 12138
+f 12137 12249 12138
+f 12251 12139 12138
+f 12250 12251 12138
+f 12252 12140 12139
+f 12251 12252 12139
+f 12253 12141 12140
+f 12252 12253 12140
+f 12254 12142 12141
+f 12253 12254 12141
+f 12255 12143 12142
+f 12254 12255 12142
+f 12255 12256 12144
+f 12143 12255 12144
+f 12256 12148 12145
+f 12144 12256 12145
+f 12257 4394 4396
+f 8034 7944 7941
+f 12258 12259 12260
+f 9159 9284 9281
+f 10903 10844 10843
+f 12156 12224 12157
+f 11355 10702 10754
+f 5301 5152 5151
+f 12261 12262 12263
+f 12264 12265 12266
+f 10597 12267 10598
+f 12268 8681 8684
+f 5534 5536 12269
+f 11988 4410 11078
+f 9488 463 462
+f 11843 11842 12159
+f 8682 4625 12270
+f 12271 1053 1052
+f 12272 10952 10953
+f 12158 12273 8661
+f 12274 10589 5730
+f 9854 9853 12275
+f 12272 10953 11201
+f 12064 12276 12277
+f 12278 11110 11059
+f 11121 12279 12280
+f 12281 11121 12280
+f 10844 11347 12282
+f 12065 12064 12277
+f 12283 12284 12285
+f 11058 12278 11059
+f 10728 12286 12287
+f 4456 4458 12288
+f 12289 12290 10848
+f 11625 12184 12185
+f 11034 12189 12188
+f 12187 12289 10848
+f 12191 12291 12292
+f 11034 11982 12189
+f 3722 8281 4617
+f 12190 12191 12292
+f 12293 5817 3547
+f 6893 6895 8915
+f 12294 12295 11515
+f 3911 3755 12296
+f 12297 12298 12299
+f 12159 12158 8661
+f 2216 12300 5904
+f 12301 12297 12299
+f 10789 11215 12302
+f 942 1995 4012
+f 10837 10787 12302
+f 12303 10837 12302
+f 10835 10837 12303
+f 12304 10835 12303
+f 12305 12306 12307
+f 10835 12304 12308
+f 12309 12305 12310
+f 12306 10835 12308
+f 12311 12309 12312
+f 12306 12308 12307
+f 12309 12310 12312
+f 12305 12307 12310
+f 12211 12313 12212
+f 10742 10741 12314
+f 12209 12211 10798
+f 12315 11973 12316
+f 12313 12315 12316
+f 12313 12316 12212
+f 12317 11974 11973
+f 12315 12317 11973
+f 5665 8211 6432
+f 12318 11970 11974
+f 12217 11795 11794
+f 12319 12320 12321
+f 12322 12323 12324
+f 12325 12223 12326
+f 12020 12019 12119
+f 12327 11009 12225
+f 12120 11509 11889
+f 12226 12227 12084
+f 4537 12215 12328
+f 11890 11800 11799
+f 12328 12231 4537
+f 7749 7851 7750
+f 12328 12329 12233
+f 12231 12328 12233
+f 12330 12234 12233
+f 12329 12330 12233
+f 12331 12235 12234
+f 12330 12331 12234
+f 12332 12236 12235
+f 12331 12332 12235
+f 12333 12237 12236
+f 12332 12333 12236
+f 12334 12238 12237
+f 12333 12334 12237
+f 12335 12239 12238
+f 12334 12335 12238
+f 12335 12336 12240
+f 12239 12335 12240
+f 12336 12337 12241
+f 12240 12336 12241
+f 12337 12338 12242
+f 12241 12337 12242
+f 12338 12339 12243
+f 12242 12338 12243
+f 12339 12340 12244
+f 12243 12339 12244
+f 12340 12341 12245
+f 12244 12340 12245
+f 12342 12246 12245
+f 12341 12342 12245
+f 12343 12247 12246
+f 12342 12343 12246
+f 12343 12344 12248
+f 12247 12343 12248
+f 12344 12345 12249
+f 12248 12344 12249
+f 12345 12346 12250
+f 12249 12345 12250
+f 12346 12347 12251
+f 12250 12346 12251
+f 12348 12252 12251
+f 12347 12348 12251
+f 12349 12253 12252
+f 12348 12349 12252
+f 12350 12254 12253
+f 12349 12350 12253
+f 12351 12255 12254
+f 12350 12351 12254
+f 12351 12352 12256
+f 12255 12351 12256
+f 12353 12148 12256
+f 12352 12353 12256
+f 10070 10138 12354
+f 10748 8034 7941
+f 10792 10793 12355
+f 12356 4918 12357
+f 4460 12358 12359
+f 12224 12327 12225
+f 12360 12361 11056
+f 12362 10752 10754
+f 12363 10666 10753
+f 12364 12365 11570
+f 9261 12366 7663
+f 9801 12367 12368
+f 8654 5661 3190
+f 9801 12369 12367
+f 12370 12367 12371
+f 2014 2013 10938
+f 12273 12372 3364
+f 8661 12273 3364
+f 12373 10848 10850
+f 8114 10843 8920
+f 12212 12316 12374
+f 10844 12282 10655
+f 11061 12375 11062
+f 12376 10660 10693
+f 11010 11009 9386
+f 10752 12363 10753
+f 12377 10147 8123
+f 12378 10075 12379
+f 12380 9385 11009
+f 12381 12382 12383
+f 12384 12385 8961
+f 12386 12387 12388
+f 11926 10779 10781
+f 10797 10792 12389
+f 10793 12287 12355
+f 10848 12290 10849
+f 12290 12390 10849
+f 11035 12188 12391
+f 11406 11035 12391
+f 12292 12291 10672
+f 12291 12392 10672
+f 8370 3667 8366
+f 12091 12393 10232
+f 8275 8369 11142
+f 3731 4617 8279
+f 12394 12395 12294
+f 12295 6213 11515
+f 12297 12396 12298
+f 12396 12397 12298
+f 3511 9866 8918
+f 3384 7016 7015
+f 12398 9858 6252
+f 10299 1808 5664
+f 7015 12399 3384
+f 12399 12400 3384
+f 12399 12401 12400
+f 12401 12402 12400
+f 4376 12403 12404
+f 12405 12406 12402
+f 12401 12405 12402
+f 7456 6202 5497
+f 12407 4020 12406
+f 12405 12407 12406
+f 4124 2722 1717
+f 12408 12409 12410
+f 12311 12312 12411
+f 10629 5188 7840
+f 10741 12411 12314
+f 10741 12311 12411
+f 3773 12412 3774
+f 10742 12314 12413
+f 6710 2751 6160
+f 12412 10742 12413
+f 12414 12301 10610
+f 12415 11722 12416
+f 6602 3629 3628
+f 12417 12418 10610
+f 12223 12216 11794
+f 8546 3526 3525
+f 12419 12420 12421
+f 6602 3628 12422
+f 6996 12226 12084
+f 12423 12419 12421
+f 6997 12424 12425
+f 12118 12119 12227
+f 4760 10431 1357
+f 5917 5916 8008
+f 2972 2746 2748
+f 12215 5002 5004
+f 806 7205 7204
+f 12426 6187 12427
+f 12428 12331 12330
+f 12429 12428 12330
+f 12430 12332 12331
+f 12428 12430 12331
+f 12431 12333 12332
+f 12430 12431 12332
+f 12431 12432 12334
+f 12333 12431 12334
+f 12432 12433 12335
+f 12334 12432 12335
+f 12433 12434 12336
+f 12335 12433 12336
+f 12434 12435 12337
+f 12336 12434 12337
+f 12436 12338 12337
+f 12435 12436 12337
+f 12437 12339 12338
+f 12436 12437 12338
+f 12438 12340 12339
+f 12437 12438 12339
+f 12439 12341 12340
+f 12438 12439 12340
+f 12440 12342 12341
+f 12439 12440 12341
+f 12441 12343 12342
+f 12440 12441 12342
+f 12442 12344 12343
+f 12441 12442 12343
+f 12443 12345 12344
+f 12442 12443 12344
+f 12443 12444 12346
+f 12345 12443 12346
+f 12444 12445 12347
+f 12346 12444 12347
+f 12446 12348 12347
+f 12445 12446 12347
+f 12447 12349 12348
+f 12446 12447 12348
+f 12448 12350 12349
+f 12447 12448 12349
+f 12448 12449 12351
+f 12350 12448 12351
+f 12449 12450 12352
+f 12351 12449 12352
+f 12357 12353 12352
+f 12450 12357 12352
+f 12357 4918 12353
+f 10748 7941 12451
+f 12300 2216 12452
+f 11086 2700 2537
+f 12372 12453 12454
+f 12455 6368 6370
+f 3451 11200 8383
+f 6453 12456 6451
+f 3133 12457 3134
+f 12327 12380 11009
+f 9801 12368 12458
+f 12459 12460 1244
+f 12461 12462 12369
+f 9801 12461 12369
+f 12367 5925 5651
+f 12462 5926 12369
+f 11927 5890 12463
+f 3103 3105 12464
+f 11625 12185 12183
+f 12184 11980 12076
+f 3364 12372 12454
+f 10793 10728 12287
+f 12465 10705 10707
+f 2666 12466 12467
+f 12380 12468 4680
+f 10671 10591 10593
+f 9385 12380 4680
+f 12468 12469 4681
+f 6294 8673 5523
+f 4680 12468 4681
+f 12470 12471 12472
+f 11343 12473 10768
+f 3510 9866 3511
+f 12474 6537 12475
+f 8886 10797 12476
+f 10792 12355 12389
+f 10849 12390 12477
+f 12390 12478 12477
+f 11405 11406 12391
+f 12479 11405 12391
+f 10672 12392 10673
+f 12392 12480 10673
+f 12481 5315 12482
+f 12483 12484 12214
+f 10783 2060 2059
+f 12485 8275 11142
+f 12486 12487 12394
+f 12395 12295 12294
+f 12396 12488 12397
+f 12488 12489 12397
+f 5225 5224 6817
+f 10632 10631 12490
+f 9328 9042 12491
+f 8780 8779 10931
+f 12492 12154 12493
+f 6071 6487 6346
+f 9275 5535 10959
+f 12494 12495 11695
+f 2557 12496 1205
+f 12497 3694 3910
+f 1627 1787 8022
+f 12498 11961 10641
+f 12499 12500 3689
+f 11961 11960 10641
+f 4548 3359 7919
+f 12501 2593 2595
+f 12469 12502 12503
+f 5716 4548 7919
+f 8022 10573 7824
+f 12409 11001 11000
+f 10960 12504 10958
+f 11006 10730 11323
+f 10632 12490 11339
+f 8820 10375 8385
+f 3755 3731 8279
+f 4681 12469 12503
+f 12301 12299 10610
+f 3553 7230 1931
+f 4564 3272 3271
+f 12505 12506 12073
+f 12325 12326 12507
+f 7369 12508 7365
+f 12088 11987 12509
+f 10384 10460 10526
+f 12420 12510 12509
+f 12510 12088 12509
+f 12511 6931 12512
+f 12421 12420 12509
+f 5004 12328 12215
+f 8500 8502 2350
+f 12513 5006 5152
+f 4413 4412 8113
+f 12513 6693 12428
+f 12429 12513 12428
+f 6693 12514 12430
+f 12428 6693 12430
+f 12514 12515 12431
+f 12430 12514 12431
+f 12515 12516 12432
+f 12431 12515 12432
+f 12516 12517 12433
+f 12432 12516 12433
+f 12517 12518 12434
+f 12433 12517 12434
+f 12518 12519 12435
+f 12434 12518 12435
+f 12520 12436 12435
+f 12519 12520 12435
+f 12521 12437 12436
+f 12520 12521 12436
+f 12522 12438 12437
+f 12521 12522 12437
+f 12523 12439 12438
+f 12522 12523 12438
+f 12524 12440 12439
+f 12523 12524 12439
+f 12525 12441 12440
+f 12524 12525 12440
+f 12526 12442 12441
+f 12525 12526 12441
+f 12527 12443 12442
+f 12526 12527 12442
+f 12528 12444 12443
+f 12527 12528 12443
+f 12528 12529 12445
+f 12444 12528 12445
+f 12530 12446 12445
+f 12529 12530 12445
+f 12531 12447 12446
+f 12530 12531 12446
+f 12531 12532 12448
+f 12447 12531 12448
+f 12532 12533 12449
+f 12448 12532 12449
+f 12533 12534 12450
+f 12449 12533 12450
+f 12535 12357 12450
+f 12534 12535 12450
+f 10569 6163 3360
+f 12535 12356 12357
+f 8386 8914 7466
+f 4419 5454 4139
+f 12536 12537 12538
+f 12539 11482 5926
+f 10977 10757 10759
+f 12540 12541 12542
+f 10758 11055 11057
+f 1022 1029 1023
+f 4434 12543 4435
+f 12453 12544 12545
+f 12546 12547 12462
+f 12461 12546 12462
+f 12539 5926 12462
+f 12547 12539 12462
+f 2955 3105 3104
+f 11482 6072 5927
+f 12080 12079 10621
+f 12548 9785 9722
+f 10727 12183 12286
+f 12186 12289 12187
+f 2846 2661 12549
+f 10728 10727 12286
+f 12550 12551 12552
+f 4922 12553 4921
+f 12554 10815 10819
+f 12366 12555 12556
+f 7239 11512 11481
+f 12557 3322 3685
+f 12558 11513 11512
+f 11959 10742 12412
+f 12559 12560 12561
+f 12562 10996 10995
+f 12563 12548 9642
+f 8886 12476 12564
+f 7263 3433 10982
+f 12477 12478 12565
+f 12478 12566 12565
+f 12567 12568 12569
+f 11405 12479 12570
+f 10673 12480 12571
+f 12480 12572 12571
+f 12573 12574 6230
+f 3755 8279 12296
+f 12464 12497 3910
+f 7353 7352 12575
+f 12576 12487 12486
+f 12577 12576 12486
+f 12488 12578 12489
+f 12578 12579 12489
+f 12048 12050 6175
+f 12580 10635 11158
+f 10449 10521 10932
+f 3688 12499 3689
+f 12581 10664 10685
+f 12582 11092 12583
+f 11698 12584 12585
+f 12584 12586 12585
+f 11158 10635 11159
+f 12587 12588 12586
+f 12589 728 727
+f 11584 12590 11585
+f 12591 12592 12410
+f 12409 12593 12410
+f 12584 12587 12586
+f 12587 12594 12588
+f 8016 8015 3688
+f 12594 12595 12588
+f 12596 9178 8029
+f 6915 6917 12597
+f 8029 9178 8028
+f 12049 6915 12597
+f 4281 7746 4280
+f 8102 12598 5191
+f 6916 6582 6917
+f 12599 12600 12601
+f 8458 7330 8372
+f 2751 8454 7657
+f 12506 12418 12417
+f 8371 8664 3833
+f 12602 12603 12604
+f 11782 12605 11423
+f 3315 7833 11540
+f 6912 8802 6913
+f 3286 3285 9047
+f 9284 12606 9281
+f 12502 12607 12608
+f 6038 5095 5900
+f 12609 12325 12507
+f 12223 12222 12326
+f 4045 5442 7831
+f 12454 12453 12545
+f 12513 5301 6693
+f 7061 3003 3002
+f 6692 12610 12514
+f 6693 6692 12514
+f 12610 12611 12515
+f 12514 12610 12515
+f 12611 12612 12516
+f 12515 12611 12516
+f 12612 12613 12517
+f 12516 12612 12517
+f 12613 12614 12518
+f 12517 12613 12518
+f 12614 12615 12519
+f 12518 12614 12519
+f 12616 12520 12519
+f 12615 12616 12519
+f 12617 12521 12520
+f 12616 12617 12520
+f 12618 12522 12521
+f 12617 12618 12521
+f 12619 12523 12522
+f 12618 12619 12522
+f 12620 12524 12523
+f 12619 12620 12523
+f 12621 12525 12524
+f 12620 12621 12524
+f 12622 12526 12525
+f 12621 12622 12525
+f 12623 12527 12526
+f 12622 12623 12526
+f 12624 12528 12527
+f 12623 12624 12527
+f 12624 12625 12529
+f 12528 12624 12529
+f 12626 12530 12529
+f 12625 12626 12529
+f 12627 12531 12530
+f 12626 12627 12530
+f 12628 12532 12531
+f 12627 12628 12531
+f 12629 12533 12532
+f 12628 12629 12532
+f 12630 12534 12533
+f 12629 12630 12533
+f 12631 12535 12534
+f 12630 12631 12534
+f 12631 12632 12356
+f 12535 12631 12356
+f 12353 4918 4920
+f 12632 12633 12356
+f 2575 1204 1206
+f 12634 7247 4970
+f 10650 12635 11655
+f 6604 9271 6605
+f 7239 12558 11512
+f 6070 11482 12539
+f 12636 6234 11070
+f 12544 12637 12638
+f 12639 12640 12547
+f 12546 12639 12547
+f 12640 12641 12539
+f 12547 12640 12539
+f 12642 7262 7263
+f 12641 6070 12539
+f 12643 12644 12645
+f 1579 636 635
+f 12646 8293 12647
+f 12648 12649 12650
+f 5311 9781 11161
+f 12651 2967 2966
+f 12652 12653 12654
+f 4477 12017 12655
+f 12656 11514 11513
+f 12558 12656 11513
+f 12657 11558 11514
+f 10794 10796 11892
+f 12656 12657 11514
+f 12658 12562 10995
+f 11005 12659 12660
+f 4619 4123 1716
+f 12562 12661 8804
+f 12566 12662 12663
+f 10797 12389 12476
+f 12568 12570 12569
+f 12565 12566 12663
+f 12572 12664 11621
+f 12568 11405 12570
+f 12574 6231 6230
+f 12571 12572 11621
+f 6629 12665 12666
+f 1584 12667 1574
+f 12668 12669 12670
+f 5929 10233 5754
+f 12671 12672 12579
+f 12487 12395 12394
+f 12592 12673 12408
+f 12578 12671 12579
+f 12500 4125 5051
+f 12674 12675 12676
+f 6816 2112 9224
+f 3554 1467 8022
+f 12677 12678 11045
+f 12679 12580 11158
+f 12680 12681 12682
+f 12683 12680 12682
+f 12684 12685 12686
+f 12687 12684 12688
+f 12593 12409 11000
+f 12689 12690 12691
+f 12692 12693 12689
+f 12694 12695 12492
+f 12693 12690 12689
+f 12690 12696 12691
+f 8110 8109 12595
+f 12697 12698 12699
+f 12594 8110 12595
+f 12644 12643 12700
+f 5927 5924 11482
+f 6424 6687 6689
+f 12701 12702 6648
+f 11339 12490 10640
+f 12703 12704 1468
+f 12705 12706 12707
+f 12708 11566 12709
+f 12599 12601 12710
+f 12711 1790 1940
+f 2920 5354 5353
+f 12712 12505 12073
+f 12713 12714 12715
+f 10070 12354 4697
+f 12716 12605 11782
+f 6602 12507 6603
+f 10790 8885 7934
+f 8802 11796 9147
+f 6696 6603 11180
+f 7855 12717 12718
+f 11958 11307 11308
+f 12074 12506 12417
+f 2464 7543 3206
+f 3894 5231 3889
+f 8209 5614 5617
+f 12719 12720 12610
+f 6692 12719 12610
+f 12720 12721 12611
+f 12610 12720 12611
+f 12721 12722 12612
+f 12611 12721 12612
+f 12722 12723 12613
+f 12612 12722 12613
+f 12723 12724 12614
+f 12613 12723 12614
+f 12724 12725 12615
+f 12614 12724 12615
+f 12725 12726 12616
+f 12615 12725 12616
+f 12726 12727 12617
+f 12616 12726 12617
+f 12727 12728 12618
+f 12617 12727 12618
+f 12729 12619 12618
+f 12728 12729 12618
+f 12730 12620 12619
+f 12729 12730 12619
+f 12731 12621 12620
+f 12730 12731 12620
+f 12732 12622 12621
+f 12731 12732 12621
+f 12733 12623 12622
+f 12732 12733 12622
+f 12734 12624 12623
+f 12733 12734 12623
+f 12735 12625 12624
+f 12734 12735 12624
+f 12735 12736 12626
+f 12625 12735 12626
+f 12737 12627 12626
+f 12736 12737 12626
+f 12738 12628 12627
+f 12737 12738 12627
+f 12739 12629 12628
+f 12738 12739 12628
+f 12740 12630 12629
+f 12739 12740 12629
+f 12741 12631 12630
+f 12740 12741 12630
+f 12741 12742 12632
+f 12631 12741 12632
+f 12742 12743 12633
+f 12632 12742 12633
+f 2953 3104 8689
+f 12743 12167 12633
+f 6692 5300 12719
+f 5093 10234 10933
+f 10007 8462 9935
+f 7262 12642 12744
+f 12545 12544 12638
+f 9446 12745 12746
+f 12546 6955 12639
+f 12747 12640 12639
+f 12748 12747 12639
+f 12749 12641 12640
+f 12747 12749 12640
+f 12750 6070 12641
+f 12749 12750 12641
+f 6487 6071 6070
+f 12750 6487 6070
+f 6071 6346 11707
+f 9636 12192 9637
+f 12751 7758 8667
+f 3065 3069 11191
+f 7460 7219 7345
+f 11438 11440 12752
+f 10001 10002 6809
+f 4603 4606 9621
+f 12753 11559 11558
+f 12657 12753 11558
+f 11836 12754 10675
+f 11217 10669 11129
+f 8804 12661 6453
+f 10996 12562 8804
+f 10845 12646 12755
+f 11440 11546 12752
+f 12663 12662 12756
+f 12662 12757 12756
+f 12567 12569 12758
+f 12759 12567 12758
+f 11621 12664 11622
+f 12664 12760 11622
+f 12761 12574 12573
+f 12762 12761 12573
+f 12763 2828 2834
+f 12764 10522 8552
+f 12765 12766 12577
+f 12767 1337 12768
+f 12671 12769 12672
+f 12769 12770 12672
+f 12771 12772 12773
+f 12774 12775 12592
+f 12776 6146 4592
+f 4890 6512 4891
+f 12406 4020 9852
+f 12402 12406 5922
+f 12777 5958 5957
+f 12582 12679 11092
+f 12778 12779 12682
+f 12681 12778 12682
+f 12780 12687 12688
+f 12781 12687 12780
+f 12782 12694 12492
+f 12783 12784 12085
+f 12785 12085 12695
+f 12694 12785 12695
+f 12785 12783 12085
+f 12784 12783 12786
+f 12698 12693 12692
+f 12783 12787 12786
+f 12788 12697 12789
+f 5586 12698 12692
+f 12697 12699 12789
+f 12698 5586 12699
+f 12154 12155 12258
+f 11871 12087 11872
+f 12790 12791 12792
+f 12493 12154 12258
+f 12793 12703 12794
+f 12795 11354 12790
+f 1994 12596 1995
+f 5648 12796 1469
+f 6233 9096 9373
+f 12660 12599 12797
+f 12798 12716 11782
+f 7669 3509 12799
+f 12317 12318 11974
+f 12605 12712 11423
+f 12716 12798 11970
+f 12318 12716 11970
+f 11423 12712 12073
+f 12506 12074 12073
+f 3689 12500 5051
+f 12418 12414 10610
+f 1712 12800 8041
+f 1472 7766 12801
+f 12802 12803 12720
+f 12719 12802 12720
+f 12803 12804 12721
+f 12720 12803 12721
+f 12805 12722 12721
+f 12804 12805 12721
+f 12806 12723 12722
+f 12805 12806 12722
+f 12807 12724 12723
+f 12806 12807 12723
+f 12808 12725 12724
+f 12807 12808 12724
+f 12808 12809 12726
+f 12725 12808 12726
+f 12809 12810 12727
+f 12726 12809 12727
+f 12810 12811 12728
+f 12727 12810 12728
+f 12811 12812 12729
+f 12728 12811 12729
+f 12812 12813 12730
+f 12729 12812 12730
+f 12813 12814 12731
+f 12730 12813 12731
+f 12815 12732 12731
+f 12814 12815 12731
+f 12816 12733 12732
+f 12815 12816 12732
+f 12816 12817 12734
+f 12733 12816 12734
+f 12818 12735 12734
+f 12817 12818 12734
+f 12819 12736 12735
+f 12818 12819 12735
+f 12820 12737 12736
+f 12819 12820 12736
+f 12821 12738 12737
+f 12820 12821 12737
+f 12822 12739 12738
+f 12821 12822 12738
+f 12823 12740 12739
+f 12822 12823 12739
+f 12824 12741 12740
+f 12823 12824 12740
+f 12825 12742 12741
+f 12824 12825 12741
+f 12825 12826 12743
+f 12742 12825 12743
+f 12168 12827 12828
+f 12743 12826 12167
+f 4312 12829 4313
+f 7471 2740 10151
+f 8385 9593 8386
+f 5220 7035 11278
+f 12830 12831 12832
+f 12833 10949 10951
+f 12834 12835 12748
+f 6541 12836 12837
+f 12838 12747 12748
+f 12835 12838 12748
+f 12839 12749 12747
+f 12838 12839 12747
+f 12840 12750 12749
+f 12839 12840 12749
+f 6488 6487 12750
+f 12840 6488 12750
+f 2422 2122 12841
+f 6071 11707 6072
+f 12661 12456 6453
+f 12456 10595 6451
+f 12842 12843 11835
+f 12844 12754 11836
+f 12845 11628 11559
+f 12753 12845 11559
+f 12846 11629 11628
+f 12845 12846 11628
+f 12847 12848 2533
+f 12843 12844 11835
+f 1668 6463 6332
+f 3316 3102 11250
+f 12849 10945 10789
+f 10788 12849 10789
+f 12756 12757 12850
+f 12757 12851 12850
+f 12852 12853 12854
+f 12759 12758 12854
+f 11622 12760 12470
+f 12760 12855 12470
+f 10721 12856 12857
+f 12856 12761 12762
+f 7441 7327 8781
+f 12858 12859 12860
+f 12861 12766 12765
+f 12862 12861 12765
+f 12769 12863 12770
+f 12863 12864 12770
+f 6933 6834 7038
+f 4020 6891 9852
+f 12503 12502 12608
+f 8831 9262 12865
+f 6422 6423 6425
+f 12402 5922 3382
+f 12866 12867 12779
+f 12866 12868 12867
+f 12778 12866 12779
+f 12868 12869 12867
+f 11353 12781 12780
+f 10663 12870 12871
+f 12595 8109 10634
+f 6615 1179 1208
+f 12797 12710 12678
+f 12677 12797 12678
+f 1125 12872 732
+f 12679 11158 11092
+f 12873 12585 12874
+f 12797 12599 12710
+f 12873 12874 12786
+f 12586 12679 12582
+f 12787 12873 12786
+f 12585 12582 12874
+f 12585 12586 12582
+f 12588 12580 12679
+f 3703 3702 5905
+f 12595 10634 12580
+f 12791 12875 12792
+f 12688 12684 12686
+f 12876 12793 12877
+f 12878 12879 12880
+f 12659 12600 12599
+f 12642 7263 10982
+f 1637 8692 7246
+f 12881 12882 12089
+f 12607 12883 12884
+f 12412 12413 3774
+f 8045 12885 12886
+f 12887 12888 8692
+f 12889 6915 12049
+f 8041 709 708
+f 4012 12596 8029
+f 12890 12891 12892
+f 3592 5506 3778
+f 8204 8203 5491
+f 5711 12893 12803
+f 12802 5711 12803
+f 12894 12804 12803
+f 12893 12894 12803
+f 12895 12805 12804
+f 12894 12895 12804
+f 12896 12806 12805
+f 12895 12896 12805
+f 12897 12807 12806
+f 12896 12897 12806
+f 12898 12808 12807
+f 12897 12898 12807
+f 12898 12899 12809
+f 12808 12898 12809
+f 12899 12900 12810
+f 12809 12899 12810
+f 12900 12901 12811
+f 12810 12900 12811
+f 12901 12902 12812
+f 12811 12901 12812
+f 12902 12903 12813
+f 12812 12902 12813
+f 12903 12904 12814
+f 12813 12903 12814
+f 12904 12905 12815
+f 12814 12904 12815
+f 12905 12906 12816
+f 12815 12905 12816
+f 12906 12907 12817
+f 12816 12906 12817
+f 12908 12818 12817
+f 12907 12908 12817
+f 12909 12819 12818
+f 12908 12909 12818
+f 12909 12910 12820
+f 12819 12909 12820
+f 12911 12821 12820
+f 12910 12911 12820
+f 12912 12822 12821
+f 12911 12912 12821
+f 12913 12823 12822
+f 12912 12913 12822
+f 12914 12824 12823
+f 12913 12914 12823
+f 12915 12825 12824
+f 12914 12915 12824
+f 12916 12826 12825
+f 12915 12916 12825
+f 10049 3146 9905
+f 8689 3104 12917
+f 12918 12919 1370
+f 12920 7643 7645
+f 9933 2593 12501
+f 12921 12922 12923
+f 12924 12925 12834
+f 6957 12926 12834
+f 12925 12927 12835
+f 12834 12925 12835
+f 12928 12838 12835
+f 12927 12928 12835
+f 12929 12839 12838
+f 12928 12929 12838
+f 6833 12840 12839
+f 12929 6833 12839
+f 6727 6488 12840
+f 6833 6727 12840
+f 12608 12884 12930
+f 12931 5460 8219
+f 12932 3812 99
+f 1470 12796 12933
+f 6193 6192 12934
+f 12493 12258 12935
+f 12936 11630 11629
+f 11586 12937 12938
+f 12939 12940 12941
+f 12846 12936 11629
+f 11835 12844 11836
+f 12942 11663 11630
+f 12943 12921 12923
+f 12754 11506 10675
+f 12944 11361 10879
+f 12945 12167 931
+f 12851 12946 12181
+f 10899 10846 11214
+f 12947 12853 12852
+f 12850 12851 12181
+f 12855 12948 12471
+f 12949 12759 12854
+f 12856 12950 12857
+f 12470 12855 12471
+f 10523 7441 8781
+f 12950 12856 12762
+f 12951 12952 12862
+f 12953 1145 12954
+f 12955 12956 12864
+f 12766 12576 12577
+f 8009 12048 6175
+f 12863 12955 12864
+f 3775 11891 12494
+f 3708 3710 10017
+f 7647 7646 5443
+f 5062 12704 7217
+f 12400 12402 3382
+f 12406 9852 5922
+f 12957 12958 12869
+f 12868 12957 12869
+f 12870 12959 12871
+f 12960 12870 10663
+f 12959 12781 11353
+f 12871 12959 11353
+f 5452 9623 5453
+f 10937 12961 12962
+f 4909 4908 4011
+f 8449 12963 8450
+f 12780 12688 12791
+f 12688 12686 12875
+f 12600 12493 12601
+f 11354 12780 12791
+f 12794 1470 12964
+f 12877 12794 12964
+f 12219 12965 12966
+f 12967 12968 12969
+f 12880 12970 12971
+f 12966 12967 12969
+f 12588 12595 12580
+f 12683 12673 12775
+f 12788 12789 12686
+f 12586 12588 12679
+f 12680 12683 12970
+f 12685 12788 12686
+f 12793 12794 12877
+f 12967 12972 12968
+f 11875 12797 12677
+f 12659 12782 12600
+f 12881 12089 12504
+f 12882 11875 12677
+f 10960 12881 12504
+f 12882 12677 12089
+f 12660 12659 12599
+f 12973 12974 3042
+f 5851 5582 5850
+f 7216 8298 2775
+f 3876 3874 3491
+f 12975 12976 12977
+f 12978 12893 5711
+f 12979 12978 5711
+f 12980 12894 12893
+f 12978 12980 12893
+f 12981 12895 12894
+f 12980 12981 12894
+f 12982 12896 12895
+f 12981 12982 12895
+f 12983 12897 12896
+f 12982 12983 12896
+f 12984 12898 12897
+f 12983 12984 12897
+f 12984 12985 12899
+f 12898 12984 12899
+f 12985 12986 12900
+f 12899 12985 12900
+f 12986 12987 12901
+f 12900 12986 12901
+f 12987 12988 12902
+f 12901 12987 12902
+f 12988 12989 12903
+f 12902 12988 12903
+f 12989 12990 12904
+f 12903 12989 12904
+f 12990 12991 12905
+f 12904 12990 12905
+f 12991 12992 12906
+f 12905 12991 12906
+f 12993 12907 12906
+f 12992 12993 12906
+f 12994 12908 12907
+f 12993 12994 12907
+f 12994 12995 12909
+f 12908 12994 12909
+f 12995 12996 12910
+f 12909 12995 12910
+f 12997 12911 12910
+f 12996 12997 12910
+f 12997 12998 12912
+f 12911 12997 12912
+f 12998 12999 12913
+f 12912 12998 12913
+f 12999 13000 12914
+f 12913 12999 12914
+f 13001 12915 12914
+f 13000 13001 12914
+f 13002 12916 12915
+f 13001 13002 12915
+f 12918 12827 12916
+f 13002 12918 12916
+f 4536 4535 4534
+f 13003 13004 10
+f 5884 5883 5747
+f 6730 6727 6833
+f 12924 12926 13005
+f 13006 13007 12927
+f 12925 13006 12927
+f 13008 12928 12927
+f 13007 13008 12927
+f 11239 12929 12928
+f 13008 11239 12928
+f 4726 4576 4575
+f 4741 5913 5912
+f 3270 3274 3070
+f 4325 13009 4326
+f 13010 13011 13012
+f 13013 13014 13015
+f 5585 5587 13016
+f 13017 5585 13016
+f 12601 12493 12935
+f 10686 13018 13019
+f 1594 1597 1826
+f 7022 6818 5226
+f 2898 2705 2704
+f 7453 4896 5725
+f 12936 12942 11630
+f 12942 13020 11700
+f 9262 8831 9375
+f 7425 7427 7429
+f 13021 11358 13022
+f 11218 11129 12090
+f 12670 13023 10875
+f 13024 13025 13026
+f 13027 13013 13015
+f 12946 13028 13029
+f 13030 12947 13031
+f 13032 13030 13031
+f 13033 13034 10925
+f 12948 13033 13035
+f 13036 10722 6808
+f 10721 12857 13037
+f 3107 3106 7834
+f 13038 13039 13040
+f 13041 12952 12951
+f 13042 13041 12951
+f 12955 13043 12956
+f 13043 13044 12956
+f 11874 12660 11875
+f 12608 12607 12884
+f 3775 3774 11891
+f 3774 10794 11891
+f 13023 10873 10875
+f 7040 8837 8836
+f 13045 13046 12958
+f 3938 1086 4618
+f 12957 13045 12958
+f 6704 5882 5884
+f 13047 12960 10663
+f 11581 13048 13049
+f 13050 13051 13052
+f 13053 10949 12833
+f 6808 3628 6809
+f 13054 13055 13056
+f 11960 11962 13057
+f 3836 3148 1537
+f 12791 12688 12875
+f 6332 1669 1668
+f 13058 4923 13059
+f 12794 1468 1470
+f 12691 12877 12964
+f 13060 12691 12964
+f 12880 12971 12969
+f 12968 12880 12969
+f 13061 13062 13063
+f 13064 13061 13063
+f 13065 13066 13067
+f 12772 13065 13067
+f 13046 13068 12771
+f 10631 13046 12771
+f 12958 13046 10631
+f 10630 12958 10631
+f 12878 12880 12968
+f 7021 11229 7023
+f 5624 5876 5625
+f 13069 12972 12967
+f 11875 12660 12797
+f 9178 13070 8028
+f 12703 1468 12794
+f 12634 10016 7247
+f 12696 12876 12877
+f 12691 12696 12877
+f 4734 9662 13071
+f 13072 13038 13040
+f 5582 5851 12979
+f 13073 13053 12833
+f 13074 12978 12979
+f 6006 13074 12979
+f 13075 12980 12978
+f 13074 13075 12978
+f 13076 12981 12980
+f 13075 13076 12980
+f 13077 12982 12981
+f 13076 13077 12981
+f 13078 12983 12982
+f 13077 13078 12982
+f 13078 13079 12984
+f 12983 13078 12984
+f 13079 13080 12985
+f 12984 13079 12985
+f 13080 13081 12986
+f 12985 13080 12986
+f 13081 13082 12987
+f 12986 13081 12987
+f 13082 13083 12988
+f 12987 13082 12988
+f 13083 13084 12989
+f 12988 13083 12989
+f 13084 13085 12990
+f 12989 13084 12990
+f 13085 13086 12991
+f 12990 13085 12991
+f 13086 13087 12992
+f 12991 13086 12992
+f 13087 13088 12993
+f 12992 13087 12993
+f 13088 13089 12994
+f 12993 13088 12994
+f 13089 13090 12995
+f 12994 13089 12995
+f 13090 13091 12996
+f 12995 13090 12996
+f 13092 12997 12996
+f 13091 13092 12996
+f 13093 12998 12997
+f 13092 13093 12997
+f 13093 13094 12999
+f 12998 13093 12999
+f 13094 13095 13000
+f 12999 13094 13000
+f 13095 13096 13001
+f 13000 13095 13001
+f 13097 13002 13001
+f 13096 13097 13001
+f 1013 13097 1014
+f 13098 13099 13100
+f 4971 1100 1099
+f 3938 9151 5051
+f 3465 3515 3270
+f 4560 5054 9784
+f 13101 13102 13007
+f 857 13053 13073
+f 13103 13008 13007
+f 13102 13103 13007
+f 11238 11239 13008
+f 13103 11238 13008
+f 13104 8115 7845
+f 858 857 13073
+f 13031 12947 12852
+f 6302 7112 6457
+f 12181 12946 13029
+f 13028 13105 13106
+f 10874 13107 10923
+f 13107 13108 13109
+f 11210 13110 13111
+f 13112 11262 13113
+f 10775 10639 6628
+f 11927 12463 13114
+f 13115 10680 13116
+f 11663 12942 11700
+f 13020 13117 11701
+f 11700 13020 11701
+f 10281 10280 1357
+f 7352 13118 12575
+f 13119 13120 13121
+f 13110 13122 13111
+f 13025 10970 13026
+f 11322 10720 11749
+f 13015 13014 13123
+f 13014 13124 13123
+f 13125 10617 13126
+f 10643 13127 13128
+f 11695 12495 10960
+f 13035 13033 10925
+f 3315 11540 3108
+f 10722 10721 13037
+f 12196 13129 13130
+f 5889 6704 5890
+f 7653 6462 6461
+f 12952 12861 12862
+f 13131 13132 13133
+f 13043 13134 13135
+f 12413 10795 10794
+f 12875 13136 12111
+f 13137 13138 13139
+f 3774 12413 10794
+f 13140 13141 13142
+f 12182 13029 13143
+f 13144 13145 12884
+f 13146 13140 13142
+f 11580 11581 13049
+f 11044 11046 13147
+f 13148 13149 11052
+f 11093 11159 11341
+f 11325 11338 13150
+f 12052 11000 13151
+f 6457 11178 6458
+f 11092 11158 11093
+f 6062 9621 4606
+f 13152 13153 10831
+f 12053 13151 13154
+f 12260 12259 13155
+f 13156 13157 13158
+f 7221 7460 7349
+f 13159 12965 12219
+f 11696 11698 13012
+f 12970 12775 12971
+f 12218 13159 12219
+f 13064 13063 13067
+f 13066 13064 13067
+f 13160 13061 13064
+f 13161 13160 13064
+f 2011 12959 12870
+f 13162 12960 13061
+f 13163 12687 12781
+f 13164 2011 12870
+f 12938 13165 10609
+f 2010 13163 12781
+f 12965 13069 12967
+f 13166 12685 12684
+f 13167 13168 13169
+f 12972 13170 12968
+f 13171 13069 12965
+f 13159 13171 12965
+f 13170 12878 12968
+f 12879 12970 12880
+f 13172 12848 12847
+f 12879 12680 12970
+f 5851 6006 12979
+f 6511 10503 9188
+f 13173 13074 6006
+f 6005 13173 6006
+f 13174 13075 13074
+f 13173 13174 13074
+f 13175 13076 13075
+f 13174 13175 13075
+f 13176 13077 13076
+f 13175 13176 13076
+f 13177 13078 13077
+f 13176 13177 13077
+f 13177 13178 13079
+f 13078 13177 13079
+f 13178 13179 13080
+f 13079 13178 13080
+f 13179 13180 13081
+f 13080 13179 13081
+f 13180 13181 13082
+f 13081 13180 13082
+f 13181 13182 13083
+f 13082 13181 13083
+f 13182 13183 13084
+f 13083 13182 13084
+f 13183 13184 13085
+f 13084 13183 13085
+f 13184 13185 13086
+f 13085 13184 13086
+f 13185 13186 13087
+f 13086 13185 13087
+f 13186 13187 13088
+f 13087 13186 13088
+f 13187 13188 13089
+f 13088 13187 13089
+f 13188 13189 13090
+f 13089 13188 13090
+f 13189 13190 13091
+f 13090 13189 13091
+f 13191 13092 13091
+f 13190 13191 13091
+f 13192 13093 13092
+f 13191 13192 13092
+f 13193 13094 13093
+f 13192 13193 13093
+f 13193 13194 13095
+f 13094 13193 13095
+f 13194 13195 13096
+f 13095 13194 13096
+f 1014 13097 13096
+f 13195 1014 13096
+f 3332 8013 7920
+f 1371 1015 1872
+f 8567 12268 13196
+f 5490 8204 5491
+f 7241 943 4908
+f 10878 13197 10876
+f 13198 13199 13102
+f 13101 13198 13102
+f 13200 13103 13102
+f 13199 13200 13102
+f 11328 11238 13103
+f 13200 11328 13103
+f 3454 11189 11230
+f 13201 13202 13203
+f 12853 12949 12854
+f 2753 2752 6198
+f 13029 13028 13106
+f 10643 13030 13127
+f 11361 10880 10879
+f 13105 13013 13027
+f 13204 13112 13113
+f 13205 13206 13207
+f 11159 7843 7842
+f 11317 11316 11420
+f 13117 13208 11750
+f 4969 8672 13209
+f 11701 13117 11750
+f 13208 13210 13211
+f 3083 10656 13212
+f 11750 13208 13211
+f 13213 13214 13039
+f 3084 3083 13212
+f 13215 13216 13217
+f 13218 13219 13220
+f 13221 1032 1831
+f 3672 6579 3478
+f 13222 13223 13224
+f 6068 13225 13226
+f 13227 13228 13126
+f 10617 13128 13126
+f 13011 13229 13012
+f 11892 10796 12882
+f 12773 12498 10641
+f 10640 12773 10641
+f 6300 5167 6298
+f 13230 13231 13232
+f 13233 13234 13235
+f 6359 11776 8951
+f 13016 5587 12114
+f 13231 11258 13232
+f 13236 13237 11659
+f 12113 13060 13238
+f 13239 13240 13241
+f 13242 11548 11617
+f 12261 12263 13243
+f 938 12945 930
+f 6510 11272 6511
+f 12205 10798 10800
+f 13239 13241 7545
+f 13240 11083 13241
+f 13141 12060 13142
+f 11342 13244 13245
+f 12606 13246 9281
+f 12060 13245 13142
+f 12314 11003 10795
+f 13115 4860 4859
+f 12964 12933 13238
+f 13060 12964 13238
+f 12199 12201 13247
+f 13129 12196 13248
+f 13213 13249 13214
+f 12883 13144 12884
+f 3707 387 13250
+f 13251 13068 13046
+f 12965 12967 12966
+f 13062 13061 13047
+f 13068 13065 12772
+f 12771 13068 12772
+f 13160 13162 13061
+f 13164 12870 12960
+f 12874 12583 11181
+f 12673 13252 12408
+f 12504 12089 11044
+f 12874 12582 12583
+f 5441 8462 10081
+f 12089 12677 11045
+f 13253 12704 12703
+f 13254 13253 12703
+f 13254 12703 12793
+f 13255 13254 12793
+f 13256 13257 12696
+f 12690 13256 12696
+f 12696 13257 12876
+f 13257 13258 12876
+f 13258 13255 12876
+f 13255 12793 12876
+f 11277 5878 5725
+f 13259 13260 13261
+f 11787 13262 13173
+f 6005 11787 13173
+f 13263 13174 13173
+f 13262 13263 13173
+f 13264 13175 13174
+f 13263 13264 13174
+f 13265 13176 13175
+f 13264 13265 13175
+f 13266 13177 13176
+f 13265 13266 13176
+f 13266 13267 13178
+f 13177 13266 13178
+f 13267 13268 13179
+f 13178 13267 13179
+f 13268 13269 13180
+f 13179 13268 13180
+f 13269 13270 13181
+f 13180 13269 13181
+f 13270 13271 13182
+f 13181 13270 13182
+f 13271 13272 13183
+f 13182 13271 13183
+f 13272 13273 13184
+f 13183 13272 13184
+f 13273 13274 13185
+f 13184 13273 13185
+f 13274 13275 13186
+f 13185 13274 13186
+f 13275 13276 13187
+f 13186 13275 13187
+f 13276 13277 13188
+f 13187 13276 13188
+f 13277 13278 13189
+f 13188 13277 13189
+f 13278 13279 13190
+f 13189 13278 13190
+f 13280 13191 13190
+f 13279 13280 13190
+f 13281 13192 13191
+f 13280 13281 13191
+f 13281 13282 13193
+f 13192 13281 13193
+f 13282 13283 13194
+f 13193 13282 13194
+f 13283 13284 13195
+f 13194 13283 13195
+f 13285 1014 13195
+f 13284 13285 13195
+f 1015 13286 1872
+f 13285 1015 1014
+f 13287 6192 13288
+f 13289 13290 12940
+f 13291 13292 2424
+f 3407 1595 3204
+f 13293 7244 13199
+f 13101 13007 13006
+f 13294 13200 13199
+f 7244 13294 13199
+f 13295 11328 13200
+f 13294 13295 13200
+f 6187 13296 12427
+f 8308 6894 6893
+f 12471 12948 13035
+f 13297 12674 13298
+f 10617 10643 13128
+f 13030 13032 13127
+f 13106 13105 13027
+f 13299 13300 13301
+f 13302 13303 13304
+f 13229 11696 13012
+f 11419 7950 13305
+f 7640 943 7241
+f 11477 13306 11478
+f 5440 10156 10080
+f 7438 6829 3113
+f 9055 5755 9056
+f 8106 5192 8669
+f 7202 6580 6916
+f 2427 13291 2424
+f 4292 6017 4289
+f 11408 11477 11409
+f 13306 12153 13307
+f 3450 3452 5620
+f 13119 13121 13308
+f 10938 10937 12962
+f 10804 12232 13309
+f 11879 13310 13311
+f 13312 13222 13224
+f 13313 13228 13227
+f 13314 13313 13227
+f 10925 13034 13315
+f 13034 13316 13315
+f 11324 10632 11339
+f 12490 12773 10640
+f 12207 13317 13247
+f 5183 7940 8040
+f 6691 5858 13145
+f 12195 12197 13318
+f 12060 11342 13245
+f 11341 13319 13244
+f 11342 11341 13244
+f 7842 9155 13319
+f 13240 5496 11083
+f 13320 11780 13321
+f 13322 13323 13324
+f 13325 12208 10800
+f 13326 11873 13327
+f 13328 13326 13327
+f 13326 13328 13329
+f 12259 13326 13329
+f 6458 6462 6459
+f 6457 7457 11178
+f 12775 12673 12592
+f 3213 9662 9210
+f 13252 13330 12409
+f 13144 6691 13145
+f 12964 1470 12933
+f 13331 5211 13332
+f 13333 13334 13335
+f 12504 11044 13336
+f 5923 8463 5921
+f 12413 12314 10795
+f 13045 13251 13046
+f 3384 12400 3382
+f 13061 12960 13047
+f 13337 13065 13068
+f 12869 12958 10630
+f 10729 12869 10630
+f 13162 13164 12960
+f 2010 12781 12959
+f 12695 12087 12154
+f 12580 10634 10635
+f 12310 12307 12674
+f 12307 12308 13011
+f 12304 12303 13229
+f 12675 12307 13011
+f 12302 11215 11697
+f 12302 11697 11696
+f 12755 13338 13339
+f 11214 13339 13340
+f 12646 13341 13338
+f 11214 12755 13339
+f 13342 13343 13344
+f 12755 12646 13338
+f 13156 13345 5492
+f 13346 9340 9847
+f 12398 13347 10018
+f 13038 13213 13039
+f 13348 13262 11787
+f 13349 13348 11787
+f 13350 13263 13262
+f 13348 13350 13262
+f 13351 13264 13263
+f 13350 13351 13263
+f 13352 13265 13264
+f 13351 13352 13264
+f 13353 13266 13265
+f 13352 13353 13265
+f 13353 13354 13267
+f 13266 13353 13267
+f 13354 13355 13268
+f 13267 13354 13268
+f 13355 13356 13269
+f 13268 13355 13269
+f 13356 13357 13270
+f 13269 13356 13270
+f 13357 13358 13271
+f 13270 13357 13271
+f 13358 13359 13272
+f 13271 13358 13272
+f 13359 13360 13273
+f 13272 13359 13273
+f 13360 13361 13274
+f 13273 13360 13274
+f 13361 13362 13275
+f 13274 13361 13275
+f 13362 13363 13276
+f 13275 13362 13276
+f 13363 13364 13277
+f 13276 13363 13277
+f 13364 13365 13278
+f 13277 13364 13278
+f 13365 13366 13279
+f 13278 13365 13279
+f 13367 13280 13279
+f 13366 13367 13279
+f 13368 13281 13280
+f 13367 13368 13280
+f 13368 13369 13282
+f 13281 13368 13282
+f 13370 6901 13369
+f 13282 13369 13283
+f 13371 13369 6901
+f 13283 13371 13284
+f 13372 13285 13284
+f 6900 13372 13284
+f 6900 13373 13372
+f 8696 1338 3320
+f 7115 8116 8200
+f 13374 10749 10750
+f 12087 11871 12155
+f 2960 13375 4640
+f 13376 13377 13378
+f 13379 13376 13378
+f 13380 13294 7244
+f 7243 13380 7244
+f 13381 13295 13294
+f 13380 13381 13294
+f 9771 7039 7041
+f 13381 13382 13295
+f 13249 13383 13214
+f 13382 7142 7042
+f 13384 13217 13385
+f 4440 4059 4058
+f 8450 13386 13387
+f 13308 13388 13389
+f 13390 13391 13392
+f 7729 8658 13393
+f 9784 11020 5633
+f 13394 13395 13396
+f 13397 13398 10785
+f 4012 8029 4010
+f 8303 6625 6142
+f 12153 11627 13307
+f 1862 2015 2017
+f 9932 8561 8560
+f 13399 13400 13401
+f 8456 8550 8457
+f 13402 11502 9630
+f 13306 13307 11478
+f 2016 13403 13404
+f 9631 13402 9630
+f 13405 11879 13311
+f 2921 3505 2922
+f 13406 13313 13314
+f 12481 13407 13408
+f 13316 13409 11431
+f 13228 13125 13126
+f 13410 13411 10002
+f 13315 13316 11431
+f 13411 13036 6807
+f 10722 13037 6808
+f 12323 13412 13413
+f 3361 3360 6165
+f 13011 13010 13414
+f 13415 12792 13416
+f 13417 13253 13254
+f 9059 12270 9058
+f 12201 12207 13247
+f 12197 12199 13318
+f 11341 7842 13319
+f 8837 4580 5512
+f 2354 928 9781
+f 1366 1365 5514
+f 11873 13140 13146
+f 13327 11873 13146
+f 13249 13418 13419
+f 12772 13067 12498
+f 6062 10716 9621
+f 10796 11875 12882
+f 13044 13043 13135
+f 13134 13420 13421
+f 12495 11892 12882
+f 13135 13134 13421
+f 12463 6704 13422
+f 4701 4703 9709
+f 8109 1217 10634
+f 5884 13423 9622
+f 12411 11004 11003
+f 4702 4045 4703
+f 8698 11479 391
+f 12314 12411 11003
+f 13251 13337 13068
+f 13063 11961 12498
+f 13424 12867 10729
+f 13425 13066 13065
+f 2011 2010 12959
+f 13426 12684 12687
+f 12232 10804 2921
+f 12600 12492 12493
+f 12308 12304 13229
+f 13011 12308 13229
+f 10713 13427 7014
+f 13428 12399 7015
+f 8032 13429 8033
+f 10081 10007 13430
+f 6754 390 11160
+f 13431 12404 12403
+f 13431 12403 4213
+f 13432 13431 4213
+f 13433 13434 13320
+f 13435 4687 11780
+f 13432 4213 4687
+f 13434 13435 11780
+f 4125 3938 5051
+f 13435 13432 4687
+f 7954 13348 13349
+f 2396 2398 13436
+f 13437 13350 13348
+f 7954 13437 13348
+f 13438 13351 13350
+f 13437 13438 13350
+f 13439 13352 13351
+f 13438 13439 13351
+f 13440 13353 13352
+f 13439 13440 13352
+f 13441 13354 13353
+f 13440 13441 13353
+f 13441 13442 13355
+f 13354 13441 13355
+f 13442 13443 13356
+f 13355 13442 13356
+f 13443 13444 13357
+f 13356 13443 13357
+f 13444 13445 13358
+f 13357 13444 13358
+f 13445 13446 13359
+f 13358 13445 13359
+f 13446 13447 13360
+f 13359 13446 13360
+f 13447 13448 13361
+f 13360 13447 13361
+f 13448 13449 13362
+f 13361 13448 13362
+f 13449 1774 13363
+f 13362 13449 13363
+f 1774 13450 13364
+f 13363 1774 13364
+f 13450 13451 13365
+f 13364 13450 13365
+f 13451 13452 13366
+f 13365 13451 13366
+f 13452 13453 13367
+f 13366 13452 13367
+f 13454 13368 13367
+f 13455 13453 13456
+f 13457 13458 13459
+f 13454 13453 13455
+f 11094 11093 11342
+f 12080 10621 10620
+f 13109 13460 13461
+f 11159 7842 11341
+f 3902 9055 9057
+f 3815 9135 2905
+f 12147 6183 2578
+f 13462 1170 1042
+f 13463 7646 4208
+f 11550 13464 11551
+f 13465 9380 13345
+f 6054 6339 6055
+f 13466 13467 13468
+f 13469 13470 6229
+f 9999 3443 6502
+f 1017 1154 1018
+f 7114 7113 4595
+f 13293 7245 7244
+f 1250 7932 1248
+f 3515 3465 11237
+f 3454 3455 11188
+f 13471 2459 9211
+f 1700 4151 267
+f 4204 12231 11425
+f 13217 13308 13389
+f 13472 13473 11134
+f 13474 13475 12061
+f 13121 13476 13388
+f 9281 13477 9282
+f 12464 3910 3545
+f 13478 13479 13480
+f 4456 12288 13481
+f 11433 13482 13483
+f 13484 13485 13486
+f 4305 4456 13481
+f 13487 13488 13489
+f 4458 12359 12288
+f 12472 10927 11968
+f 12376 13490 10660
+f 11170 11489 13491
+f 12285 12284 13492
+f 12871 11353 11352
+f 8300 13493 8301
+f 13494 12871 11352
+f 13495 11504 11502
+f 8892 8301 13493
+f 11900 11899 10896
+f 13402 13495 11502
+f 6700 12481 13408
+f 6815 13496 13497
+f 13498 13406 13499
+f 12221 13500 3947
+f 13501 11432 11431
+f 13499 13406 13314
+f 13502 13410 11068
+f 13409 13501 11431
+f 13503 11217 11216
+f 13036 6808 6807
+f 13504 12093 12094
+f 13505 13503 11216
+f 13412 13505 11216
+f 13413 13412 11216
+f 13506 13507 10670
+f 13508 13509 13510
+f 13507 13510 10670
+f 5863 12549 13511
+f 12792 12875 12111
+f 13136 12109 12111
+f 10665 10664 13512
+f 10664 13494 10685
+f 11354 12795 13018
+f 11352 11354 13018
+f 11354 12791 12790
+f 12155 11871 13326
+f 13422 5884 9622
+f 2705 2899 1619
+f 13513 13514 13515
+f 13515 13516 13042
+f 13517 13518 13513
+f 13516 13041 13042
+f 13420 13519 13520
+f 13514 13516 13515
+f 13421 13420 13520
+f 11780 11781 13321
+f 13521 13522 13520
+f 13519 13521 13520
+f 13523 12407 12405
+f 13523 7054 12407
+f 12312 13297 11004
+f 13524 13523 12405
+f 10634 1217 9038
+f 12411 12312 11004
+f 13337 13425 13065
+f 12773 12772 12498
+f 13163 13426 12687
+f 13425 13161 13064
+f 7748 13525 13526
+f 13253 13321 12704
+f 12303 11696 13229
+f 12303 12302 11696
+f 5858 3861 3677
+f 13427 7015 7014
+f 12862 12765 13527
+f 13528 12862 13527
+f 12394 13529 13530
+f 12765 12577 13531
+f 12394 12294 13529
+f 12486 12394 13530
+f 13532 12294 11225
+f 12294 11515 11225
+f 5921 3382 5922
+f 6424 6423 6687
+f 7953 6424 6689
+f 13383 13249 13419
+f 13533 13534 2396
+f 13436 13535 13533
+f 7953 13536 13437
+f 7954 7953 13437
+f 13537 13438 13437
+f 13536 13537 13437
+f 13538 13439 13438
+f 13537 13538 13438
+f 13539 13440 13439
+f 13538 13539 13439
+f 13539 13540 13441
+f 13440 13539 13441
+f 13540 13541 13442
+f 13441 13540 13442
+f 13542 13443 13442
+f 13541 13542 13442
+f 13542 13543 13444
+f 13443 13542 13444
+f 13543 13544 13445
+f 13444 13543 13445
+f 13544 13545 13446
+f 13445 13544 13446
+f 13545 13546 13447
+f 13446 13545 13447
+f 13546 413 13448
+f 13447 13546 13448
+f 413 1775 13449
+f 13448 413 13449
+f 1775 412 13547
+f 13449 1775 1774
+f 1773 13548 13450
+f 1774 1773 13450
+f 13548 13549 13451
+f 13450 13548 13451
+f 13549 13550 13452
+f 13451 13549 13452
+f 12494 11891 11892
+f 5660 5211 13331
+f 13551 10603 10602
+f 13552 13551 10602
+f 13458 10801 13459
+f 13125 13553 10617
+f 11046 13554 3034
+f 11744 11399 13555
+f 13109 13556 13460
+f 13509 11359 13557
+f 9137 9136 9996
+f 11830 11969 13558
+f 3715 8821 6308
+f 13559 13560 13561
+f 10940 10967 13562
+f 12933 13563 13564
+f 6730 6832 6728
+f 5785 5787 5786
+f 8664 8783 12210
+f 12508 7369 13381
+f 12270 9059 8683
+f 1259 1258 1401
+f 1254 1253 1259
+f 4163 13565 13566
+f 11328 13295 7038
+f 9144 11633 11561
+f 11890 10622 11800
+f 13567 11657 13568
+f 12373 10850 11711
+f 10635 9038 7843
+f 11320 11658 13569
+f 13570 13472 11137
+f 13571 11320 13569
+f 13308 13121 13388
+f 13473 11254 11134
+f 11205 7233 8544
+f 13220 13572 13476
+f 2916 13573 208
+f 13574 13575 13576
+f 13577 11499 11504
+f 12178 4303 13481
+f 11582 11114 13578
+f 13495 13577 11504
+f 12756 12850 13579
+f 2061 2220 6826
+f 5377 13580 5520
+f 13581 13582 12152
+f 2461 13583 13584
+f 9856 10006 9935
+f 13582 8565 8566
+f 13585 13586 10917
+f 6355 6075 4005
+f 11165 11900 10896
+f 8558 10093 6844
+f 13587 13484 13486
+f 5743 4090 4899
+f 3893 8678 13588
+f 13589 13590 6611
+f 13591 10851 10915
+f 11582 13578 13493
+f 5725 3174 4278
+f 13592 11487 11486
+f 8300 11582 13493
+f 11125 11213 6341
+f 13593 13592 11486
+f 13594 6022 3948
+f 13481 12288 13595
+f 13498 13596 13597
+f 13598 13599 12484
+f 13501 13600 13601
+f 13596 13498 13499
+f 13602 13502 13603
+f 11432 13501 13601
+f 13604 10669 11217
+f 13411 6807 10002
+f 13508 13605 11359
+f 13503 13604 11217
+f 10693 10662 13606
+f 13507 13508 13510
+f 10662 13607 13608
+f 13607 13609 13608
+f 13609 13607 13610
+f 13607 13611 13610
+f 13612 10693 13613
+f 13611 10734 13614
+f 10693 13606 13613
+f 10662 13608 13606
+f 13615 13612 13616
+f 12086 13617 11183
+f 13618 13615 13619
+f 12087 12086 11872
+f 12678 10696 13620
+f 13612 13613 13616
+f 13509 13508 11359
+f 13605 13621 11360
+f 11359 13605 11360
+f 13621 13622 13623
+f 11360 13621 13623
+f 13622 13624 13625
+f 13626 13518 13517
+f 13623 13622 13625
+f 13627 13626 13517
+f 13518 13514 13513
+f 13522 13521 13628
+f 13521 13629 13628
+f 13629 13627 13630
+f 13628 13629 13630
+f 13631 8209 10633
+f 13524 12405 12401
+f 12310 12674 13297
+f 13632 13417 13254
+f 12971 12775 13633
+f 5890 6704 12463
+f 13066 13425 13064
+f 7455 6429 4714
+f 9828 12101 12550
+f 12410 12593 13634
+f 11215 13340 11697
+f 11215 11214 13340
+f 4387 3245 5817
+f 4137 13635 13636
+f 13527 12765 13531
+f 12486 13530 13531
+f 13637 13134 13043
+f 13638 13637 13043
+f 13460 12955 12863
+f 13461 13460 12863
+f 13639 12769 12671
+f 13640 13639 12671
+f 13641 13642 12488
+f 13640 12671 12578
+f 13641 12488 12396
+f 13643 13641 12396
+f 13373 13644 13645
+f 13642 12578 12488
+f 10498 13536 7953
+f 10498 7953 6689
+f 13646 13537 13536
+f 10498 13646 13536
+f 13647 13538 13537
+f 13646 13647 13537
+f 13647 13648 13539
+f 13538 13647 13539
+f 13648 13649 13540
+f 13539 13648 13540
+f 13650 13541 13540
+f 13649 13650 13540
+f 13650 13651 13542
+f 13541 13650 13542
+f 13651 13652 13543
+f 13542 13651 13543
+f 13652 13653 13544
+f 13543 13652 13544
+f 13653 13654 13545
+f 13544 13653 13545
+f 13654 13655 13546
+f 13545 13654 13546
+f 13655 414 413
+f 13546 13655 413
+f 5772 13656 13657
+f 13658 414 13655
+f 5774 13659 13660
+f 5773 5772 13657
+f 9376 13661 13548
+f 9323 8358 2746
+f 13662 2999 3702
+f 13548 13661 13549
+f 13663 13634 12051
+f 13664 13665 13666
+f 10385 10384 6622
+f 13667 12782 12659
+f 13551 13552 8471
+f 10603 10701 10604
+f 13668 13669 13483
+f 13670 13671 12947
+f 11182 11094 12060
+f 13147 11046 3034
+f 13672 13509 13557
+f 13620 13673 13554
+f 10929 11033 10930
+f 10929 11985 11033
+f 13674 13675 10661
+f 9596 9773 9597
+f 10894 10940 10924
+f 10991 11964 11882
+f 12263 13676 13243
+f 2226 7235 2227
+f 13677 2247 7332
+f 6927 785 2092
+f 13678 1558 1559
+f 6328 6461 8030
+f 5853 6005 5851
+f 6889 13679 7552
+f 11838 4088 10457
+f 11785 11838 10457
+f 13291 2427 12842
+f 11650 11654 10616
+f 10456 11785 10457
+f 8102 6174 12598
+f 11736 11735 13680
+f 11658 11657 13567
+f 10674 13131 13681
+f 2247 1632 1631
+f 13569 11658 13567
+f 13121 13220 13476
+f 13472 11134 11137
+f 12598 13310 11879
+f 7028 12889 12049
+f 13682 13683 13684
+f 12065 11408 11407
+f 13593 11486 11499
+f 13577 13593 11499
+f 13685 13686 13687
+f 4057 11076 4058
+f 13688 12565 13689
+f 6212 11707 6211
+f 11122 13690 13691
+f 12670 10875 13640
+f 13258 13692 13255
+f 12754 10602 11506
+f 13693 11620 11704
+f 10733 10732 11705
+f 10726 11624 10727
+f 11699 12184 11625
+f 13677 7332 4784
+f 13500 3948 3947
+f 13694 13695 11492
+f 13696 13697 13698
+f 13592 13694 11492
+f 11487 13592 11492
+f 11062 12285 13699
+f 13695 11578 11492
+f 9268 10944 12366
+f 10963 13700 13069
+f 11257 13597 13701
+f 6176 13222 13310
+f 13702 10695 13601
+f 11257 13498 13597
+f 10736 13602 13703
+f 13600 13702 13601
+f 13506 10670 10669
+f 13410 10002 11068
+f 13704 10803 13619
+f 13604 13506 10669
+f 13705 11104 13704
+f 13615 13616 13619
+f 13706 13707 13708
+f 10803 13618 13619
+f 13709 13706 13710
+f 13711 13709 13710
+f 13712 13713 13714
+f 13715 13712 13714
+f 13713 13709 13711
+f 13714 13713 13711
+f 13707 13716 13708
+f 13717 13458 13457
+f 13716 13717 13457
+f 13717 13718 13719
+f 13718 13720 13721
+f 13458 13717 13719
+f 13722 13723 13724
+f 13719 13718 13721
+f 13725 12361 13722
+f 11107 11109 13726
+f 13727 11056 13725
+f 13723 11107 13724
+f 11057 11056 13728
+f 12361 13723 13722
+f 13624 13729 13397
+f 11056 12361 13725
+f 13521 13730 13629
+f 13625 13624 13397
+f 13731 13626 13627
+f 13629 13731 13627
+f 13630 13627 13732
+f 13627 13517 13732
+f 13733 13524 12401
+f 13428 13733 12399
+f 6704 5884 13422
+f 13417 13320 13321
+f 5618 8209 5617
+f 12792 12111 13416
+f 13734 8198 4326
+f 13151 11002 13735
+f 13736 12410 13634
+f 12795 12790 13683
+f 4540 8033 4553
+f 11000 11002 13151
+f 13644 13373 6884
+f 13057 11962 13737
+f 12577 12486 13531
+f 12294 13532 13529
+f 13638 13043 12955
+f 13460 13638 12955
+f 13738 13739 10303
+f 1165 1164 1496
+f 13740 13741 13742
+f 13743 13744 13739
+f 13745 13746 13747
+f 13748 13740 13742
+f 13749 13750 12278
+f 13751 13745 13747
+f 13750 13752 11110
+f 13753 13749 12278
+f 10229 8546 8545
+f 3463 3459 11231
+f 13754 13646 10498
+f 13755 13754 10498
+f 13756 13647 13646
+f 13754 13756 13646
+f 13756 13757 13648
+f 13647 13756 13648
+f 13757 13758 13649
+f 13648 13757 13649
+f 13759 13650 13649
+f 13758 13759 13649
+f 13759 13760 13651
+f 13650 13759 13651
+f 13760 13761 13652
+f 13651 13760 13652
+f 13761 13762 13653
+f 13652 13761 13653
+f 13762 13763 13654
+f 13653 13762 13654
+f 13763 13764 13655
+f 13654 13763 13655
+f 13765 13766 13767
+f 9369 4469 9370
+f 7854 13768 7855
+f 7209 7540 7352
+f 10989 7755 13118
+f 3737 13765 13769
+f 5870 5871 11163
+f 2925 6702 964
+f 13482 13770 13483
+f 13139 13602 10736
+f 4780 13677 4784
+f 2989 2991 13771
+f 11874 11005 12660
+f 7745 8208 4461
+f 8283 8688 8284
+f 8471 12843 2427
+f 11655 12635 11577
+f 11508 12080 10620
+f 13772 13461 13639
+f 13623 13625 10784
+f 13234 13410 13502
+f 10620 10622 11890
+f 11985 13558 11033
+f 11798 10928 13773
+f 11584 11586 13774
+f 13775 12477 13688
+f 10889 10894 10878
+f 10967 11882 13562
+f 13776 13748 13777
+f 13778 12174 13779
+f 3459 3454 11230
+f 6028 5189 10619
+f 8278 13780 13261
+f 1944 12058 12059
+f 13781 13591 10915
+f 3506 8679 3893
+f 4594 4595 3864
+f 13782 11116 11115
+f 13783 11786 10456
+f 13784 11348 10824
+f 13785 11881 13786
+f 11877 11786 13783
+f 13723 13787 11107
+f 13786 11877 13783
+f 11657 11656 13568
+f 8812 3171 3377
+f 13570 11137 5871
+f 11656 11652 13788
+f 13744 13748 13776
+f 13742 13751 13789
+f 13790 13791 13792
+f 11125 6341 5221
+f 13793 11574 11578
+f 13695 13793 11578
+f 13793 13794 11574
+f 13794 11579 11574
+f 13794 9808 11579
+f 9808 9810 11579
+f 12379 8699 8700
+f 3231 6898 5210
+f 6905 4002 2997
+f 13795 11403 9809
+f 11403 13795 11471
+f 13795 9142 11471
+f 11471 9142 11553
+f 9142 9144 11553
+f 11553 9144 11561
+f 13796 13797 9143
+f 11652 11572 13798
+f 13132 11621 11623
+f 10668 11355 10753
+f 13788 11652 13798
+f 12267 13744 13776
+f 11355 10668 10708
+f 13206 13799 13800
+f 13748 13742 13777
+f 13801 10623 10695
+f 11258 11257 13701
+f 10734 10736 13614
+f 13702 13801 10695
+f 13802 11105 13705
+f 13502 11068 13603
+f 13726 11109 13802
+f 11104 10803 13704
+f 13803 13804 13805
+f 11105 11104 13705
+f 13716 13457 13708
+f 11207 13803 13805
+f 13806 2308 13807
+f 13710 13706 13708
+f 13808 13809 13810
+f 13384 13385 13811
+f 13812 8661 3363
+f 13217 13389 13385
+f 13813 13814 13815
+f 6100 13816 6101
+f 12711 1940 539
+f 3552 10232 7229
+f 6714 6038 13817
+f 13818 4965 13819
+f 965 3741 966
+f 10151 13820 5757
+f 13720 13803 11207
+f 6926 2100 6927
+f 13821 13822 13823
+f 13721 13720 11207
+f 13675 13824 13821
+f 13825 13826 13827
+f 13823 13825 13827
+f 13822 13825 13823
+f 10759 11057 13828
+f 13826 13829 13137
+f 13729 13830 13398
+f 11056 13727 13728
+f 11662 13519 13420
+f 13397 13729 13398
+f 13513 13831 13732
+f 11661 11662 13420
+f 13427 13428 7015
+f 13042 12951 13832
+f 12312 12310 13297
+f 13733 12401 12399
+f 13019 12795 13683
+f 13253 13417 13321
+f 10654 13833 13834
+f 12790 12792 13415
+f 13673 10654 13834
+f 10653 13835 13833
+f 10653 12260 13835
+f 13836 12669 12668
+f 13512 12581 13837
+f 12259 13329 13155
+f 11002 11323 13735
+f 13837 12581 10684
+f 13461 12863 12769
+f 13639 13461 12769
+f 13738 13743 13739
+f 13740 13748 13744
+f 13838 13839 13840
+f 13841 13838 13840
+f 13770 13842 13843
+f 13844 13770 13843
+f 13668 13483 13845
+f 13846 13668 13845
+f 13668 13846 13847
+f 13848 13668 13847
+f 9808 13849 9809
+f 13850 12934 13851
+f 6469 7138 13754
+f 13755 6469 13754
+f 7138 13852 13756
+f 13754 7138 13756
+f 13852 13853 13757
+f 13756 13852 13757
+f 13854 13758 13757
+f 13853 13854 13757
+f 13855 13759 13758
+f 13854 13855 13758
+f 13855 13856 13760
+f 13759 13855 13760
+f 13856 13857 13761
+f 13760 13856 13761
+f 13857 13858 13762
+f 13761 13857 13762
+f 13858 13859 13763
+f 13762 13858 13763
+f 938 13860 12945
+f 13763 13859 13764
+f 5765 5764 6188
+f 5764 7756 8467
+f 5764 8467 6188
+f 7756 2388 8467
+f 5588 4370 7337
+f 13861 10782 13862
+f 6430 7135 5086
+f 10237 10156 10315
+f 13669 11431 11433
+f 11585 12937 11586
+f 11402 11497 13863
+f 11319 13864 10644
+f 11872 12086 11183
+f 5224 5226 6818
+f 12608 12930 12078
+f 7014 7016 6697
+f 12590 11584 13865
+f 13866 13867 11400
+f 732 13868 734
+f 10923 13772 13639
+f 13035 10925 10927
+f 11969 13491 11823
+f 13558 11982 11034
+f 10928 10930 13773
+f 13869 11792 11551
+f 11505 11493 13870
+f 4701 9709 6711
+f 10940 13562 10924
+f 13777 13742 13789
+f 13751 13747 13021
+f 13871 13872 13849
+f 13699 12285 13873
+f 13874 13782 11115
+f 13492 13782 13874
+f 13873 13492 13874
+f 11786 11785 10456
+f 11876 11881 13785
+f 13875 11343 10770
+f 9263 9268 12366
+f 13568 11656 13788
+f 13876 11318 13571
+f 13789 13751 13021
+f 13753 11356 13021
+f 12279 12264 12280
+f 10598 12267 13877
+f 3829 3831 3117
+f 10791 10731 10793
+f 13878 3717 6815
+f 13879 13880 13881
+f 1116 1235 1117
+f 11565 11564 13882
+f 13883 11567 13884
+f 11568 4639 3180
+f 13885 11571 13883
+f 11567 3179 13884
+f 13886 11496 13885
+f 11571 11567 13883
+f 13887 11495 13886
+f 11496 11571 13885
+f 11572 11495 13887
+f 13798 11572 13887
+f 13747 13753 13021
+f 11495 11496 13886
+f 13753 12278 11058
+f 13888 13879 13881
+f 13232 13889 13890
+f 4681 12077 4682
+f 13891 11263 10623
+f 13799 13232 13890
+f 10736 13703 13614
+f 13801 13891 10623
+f 13724 11107 13726
+f 13602 13603 13703
+f 13892 13893 13674
+f 11109 11105 13802
+f 13805 13804 13490
+f 13490 13892 13674
+f 1790 4109 1940
+f 13804 13892 13490
+f 10850 10849 13775
+f 10973 10883 13894
+f 13895 11636 11395
+f 8544 7232 11510
+f 13896 11309 11254
+f 13473 13896 11254
+f 13897 11395 11309
+f 13896 13897 11309
+f 13895 13898 11636
+f 13899 11643 11638
+f 13898 13899 11638
+f 13900 11645 11643
+f 13899 13900 11643
+f 13901 11640 11645
+f 13900 13901 11645
+f 13902 11646 11640
+f 11790 7208 7207
+f 13009 13903 4326
+f 10763 11435 13904
+f 10764 10763 13904
+f 5527 13905 5657
+f 13906 13907 12083
+f 13908 13909 13910
+f 13869 13911 11709
+f 13827 13826 13137
+f 6488 6727 6485
+f 11334 11266 13912
+f 13829 13913 13138
+f 10003 13914 13398
+f 13915 11334 13912
+f 13637 11661 13420
+f 3565 3285 3287
+f 13916 13042 13832
+f 13134 13637 13420
+f 13917 13918 13632
+f 12951 12862 13528
+f 12307 12675 12674
+f 13919 13920 13417
+f 12225 11009 11011
+f 13165 13921 10609
+f 12264 13922 12265
+f 8287 13923 11073
+f 10798 12212 10799
+f 2164 3252 3254
+f 13681 13131 13133
+f 8100 3457 13924
+f 10685 13018 10686
+f 11623 13925 13133
+f 13642 13640 12578
+f 11340 10640 10642
+f 13743 13740 13744
+f 13741 13745 13751
+f 13842 13838 13841
+f 13843 13842 13841
+f 13926 11419 11316
+f 13927 13926 11316
+f 13928 12048 8009
+f 13927 13929 13926
+f 13930 13931 7432
+f 3519 3911 3520
+f 5625 13932 3466
+f 13933 10582 13934
+f 7123 7219 7220
+f 2646 13935 2647
+f 7139 13936 13852
+f 7138 7139 13852
+f 13937 13853 13852
+f 13936 13937 13852
+f 13938 13854 13853
+f 13937 13938 13853
+f 13939 13855 13854
+f 13938 13939 13854
+f 13939 13940 13856
+f 13855 13939 13856
+f 13940 13941 13857
+f 13856 13940 13857
+f 13941 13942 13858
+f 13857 13941 13858
+f 13942 13943 13859
+f 13858 13942 13859
+f 13944 12150 12149
+f 13943 13945 13946
+f 13947 13944 12149
+f 13948 13791 12150
+f 2064 13949 13950
+f 13944 13948 12150
+f 13951 13952 13953
+f 13477 9281 13954
+f 4411 11079 4410
+f 10238 10237 10313
+f 4257 4259 4411
+f 7934 9626 5201
+f 10689 10692 10606
+f 8694 13955 12708
+f 7749 7655 7943
+f 11181 12583 11182
+f 13956 11101 13957
+f 11416 10997 10999
+f 11178 13240 13239
+f 5585 13017 12110
+f 9714 7839 7012
+f 9907 9906 8504
+f 11509 10620 11890
+f 10706 11798 13773
+f 10926 10925 13958
+f 13491 11824 11823
+f 11493 11576 13959
+f 13960 13961 13962
+f 2423 2422 12841
+f 13963 6473 6331
+f 7545 10872 9060
+f 13964 13910 13965
+f 13241 8559 10872
+f 7545 13241 10872
+f 3865 3864 4059
+f 11116 11126 11117
+f 4074 4073 3874
+f 13868 5100 734
+f 9876 9881 13966
+f 10920 5862 5379
+f 6342 8812 13967
+f 11924 11706 3128
+f 12288 12359 13968
+f 4256 4057 4059
+f 4303 12178 12177
+f 12555 11131 12556
+f 11976 11965 13969
+f 5913 5915 5917
+f 3831 3904 3117
+f 11876 13970 13971
+f 11401 11318 13876
+f 10932 10521 13972
+f 13973 11401 13876
+f 11318 11320 13571
+f 8477 13974 4153
+f 6605 9271 6607
+f 8951 4086 4085
+f 1865 13975 13976
+f 13958 13848 13977
+f 13978 7475 1021
+f 11581 11404 13048
+f 13149 11053 11052
+f 13236 11659 11746
+f 11404 13979 13048
+f 13143 13106 13980
+f 7457 5496 13240
+f 13205 13981 13206
+f 5320 11166 11168
+f 13138 13233 13235
+f 10845 8293 12646
+f 13436 13533 2396
+f 12269 7031 13982
+f 13219 13983 13572
+f 10091 12268 13984
+f 11258 13701 13889
+f 13220 13219 13572
+f 13985 10975 11263
+f 13232 11258 13889
+f 13986 13024 13752
+f 13891 13985 11263
+f 13987 13986 13750
+f 13750 13986 13752
+f 13674 13893 13675
+f 13749 13987 13750
+f 12082 13906 12083
+f 13893 13824 13675
+f 13906 8286 13988
+f 13907 13906 13988
+f 13989 13990 11653
+f 10608 13991 13992
+f 13898 11638 11636
+f 13993 11734 11740
+f 11563 11401 13973
+f 13897 13895 11395
+f 11476 11563 13994
+f 13994 11563 13973
+f 11560 11476 13995
+f 13995 11476 13994
+f 11560 13996 13997
+f 13996 11560 13995
+f 11634 13997 13998
+f 11634 11560 13997
+f 11793 13998 13999
+f 11793 11634 13998
+f 13901 13902 11640
+f 11552 11793 13999
+f 14000 11648 11646
+f 13902 14000 11646
+f 14001 11651 11648
+f 14000 14001 11648
+f 14002 11470 11743
+f 14003 14002 11743
+f 14004 11397 11470
+f 14002 14004 11470
+f 4371 4370 7726
+f 14004 14005 11544
+f 13137 13829 13138
+f 14006 14007 13419
+f 13839 11334 13915
+f 14008 11322 13391
+f 13641 12668 13642
+f 13840 13839 13915
+f 12280 12301 12414
+f 2685 11191 11155
+f 13832 12951 13528
+f 12281 12280 12414
+f 13692 14009 13917
+f 12966 12969 14010
+f 13129 13248 14011
+f 13918 13919 13632
+f 14012 13236 11746
+f 10607 11270 10608
+f 14013 14014 14015
+f 14016 6437 10718
+f 14017 14018 14019
+f 13465 14020 9380
+f 12265 13836 12668
+f 5023 9932 5496
+f 13921 10607 10609
+f 11270 11269 10608
+f 13742 13741 13751
+f 13746 13749 13753
+f 13483 13770 13844
+f 13845 13483 13844
+f 11419 13926 7950
+f 13882 6815 13497
+f 13393 9707 9706
+f 5159 13393 9706
+f 14021 12485 7753
+f 11142 11144 14022
+f 12466 5622 5621
+f 8670 11880 11203
+f 11212 14023 6995
+f 12710 10652 10696
+f 14024 14025 14026
+f 14027 14028 14029
+f 14030 13937 13936
+f 14023 14030 13936
+f 14031 13938 13937
+f 14030 14031 13937
+f 14032 13939 13938
+f 14031 14032 13938
+f 14032 14033 13940
+f 13939 14032 13940
+f 14033 14034 13941
+f 13940 14033 13941
+f 14034 13945 13942
+f 13941 14034 13942
+f 14035 13946 1005
+f 13942 13945 13943
+f 14036 13574 14037
+f 13635 4136 14038
+f 5914 8101 8105
+f 14039 7948 14040
+f 4290 5903 5763
+f 11412 14041 14042
+f 12495 12881 10960
+f 7741 3859 7848
+f 10701 10605 10604
+f 9061 9039 9038
+f 4073 3084 4079
+f 387 3707 388
+f 14043 10920 5378
+f 14044 2018 10948
+f 837 5507 4285
+f 11016 2327 6749
+f 13112 11259 11262
+f 14045 2317 14046
+f 12358 14047 14048
+f 14049 10761 10767
+f 12316 11973 14050
+f 11974 11972 11975
+f 13558 11969 11982
+f 14045 5248 2317
+f 10925 13315 13958
+f 11978 13139 10736
+f 5167 8796 6298
+f 6060 12018 6059
+f 10576 9778 6299
+f 14051 9771 3218
+f 2705 1619 1621
+f 10147 10576 6299
+f 10678 10680 10913
+f 3079 11118 5310
+f 12666 14052 2821
+f 4300 4303 12177
+f 10830 13152 10831
+f 14053 14054 14055
+f 12919 13002 13097
+f 3032 5438 3033
+f 14056 3512 3514
+f 2576 2575 6473
+f 13970 11876 13785
+f 14030 14023 11212
+f 11965 11876 13971
+f 11881 11877 13786
+f 12279 14057 12264
+f 12054 11976 14058
+f 13922 13836 12265
+f 13132 11623 13133
+f 14059 14060 13925
+f 14061 14062 14063
+f 14064 13821 10735
+f 6579 14065 3478
+f 11976 13969 14058
+f 11547 11549 14066
+f 2424 13292 7358
+f 11547 14067 14068
+f 14067 11547 14066
+f 11618 14068 14069
+f 11618 11547 14068
+f 11747 11748 14070
+f 11660 11618 14069
+f 11660 14069 14071
+f 11748 11660 14071
+f 11651 14001 11653
+f 14001 13989 11653
+f 13956 10973 13894
+f 10883 10885 14072
+f 13207 13206 14073
+f 13799 13890 13800
+f 13304 13207 14074
+f 13206 13800 14073
+f 13304 14074 13983
+f 13219 13304 13983
+f 14075 14076 10976
+f 13207 14073 14074
+f 14075 10976 10975
+f 13985 14075 10975
+f 13752 13024 14077
+f 14076 14078 10976
+f 11805 8811 11806
+f 13024 13026 14077
+f 5475 14079 14080
+f 11103 11102 11809
+f 10309 3829 3115
+f 13824 13822 13821
+f 6018 11510 11718
+f 4699 9973 7731
+f 14081 11741 11734
+f 13993 14081 11734
+f 11693 11834 14082
+f 13990 13993 11740
+f 11694 11693 14083
+f 11747 14070 14084
+f 12751 7335 3923
+f 11834 14084 14082
+f 12842 11835 11837
+f 14085 10667 12363
+f 4563 3271 3478
+f 11337 11326 11417
+f 14086 13062 10665
+f 14087 6465 10985
+f 4419 11957 10626
+f 13111 11994 13626
+f 7114 3071 3280
+f 11957 10618 10626
+f 11549 11552 13999
+f 12152 8566 11626
+f 11887 11779 14088
+f 14066 11549 13999
+f 11979 11887 14089
+f 11694 14083 14090
+f 11979 14089 14091
+f 11779 14090 14088
+f 12076 11979 14091
+f 11887 14088 14089
+f 14092 11708 11544
+f 11397 14004 11544
+f 2619 2621 14093
+f 14094 14095 11981
+f 14096 14008 13391
+f 9707 9041 9040
+f 14060 14097 14098
+f 13927 11316 11322
+f 8688 9522 10833
+f 13925 14060 14098
+f 13690 12281 12414
+f 14099 10599 11264
+f 14100 12966 14010
+f 12418 13690 12414
+f 14101 14102 13692
+f 10665 13512 11962
+f 13700 13129 14011
+f 14009 13918 13917
+f 11269 11271 14103
+f 13318 14104 14011
+f 12258 12155 12259
+f 11871 11873 13326
+f 13158 11927 11929
+f 2798 2400 5911
+f 12155 13326 12259
+f 13779 13243 12505
+f 13747 13746 13753
+f 12278 13750 11110
+f 13848 13847 14105
+f 13977 13848 14105
+f 1139 13926 14106
+f 14107 14108 10697
+f 4444 3735 6618
+f 14109 14110 14111
+f 14112 14113 11828
+f 14114 11831 11829
+f 11832 14115 12079
+f 14113 14114 11829
+f 12186 14116 12289
+f 14117 14116 12186
+f 9374 8219 5735
+f 13158 11929 13465
+f 14118 3359 4548
+f 3316 7834 3106
+f 14119 14031 14030
+f 14023 13936 6995
+f 14119 14120 14032
+f 14031 14119 14032
+f 14120 14121 14033
+f 14032 14120 14033
+f 14121 14122 14034
+f 14033 14121 14034
+f 14122 14123 13945
+f 14034 14122 13945
+f 14124 10588 1006
+f 13945 14123 13946
+f 13767 14125 14126
+f 13766 7854 7856
+f 13224 3949 10783
+f 14127 13224 10783
+f 11903 3904 3906
+f 7562 4098 11480
+f 5096 5791 9370
+f 10629 7840 7839
+f 13777 14128 13877
+f 5855 5857 5859
+f 12643 14129 12700
+f 3084 13212 4079
+f 3344 3345 3529
+f 11168 11061 11063
+f 11037 11086 2536
+f 7036 4268 3175
+f 12635 14130 11577
+f 5888 5068 5889
+f 12363 10752 14131
+f 9785 14132 9856
+f 14133 3860 14134
+f 13257 14101 13258
+f 6346 6211 11707
+f 10707 10706 13773
+f 13772 13109 13461
+f 12471 13035 12472
+f 8128 14135 8129
+f 9261 7663 7662
+f 12366 12556 7663
+f 5477 9261 7662
+f 14047 10091 13984
+f 3312 4301 14136
+f 13827 11978 10735
+f 14137 13498 11257
+f 12872 13868 732
+f 6079 6080 5647
+f 4300 12177 14138
+f 14139 14140 11131
+f 12054 14058 14062
+f 12555 14139 11131
+f 14141 14142 14143
+f 4772 12872 1125
+f 1010 1012 14144
+f 13974 517 4154
+f 1123 4772 1125
+f 9621 9620 4603
+f 4153 13974 4154
+f 14145 4714 6430
+f 3712 3711 3895
+f 11965 13971 13969
+f 12556 11131 11133
+f 11485 11484 14146
+f 11200 12272 11201
+f 13865 14147 14148
+f 7638 12558 7239
+f 14149 11752 12072
+f 7238 7638 7239
+f 10944 12555 12366
+f 14150 14151 14152
+f 11167 11073 11061
+f 11337 11409 11327
+f 2318 2325 2319
+f 14153 12177 12179
+f 11256 14137 11257
+f 11576 14154 13959
+f 11834 11747 14084
+f 11748 14071 14070
+f 12937 13165 12938
+f 13990 11740 11653
+f 3677 4846 13145
+f 13894 10883 14072
+f 14155 3836 5438
+f 14076 14156 14157
+f 11352 13018 10685
+f 14078 14076 14157
+f 14086 10665 11962
+f 13712 13715 14157
+f 14158 12220 12937
+f 14156 13712 14157
+f 12110 13017 14159
+f 13610 13611 13614
+f 3380 2906 14160
+f 10971 14161 14077
+f 14162 11821 14163
+f 8811 11103 11806
+f 14164 11313 14162
+f 11737 11739 14165
+f 14166 14167 12290
+f 11821 11737 14163
+f 14081 14003 11741
+f 12289 14166 12290
+f 11779 11694 14090
+f 14003 11743 11741
+f 14168 2846 12549
+f 11693 14082 14083
+f 11576 11575 14154
+f 14169 14170 14171
+f 2821 14172 2822
+f 7923 8014 8016
+f 14173 12756 13579
+f 11840 11843 14174
+f 14175 3312 14176
+f 14177 5675 14045
+f 10946 14178 11468
+f 12850 12181 12180
+f 11926 10781 11123
+f 3312 14136 14176
+f 14179 13553 13125
+f 11356 11058 11357
+f 12403 4211 4213
+f 11052 11054 11126
+f 11040 8112 8920
+f 11626 8387 8037
+f 2335 12536 12538
+f 14180 12658 14181
+f 9534 9580 12563
+f 14182 12562 12658
+f 12287 14183 14184
+f 12286 14185 14183
+f 12355 14184 14186
+f 12355 12287 14184
+f 14112 11828 11984
+f 12389 12355 14186
+f 14187 11730 14188
+f 14095 14112 11984
+f 14008 13927 11322
+f 11727 11725 14189
+f 13925 14098 14099
+f 13242 13464 11548
+f 14190 14099 11264
+f 13133 13925 14099
+f 13690 12418 12506
+f 14098 12173 10599
+f 12775 12774 13633
+f 13691 13690 12506
+f 14191 14192 14101
+f 4601 11180 11308
+f 13248 13318 14011
+f 14102 14009 13692
+f 14193 14194 14195
+f 14196 14197 14198
+f 10995 14181 12658
+f 14158 12937 11585
+f 12716 14199 12605
+f 13778 13779 12712
+f 14077 11111 11110
+f 14200 14201 14202
+f 13026 10971 14077
+f 13681 14190 14161
+f 6480 14107 10697
+f 9040 9042 9328
+f 8776 8778 11252
+f 14203 14204 14205
+f 14114 14115 11832
+f 11831 14114 11832
+f 12389 14186 14206
+f 12476 12389 14206
+f 12564 14207 13967
+f 8812 12564 13967
+f 2910 2909 4291
+f 14208 14209 14210
+f 14211 14212 14213
+f 14214 13550 13549
+f 9853 9855 14119
+f 13936 7139 6995
+f 9855 14215 14120
+f 14119 9855 14120
+f 14215 14216 14121
+f 14120 14215 14121
+f 14216 14217 14122
+f 14121 14216 14122
+f 14217 14218 14123
+f 14122 14217 14123
+f 10587 1006 10588
+f 14123 14218 14124
+f 1932 14219 1933
+f 3544 3546 10834
+f 14220 9329 14221
+f 1933 14222 346
+f 14219 14222 1933
+f 13768 11043 7855
+f 10663 12871 10664
+f 7012 7840 4392
+f 13256 14191 13257
+f 11423 11422 11783
+f 4404 3039 3038
+f 10156 10237 10157
+f 13237 13242 11617
+f 13140 11872 13141
+f 8035 8296 8036
+f 8673 2288 8671
+f 11172 11171 11508
+f 11260 10723 10725
+f 14223 14224 14225
+f 10559 14226 13551
+f 10703 14133 14134
+f 10704 10703 14134
+f 14227 9322 2971
+f 11351 12364 11570
+f 13235 13234 13502
+f 13557 11359 11361
+f 6220 6355 4005
+f 11353 12780 11354
+f 14136 10657 10901
+f 14176 14136 10901
+f 4458 4460 12359
+f 4616 4625 14047
+f 13464 14228 11551
+f 8139 1684 8220
+f 4311 9054 3517
+f 14229 12656 12558
+f 7638 14229 12558
+f 5769 5926 5924
+f 10753 11355 10754
+f 14230 12657 12656
+f 11347 5321 12282
+f 14229 14230 12656
+f 2075 2074 2091
+f 3654 2465 2464
+f 1514 5238 5373
+f 1455 744 2407
+f 382 523 4488
+f 4154 517 4330
+f 1998 1685 8042
+f 1996 1998 7955
+f 7131 10379 7132
+f 4376 4211 12403
+f 11970 12798 11971
+f 11500 11488 14231
+f 8472 8565 8389
+f 838 8207 529
+f 14232 12753 12657
+f 14230 14232 12657
+f 14233 12845 12753
+f 14232 14233 12753
+f 13556 13638 13460
+f 14234 12846 12845
+f 11882 11964 11075
+f 4550 5227 3838
+f 14235 14236 14237
+f 10985 6465 6467
+f 14238 11589 11518
+f 2921 8680 3505
+f 13106 13027 13980
+f 12185 12076 14239
+f 8030 11178 13239
+f 13634 12593 12052
+f 12592 12408 12410
+f 4601 6696 11180
+f 12774 12592 12591
+f 11270 12774 12591
+f 12774 11270 10607
+f 13633 12774 10607
+f 14100 14010 13921
+f 13165 14100 13921
+f 13336 11044 13147
+f 14010 13633 13921
+f 13016 14240 14241
+f 13017 13016 14241
+f 12933 12796 13563
+f 12669 13023 12670
+f 14242 11584 13774
+f 14163 11737 14165
+f 13151 13735 13154
+f 12946 14243 13028
+f 14244 13557 12944
+f 14167 14245 12390
+f 13107 13772 10923
+f 10945 10899 10789
+f 14246 14247 14248
+f 13557 11361 12944
+f 13671 13555 12949
+f 2701 2703 10076
+f 11108 13710 14249
+f 10781 10829 11123
+f 14233 14234 12845
+f 14250 3441 2564
+f 14251 12936 12846
+f 14234 14251 12846
+f 14252 12942 12936
+f 14251 14252 12936
+f 14252 14253 13020
+f 12942 14252 13020
+f 14253 14254 13117
+f 13020 14253 13117
+f 14254 14255 13208
+f 13117 14254 13208
+f 11662 11175 13730
+f 12114 12113 13238
+f 10669 10671 11129
+f 14256 12931 14257
+f 13315 11431 13958
+f 11175 11210 13730
+f 14258 12661 12562
+f 14180 14182 12658
+f 2416 5523 4969
+f 11420 11419 13305
+f 13305 7950 11418
+f 13216 13119 13308
+f 11472 11554 14259
+f 13371 6900 13284
+f 14113 11829 11828
+f 14260 14261 11833
+f 11732 11730 14187
+f 12662 14262 12757
+f 14263 13313 13406
+f 14264 11732 14187
+f 10971 13681 14161
+f 13689 12663 14173
+f 14099 14098 10599
+f 13133 14099 14190
+f 12712 13779 12505
+f 14097 12262 12173
+f 2848 14265 2849
+f 13243 13691 12506
+f 11783 14266 14267
+f 7654 14268 7558
+f 11422 14269 14266
+f 11784 11783 14267
+f 6078 5919 9667
+f 6709 6710 3736
+f 14270 14271 12313
+f 14271 14272 12317
+f 14273 14200 14202
+f 11966 14105 11120
+f 11261 11260 13745
+f 13741 11261 13745
+f 10983 9040 9328
+f 11163 9850 5055
+f 11739 11732 14264
+f 14165 11739 14264
+f 14115 14117 12079
+f 12079 14117 12186
+f 12476 14206 14207
+f 12564 12476 14207
+f 2415 10718 2996
+f 13310 13222 13312
+f 9853 11212 11211
+f 7109 7731 14274
+f 2516 3547 3247
+f 14275 13402 9631
+f 2358 14276 2359
+f 12647 13341 12646
+f 14277 14278 8919
+f 14278 14279 8919
+f 14280 14277 8919
+f 14215 8136 14216
+f 8136 14281 14216
+f 14216 14281 14217
+f 8138 14282 14281
+f 14217 14282 14218
+f 2224 14283 2070
+f 14284 14282 14285
+f 14127 10783 10782
+f 7353 3717 13878
+f 9591 3118 8449
+f 3906 14219 1932
+f 4098 4290 5763
+f 11903 3906 12963
+f 12789 12699 12109
+f 12798 11782 11784
+f 12049 12597 12050
+f 10664 12581 13512
+f 14197 14286 14287
+f 3358 8012 7919
+f 13317 12207 13325
+f 13464 11550 11548
+f 10730 10630 10632
+f 11961 14086 11962
+f 13680 13670 13030
+f 10651 10650 11655
+f 14288 8471 2426
+f 14226 10700 10603
+f 3860 3859 14134
+f 13551 14226 10603
+f 10743 8036 10744
+f 14289 12362 14290
+f 14291 8468 280
+f 11350 12364 11351
+f 4844 4843 14292
+f 8567 8389 8565
+f 14138 10658 10657
+f 14136 14138 10657
+f 4616 14047 12358
+f 4460 4616 12358
+f 5155 7565 2425
+f 14040 7948 14172
+f 14293 14294 14295
+f 1278 13123 1279
+f 10959 9276 9275
+f 13208 14255 13210
+f 2713 7436 3113
+f 5759 5605 8103
+f 10780 14296 10781
+f 13231 11256 11258
+f 3307 3354 3549
+f 10050 4311 3326
+f 9370 4489 5096
+f 14297 14298 14299
+f 9346 14300 1409
+f 1566 5373 4934
+f 14301 14302 14303
+f 4330 382 4488
+f 9283 14304 12606
+f 4938 1996 7955
+f 13967 14305 6342
+f 455 8216 8218
+f 8113 11990 10900
+f 4291 8543 4292
+f 1380 611 613
+f 11073 12375 11061
+f 11413 11412 14042
+f 1947 11017 13880
+f 10988 14021 7753
+f 6645 7010 9905
+f 1312 13817 1314
+f 4233 4095 4094
+f 2243 14013 14015
+f 10944 10943 12555
+f 13958 13669 13848
+f 11508 10620 11509
+f 14258 14306 12456
+f 5959 45 44
+f 13248 12195 13318
+f 9805 12847 2532
+f 13737 13837 14307
+f 11586 12938 14308
+f 8919 7039 14051
+f 11841 13554 13834
+f 13779 12261 13243
+f 14199 10600 13778
+f 12174 12261 13779
+f 14309 10601 14199
+f 10600 12174 13778
+f 14272 14310 14309
+f 13964 13965 14311
+f 14271 11112 14272
+f 10686 13019 14312
+f 9115 14313 289
+f 13157 5890 11927
+f 14314 13416 14315
+f 12288 13968 13595
+f 13158 13157 11927
+f 10077 6323 7554
+f 13345 13156 13158
+f 14316 13577 13495
+f 12930 14317 14065
+f 14306 14318 10595
+f 14319 14316 13495
+f 11399 12056 13555
+f 6097 11919 6098
+f 14175 14176 14139
+f 11431 13669 13958
+f 8570 9350 2938
+f 13481 13595 12179
+f 11062 12283 12285
+f 7545 3560 13239
+f 12503 12608 12078
+f 12284 14320 13492
+f 8375 11438 8376
+f 14321 2929 12976
+f 11122 11121 13690
+f 10975 11265 11333
+f 11009 9385 9386
+f 13615 11206 13612
+f 12376 10693 13612
+f 14322 14323 14324
+f 14108 1934 14325
+f 13120 13220 13121
+f 14053 13794 13793
+f 14054 14053 13793
+f 14261 11745 11833
+f 13782 13148 11116
+f 14326 14327 12851
+f 12757 14326 12851
+f 11730 11727 14188
+f 11313 11821 14162
+f 9275 1538 5536
+f 13527 13531 13428
+f 13681 13133 14190
+f 13746 10725 13749
+f 14098 14097 12173
+f 14273 14202 12262
+f 12505 13243 12506
+f 12605 13778 12712
+f 6479 8289 11118
+f 1637 1636 8692
+f 11130 10740 11959
+f 12092 12090 14328
+f 5755 6614 2219
+f 1930 3553 1931
+f 11060 14270 12211
+f 14271 12315 12313
+f 13847 13846 14057
+f 13836 13844 12669
+f 7040 8838 8837
+f 3174 5878 6030
+f 8651 8810 8809
+f 11811 14329 11812
+f 14330 11710 14331
+f 11712 11391 14332
+f 14116 14166 12289
+f 12851 14327 12946
+f 11967 10927 13977
+f 14333 11472 14259
+f 12199 14334 13318
+f 12207 12208 13325
+f 12101 10016 12634
+f 12675 13011 13414
+f 11207 13805 11208
+f 11432 13601 13482
+f 9620 13423 5747
+f 7943 7558 14268
+f 12091 11790 11789
+f 12393 12091 11789
+f 14335 14336 7538
+f 10988 14337 14021
+f 14337 10988 7539
+f 14336 14337 7539
+f 13374 10750 7430
+f 1062 1065 14338
+f 215 2943 7355
+f 2716 13790 10459
+f 8784 6024 2060
+f 11691 7353 13878
+f 3906 3905 14219
+f 6174 6176 12598
+f 8542 8544 11510
+f 5190 8102 5191
+f 14339 12924 13005
+f 14340 10642 14341
+f 10629 10626 5188
+f 13735 11323 11325
+f 13552 10602 12754
+f 14342 14343 7336
+f 12842 2427 12843
+f 12844 13552 12754
+f 12674 12676 13298
+f 10631 12771 12490
+f 13671 12853 12947
+f 11171 12080 11508
+f 11421 11264 14310
+f 13839 11333 11334
+f 10700 12169 10701
+f 12169 12162 10701
+f 6707 14344 14289
+f 12362 10754 14290
+f 13555 12056 12949
+f 12055 12567 12759
+f 10708 10895 10897
+f 11899 4844 14292
+f 14138 12177 14153
+f 10658 14138 14153
+f 7830 4314 6052
+f 14345 11098 8308
+f 12496 11069 6334
+f 7735 7737 7664
+f 1338 3321 3320
+f 6584 6591 6592
+f 14346 14347 13582
+f 10852 14348 10304
+f 14349 14346 13581
+f 14350 14351 6199
+f 265 14352 374
+f 10625 13842 13770
+f 14353 14349 14354
+f 9188 10505 14355
+f 14347 8565 13582
+f 14356 14357 14358
+f 14359 3474 14360
+f 317 316 14361
+f 14361 14362 14363
+f 316 14364 14362
+f 14361 316 14362
+f 14364 14365 14304
+f 14362 14364 14304
+f 9283 9160 8953
+f 14365 12606 14304
+f 14181 10995 11013
+f 14366 14367 14368
+f 10849 12477 13775
+f 11966 11122 13676
+f 10705 12465 12055
+f 11400 13867 11319
+f 12064 14369 12276
+f 13578 14370 14371
+f 14346 13582 13581
+f 12276 14372 14373
+f 14372 14374 14373
+f 14374 14353 14373
+f 13578 14371 14375
+f 13493 13578 14375
+f 14376 1657 14377
+f 12661 14258 12456
+f 11213 5629 6341
+f 12071 12066 10690
+f 12114 14378 14240
+f 13016 12114 14240
+f 13837 10684 14379
+f 10684 10686 14380
+f 13554 11841 9375
+f 13554 13673 13834
+f 13823 13827 10735
+f 3034 13554 9375
+f 13736 13634 13663
+f 13137 13139 11978
+f 12111 12110 14159
+f 14381 13736 13663
+f 10628 10633 5618
+f 13416 12111 14159
+f 3082 3084 4074
+f 12066 11407 10690
+f 10606 10692 11329
+f 13744 12267 10597
+f 14316 14382 13577
+f 3460 6356 14383
+f 13493 14375 8892
+f 14382 13593 13577
+f 3523 6825 12552
+f 9662 14384 9663
+f 14353 14354 14373
+f 11566 11565 12709
+f 10659 14369 12070
+f 14349 13581 14354
+f 10902 10659 12163
+f 14369 14372 12276
+f 11709 13911 11474
+f 14369 12064 12070
+f 12477 12565 13688
+f 11488 11505 14385
+f 11076 11079 4411
+f 13911 14386 11474
+f 11964 11963 11077
+f 6215 6214 6313
+f 7248 7140 7142
+f 11963 11410 12081
+f 14387 9268 9267
+f 12358 14048 14388
+f 14389 11635 14390
+f 12153 11626 11627
+f 11620 10733 11704
+f 10804 14391 8678
+f 14392 14393 14394
+f 14395 9808 13794
+f 10668 10895 10708
+f 3443 3442 7639
+f 14327 14243 12946
+f 10758 11057 10759
+f 14331 11712 14332
+f 14396 14397 13105
+f 11803 8651 8809
+f 11391 11313 14164
+f 11260 10725 13746
+f 11806 11103 11809
+f 14097 14273 12262
+f 13745 11260 13746
+f 11168 11063 9451
+f 14105 11966 14201
+f 10628 10627 6218
+f 2599 2589 6617
+f 9856 14132 10006
+f 5883 5882 5070
+f 5779 6905 5780
+f 427 592 428
+f 6161 7854 13766
+f 6045 6051 6046
+f 13843 13841 13023
+f 12669 13843 13023
+f 13872 14398 14399
+f 11990 12081 12083
+f 14400 14401 11814
+f 4746 14402 7829
+f 12208 12205 10800
+f 14334 12199 13247
+f 14243 14396 13028
+f 14403 14404 13014
+f 11055 12360 11056
+f 11278 11117 5221
+f 14405 14406 1911
+f 14395 13871 9808
+f 14407 11980 12184
+f 11699 14407 12184
+f 14408 14409 14410
+f 4011 942 4012
+f 14411 14412 14413
+f 7558 7943 7655
+f 6300 9777 9779
+f 14414 7564 14415
+f 3575 3820 8281
+f 3722 3575 8281
+f 8274 8275 12485
+f 14337 8274 14021
+f 7827 14416 7828
+f 14021 8274 12485
+f 14126 10307 7827
+f 6480 10697 6481
+f 14417 14418 14419
+f 13861 14127 10782
+f 11691 13878 11564
+f 12575 3718 3717
+f 14420 14127 13861
+f 9591 8449 8448
+f 10606 11329 11506
+f 10626 10619 5188
+f 8846 14421 8847
+f 10604 10606 11506
+f 11182 12060 13141
+f 8471 13552 12844
+f 11575 11580 14422
+f 13579 12850 12180
+f 11615 14423 11616
+f 3034 9375 8833
+f 575 10921 573
+f 14424 14425 14426
+f 11264 10601 14310
+f 11333 11265 11334
+f 12164 10689 10605
+f 12162 12164 10605
+f 14344 6707 5629
+f 11213 14344 5629
+f 13711 13710 11108
+f 13787 13711 11108
+f 10896 11899 14292
+f 10897 10896 14292
+f 14427 14428 9351
+f 7355 2943 7356
+f 14429 3522 3524
+f 1205 12496 6334
+f 14430 14118 11069
+f 14431 5758 5760
+f 2930 14432 2931
+f 14433 11017 11018
+f 8505 3015 5380
+f 5164 14434 14435
+f 6030 7035 3175
+f 13834 14436 14387
+f 11841 13834 14387
+f 4301 4300 14138
+f 14437 836 14438
+f 934 13487 13489
+f 11900 14439 4844
+f 14176 10901 14140
+f 1048 1047 14440
+f 1048 14440 14441
+f 6168 12319 14442
+f 5862 14168 5863
+f 315 14443 14364
+f 14361 14444 317
+f 14443 13246 14365
+f 14364 14443 14365
+f 10016 9388 7247
+f 13395 12848 14445
+f 4720 5215 14446
+f 9452 5320 9451
+f 13833 10942 14436
+f 13834 13833 14436
+f 14182 14258 12562
+f 10691 11337 11417
+f 5855 6691 10716
+f 14447 14448 14449
+f 14139 14176 14140
+f 14450 13637 13638
+f 931 930 12945
+f 14451 14452 14453
+f 14370 14454 14371
+f 13835 10972 10942
+f 14275 14319 13402
+f 14319 13495 13402
+f 11627 8037 8036
+f 12871 13494 10664
+f 13017 14241 14159
+f 10661 13607 10662
+f 6605 6464 6463
+f 14379 10684 14380
+f 7839 9714 5452
+f 13692 13917 13255
+f 14455 11960 13057
+f 13255 13917 13254
+f 13887 13886 14456
+f 11962 13512 13737
+f 14457 12842 11837
+f 14458 13887 14456
+f 10692 10691 11330
+f 13787 11108 11107
+f 3491 4079 3294
+f 14459 6366 6365
+f 14460 10456 5491
+f 6934 7042 7043
+f 13783 10456 14460
+f 13298 12676 12694
+f 11923 11170 13491
+f 14461 13783 14460
+f 1569 3434 5060
+f 10754 10702 10709
+f 14462 14230 14229
+f 14229 7638 14463
+f 14464 14232 14230
+f 14462 14464 14230
+f 13965 13910 13909
+f 14465 14233 14232
+f 10628 5618 9531
+f 14360 3473 14444
+f 8885 5206 9626
+f 13618 14466 13615
+f 13640 10875 13639
+f 11490 11172 11507
+f 13833 13835 10942
+f 14467 11269 14103
+f 14464 14465 14232
+f 13155 3310 10972
+f 2559 14234 14233
+f 14465 2559 14233
+f 2561 14251 14234
+f 2559 2561 14234
+f 14468 14252 14251
+f 6530 6532 2144
+f 13969 13971 14469
+f 13785 14470 14471
+f 13970 14471 14472
+f 13971 13970 14472
+f 4310 3946 5056
+f 12369 5926 5925
+f 12178 13481 12179
+f 11564 13878 13882
+f 13028 14396 13105
+f 14397 14403 13013
+f 14332 11391 14164
+f 14473 12479 14474
+f 11102 14329 11811
+f 11809 11102 11811
+f 10725 13987 13749
+f 12668 12670 13642
+f 14200 14105 14201
+f 14105 13847 11120
+f 13802 13705 11991
+f 13726 13802 13122
+f 13705 13704 11992
+f 11995 13802 11991
+f 13704 13619 11996
+f 11991 13705 11992
+f 13616 11999 11996
+f 11992 13704 11996
+f 13841 13840 10873
+f 13023 13841 10873
+f 11011 11010 10667
+f 11010 11064 10667
+f 14475 14476 7637
+f 13835 13155 10972
+f 14477 12021 14478
+f 12120 11889 14479
+f 13013 14403 13014
+f 827 14480 11204
+f 4734 7339 14384
+f 14481 13884 14482
+f 13794 14053 14395
+f 11478 11426 11327
+f 14058 13969 14483
+f 13971 14472 14469
+f 14468 14484 14253
+f 14252 14468 14253
+f 14484 14485 14254
+f 4695 4694 4550
+f 8397 8396 14486
+f 9934 6916 6915
+f 12354 14487 4698
+f 12889 9934 6915
+f 5215 6049 7109
+f 7727 7728 10308
+f 7827 10307 14416
+f 8450 12963 13386
+f 14488 7754 11394
+f 7230 11691 11564
+f 12575 13118 14489
+f 14419 14420 13861
+f 14490 9591 8448
+f 14491 14325 345
+f 7230 11564 1931
+f 14492 14197 14287
+f 10692 11330 11329
+f 14312 13019 13682
+f 12109 5585 12110
+f 12101 12100 10016
+f 13228 14179 13125
+f 8401 3457 3456
+f 10828 12363 14131
+f 2277 4860 13116
+f 14493 14494 10777
+f 10624 13838 13842
+f 13482 10625 13770
+f 1620 11250 3102
+f 12174 12173 12261
+f 12071 10690 10689
+f 11040 8920 3083
+f 14344 12362 14289
+f 12164 12071 10689
+f 14495 7660 14496
+f 14496 7660 7234
+f 14496 14497 14495
+f 14498 14499 14495
+f 14497 14428 14427
+f 14495 14497 14427
+f 1834 6606 1668
+f 1834 9351 14428
+f 14500 3963 14501
+f 7931 8391 6703
+f 11307 11796 8802
+f 14502 6184 3740
+f 14058 14483 14063
+f 14063 14503 14504
+f 14253 14484 14254
+f 14485 14505 14255
+f 11702 8365 4899
+f 12583 11092 11094
+f 14224 14506 14225
+f 14507 14508 14509
+f 14254 14485 14255
+f 3858 7847 3859
+f 10590 14155 8832
+f 14510 11885 14511
+f 11787 6005 5853
+f 315 14364 316
+f 12319 12321 14442
+f 10755 14512 14443
+f 315 10755 14443
+f 14512 14513 13246
+f 14443 14512 13246
+f 13172 14445 12848
+f 13560 12101 12634
+f 7041 7040 8836
+f 4027 4392 5189
+f 13329 3311 3310
+f 8391 14502 3740
+f 9977 14514 10210
+f 13886 13885 14515
+f 14516 13376 13379
+f 2287 2289 4693
+f 14517 14518 13929
+f 14519 10814 14520
+f 6829 2909 3113
+f 14521 490 489
+f 2950 2819 2948
+f 2560 14522 14523
+f 14524 9278 9277
+f 14524 14525 9278
+f 12072 11840 14174
+f 14526 6185 6184
+f 3899 2818 2400
+f 13571 13569 14527
+f 14528 13571 14527
+f 14529 13876 14528
+f 12410 13736 11271
+f 14530 13973 14529
+f 11270 12591 11271
+f 8288 11073 11167
+f 13876 13571 14528
+f 4563 3478 14065
+f 12375 12283 11062
+f 13155 13329 3310
+f 14168 12549 5863
+f 13328 4299 3311
+f 11665 11752 14149
+f 7825 8107 3549
+f 11059 11110 11112
+f 8107 3307 3549
+f 10520 5596 6443
+f 7335 1797 1796
+f 14531 9720 1788
+f 13817 5906 1314
+f 13329 13328 3311
+f 11208 13805 12376
+f 13327 4302 4299
+f 2556 3531 2558
+f 14532 13786 14461
+f 4846 3677 4564
+f 2063 13949 2064
+f 12456 14306 10595
+f 10595 14318 10594
+f 11995 11994 13111
+f 6451 10594 6452
+f 14318 13104 10594
+f 13122 11995 13111
+f 4411 4259 4058
+f 13328 13327 4299
+f 8372 8371 3833
+f 13204 13113 14533
+f 13786 13783 14461
+f 14103 11271 14381
+f 3229 7018 14534
+f 13970 13785 14471
+f 8100 14535 14536
+f 14132 9785 14537
+f 13341 12647 8108
+f 5001 5005 5004
+f 8308 6893 8309
+f 14048 13984 14347
+f 11166 5320 5321
+f 6461 11178 8030
+f 11478 13307 11426
+f 14263 14179 13313
+f 13997 13996 14538
+f 13731 13111 13626
+f 13105 14397 13013
+f 13996 13995 14539
+f 12570 12479 14540
+f 13327 13146 4304
+f 14329 14400 11812
+f 12479 12391 14474
+f 11987 11986 13604
+f 14541 12014 12020
+f 12509 11987 13503
+f 11986 13506 13604
+f 13505 12421 13503
+f 11987 13604 13503
+f 13412 12423 13505
+f 12421 12509 13503
+f 13504 12323 13413
+f 12423 12421 13505
+f 4302 13327 4304
+f 12322 12423 13412
+f 14542 14543 14544
+f 14283 4120 2070
+f 14545 14546 14547
+f 11620 3129 11706
+f 14548 10920 14043
+f 14549 14550 14551
+f 11922 12021 14477
+f 14552 11922 14477
+f 14553 14554 14555
+f 8273 7562 11480
+f 14515 13885 14556
+f 13883 13884 14481
+f 7824 9270 8107
+f 10521 7447 13972
+f 13562 11882 11074
+f 12152 11626 12153
+f 14388 14346 14349
+f 13968 14388 14349
+f 4575 5087 5019
+f 13169 12768 13167
+f 7111 8669 3319
+f 7203 7730 6580
+f 6133 6134 14557
+f 6134 7535 14557
+f 6036 6133 14557
+f 7535 14558 14557
+f 7535 7314 14559
+f 14558 7535 14559
+f 7196 14560 14559
+f 7314 7196 14559
+f 7198 14335 14560
+f 7196 7198 14560
+f 7198 7201 14336
+f 14335 7198 14336
+f 10236 3940 14561
+f 7197 8012 7199
+f 13721 11207 11206
+f 3506 3505 8680
+f 10600 10599 12174
+f 13719 13721 10802
+f 10625 10624 13842
+f 10624 11333 13839
+f 13680 13030 10643
+f 14466 13721 11206
+f 12187 10848 12373
+f 10622 12187 12373
+f 14049 13875 10761
+f 10646 10649 10651
+f 5617 5614 5612
+f 10645 10649 10646
+f 14496 7234 7233
+f 7233 7232 8544
+f 14562 14496 7233
+f 11205 14562 7233
+f 14562 14563 14497
+f 14496 14562 14497
+f 14563 14564 14428
+f 14497 14563 14428
+f 6606 1834 14428
+f 14564 6606 14428
+f 14531 2872 9720
+f 14565 10019 14566
+f 6227 6233 9373
+f 11339 10640 11340
+f 13969 14469 14483
+f 11872 13140 11873
+f 14048 14347 14346
+f 10609 13992 14308
+f 14388 14048 14346
+f 11169 3895 11688
+f 5152 5301 12513
+f 1797 7434 3162
+f 14567 14568 13590
+f 2718 4128 4306
+f 14118 3357 3359
+f 3192 5232 3591
+f 3247 3246 2516
+f 13396 14548 14043
+f 7644 14569 10755
+f 10756 7644 10755
+f 14569 14570 14512
+f 10755 14569 14512
+f 14570 14571 14513
+f 14512 14570 14513
+f 14571 9579 13954
+f 14513 14571 13954
+f 14572 14573 9352
+f 14574 3429 1858
+f 3506 3893 3892
+f 10006 13430 10007
+f 13569 13567 14575
+f 14527 13569 14575
+f 14576 9178 9177
+f 10843 10655 8920
+f 10696 10654 13673
+f 14577 10756 315
+f 6818 6819 6717
+f 12884 14317 12930
+f 8116 7115 7845
+f 14578 14579 11705
+f 5808 2337 2339
+f 14439 14065 6579
+f 11744 13555 13671
+f 11505 13870 14385
+f 5087 7135 5019
+f 14580 14182 14180
+f 10143 14580 14180
+f 14581 14258 14182
+f 14580 14581 14182
+f 10316 10460 10313
+f 14582 14306 14258
+f 12853 13671 12949
+f 4339 10581 14583
+f 10828 14131 11124
+f 13416 14159 14315
+f 14584 14585 14586
+f 11735 11742 13670
+f 11503 14587 14588
+f 6322 6479 7554
+f 10941 10876 7113
+f 11497 11498 14589
+f 14590 12311 10741
+f 11500 14231 14591
+f 14590 14592 12311
+f 11491 13866 11400
+f 14593 14594 13592
+f 11126 11054 11127
+f 14593 13592 13593
+f 14382 14593 13593
+f 13391 11749 13392
+f 14594 13694 13592
+f 12076 14091 14239
+f 13986 14595 13024
+f 12286 12183 14185
+f 12185 14239 14596
+f 12287 12286 14183
+f 12183 12185 14596
+f 14597 13390 14598
+f 12183 14596 14185
+f 14054 13793 13695
+f 12147 2578 2600
+f 14599 13695 13694
+f 14599 14054 13695
+f 13785 13786 14532
+f 14594 14599 13694
+f 11054 11926 11127
+f 14470 13785 14532
+f 11501 11500 14591
+f 10745 10744 14600
+f 14466 11206 13615
+f 9000 8870 741
+f 11360 13623 10880
+f 13139 13235 13602
+f 11347 11166 5321
+f 10682 10681 10738
+f 14601 2011 13164
+f 13230 13232 13799
+f 13997 14538 14602
+f 7345 7461 7460
+f 14603 14604 14605
+f 13998 13997 14602
+f 12570 14540 14606
+f 13142 4455 4304
+f 14607 14541 12020
+f 12569 12570 14606
+f 14608 14609 13501
+f 14541 14610 12115
+f 14609 14611 13600
+f 13409 14608 13501
+f 14612 13702 13600
+f 13501 14609 13600
+f 14613 13801 13702
+f 14611 14612 13600
+f 14614 13891 13801
+f 14612 14613 13702
+f 14606 13985 13891
+f 14613 14614 13801
+f 14540 14075 13985
+f 14614 14606 13891
+f 13146 13142 4304
+f 14606 14540 13985
+f 12021 12120 14478
+f 14550 6998 12425
+f 2558 3533 2420
+f 11827 11922 14552
+f 14556 13883 14481
+f 13408 13407 14615
+f 4681 12503 12078
+f 14456 13886 14515
+f 13067 13063 12498
+f 10618 14290 10613
+f 13642 12670 13640
+f 11427 10745 14616
+f 13235 13502 13602
+f 11421 14310 11112
+f 14617 5862 10920
+f 7651 6309 3131
+f 10300 10355 14618
+f 10355 8660 14619
+f 5626 10300 7027
+f 8660 8659 14619
+f 5056 5626 7026
+f 10355 14619 14618
+f 5056 7026 14620
+f 10300 14618 7027
+f 5057 5056 14620
+f 5626 7027 7026
+f 7201 3550 14336
+f 3550 14337 14336
+f 14621 14622 14623
+f 3750 3123 8370
+f 13458 13719 10801
+f 14624 702 12511
+f 8042 1685 8139
+f 10616 13680 10643
+f 14625 6378 12474
+f 7459 7654 7558
+f 13586 10857 10917
+f 9047 7846 7546
+f 14626 12172 14627
+f 14226 10559 7735
+f 14626 11133 12171
+f 12172 14626 12171
+f 7933 11402 13932
+f 11402 13863 13932
+f 14480 11205 11204
+f 8543 11204 8544
+f 14628 14562 11205
+f 14480 14628 11205
+f 14628 14629 14563
+f 14562 14628 14563
+f 14630 14564 14563
+f 14629 14630 14563
+f 6604 6606 14564
+f 14630 6604 14564
+f 1217 9341 9038
+f 4958 8380 14631
+f 13568 13788 14632
+f 11324 11339 11338
+f 10652 12935 10653
+f 13484 14633 14634
+f 698 697 2290
+f 10737 11427 10738
+f 11963 11989 11077
+f 14635 14636 6520
+f 4096 2907 4097
+f 3549 3550 7201
+f 7437 5350 7438
+f 14548 14617 10920
+f 14637 14638 14639
+f 2927 4163 14640
+f 3512 3711 3513
+f 7645 10756 14641
+f 4912 1484 13734
+f 5309 5310 5025
+f 14642 693 14643
+f 8195 14644 14570
+f 14569 8195 14570
+f 14644 14645 14571
+f 14570 14644 14571
+f 14645 14646 9579
+f 14571 14645 9579
+f 1858 1857 14574
+f 14646 9580 9579
+f 14647 14168 5862
+f 7332 14648 14649
+f 14066 13999 14650
+f 14651 14066 14650
+f 14386 14652 11475
+f 10143 14180 10144
+f 13297 13298 13667
+f 2725 336 8038
+f 13021 11356 11358
+f 13245 4457 4455
+f 6313 6312 6215
+f 13142 13245 4455
+f 6218 4911 4010
+f 10627 9531 6301
+f 14653 11013 11494
+f 3667 5205 4444
+f 7840 5188 4392
+f 14617 14647 5862
+f 13380 12508 13381
+f 14654 11174 14450
+f 11063 11062 13699
+f 10708 10897 14133
+f 13244 4459 4457
+f 10829 10828 11124
+f 13245 13244 4457
+f 13319 4615 4459
+f 13244 13319 4459
+f 9155 4624 4615
+f 3999 11336 3808
+f 13319 9155 4615
+f 12359 12358 14388
+f 10077 7554 11118
+f 9634 10502 4760
+f 11503 11501 14587
+f 10943 14175 14139
+f 11427 14616 10738
+f 10667 11064 10668
+f 4301 14138 14136
+f 6815 3719 13496
+f 14627 7664 14626
+f 14595 13025 13024
+f 12267 13776 13877
+f 14655 14656 11888
+f 13108 14657 13109
+f 14005 14092 11544
+f 14655 11797 11708
+f 14092 14655 11708
+f 14315 14159 14658
+f 11797 14655 11888
+f 12581 10685 10684
+f 14094 11981 11888
+f 14656 14094 11888
+f 13303 13207 13304
+f 14095 11984 11981
+f 4303 4305 13481
+f 13218 13302 13219
+f 7208 7538 7209
+f 14659 13996 14539
+f 7055 11515 6215
+f 13917 13632 13254
+f 7341 4924 2356
+f 13777 13789 13022
+f 11989 11963 12081
+f 11923 13491 11969
+f 7732 6430 5086
+f 14290 10754 10709
+f 14375 14371 14660
+f 5897 2958 5875
+f 14454 14661 14662
+f 14371 14454 14662
+f 338 1222 9192
+f 11001 11006 11002
+f 13996 14659 14538
+f 13998 14602 14650
+f 9155 9058 4624
+f 14201 11966 13676
+f 12479 14473 14540
+f 12569 14606 14614
+f 12014 14541 12115
+f 14610 14663 12191
+f 13800 14664 14663
+f 14073 13800 14663
+f 14074 14610 14541
+f 13983 14074 14541
+f 13476 14665 14666
+f 13388 13476 14666
+f 13388 14666 14667
+f 13389 13388 14667
+f 13389 14667 14668
+f 13385 13389 14668
+f 14498 14495 14427
+f 13385 14668 14549
+f 14473 14076 14075
+f 13811 13385 14549
+f 6601 458 457
+f 14540 14473 14075
+f 14669 11827 14552
+f 6997 12425 6998
+f 14670 13948 13944
+f 11825 11921 14671
+f 13885 13883 14556
+f 3516 1758 3552
+f 8020 8283 8021
+f 14067 14672 14673
+f 10744 10747 14600
+f 5648 14674 14675
+f 14373 14676 12277
+f 14371 14662 14660
+f 12162 10605 10701
+f 7932 1405 10074
+f 3345 3153 3945
+f 2926 13565 4163
+f 6925 6924 8662
+f 11481 7240 7239
+f 6924 14429 8663
+f 8662 6924 8663
+f 14429 3524 8782
+f 8663 14429 8782
+f 5057 14620 5915
+f 4740 5057 5915
+f 9992 4697 6049
+f 3550 3353 8274
+f 13581 12152 12151
+f 13582 8566 12152
+f 6473 1206 6331
+f 14354 13581 12151
+f 8288 10904 10903
+f 4021 12407 7054
+f 13988 10903 14677
+f 13988 8288 10903
+f 8113 10900 8114
+f 13907 13988 14677
+f 13907 14677 10900
+f 12083 13907 10900
+f 11133 11132 12171
+f 11132 12160 12171
+f 12972 14011 13170
+f 13595 13968 14353
+f 826 14480 827
+f 8543 827 11204
+f 14678 14628 14480
+f 826 14678 14480
+f 14679 14629 14628
+f 14678 14679 14628
+f 14679 14680 14630
+f 14629 14679 14630
+f 14681 6604 14630
+f 14680 14681 14630
+f 10636 6429 7455
+f 14681 9271 6604
+f 11325 11324 11338
+f 14682 14223 14225
+f 2313 10687 9099
+f 13567 13568 14683
+f 10745 14600 14616
+f 2514 2313 9099
+f 13968 14349 14353
+f 14375 14660 14684
+f 14685 14551 14550
+f 4120 4119 14686
+f 5629 6707 5630
+f 1424 10520 6443
+f 11069 4548 4547
+f 11069 14118 4548
+f 5489 5491 10457
+f 4090 10457 4088
+f 5406 14687 14688
+f 14689 14690 14691
+f 14692 2846 14168
+f 5819 5815 6375
+f 14693 14694 5812
+f 8194 14695 14644
+f 14696 6925 8662
+f 14695 14697 14645
+f 14644 14695 14645
+f 14697 14698 14646
+f 14645 14697 14646
+f 12563 9580 14646
+f 14698 12563 14646
+f 4205 3999 4203
+f 5791 5790 9370
+f 14069 14068 14699
+f 3072 3071 9779
+f 14700 10144 14181
+f 14620 13928 5916
+f 8892 14684 8890
+f 8891 14701 9208
+f 10655 12282 11332
+f 14702 14465 14464
+f 6897 5237 6898
+f 14522 2559 14465
+f 14703 14704 9081
+f 14522 2560 2559
+f 14465 14702 14522
+f 14601 2009 2011
+f 14494 14049 10767
+f 2861 14705 2862
+f 13875 10770 10761
+f 6348 6350 14485
+f 14484 6348 14485
+f 6350 12116 14505
+f 14485 6350 14505
+f 2672 842 3510
+f 5659 5658 14706
+f 2909 6829 7107
+f 13427 13527 13428
+f 12709 11565 13497
+f 14707 5588 7337
+f 12264 12266 12280
+f 12767 12768 13169
+f 10502 14708 10431
+f 14709 13422 10715
+f 3533 4138 8021
+f 9099 10687 222
+f 12557 3320 3322
+f 13226 14490 14710
+f 2549 2710 2548
+f 14711 14712 12566
+f 6726 10890 10206
+f 12290 14167 12390
+f 14245 14711 12478
+f 11719 11721 14713
+f 12390 14245 12478
+f 1085 2720 4123
+f 6646 6645 9905
+f 12583 11094 11182
+f 8038 338 9192
+f 14686 14531 1937
+f 13617 11181 11183
+f 14189 11725 14713
+f 11721 14714 14713
+f 12566 14712 12662
+f 14188 11727 14189
+f 12478 14711 12566
+f 14262 14326 12757
+f 13995 13994 14715
+f 14712 14262 12662
+f 14318 14716 13104
+f 14083 14717 14718
+f 13510 13509 14719
+f 2768 5320 9452
+f 8012 7197 7315
+f 11124 14131 11213
+f 7200 7825 3549
+f 6600 4850 4849
+f 9476 6600 4849
+f 14720 14721 14722
+f 12055 12465 12567
+f 10787 10789 12302
+f 2133 697 2725
+f 7123 7122 7219
+f 13999 13998 14650
+f 14068 14067 14673
+f 13490 13674 10660
+f 11404 11473 13979
+f 12758 12569 14614
+f 12758 14614 14613
+f 12115 14610 12191
+f 14664 12291 12191
+f 14073 14663 14610
+f 14074 14073 14610
+f 14723 14000 13902
+f 14724 14723 13902
+f 14725 13990 13989
+f 14726 14001 14000
+f 14727 14003 14081
+f 14728 14725 13989
+f 14729 14002 14003
+f 14717 14727 14081
+f 14730 14004 14002
+f 14727 14729 14003
+f 13330 12779 13424
+f 14729 14730 14002
+f 14473 14474 14156
+f 14731 14732 14733
+f 14549 14668 14550
+f 14076 14473 14156
+f 11921 11827 14669
+f 14667 6996 6998
+f 11271 13736 14381
+f 14734 11921 14669
+f 14088 14090 14725
+f 14735 14736 11028
+f 11161 8367 8111
+f 14737 11777 11886
+f 10707 11405 12568
+f 10927 10926 13977
+f 1937 14531 1788
+f 10504 7062 10505
+f 5915 14620 5916
+f 3116 9498 7635
+f 14738 5028 5027
+f 14739 7661 7660
+f 6019 11716 7756
+f 7540 10989 13118
+f 8782 3524 6021
+f 3524 12552 6021
+f 6048 9992 6049
+f 9992 10070 4697
+f 11498 14588 14589
+f 14740 14741 13260
+f 3714 4076 4078
+f 11348 14742 10825
+f 8931 8933 14743
+f 14493 10777 10851
+f 4440 4058 4259
+f 7844 7843 9039
+f 3071 3073 3279
+f 14744 3444 14745
+f 8652 8651 11803
+f 14746 14747 14150
+f 11198 11199 14748
+f 10878 10924 13197
+f 14749 12161 12160
+f 11990 12083 10900
+f 11005 13667 12659
+f 11132 14749 12160
+f 14750 826 825
+f 4291 825 827
+f 14751 14678 826
+f 14750 14751 826
+f 14752 14679 14678
+f 14751 14752 14678
+f 14753 14680 14679
+f 14752 14753 14679
+f 14754 14681 14680
+f 14753 14754 14680
+f 6817 9271 14681
+f 14754 6817 14681
+f 14172 7948 2822
+f 4119 2870 14686
+f 14575 13567 14683
+f 11928 11927 13114
+f 14755 14756 41
+f 14090 14718 14725
+f 8892 14375 14684
+f 8564 9233 9232
+f 14145 6430 8446
+f 11635 11619 14390
+f 6342 14305 6343
+f 14757 14300 14758
+f 12145 6360 8950
+f 9135 3814 2349
+f 9977 10210 10124
+f 14502 14526 6184
+f 5219 5221 6341
+f 14647 14692 14168
+f 14692 14759 2012
+f 14760 14761 14762
+f 14763 14764 14765
+f 563 560 14766
+f 14766 560 14767
+f 14768 14769 14695
+f 8194 14768 14695
+f 14769 14770 14697
+f 14695 14769 14697
+f 14770 14537 14698
+f 14697 14770 14698
+f 14537 12548 14698
+f 12548 12563 14698
+f 6209 6705 8548
+f 12407 4021 4020
+f 14089 14728 14726
+f 3103 12464 14771
+f 14772 1141 1140
+f 14773 13057 14774
+f 14407 14775 11980
+f 14776 11562 14389
+f 13923 14777 12375
+f 5204 6709 3735
+f 10784 13625 10785
+f 12930 14065 14439
+f 12078 12930 14439
+f 4682 12077 11165
+f 12077 12078 14439
+f 6344 6216 6346
+f 9386 4682 11065
+f 10233 7341 5009
+f 7934 3468 10790
+f 12377 14778 14779
+f 13776 13777 13877
+f 3310 3312 14175
+f 14780 14781 7739
+f 2846 14692 2012
+f 14782 14783 14784
+f 14683 13568 14632
+f 14759 14785 2013
+f 14739 14786 14787
+f 13788 13798 14788
+f 14789 14790 14791
+f 1934 345 14325
+f 14478 12120 14479
+f 13014 14404 13124
+f 1746 6309 7651
+f 11710 11712 14331
+f 14597 14792 13390
+f 6018 11718 11716
+f 14793 14792 14597
+f 13233 14793 14597
+f 13913 14793 13233
+f 14792 14794 13390
+f 14096 13391 13390
+f 13138 13913 13233
+f 3529 3345 3944
+f 14794 14096 13390
+f 11725 11719 14713
+f 3663 3658 14795
+f 14796 13597 14797
+f 13596 13499 14798
+f 14242 13774 10146
+f 14799 13895 13897
+f 14185 14800 14801
+f 14183 14185 14801
+f 13104 7845 7033
+f 14802 14594 14593
+f 7259 6360 12145
+f 14803 5721 14804
+f 11900 12077 14439
+f 9386 11065 11064
+f 12077 11900 11165
+f 11010 9386 11064
+f 14455 13057 14773
+f 10578 14461 8203
+f 13950 14036 14037
+f 14805 11692 11778
+f 14066 14651 14672
+f 14186 14806 14799
+f 11473 14807 13979
+f 14012 11746 11745
+f 12854 12758 14613
+f 14808 13889 14809
+f 14663 14664 12191
+f 14810 12392 12291
+f 13983 14541 14607
+f 13572 13983 14607
+f 14723 14726 14000
+f 14726 14728 13989
+f 12508 13380 7363
+f 5936 6212 6074
+f 13302 13304 13219
+f 13391 11322 11749
+f 13015 13123 14811
+f 13120 13218 13220
+f 14260 11833 11692
+f 14805 14260 11692
+f 14812 14005 14004
+f 14813 13015 14811
+f 10145 14242 10146
+f 14730 14812 14004
+f 6829 3663 14795
+f 14526 11931 6185
+f 14228 13869 11551
+f 13774 14308 10575
+f 14500 14501 7464
+f 11796 9148 9147
+f 4258 4257 4412
+f 14814 8392 2594
+f 14775 14737 11886
+f 14815 14599 14594
+f 14532 14461 10578
+f 14816 14532 10578
+f 4682 11165 11065
+f 4404 3040 4083
+f 2593 14814 2594
+f 6716 6715 5224
+f 7265 14817 14818
+f 14819 4491 14041
+f 14804 5721 7928
+f 7929 7946 7930
+f 12848 13394 4082
+f 12551 2867 6021
+f 10999 10772 8287
+f 14820 14821 14822
+f 12082 11411 13906
+f 8286 10999 8287
+f 11416 10999 8286
+f 13906 11416 8286
+f 10924 14823 13197
+f 8287 10772 13923
+f 14824 14263 13406
+f 3243 14744 3244
+f 10660 13674 10661
+f 13675 13821 14064
+f 12710 12601 10652
+f 14059 12472 14060
+f 13562 11074 14823
+f 12196 12195 13248
+f 2012 14759 2013
+f 10924 13562 14823
+f 12779 12867 13424
+f 14825 3020 3413
+f 11914 14750 11915
+f 7107 11915 825
+f 14826 14751 14750
+f 11914 14826 14750
+f 14827 14752 14751
+f 14826 14827 14751
+f 14828 14753 14752
+f 14827 14828 14752
+f 14828 14829 14754
+f 14753 14828 14754
+f 14829 5225 6817
+f 14754 14829 6817
+f 1580 6504 636
+f 14830 4490 4492
+f 10527 4210 6622
+f 14831 14832 14833
+f 14088 14725 14728
+f 14089 14088 14728
+f 11989 11988 11078
+f 14802 14815 14594
+f 14834 14471 14835
+f 14470 14532 14816
+f 4469 880 4489
+f 11011 10667 14085
+f 14836 14837 14838
+f 12269 6041 7031
+f 2870 2872 14531
+f 14686 2870 14531
+f 14839 14840 14841
+f 14842 14843 14844
+f 14785 14845 10937
+f 2013 14785 10937
+f 14846 1346 1347
+f 11095 3538 11096
+f 14644 8195 8194
+f 3726 14847 3727
+f 14848 14849 14769
+f 14768 14848 14769
+f 14849 14850 14770
+f 14769 14849 14770
+f 14850 14132 14537
+f 14770 14850 14537
+f 2700 11087 2699
+f 9785 12548 14537
+f 14851 14852 14853
+f 14854 2217 2219
+f 13967 14855 14856
+f 14091 14089 14726
+f 14341 14455 14773
+f 6688 6785 13755
+f 14472 14471 14857
+f 14471 14470 14835
+f 14858 11011 14085
+f 14471 14834 14857
+f 10639 10638 14296
+f 14858 14085 10827
+f 6628 10639 10780
+f 10638 14858 10827
+f 10779 6626 10780
+f 10638 10827 14296
+f 11925 3563 10779
+f 10639 14296 10780
+f 5582 12979 5711
+f 10637 12157 10638
+f 6039 14701 14859
+f 8467 2388 2390
+f 14716 8115 13104
+f 10934 8545 3574
+f 14581 14582 14258
+f 14716 14318 14306
+f 14539 13995 14715
+f 14582 14716 14306
+f 10642 10641 14455
+f 13994 13973 14530
+f 14632 13788 14788
+f 13798 13887 14458
+f 1934 14108 14107
+f 14788 13798 14458
+f 14490 8448 14710
+f 8012 7826 7199
+f 11889 11799 14860
+f 8448 8450 13387
+f 3153 4132 3945
+f 14479 11889 14860
+f 5215 7109 14446
+f 3530 3529 4130
+f 11967 14200 14273
+f 3345 3945 3944
+f 11266 10759 13912
+f 11968 11967 14273
+f 10759 13828 13912
+f 11057 13728 13828
+f 11968 14273 14097
+f 14060 11968 14097
+f 11895 13507 13506
+f 11986 11895 13506
+f 10146 13774 10575
+f 14861 13316 13034
+f 13701 13597 14796
+f 14809 13701 14796
+f 14862 14799 13897
+f 14806 13898 13895
+f 14186 14184 14806
+f 14183 14801 14863
+f 14864 14802 14593
+f 3007 14865 14866
+f 3050 3049 14524
+f 14867 14868 14869
+f 6626 6628 10780
+f 12225 11011 14858
+f 12157 12225 14858
+f 11361 11360 10880
+f 4614 1635 1637
+f 14870 14871 14872
+f 14873 14805 11778
+f 14874 11665 14149
+f 13967 14207 14855
+f 8028 13070 10628
+f 14261 14012 11745
+f 14206 14799 14862
+f 13889 14808 14810
+f 14801 13900 13899
+f 14664 14810 12291
+f 13890 13889 14810
+f 13572 14607 14665
+f 13476 13572 14665
+f 14001 14726 13989
+f 14718 13993 13990
+f 13772 13107 13109
+f 14657 13556 13109
+f 13424 10729 11006
+f 14875 1552 14876
+f 10934 3574 3721
+f 11108 14249 11109
+f 12865 9262 5477
+f 10904 11347 10844
+f 11473 11472 14807
+f 12217 14877 14878
+f 14699 14092 14005
+f 11472 14333 14807
+f 14530 14529 14166
+f 14812 14699 14005
+f 14529 14528 14167
+f 14116 14530 14166
+f 3901 3750 8369
+f 13422 9622 10715
+f 8105 8101 5190
+f 13296 6187 14879
+f 11068 10002 10000
+f 8101 8102 5190
+f 14461 14460 8203
+f 14880 14881 14882
+f 13992 10717 10575
+f 12593 11000 12052
+f 12422 12609 6602
+f 14883 14884 14885
+f 14886 14748 11199
+f 5908 7328 14887
+f 7338 7137 8019
+f 8922 8921 14888
+f 8018 11305 8019
+f 12360 13714 13787
+f 10772 10765 13923
+f 11055 13715 12360
+f 12094 10020 14889
+f 14157 13715 10758
+f 12360 13787 13723
+f 10977 10976 10757
+f 13715 13714 12360
+f 14308 13992 10575
+f 13715 11055 10758
+f 13991 10776 10717
+f 13992 13991 10717
+f 13991 14467 10805
+f 10776 13991 10805
+f 14078 14157 10757
+f 14467 14103 10809
+f 11882 11075 11074
+f 10976 14078 10757
+f 10937 14845 12961
+f 10765 10764 14777
+f 8451 11914 8452
+f 14795 8452 11915
+f 14890 14826 11914
+f 8451 14890 11914
+f 14891 14827 14826
+f 14890 14891 14826
+f 14892 14828 14827
+f 14891 14892 14827
+f 14893 14829 14828
+f 14892 14893 14828
+f 14893 14894 5225
+f 14829 14893 5225
+f 12330 12329 12429
+f 5004 5006 12329
+f 12329 5006 12429
+f 5004 12329 12328
+f 8566 8388 8387
+f 1833 1668 1670
+f 14895 14054 14599
+f 10805 14467 10809
+f 14835 14470 14816
+f 12056 12759 12949
+f 14103 14381 10886
+f 10809 14103 10886
+f 13663 10888 10886
+f 9112 9225 1154
+f 8657 10357 8779
+f 9778 3072 9779
+f 14896 14897 14898
+f 7572 14899 14900
+f 12961 14901 12962
+f 14902 14903 14904
+f 14905 14906 14907
+f 14908 14909 14910
+f 14911 14912 14848
+f 14913 8194 7643
+f 14912 14914 14849
+f 14848 14912 14849
+f 14914 13430 14850
+f 14849 14914 14850
+f 10006 14132 14850
+f 13430 10006 14850
+f 3716 4087 4086
+f 3353 3355 8275
+f 3874 4073 3491
+f 14317 4563 14065
+f 14915 14916 14652
+f 14386 14915 14652
+f 11623 11622 14059
+f 12686 12789 13136
+f 14917 13904 14918
+f 14381 13663 10886
+f 12051 10893 10888
+f 13663 12051 10888
+f 12053 10939 10893
+f 11119 10077 11118
+f 11053 3564 11925
+f 11411 12082 12081
+f 11410 11411 12081
+f 13864 10645 10644
+f 14483 14919 14503
+f 13781 10915 10867
+f 14775 11886 11980
+f 14503 10142 14504
+f 8543 8542 6017
+f 4292 8543 6017
+f 3319 8669 3317
+f 1930 3516 3552
+f 1866 14920 2021
+f 14921 13384 14922
+f 14921 13215 13384
+f 13216 13308 13217
+f 14069 14699 14812
+f 14274 7634 14923
+f 14715 13994 14530
+f 14067 14066 14672
+f 14320 13148 13782
+f 13973 13876 14529
+f 13415 13416 14314
+f 7027 12889 7028
+f 7229 12393 11690
+f 12482 14924 13407
+f 12189 11983 14925
+f 12481 12482 13407
+f 11799 11710 14330
+f 11825 14671 14926
+f 11812 14400 11814
+f 14860 11799 14330
+f 13113 13743 13738
+f 12887 4080 12888
+f 13977 14105 14200
+f 13740 11262 13741
+f 12051 12053 10893
+f 11967 13977 14200
+f 12053 13154 10966
+f 10939 12053 10966
+f 13830 10003 13398
+f 13154 14927 10990
+f 14928 14601 13164
+f 10003 11902 7125
+f 11895 11898 13508
+f 14161 14190 11421
+f 14929 14861 13034
+f 8277 13780 8278
+f 13597 13596 14797
+f 14861 14608 13409
+f 14799 14806 13895
+f 2312 11280 14930
+f 14184 14183 14863
+f 14863 13899 13898
+f 13070 10633 10628
+f 14206 14186 14799
+f 14931 14524 9277
+f 13700 14011 12972
+f 12276 14373 12277
+f 13197 14823 4057
+f 14354 12151 14676
+f 7663 14626 7664
+f 13591 14493 10851
+f 10656 10655 11332
+f 14525 10946 9278
+f 14749 10902 12161
+f 12867 12869 10729
+f 13298 12694 12782
+f 14207 14206 14862
+f 14305 13967 14856
+f 14863 14801 13899
+f 14800 13901 13900
+f 13889 13701 14809
+f 13890 14810 14664
+f 13956 13894 14400
+f 14329 13956 14400
+f 14725 14718 13990
+f 14717 14081 13993
+f 13390 13392 14598
+f 14932 14595 13987
+f 13676 13691 13243
+f 11054 11925 11926
+f 14742 10867 10825
+f 11127 11926 11123
+f 636 1362 637
+f 14627 12172 10700
+f 13307 10743 11426
+f 13805 13490 12376
+f 14131 14344 11213
+f 14878 14933 11795
+f 13386 14107 13387
+f 12175 12176 10853
+f 13259 14740 13260
+f 14710 8448 13387
+f 2735 3179 2736
+f 3546 3519 3521
+f 5225 14894 5226
+f 14934 14935 14936
+f 4741 4740 5913
+f 14937 10839 14938
+f 6360 6359 8950
+f 10138 5912 12354
+f 4141 11957 4419
+f 9712 14939 14940
+f 12564 8812 3377
+f 14941 4592 2422
+f 14942 14943 14944
+f 2341 5402 14945
+f 5402 5547 14945
+f 5111 14946 4338
+f 14947 14948 14949
+f 14950 13534 13533
+f 10966 13154 10990
+f 14157 10758 10757
+f 14927 13150 11007
+f 10990 14927 11007
+f 13150 11583 11021
+f 13625 13397 10785
+f 11007 13150 11021
+f 11583 14340 11050
+f 11021 11583 11050
+f 14340 14341 11071
+f 13398 10830 10785
+f 11050 14340 11071
+f 13923 10765 14777
+f 10803 10802 13618
+f 3658 8453 8452
+f 10764 13904 14917
+f 14951 14890 8451
+f 14952 14951 8451
+f 14953 14891 14890
+f 14951 14953 14890
+f 14954 14892 14891
+f 14953 14954 14891
+f 14954 14955 14893
+f 14892 14954 14893
+f 14955 14956 14894
+f 14893 14955 14894
+f 14956 14957 5226
+f 14894 14956 5226
+f 7020 7022 5226
+f 14957 7020 5226
+f 7023 11229 7122
+f 5900 5907 5906
+f 14341 14773 11145
+f 12463 13422 14709
+f 14394 14895 14661
+f 10675 11331 10676
+f 4625 10091 14047
+f 6707 14289 11957
+f 14958 14959 5390
+f 13237 11617 11659
+f 6711 2920 2922
+f 8783 8782 9780
+f 8731 2629 14960
+f 14961 14950 13533
+f 14962 14963 14964
+f 14965 14966 14967
+f 2667 2666 12467
+f 14968 14969 11222
+f 4957 14970 1540
+f 3362 3361 14971
+f 14972 14973 14912
+f 14974 14911 14848
+f 14973 14975 14914
+f 14912 14973 14914
+f 14975 10081 13430
+f 14914 14975 13430
+f 655 12589 727
+f 14976 14977 14978
+f 14979 14980 14981
+f 7217 5066 5062
+f 14982 14983 10649
+f 10645 14982 10649
+f 14916 14984 13866
+f 14652 14916 13866
+f 13138 13235 13139
+f 7245 13293 7366
+f 14130 14985 11573
+f 10602 10604 11506
+f 12316 14050 12374
+f 11004 13297 13667
+f 10234 10230 10934
+f 4203 4368 4204
+f 10068 10069 904
+f 14469 14472 14986
+f 13904 8374 14918
+f 14469 14986 14919
+f 14483 14469 14919
+f 11238 6932 6832
+f 14472 14857 14986
+f 14987 14988 14989
+f 14990 14971 14991
+f 14859 14316 14319
+f 6440 7828 5714
+f 14864 14593 14382
+f 14992 14398 14395
+f 14993 14382 14316
+f 14993 14864 14382
+f 14090 14083 14718
+f 14859 14993 14316
+f 10943 14139 12555
+f 14071 14069 14812
+f 14994 14995 1610
+f 11277 4896 4895
+f 12188 14996 14474
+f 6606 6604 6463
+f 12188 12189 14996
+f 12391 12188 14474
+f 11983 11825 14926
+f 11983 14926 14925
+f 6573 2577 14997
+f 11921 14734 14671
+f 11814 14401 11816
+f 14998 7235 2226
+f 14533 13113 13738
+f 7027 14618 12889
+f 14190 11264 11421
+f 11262 13740 13743
+f 13752 14077 11110
+f 14161 11421 11111
+f 12266 12297 12301
+f 14077 14161 11111
+f 11662 13730 13521
+f 12280 12266 12301
+f 13519 11662 13521
+f 13730 13731 13629
+f 13153 647 10898
+f 10831 13153 10898
+f 13802 11995 13122
+f 13619 13616 11996
+f 14338 14999 15000
+f 14635 15001 14636
+f 13316 14861 13409
+f 14996 13712 14156
+f 2817 5909 2818
+f 11071 14341 11145
+f 14806 14863 13898
+f 14673 14655 14092
+f 14184 14863 14806
+f 13148 11052 11116
+f 5922 9852 5923
+f 14984 15002 13867
+f 11489 11170 11172
+f 11212 14119 14030
+f 14085 12363 10828
+f 12513 12429 5006
+f 15003 9457 15004
+f 12675 13414 12676
+f 14744 3243 3444
+f 14985 11350 11349
+f 12875 12686 13136
+f 9858 12494 11695
+f 14207 14862 14855
+f 14305 14856 15005
+f 14801 14800 13900
+f 14724 13902 13901
+f 13800 13890 14664
+f 14701 15006 9208
+f 11101 13956 14329
+f 11102 11101 14329
+f 14718 14717 13993
+f 14602 14538 14112
+f 14595 13986 13987
+f 13311 14418 15007
+f 9451 5320 11168
+f 15002 15008 13864
+f 1218 1217 8109
+f 13684 13415 14314
+f 6820 6819 6918
+f 6349 6348 15009
+f 11331 15010 10676
+f 6348 14484 15011
+f 12222 11307 11958
+f 3286 11119 3287
+f 10573 9270 7824
+f 15008 14982 10645
+f 14140 10901 14749
+f 13459 10801 11105
+f 13115 4859 12473
+f 15012 4637 6822
+f 4174 4173 15013
+f 15014 12062 15015
+f 14380 10686 14312
+f 10740 14590 10741
+f 13345 9380 5492
+f 9352 14573 1554
+f 13423 9620 9622
+f 15016 15017 15018
+f 12117 6349 15019
+f 12398 6251 15020
+f 15021 15022 15023
+f 15024 9448 9457
+f 14773 14774 11147
+f 15003 15024 9457
+f 11145 14773 11147
+f 14774 14307 11306
+f 11147 14774 11306
+f 14307 14379 11430
+f 11306 14307 11430
+f 13928 7028 12048
+f 14379 14380 11434
+f 14777 10764 14917
+f 4617 8282 8280
+f 15025 14951 14952
+f 10984 15025 14952
+f 15026 14953 14951
+f 15025 15026 14951
+f 15026 15027 14954
+f 14953 15026 14954
+f 15027 15028 14955
+f 14954 15027 14955
+f 15029 14956 14955
+f 15028 15029 14955
+f 15030 14957 14956
+f 15029 15030 14956
+f 15031 7020 14957
+f 15030 15031 14957
+f 15032 15033 15034
+f 15031 11229 7020
+f 13114 12463 14709
+f 6038 5900 13817
+f 12842 14457 13291
+f 11430 14379 11434
+f 14290 10709 10613
+f 3890 3892 3894
+f 6350 12117 12116
+f 12935 12258 12260
+f 12117 15035 557
+f 3677 13145 5858
+f 10018 14566 10019
+f 3521 9848 5223
+f 15036 9523 9448
+f 15024 15036 9448
+f 5248 2318 2317
+f 15037 15038 15039
+f 15040 15041 15042
+f 6392 15043 6393
+f 15044 14972 15045
+f 10712 14972 14911
+f 15046 15047 14975
+f 14973 15046 14975
+f 15047 5441 10081
+f 14975 15047 10081
+f 4114 4110 4929
+f 776 670 6574
+f 11565 13882 13497
+f 13150 11338 11583
+f 14983 14038 10650
+f 10649 14983 10650
+f 11836 10675 10677
+f 10744 8296 10747
+f 15048 15049 15050
+f 12326 12222 11958
+f 12116 557 556
+f 12826 12916 12827
+f 4869 11234 8017
+f 4745 4747 14568
+f 7919 8012 7315
+f 14380 14312 11436
+f 13234 14598 13410
+f 15051 7471 4721
+f 11742 13671 13670
+f 11622 12470 14059
+f 13171 10963 13069
+f 11266 10977 10759
+f 14596 14724 14800
+f 11800 12373 11711
+f 14068 14673 14699
+f 14185 14596 14800
+f 14071 14812 14730
+f 14070 14071 14730
+f 14070 14730 14729
+f 14084 14070 14729
+f 14082 14727 14717
+f 14083 14082 14717
+f 14084 14729 14727
+f 14082 14084 14727
+f 13233 14597 13234
+f 14597 14598 13234
+f 13128 13127 14608
+f 14861 13128 14608
+f 14607 12020 12118
+f 12189 14925 14996
+f 14665 12118 12226
+f 14666 14665 12226
+f 14668 14667 6998
+f 14666 12226 6996
+f 11434 14380 11436
+f 14667 14666 6996
+f 13113 11262 13743
+f 13682 11437 11436
+f 11120 13847 14057
+f 11262 11261 13741
+f 14309 14199 12716
+f 13845 13922 14057
+f 13643 12396 12297
+f 14199 13778 12605
+f 13042 13916 15052
+f 12266 13643 12297
+f 13515 15052 13831
+f 13515 13042 15052
+f 13517 13513 13732
+f 13513 13515 13831
+f 10788 10879 12849
+f 10786 10945 12849
+f 13613 12002 11999
+f 12487 12010 12395
+f 3527 3530 4129
+f 9774 2925 964
+f 14474 14996 14156
+f 14925 13713 13712
+f 4094 2574 2577
+f 6573 4094 2577
+f 14699 14673 14092
+f 14672 14656 14655
+f 13739 10597 12175
+f 10782 2059 15053
+f 13866 14984 13867
+f 14130 15054 14985
+f 12366 9261 9263
+f 3280 3279 10941
+f 1781 15055 9718
+f 14312 13682 11436
+f 13684 11439 11437
+f 15056 9530 9523
+f 13682 13684 11437
+f 12692 12689 12113
+f 11226 14129 7343
+f 15057 15058 15059
+f 11350 15060 12364
+f 14800 14724 13901
+f 14108 14325 10698
+f 14618 9934 12889
+f 14650 14095 14094
+f 14554 14553 15061
+f 3652 11161 8111
+f 14659 14114 14113
+f 14538 14659 14113
+f 13767 7856 14125
+f 11555 11561 11633
+f 13867 15002 13864
+f 6459 6462 7746
+f 10303 13739 12175
+f 10795 11003 11874
+f 13684 14314 11545
+f 11439 13684 11545
+f 14314 14315 11703
+f 11121 12281 13690
+f 11545 14314 11703
+f 13864 15008 10645
+f 13676 11122 13691
+f 12006 12008 12576
+f 11206 11208 13612
+f 14128 13777 13022
+f 12861 12003 12766
+f 13509 13672 14719
+f 13556 14450 13638
+f 13392 13036 13411
+f 11174 11209 11175
+f 9444 15062 10832
+f 10670 13510 10591
+f 9283 12606 9284
+f 4553 8033 10714
+f 15036 15056 9523
+f 15063 8453 3657
+f 14315 14658 11878
+f 11703 14315 11878
+f 8379 15064 10984
+f 10875 10923 13639
+f 3124 2067 3332
+f 15065 15025 10984
+f 14952 8451 8453
+f 15066 15026 15025
+f 15065 15066 15025
+f 15067 15027 15026
+f 15066 15067 15026
+f 15067 15068 15028
+f 15027 15067 15028
+f 15069 15029 15028
+f 15068 15069 15028
+f 15070 15030 15029
+f 15069 15070 15029
+f 15071 15031 15030
+f 15070 15071 15030
+f 7218 11229 15031
+f 15071 7218 15031
+f 15072 9273 9272
+f 3741 6189 966
+f 14658 15073 11896
+f 11340 10642 14340
+f 11428 10683 15010
+f 12181 13029 12182
+f 3560 8030 13239
+f 9637 12192 12193
+f 11878 14658 11896
+f 15073 15074 11901
+f 9371 4118 14283
+f 14283 4118 4120
+f 15075 9617 9530
+f 15056 15075 9530
+f 15076 5675 14177
+f 15039 15076 14177
+f 15077 15078 15079
+f 12457 15080 15081
+f 15082 15083 15084
+f 15085 2838 2127
+f 15086 15087 15047
+f 15046 15086 15047
+f 15087 5439 5441
+f 15047 15087 5441
+f 15088 9638 9617
+f 7140 7043 7142
+f 14403 14481 14404
+f 13154 13735 14927
+f 14038 15089 12635
+f 11167 11061 11168
+f 13872 14399 9143
+f 4536 4839 12215
+f 11896 15073 11901
+f 15090 11918 11901
+f 15074 15090 11901
+f 15091 12156 11918
+f 14660 14802 14864
+f 12752 3564 11053
+f 10650 14038 12635
+f 14598 13411 13410
+f 14239 14091 14723
+f 15089 15054 14130
+f 14239 14723 14724
+f 14596 14239 14724
+f 13981 13799 13206
+f 14091 14726 14723
+f 13980 13027 14813
+f 13027 13015 14813
+f 14932 13987 10725
+f 13303 13205 13207
+f 10790 3468 3467
+f 10724 14932 10725
+f 4100 9827 6616
+f 15005 13472 13570
+f 4714 4713 7455
+f 14856 13473 13472
+f 15005 14856 13472
+f 14855 13896 13473
+f 13314 13227 15092
+f 15093 13314 15092
+f 15092 14929 13034
+f 14665 14607 12118
+f 13507 11895 13508
+f 11898 11911 13605
+f 15090 15091 11918
+f 10880 13623 10784
+f 13845 13844 13922
+f 14675 12224 12156
+f 13846 13845 14057
+f 13844 13843 12669
+f 12315 14271 12317
+f 13844 13836 13922
+f 12969 12971 14010
+f 12318 14309 12716
+f 12971 13633 14010
+f 13494 11352 10685
+f 13632 13919 13417
+f 12220 12219 14100
+f 13920 13433 13320
+f 13417 13920 13320
+f 13421 13520 13920
+f 13919 13421 13920
+f 10881 10786 12849
+f 10831 10898 10945
+f 13616 13613 11999
+f 13606 12004 12002
+f 11142 8369 11143
+f 7661 14739 14787
+f 14996 14925 13712
+f 14926 13709 13713
+f 15094 14950 14961
+f 14925 14926 13713
+f 14673 14672 14655
+f 3741 6186 6189
+f 13492 14320 13782
+f 14651 14094 14656
+f 10433 15060 11350
+f 14458 14456 14243
+f 13510 14719 10591
+f 14985 10433 11350
+f 13149 12752 11053
+f 8890 14684 14993
+f 8376 12752 13149
+f 15095 8376 13149
+f 8374 8376 15095
+f 14859 14319 6039
+f 14684 14864 14993
+f 11163 5055 5870
+f 12364 15096 12365
+f 14924 13944 13947
+f 14397 14556 14403
+f 14651 14650 14094
+f 14602 14112 14095
+f 6703 3740 965
+f 13894 14072 14401
+f 14659 14539 14115
+f 12935 12260 10653
+f 12066 12065 11407
+f 14114 14659 14115
+f 12365 15096 15097
+f 3696 964 966
+f 11001 13424 11006
+f 11079 11078 4410
+f 14918 8374 15095
+f 7217 12704 13321
+f 15091 14675 12156
+f 14674 12327 12224
+f 12220 14100 13165
+f 14675 14674 12224
+f 11554 11562 14776
+f 14259 11554 14776
+f 14020 12380 12327
+f 14674 14020 12327
+f 13465 12468 12380
+f 14020 13465 12380
+f 11929 12469 12468
+f 13465 11929 12468
+f 4617 8281 8282
+f 14737 14873 11777
+f 10946 11468 10841
+f 3301 3692 12497
+f 15075 15088 9617
+f 15098 9708 9638
+f 6337 3857 6338
+f 12655 15064 6337
+f 7639 4387 5816
+f 15099 15065 15064
+f 12655 15099 15064
+f 15100 15066 15065
+f 15099 15100 15065
+f 15101 15067 15066
+f 15100 15101 15066
+f 15101 15102 15068
+f 15067 15101 15068
+f 15102 15103 15069
+f 15068 15102 15069
+f 15104 15070 15069
+f 15103 15104 15069
+f 15104 15105 15071
+f 15070 15104 15071
+f 7346 7218 15071
+f 15105 7346 15071
+f 6627 10774 6628
+f 7219 7460 7220
+f 11583 11340 14340
+f 2129 1635 2127
+f 13669 11433 13483
+f 14326 14788 14327
+f 3838 4551 4550
+f 13719 10802 10801
+f 11928 12502 12469
+f 14873 11778 11777
+f 11929 11928 12469
+f 10834 5223 10840
+f 15088 15098 9638
+f 15106 9719 9708
+f 15107 15108 15109
+f 15110 7544 5064
+f 15111 15112 15113
+f 15114 15115 15086
+f 15116 15046 15044
+f 15115 15117 15087
+f 15086 15115 15087
+f 15117 10315 5439
+f 15087 15117 5439
+f 12648 12650 15118
+f 12647 8293 15119
+f 13869 15120 13911
+f 12052 13151 12053
+f 12556 11133 14626
+f 7663 12556 14626
+f 14661 14895 14815
+f 14662 14661 14815
+f 11928 13114 12607
+f 12502 11928 12607
+f 3563 6626 10779
+f 14387 14436 9268
+f 14684 14660 14864
+f 11411 11416 13906
+f 12635 15089 14130
+f 14662 14815 14802
+f 14262 14632 14326
+f 15054 10433 14985
+f 11841 14387 9267
+f 12359 14388 13968
+f 14862 13897 13896
+f 14856 14855 13473
+f 14797 13596 14798
+f 14855 14862 13896
+f 12852 12854 14612
+f 13499 13314 15093
+f 14611 13031 14612
+f 12854 14613 14612
+f 13032 13031 14611
+f 14609 13032 14611
+f 13127 13032 14609
+f 13031 12852 14612
+f 13126 13128 14861
+f 14608 13127 14609
+f 13126 14929 15092
+f 14929 13126 14861
+f 12855 14798 12948
+f 13227 13126 15092
+f 13508 11898 13605
+f 13033 15092 13034
+f 10874 13915 13107
+f 11911 11913 13621
+f 13840 13915 10874
+f 10873 13840 10874
+f 11357 12209 12204
+f 13915 13912 13107
+f 11358 11357 12204
+f 11060 12211 12209
+f 14272 14309 12318
+f 12317 14272 12318
+f 12408 13252 12409
+f 12219 12966 14100
+f 14192 14102 14101
+f 15121 14192 14191
+f 3149 5052 2551
+f 13434 11780 13320
+f 11784 14267 15122
+f 11971 11784 15122
+f 14009 13044 13918
+f 13421 13919 13918
+f 12944 10879 10788
+f 10786 10831 10945
+f 13613 13606 12002
+f 12010 12106 12395
+f 7755 7754 14488
+f 15123 12063 15124
+f 2388 12213 2389
+f 8369 8370 11143
+f 14671 13706 13709
+f 13716 14669 13717
+f 6198 15125 6060
+f 2052 3039 2853
+f 14672 14651 14656
+f 9045 15126 12491
+f 14712 14683 14262
+f 14632 14788 14326
+f 15060 15096 12364
+f 8798 14044 10948
+f 15127 1631 15128
+f 13311 13310 13312
+f 14823 11074 4057
+f 11498 11503 14588
+f 14742 13781 10867
+f 14373 14354 14676
+f 15129 14921 14922
+f 13215 13217 13384
+f 11104 10801 10803
+f 13114 14709 12883
+f 14481 14482 14404
+f 14245 14527 14711
+f 14650 14602 14095
+f 14538 14113 14112
+f 14400 13894 14401
+f 1933 346 345
+f 14179 13228 13313
+f 14926 14671 13709
+f 14539 14715 14117
+f 13773 10930 11406
+f 2752 6146 6198
+f 14115 14539 14117
+f 12265 13643 12266
+f 14396 14515 14397
+f 8890 14993 14859
+f 11426 10743 10745
+f 10900 14677 10843
+f 12937 12220 13165
+f 14494 10767 10777
+f 14652 13866 11491
+f 14959 14958 15130
+f 11363 11442 15131
+f 4378 5315 6700
+f 5315 10236 12482
+f 13491 11489 11826
+f 13988 8286 8288
+f 10695 10625 13482
+f 7746 4281 6459
+f 290 4770 4769
+f 3382 5738 3383
+f 6533 15132 15133
+f 10230 8545 10934
+f 15098 15106 9708
+f 15134 9775 9719
+f 3006 15135 4369
+f 5586 12692 5587
+f 12016 15099 12655
+f 12017 12016 12655
+f 15136 15100 15099
+f 12016 15136 15099
+f 15137 15101 15100
+f 15136 15137 15100
+f 15138 15102 15101
+f 15137 15138 15101
+f 15138 15139 15103
+f 15102 15138 15103
+f 15140 15104 15103
+f 15139 15140 15103
+f 15141 15105 15104
+f 15140 15141 15104
+f 15142 7346 15105
+f 15141 15142 15105
+f 5876 5875 7933
+f 15142 7345 7346
+f 4553 10714 6697
+f 8201 8200 8205
+f 14788 14458 14327
+f 10609 10608 13992
+f 11167 11166 11347
+f 15143 15144 15145
+f 11089 11088 15146
+f 769 3751 762
+f 11208 12376 13612
+f 11824 13491 11826
+f 15106 15134 9719
+f 12607 13114 12883
+f 14047 13984 14048
+f 5815 15147 6375
+f 12643 15148 9525
+f 15149 15150 15114
+f 15114 15116 15149
+f 15151 15152 15117
+f 15115 15151 15117
+f 15152 10316 10315
+f 15117 15152 10315
+f 8919 14051 15153
+f 7343 12643 9525
+f 15154 14228 13464
+f 15155 15156 13242
+f 14296 10827 10829
+f 14719 13672 15157
+f 13157 5888 5890
+f 11065 10895 10668
+f 7847 3858 4427
+f 14660 14662 14802
+f 14835 14816 14716
+f 8116 8205 8200
+f 10578 8116 8115
+f 14816 10578 8115
+f 8803 9146 7640
+f 11109 14249 11105
+f 14228 15154 13869
+f 15120 15158 13911
+f 13904 11435 8374
+f 11435 8375 8374
+f 4256 13197 4057
+f 4680 4682 9386
+f 3902 9057 3903
+f 14798 13499 15093
+f 14810 14808 12480
+f 12392 14810 12480
+f 12480 14808 12572
+f 14808 14809 12572
+f 12760 14797 12855
+f 14809 14796 12664
+f 12572 14809 12664
+f 14796 14797 12760
+f 12664 14796 12760
+f 14797 14798 12855
+f 15093 15092 13033
+f 14798 15093 12948
+f 13605 11911 13621
+f 12948 15093 13033
+f 13722 11209 11174
+f 11913 11909 13622
+f 4897 9451 11063
+f 13724 13726 13110
+f 11357 11060 12209
+f 10596 12198 12194
+f 3833 8664 12210
+f 14270 12313 12211
+f 4697 12354 4698
+f 8783 9780 7437
+f 8125 8124 8296
+f 6710 7563 3736
+f 12108 2641 6213
+f 7028 12049 12048
+f 15159 15121 14191
+f 14196 15160 14197
+f 13130 13129 13700
+f 10963 13130 13700
+f 11971 15122 15161
+f 11972 11971 15161
+f 13135 13421 13918
+f 13520 13522 13433
+f 15162 12944 10788
+f 10879 10881 12849
+f 12106 12108 12295
+f 12395 12106 12295
+f 12295 12108 6213
+f 10978 2530 2685
+f 11393 15163 11394
+f 6230 6229 14877
+f 14552 14477 13718
+f 13717 14552 13718
+f 7729 13393 5159
+f 3830 7729 5159
+f 15126 9329 12491
+f 14007 14006 15164
+f 14575 14683 14712
+f 14711 14575 14712
+f 14449 14448 15165
+f 6572 6573 10458
+f 14835 14716 14582
+f 14834 14835 14582
+f 13601 10695 13482
+f 15166 15124 15014
+f 7112 6301 5611
+f 14986 14857 14580
+f 9284 9159 9160
+f 3926 15167 8611
+f 14834 14582 14581
+f 14528 14527 14245
+f 11180 11179 11958
+f 14166 14529 14167
+f 14167 14528 14245
+f 15168 13957 14555
+f 14709 10715 13144
+f 14671 14734 13707
+f 8473 932 15169
+f 12465 10707 12568
+f 13706 14671 13707
+f 14715 14530 14116
+f 12565 12663 13689
+f 14556 14481 14403
+f 14117 14715 14116
+f 12883 14709 13144
+f 14243 14456 14396
+f 13633 10607 13921
+f 15170 15171 15172
+f 11562 11635 14389
+f 10563 9632 15173
+f 11619 11620 13693
+f 14390 11619 13693
+f 14919 14986 10143
+f 14857 14581 14580
+f 14226 14627 10700
+f 13721 14466 10802
+f 4089 11702 4899
+f 13057 13737 14774
+f 13595 14353 14374
+f 10457 4090 5489
+f 10357 8455 8779
+f 15174 9776 9775
+f 15134 15174 9775
+f 13774 11586 14308
+f 2009 15175 2010
+f 12176 12194 10853
+f 15175 13163 2010
+f 15176 15136 12016
+f 12018 15176 12016
+f 15177 15137 15136
+f 15176 15177 15136
+f 15178 15138 15137
+f 15177 15178 15137
+f 15179 15139 15138
+f 15178 15179 15138
+f 15180 15140 15139
+f 15179 15180 15139
+f 15181 15141 15140
+f 15180 15181 15140
+f 15181 15182 15142
+f 15141 15181 15142
+f 15183 7345 15142
+f 15182 15183 15142
+f 15184 13052 15185
+f 15183 7461 7345
+f 10608 11269 14467
+f 5444 7646 13463
+f 14653 11494 8612
+f 15154 15120 13869
+f 9376 1773 13547
+f 8611 14653 8612
+f 10659 12070 12163
+f 14986 14580 10143
+f 14917 14918 12284
+f 9522 9444 10832
+f 10715 10716 6691
+f 13019 13683 13682
+f 6201 14961 15186
+f 15187 15188 5946
+f 15189 5804 5806
+f 15190 15191 3006
+f 15192 15193 15152
+f 15115 15150 15151
+f 15193 10460 10316
+f 15152 15193 10316
+f 12404 4540 4376
+f 13398 13914 10830
+f 6337 4478 4477
+f 6822 15194 9996
+f 15195 14719 15157
+f 14654 14450 13556
+f 11919 856 11920
+f 14919 10143 10142
+f 13867 13864 11319
+f 10142 10144 14700
+f 14824 13406 13498
+f 3564 3563 11925
+f 10922 12058 1944
+f 15196 563 14766
+f 14657 14654 13556
+f 7937 7331 7938
+f 15197 13236 14012
+f 15197 15198 13236
+f 15199 15197 14012
+f 15198 13237 13236
+f 11074 11076 4057
+f 10972 14175 10943
+f 15200 13738 10303
+f 6175 12102 6176
+f 14332 14164 13822
+f 13893 14331 13824
+f 1993 1995 9421
+f 7455 4607 10636
+f 13624 11906 13729
+f 11904 11902 13830
+f 5760 5759 8103
+f 13729 11904 13830
+f 11906 11904 13729
+f 13830 11902 10003
+f 13621 11913 13622
+f 11909 11906 13624
+f 13725 13722 11174
+f 13622 11909 13624
+f 12176 10596 12194
+f 13724 13110 11209
+f 9993 10458 10140
+f 10598 12200 12198
+f 12103 9528 10354
+f 9528 8456 8455
+f 15201 15175 2009
+f 2359 15202 2360
+f 14193 14195 15203
+f 10611 15201 2009
+f 15204 14193 15203
+f 14194 14198 14195
+f 14194 14196 14198
+f 15160 14286 14197
+f 15160 15121 15159
+f 14286 15160 15159
+f 13318 14334 15205
+f 14104 13318 15205
+f 14050 11975 15206
+f 11972 15161 15207
+f 13920 13520 13433
+f 13628 13434 13433
+f 14244 12944 15162
+f 10836 14244 15162
+f 15157 14244 10836
+f 15208 15157 10836
+f 1864 1863 3254
+f 12003 12006 12766
+f 10236 14561 12482
+f 13975 15209 13976
+f 14477 14478 13720
+f 6230 12217 12216
+f 15210 13474 12063
+f 13718 14477 13720
+f 15211 15212 15213
+f 14189 14713 14794
+f 14683 14632 14262
+f 10930 11035 11406
+f 12467 12466 5621
+f 15156 13464 13242
+f 14816 8115 14716
+f 15214 9849 9776
+f 13144 10715 6691
+f 573 10922 1944
+f 7458 7350 7349
+f 15174 15214 9776
+f 12212 12374 10799
+f 14857 14834 14581
+f 13485 13484 14634
+f 10846 12755 11214
+f 10789 10899 11215
+f 14527 14575 14711
+f 15158 14915 14386
+f 6192 13287 12934
+f 13018 12795 13019
+f 7435 7636 3695
+f 12485 14022 7753
+f 14734 14669 13716
+f 13720 14478 13803
+f 11575 14422 14154
+f 13707 14734 13716
+f 11143 8366 11164
+f 10930 11033 11035
+f 14515 14556 14397
+f 13500 13594 3948
+f 10688 10921 575
+f 14327 14458 14243
+f 15215 15216 985
+f 222 10688 575
+f 13879 1947 13880
+f 15217 14447 15218
+f 5675 5248 14045
+f 15219 15220 15221
+f 14639 9931 9849
+f 4879 6028 10647
+f 15073 14240 15074
+f 3561 3560 7545
+f 15214 14639 9849
+f 14323 12464 3545
+f 15222 9994 9931
+f 12108 3659 2641
+f 4477 12655 6337
+f 6328 3560 3559
+f 14639 15222 9931
+f 6059 12018 12017
+f 7020 6918 7022
+f 15223 15177 15176
+f 15224 15223 15176
+f 15225 15178 15177
+f 15223 15225 15177
+f 15225 15226 15179
+f 15178 15225 15179
+f 15226 15227 15180
+f 15179 15226 15180
+f 15228 15181 15180
+f 15227 15228 15180
+f 15229 15182 15181
+f 15228 15229 15181
+f 15230 15183 15182
+f 15229 15230 15182
+f 15231 7461 15183
+f 15230 15231 15183
+f 8009 6175 6174
+f 15231 7654 7461
+f 15156 15154 13464
+f 5925 12367 12369
+f 7038 6932 11328
+f 11174 11173 14450
+f 10972 3310 14175
+f 2387 9995 9994
+f 12929 11239 6832
+f 8211 8836 3896
+f 15222 2387 9994
+f 2288 2287 8671
+f 12829 12939 12941
+f 13345 13158 13465
+f 2386 10071 9995
+f 1645 776 7951
+f 15232 15233 15234
+f 15235 15236 1868
+f 15237 15238 15239
+f 15165 15240 6099
+f 15241 15242 15193
+f 15192 15241 15193
+f 15242 10526 10460
+f 15193 15242 10460
+f 4210 10574 4208
+f 8886 12564 3377
+f 11197 3466 13932
+f 5625 7933 13932
+f 3311 4301 3312
+f 4844 14439 6579
+f 11030 14735 11028
+f 3468 7934 5202
+f 4896 11277 5725
+f 2387 2386 9995
+f 13197 7113 10876
+f 1275 4923 1276
+f 10904 8288 11167
+f 12109 12699 5585
+f 11209 13110 11210
+f 13863 14589 15243
+f 14588 15244 15245
+f 15246 15247 14805
+f 15248 14261 14260
+f 9975 9913 2893
+f 1771 9376 13547
+f 14008 14714 13927
+f 15249 13929 15250
+f 13564 15090 15074
+f 13824 14332 13822
+f 13727 13725 14654
+f 13037 12422 3628
+f 14657 13728 14654
+f 13725 11174 14654
+f 13828 13728 14657
+f 13108 13828 14657
+f 13828 13108 13107
+f 13728 13727 14654
+f 13722 13724 11209
+f 13912 13828 13107
+f 10596 10598 12198
+f 13726 13122 13110
+f 11546 3564 12752
+f 10598 13877 12202
+f 11783 11422 14266
+f 12090 11959 14328
+f 15204 15203 15175
+f 11422 11424 15251
+f 15252 15253 12778
+f 15201 15204 15175
+f 13325 10800 15254
+f 10799 15253 15252
+f 15255 13317 15254
+f 10800 10799 15252
+f 13247 13317 15256
+f 10800 15252 15254
+f 13247 15256 15205
+f 13317 13325 15254
+f 14334 13247 15205
+f 13317 15255 15256
+f 14050 15206 15257
+f 11975 11972 15207
+f 13522 13628 13433
+f 13630 13435 13434
+f 13628 13630 13434
+f 13732 13432 13435
+f 13530 13733 13428
+f 13531 13530 13428
+f 12001 12003 12861
+f 12952 12001 12861
+f 9780 2869 5350
+f 4132 12103 4133
+f 12573 6230 12216
+f 8658 8657 8780
+f 14478 14479 13803
+f 11801 11802 11894
+f 14792 14188 14794
+f 14713 14096 14794
+f 11969 11823 11982
+f 15258 14922 13811
+f 15259 14873 14737
+f 15260 15259 14737
+f 10846 10845 12755
+f 13863 15243 11197
+f 10902 12163 12161
+f 11474 14386 11475
+f 5731 11702 10769
+f 2386 6195 10141
+f 11623 14059 13925
+f 10071 2386 10141
+f 11957 14289 10618
+f 11497 14589 13863
+f 6195 6197 10225
+f 10713 10714 13429
+f 13911 15158 14386
+f 15155 13242 13237
+f 6531 1960 3708
+f 10749 2715 8547
+f 12485 11142 14022
+f 5916 13928 8009
+f 14479 14860 13804
+f 13803 14479 13804
+f 14669 14552 13717
+f 12573 12216 12223
+f 14991 15261 15262
+f 10564 4575 4577
+f 13594 10838 6022
+f 14187 14188 14792
+f 14456 14515 14396
+f 14436 10942 10944
+f 15199 14012 14261
+f 15248 15199 14261
+f 14589 14588 15245
+f 14587 15263 15244
+f 2653 14706 2018
+f 6919 6918 7021
+f 11075 11079 11076
+f 12472 11968 14060
+f 3105 12497 12464
+f 13991 10608 14467
+f 7567 1878 1656
+f 10141 6195 10225
+f 1471 1473 13526
+f 4045 5443 5442
+f 6727 6730 6630
+f 7113 13197 4256
+f 4618 1086 4619
+f 11792 13869 11709
+f 15125 15264 15223
+f 15224 12018 6060
+f 15264 15265 15225
+f 15223 15264 15225
+f 15265 15266 15226
+f 15225 15265 15226
+f 15266 15267 15227
+f 15226 15266 15227
+f 15268 15228 15227
+f 15267 15268 15227
+f 15269 15229 15228
+f 15268 15269 15228
+f 15270 15230 15229
+f 15269 15270 15229
+f 15271 15231 15230
+f 15270 15271 15230
+f 14268 7654 15231
+f 15271 14268 15231
+f 7730 3830 10309
+f 5899 9631 2957
+f 4058 11076 4411
+f 15247 15248 14260
+f 15272 15236 15235
+f 14231 15260 15273
+f 11501 14591 14587
+f 14289 14290 10618
+f 14918 15095 14320
+f 10229 10523 8546
+f 14129 12643 7343
+f 6197 3909 10231
+f 9757 6613 9055
+f 12173 12262 12261
+f 4374 4212 4211
+f 5811 2835 2837
+f 5751 15274 15275
+f 13953 15276 15241
+f 15150 15277 15192
+f 15276 15278 15242
+f 15241 15276 15242
+f 15278 10527 10526
+f 15242 15278 10526
+f 1248 7932 15279
+f 3753 2968 9390
+f 13870 15246 15259
+f 14385 13870 15259
+f 11120 14057 12279
+f 12884 13145 14317
+f 14153 14372 14369
+f 11475 14652 11491
+f 7054 7056 4021
+f 14134 3859 10647
+f 11577 14130 11573
+f 15280 15281 15282
+f 10829 11124 11123
+f 10827 14085 10828
+f 14154 15248 15247
+f 13959 14154 15247
+f 15246 14805 14873
+f 15259 15246 14873
+f 15283 15284 15285
+f 15286 15287 2504
+f 14241 14240 15073
+f 14714 15250 13927
+f 14378 13564 15074
+f 13563 15091 15090
+f 13603 11068 2639
+f 11191 2685 3065
+f 12695 12085 12087
+f 13617 12784 11181
+f 12203 13022 12204
+f 13022 11358 12204
+f 14128 13022 12203
+f 12206 14128 12203
+f 12200 10598 12202
+f 13877 14128 12206
+f 11119 3079 3287
+f 12202 13877 12206
+f 14269 11422 15251
+f 12092 14328 10020
+f 15206 12957 12868
+f 11424 12075 14928
+f 14658 14241 15073
+f 15257 12868 12866
+f 13827 13137 11978
+f 15253 15257 12866
+f 12697 14492 12698
+f 14287 15288 12693
+f 15289 14492 12697
+f 12698 14287 12693
+f 12788 15289 12697
+f 14492 14287 12698
+f 15288 13256 12690
+f 12693 15288 12690
+f 15161 13251 13045
+f 15207 15161 13045
+f 12374 14050 15257
+f 11975 15207 15206
+f 12374 15257 15253
+f 10799 12374 15253
+f 12298 12397 15204
+f 12489 14194 14193
+f 13529 13524 13733
+f 13530 13529 13733
+f 12000 12001 12952
+f 13041 12000 12952
+f 9528 10357 10354
+f 2623 2118 2120
+f 9045 9044 9657
+f 7326 12165 2942
+f 12119 12019 10723
+f 11259 12119 10723
+f 14163 13826 13825
+f 14162 14163 13825
+f 14961 13533 15186
+f 5634 13215 14921
+f 15260 14737 14775
+f 15273 15260 14775
+f 14422 13049 15199
+f 13048 15198 15197
+f 14328 11959 12412
+f 13564 13563 15090
+f 6574 670 669
+f 14676 12151 13306
+f 14286 15159 15288
+f 12277 14676 11477
+f 12262 14202 12263
+f 11409 11478 11327
+f 13932 13863 11197
+f 14589 15245 15243
+f 15198 15155 13237
+f 15273 14775 14407
+f 15290 12416 15291
+f 14436 10944 9268
+f 12354 5912 14487
+f 11880 15292 11203
+f 14860 14330 13892
+f 13804 14860 13892
+f 12762 12573 12223
+f 12762 12223 12325
+f 13241 8560 8559
+f 9047 7546 9060
+f 13312 13224 14127
+f 14420 13312 14127
+f 8366 4444 4446
+f 9850 13119 13216
+f 15263 14407 11699
+f 15244 15263 11699
+f 14588 14587 15244
+f 14591 15273 15263
+f 14292 3860 14133
+f 10897 14292 14133
+f 12151 12153 13306
+f 13710 13708 14249
+f 12065 12277 11477
+f 2357 4483 4482
+f 9784 5054 9851
+f 5919 15293 9667
+f 8376 11438 12752
+f 10225 6197 10231
+f 10854 15294 10852
+f 13821 13823 10735
+f 15295 15264 15125
+f 15224 6060 15125
+f 15295 15296 15265
+f 15264 15295 15265
+f 15296 15297 15266
+f 15265 15296 15266
+f 15297 15298 15267
+f 15266 15297 15267
+f 15299 15268 15267
+f 15298 15299 15267
+f 15300 15269 15268
+f 15299 15300 15268
+f 15300 15301 15270
+f 15269 15300 15270
+f 15302 15271 15270
+f 15301 15302 15270
+f 15303 14268 15271
+f 15302 15303 15271
+f 8566 8387 11626
+f 15303 7943 14268
+f 15245 15244 11624
+f 15063 10984 14952
+f 14591 14231 15273
+f 14385 15259 15260
+f 7026 7028 13928
+f 10703 10708 14133
+f 11408 12065 11477
+f 2927 1487 9558
+f 1064 215 7355
+f 9866 7204 8838
+f 6715 9271 6817
+f 3531 2556 2555
+f 6067 13225 6068
+f 8034 10748 8124
+f 6912 4601 11308
+f 14676 13306 11477
+f 14694 5811 5812
+f 15304 15305 15306
+f 15307 15308 15276
+f 13953 15277 13951
+f 15308 15309 15278
+f 15276 15308 15278
+f 15309 10574 10527
+f 15278 15309 10527
+f 15158 14776 14915
+f 12579 14196 14194
+f 13959 15247 15246
+f 13870 13959 15246
+f 6724 8692 12888
+f 12056 12055 12759
+f 4010 8029 6218
+f 10704 14134 10614
+f 10756 14577 14641
+f 6219 4004 6347
+f 12213 12483 12214
+f 14348 10852 15294
+f 14153 12179 14374
+f 2954 5093 3301
+f 6331 5588 14707
+f 14154 14422 15248
+f 14422 15199 15248
+f 15247 14260 14805
+f 15243 15245 10726
+f 11023 1861 1860
+f 13343 15310 15311
+f 14714 14008 14096
+f 14713 14714 14096
+f 13822 14164 13825
+f 14164 14162 13825
+f 8567 8565 14347
+f 4372 15312 14342
+f 11083 5496 9932
+f 12784 12786 11181
+f 10592 15195 14592
+f 15157 15208 15313
+f 3909 2062 10235
+f 10231 3909 10235
+f 15314 714 727
+f 4372 14342 7336
+f 15251 11424 14928
+f 1707 961 12095
+f 15257 15206 12868
+f 10612 14601 14928
+f 15315 15316 15317
+f 15206 15207 12957
+f 12269 13982 15020
+f 11546 3562 3564
+f 14592 12309 12311
+f 6347 6489 6219
+f 2062 2064 10302
+f 12881 12495 12882
+f 14378 12114 13564
+f 13426 13166 12684
+f 13414 13010 12787
+f 15289 12788 12685
+f 15253 12866 12778
+f 12783 13414 12787
+f 15122 13337 13251
+f 12680 15255 12681
+f 14267 13425 13337
+f 15161 15122 13251
+f 15203 13426 13163
+f 15175 15203 13163
+f 12299 12298 15201
+f 12397 14193 15204
+f 13532 13523 13524
+f 13529 13532 13524
+f 11997 12000 13041
+f 13516 11997 13041
+f 8553 15318 1831
+f 10235 2062 10302
+f 12796 1470 1469
+f 7111 8106 8669
+f 12019 12013 10724
+f 10723 12019 10724
+f 11733 12182 11731
+f 13143 13980 11728
+f 15319 5634 14921
+f 11135 13303 13302
+f 8219 9374 15320
+f 1095 1094 877
+f 13049 13048 15197
+f 13979 15155 15198
+f 6471 6995 7139
+f 8556 15321 8554
+f 12179 13595 14374
+f 11073 13923 12375
+f 12283 14917 12284
+f 14592 15313 12305
+f 4079 3872 3294
+f 2064 13950 10383
+f 14807 15156 15155
+f 13979 14807 15155
+f 15263 15273 14407
+f 14719 15195 10592
+f 2503 15286 2504
+f 11265 10975 10977
+f 3118 11903 8449
+f 14793 14187 14792
+f 14330 14331 13893
+f 13892 14330 13893
+f 12950 12762 12325
+f 6808 13037 3628
+f 12663 12756 14173
+f 11077 11989 11078
+f 9519 15322 2139
+f 11720 14811 11729
+f 11020 9850 13216
+f 11310 11396 13981
+f 13557 14244 15157
+f 13672 13557 15157
+f 14587 14591 15263
+f 14807 14333 15156
+f 3123 3667 8370
+f 9047 3285 7004
+f 14137 14824 13498
+f 10302 2064 10383
+f 13241 11083 8560
+f 8561 6427 8563
+f 13950 14037 10454
+f 14119 11212 9853
+f 3657 3700 15063
+f 14057 13922 12264
+f 7019 7055 6312
+f 15323 15295 6297
+f 15295 15125 6297
+f 15324 15296 15295
+f 15323 15324 15295
+f 15325 15297 15296
+f 15324 15325 15296
+f 15326 15298 15297
+f 15325 15326 15297
+f 15326 15327 15299
+f 15298 15326 15299
+f 15328 15300 15299
+f 15327 15328 15299
+f 15329 15301 15300
+f 15328 15329 15300
+f 15330 15302 15301
+f 15329 15330 15301
+f 15331 15303 15302
+f 15330 15331 15302
+f 7942 7943 15303
+f 15331 7942 15303
+f 15332 15333 7931
+f 11315 7749 7942
+f 14231 14385 15260
+f 15154 14333 15120
+f 12798 11784 11971
+f 6072 11482 6070
+f 5454 10629 5452
+f 6032 5923 6167
+f 14999 7355 7357
+f 10383 13950 10454
+f 9858 12398 12494
+f 3834 12210 7436
+f 15334 14283 2224
+f 5192 5191 11880
+f 7052 7149 6843
+f 7844 9039 8937
+f 13157 5063 5888
+f 4367 4535 4368
+f 13953 15307 15276
+f 8963 13771 10093
+f 15335 15336 15308
+f 15307 15335 15308
+f 15336 15337 15309
+f 15308 15336 15309
+f 15337 13463 10574
+f 15309 15337 10574
+f 14389 14390 14916
+f 517 382 4330
+f 7466 5467 7467
+f 14101 13692 13258
+f 10914 10680 13115
+f 9622 9621 10716
+f 14514 9977 9914
+f 8682 8681 10091
+f 6215 11515 6213
+f 14037 13576 10455
+f 9459 9534 9460
+f 9614 2676 11199
+f 9651 760 639
+f 10914 13115 12473
+f 10911 10914 12473
+f 14390 13693 14984
+f 13049 15197 15199
+f 15244 11699 11624
+f 15243 10726 10731
+f 15338 15339 15340
+f 15341 13806 13807
+f 14264 14187 14793
+f 13913 14264 14793
+f 11893 11801 11894
+f 12088 11804 11893
+f 9375 8831 8833
+f 12934 13850 6193
+f 12085 12784 13617
+f 12492 12695 12154
+f 15195 15157 15313
+f 10593 10592 14590
+f 13831 13431 13432
+f 13630 13732 13435
+f 12075 10612 14928
+f 10611 2009 14601
+f 15251 13162 13160
+f 10612 10611 14601
+f 15255 12680 12879
+f 15207 13045 12957
+f 13620 10696 13673
+f 13166 15289 12685
+f 11112 14310 14272
+f 11178 7457 13240
+f 11059 11112 14270
+f 1466 2558 1625
+f 8564 9232 14991
+f 11046 13620 13554
+f 13981 13230 13799
+f 13029 13106 13143
+f 13026 10970 10971
+f 3032 3034 8833
+f 13010 13012 12873
+f 12787 13010 12873
+f 15252 12778 12681
+f 15254 15252 12681
+f 13341 8108 8110
+f 11118 8289 5310
+f 14195 13166 13426
+f 15203 14195 13426
+f 10610 12299 10611
+f 12298 15204 15201
+f 11225 7054 13523
+f 13532 11225 13523
+f 11998 11997 13516
+f 13514 11998 13516
+f 10454 14037 10455
+f 13576 6056 10501
+f 5315 12481 6700
+f 2149 5778 3749
+f 12013 12015 14932
+f 10724 12013 14932
+f 11819 12180 11733
+f 12182 13143 11731
+f 11136 11135 13302
+f 11644 11642 14137
+f 15208 10836 10835
+f 12305 15313 12306
+f 13048 13979 15198
+f 11705 14579 14982
+f 10911 12473 11343
+f 10909 10911 11343
+f 10661 13675 14064
+f 13789 13021 13022
+f 12284 14918 14320
+f 15095 13149 13148
+f 10907 10909 11343
+f 13875 10907 11343
+f 15342 15343 15344
+f 14333 15154 15156
+f 10591 14719 10592
+f 7221 7220 7460
+f 11020 13216 13215
+f 5634 11020 13215
+f 14188 14189 14794
+f 14402 14366 14368
+f 14331 14332 13824
+f 11810 11813 11910
+f 12857 12609 12422
+f 13037 12857 12422
+f 11989 12081 11990
+f 12084 13204 15345
+f 11728 13980 11726
+f 14813 14811 11720
+f 11637 13231 13230
+f 11396 11637 13230
+f 10837 15162 10787
+f 10898 647 10846
+f 14333 14259 15120
+f 14982 14579 14983
+f 10866 10871 14494
+f 10907 13875 14049
+f 10658 14153 14369
+f 11131 14140 11132
+f 8652 11803 12047
+f 1205 6334 6331
+f 5900 5185 5907
+f 15346 15323 6297
+f 11121 11120 12279
+f 15347 15324 15323
+f 15348 15347 15323
+f 15347 15349 15325
+f 15324 15347 15325
+f 15349 15350 15326
+f 15325 15349 15326
+f 15350 15351 15327
+f 15326 15350 15327
+f 15352 15328 15327
+f 15351 15352 15327
+f 15353 15329 15328
+f 15352 15353 15328
+f 15353 15354 15330
+f 15329 15353 15330
+f 15355 15331 15330
+f 15354 15355 15330
+f 15356 7942 15331
+f 15355 15356 15331
+f 7749 11315 7851
+f 15356 11315 7942
+f 14259 14776 15158
+f 3121 10050 3326
+f 13330 13424 11001
+f 15120 14259 15158
+f 4595 4256 3864
+f 10871 14049 14494
+f 3591 5359 3592
+f 8696 1339 1338
+f 3350 3349 13666
+f 6622 10384 10526
+f 1788 9720 1628
+f 9055 6613 5755
+f 13225 9497 14490
+f 2672 3510 3509
+f 499 15357 15358
+f 5053 9851 5054
+f 4204 4368 4537
+f 3231 5209 7018
+f 15359 2654 2504
+f 15360 15361 15336
+f 15335 15360 15336
+f 15361 15362 15337
+f 15336 15361 15337
+f 15362 5444 13463
+f 15337 15362 13463
+f 14915 14389 14916
+f 10594 13104 7033
+f 10866 14494 14493
+f 10864 10866 14493
+f 9581 10564 6013
+f 5153 4577 4576
+f 11063 13699 4895
+f 4895 13699 11277
+f 13699 13873 11277
+f 11277 13873 11276
+f 10856 10860 14742
+f 13873 13874 11276
+f 14916 14390 14984
+f 10455 13576 10501
+f 3467 11197 10791
+f 13693 11704 15002
+f 11197 15243 10731
+f 15245 11624 10726
+f 11163 13120 13119
+f 9850 11163 13119
+f 14163 14165 13829
+f 13826 14163 13829
+f 11894 11802 11897
+f 11802 11807 11897
+f 13614 13703 12107
+f 13603 2639 3659
+f 2426 7566 10559
+f 12086 12085 13617
+f 15195 15313 14592
+f 10593 14590 10740
+f 13732 13831 13432
+f 15052 12404 13431
+f 12956 13044 14009
+f 14102 12956 14009
+f 15122 14267 13337
+f 14266 13161 13425
+f 15255 15254 12681
+f 15256 15255 12879
+f 11183 11182 13141
+f 11872 11183 13141
+f 10601 10600 14199
+f 3891 5229 3894
+f 10971 10674 13681
+f 11045 13620 11046
+f 11112 14271 14270
+f 11045 12678 13620
+f 934 933 2951
+f 14310 10601 14309
+f 9651 639 9652
+f 12260 13155 13835
+f 11698 12585 12873
+f 15363 12275 15364
+f 13012 11698 12873
+f 14298 14297 15365
+f 13338 8110 12594
+f 13338 13341 8110
+f 14198 15289 13166
+f 14195 14198 13166
+f 12417 10610 10612
+f 12299 15201 10611
+f 11229 7218 7122
+f 10872 8559 8563
+f 11993 11998 13514
+f 13518 11993 13514
+f 15366 15367 6058
+f 7341 2356 5009
+f 11420 13305 12574
+f 12761 11420 12574
+f 12015 12190 14595
+f 14932 12015 14595
+f 11738 13579 11819
+f 12180 12182 11733
+f 11641 14263 14824
+f 11642 11641 14824
+f 15313 15208 12306
+f 10785 10830 10786
+f 15008 11705 14982
+f 528 530 4387
+f 10823 10856 11348
+f 10860 13781 14742
+f 10709 10704 10614
+f 13874 11115 11275
+f 14134 10647 10614
+f 10431 14708 10432
+f 1487 2927 14640
+f 9381 10360 10432
+f 7549 7133 2167
+f 7457 5497 5496
+f 11255 13205 13303
+f 11004 13667 11005
+f 11135 11255 13303
+f 11310 13981 13205
+f 8366 4446 11164
+f 11879 13405 15292
+f 12011 11810 11910
+f 11813 11815 11907
+f 12950 12325 12609
+f 12857 12950 12609
+f 15345 15368 12424
+f 8779 10449 10931
+f 11726 14813 11720
+f 12227 13112 13204
+f 11639 11256 13231
+f 11731 13143 11728
+f 2536 11086 2537
+f 11637 11639 13231
+f 15369 12165 7325
+f 10836 15162 10837
+f 10871 10907 14049
+f 14983 13635 14038
+f 10613 10709 10614
+f 10821 10823 13784
+f 13586 13784 10857
+f 9913 9975 9167
+f 9267 9263 9262
+f 10919 3328 3330
+f 1086 4123 4619
+f 15370 15347 15348
+f 15371 15370 15348
+f 15370 15372 15349
+f 15347 15370 15349
+f 15372 15373 15350
+f 15349 15372 15350
+f 15373 15374 15351
+f 15350 15373 15351
+f 15375 15352 15351
+f 15374 15375 15351
+f 15376 15353 15352
+f 15375 15376 15352
+f 15376 15377 15354
+f 15353 15376 15354
+f 15378 15355 15354
+f 15377 15378 15354
+f 15379 15356 15355
+f 15378 15379 15355
+f 11314 11315 15356
+f 15379 11314 15356
+f 4546 8799 8801
+f 15380 6465 14087
+f 14776 14389 14915
+f 15381 15060 10435
+f 10821 13784 13586
+f 10816 10821 13586
+f 14845 15382 15383
+f 13670 12947 13030
+f 13636 14579 14578
+f 3518 3517 3356
+f 12157 14858 10638
+f 10501 6056 10524
+f 15384 3751 769
+f 1888 4631 1889
+f 10230 10229 8545
+f 10523 8781 8546
+f 10560 15385 15386
+f 10020 12094 12092
+f 15387 561 15196
+f 15287 15359 2504
+f 15388 15389 15361
+f 489 15390 8722
+f 15389 15391 15362
+f 15361 15389 15362
+f 15391 5442 5444
+f 15362 15391 5444
+f 3321 3922 3921
+f 14579 13636 13635
+f 10816 13586 13585
+f 10817 10816 13585
+f 15392 389 844
+f 10658 14369 10659
+f 14372 14153 14374
+f 14777 14917 12283
+f 12375 14777 12283
+f 10862 13591 13781
+f 14240 14378 15074
+f 14984 13693 15002
+f 10860 10862 13781
+f 11704 11705 15008
+f 15002 11704 15008
+f 14307 13837 14379
+f 3467 10791 10790
+f 13156 5492 5061
+f 7313 12275 11211
+f 14165 14264 13913
+f 11138 13218 13120
+f 11807 11808 11912
+f 13829 14165 13913
+f 13609 13610 12007
+f 11897 11807 11912
+f 5611 7456 7112
+f 13703 13603 3659
+f 12576 12008 12487
+f 5858 6691 5859
+f 11130 10593 10740
+f 10592 14592 14590
+f 13831 15052 13431
+f 13916 8032 12404
+f 13044 13135 13918
+f 12956 14102 14192
+f 14269 13160 13161
+f 14267 14266 13425
+f 15256 12879 12878
+f 15205 15256 12878
+f 11008 11022 11410
+f 10169 15393 10171
+f 12114 13238 13564
+f 13238 12933 13564
+f 12970 12683 12775
+f 12601 12935 10652
+f 12678 12710 10696
+f 11356 13753 11058
+f 10641 11960 14455
+f 13735 11325 14927
+f 10654 10653 13833
+f 13737 13512 13837
+f 3360 6163 6165
+f 15394 7344 15395
+f 8015 12499 3688
+f 15396 15397 453
+f 13339 12594 12587
+f 13339 13338 12594
+f 14197 14492 15289
+f 14198 14197 15289
+f 11424 12073 12075
+f 12074 12417 10612
+f 13062 13047 10665
+f 11002 11006 11323
+f 11993 13518 13626
+f 11994 11993 13626
+f 13504 13413 12093
+f 15398 14889 14565
+f 11317 11420 12761
+f 12856 11317 12761
+f 12190 12292 13025
+f 10970 10672 10674
+f 11311 13688 11312
+f 13689 14173 11822
+f 11647 14179 14263
+f 11641 11647 14263
+f 5002 5001 5004
+f 8023 4897 4896
+f 10433 10435 15060
+f 13136 12789 12109
+f 3820 4739 5198
+f 5612 5611 9531
+f 12309 14592 12305
+f 7456 7457 6457
+f 9581 14708 9633
+f 11030 11029 15399
+f 5936 5937 5655
+f 14708 9581 6909
+f 11255 11310 13205
+f 10574 13463 4208
+f 6581 10309 3114
+f 11396 13230 13981
+f 3829 3117 3115
+f 12094 15398 13504
+f 11880 11879 15292
+f 4288 4292 4289
+f 11910 11813 11907
+f 11815 11817 11905
+f 13610 12009 12007
+f 13609 12007 12005
+f 1631 1633 15128
+f 14661 14454 14392
+f 12084 12227 13204
+f 1557 1556 1662
+f 13980 14813 11726
+f 12119 11259 13112
+f 11644 14137 11256
+f 13579 12180 11819
+f 15162 10788 10787
+f 11639 11644 11256
+f 4136 13635 4137
+f 4540 12404 8032
+f 10856 14742 11348
+f 14038 4136 15089
+f 13116 4860 13115
+f 11053 11925 11054
+f 4563 14317 4846
+f 4846 14317 13145
+f 727 714 655
+f 5006 5005 5152
+f 15400 15370 15371
+f 15348 15346 12776
+f 15400 15401 15372
+f 15370 15400 15372
+f 15401 15402 15373
+f 15372 15401 15373
+f 15402 15403 15374
+f 15373 15402 15374
+f 15404 15375 15374
+f 15403 15404 15374
+f 15405 15376 15375
+f 15404 15405 15375
+f 15406 15377 15376
+f 15405 15406 15376
+f 15406 15407 15378
+f 15377 15406 15378
+f 15408 15379 15378
+f 15407 15408 15378
+f 15409 11314 15379
+f 15408 15409 15379
+f 10698 2800 10699
+f 15409 12451 11314
+f 12591 12410 11271
+f 11706 11924 4062
+f 10823 11348 13784
+f 6346 6487 6344
+f 10432 14708 6909
+f 11033 13558 11034
+f 7851 12451 7941
+f 14927 11325 13150
+f 14249 13459 11105
+f 12603 1714 1617
+f 3464 11237 3465
+f 10991 11008 11964
+f 3873 4074 3874
+f 4770 2271 2270
+f 10562 8977 10561
+f 6514 4932 4933
+f 15410 15411 15412
+f 15359 15413 2656
+f 15414 15415 15389
+f 15360 15388 15361
+f 15415 15416 15391
+f 15389 15415 15391
+f 7831 5442 15391
+f 15416 7831 15391
+f 10578 8203 8205
+f 962 3323 7541
+f 15417 10806 10808
+f 2851 2850 3057
+f 13860 4919 4918
+f 14320 15095 13148
+f 2654 15359 2656
+f 12361 12360 13723
+f 10864 14493 13591
+f 9777 6300 6299
+f 13375 2960 2959
+f 10862 10864 13591
+f 15418 15419 15420
+f 3655 3205 9117
+f 877 3587 1095
+f 12306 15208 10835
+f 14328 12412 3773
+f 11197 10731 10791
+f 13683 12790 13415
+f 10020 14328 3773
+f 11808 11810 12011
+f 10642 14455 14341
+f 13614 12107 12009
+f 11912 11808 12011
+f 12507 11179 6603
+f 13610 13614 12009
+f 12766 12006 12576
+f 12326 11958 11179
+f 13916 13832 8032
+f 12090 11130 11959
+f 13528 10713 13429
+f 13832 13528 13429
+f 15052 13916 12404
+f 13832 13429 8032
+f 12864 12956 14192
+f 12672 12770 15160
+f 14269 15251 13160
+f 14266 14269 13161
+f 15205 12878 13170
+f 14104 15205 13170
+f 10561 10560 15386
+f 4021 5880 4022
+f 12676 13414 12783
+f 12785 12676 12783
+f 12673 12683 13252
+f 12683 12682 13252
+f 12689 12691 12113
+f 5587 12692 12113
+f 12409 13330 11001
+f 10635 7843 11159
+f 14774 13737 14307
+f 8388 8566 8472
+f 12786 12874 11181
+f 10434 10433 15054
+f 14990 15262 15421
+f 10564 10563 4575
+f 13340 12587 12584
+f 13340 13339 12587
+f 14287 14286 15288
+f 14191 14101 13257
+f 11782 11423 11783
+f 12075 12074 10612
+f 13062 14086 11961
+f 15422 1784 1783
+f 11210 13111 13731
+f 13730 11210 13731
+f 11216 11218 12093
+f 13413 11216 12093
+f 11317 12856 10721
+f 10720 11317 10721
+f 10673 12571 13131
+f 10674 10673 13131
+f 11711 10850 11715
+f 13775 13688 11311
+f 11649 13553 14179
+f 10615 11650 10616
+f 12059 3048 3050
+f 15423 15424 15425
+f 8036 8296 10744
+f 7217 13321 11781
+f 10707 13773 11406
+f 11263 10975 11333
+f 11493 13959 13870
+f 10667 10666 12363
+f 10563 9581 9632
+f 9633 9632 9581
+f 10234 10934 10933
+f 6013 10564 4577
+f 7951 776 775
+f 12210 7437 7436
+f 4446 4445 15290
+f 15426 15427 15428
+f 11916 11908 11820
+f 4097 4290 4098
+f 11907 11815 11905
+f 7126 11820 3185
+f 11817 11820 7126
+f 11905 11817 7126
+f 13608 13609 12005
+f 11804 11801 11893
+f 6828 3522 14429
+f 11794 11796 11307
+f 13305 11418 6231
+f 12574 13305 6231
+f 12227 12119 13112
+f 14595 12190 13025
+f 11312 13689 11822
+f 14173 13579 11738
+f 11642 14824 14137
+f 11647 11649 14179
+f 11025 5666 11026
+f 1615 2335 2334
+f 11428 10681 10683
+f 11964 11077 11075
+f 12465 12568 12567
+f 13933 15429 10582
+f 8112 4413 8113
+f 10807 11665 14874
+f 6299 9778 9777
+f 9060 7546 7545
+f 13292 15400 15430
+f 15430 15400 15371
+f 15431 15401 15400
+f 13292 15431 15400
+f 15431 15432 15402
+f 15401 15431 15402
+f 15432 15433 15403
+f 15402 15432 15403
+f 15434 15404 15403
+f 15433 15434 15403
+f 15435 15405 15404
+f 15434 15435 15404
+f 15436 15406 15405
+f 15435 15436 15405
+f 15436 15437 15407
+f 15406 15436 15407
+f 15438 15408 15407
+f 15437 15438 15407
+f 15439 15409 15408
+f 15438 15439 15408
+f 15440 12451 15409
+f 15439 15440 15409
+f 13934 5638 15441
+f 15440 10748 12451
+f 11331 11428 15010
+f 5093 10933 3692
+f 10752 12362 14344
+f 13714 13711 13787
+f 12070 12064 12066
+f 12285 13492 13873
+f 10926 13958 13977
+f 13669 13668 13848
+f 11985 11830 13558
+f 11058 11060 11357
+f 11963 11008 11410
+f 3105 3301 12497
+f 13683 13415 13684
+f 12609 12507 6602
+f 15442 15443 15143
+f 2661 2171 3207
+f 15444 15445 15415
+f 15388 15446 15414
+f 15445 9710 15416
+f 15415 15445 15416
+f 4703 7831 15416
+f 9710 4703 15416
+f 11336 3999 4205
+f 5721 7929 7928
+f 6946 15447 15448
+f 11327 11426 11427
+f 11570 12365 11568
+f 10808 10807 14874
+f 11398 10705 12055
+f 14131 10752 14344
+f 13708 13457 14249
+f 11573 14985 11349
+f 14677 10903 10843
+f 9387 7736 15449
+f 15311 15310 15450
+f 3049 14525 14524
+f 11163 11138 13120
+f 11136 13302 13218
+f 10622 12373 11800
+f 11138 11136 13218
+f 14059 12470 12472
+f 13634 12052 12051
+f 14064 13611 13607
+f 10661 14064 13607
+f 13882 13878 6815
+f 13703 3659 12107
+f 12265 12668 13641
+f 12507 12326 11179
+f 13527 13427 10713
+f 12008 12010 12487
+f 12397 12489 14193
+f 13528 13527 10713
+f 12489 12579 14194
+f 12672 15160 14196
+f 12579 12672 14196
+f 12770 15121 15160
+f 12864 14192 15121
+f 12770 12864 15121
+f 13162 15251 13164
+f 15251 14928 13164
+f 13069 13700 12972
+f 14011 14104 13170
+f 12782 12492 12600
+f 15364 12275 7313
+f 13667 13298 12782
+f 12676 12785 12694
+f 13252 12682 13330
+f 12682 12779 13330
+f 12691 13060 12113
+f 12699 5586 5585
+f 12495 12494 11892
+f 10795 11874 10796
+f 10091 8681 12268
+f 11003 11005 11874
+f 12215 4839 5002
+f 15451 3104 3103
+f 6299 6298 8123
+f 9850 9784 9851
+f 11697 12584 11698
+f 11697 13340 12584
+f 15159 14191 13256
+f 15288 15159 13256
+f 11974 11970 11972
+f 11423 12073 11424
+f 12490 12771 12773
+f 13047 10663 10665
+f 11173 11661 13637
+f 14450 11173 13637
+f 11217 11129 11218
+f 10670 10591 10671
+f 11749 10722 13036
+f 13392 11749 13036
+f 12571 11621 13132
+f 13131 12571 13132
+f 11715 13775 11311
+f 13688 13689 11312
+f 11736 13680 10616
+f 11735 13670 13680
+f 15413 15452 2839
+f 15450 15217 15218
+f 6833 12929 6832
+f 10657 10659 10902
+f 13457 13459 14249
+f 11580 13049 14422
+f 14201 13676 12263
+f 14202 14201 12263
+f 5087 10563 15173
+f 5088 5087 15173
+f 6580 7730 6581
+f 10563 5087 4575
+f 12017 4477 6059
+f 15429 9379 10583
+f 10582 15429 10583
+f 6057 15366 6058
+f 4284 8754 837
+f 2656 15413 2839
+f 13488 12047 12510
+f 12420 13488 12510
+f 12047 11804 12088
+f 12510 12047 12088
+f 13608 12005 12004
+f 13606 13608 12004
+f 12222 11794 11307
+f 11795 9148 11796
+f 15453 15454 15455
+f 6324 7036 5220
+f 12292 10672 10970
+f 14598 13392 13411
+f 11822 14173 11738
+f 13025 12292 10970
+f 11649 11650 10615
+f 10850 13775 11715
+f 13643 12265 13641
+f 13553 11649 10615
+f 12146 15456 12147
+f 15452 15457 2840
+f 10802 14466 13618
+f 11973 11975 14050
+f 11059 14270 11060
+f 5219 5081 5080
+f 4895 4897 11063
+f 15020 6251 12269
+f 8204 9450 8205
+f 13292 15430 7358
+f 5647 8394 3962
+f 13291 14457 15431
+f 13292 13291 15431
+f 14457 11837 15432
+f 15431 14457 15432
+f 11837 10677 15433
+f 15432 11837 15433
+f 10676 15434 15433
+f 10677 10676 15433
+f 15010 15435 15434
+f 10676 15010 15434
+f 10683 15436 15435
+f 15010 10683 15435
+f 10682 15437 15436
+f 10683 10682 15436
+f 10682 10738 15438
+f 15437 10682 15438
+f 14616 15439 15438
+f 10738 14616 15438
+f 14600 15440 15439
+f 14616 14600 15439
+f 10747 10748 15440
+f 14600 10747 15440
+f 3634 4461 3184
+f 8296 8124 10747
+f 10001 10000 10002
+f 10621 12187 10622
+f 11276 13874 11275
+f 13063 13062 11961
+f 10597 10596 12176
+f 2426 10559 14288
+f 11115 11117 11278
+f 11488 14385 14231
+f 12938 10609 14308
+f 15445 15444 5355
+f 13784 10824 10857
+f 15445 5355 5354
+f 10714 8033 13429
+f 2839 15452 2840
+f 13394 4404 4082
+f 14460 5491 8203
+f 15458 15459 14976
+f 15445 5354 9710
+f 14978 15458 14976
+f 3381 1130 3184
+f 14296 10829 10781
+f 14140 14749 11132
+f 14159 14241 14658
+f 4256 4595 7113
+f 13838 10624 13839
+f 13307 11627 10743
+f 8293 10845 649
+f 10901 10902 14749
+f 10691 11417 11330
+f 11627 8036 10743
+f 3286 9060 11119
+f 13553 10615 10617
+f 11065 11165 10895
+f 13739 13744 10597
+f 11742 11744 13671
+f 11654 11736 10616
+f 11826 11489 11490
+f 11172 11508 11507
+f 11433 11432 13482
+f 13035 10927 12472
+f 14064 10735 13611
+f 10735 10734 13611
+f 13914 13152 10830
+f 3743 8548 2721
+f 9413 15460 15461
+f 15457 15462 3041
+f 10458 6573 14997
+f 14599 14815 14895
+f 9444 9371 15334
+f 2840 15457 3041
+f 15463 15464 15465
+f 15466 1387 15465
+f 15467 15466 15465
+f 13300 1388 15466
+f 15466 1388 1387
+f 15468 15469 15470
+f 15471 927 1276
+f 3520 12296 9930
+f 8279 8280 9991
+f 15472 15473 15474
+f 13462 15475 1170
+f 15123 15210 12063
+f 15476 4452 13474
+f 15210 15476 13474
+f 15477 3732 4452
+f 15476 15477 4452
+f 15478 9711 3732
+f 15477 15478 3732
+f 7469 9712 9711
+f 15478 7469 9711
+f 7468 14939 9712
+f 7469 7468 9712
+f 15479 14942 14939
+f 7468 15479 14939
+f 15480 15481 9064
+f 15482 15483 7571
+f 15475 15484 1171
+f 15485 202 2160
+f 7132 10379 15486
+f 15487 2742 15488
+f 15489 15490 2914
+f 3751 15489 2914
+f 2914 15490 2915
+f 15490 15491 2915
+f 15491 15492 2916
+f 2915 15491 2916
+f 15492 15493 13573
+f 2916 15492 13573
+f 15493 14543 14542
+f 13573 15493 14542
+f 15488 7132 15486
+f 2602 15494 15495
+f 10379 15496 8553
+f 2755 2758 15497
+f 2758 2757 15498
+f 15499 15384 2724
+f 2588 14846 1851
+f 15500 15501 2723
+f 15502 1042 1056
+f 15384 15499 3751
+f 15503 15504 1055
+f 15504 15502 1056
+f 15505 15506 2076
+f 14899 14936 14900
+f 15507 8221 5065
+f 15508 15509 15510
+f 14063 14504 14061
+f 2758 15511 15497
+f 15512 15513 7228
+f 6169 6171 15514
+f 15515 451 14720
+f 15513 7226 7228
+f 15516 15517 25
+f 15518 15519 6517
+f 15520 15521 8847
+f 15456 8847 12147
+f 2580 2602 15495
+f 15520 15522 15523
+f 15153 14051 6336
+f 2755 15497 15494
+f 15521 15520 15523
+f 15524 3195 3041
+f 15522 15525 15526
+f 15523 15522 15526
+f 15525 15527 15464
+f 15526 15525 15464
+f 15528 15529 14544
+f 15530 15531 15532
+f 15533 8046 2456
+f 15534 15535 15536
+f 2580 15495 15537
+f 2601 2580 15537
+f 15538 15467 15464
+f 15539 15540 15541
+f 15527 15538 15464
+f 15542 15466 15467
+f 15538 15542 15467
+f 11695 10959 5535
+f 15542 13300 15466
+f 14937 5744 10839
+f 15543 2619 14093
+f 12296 8279 9991
+f 3346 3154 12103
+f 3752 13664 13666
+f 13286 13373 13645
+f 14702 15544 14522
+f 15545 15546 15547
+f 14934 15548 15549
+f 1671 1673 15550
+f 15551 14545 15552
+f 1491 15553 15554
+f 15555 9997 15556
+f 15504 1056 1055
+f 15557 15558 15559
+f 15560 10024 11285
+f 1352 15561 1055
+f 15562 1270 15563
+f 15564 15565 7469
+f 15262 14990 14991
+f 2787 462 15566
+f 3534 15567 3535
+f 2602 2755 15494
+f 2786 462 2787
+f 14971 8564 14991
+f 15568 8700 8845
+f 304 2099 305
+f 15569 15570 15571
+f 1351 15572 1352
+f 15561 15503 1055
+f 15573 15572 1351
+f 1174 15573 1351
+f 15574 15573 1174
+f 15572 15561 1352
+f 15574 2096 772
+f 2096 15574 1174
+f 15575 15576 771
+f 15576 15574 772
+f 15577 15575 841
+f 15578 15579 15580
+f 15578 15581 15579
+f 15582 15578 15580
+f 15581 15583 15579
+f 12602 15540 12603
+f 14543 15528 14544
+f 15576 772 771
+f 3768 3767 15584
+f 2289 2288 7008
+f 15585 13399 15586
+f 8564 14971 3361
+f 15575 771 841
+f 15587 15588 205
+f 15421 15589 15590
+f 5438 3032 8832
+f 305 2099 15591
+f 15592 15587 15593
+f 15594 15595 15596
+f 4787 5476 15055
+f 6895 10021 5468
+f 15597 15592 15536
+f 15598 15599 15600
+f 15601 15602 15603
+f 15587 205 15593
+f 6426 8222 14383
+f 15604 15605 15606
+f 15607 15608 15609
+f 1780 1781 9718
+f 15610 15611 548
+f 8627 9483 9552
+f 12715 12714 15612
+f 15613 15614 15615
+f 408 15616 9551
+f 15617 14833 15618
+f 4389 15619 15620
+f 15621 15622 15623
+f 15624 15625 15626
+f 12954 15621 15627
+f 4646 1608 15628
+f 15629 15630 15631
+f 15622 15632 15623
+f 2931 15633 12977
+f 12976 2931 12977
+f 15634 15635 15636
+f 24 15637 25
+f 15638 15520 14421
+f 8845 8847 15456
+f 15639 15640 15641
+f 15642 15522 15520
+f 15580 15579 2448
+f 15583 859 2001
+f 15638 15642 15520
+f 15640 15643 15641
+f 15644 15525 15522
+f 15642 15644 15522
+f 15645 15527 15525
+f 15644 15645 15525
+f 15646 3010 3009
+f 15014 15015 15166
+f 13475 15647 12061
+f 13474 4452 13475
+f 10936 10965 15648
+f 15649 3341 3343
+f 15645 15650 15538
+f 15651 15652 15653
+f 15527 15645 15538
+f 15650 15654 15542
+f 15538 15650 15542
+f 15655 5796 7359
+f 2054 4912 7767
+f 10453 677 15656
+f 6189 6726 10206
+f 3346 12103 4132
+f 3153 3346 4132
+f 9317 6053 15657
+f 12497 3692 3694
+f 13849 9808 13871
+f 10583 9379 10947
+f 15658 15659 15660
+f 465 15610 548
+f 15611 15661 602
+f 15662 15658 15660
+f 15663 15664 15665
+f 548 15611 602
+f 15666 15667 15668
+f 15661 15669 766
+f 602 15661 766
+f 15670 796 766
+f 15669 15670 766
+f 15671 975 796
+f 15670 15671 796
+f 7444 1101 1176
+f 15672 4693 4692
+f 15673 15674 15675
+f 5170 11253 7065
+f 15676 15677 15678
+f 15679 15680 15681
+f 15674 15673 982
+f 15682 15683 15684
+f 15685 15686 14872
+f 15616 408 9717
+f 408 410 9717
+f 7029 8883 7030
+f 9483 408 9551
+f 1385 15674 982
+f 15687 1652 1494
+f 15688 15687 1494
+f 15689 1686 1652
+f 1175 7467 3713
+f 15687 15689 1652
+f 3595 15690 4156
+f 9139 12112 15691
+f 15589 15421 15262
+f 1672 952 1673
+f 15692 1692 1686
+f 15689 15692 1686
+f 15592 15593 15536
+f 15693 1762 1692
+f 15692 15693 1692
+f 15693 15694 1883
+f 15695 2976 2975
+f 1762 15693 1883
+f 15696 8882 7451
+f 7551 15697 7133
+f 15698 15699 15700
+f 15701 5744 14937
+f 14432 4723 15633
+f 8882 8884 7451
+f 15694 15702 1973
+f 2583 2582 8995
+f 1883 15694 1973
+f 15702 15703 2094
+f 1973 15702 2094
+f 15703 15704 2154
+f 15705 9310 15706
+f 15707 15708 2582
+f 15709 15701 14937
+f 8662 7330 14696
+f 4452 3734 13475
+f 15710 5745 5744
+f 2094 15703 2154
+f 6536 15711 15712
+f 15704 15713 2249
+f 2154 15704 2249
+f 15713 15714 2309
+f 2249 15713 2309
+f 15714 15715 2453
+f 14832 15514 14833
+f 15716 15717 15718
+f 15719 15624 15626
+f 15720 17 15721
+f 15722 15723 15724
+f 1852 15725 15726
+f 15215 15727 15728
+f 15729 15730 15731
+f 15732 15215 15728
+f 1781 4787 15055
+f 1853 1852 15726
+f 15733 13566 15734
+f 1577 15638 1578
+f 14421 1578 15638
+f 15735 15642 15638
+f 1577 15735 15638
+f 14627 14226 7735
+f 12323 13504 15736
+f 15737 15644 15642
+f 8564 3361 6165
+f 15735 15737 15642
+f 15738 15645 15644
+f 15737 15738 15644
+f 15739 15650 15645
+f 15738 15739 15645
+f 2309 15714 2453
+f 15740 15654 15650
+f 3356 2749 2751
+f 15715 15741 3582
+f 11691 7351 7353
+f 1466 1625 1467
+f 8994 15742 15743
+f 8995 8994 15743
+f 15511 15498 15744
+f 8995 15743 15745
+f 15497 15511 15746
+f 15498 8995 15745
+f 15494 15497 15746
+f 15498 15745 15744
+f 15747 15494 15746
+f 15511 15744 15746
+f 6903 7029 6928
+f 12100 10017 10016
+f 15748 15749 7322
+f 8883 8882 7030
+f 15750 6050 14453
+f 9084 10525 1112
+f 15495 15494 15747
+f 2453 15715 3582
+f 15739 15740 15650
+f 6147 7444 9499
+f 15740 13301 15654
+f 15741 15751 3596
+f 10891 6726 6725
+f 6050 15752 14453
+f 7057 3338 3340
+f 15753 15754 15755
+f 15756 6045 6050
+f 15757 15758 15759
+f 3589 2190 15760
+f 15750 15756 6050
+f 15761 6051 6045
+f 15762 15763 15764
+f 15763 15762 15765
+f 15766 15767 15768
+f 3154 9528 12103
+f 6726 10891 10890
+f 10933 3721 3693
+f 8281 3820 5198
+f 4582 4581 3110
+f 10883 10974 10884
+f 15769 15770 15771
+f 15770 15762 15764
+f 15772 15773 15774
+f 1798 15775 15776
+f 1758 10232 3552
+f 15770 15764 15771
+f 3582 15741 3596
+f 15777 15778 11616
+f 15751 15779 3966
+f 3596 15751 3966
+f 15780 4620 3966
+f 15779 15780 3966
+f 15780 15781 4767
+f 4620 15780 4767
+f 15782 4791 4767
+f 572 574 885
+f 15781 15782 4767
+f 15727 15783 15784
+f 2459 3213 9210
+f 15756 15761 6045
+f 15785 4893 4791
+f 15710 15748 5745
+f 15786 7830 6051
+f 15701 15710 5744
+f 15749 7323 7322
+f 15062 15334 2223
+f 15748 7322 5745
+f 15782 15785 4791
+f 15733 15734 15787
+f 15788 5761 4893
+f 15785 15788 4893
+f 15789 6226 5761
+f 15788 15789 5761
+f 15790 6232 6226
+f 15789 15790 6226
+f 15790 15791 6642
+f 6232 15790 6642
+f 5409 5679 5407
+f 15792 15793 15794
+f 15795 2131 2130
+f 15720 15721 15796
+f 15797 15798 15799
+f 14441 15800 15725
+f 1852 14441 15725
+f 15801 1577 1576
+f 1802 15802 15803
+f 2152 1576 1578
+f 15791 15804 6694
+f 13118 7755 14489
+f 15582 15580 15795
+f 6642 15791 6694
+f 15805 15735 1577
+f 15806 15807 15808
+f 15801 15805 1577
+f 15809 15737 15735
+f 15805 15809 15735
+f 15810 15738 15737
+f 15809 15810 15737
+f 15810 15811 15739
+f 15738 15810 15739
+f 15812 15740 15739
+f 15811 15812 15739
+f 15813 13301 15740
+f 15814 3379 15815
+f 15816 15582 15795
+f 15817 15749 15818
+f 12379 8700 15568
+f 3152 7326 2942
+f 10525 15819 1349
+f 15820 15821 15822
+f 15823 15824 15825
+f 15826 10918 1047
+f 15827 15495 15747
+f 15812 15813 15740
+f 15828 2748 6645
+f 15813 15829 13301
+f 1934 1933 345
+f 15804 15830 6722
+f 6829 14795 7107
+f 15831 15832 15833
+f 6694 15804 6722
+f 6788 11556 6789
+f 15834 15835 15836
+f 15837 15838 15839
+f 12230 12229 15840
+f 11140 15733 11141
+f 15841 15842 12384
+f 1065 14999 14338
+f 6061 11177 15472
+f 15762 15843 15765
+f 8384 7029 6903
+f 3820 4129 4739
+f 2148 385 5779
+f 7230 11690 11691
+f 2714 2910 4288
+f 4129 4131 4739
+f 15844 14852 14851
+f 15845 15846 15847
+f 15830 15604 15848
+f 11067 2670 15849
+f 6722 15830 15848
+f 15462 15524 3041
+f 15850 8857 8859
+f 15851 5501 3195
+f 15852 15853 12541
+f 15854 15855 15548
+f 2145 9827 4100
+f 4778 15856 15857
+f 15858 15859 7473
+f 7472 15858 7473
+f 7449 7451 15860
+f 15861 15559 15862
+f 15761 15786 6051
+f 15825 4312 7830
+f 203 15863 15864
+f 15786 15825 7830
+f 15754 12230 15840
+f 15865 15866 12229
+f 15754 15840 15755
+f 15867 15868 15866
+f 15869 15831 15833
+f 15753 15755 15870
+f 11141 15733 15787
+f 15832 15834 15836
+f 11141 15787 3645
+f 12802 12719 5437
+f 15871 5235 5237
+f 3647 11141 3645
+f 788 787 15872
+f 4388 15873 4389
+f 15535 15597 15536
+f 4775 15874 4781
+f 15875 7760 7473
+f 8668 15535 15534
+f 3011 8668 15534
+f 15859 15875 7473
+f 15876 8381 7760
+f 15875 15876 7760
+f 15877 8578 8381
+f 7247 9388 7650
+f 15876 15877 8381
+f 15825 15824 4312
+f 15878 15879 2791
+f 7030 15696 15880
+f 15824 12829 4312
+f 15881 8655 8578
+f 7030 8882 15696
+f 15877 15881 8578
+f 15079 15882 15883
+f 12665 15884 12666
+f 15885 15886 15887
+f 1889 4798 9082
+f 15888 15889 15890
+f 15891 15892 15893
+f 1495 1653 15894
+f 15895 8863 8655
+f 372 2235 15896
+f 2479 2726 8213
+f 15537 15495 15827
+f 10811 15537 15827
+f 6503 7639 5816
+f 3002 15897 7061
+f 4969 5523 8672
+f 5478 7737 9387
+f 15898 15899 2269
+f 1485 15900 7670
+f 15881 15895 8655
+f 1491 1062 15553
+f 15901 15902 15903
+f 4788 15695 2975
+f 15904 15905 15906
+f 15838 15901 15903
+f 2976 11232 2977
+f 1496 1495 8613
+f 11393 15907 15163
+f 15757 15908 15758
+f 12922 15769 15771
+f 14561 15909 12482
+f 3379 2785 15815
+f 11177 15473 15472
+f 15910 15911 15912
+f 15814 15815 15913
+f 15914 15910 15912
+f 14440 15915 15800
+f 14013 1853 14014
+f 13935 15801 2647
+f 1576 2647 15801
+f 15916 15805 15801
+f 13935 15916 15801
+f 15917 15809 15805
+f 15916 15917 15805
+f 15918 15810 15809
+f 15917 15918 15809
+f 15919 15811 15810
+f 15918 15919 15810
+f 15920 15921 15922
+f 14042 15923 15924
+f 14415 15925 15926
+f 15927 8916 8863
+f 15895 15927 8863
+f 15135 15928 15929
+f 15837 15839 15930
+f 15838 15903 15839
+f 15931 15930 15932
+f 15931 15837 15930
+f 15933 15753 15870
+f 15934 15931 15932
+f 596 9206 10560
+f 15935 15936 15937
+f 15938 15869 15833
+f 15939 15940 15941
+f 15832 15836 15833
+f 9088 595 8977
+f 8977 596 10560
+f 2634 15942 15941
+f 15943 15944 2612
+f 2635 2634 15941
+f 15524 15851 3195
+f 787 15945 15872
+f 15946 15812 15811
+f 12764 15947 15948
+f 15919 15946 15811
+f 15946 15949 15813
+f 15812 15946 15813
+f 15950 9007 8916
+f 15949 15951 15813
+f 4738 10051 3331
+f 3943 4738 3331
+f 3331 10051 3121
+f 15952 15953 15954
+f 15955 15956 15957
+f 14930 11363 15131
+f 15958 15891 15959
+f 10051 10050 3121
+f 4289 6019 5903
+f 4130 4310 4131
+f 1936 2066 5212
+f 15927 15950 8916
+f 15960 9140 9007
+f 15950 15960 9007
+f 15961 9149 9140
+f 15960 15961 9140
+f 15961 15962 9296
+f 9149 15961 9296
+f 15963 15964 15965
+f 15962 15966 9339
+f 15843 15964 15963
+f 9210 9663 8359
+f 15967 5750 5501
+f 12496 14430 11069
+f 15968 15888 15890
+f 15969 10917 10912
+f 15970 1482 15971
+f 979 15972 9192
+f 1222 979 9192
+f 15898 2269 2234
+f 15973 15974 371
+f 15899 2477 2269
+f 15974 15898 2234
+f 9730 4779 9731
+f 9224 2809 3008
+f 15975 15976 15977
+f 15978 6902 6904
+f 9296 15962 9339
+f 7572 15979 7570
+f 15851 15967 5501
+f 6960 15980 15981
+f 5055 9850 5053
+f 15957 15982 15983
+f 15984 15985 15986
+f 15987 396 3393
+f 15988 15453 15989
+f 6745 6744 8650
+f 13957 15990 10973
+f 8132 15991 1802
+f 6378 14625 6376
+f 4099 4100 1208
+f 15460 15992 15461
+f 982 15673 558
+f 15993 15994 15995
+f 9654 15996 9655
+f 15765 15843 15963
+f 15997 15998 15999
+f 15610 16000 16001
+f 15964 15646 15965
+f 16002 16003 10023
+f 16004 16005 16006
+f 2112 6816 16007
+f 16008 16009 16010
+f 16011 451 15515
+f 16012 16013 16014
+f 16015 16010 16016
+f 1853 15726 14014
+f 15519 3809 16017
+f 3435 13935 2646
+f 2153 2645 2647
+f 16018 16019 9195
+f 15169 13489 13488
+f 15907 15291 15163
+f 15061 8810 16020
+f 1671 11713 1672
+f 16021 5532 5531
+f 16022 16023 16024
+f 16025 16022 16024
+f 16026 16027 16028
+f 13323 16029 13324
+f 15343 1179 6615
+f 16030 15314 726
+f 15933 15870 16031
+f 15901 9049 9223
+f 16019 15935 16032
+f 15936 15933 16031
+f 16019 16032 9196
+f 15936 16031 15937
+f 14223 14682 16033
+f 15935 15937 16032
+f 15892 16034 15893
+f 7443 16033 15016
+f 15639 15641 16034
+f 15892 15639 16034
+f 16035 16036 16037
+f 12923 12922 15771
+f 16038 15916 13935
+f 12963 3906 1932
+f 3435 16038 13935
+f 16039 15917 15916
+f 16038 16039 15916
+f 16040 15918 15917
+f 16039 16040 15917
+f 3645 15787 16041
+f 15787 15734 16042
+f 16043 15919 15918
+f 15734 15990 16042
+f 16040 16043 15918
+f 16044 15946 15919
+f 15871 3645 5235
+f 16043 16044 15919
+f 6928 7030 15880
+f 2757 2583 15498
+f 2076 15506 2077
+f 4333 16045 4334
+f 16046 16047 16048
+f 4943 4942 4332
+f 15474 12953 12954
+f 16049 16050 16051
+f 2098 16052 16053
+f 2237 2236 6904
+f 16054 16055 16056
+f 16057 15472 16058
+f 16059 16060 15976
+f 9196 16032 9194
+f 16061 15657 16062
+f 16063 16018 9195
+f 7443 14223 16033
+f 16064 5939 5750
+f 6251 12398 6252
+f 3646 3645 15871
+f 16065 16066 16067
+f 16066 16068 16069
+f 2005 3761 2632
+f 7467 5467 4076
+f 16070 6960 15981
+f 16071 16072 1216
+f 11144 11164 15907
+f 5534 12269 6251
+f 16073 16074 16075
+f 3332 2069 8013
+f 16076 16077 16078
+f 16079 16080 16081
+f 16082 16083 16084
+f 16083 16076 16078
+f 16085 16086 13780
+f 16087 16085 13780
+f 2412 5065 8214
+f 16088 16089 16090
+f 16091 1623 16092
+f 3110 9188 3111
+f 16005 12701 6648
+f 13583 16093 13584
+f 16094 16095 16096
+f 15533 2456 2455
+f 15658 16097 15659
+f 6017 8542 6018
+f 16098 16099 16100
+f 16101 16102 16103
+f 16104 16105 6658
+f 16106 16107 16108
+f 16109 15949 15946
+f 16110 16111 16112
+f 16044 16109 15946
+f 14144 15951 15949
+f 16109 14144 15949
+f 4738 3943 3900
+f 4743 4738 3900
+f 16113 16114 14367
+f 6049 4697 4699
+f 1787 1936 10573
+f 1466 1465 14430
+f 2066 3127 5212
+f 14536 15332 16115
+f 16116 16117 16118
+f 2123 3714 2121
+f 11280 11363 14930
+f 16119 8966 16120
+f 11843 12159 14178
+f 16121 16122 16023
+f 11176 11177 6061
+f 2634 232 15942
+f 16028 2566 8130
+f 7476 3232 16123
+f 16124 16125 16126
+f 16127 16063 16128
+f 16030 726 16129
+f 7754 7753 11392
+f 16130 15736 15398
+f 16131 6906 16132
+f 12050 12597 12221
+f 7031 14565 14566
+f 2891 2890 13375
+f 13565 10987 13566
+f 6349 16133 15019
+f 2268 2267 5528
+f 12383 16134 16135
+f 15925 15061 16020
+f 3585 12271 3586
+f 709 8041 12800
+f 16136 16137 16138
+f 10093 12474 6378
+f 8994 2582 15708
+f 16139 16140 16141
+f 7439 7440 16142
+f 16143 16144 16145
+f 15743 16146 16147
+f 16148 16149 16150
+f 16145 16144 16151
+f 15745 15743 16147
+f 16152 16153 2048
+f 16154 16155 16156
+f 15745 16147 16157
+f 16158 16159 16160
+f 16161 16162 16163
+f 15787 16042 16041
+f 16164 16128 16165
+f 16166 16167 16168
+f 8602 2950 2949
+f 4691 6753 4692
+f 15968 15890 16169
+f 16170 6094 10918
+f 16060 16171 15976
+f 14355 15968 16169
+f 15888 16172 15975
+f 15889 15888 15975
+f 16172 16059 15976
+f 15975 16172 15976
+f 16060 16173 16171
+f 3770 4926 3771
+f 16174 16175 16176
+f 6081 16177 16178
+f 6147 4592 6146
+f 14682 14225 16179
+f 10697 10699 6481
+f 6186 6726 6189
+f 15864 16180 16181
+f 6744 15926 8650
+f 16182 16183 16184
+f 16185 16186 16187
+f 14170 16188 16189
+f 15938 15833 16190
+f 16073 16075 16191
+f 5917 8008 8101
+f 6305 7064 6306
+f 16192 16073 16191
+f 16193 16194 16195
+f 16196 16197 16077
+f 15759 16198 16199
+f 16200 16201 16199
+f 16201 15759 16199
+f 15758 16202 16198
+f 16203 16106 16108
+f 13561 12634 4970
+f 16204 16205 9307
+f 16206 15709 16207
+f 16208 15710 15701
+f 16209 16210 16211
+f 16212 15748 15710
+f 16213 16208 15701
+f 16214 16215 16216
+f 16208 16212 15710
+f 6185 6725 6186
+f 6744 14414 15926
+f 12597 13500 12221
+f 14434 16217 16218
+f 15511 2758 15498
+f 15925 16020 15926
+f 16219 16220 16117
+f 2583 8995 15498
+f 3645 16041 5235
+f 16221 16222 16223
+f 16224 5399 5401
+f 16225 16226 16227
+f 2341 14945 16228
+f 16229 5256 16230
+f 16231 16232 8798
+f 6200 15094 14961
+f 14351 16233 6200
+f 16234 15123 16235
+f 7008 7007 8505
+f 16236 15210 15123
+f 16234 16236 15123
+f 16236 16237 15476
+f 15747 15746 16238
+f 15744 16157 16239
+f 16240 16241 14842
+f 1890 1889 9082
+f 16242 16243 16244
+f 1623 16245 16092
+f 16246 16187 16247
+f 15880 16248 16249
+f 16250 16251 16183
+f 6917 6582 13594
+f 16252 16253 16254
+f 1064 7355 14999
+f 16255 16256 16257
+f 16258 16259 9377
+f 16260 16030 16129
+f 16125 16255 16257
+f 16260 16129 16261
+f 15902 714 15314
+f 1980 16262 16261
+f 16262 16260 16261
+f 3902 9757 9055
+f 16263 1980 16261
+f 14619 7202 9934
+f 6614 14854 2219
+f 15210 16236 15476
+f 16264 16265 16266
+f 8752 9669 13213
+f 5914 5917 8101
+f 204 203 15864
+f 16248 230 233
+f 15743 15742 16146
+f 16267 16268 16269
+f 16237 16270 15477
+f 15827 15747 16271
+f 15476 16237 15477
+f 16272 15478 15477
+f 16270 16272 15477
+f 7470 7469 15565
+f 182 16273 183
+f 16274 16275 16276
+f 13004 16015 16016
+f 16273 16277 16278
+f 3810 6947 3811
+f 4888 4887 16279
+f 16280 16281 15625
+f 16282 16283 16284
+f 15744 15745 16157
+f 16285 15991 8132
+f 16286 16287 16288
+f 6697 7016 6154
+f 16289 10382 16290
+f 4721 5756 4722
+f 16291 14702 14464
+f 6340 11977 16292
+f 10834 3521 5223
+f 6340 16292 16062
+f 6055 6340 16062
+f 7426 7312 7194
+f 11977 16293 16292
+f 16294 5910 16061
+f 2070 4120 2071
+f 5910 16294 5911
+f 15657 6055 16062
+f 2400 2818 5911
+f 5910 15657 16061
+f 16295 16296 16297
+f 16298 16295 16297
+f 8862 9093 16299
+f 291 4769 16300
+f 1980 16263 11186
+f 1981 1980 11186
+f 7316 16301 7317
+f 16302 16303 16304
+f 16305 16306 16307
+f 16308 16309 16310
+f 16192 16191 16311
+f 16074 16081 16075
+f 16076 16196 16077
+f 16312 16313 16314
+f 16315 16194 16316
+f 16195 16200 16199
+f 9703 15825 15786
+f 16317 16318 16319
+f 16213 15701 15709
+f 16206 16213 15709
+f 16320 16225 16227
+f 16321 16206 16207
+f 16322 16323 16324
+f 16325 16320 16326
+f 16327 5663 1960
+f 8965 7633 9303
+f 16328 16329 1054
+f 16330 7464 7463
+f 9656 15550 16331
+f 7570 15979 16332
+f 16315 16316 16333
+f 16212 16208 16334
+f 16069 16315 16333
+f 16194 16193 16316
+f 16197 16335 16336
+f 15891 15893 15959
+f 8832 14155 5438
+f 16335 16197 16337
+f 16077 16197 16336
+f 383 8311 6426
+f 6898 5236 1236
+f 1179 1178 1207
+f 2731 1466 14430
+f 1235 1236 16338
+f 13386 1932 1934
+f 7660 14495 14739
+f 15746 15744 16239
+f 1078 16339 855
+f 3434 2646 8934
+f 16340 16341 16342
+f 5077 15513 16343
+f 16344 16038 3435
+f 10589 16344 3435
+f 10954 10956 16345
+f 16346 16347 16348
+f 16349 16350 16351
+f 16352 15663 15665
+f 16353 15856 4777
+f 16269 16284 16354
+f 16355 7265 14818
+f 16356 16246 16357
+f 16358 16355 14818
+f 13584 16359 16360
+f 16361 16362 16249
+f 16363 16364 16365
+f 16366 16367 16368
+f 14568 16369 6612
+f 16370 16371 16372
+f 16373 16374 16375
+f 16255 16371 16370
+f 11365 14825 16376
+f 16256 16255 16370
+f 16377 16371 16378
+f 16379 16380 16381
+f 16382 16383 16384
+f 16385 16386 16387
+f 11202 16388 16389
+f 16390 16391 16392
+f 2069 2222 8013
+f 16022 16121 16023
+f 16393 16394 4942
+f 8131 16285 8132
+f 16395 16396 16122
+f 16397 16398 16399
+f 15987 16400 16401
+f 15746 16239 16238
+f 16253 16397 16399
+f 16402 16039 16038
+f 15530 16403 16404
+f 16344 16402 16038
+f 16402 16405 16040
+f 16039 16402 16040
+f 16405 16406 16043
+f 16040 16405 16043
+f 16406 16407 16044
+f 16043 16406 16044
+f 2085 16109 16044
+f 16407 2085 16044
+f 2086 1010 2087
+f 2085 2087 16109
+f 4743 3900 3551
+f 4742 4743 3551
+f 11614 11616 16408
+f 5912 5914 14487
+f 5676 16409 5397
+f 1753 16410 16411
+f 16412 16413 16414
+f 16415 16416 16417
+f 16418 16419 16420
+f 16421 16422 2189
+f 16418 16420 16423
+f 2416 5660 5524
+f 16424 16425 16426
+f 16419 16426 16420
+f 16427 16428 16429
+f 16419 16424 16426
+f 16427 16429 11048
+f 16428 16430 16429
+f 16431 16432 16433
+f 16434 11048 16435
+f 16431 16433 16425
+f 16432 16434 16435
+f 16424 16431 16425
+f 16432 16435 16433
+f 16298 16297 16430
+f 16428 16298 16430
+f 16436 16437 16185
+f 16438 16439 16296
+f 16440 16357 16441
+f 574 1944 16442
+f 11791 16443 16444
+f 16383 16445 16384
+f 15723 16305 16307
+f 16446 16440 16441
+f 11187 16447 16448
+f 16449 16450 16451
+f 16452 16311 16453
+f 16452 16192 16311
+f 16196 16454 16455
+f 16197 16196 16455
+f 16220 16269 16456
+f 16194 16200 16195
+f 9781 6754 11160
+f 16317 9703 15786
+f 15816 15795 15879
+f 16457 15816 15879
+f 4162 4161 16458
+f 16457 15879 15878
+f 7438 5350 6829
+f 11479 5380 10968
+f 6706 7928 11146
+f 464 1849 16459
+f 16460 16461 14345
+f 4776 4781 4783
+f 8992 4162 8993
+f 16462 16463 16464
+f 16465 892 16466
+f 4161 15878 16458
+f 16467 16067 16468
+f 16469 16470 16471
+f 9453 16472 9454
+f 16069 16333 16473
+f 15996 16474 4939
+f 8741 8740 15622
+f 16475 12859 16476
+f 8740 15629 15622
+f 10733 11706 4062
+f 16477 16478 16479
+f 16480 16481 16482
+f 1708 8458 16483
+f 9276 10959 10958
+f 16484 16485 16486
+f 6922 6923 16487
+f 2552 3942 2718
+f 16488 16489 16490
+f 16491 16492 16493
+f 16494 9324 16495
+f 16248 7450 230
+f 16496 16497 1602
+f 16386 16385 16498
+f 7862 16499 16500
+f 9705 16501 15823
+f 8914 6893 8915
+f 7450 578 230
+f 16502 16503 16504
+f 10453 15656 16120
+f 16505 16181 15630
+f 15864 15863 13072
+f 15985 3393 15986
+f 16506 16507 15940
+f 16185 16390 16186
+f 16020 8651 8650
+f 15823 9703 9705
+f 579 2077 15939
+f 8100 14536 4081
+f 2798 15934 2799
+f 16508 16373 16375
+f 16509 16325 16510
+f 16511 16512 16513
+f 16514 16515 16374
+f 16512 16516 16517
+f 16516 16518 16517
+f 16516 16519 16518
+f 16519 16520 16518
+f 16521 4889 16522
+f 16523 16524 16520
+f 16306 16305 2590
+f 15967 16064 5750
+f 16525 16526 16527
+f 396 15987 16401
+f 16528 16529 16530
+f 14367 16531 16532
+f 16437 16390 16185
+f 16533 8362 8361
+f 16534 16535 16536
+f 3230 6073 6897
+f 4786 10381 10380
+f 16286 16537 16538
+f 16539 16540 16541
+f 15564 15478 16272
+f 16540 16542 16543
+f 16544 16545 16546
+f 16547 16548 16549
+f 16204 9306 15133
+f 14174 11843 14178
+f 10811 15827 3002
+f 15747 16238 16271
+f 16550 542 10453
+f 14545 14547 15552
+f 16542 182 179
+f 16551 15506 15505
+f 15514 6171 16552
+f 16015 16008 16010
+f 16553 16300 16554
+f 16555 16344 10589
+f 42 15826 1047
+f 15803 15806 15808
+f 16556 16557 16398
+f 15827 16271 3002
+f 6510 7212 11272
+f 16558 16559 16560
+f 16529 16533 8361
+f 5752 16561 4788
+f 16562 13697 13696
+f 16563 8776 8362
+f 2298 9115 289
+f 15905 16564 16565
+f 16566 16567 15841
+f 16568 16569 16570
+f 16567 15842 15841
+f 1077 4160 9670
+f 16570 16569 16566
+f 16569 16567 16566
+f 13780 16086 13261
+f 9115 16571 14313
+f 16572 16568 16570
+f 16573 16568 16572
+f 1856 1855 16574
+f 14313 16573 16572
+f 16553 291 16300
+f 788 15872 4160
+f 1855 1077 9670
+f 10841 11468 220
+f 16285 452 15991
+f 15802 2275 15806
+f 5458 16575 5459
+f 8473 3016 932
+f 12843 8471 12844
+f 16576 16496 1601
+f 16577 16578 16579
+f 16580 16581 16447
+f 16582 16583 16584
+f 16585 16452 16453
+f 16357 16247 16586
+f 16441 16357 16586
+f 16117 16220 16587
+f 16284 16588 16354
+f 2790 8978 16356
+f 373 372 9496
+f 15948 16589 16590
+f 16591 7475 13978
+f 16592 11818 10075
+f 16593 16402 16344
+f 16555 16593 16344
+f 16594 16405 16402
+f 16593 16594 16402
+f 16595 16406 16405
+f 4161 16457 15878
+f 7106 14016 2413
+f 8978 9193 16246
+f 16596 2790 16356
+f 16067 16069 16473
+f 16597 16467 16598
+f 16295 16438 16296
+f 16025 16024 16599
+f 16600 16599 16439
+f 16438 16600 16439
+f 10382 16476 16290
+f 16600 16025 16599
+f 449 16361 233
+f 215 217 2943
+f 16386 16488 16387
+f 2932 568 7032
+f 16601 16602 15995
+f 15937 16603 16604
+f 16605 15551 16521
+f 4784 7332 14649
+f 16606 16607 16608
+f 15474 12954 15627
+f 16594 16595 16405
+f 16609 16407 16406
+f 16595 16609 16406
+f 16610 2085 16407
+f 16611 16612 16613
+f 16614 16615 16616
+f 16617 15539 16618
+f 372 15896 9496
+f 16619 7668 16620
+f 16621 16001 16000
+f 16622 632 634
+f 16623 16624 15479
+f 16625 16334 16208
+f 16001 16626 15611
+f 16627 16091 16628
+f 16629 6491 5939
+f 1980 1979 3220
+f 2798 16630 15931
+f 16077 16336 16631
+f 16078 16077 16631
+f 16632 16312 16314
+f 16187 16186 16247
+f 16186 16633 16247
+f 16634 16635 16636
+f 15890 15889 16637
+f 15610 16001 15611
+f 16638 16639 16640
+f 16626 15562 15661
+f 16519 16523 16520
+f 16641 16642 16643
+f 16644 6922 16645
+f 16508 16375 16646
+f 14368 16532 16647
+f 7829 14368 16647
+f 16533 16563 8362
+f 6533 803 6534
+f 16648 16505 15630
+f 1656 1878 16649
+f 16650 15750 16651
+f 15611 16626 15661
+f 16652 16397 16253
+f 2080 2082 4951
+f 16609 16610 16407
+f 4340 2086 10579
+f 2589 16653 6617
+f 12063 13474 12061
+f 16610 2086 2085
+f 14833 15514 16654
+f 16045 16655 2189
+f 5010 4482 9564
+f 16656 16657 5401
+f 16658 16558 16560
+f 16659 16660 16661
+f 1077 788 4160
+f 16662 16663 1664
+f 15879 2130 2791
+f 4646 15628 16664
+f 15795 15580 2131
+f 16665 9310 15705
+f 16666 16667 16668
+f 16660 16658 16560
+f 15759 15758 16198
+f 15999 15662 16669
+f 16670 16671 8277
+f 3338 9482 3339
+f 3020 14825 16672
+f 9257 16670 8277
+f 226 1776 16673
+f 16674 15938 16675
+f 16400 8133 16676
+f 15834 16677 16678
+f 11392 14022 11393
+f 16679 16680 16681
+f 2272 3014 8861
+f 5060 3434 8934
+f 16458 9091 9090
+f 16458 15878 9091
+f 8860 8862 16299
+f 15878 2791 9091
+f 2138 16682 9346
+f 229 228 16026
+f 3013 9089 8861
+f 8993 16458 9090
+f 16683 2270 16684
+f 3014 3013 8861
+f 2275 2276 15806
+f 2276 351 15807
+f 7562 7541 4098
+f 14299 600 524
+f 15562 16685 15669
+f 15661 15562 15669
+f 8218 9231 10003
+f 3349 3752 13666
+f 11187 16580 16447
+f 16580 16686 16687
+f 16688 16584 16689
+f 16688 16582 16584
+f 2078 2003 327
+f 8857 2462 8858
+f 16117 16587 16690
+f 16269 16354 16456
+f 978 1720 16436
+f 2235 8213 15896
+f 657 238 16691
+f 15579 15583 2001
+f 16692 15670 15669
+f 16693 16694 16695
+f 7662 7664 7737
+f 14567 4745 14568
+f 2943 2761 7356
+f 14804 7928 6706
+f 6061 15472 16057
+f 6705 14804 6706
+f 15621 15623 15627
+f 781 6061 16057
+f 16696 16697 16698
+f 4162 16458 8993
+f 1410 9197 11304
+f 16356 8978 16246
+f 16067 16473 16468
+f 16699 16597 16700
+f 16701 16676 16702
+f 15904 15906 16703
+f 16704 16585 16705
+f 16706 16707 16705
+f 16528 16530 16708
+f 16709 16710 16711
+f 16121 16395 16122
+f 16712 16528 16708
+f 16712 16708 16396
+f 16395 16712 16396
+f 16032 15937 16604
+f 16529 8361 16530
+f 16685 16692 15669
+f 15581 16713 15583
+f 16058 15474 15627
+f 2246 16714 14648
+f 4843 3672 3673
+f 16715 4078 16716
+f 16717 15671 15670
+f 16692 16717 15670
+f 16718 16719 16720
+f 2594 7858 2595
+f 16721 16722 7336
+f 16723 16634 16724
+f 16273 16278 183
+f 15316 15315 16696
+f 16548 16725 16549
+f 16726 16727 16728
+f 8460 8476 16729
+f 12651 16730 16731
+f 16732 16733 9832
+f 16734 16735 16736
+f 401 5060 8934
+f 3281 1485 7670
+f 16737 14880 14882
+f 16738 16739 16740
+f 16717 16718 15671
+f 16741 16742 16743
+f 15640 12921 15643
+f 15473 12953 15474
+f 15934 2798 15931
+f 16630 16744 15837
+f 16745 13322 13324
+f 16746 16747 16748
+f 16713 15973 15583
+f 13405 15007 16749
+f 16070 15981 16750
+f 6961 16628 15980
+f 2270 2272 16684
+f 15000 15974 15973
+f 16751 16752 16753
+f 15833 15836 16754
+f 13574 16755 13575
+f 16756 16757 16758
+f 16759 16508 16646
+f 16760 16723 16761
+f 14568 4747 16369
+f 7829 16647 16762
+f 16064 16629 5939
+f 10204 10353 10205
+f 16763 15211 9454
+f 3700 10984 15063
+f 2653 5659 14706
+f 13370 13368 13454
+f 16764 16765 16766
+f 16767 4648 4647
+f 3769 16555 12274
+f 16768 4647 5966
+f 10589 12274 16555
+f 16769 11869 10962
+f 13130 10962 11870
+f 16770 16771 16330
+f 12196 11870 10854
+f 7637 7238 16772
+f 10847 1768 1808
+f 15985 15987 3393
+f 2399 2998 2400
+f 16628 16091 16773
+f 16774 11303 11233
+f 16775 16776 16650
+f 16628 16773 16777
+f 16776 15756 15750
+f 16317 15786 15761
+f 3713 4076 3714
+f 16318 15761 15756
+f 16750 16778 16202
+f 16318 16776 16779
+f 16671 16087 13780
+f 15758 16750 16202
+f 16780 16781 16782
+f 8277 16671 13780
+f 16783 1751 16784
+f 16564 16785 16565
+f 15674 16786 15675
+f 5965 16768 5966
+f 16687 16787 16788
+f 16789 15687 15688
+f 16687 16788 16790
+f 16581 16687 16790
+f 16791 16792 16793
+f 16794 14211 16787
+f 16795 14743 3208
+f 4715 3815 2905
+f 15018 15333 15332
+f 14535 15018 15332
+f 16796 16797 7439
+f 14536 14535 15332
+f 16798 16799 16800
+f 12888 4081 9048
+f 16581 16790 16801
+f 16447 16581 16801
+f 184 16802 180
+f 16803 16804 16805
+f 15688 1494 16806
+f 1089 16807 16808
+f 2105 3379 15814
+f 16809 15689 15687
+f 14022 11144 11393
+f 16258 9377 15429
+f 16789 16809 15687
+f 15630 16181 16810
+f 16811 16689 16812
+f 16811 16688 16689
+f 442 16813 448
+f 16814 571 12384
+f 16118 16117 16690
+f 16220 16456 16587
+f 16118 16690 16815
+f 16816 16118 16815
+f 978 16436 15972
+f 16816 16815 16817
+f 16818 16819 16820
+f 15974 2234 371
+f 16821 16822 16823
+f 16824 16825 16826
+f 15472 15474 16058
+f 16827 1539 16828
+f 3604 9224 3008
+f 12112 16829 15691
+f 11303 13687 11304
+f 12860 9453 9455
+f 13687 13686 11304
+f 16830 16831 16832
+f 13686 1410 11304
+f 16775 16650 16833
+f 16467 16468 16598
+f 16699 16700 16834
+f 15601 16835 16836
+f 16837 16526 16525
+f 16585 16453 16705
+f 16838 16839 16706
+f 16840 16841 16842
+f 2066 2067 3124
+f 15723 15722 8958
+f 8959 16843 16844
+f 16845 15692 15689
+f 7235 14998 16846
+f 14533 15368 15345
+f 16847 15838 15837
+f 15908 16070 16750
+f 15908 16750 15758
+f 16809 16845 15689
+f 16848 15609 16849
+f 3870 6059 4477
+f 15486 10379 8553
+f 16850 16593 16555
+f 3769 16850 16555
+f 16851 16594 16593
+f 16850 16851 16593
+f 16852 16595 16594
+f 16851 16852 16594
+f 16853 16609 16595
+f 16852 16853 16595
+f 16853 10580 16610
+f 16609 16853 16610
+f 4340 10579 10581
+f 16610 10580 2086
+f 9041 10932 9043
+f 6024 2220 2060
+f 12012 8456 9529
+f 5010 2357 4482
+f 12322 13412 12323
+f 10854 12194 12196
+f 16854 16760 16855
+f 6042 9154 16130
+f 13924 16856 14535
+f 15931 16630 15837
+f 3740 6184 3741
+f 15191 15135 3006
+f 14565 16130 15398
+f 15019 15035 12117
+f 16857 16858 8047
+f 16062 16292 16847
+f 9050 1212 4633
+f 16744 16061 16847
+f 16292 16859 16847
+f 16061 16744 16630
+f 16294 16061 16630
+f 16860 9730 9732
+f 16061 16062 16847
+f 16861 16854 16862
+f 16863 16864 2385
+f 4747 7829 16762
+f 8836 5512 3896
+f 13590 14568 6612
+f 4747 16762 16369
+f 15996 4939 9655
+f 14247 14246 16865
+f 6641 6699 1175
+f 4410 11988 4412
+f 16866 15693 15692
+f 16357 16246 16247
+f 16867 16660 16560
+f 16845 16866 15692
+f 15657 6053 6055
+f 16287 16868 16288
+f 10833 10832 2419
+f 16869 15294 11869
+f 10961 16870 16769
+f 16871 11139 11141
+f 11869 15294 10854
+f 4308 16872 9257
+f 16873 16180 13040
+f 8777 16874 4308
+f 16872 16670 9257
+f 16874 8777 8776
+f 16563 16874 8776
+f 15980 16628 16777
+f 16874 16872 4308
+f 15981 15980 16875
+f 16091 16092 16773
+f 15981 16875 16778
+f 16750 15981 16778
+f 16876 16877 14740
+f 15980 16777 16875
+f 16074 16079 16081
+f 16082 16084 16878
+f 16807 16879 16808
+f 16880 16780 16782
+f 9795 16881 16882
+f 16883 16302 16884
+f 16885 16165 16886
+f 8963 2989 13771
+f 16887 3051 16888
+f 15622 15629 15632
+f 16889 16890 16891
+f 15017 16892 16893
+f 16179 16894 16895
+f 16896 16897 4809
+f 4808 16896 4809
+f 16898 16899 16897
+f 16896 16898 16897
+f 16900 16901 16899
+f 16898 16900 16899
+f 16902 16903 16901
+f 16904 16905 16906
+f 16900 16902 16901
+f 16907 16904 16906
+f 16908 16909 16905
+f 44 43 16910
+f 7636 3696 3695
+f 16911 8140 2609
+f 16544 16601 15995
+f 16912 16913 16914
+f 8811 11805 8809
+f 16915 16391 16390
+f 3001 7237 16916
+f 9046 16917 538
+f 16169 15890 16918
+f 16919 16920 16519
+f 16921 16811 16812
+f 15550 1673 2195
+f 15856 4778 4777
+f 13072 15863 13038
+f 571 12385 12384
+f 1318 6617 2243
+f 16478 16360 16353
+f 15868 16816 16817
+f 8752 13213 13038
+f 15973 371 859
+f 12229 15866 11047
+f 8859 8858 16922
+f 9732 10025 16655
+f 1062 14338 15553
+f 1608 1491 15554
+f 16031 16923 16603
+f 9454 15213 16924
+f 15755 15840 16925
+f 15937 16031 16603
+f 15840 12229 11049
+f 15866 16926 11047
+f 16283 16834 16588
+f 16284 16283 16588
+f 16283 16699 16834
+f 16597 16598 16700
+f 16927 15869 15938
+f 16928 16929 16930
+f 16707 16704 16705
+f 16931 16932 16838
+f 16933 16934 16134
+f 16581 16580 16687
+f 16935 16936 16937
+f 1485 1487 14640
+f 9196 9195 16019
+f 6196 3907 6197
+f 16744 16847 15837
+f 15994 16544 15995
+f 15842 16814 12384
+f 16859 15901 15838
+f 2180 2179 9687
+f 2949 16169 8602
+f 13551 14288 10559
+f 13336 10958 12504
+f 10832 15062 2248
+f 16938 8216 454
+f 1747 7651 7650
+f 9655 4939 4941
+f 16939 16940 16941
+f 1116 6898 1236
+f 16942 16943 16944
+f 16945 16946 16947
+f 16948 16949 16816
+f 16950 16951 16952
+f 16953 16954 15888
+f 16955 11321 14250
+f 16956 16173 16060
+f 16957 16956 16060
+f 15909 14561 16958
+f 16959 16054 16056
+f 15212 15656 676
+f 16960 16961 16962
+f 16292 16293 16859
+f 12829 12941 4313
+f 838 529 11321
+f 14546 16963 9654
+f 14415 1118 15925
+f 16605 16521 893
+f 1117 16964 15925
+f 16964 15061 15925
+f 5911 16294 2798
+f 3860 14292 4843
+f 16864 16965 3907
+f 6196 16864 3907
+f 11393 11144 15907
+f 16966 16596 15905
+f 8778 9037 16582
+f 16967 4307 16932
+f 9037 4307 16967
+f 16968 9037 16967
+f 16969 3577 3576
+f 16970 16971 16972
+f 14040 16973 14039
+f 16294 16630 2798
+f 16855 16760 16761
+f 15968 16953 15888
+f 16974 16975 16365
+f 16949 16118 16816
+f 16976 16726 16728
+f 16977 16978 16727
+f 16979 14348 15294
+f 16980 16869 16769
+f 13382 7042 13295
+f 7038 13295 7042
+f 7038 7042 6933
+f 12175 10852 10303
+f 16981 16982 14376
+f 8452 14795 3658
+f 16781 16983 16984
+f 16985 16562 13696
+f 16986 16876 13259
+f 16877 16878 14740
+f 16986 13259 16086
+f 16085 16986 16086
+f 16877 16082 16878
+f 16876 14740 13259
+f 16780 16880 16080
+f 16083 16078 16084
+f 7356 2761 15899
+f 16079 16780 16080
+f 2761 8039 15899
+f 8781 7327 3528
+f 7356 15899 15898
+f 14313 16572 290
+f 7357 15898 15974
+f 7357 7356 15898
+f 16987 16988 16989
+f 15000 7357 15974
+f 12454 12545 16990
+f 16713 15000 15973
+f 2316 2315 5257
+f 16991 5666 5667
+f 3013 8993 9089
+f 16992 8557 6491
+f 8993 9090 9089
+f 16629 16992 6491
+f 228 226 16673
+f 3365 12454 16990
+f 16993 16994 16903
+f 16902 16993 16903
+f 16995 16996 16997
+f 16646 16998 16994
+f 16907 16906 16999
+f 16996 16907 16999
+f 17000 17001 17002
+f 16884 16304 9412
+f 2132 2450 17003
+f 2002 1558 13678
+f 225 17004 1776
+f 16437 16915 16390
+f 8602 16169 16918
+f 10380 10382 16289
+f 16921 16812 16523
+f 16920 16921 16523
+f 17005 16919 16516
+f 16920 16523 16519
+f 17006 17005 16512
+f 16919 16519 16516
+f 17007 17008 17009
+f 17006 16512 16511
+f 423 17010 4644
+f 14321 704 4644
+f 15868 16817 16926
+f 15866 15868 16926
+f 15870 15755 17011
+f 15840 11049 16925
+f 15870 17011 16923
+f 16031 15870 16923
+f 568 567 2237
+f 15755 16925 17011
+f 16648 15630 15629
+f 8740 16648 15629
+f 14423 17012 15777
+f 17013 17014 17015
+f 16246 9193 16187
+f 17016 16361 449
+f 9193 17017 16187
+f 2003 2005 327
+f 1801 1803 16526
+f 14870 17018 17019
+f 16839 16707 16706
+f 16967 16932 16931
+f 17020 16787 16687
+f 16686 17020 16687
+f 17021 17022 17023
+f 17024 17021 17023
+f 16373 16514 16374
+f 17025 17026 16515
+f 16918 15890 16637
+f 15889 15975 15977
+f 16847 16859 15838
+f 16293 9050 9049
+f 2638 15016 1379
+f 1379 16856 1377
+f 15826 16170 10918
+f 15888 16954 16172
+f 16164 16165 17027
+f 6350 6349 12117
+f 5730 5729 12274
+f 17028 16548 17029
+f 17030 16850 3769
+f 3771 17030 3769
+f 17031 16851 16850
+f 17030 17031 16850
+f 17032 16852 16851
+f 17031 17032 16851
+f 17033 16853 16852
+f 17032 17033 16852
+f 17034 10580 16853
+f 17033 17034 16853
+f 16042 15168 17035
+f 16042 15990 15168
+f 16041 16042 17035
+f 13204 14533 15345
+f 1465 3357 14118
+f 2437 17036 17037
+f 8474 12324 9154
+f 1653 17038 15894
+f 9482 9481 17039
+f 17040 14964 17041
+f 16866 17042 15694
+f 17043 15958 17044
+f 11885 14510 11883
+f 16761 16723 16724
+f 16041 17035 16338
+f 5235 16041 16338
+f 16862 16854 16855
+f 1236 5235 16338
+f 16964 14554 15061
+f 15537 10811 3004
+f 15693 16866 15694
+f 3945 4134 3946
+f 554 17045 17010
+f 17046 17047 17048
+f 17042 17049 15702
+f 15694 17042 15702
+f 4309 8276 16839
+f 4307 4309 16932
+f 16392 17050 16633
+f 15926 16020 8650
+f 423 554 17010
+f 8742 8752 13038
+f 16954 17051 16172
+f 16125 16257 16126
+f 17052 17053 17054
+f 16164 16962 17055
+f 16250 16183 16182
+f 17034 10581 10580
+f 17056 17057 14348
+f 16980 16979 16869
+f 17057 10305 10304
+f 14348 17057 10304
+f 8722 17058 17059
+f 17058 17060 17059
+f 17061 17062 17063
+f 8453 3658 3657
+f 16782 16781 16984
+f 17064 17065 11388
+f 13697 16136 13698
+f 16984 16983 17066
+f 17067 17068 17069
+f 16675 15938 16190
+f 16983 17067 17070
+f 16183 15904 16703
+f 16527 16674 16675
+f 16837 1801 16526
+f 3624 15551 16605
+f 17017 16185 16187
+f 1803 16927 16674
+f 17071 5752 5753
+f 16390 16392 16186
+f 231 579 15942
+f 16391 8130 16392
+f 3761 1075 2988
+f 579 15939 15942
+f 4769 2270 16300
+f 2632 3761 2988
+f 17072 17073 214
+f 2270 16683 16300
+f 571 1856 12385
+f 12059 3050 17074
+f 4940 11713 1671
+f 1855 9670 16574
+f 3624 17075 15551
+f 225 452 16285
+f 16678 8860 16299
+f 16401 16400 16676
+f 9093 17076 16299
+f 16993 16646 16994
+f 16027 17077 2566
+f 17078 16995 17079
+f 16375 17080 16998
+f 17078 17079 17081
+f 16996 16999 16997
+f 17082 17083 17084
+f 17083 17078 17081
+f 228 16673 16026
+f 226 225 1776
+f 8130 2568 17050
+f 16084 17085 17086
+f 16084 16078 17085
+f 16878 16084 17086
+f 16078 16631 17085
+f 12859 12858 16290
+f 13806 2306 2308
+f 10963 17087 10961
+f 17008 17006 16511
+f 17005 16516 16512
+f 778 17088 17045
+f 17089 17007 17090
+f 17043 17044 17088
+f 554 778 17045
+f 2161 16505 16648
+f 778 17043 17088
+f 1172 16648 8740
+f 5679 17091 5680
+f 14368 14367 16532
+f 1172 2161 16648
+f 17092 17089 17025
+f 16114 16759 16531
+f 17092 17025 16514
+f 17007 17009 17090
+f 17093 17092 16514
+f 17089 17090 17025
+f 16968 17094 16583
+f 16582 16968 16583
+f 16967 17095 17094
+f 16968 16967 17094
+f 17095 16967 16931
+f 16932 16839 16838
+f 726 728 17096
+f 17020 17096 16787
+f 16126 17097 17022
+f 2227 7236 17098
+f 16514 17025 16515
+f 17024 17023 17099
+f 15629 15631 15632
+f 17090 17100 17026
+f 16859 9049 15901
+f 16249 16248 233
+f 8449 11903 12963
+f 17101 17102 16848
+f 17051 17103 16059
+f 7235 16846 7236
+f 17104 17105 7236
+f 16172 17051 16059
+f 8780 10931 9707
+f 12499 2596 12500
+f 13862 10782 15053
+f 17106 8962 8557
+f 2931 14432 15633
+f 8284 2421 2420
+f 8021 8284 2420
+f 15993 15995 17104
+f 17107 17108 17109
+f 16962 16164 17027
+f 17110 16939 16941
+f 15044 15045 15116
+f 4640 16592 12378
+f 16726 16977 16727
+f 9499 7759 4592
+f 7065 11253 2645
+f 16239 17111 17112
+f 17111 16239 17113
+f 16541 16543 17114
+f 16238 16239 17112
+f 3704 8741 15621
+f 6710 3356 2751
+f 17115 17116 17117
+f 2161 204 16505
+f 17118 2003 2078
+f 17119 17120 17121
+f 1118 1117 15925
+f 5716 7919 7534
+f 16238 17112 17122
+f 16271 16238 17122
+f 17123 17124 17125
+f 17126 17030 3771
+f 3002 16271 17122
+f 4927 17126 3771
+f 5907 7328 5908
+f 15897 3002 17122
+f 738 740 1115
+f 2897 17127 2895
+f 16092 16083 16082
+f 9206 9207 15385
+f 16875 16777 16876
+f 16773 16092 16082
+f 16773 16082 16877
+f 16777 16773 16877
+f 9669 13249 13213
+f 17049 17128 15703
+f 5052 3941 2551
+f 17129 17130 17131
+f 15587 15084 15588
+f 7061 10505 7062
+f 17132 17031 17030
+f 17126 17132 17030
+f 17133 17134 17057
+f 17056 16979 17135
+f 17134 17136 10305
+f 17057 17134 10305
+f 17136 15368 15200
+f 10305 17136 15200
+f 11280 2312 2311
+f 2534 4084 13525
+f 4941 4940 1671
+f 15702 17049 15703
+f 16598 16468 16528
+f 15905 16565 15906
+f 16700 16598 16712
+f 16473 16533 16529
+f 16588 16834 16121
+f 16468 16529 16528
+f 16354 16588 16022
+f 16700 16712 16395
+f 16456 16354 16025
+f 16834 16395 16121
+f 16587 16456 16600
+f 16588 16121 16022
+f 16690 16587 16438
+f 16354 16022 16025
+f 16815 16690 16295
+f 16456 16025 16600
+f 16817 16815 16298
+f 16587 16600 16438
+f 16926 16817 16428
+f 16690 16438 16295
+f 16926 16428 16427
+f 16815 16295 16298
+f 11047 16926 16427
+f 16817 16298 16428
+f 2891 13375 2959
+f 17137 4942 4944
+f 14547 9656 16331
+f 10718 6690 9948
+f 2456 8047 17138
+f 17139 17140 16709
+f 8133 1801 16837
+f 8958 8960 17141
+f 16646 16375 16998
+f 16391 16028 8130
+f 16374 17142 17080
+f 16375 16374 17080
+f 17100 17143 17144
+f 17026 17100 17144
+f 1449 577 16915
+f 229 16026 17145
+f 2450 17146 17003
+f 577 17145 16915
+f 17147 3603 15874
+f 577 229 17145
+f 17148 2457 17149
+f 2618 2132 17150
+f 17151 17152 17153
+f 16170 16976 6094
+f 17154 15994 15993
+f 2052 2054 7766
+f 17008 16511 17009
+f 15630 16810 15631
+f 17093 16514 16373
+f 17155 17093 16373
+f 17155 16373 16508
+f 17156 17155 16508
+f 14367 16114 16531
+f 17156 16508 16759
+f 16532 16902 16900
+f 16114 17156 16759
+f 16369 16762 16896
+f 16647 16900 16898
+f 6612 16369 4808
+f 16762 16647 16898
+f 13349 6425 7954
+f 16762 16898 16896
+f 16259 11268 9377
+f 9387 15449 10590
+f 1315 5908 3743
+f 16892 16179 16895
+f 17157 17104 16602
+f 16846 17154 15993
+f 17158 17159 17160
+f 6997 12084 15345
+f 16917 12711 539
+f 8013 2222 7922
+f 17161 17024 17099
+f 410 1780 9718
+f 17025 17090 17026
+f 17161 17099 17162
+f 1104 1103 16959
+f 17009 17163 17100
+f 7830 4312 4314
+f 17164 17165 16476
+f 14721 158 153
+f 16575 17166 17167
+f 16957 16060 16059
+f 15624 16280 15625
+f 10833 2419 2421
+f 17103 16957 16059
+f 17168 17032 17031
+f 2596 2554 12500
+f 17132 17168 17031
+f 17169 17033 17032
+f 17168 17169 17032
+f 17169 17170 17034
+f 17033 17169 17034
+f 16939 17110 17171
+f 14583 10581 17034
+f 17170 14583 17034
+f 13393 8780 9707
+f 9526 8723 718
+f 10151 2742 15487
+f 10931 10932 9041
+f 8284 10833 2421
+f 6050 6047 15752
+f 14924 14670 13944
+f 10832 2392 2419
+f 16239 16157 17113
+f 17128 17172 15704
+f 2750 8454 2751
+f 17173 17174 17175
+f 2468 2644 2643
+f 15958 15959 17044
+f 16674 16927 15938
+f 4334 16045 2189
+f 17176 17177 17178
+f 17179 17180 17181
+f 15703 17128 15704
+f 17172 17182 15713
+f 17183 16509 16510
+f 17184 16226 17185
+f 10075 8699 12379
+f 15704 17172 15713
+f 10022 16002 10023
+f 9087 17186 17187
+f 16714 2246 15127
+f 17188 17129 17189
+f 17190 16206 16321
+f 2933 2932 16362
+f 6928 15880 17191
+f 16778 16875 16986
+f 16777 16877 16876
+f 2462 8871 16829
+f 12859 9453 12860
+f 16951 17192 16952
+f 17193 7058 17194
+f 17195 2917 2919
+f 17196 11413 15924
+f 13058 1276 4923
+f 13418 4785 14006
+f 17197 17198 9568
+f 13054 13056 17134
+f 17135 17133 17056
+f 13056 17199 17136
+f 17134 13056 17136
+f 17199 12424 15368
+f 17136 17199 15368
+f 13738 15200 14533
+f 16992 17106 8557
+f 16834 16700 16395
+f 11332 13212 10656
+f 15568 8845 15456
+f 16598 16528 16712
+f 17200 17201 8373
+f 8832 8831 12865
+f 17202 17200 8373
+f 1065 1064 14999
+f 4843 3673 3858
+f 3860 4843 3858
+f 3130 11633 17203
+f 8695 11415 11113
+f 16268 16284 16269
+f 15125 15223 15224
+f 16116 16219 16117
+f 16267 16269 16220
+f 9475 8966 16119
+f 5534 9858 17204
+f 17205 17206 16201
+f 17207 16194 16315
+f 16180 15864 13072
+f 13249 9669 13418
+f 16171 8665 17208
+f 17209 15508 15510
+f 16925 16432 16431
+f 11049 16434 16432
+f 16603 16923 16419
+f 17011 16925 16431
+f 17011 16431 16424
+f 16923 17011 16424
+f 203 2606 15863
+f 2991 8957 5865
+f 10919 3330 15915
+f 16226 17184 16227
+f 16380 3020 16672
+f 17210 17211 17212
+f 17213 17214 17215
+f 16384 16445 16985
+f 17100 17163 17143
+f 17163 16094 17143
+f 16513 17216 16094
+f 17163 16513 16094
+f 17217 17218 17219
+f 17216 17220 17219
+f 17221 16217 5164
+f 17001 17222 17223
+f 2232 4627 4629
+f 5753 4788 4789
+f 2590 16305 16450
+f 16251 15904 16183
+f 17224 16307 17225
+f 14547 9654 9656
+f 3520 9930 9848
+f 6367 17226 5975
+f 17038 1653 10090
+f 16369 16896 4808
+f 16531 16993 16902
+f 16647 16532 16900
+f 16759 16646 16993
+f 16532 16531 16902
+f 17021 16126 17022
+f 16531 16759 16993
+f 3968 2911 11228
+f 16257 17227 17097
+f 17228 16370 17229
+f 3050 14524 14931
+f 17230 17231 6139
+f 16371 16377 16372
+f 15386 15385 16382
+f 2263 9088 10577
+f 17004 17232 1777
+f 1776 17004 1777
+f 15991 2301 15802
+f 17004 16285 8131
+f 3831 9153 3905
+f 3904 3831 3905
+f 14941 15371 12776
+f 15348 15323 15346
+f 1851 1347 1852
+f 17182 17233 15714
+f 17234 17161 17162
+f 7564 1118 14415
+f 17090 17009 17100
+f 17234 17162 17235
+f 17165 16475 16476
+f 16511 16513 17163
+f 2765 17236 17237
+f 11444 11367 11366
+f 3221 2401 2799
+f 9154 12324 15736
+f 15345 12424 6997
+f 16636 16635 17238
+f 15708 17239 15742
+f 11164 4446 15290
+f 16146 17036 17240
+f 3948 6022 6024
+f 16147 17240 17113
+f 16147 16146 17240
+f 17241 17242 17243
+f 16157 16147 17113
+f 17244 17245 17246
+f 15213 676 16924
+f 5048 16978 9533
+f 17247 17126 4927
+f 3548 17247 4927
+f 17248 17132 17126
+f 17247 17248 17126
+f 17249 17168 17132
+f 17248 17249 17132
+f 16724 16634 16636
+f 4785 4786 14006
+f 17250 16358 17251
+f 17252 17253 17254
+f 8741 15622 15621
+f 16361 16249 233
+f 11233 11232 17255
+f 11252 8778 16688
+f 17256 17252 17254
+f 5211 5210 11221
+f 15713 17182 15714
+f 15999 15998 15662
+f 17249 17257 17169
+f 17258 17259 17260
+f 17168 17249 17169
+f 17257 17261 17170
+f 15879 15795 2130
+f 17169 17257 17170
+f 1720 16437 16436
+f 17167 10519 16575
+f 7032 6929 17191
+f 2760 2759 2933
+f 16202 16778 16085
+f 16875 16876 16986
+f 16476 12859 16290
+f 1856 16574 12385
+f 17106 17262 9354
+f 217 2759 2943
+f 15545 17263 17264
+f 17265 17266 17267
+f 659 17268 3772
+f 17269 16683 16677
+f 17261 17270 14583
+f 17170 17261 14583
+f 13055 17271 13056
+f 17272 13054 17133
+f 17271 17273 17199
+f 13056 17271 17199
+f 17273 12425 12424
+f 17199 17273 12424
+f 14499 10252 14786
+f 13504 15398 15736
+f 14464 14462 16291
+f 16925 11049 16432
+f 17268 17118 3772
+f 3737 6162 13765
+f 1349 15819 1600
+f 16677 16684 8860
+f 2108 10525 1349
+f 1600 17274 659
+f 17275 17276 17277
+f 17274 17268 659
+f 17278 17279 17280
+f 15819 17274 1600
+f 2844 17281 5549
+f 17282 17283 17284
+f 17285 14839 17286
+f 17276 16221 17277
+f 17075 17287 14545
+f 17288 10310 17289
+f 16120 9303 7633
+f 16112 14839 17285
+f 17290 15479 7468
+f 12541 17291 12542
+f 16856 1379 14535
+f 1379 15018 14535
+f 17292 17293 16127
+f 8392 14817 17294
+f 17295 3157 3156
+f 7348 7542 3508
+f 16475 16472 12859
+f 17296 17297 17298
+f 16472 16763 9454
+f 9946 5930 10049
+f 9136 2348 15012
+f 1936 5212 10573
+f 6897 9516 5237
+f 2731 14430 12496
+f 16782 16984 16255
+f 16255 16984 16371
+f 16125 16782 16255
+f 16984 17066 16371
+f 16513 16517 17216
+f 16517 17220 17216
+f 17299 16996 16995
+f 17300 17299 16995
+f 17301 17302 1513
+f 17218 17303 16095
+f 17304 17305 17306
+f 17307 17308 17309
+f 2449 13678 17146
+f 9092 2618 17310
+f 16306 2590 2592
+f 17225 16306 2592
+f 17311 17312 17313
+f 3322 3321 3921
+f 17314 16256 17228
+f 16307 16306 17225
+f 16257 16256 17227
+f 16370 16372 17229
+f 16126 16257 17097
+f 16256 16370 17228
+f 12500 2554 4125
+f 16256 17314 17227
+f 14619 8659 7202
+f 8658 7729 7203
+f 2853 2852 17315
+f 2222 2391 7922
+f 1802 15803 1803
+f 16494 17149 9324
+f 17233 17316 15715
+f 6582 10838 13594
+f 1145 3704 12954
+f 17104 17157 17105
+f 3405 2266 2268
+f 3576 3578 17317
+f 15714 17233 15715
+f 17316 17318 15741
+f 15715 17316 15741
+f 17318 17319 15751
+f 15741 17318 15751
+f 17319 17320 15779
+f 15751 17319 15779
+f 17022 17321 17322
+f 17323 17234 17235
+f 17324 15780 15779
+f 17009 16511 17163
+f 17323 17235 17325
+f 13147 3034 3033
+f 16512 16517 16513
+f 13797 17203 11633
+f 15552 14547 16331
+f 6957 17326 12926
+f 17320 17324 15779
+f 3948 8784 3949
+f 8962 17106 9354
+f 15934 15932 3220
+f 16268 16282 16284
+f 2799 15934 3220
+f 17327 17328 17329
+f 17330 16699 16283
+f 17294 14817 17331
+f 17332 15570 15569
+f 17333 17334 17293
+f 922 1433 9180
+f 16105 17335 6751
+f 17270 17336 14583
+f 9707 10931 9041
+f 4698 8104 9973
+f 10150 9491 9420
+f 10932 13972 9043
+f 17337 17338 17339
+f 17340 10150 9420
+f 17341 17342 17343
+f 17183 17344 16509
+f 17131 5802 17345
+f 17346 17347 17348
+f 3772 17118 2078
+f 16571 16573 14313
+f 9037 16968 16582
+f 16923 16424 16419
+f 17349 17350 17351
+f 8276 8278 16707
+f 17186 9087 17196
+f 17352 17353 17354
+f 787 619 15945
+f 17355 17356 17357
+f 16510 16325 16326
+f 15580 2448 2131
+f 14908 17358 14909
+f 17359 17360 17361
+f 15910 5355 15444
+f 15686 15685 14760
+f 16684 8861 8860
+f 17362 16553 16554
+f 8808 17363 9317
+f 17364 17365 17366
+f 16874 16316 16872
+f 16193 16195 16670
+f 8659 8658 7203
+f 6917 13594 13500
+f 448 17016 449
+f 17367 17368 17369
+f 17370 6054 6053
+f 17202 8373 6339
+f 8861 9089 8862
+f 16300 16683 16554
+f 16548 16547 17029
+f 14129 17371 12700
+f 15719 15626 20
+f 17262 17372 9543
+f 101 12932 99
+f 13055 13054 17272
+f 9251 14685 17273
+f 17271 9251 17273
+f 6334 4547 5588
+f 17273 14685 12425
+f 17373 16597 16699
+f 7016 3383 6154
+f 17374 17375 17376
+f 17377 14435 14434
+f 17378 17247 3548
+f 17341 17379 17342
+f 6753 4691 8697
+f 17380 17248 17247
+f 17378 17380 17247
+f 17381 17249 17248
+f 17380 17381 17248
+f 17382 17257 17249
+f 17381 17382 17249
+f 17382 17383 17261
+f 17257 17382 17261
+f 17384 17270 17261
+f 17383 17384 17261
+f 12596 1994 9178
+f 17384 9180 17270
+f 4699 4698 9973
+f 6582 6581 10838
+f 9043 13972 9044
+f 17375 17190 16321
+f 17385 17190 17374
+f 8476 17187 16729
+f 16209 16211 17386
+f 17356 17278 17280
+f 17387 17388 17389
+f 630 4932 6514
+f 16601 16544 16546
+f 17390 13931 17391
+f 10839 17392 17391
+f 2933 16362 16361
+f 2759 217 2932
+f 9615 9616 9227
+f 9228 9616 17393
+f 1379 15016 15018
+f 5765 6187 11480
+f 6894 11098 11100
+f 16033 16892 15017
+f 17394 16931 17395
+f 16706 16705 17396
+f 16838 16706 17397
+f 17395 16838 17397
+f 17299 17398 16996
+f 17398 16907 16996
+f 17399 16904 16907
+f 17398 17399 16907
+f 17080 17400 16347
+f 16998 17080 16347
+f 17401 17402 17403
+f 17404 17405 17406
+f 2132 17003 17150
+f 9092 17310 17076
+f 17407 11908 11916
+f 9093 9092 17076
+f 2618 17150 17310
+f 3544 10834 9234
+f 16915 17145 16391
+f 16677 8860 16678
+f 17174 17408 17175
+f 6805 17409 17410
+f 3115 3117 3119
+f 1877 17411 16649
+f 17412 17413 17414
+f 17415 17225 17416
+f 17417 17418 17419
+f 17418 17420 17421
+f 17420 17047 17421
+f 6475 6615 6476
+f 17235 17422 16366
+f 17420 17423 17424
+f 17423 17425 17424
+f 17325 17235 16366
+f 17425 17325 16366
+f 17426 17425 16366
+f 17162 17427 17422
+f 17235 17162 17422
+f 17099 17428 17427
+f 17162 17099 17427
+f 17023 17322 17428
+f 17099 17023 17428
+f 17023 17022 17322
+f 17097 17429 17321
+f 17430 15781 15780
+f 16755 17224 17415
+f 17431 17323 17325
+f 17324 17430 15780
+f 16812 17300 16524
+f 17432 17431 17325
+f 727 726 15314
+f 16523 16812 16524
+f 17433 15782 15781
+f 16303 16308 16310
+f 4219 8886 3377
+f 17426 16366 16368
+f 17430 17433 15781
+f 16320 16227 16326
+f 204 15864 16505
+f 3364 12454 3365
+f 16401 16676 16701
+f 2585 2598 1317
+f 3158 3303 3300
+f 16676 16837 16702
+f 8871 17434 17435
+f 17436 16213 16206
+f 7436 7438 3113
+f 11413 14042 15924
+f 7447 7446 13972
+f 3542 6164 3543
+f 15529 12604 14544
+f 5468 10021 4077
+f 17437 17127 16977
+f 17438 62 17439
+f 17440 17437 16977
+f 17441 17442 17443
+f 15118 12650 17444
+f 16282 17330 16283
+f 12650 17445 17444
+f 16546 16545 16832
+f 14685 14550 12425
+f 16839 8276 16707
+f 16603 16419 16418
+f 397 396 17446
+f 8278 13261 16704
+f 17190 17436 16206
+f 16196 17353 16454
+f 619 16664 15945
+f 16625 16208 16213
+f 1720 1449 16437
+f 17447 17448 7862
+f 16683 16684 16677
+f 15808 15807 17362
+f 15807 16553 17362
+f 16683 17269 16554
+f 17449 17450 17451
+f 17452 10519 17167
+f 16195 16199 16671
+f 16872 16193 16670
+f 16932 4309 16839
+f 17453 14998 2226
+f 16468 16473 16529
+f 16333 16563 16533
+f 17363 17370 6053
+f 17370 17454 6339
+f 17454 17202 6339
+f 6054 17370 6339
+f 17433 17455 15785
+f 1339 17456 1337
+f 12458 9802 9801
+f 19 15719 20
+f 9354 17262 9543
+f 17372 17457 9721
+f 9543 17372 9721
+f 9443 7323 17458
+f 17271 9252 9251
+f 17459 17460 17461
+f 15544 14523 14522
+f 17462 17463 17464
+f 17334 17465 17293
+f 6806 4114 4113
+f 12801 7767 13009
+f 11253 401 8934
+f 17466 17467 17468
+f 17469 17380 17378
+f 11466 17469 17378
+f 17470 17381 17380
+f 17469 17470 17380
+f 4290 4289 5903
+f 17471 16974 16365
+f 17472 8694 17473
+f 16308 7740 16309
+f 5746 17474 17392
+f 14938 10839 17391
+f 6052 4314 17475
+f 4313 17476 17477
+f 15802 15806 15803
+f 9616 17478 17393
+f 16813 2760 17016
+f 17004 225 16285
+f 15782 17433 15785
+f 15016 16033 15017
+f 8666 16173 1009
+f 15965 15646 3009
+f 16583 17094 17399
+f 16931 17394 17479
+f 17095 17479 17480
+f 17094 17095 17480
+f 17480 16908 16904
+f 17394 17395 17481
+f 17399 17480 16904
+f 17479 17482 16908
+f 17483 17484 17485
+f 17142 17484 17486
+f 17487 17488 17489
+f 1445 2764 17490
+f 17228 17229 17491
+f 16965 17228 17491
+f 17047 17420 17424
+f 17425 17426 17424
+f 16730 12651 16259
+f 16259 12651 11268
+f 15986 17492 17493
+f 2450 2449 17146
+f 2591 9383 2592
+f 17494 16730 16259
+f 17416 2592 9384
+f 8980 4433 7338
+f 17495 17496 17497
+f 17498 17499 17496
+f 3983 17500 17501
+f 11185 11184 17502
+f 17503 16355 16358
+f 15544 14702 16291
+f 16909 17417 17504
+f 17505 17503 16358
+f 16905 16909 17506
+f 17418 17421 17419
+f 16906 16905 17507
+f 17417 17419 17504
+f 16999 16906 17367
+f 16909 17504 17506
+f 16997 16999 17508
+f 16905 17506 17507
+f 17509 17486 17484
+f 16906 17507 17367
+f 17225 2592 17416
+f 17510 17511 17512
+f 6791 7129 17513
+f 3206 7543 1178
+f 17425 17432 17325
+f 17514 6791 17513
+f 16689 17299 17300
+f 17420 17481 17423
+f 16263 16580 11187
+f 16812 16689 17300
+f 9663 14384 5929
+f 11186 16263 11187
+f 17455 17515 15788
+f 8778 16582 16688
+f 15785 17455 15788
+f 5237 3646 15871
+f 7740 17000 16309
+f 17516 7316 7318
+f 17517 15695 16404
+f 17518 17519 7231
+f 16462 16709 17140
+f 10839 5746 17392
+f 17035 15168 14554
+f 15062 9444 15334
+f 17520 17382 17381
+f 17470 17520 17381
+f 17521 17383 17382
+f 17520 17521 17382
+f 17522 17384 17383
+f 17521 17522 17383
+f 9181 9180 17384
+f 17522 9181 17384
+f 10309 3115 3114
+f 17523 17524 17525
+f 16338 17035 16964
+f 17526 17527 16018
+f 16063 17526 16018
+f 16604 16603 16418
+f 3039 5378 2854
+f 16707 8278 16704
+f 16463 17140 17528
+f 17446 16401 16701
+f 13260 16585 16704
+f 16362 7032 17191
+f 17353 16196 16076
+f 17436 17190 17385
+f 6929 6928 17191
+f 17379 17529 17342
+f 17530 17531 17532
+f 2932 7032 16362
+f 17533 17288 17534
+f 17535 17536 17537
+f 17363 6053 9317
+f 16333 16316 16563
+f 16670 16195 16671
+f 16780 16335 16781
+f 16335 16337 16781
+f 16473 16333 16533
+f 16316 16874 16563
+f 16166 17185 16226
+f 17344 17238 16635
+f 17538 17539 17540
+f 17538 17541 17539
+f 11467 3548 2516
+f 5637 17542 17543
+f 460 2139 461
+f 3112 3832 2908
+f 17544 10182 9721
+f 15131 11442 15417
+f 17457 17544 9721
+f 9443 17458 17545
+f 3938 1084 1086
+f 16856 13924 1377
+f 17541 17459 17461
+f 3834 7436 2713
+f 4926 3547 3548
+f 3517 9054 3351
+f 4402 3690 3352
+f 9520 17340 9419
+f 17546 10694 10182
+f 17547 17548 16976
+f 3260 17549 17550
+f 16276 16275 6718
+f 17440 16977 16726
+f 16280 17551 16281
+f 10711 10710 17552
+f 530 9204 7744
+f 5681 9533 10905
+f 17553 17469 11466
+f 1132 17553 11466
+f 17554 17470 17469
+f 17553 17554 17469
+f 17555 17520 17470
+f 17554 17555 17470
+f 17555 17556 17521
+f 17520 17555 17521
+f 17051 17112 17103
+f 17240 16956 16957
+f 17113 16957 17103
+f 17111 17113 17103
+f 12941 17557 17476
+f 4314 4313 17477
+f 4313 12941 17476
+f 12940 17558 17557
+f 17559 15908 15757
+f 17559 17560 15908
+f 17558 17559 15757
+f 17560 16070 15908
+f 17515 17561 15789
+f 16171 8666 8665
+f 16033 14682 16892
+f 16423 16420 14567
+f 11252 16688 16811
+f 17094 17480 17399
+f 8363 11252 16811
+f 16584 16583 17398
+f 17394 17562 17482
+f 17480 17479 16908
+f 17142 17486 17400
+f 17080 17142 17400
+f 2567 17563 17564
+f 5458 5460 17565
+f 2063 17566 13949
+f 17567 17568 17569
+f 8144 6889 6888
+f 13378 13377 16881
+f 14079 9520 9521
+f 17570 17571 4398
+f 17570 4398 16355
+f 17572 17573 17574
+f 17503 17570 16355
+f 17571 4399 4398
+f 17495 17498 17496
+f 17219 17218 16095
+f 17498 17508 17499
+f 17367 17507 17368
+f 15429 9377 9379
+f 17575 1798 15776
+f 17576 17577 17578
+f 7231 17519 2226
+f 17579 2650 17580
+f 16893 16895 14502
+f 16894 11931 14526
+f 16362 17191 16249
+f 16895 16894 14526
+f 2650 17579 6741
+f 5475 14080 5476
+f 15788 17515 15789
+f 16930 15790 15789
+f 16472 9453 12859
+f 15211 15213 9454
+f 17561 16930 15789
+f 17581 17582 17583
+f 17238 17344 17183
+f 17224 17225 17415
+f 17584 17585 17586
+f 16930 17587 15791
+f 17588 17589 17590
+f 17591 17432 17425
+f 15790 16930 15791
+f 2515 2514 3021
+f 17423 17591 17425
+f 16261 16686 16580
+f 15017 16893 15333
+f 16263 16261 16580
+f 16129 17020 16686
+f 16261 16129 16686
+f 16129 726 17020
+f 17592 17593 14214
+f 726 17096 17020
+f 17528 17518 7231
+f 7739 17594 17000
+f 9442 17595 17474
+f 452 2301 15991
+f 11101 14555 13957
+f 5746 9442 17474
+f 17556 17596 17522
+f 17112 17111 17103
+f 17521 17556 17522
+f 17597 9181 17522
+f 17596 17597 17522
+f 17598 1842 467
+f 17597 17598 9181
+f 2908 3834 2713
+f 15168 14555 14554
+f 16954 17122 17051
+f 17599 17540 17527
+f 17526 17599 17527
+f 17600 17601 17602
+f 3026 443 2633
+f 17603 17098 7236
+f 17604 17605 17606
+f 13261 13260 16704
+f 16880 16124 17607
+f 16245 17353 16076
+f 14741 16452 16585
+f 16245 16076 16083
+f 17353 17352 16454
+f 16198 16202 16087
+f 16092 16245 16083
+f 16199 16198 16087
+f 16778 16986 16085
+f 16671 16199 16087
+f 16202 16085 16087
+f 16335 16780 16079
+f 16316 16193 16872
+f 16781 16337 16983
+f 16337 17067 16983
+f 487 17608 9115
+f 3220 15932 1980
+f 17587 17609 15804
+f 14939 14942 14944
+f 17599 17538 17540
+f 17541 17461 17539
+f 16338 16964 1117
+f 1235 16338 1117
+f 17544 17546 10182
+f 17035 14554 16964
+f 4698 14487 8104
+f 14178 12159 13812
+f 15899 8039 2477
+f 15063 14952 8453
+f 2910 4292 4288
+f 4092 13374 7430
+f 3351 4402 3352
+f 17122 17112 17051
+f 3832 3834 2908
+f 2720 2722 4124
+f 15897 17122 16953
+f 13453 13452 13456
+f 15791 17587 15804
+f 6343 15005 3094
+f 17609 17610 15830
+f 17519 17453 2226
+f 4163 13566 15733
+f 16275 6719 6718
+f 16286 16288 17611
+f 17612 17465 17334
+f 16949 16116 16118
+f 15867 16948 15868
+f 15865 15867 15866
+f 16948 16816 15868
+f 16166 17613 17185
+f 3947 3949 13224
+f 17614 17615 16975
+f 17616 14411 17617
+f 17548 17440 16726
+f 16974 17614 16975
+f 15914 15912 16009
+f 17618 15468 15470
+f 11467 2516 2518
+f 17619 2476 17620
+f 16976 16728 6094
+f 16871 3647 9516
+f 16379 14408 16380
+f 3970 16955 14250
+f 13290 17559 17558
+f 12941 12940 17557
+f 1609 1502 1674
+f 2478 1609 1674
+f 17476 17205 17621
+f 17476 17557 17205
+f 17477 17476 17621
+f 17557 17206 17205
+f 16426 4745 14567
+f 4759 17622 17623
+f 16420 16426 14567
+f 16425 4746 4745
+f 7017 14534 7018
+f 17624 8363 16921
+f 16358 14818 17251
+f 17479 17394 17482
+f 17625 17626 17627
+f 3898 3897 2819
+f 11305 7338 8019
+f 9377 11268 9378
+f 17322 17321 14637
+f 15429 13933 16258
+f 17507 17506 17628
+f 17504 17419 17629
+f 17491 17566 2063
+f 3908 17491 2063
+f 1657 1656 14377
+f 16440 16356 16357
+f 15804 17609 15830
+f 17630 17631 17632
+f 5670 17633 5671
+f 17633 17505 17250
+f 17250 17251 17634
+f 17505 16358 17250
+f 7065 2645 2153
+f 15830 17610 15604
+f 2195 2194 4890
+f 17635 14235 14237
+f 17419 17421 17636
+f 3652 8111 1538
+f 1877 4784 17411
+f 15333 16893 8391
+f 14213 16788 14211
+f 16893 14502 8391
+f 17565 17637 17638
+f 9999 3441 3443
+f 11467 11466 17378
+f 5458 17565 17638
+f 17639 10746 10694
+f 14822 14821 17640
+f 17633 17250 5671
+f 12702 8046 15533
+f 17641 17642 17643
+f 16939 17644 16940
+f 17645 17224 16755
+f 17646 17647 17648
+f 4944 4943 953
+f 17491 17229 17566
+f 16908 17482 16909
+f 17649 17650 15859
+f 15018 15017 15333
+f 17562 17418 17417
+f 16689 16584 17299
+f 16892 16895 16893
+f 16584 17398 17299
+f 16583 17399 17398
+f 16080 16880 17607
+f 16782 16125 16124
+f 15932 16262 1980
+f 15858 17649 15859
+f 1778 15984 17077
+f 698 2290 2988
+f 7324 17651 17595
+f 12940 13290 17558
+f 17644 16939 17652
+f 17653 17654 17655
+f 17656 17553 1132
+f 1131 17656 1132
+f 17656 17657 17554
+f 17553 17656 17554
+f 17657 17658 17555
+f 17554 17657 17555
+f 17659 15875 15859
+f 17660 17556 17555
+f 9442 7324 17595
+f 17650 17659 15859
+f 8133 8132 1801
+f 17661 13289 17662
+f 17608 16571 9115
+f 16027 1778 17077
+f 16075 16081 17663
+f 6960 6961 15980
+f 17085 16073 16192
+f 16080 17607 17664
+f 13260 14741 16585
+f 17086 17085 16192
+f 17086 16192 16452
+f 14741 17086 16452
+f 16631 16074 16073
+f 17085 16631 16073
+f 16336 16079 16074
+f 16631 16336 16074
+f 8467 2390 8468
+f 16336 16335 16079
+f 17141 16305 15723
+f 8958 17141 15723
+f 15930 16260 16262
+f 16307 17665 15724
+f 15979 17666 14943
+f 15932 15930 16262
+f 17458 17667 17545
+f 17077 17563 2567
+f 9443 17545 17651
+f 7324 9443 17651
+f 9455 9454 16924
+f 2246 1631 15127
+f 3321 1338 3922
+f 16884 9412 17668
+f 1086 1085 4123
+f 17658 17660 17555
+f 17669 17596 17556
+f 17660 17669 17556
+f 17670 17597 17596
+f 17669 17670 17596
+f 3350 1717 2722
+f 1608 15554 15628
+f 14006 4786 10380
+f 17671 17061 17460
+f 17459 17671 17460
+f 4448 8460 17672
+f 17673 17674 17675
+f 7433 17676 3368
+f 8460 16729 17672
+f 7432 17677 17676
+f 3366 3368 15867
+f 13931 17390 17677
+f 7433 7432 17676
+f 13931 14938 17391
+f 7432 13931 17677
+f 8015 2732 12499
+f 486 17678 487
+f 17113 17240 16957
+f 17036 2437 16956
+f 17122 16954 16953
+f 17240 17036 16956
+f 17670 1842 17597
+f 15815 2785 6190
+f 7326 3152 3344
+f 6036 14557 4122
+f 1707 962 961
+f 16483 3832 3112
+f 15583 15973 859
+f 619 4646 16664
+f 463 1849 464
+f 7667 17447 7862
+f 443 450 2633
+f 697 2133 2290
+f 2761 2760 8039
+f 8039 16813 3194
+f 16066 17679 16068
+f 17477 17621 17207
+f 17475 17207 16068
+f 17680 17475 16068
+f 16433 14402 4746
+f 16426 16425 4745
+f 17421 17047 17681
+f 17426 16368 17048
+f 17682 16755 13574
+f 16755 17415 13575
+f 17546 17639 10694
+f 17683 15876 15875
+f 17684 17685 17686
+f 17659 17683 15875
+f 16897 16899 17633
+f 16052 304 411
+f 17687 15877 15876
+f 17321 14638 14637
+f 16965 17491 3908
+f 3907 16965 3908
+f 17428 17688 17689
+f 17504 17629 17690
+f 14377 1656 16649
+f 17427 17428 17689
+f 16895 14526 14502
+f 17691 431 16545
+f 17683 17687 15876
+f 17692 15881 15877
+f 17687 17692 15877
+f 17693 15895 15881
+f 8659 7203 7202
+f 4784 14649 17411
+f 543 8883 7029
+f 17694 10887 10746
+f 17695 17696 17697
+f 7832 16115 7931
+f 2554 2934 4125
+f 14432 4721 4723
+f 3950 2555 2569
+f 4095 3950 2569
+f 17692 17693 15881
+f 17434 8871 13584
+f 16829 8871 17435
+f 16806 17698 17699
+f 465 424 15610
+f 17700 15927 15895
+f 17693 17700 15895
+f 17701 15950 15927
+f 17084 17702 17703
+f 8956 17704 5866
+f 15275 11200 3451
+f 17705 17084 17703
+f 16804 1445 17490
+f 17229 16372 17706
+f 17482 17562 17417
+f 17700 17701 15927
+f 17562 17481 17418
+f 17481 17420 17418
+f 16518 17082 17220
+f 17481 17591 17423
+f 16880 16782 16124
+f 17707 17431 17432
+f 3857 3856 13561
+f 17708 17709 17005
+f 450 232 2634
+f 16578 16577 17710
+f 17711 17560 17559
+f 17475 17477 17207
+f 16962 17027 17712
+f 13290 17711 17559
+f 17713 17714 17715
+f 15579 2001 2448
+f 17716 17717 16348
+f 15619 15634 15620
+f 3537 17718 3538
+f 14412 17719 14413
+f 16274 17720 17721
+f 3201 14703 9081
+f 17722 15960 15950
+f 979 978 15972
+f 16561 15695 4788
+f 17723 17711 17661
+f 8132 1802 1801
+f 17232 15987 15985
+f 16676 8133 16837
+f 16526 1803 16674
+f 16081 16080 17664
+f 16191 16075 17724
+f 3626 3625 14761
+f 17725 17726 17727
+f 2588 1851 16653
+f 16303 16310 16304
+f 2067 2069 3332
+f 4888 13809 17728
+f 2386 2385 6195
+f 15617 15618 1088
+f 17701 17722 15950
+f 3127 2066 3124
+f 16515 17484 17142
+f 17729 15961 15960
+f 16526 16674 16527
+f 17507 17628 17368
+f 15839 16030 16260
+f 6057 17416 15366
+f 17730 17731 17732
+f 17733 17734 17735
+f 2566 17077 2567
+f 1777 17232 15985
+f 10381 17164 10382
+f 17722 17729 15960
+f 17736 15549 17737
+f 15882 15797 15799
+f 14578 11705 10732
+f 17738 17739 17740
+f 15080 17741 17742
+f 10299 10847 1808
+f 17743 17656 1131
+f 15972 16436 17017
+f 3380 17743 1131
+f 373 9496 1558
+f 2002 373 1558
+f 16813 442 3194
+f 441 1497 1502
+f 17744 16065 17745
+f 17667 17744 17745
+f 7129 9475 17513
+f 17729 17746 15962
+f 9475 17747 17513
+f 15961 17729 15962
+f 8966 9303 16120
+f 17746 17748 15966
+f 1808 1768 1745
+f 17667 17458 17744
+f 15752 6047 17744
+f 6047 17679 17744
+f 4314 17477 17475
+f 6046 17680 17679
+f 6047 6046 17679
+f 6052 17475 17680
+f 676 678 16924
+f 6046 6052 17680
+f 17749 17657 17656
+f 16436 16185 17017
+f 17743 17749 17656
+f 17749 17750 17658
+f 17657 17749 17658
+f 17750 17751 17660
+f 5532 17752 5533
+f 9192 15972 9193
+f 8978 8038 9193
+f 15972 17017 9193
+f 2760 2933 17016
+f 17393 17478 486
+f 17478 17678 486
+f 8384 543 7029
+f 17595 16282 16268
+f 17595 17651 16282
+f 17474 17595 16268
+f 17651 17330 16282
+f 11048 16113 14366
+f 16433 16435 14402
+f 17753 17754 17092
+f 17422 17427 17755
+f 17756 17007 17089
+f 17427 17689 17755
+f 17664 17024 17161
+f 17724 17663 17234
+f 16897 17633 5670
+f 4809 16897 5670
+f 17251 14814 2593
+f 12150 13791 13790
+f 17097 17227 17429
+f 17022 17097 17321
+f 16366 17422 16367
+f 17079 16997 17498
+f 17506 17504 17690
+f 2739 11176 6061
+f 6724 2923 7246
+f 17419 17636 17629
+f 8658 8780 13393
+f 16115 15332 7931
+f 884 572 885
+f 17429 16863 17757
+f 15962 17746 15966
+f 1878 1877 16649
+f 9324 9326 17758
+f 16858 2188 17759
+f 15011 15009 6348
+f 9481 17040 17041
+f 12888 9048 6724
+f 7313 4754 7195
+f 6581 3114 10838
+f 14487 5914 8105
+f 14997 17760 12098
+f 14487 8105 8104
+f 17269 16677 15832
+f 12597 6917 13500
+f 6791 17514 1793
+f 14265 2848 3056
+f 17639 17694 10746
+f 1792 6791 1793
+f 15696 7450 16248
+f 16310 15460 9413
+f 17081 17495 17702
+f 4776 4775 4781
+f 2264 2263 10577
+f 17084 17081 17702
+f 17761 17762 5196
+f 16864 17314 16965
+f 1848 16386 16498
+f 17763 17764 17765
+f 16903 17570 17503
+f 16901 16903 17503
+f 17397 17396 17432
+f 17591 17397 17432
+f 17766 16920 16919
+f 17709 17766 16919
+f 16186 16392 16633
+f 16296 17753 17767
+f 17676 17677 16948
+f 17390 16116 16949
+f 17711 17768 17560
+f 17769 14294 14293
+f 17291 16577 17770
+f 17771 2260 17772
+f 17658 17750 17660
+f 17751 17773 17669
+f 17660 17751 17669
+f 17774 17670 17669
+f 17773 17774 17669
+f 1843 1842 17670
+f 17774 1843 17670
+f 1449 16915 16437
+f 2260 2111 2110
+f 16392 8130 17050
+f 17139 17775 17140
+f 16400 8131 8133
+f 17679 16066 16065
+f 16337 16455 17067
+f 15385 16383 16382
+f 16081 17664 17663
+f 16311 16191 17776
+f 16181 17777 16810
+f 217 568 2932
+f 16489 17778 17779
+f 17780 4776 4783
+f 2237 6904 6929
+f 14740 16878 14741
+f 16878 17086 14741
+f 17781 1605 1604
+f 16995 16997 17079
+f 17747 9475 16119
+f 15369 7325 3137
+f 16864 6196 2385
+f 14579 13635 14983
+f 4084 1471 13525
+f 15089 17782 15054
+f 17783 6886 2926
+f 15984 15986 17563
+f 5191 12598 11879
+f 17232 8131 16400
+f 15987 17232 16400
+f 7332 2246 14648
+f 441 443 1497
+f 16355 4398 7265
+f 6146 12776 15346
+f 4121 1758 1757
+f 8691 14143 4642
+f 1706 16483 3112
+f 14558 12091 4122
+f 17784 17785 17786
+f 17787 4891 17788
+f 8046 16857 8047
+f 15549 17789 17737
+f 17737 17789 17790
+f 17667 17745 17373
+f 17545 17667 17373
+f 1943 6927 2092
+f 2074 1943 2091
+f 17791 16939 17792
+f 8957 8956 5866
+f 14297 15778 15777
+f 1733 17793 1731
+f 10382 17164 16476
+f 17789 16052 17790
+f 15164 10380 16289
+f 17775 17794 17140
+f 568 2237 7032
+f 16181 16180 17777
+f 6952 6960 16070
+f 6952 17768 6953
+f 1609 441 1502
+f 2479 2478 2726
+f 2449 2002 13678
+f 443 3026 1497
+f 14451 15817 14452
+f 13850 13851 17795
+f 2141 1556 1555
+f 15502 13462 1042
+f 4230 4229 17796
+f 17797 15596 17798
+f 17799 17800 17286
+f 11226 17801 14129
+f 17802 17803 17804
+f 17805 17795 17806
+f 17778 17807 17779
+f 17808 3624 16605
+f 16939 17791 17652
+f 16063 9195 16886
+f 17474 16268 16267
+f 17392 17474 16267
+f 16429 17809 16113
+f 16435 11048 14366
+f 16396 17709 17708
+f 16122 16396 17708
+f 17753 17092 17093
+f 17767 17753 17093
+f 17607 17021 17024
+f 17663 17664 17161
+f 17458 14451 15752
+f 16899 17505 17633
+f 17634 17251 2593
+f 13963 6331 14707
+f 17227 16863 17429
+f 17321 17429 14638
+f 16999 17367 17508
+f 17047 17046 17681
+f 15775 11176 2739
+f 17421 17681 17636
+f 9188 14355 16169
+f 17203 17810 3130
+f 14818 14817 14814
+f 7754 11392 11394
+f 17251 14818 14814
+f 2814 12887 17811
+f 14383 8222 3460
+f 12419 15169 12420
+f 15009 16133 6349
+f 2560 17812 15011
+f 15369 3137 17813
+f 17814 13636 14578
+f 13386 1934 14107
+f 15344 15343 6475
+f 14489 7755 14488
+f 11114 14370 13578
+f 15939 16506 15940
+f 14392 14454 17815
+f 17816 17817 17818
+f 6198 6297 15125
+f 14620 7026 13928
+f 15942 15939 15941
+f 14151 17819 14152
+f 15218 14447 14449
+f 2458 2460 2730
+f 14821 17635 17640
+f 3704 15621 12954
+f 15776 15775 2739
+f 17079 17498 17495
+f 17081 17079 17495
+f 17314 16864 16863
+f 17227 17314 16863
+f 16801 16790 17565
+f 16788 16787 14211
+f 16994 17571 17570
+f 16903 16994 17570
+f 17562 17394 17481
+f 17395 17397 17591
+f 17624 16921 16920
+f 17766 17624 16920
+f 16297 17767 17820
+f 16430 16297 17820
+f 17677 17390 16949
+f 17390 17391 16219
+f 16637 15977 17454
+f 17370 16637 17454
+f 17821 17822 17823
+f 17824 17825 17826
+f 17652 16962 17712
+f 17827 400 399
+f 12602 15541 15540
+f 12841 2122 2121
+f 17551 17552 16281
+f 15555 17743 3380
+f 14160 15555 3380
+f 15526 15464 15463
+f 17828 17749 17743
+f 15550 2195 16331
+f 2963 15526 15463
+f 17744 17679 16065
+f 2236 15978 6904
+f 17829 17830 17831
+f 13575 17415 6057
+f 16075 17663 17724
+f 15128 1633 17691
+f 16517 16518 17220
+f 17428 17322 17688
+f 17083 17081 17084
+f 17424 17426 17048
+f 17482 17417 16909
+f 3775 12494 12398
+f 16904 16908 16905
+f 16166 17171 17613
+f 12228 17832 17833
+f 10434 15381 10435
+f 13455 17834 13370
+f 15348 12776 15371
+f 17835 6901 13370
+f 17834 17835 13370
+f 17836 6887 6886
+f 17835 6882 6901
+f 1778 1777 15984
+f 2422 7358 15430
+f 1777 15985 15984
+f 17077 15984 17563
+f 3117 3904 3118
+f 17837 17838 17839
+f 14941 12776 4592
+f 14668 6998 14550
+f 15555 17828 17743
+f 17840 17750 17749
+f 17828 17840 17749
+f 17840 17841 17751
+f 15526 2963 2962
+f 15523 15526 2962
+f 17842 7439 16142
+f 17843 16796 17842
+f 17676 16948 15867
+f 3368 17676 15867
+f 16297 16296 17767
+f 16425 16433 4746
+f 15930 15839 16260
+f 15903 15314 16030
+f 10587 10586 14284
+f 15839 15903 16030
+f 14935 14934 17736
+f 15903 15902 15314
+f 892 16605 893
+f 8044 17844 17845
+f 14895 14394 14055
+f 14899 14934 14936
+f 17560 6952 16070
+f 6947 6914 6948
+f 17558 15757 17206
+f 17557 17558 17206
+f 1075 698 2988
+f 17545 17373 17330
+f 17846 17847 17371
+f 8859 16922 17848
+f 17750 17840 17751
+f 15523 2962 6183
+f 17841 17849 17773
+f 17751 17841 17773
+f 17850 17774 17773
+f 17849 17850 17773
+f 12146 2600 17851
+f 8847 15521 12147
+f 3809 3811 16017
+f 15521 6183 12147
+f 1319 1444 1317
+f 7228 12777 5957
+f 17527 17540 15935
+f 17461 15753 15933
+f 17539 15933 15936
+f 17540 17539 15936
+f 9641 14822 17852
+f 16708 17766 17709
+f 14934 15549 17736
+f 17754 17089 17092
+f 14055 14054 14895
+f 2391 2553 8014
+f 17853 7232 7661
+f 10963 10962 13130
+f 17854 10935 10887
+f 17328 17855 17329
+f 9270 3306 8107
+f 14533 15200 15368
+f 14638 17757 15222
+f 10732 4061 17814
+f 6293 3963 1898
+f 7661 7232 7234
+f 15011 14468 2560
+f 15752 14451 14453
+f 17856 3128 3130
+f 17810 17856 3130
+f 2961 4641 3000
+f 17856 11924 3128
+f 5062 1469 1468
+f 1469 5062 5061
+f 17857 17814 4061
+f 4060 17857 4061
+f 17858 13636 17814
+f 17857 17858 17814
+f 17859 4137 13636
+f 17858 17859 13636
+f 17860 4135 4137
+f 17859 17860 4137
+f 17861 17782 4135
+f 17860 17861 4135
+f 807 806 7204
+f 17861 10434 17782
+f 7637 17862 14463
+f 14462 14229 14463
+f 17782 15089 4135
+f 1322 1321 3939
+f 16309 17000 17002
+f 5477 5479 12865
+f 17340 9420 9419
+f 15005 6343 14305
+f 16997 17508 17498
+f 9300 9302 17863
+f 17314 17228 16965
+f 13795 13849 13872
+f 8368 9787 12269
+f 17864 13456 13550
+f 16998 16347 17571
+f 16790 17637 17565
+f 17481 17395 17591
+f 16994 16998 17571
+f 8363 16811 16921
+f 17694 17854 10887
+f 11048 16429 16113
+f 16430 17820 17809
+f 16116 17390 16219
+f 17392 16267 16219
+f 16973 17865 17866
+f 16918 17363 8808
+f 17867 16302 16883
+f 7738 14780 7739
+f 17868 1843 17774
+f 17850 17868 17774
+f 14141 8691 1843
+f 17868 14141 1843
+f 14557 14558 4122
+f 17869 14143 14142
+f 1708 16483 1706
+f 14559 11790 12091
+f 15464 15467 15465
+f 17171 16166 16168
+f 17870 8883 543
+f 16180 16873 17777
+f 17416 9384 15366
+f 17679 17680 16068
+f 1465 1467 3554
+f 16346 4399 17571
+f 12018 15224 15176
+f 17871 10964 10935
+f 11511 17872 17873
+f 16128 16886 16165
+f 17854 17871 10935
+f 13817 5900 5906
+f 13872 9143 9142
+f 10733 4062 4061
+f 17874 13455 13456
+f 17864 17874 13456
+f 17875 17834 13455
+f 17874 17875 13455
+f 17876 17835 17834
+f 17875 17876 17834
+f 6883 6882 17835
+f 17876 6883 17835
+f 17877 10992 10964
+f 1130 1132 2518
+f 14941 15430 15371
+f 17878 15060 15381
+f 2456 17138 2457
+f 17879 17880 17881
+f 14889 10019 14565
+f 17815 14370 17882
+f 2412 8214 2413
+f 13407 14924 13947
+f 2344 17883 4499
+f 16886 16128 16063
+f 16393 4942 17137
+f 14939 14944 14940
+f 8665 17200 17202
+f 15147 5818 14351
+f 17460 17061 15754
+f 17884 17885 17886
+f 16296 16439 17753
+f 16439 17754 17753
+f 17708 17005 17006
+f 17887 17708 17006
+f 16702 16837 16525
+f 16785 16564 16446
+f 16564 16440 16446
+f 16445 16562 16985
+f 16705 16453 17396
+f 16191 17724 17776
+f 15991 15802 1802
+f 17016 2933 16361
+f 232 231 15942
+f 2633 450 2634
+f 17888 16229 16230
+f 15976 16171 17208
+f 17651 17545 17330
+f 14682 16179 16892
+f 7572 14900 17666
+f 17061 12230 15754
+f 15521 15523 6183
+f 14942 15979 14943
+f 16939 16168 17889
+f 17140 17794 17528
+f 17890 17891 6946
+f 17892 17893 17894
+f 12068 17895 17721
+f 17896 17897 17898
+f 15499 15489 3751
+f 15979 7572 17666
+f 17899 16234 16235
+f 3775 10018 3773
+f 6745 8650 8652
+f 13487 6745 8652
+f 17508 17367 17369
+f 17540 15936 15935
+f 7566 7565 6888
+f 16564 16596 16440
+f 3923 7246 12751
+f 14430 1465 14118
+f 13657 13656 17900
+f 17901 3232 11072
+f 14055 14992 14395
+f 14053 14055 14395
+f 7339 7341 10233
+f 14398 13871 14395
+f 9144 9143 13797
+f 12473 4859 10768
+f 17902 13796 9143
+f 10768 4859 4861
+f 17903 17203 13797
+f 13796 17903 13797
+f 17904 17810 17203
+f 17903 17904 17203
+f 17905 17856 17810
+f 17904 17905 17810
+f 17906 11924 17856
+f 17905 17906 17856
+f 17907 4060 11924
+f 17906 17907 11924
+f 17908 17857 4060
+f 17907 17908 4060
+f 17909 17858 17857
+f 17908 17909 17857
+f 17910 17859 17858
+f 17909 17910 17858
+f 17911 17860 17859
+f 17910 17911 17859
+f 17912 17861 17860
+f 17911 17912 17860
+f 17913 10434 17861
+f 17912 17913 17861
+f 17914 15381 10434
+f 17913 17914 10434
+f 17915 17878 15381
+f 17914 17915 15381
+f 17916 15097 17878
+f 17915 17916 17878
+f 17917 17916 5918
+f 17916 17917 15097
+f 17757 2387 15222
+f 10989 7753 7755
+f 10232 12393 7229
+f 17871 17877 10964
+f 14889 15398 12094
+f 10783 3949 2060
+f 12323 15736 12324
+f 1716 4128 4619
+f 15065 10984 15064
+f 17652 17791 16962
+f 7856 7855 12718
+f 1316 1315 2913
+f 17429 17757 14638
+f 4923 1275 2353
+f 17391 17392 16219
+f 16429 16430 17809
+f 8602 16918 8808
+f 16018 17527 16019
+f 16539 16541 14781
+f 16637 17370 17363
+f 14553 8811 8810
+f 17794 17518 17528
+f 15637 15516 25
+f 15556 17918 17828
+f 15555 15556 17828
+f 17918 17919 17840
+f 17828 17918 17840
+f 17919 17920 17841
+f 1870 17867 16883
+f 15501 15499 2724
+f 16180 13072 13040
+f 16981 17775 17139
+f 17415 17416 6057
+f 17677 16949 16948
+f 3732 9711 3733
+f 6184 6186 3741
+f 5671 17250 17634
+f 17921 13861 13862
+f 6645 2748 7010
+f 391 11479 10968
+f 17922 11223 9322
+f 8698 7008 11479
+f 17923 17864 14214
+f 17593 17923 14214
+f 17924 17874 17864
+f 17923 17924 17864
+f 17925 17875 17874
+f 17924 17925 17874
+f 17926 17876 17875
+f 17925 17926 17875
+f 17927 6883 17876
+f 17926 17927 17876
+f 17927 17928 6884
+f 6883 17927 6884
+f 13559 2868 2867
+f 14670 17929 13948
+f 11047 16427 11048
+f 12552 12551 6021
+f 8144 7565 5155
+f 4097 4288 4290
+f 17840 17919 17841
+f 17920 17930 17849
+f 15501 2724 2723
+f 17841 17920 17849
+f 17208 8665 17202
+f 17931 15556 9997
+f 17527 15935 16019
+f 15529 12602 12604
+f 16599 17756 17754
+f 17932 17933 17934
+f 17820 17767 17155
+f 16439 16599 17754
+f 17396 17707 17432
+f 17709 16919 17005
+f 16374 16515 17142
+f 17776 17323 17431
+f 16515 17026 17484
+f 17026 17144 17484
+f 16311 17776 17707
+f 16453 16311 17707
+f 17397 16706 17396
+f 16453 17707 17396
+f 17095 16931 17479
+f 16931 16838 17395
+f 17756 17935 17007
+f 17935 17887 17008
+f 16435 14366 14402
+f 16599 16024 17756
+f 17539 17461 15933
+f 17460 15754 15753
+f 17936 17937 17938
+f 17939 17940 17941
+f 15318 17942 13221
+f 15500 2723 13221
+f 17930 17943 17850
+f 17849 17930 17850
+f 17944 17868 17850
+f 17943 17944 17850
+f 17942 15318 8553
+f 15496 17942 8553
+f 17945 16462 16464
+f 17942 17946 13221
+f 16020 8810 8651
+f 13369 13371 13283
+f 9139 17947 17948
+f 16917 539 538
+f 15853 17949 17710
+f 14006 10380 15164
+f 11619 11555 3129
+f 14337 3550 8274
+f 14055 14394 14992
+f 12194 10854 10853
+f 17950 17951 14398
+f 14992 17950 14398
+f 17951 17952 14399
+f 14398 17951 14399
+f 17953 17902 14399
+f 17952 17953 14399
+f 17954 13796 17902
+f 17953 17954 17902
+f 17955 17903 13796
+f 17954 17955 13796
+f 17956 17904 17903
+f 17955 17956 17903
+f 17957 17905 17904
+f 17956 17957 17904
+f 17958 17906 17905
+f 17957 17958 17905
+f 17959 17907 17906
+f 17958 17959 17906
+f 17960 17908 17907
+f 17959 17960 17907
+f 17961 17909 17908
+f 17960 17961 17908
+f 17962 17910 17909
+f 17961 17962 17909
+f 17963 17911 17910
+f 17962 17963 17910
+f 17964 17912 17911
+f 17963 17964 17911
+f 17965 17913 17912
+f 17964 17965 17912
+f 17966 17914 17913
+f 17965 17966 17913
+f 17967 17915 17914
+f 17966 17967 17914
+f 17968 17916 17915
+f 17967 17968 17915
+f 7205 7212 6510
+f 17968 5918 17916
+f 4098 5763 11480
+f 6618 3737 13769
+f 17757 2385 2387
+f 2385 6196 6195
+f 13453 13454 13367
+f 17969 14417 17970
+f 11160 392 8367
+f 13656 17969 17900
+f 11716 12213 2388
+f 7756 11716 2388
+f 11043 17971 12717
+f 7855 11043 12717
+f 7664 14627 7735
+f 15292 13405 16749
+f 16863 2385 17757
+f 8694 12708 11511
+f 17171 16168 16939
+f 6337 8379 3855
+f 16918 16637 17363
+f 17061 17063 12230
+f 17972 11031 10992
+f 1104 16959 2809
+f 17973 14141 17868
+f 17944 17973 17868
+f 17974 14142 17973
+f 17973 14142 14141
+f 14558 14559 12091
+f 14559 14560 7208
+f 13418 14006 13419
+f 16007 6816 3603
+f 17208 17202 17454
+f 15977 17208 17454
+f 17422 17755 16367
+f 17975 17847 17976
+f 17563 17493 17564
+f 15334 9371 14283
+f 15053 2059 8026
+f 17977 14419 17921
+f 17978 17592 11483
+f 9736 17979 17980
+f 17981 17593 17592
+f 17978 17981 17592
+f 17982 17923 17593
+f 17981 17982 17593
+f 17983 17924 17923
+f 17982 17983 17923
+f 17984 17925 17924
+f 17983 17984 17924
+f 17985 17926 17925
+f 17984 17985 17925
+f 17985 17986 17927
+f 17926 17985 17927
+f 17986 17987 17928
+f 17927 17986 17928
+f 3040 2052 7766
+f 6073 9516 6897
+f 17988 17989 17990
+f 5910 9317 15657
+f 15484 2160 1171
+f 17991 17940 17992
+f 17993 17994 17995
+f 825 4291 7107
+f 17996 9558 1487
+f 17997 17998 2409
+f 15551 15552 16521
+f 17999 16982 18000
+f 16200 17621 16201
+f 8666 1009 1008
+f 327 2005 2632
+f 17373 17745 16597
+f 16396 16708 17709
+f 16024 17935 17756
+f 16113 17809 16114
+f 17820 17155 17156
+f 17664 17607 17024
+f 17707 17776 17431
+f 18001 18002 18003
+f 18004 18005 52
+f 16520 17083 17082
+f 16518 16520 17082
+f 16520 16524 17083
+f 16524 17078 17083
+f 16524 17300 17078
+f 17300 16995 17078
+f 17724 17234 17323
+f 17776 17724 17323
+f 17754 17756 17089
+f 17887 17006 17008
+f 16023 17887 17935
+f 16024 16023 17935
+f 17461 17460 15753
+f 16122 17708 17887
+f 17846 17976 17847
+f 16813 17016 448
+f 17946 15500 13221
+f 2951 6745 13487
+f 17322 14637 17688
+f 5904 18006 2214
+f 18007 8686 18008
+f 7634 14274 7731
+f 14135 18009 18010
+f 14906 14905 18011
+f 17147 16007 3603
+f 15602 18012 18013
+f 17207 17621 16194
+f 17621 17205 16201
+f 16066 16069 16067
+f 17745 16065 16467
+f 17678 17608 487
+f 9669 4785 13418
+f 18014 18015 17939
+f 1487 1486 17996
+f 3692 10933 3693
+f 14394 17950 14992
+f 14393 18016 17951
+f 17950 14393 17951
+f 18016 18017 17952
+f 17951 18016 17952
+f 18018 17953 17952
+f 18017 18018 17952
+f 18019 17954 17953
+f 18018 18019 17953
+f 18020 17955 17954
+f 18019 18020 17954
+f 18021 17956 17955
+f 18020 18021 17955
+f 18022 17957 17956
+f 18021 18022 17956
+f 18023 17958 17957
+f 18022 18023 17957
+f 18024 17959 17958
+f 18023 18024 17958
+f 18025 17960 17959
+f 18024 18025 17959
+f 18026 17961 17960
+f 18025 18026 17960
+f 18027 17962 17961
+f 18026 18027 17961
+f 18028 17963 17962
+f 18027 18028 17962
+f 18029 17964 17963
+f 18028 18029 17963
+f 18030 17965 17964
+f 18029 18030 17964
+f 18031 17966 17965
+f 18030 18031 17965
+f 18032 17967 17966
+f 18031 18032 17966
+f 18033 17968 17967
+f 18032 18033 17967
+f 5919 5918 17968
+f 9485 9418 1020
+f 13071 9662 3213
+f 17968 18033 5919
+f 13598 18034 13599
+f 18034 18035 13599
+f 17900 17969 17970
+f 14417 14419 17977
+f 12416 11722 8447
+f 3949 8784 2060
+f 11718 12483 12213
+f 11716 11718 12213
+f 11042 18036 17971
+f 14615 13947 18037
+f 4083 3040 1472
+f 17877 17972 10992
+f 2557 2731 12496
+f 17929 14670 16958
+f 10995 10994 11013
+f 17499 17369 17941
+f 16068 17207 16315
+f 16505 15864 16181
+f 17769 15861 4782
+f 12542 17291 17770
+f 17195 2919 18011
+f 9052 11592 18038
+f 18039 18040 14821
+f 17931 18041 17918
+f 14160 9997 15555
+f 18041 18042 17919
+f 2742 7132 15488
+f 17918 18041 17919
+f 773 2097 11177
+f 13820 10151 15487
+f 18043 18044 18045
+f 16637 15889 15977
+f 14495 14499 14739
+f 15475 1171 1170
+f 10732 17814 14578
+f 3911 12296 3520
+f 18046 17978 11485
+f 6821 15194 6822
+f 18047 17981 17978
+f 18046 18047 17978
+f 18048 17982 17981
+f 18047 18048 17981
+f 18049 17983 17982
+f 18048 18049 17982
+f 18050 17984 17983
+f 18049 18050 17983
+f 18051 17985 17984
+f 18050 18051 17984
+f 18051 18052 17986
+f 17985 18051 17986
+f 18052 18053 17987
+f 17986 18052 17987
+f 18054 4921 17987
+f 18053 18054 17987
+f 7229 11690 7230
+f 3719 3903 13496
+f 18014 17628 18055
+f 2392 10832 2248
+f 17369 17368 17939
+f 17139 18056 16981
+f 18042 18057 17920
+f 17919 18042 17920
+f 18057 18058 17930
+f 15485 18059 625
+f 202 15485 625
+f 13223 3947 13224
+f 17621 16200 16194
+f 7638 7637 14463
+f 16068 16315 16069
+f 16708 16530 17766
+f 16530 17624 17766
+f 17767 17093 17155
+f 17809 17820 17156
+f 17607 16124 17021
+f 16124 16126 17021
+f 14462 14463 17862
+f 18060 6583 6585
+f 15346 6297 6146
+f 2853 2053 2052
+f 17082 17084 17705
+f 17220 17082 17705
+f 16901 17503 17505
+f 16899 16901 17505
+f 18061 18062 18063
+f 17663 17161 17234
+f 11103 8811 14553
+f 17935 17008 17007
+f 14366 16113 14367
+f 17809 17156 16114
+f 16023 16122 17887
+f 8361 8363 17624
+f 15976 17208 15977
+f 2077 16506 15939
+f 6746 14414 6744
+f 17330 17373 16699
+f 626 18064 420
+f 15484 15485 2160
+f 17920 18057 17930
+f 18058 18065 17943
+f 17930 18058 17943
+f 18066 17944 17943
+f 18067 18068 16236
+f 18059 18064 626
+f 18064 8568 420
+f 9712 14940 9713
+f 15064 8379 6337
+f 18069 17929 18070
+f 15880 15696 16248
+f 17206 15757 15759
+f 10853 10852 12175
+f 18071 11066 11031
+f 18072 14393 14392
+f 17815 18072 14392
+f 18072 18073 18016
+f 14393 18072 18016
+f 18073 18074 18017
+f 18016 18073 18017
+f 18075 18018 18017
+f 18074 18075 18017
+f 18076 18019 18018
+f 18075 18076 18018
+f 18077 18020 18019
+f 18076 18077 18019
+f 18078 18021 18020
+f 18077 18078 18020
+f 18079 18022 18021
+f 18078 18079 18021
+f 18080 18023 18022
+f 18079 18080 18022
+f 18081 18024 18023
+f 18080 18081 18023
+f 18082 18025 18024
+f 18081 18082 18024
+f 18083 18026 18025
+f 18082 18083 18025
+f 18084 18027 18026
+f 18083 18084 18026
+f 18085 18028 18027
+f 18084 18085 18027
+f 18086 18029 18028
+f 18085 18086 18028
+f 18087 18030 18029
+f 18086 18087 18029
+f 18088 18031 18030
+f 18087 18088 18030
+f 18089 18032 18031
+f 18088 18089 18031
+f 15293 18033 18032
+f 18089 15293 18032
+f 6162 6161 13766
+f 14576 13070 9178
+f 10307 10308 14416
+f 18034 14787 18090
+f 14107 6480 5606
+f 13766 7856 13767
+f 17970 14417 17977
+f 14419 13861 17921
+f 3908 2063 2062
+f 14489 9757 3718
+f 11717 13598 12483
+f 11718 11717 12483
+f 11042 14615 18036
+f 13947 12149 18037
+f 17972 18071 11031
+f 18091 11219 11066
+f 1261 9588 1263
+f 11722 11724 8447
+f 15061 14553 8810
+f 15004 18092 18055
+f 15863 8742 13038
+f 17702 17495 17497
+f 18093 17784 17786
+f 17002 17001 17223
+f 18065 18066 17943
+f 9711 9713 3733
+f 18094 17973 17944
+f 18066 18094 17944
+f 18095 17974 18096
+f 18094 17974 17973
+f 14560 14335 7538
+f 3939 3940 10236
+f 3605 17769 4782
+f 16234 18067 16236
+f 16197 16455 16337
+f 12921 12943 15643
+f 17580 18097 18098
+f 17368 17628 18014
+f 11723 14126 11724
+f 7232 17853 11717
+f 18099 18046 18100
+f 15012 6822 9996
+f 18101 18047 18046
+f 18099 18101 18046
+f 18102 18048 18047
+f 18101 18102 18047
+f 18103 18049 18048
+f 18102 18103 18048
+f 18104 18050 18049
+f 18103 18104 18049
+f 18105 18051 18050
+f 18104 18105 18050
+f 18105 18106 18052
+f 18051 18105 18052
+f 18106 18107 18053
+f 18052 18106 18053
+f 12800 18054 18053
+f 18107 12800 18053
+f 18071 18091 11066
+f 9833 15191 15190
+f 2248 15062 2223
+f 7327 3344 3528
+f 1315 3743 2913
+f 17690 15003 18055
+f 18108 18109 10430
+f 11790 14559 7208
+f 18110 16237 16236
+f 18068 18110 16236
+f 18111 16270 16237
+f 14146 18100 11485
+f 11047 11049 12229
+f 17628 17690 18055
+f 18100 14146 18112
+f 15990 10974 10973
+f 7240 16772 7238
+f 13550 13456 13452
+f 2724 15384 768
+f 16434 11049 11048
+f 7666 7668 16619
+f 10815 12554 11481
+f 10819 9052 9053
+f 18113 7328 5498
+f 18114 18115 18116
+f 9052 10819 10817
+f 4463 4715 2904
+f 12841 2121 14459
+f 17873 11415 11511
+f 2648 18117 2649
+f 14468 15011 14484
+f 17812 15009 15011
+f 18118 1929 13955
+f 4120 14686 2071
+f 643 18119 641
+f 16530 8361 17624
+f 17508 17369 17499
+f 16028 16027 2566
+f 8362 11252 8363
+f 6617 14013 2243
+f 16219 16267 16220
+f 625 18059 626
+f 16065 16067 16467
+f 18034 17853 14787
+f 18110 18111 16237
+f 14158 18120 12218
+f 15800 17064 18121
+f 18122 10882 18123
+f 4764 18122 18123
+f 18124 16272 16270
+f 18111 18124 16270
+f 6133 15312 4371
+f 18125 17839 17838
+f 8471 14288 13551
+f 2924 9048 7832
+f 17629 15024 15003
+f 827 8543 4291
+f 18126 18072 17815
+f 17882 18126 17815
+f 18126 18127 18073
+f 18072 18126 18073
+f 18127 18128 18074
+f 18073 18127 18074
+f 18129 18075 18074
+f 18128 18129 18074
+f 18130 18076 18075
+f 18129 18130 18075
+f 18131 18077 18076
+f 18130 18131 18076
+f 18132 18078 18077
+f 18131 18132 18077
+f 18133 18079 18078
+f 18132 18133 18078
+f 18134 18080 18079
+f 18133 18134 18079
+f 18135 18081 18080
+f 18134 18135 18080
+f 18136 18082 18081
+f 18135 18136 18081
+f 18137 18083 18082
+f 18136 18137 18082
+f 18138 18084 18083
+f 18137 18138 18083
+f 18139 18085 18084
+f 18138 18139 18084
+f 18140 18086 18085
+f 18139 18140 18085
+f 18141 18087 18086
+f 18140 18141 18086
+f 18142 18088 18087
+f 18141 18142 18087
+f 18143 18089 18088
+f 18142 18143 18088
+f 18144 15293 18089
+f 18143 18144 18089
+f 6162 13766 13765
+f 18144 1534 9665
+f 18035 18034 18090
+f 14786 18145 18090
+f 14710 13387 5606
+f 5605 14710 5606
+f 12718 7536 7727
+f 14125 12718 7727
+f 18036 13374 4092
+f 12717 4091 7536
+f 17853 18034 13598
+f 11717 17853 13598
+f 11043 11042 17971
+f 14615 18037 18036
+f 18146 11273 11219
+f 11202 11203 18147
+f 3533 8021 2420
+f 2817 9317 5910
+f 18091 18146 11219
+f 13575 6057 6056
+f 7107 14795 11915
+f 2959 18148 8707
+f 14998 17154 16846
+f 4445 6618 12415
+f 12170 7206 4580
+f 15333 8391 7931
+f 18149 18150 18151
+f 9639 9641 17158
+f 18152 18041 17931
+f 15194 18152 17931
+f 18152 18153 18042
+f 18041 18152 18042
+f 18154 18155 18156
+f 16497 1888 1602
+f 9106 17124 18157
+f 16888 2515 3021
+f 557 15035 18158
+f 17206 15759 16201
+f 11510 7232 11717
+f 14219 18159 14222
+f 2053 15971 1482
+f 3218 4000 383
+f 18160 18101 18099
+f 18161 18160 18099
+f 18162 18102 18101
+f 18160 18162 18101
+f 18163 18103 18102
+f 18162 18163 18102
+f 18164 18104 18103
+f 18163 18164 18103
+f 18165 18105 18104
+f 18164 18165 18104
+f 18165 18166 18106
+f 18105 18165 18106
+f 18166 13098 18107
+f 18106 18166 18107
+f 6887 5163 5162
+f 5063 13156 5061
+f 7922 2391 8014
+f 13156 5063 13157
+f 6618 13769 12415
+f 18159 9327 14222
+f 17690 17629 15003
+f 17636 15036 15024
+f 18153 18167 18057
+f 18042 18153 18057
+f 18167 18168 18058
+f 18057 18167 18058
+f 16576 1601 18169
+f 10854 11870 11869
+f 18170 18171 12554
+f 18117 2648 5169
+f 18171 18172 7240
+f 12554 18171 7240
+f 18172 14475 16772
+f 7240 18172 16772
+f 16772 14475 7637
+f 7637 14476 17862
+f 14476 18173 17862
+f 18174 17882 11113
+f 18173 18175 18176
+f 17862 18173 18176
+f 18175 18177 16291
+f 18176 18175 16291
+f 18177 18178 15544
+f 16291 18177 15544
+f 18178 18179 14523
+f 15544 18178 14523
+f 18179 18180 17812
+f 14523 18179 17812
+f 18180 16133 15009
+f 17812 18180 15009
+f 11870 12196 13130
+f 17629 17636 15024
+f 17681 15056 15036
+f 17636 17681 15036
+f 15051 4721 14432
+f 15169 13488 12420
+f 11140 4163 15733
+f 17046 15075 15056
+f 17745 16467 16597
+f 17611 17538 17599
+f 18181 18182 18183
+f 7353 12575 3717
+f 18168 18184 18065
+f 18058 18168 18065
+f 18185 18066 18065
+f 18184 18185 18065
+f 16496 1602 1601
+f 6745 2951 6746
+f 14618 14619 9934
+f 17465 17599 17526
+f 3083 3082 11040
+f 837 8754 8207
+f 5192 11880 8670
+f 10973 13956 13957
+f 18174 18126 17882
+f 6822 12557 3685
+f 18174 18186 18127
+f 18126 18174 18127
+f 18187 18128 18127
+f 18186 18187 18127
+f 18187 18188 18129
+f 18128 18187 18129
+f 18189 18130 18129
+f 18188 18189 18129
+f 18190 18131 18130
+f 18189 18190 18130
+f 18191 18132 18131
+f 18190 18191 18131
+f 18192 18133 18132
+f 18191 18192 18132
+f 18193 18134 18133
+f 18192 18193 18133
+f 18194 18135 18134
+f 18193 18194 18134
+f 18195 18136 18135
+f 18194 18195 18135
+f 18196 18137 18136
+f 18195 18196 18136
+f 18197 18138 18137
+f 18196 18197 18137
+f 18198 18139 18138
+f 18197 18198 18138
+f 18199 18140 18139
+f 18198 18199 18139
+f 18200 18141 18140
+f 18199 18200 18140
+f 18201 18142 18141
+f 18200 18201 18141
+f 18202 18143 18142
+f 18201 18202 18142
+f 9668 18144 18143
+f 18202 9668 18143
+f 1533 9666 9665
+f 9668 1534 18144
+f 14787 14786 18090
+f 715 15902 15901
+f 13226 14710 5605
+f 5759 13226 5605
+f 12718 12717 7536
+f 17971 4092 4091
+f 17969 15007 14417
+f 14418 14420 14419
+f 17853 7661 14787
+f 14786 14739 14499
+f 11723 13767 14126
+f 7856 12718 14125
+f 16388 11202 18147
+f 15292 16749 18147
+f 11724 14126 7827
+f 14125 7727 10307
+f 18203 18204 15997
+f 13576 13575 6056
+f 10697 14108 10698
+f 8447 11724 6440
+f 18205 18206 9473
+f 14126 14125 10307
+f 18207 18208 18209
+f 6886 18210 17836
+f 18211 18094 18066
+f 18185 18211 18066
+f 18095 18096 10890
+f 18211 18096 18094
+f 14336 7539 7538
+f 7208 14560 7538
+f 1347 14441 1852
+f 18212 18213 18214
+f 17681 17046 15056
+f 17293 17526 16063
+f 14037 13574 13576
+f 4754 7313 11211
+f 7010 10049 9905
+f 18215 13333 13335
+f 18216 18161 18215
+f 18217 18216 18215
+f 18218 18160 18161
+f 18216 18218 18161
+f 18219 18162 18160
+f 18218 18219 18160
+f 18220 18163 18162
+f 18219 18220 18162
+f 18221 18164 18163
+f 18220 18221 18163
+f 18222 18165 18164
+f 18221 18222 18164
+f 18222 18223 18166
+f 18165 18222 18166
+f 18223 13099 13098
+f 18166 18223 13098
+f 13100 18224 344
+f 1269 13099 18223
+f 2553 2732 8015
+f 8014 2553 8015
+f 12393 11789 11690
+f 15194 6821 18152
+f 17048 15088 15075
+f 3690 5052 3149
+f 18225 11279 11273
+f 13548 1773 9376
+f 12482 15909 14924
+f 18226 15042 18227
+f 2471 18228 18170
+f 17046 17048 15075
+f 18228 18229 18171
+f 18170 18228 18171
+f 18229 18230 18172
+f 18171 18229 18172
+f 18230 18231 14475
+f 18172 18230 14475
+f 18231 18232 14476
+f 14475 18231 14476
+f 18232 18233 18173
+f 14476 18232 18173
+f 18233 18234 18175
+f 18173 18233 18175
+f 18234 18235 18177
+f 18175 18234 18177
+f 18235 18236 18178
+f 18177 18235 18178
+f 18236 18237 18179
+f 18178 18236 18179
+f 18237 18238 18180
+f 18179 18237 18180
+f 18238 18239 16133
+f 18180 18238 16133
+f 18239 18240 15019
+f 16133 18239 15019
+f 18241 15035 15019
+f 18240 18241 15019
+f 15971 2053 17315
+f 18241 18158 15035
+f 14052 14172 2821
+f 2703 18117 5168
+f 17465 17611 17599
+f 4230 10840 5223
+f 15060 17878 15096
+f 18242 18243 18181
+f 4690 1320 1322
+f 1321 2719 3939
+f 18244 18245 17071
+f 17917 4639 18246
+f 12296 9991 9930
+f 11103 14553 14555
+f 16868 17459 17541
+f 16288 17541 17538
+f 1633 431 17691
+f 18247 17158 17160
+f 8695 8694 11511
+f 10304 10303 10852
+f 17353 16245 1623
+f 1623 17354 17353
+f 18248 18186 18174
+f 18249 18248 18174
+f 18250 18187 18186
+f 18248 18250 18186
+f 18250 18251 18188
+f 18187 18250 18188
+f 18252 18189 18188
+f 18251 18252 18188
+f 18253 18190 18189
+f 18252 18253 18189
+f 18254 18191 18190
+f 18253 18254 18190
+f 18255 18192 18191
+f 18254 18255 18191
+f 18256 18193 18192
+f 18255 18256 18192
+f 18257 18194 18193
+f 18256 18257 18193
+f 18258 18195 18194
+f 18257 18258 18194
+f 18259 18196 18195
+f 18258 18259 18195
+f 18260 18197 18196
+f 18259 18260 18196
+f 18261 18198 18197
+f 18260 18261 18197
+f 18262 18199 18198
+f 18261 18262 18198
+f 18263 18200 18199
+f 18262 18263 18199
+f 18264 18201 18200
+f 18263 18264 18200
+f 18265 18202 18201
+f 18264 18265 18201
+f 2939 9668 18202
+f 18265 2939 18202
+f 6188 14879 6187
+f 2939 1532 9668
+f 14786 10252 18145
+f 13790 8571 10459
+f 6068 13226 5759
+f 5758 6068 5759
+f 12717 17971 4091
+f 17971 18036 4092
+f 13656 16749 17969
+f 15007 14418 14417
+f 14489 14488 9757
+f 11394 6614 6613
+f 15163 15291 14854
+f 14488 11394 6613
+f 11203 15292 18147
+f 13405 13311 15007
+f 11041 13408 11042
+f 13407 13947 14615
+f 13455 13370 13454
+f 2929 2931 12976
+f 12483 13598 12484
+f 13387 14107 5606
+f 12598 6176 13310
+f 12102 13223 13222
+f 2561 2560 14468
+f 16368 15098 15088
+f 18266 4763 17867
+f 17191 15880 16249
+f 18267 16098 18268
+f 18269 9639 17158
+f 18270 7738 10882
+f 12963 1932 13386
+f 6095 4956 3329
+f 9640 14822 9641
+f 18271 18242 18181
+f 14079 9521 14080
+f 10936 15648 4628
+f 17293 17465 17526
+f 15096 17878 15097
+f 9261 5477 9262
+f 18272 13335 18273
+f 4445 12415 15290
+f 18274 18216 18217
+f 18275 18274 18217
+f 18276 18218 18216
+f 18274 18276 18216
+f 18277 18219 18218
+f 18276 18277 18218
+f 18278 18220 18219
+f 18277 18278 18219
+f 18279 18221 18220
+f 18278 18279 18220
+f 18279 18280 18222
+f 18221 18279 18222
+f 18280 1267 18223
+f 18222 18280 18223
+f 1268 18224 1269
+f 1267 1269 18223
+f 3354 3307 3551
+f 14488 6613 9757
+f 2732 2596 12499
+f 7758 2925 9774
+f 3120 6705 3347
+f 6706 11146 3348
+f 15990 13957 15168
+f 18146 18225 11273
+f 17864 13550 14214
+f 14750 825 11915
+f 9473 18206 18281
+f 11274 11280 2311
+f 18282 18283 18228
+f 2471 18282 18228
+f 18283 18284 18229
+f 18228 18283 18229
+f 18284 18285 18230
+f 18229 18284 18230
+f 18285 18286 18231
+f 18230 18285 18231
+f 18286 18287 18232
+f 18231 18286 18232
+f 18287 18288 18233
+f 18232 18287 18233
+f 18288 18289 18234
+f 18233 18288 18234
+f 18289 18290 18235
+f 18234 18289 18235
+f 18290 18291 18236
+f 18235 18290 18236
+f 18291 18292 18237
+f 18236 18291 18237
+f 18292 18293 18238
+f 18237 18292 18238
+f 18293 18294 18239
+f 18238 18293 18239
+f 18294 18295 18240
+f 18239 18294 18240
+f 18296 18241 18240
+f 18295 18296 18240
+f 18297 18158 18241
+f 18296 18297 18241
+f 6142 7037 3687
+f 18297 15428 18158
+f 15212 676 15213
+f 8458 8372 16483
+f 7758 12751 7246
+f 14251 2561 14468
+f 6821 3720 18152
+f 17931 9997 9996
+f 3720 3161 18153
+f 18152 3720 18153
+f 15465 1387 7924
+f 18298 7344 15394
+f 18299 1386 1388
+f 1387 1386 2581
+f 9641 17852 17159
+f 18007 17671 17459
+f 17873 11414 11415
+f 5477 7662 7737
+f 17873 18300 18249
+f 11414 17873 18249
+f 18301 18248 18249
+f 18300 18301 18249
+f 18302 18250 18248
+f 18301 18302 18248
+f 18303 18251 18250
+f 18302 18303 18250
+f 18304 18252 18251
+f 18303 18304 18251
+f 18305 18253 18252
+f 18304 18305 18252
+f 18306 18254 18253
+f 18305 18306 18253
+f 18307 18255 18254
+f 18306 18307 18254
+f 18308 18256 18255
+f 18307 18308 18255
+f 18309 18257 18256
+f 18308 18309 18256
+f 18310 18258 18257
+f 18309 18310 18257
+f 18311 18259 18258
+f 18310 18311 18258
+f 18312 18260 18259
+f 18311 18312 18259
+f 18313 18261 18260
+f 18312 18313 18260
+f 18314 18262 18261
+f 18313 18314 18261
+f 18315 18263 18262
+f 18314 18315 18262
+f 18316 18264 18263
+f 18315 18316 18263
+f 18317 18265 18264
+f 18316 18317 18264
+f 18318 2939 18265
+f 18317 18318 18265
+f 8572 9350 8570
+f 18318 2938 2939
+f 13225 14490 13226
+f 7536 7537 7728
+f 2061 6826 18319
+f 8026 2061 18319
+f 18037 10749 13374
+f 18036 18037 13374
+f 5772 18147 13656
+f 16749 15007 17969
+f 11394 15163 14854
+f 6614 11394 14854
+f 6067 9498 13225
+f 9497 9591 14490
+f 13311 13312 14420
+f 14418 13311 14420
+f 13768 11041 11043
+f 13408 14615 11042
+f 5169 2648 17827
+f 7207 7351 11690
+f 6700 13408 11041
+f 6624 6700 11041
+f 6176 12102 13222
+f 12221 3947 13223
+f 14402 14368 7829
+f 17862 18176 14462
+f 3383 7016 3384
+f 13368 13370 13369
+f 17506 17690 17628
+f 13644 17928 12553
+f 17048 16368 15088
+f 11442 10806 15417
+f 455 8218 7125
+f 11724 7827 6440
+f 3161 3162 18167
+f 18153 3161 18167
+f 3521 3520 9848
+f 1387 2581 7924
+f 17790 16052 411
+f 17611 16288 17538
+f 12719 5300 5437
+f 14523 17812 2560
+f 1643 1642 18320
+f 3905 18159 14219
+f 18321 18274 18275
+f 18322 18321 18275
+f 18323 18276 18274
+f 18321 18323 18274
+f 18324 18277 18276
+f 18323 18324 18276
+f 18325 18278 18277
+f 18324 18325 18277
+f 18326 18279 18278
+f 18325 18326 18278
+f 18326 18327 18280
+f 18279 18326 18280
+f 18327 18328 1267
+f 18280 18327 1267
+f 18329 879 1268
+f 18328 1268 1267
+f 3307 4742 3551
+f 18330 11362 11279
+f 18331 16576 18169
+f 9144 13797 11633
+f 3347 6706 3348
+f 18332 18333 18334
+f 16367 15106 15098
+f 16368 16367 15098
+f 18225 18330 11279
+f 12324 8474 12322
+f 18335 18336 18337
+f 11220 11274 308
+f 18338 18339 18283
+f 18282 18338 18283
+f 18339 18340 18284
+f 18283 18339 18284
+f 18340 18341 18285
+f 18284 18340 18285
+f 18341 18342 18286
+f 18285 18341 18286
+f 18342 18343 18287
+f 18286 18342 18287
+f 18343 18344 18288
+f 18287 18343 18288
+f 18344 18345 18289
+f 18288 18344 18289
+f 18345 18346 18290
+f 18289 18345 18290
+f 18346 18347 18291
+f 18290 18346 18291
+f 18347 18348 18292
+f 18291 18347 18292
+f 18348 18349 18293
+f 18292 18348 18293
+f 18349 18350 18294
+f 18293 18349 18294
+f 18350 18351 18295
+f 18294 18350 18295
+f 18351 18352 18296
+f 18295 18351 18296
+f 18353 18297 18296
+f 18352 18353 18296
+f 2800 1284 15426
+f 18353 18354 18297
+f 8372 3833 3832
+f 16483 8372 3832
+f 15907 11164 15290
+f 768 15384 769
+f 17047 17424 17048
+f 12398 15020 13347
+f 3162 7435 18168
+f 18167 3162 18168
+f 7435 3695 18184
+f 18168 7435 18184
+f 15465 7924 2756
+f 15463 15465 2756
+f 14941 2422 15430
+f 17755 15134 15106
+f 6075 6293 1897
+f 11787 6132 13349
+f 18355 18300 17873
+f 17872 18355 17873
+f 18356 18301 18300
+f 18355 18356 18300
+f 18357 18302 18301
+f 18356 18357 18301
+f 18357 18358 18303
+f 18302 18357 18303
+f 18359 18304 18303
+f 18358 18359 18303
+f 18359 18360 18305
+f 18304 18359 18305
+f 18361 18306 18305
+f 18360 18361 18305
+f 18362 18307 18306
+f 18361 18362 18306
+f 18363 18308 18307
+f 18362 18363 18307
+f 18364 18309 18308
+f 18363 18364 18308
+f 18365 18310 18309
+f 18364 18365 18309
+f 18366 18311 18310
+f 18365 18366 18310
+f 18367 18312 18311
+f 18366 18367 18311
+f 18368 18313 18312
+f 18367 18368 18312
+f 18369 18314 18313
+f 18368 18369 18313
+f 18370 18315 18314
+f 18369 18370 18314
+f 18371 18316 18315
+f 18370 18371 18315
+f 18372 18317 18316
+f 18371 18372 18316
+f 18373 18318 18317
+f 18372 18373 18317
+f 8570 2938 18318
+f 18373 8570 18318
+f 6924 6828 14429
+f 2277 13116 3325
+f 6826 6066 18374
+f 18319 6826 18374
+f 12149 2715 10749
+f 2716 12150 13790
+f 16388 18147 5772
+f 18375 9533 16978
+f 15291 2217 14854
+f 12416 8447 2217
+f 2220 6024 6721
+f 7635 9498 6067
+f 15290 12415 12416
+f 13769 11723 11722
+f 12415 13769 11722
+f 13769 13765 13767
+f 11789 7207 11690
+f 7209 7352 7351
+f 6624 11041 13768
+f 7658 6624 13768
+f 12102 12221 13223
+f 3114 3116 6023
+f 10983 9328 9327
+f 18159 10983 9327
+f 16086 13259 13261
+f 8373 17201 11977
+f 3352 3690 3149
+f 2930 15051 14432
+f 2071 14686 1937
+f 16367 17755 15106
+f 11140 14640 4163
+f 14393 17950 14394
+f 3697 18185 18184
+f 2963 15463 2756
+f 3695 3697 18184
+f 16288 16868 17541
+f 2964 2963 2756
+f 9807 8049 9804
+f 18210 6886 17783
+f 2431 2430 1138
+f 279 278 18376
+f 18377 18321 18322
+f 9260 18377 18322
+f 18378 18323 18321
+f 18377 18378 18321
+f 18379 18324 18323
+f 18378 18379 18323
+f 18380 18325 18324
+f 18379 18380 18324
+f 18381 18326 18325
+f 18380 18381 18325
+f 18381 18382 18327
+f 18326 18381 18327
+f 18382 18383 18328
+f 18327 18382 18328
+f 18329 1268 18328
+f 18383 18329 18328
+f 7826 7825 7200
+f 2280 310 352
+f 10768 4861 10769
+f 9054 4402 3351
+f 1314 5906 1315
+f 5908 14887 3743
+f 17689 15174 15134
+f 17755 17689 15134
+f 18330 18384 11441
+f 11067 11220 2670
+f 11362 18330 11441
+f 18385 18386 18338
+f 2470 18387 18282
+f 18386 18388 18339
+f 18338 18386 18339
+f 18388 18389 18340
+f 18339 18388 18340
+f 18389 18390 18341
+f 18340 18389 18341
+f 18390 18391 18342
+f 18341 18390 18342
+f 18391 18392 18343
+f 18342 18391 18343
+f 18392 18393 18344
+f 18343 18392 18344
+f 18393 18394 18345
+f 18344 18393 18345
+f 18394 18395 18346
+f 18345 18394 18346
+f 18395 18396 18347
+f 18346 18395 18347
+f 18396 14431 18348
+f 18347 18396 18348
+f 14431 5760 18349
+f 18348 14431 18349
+f 5760 8103 18350
+f 18349 5760 18350
+f 8103 5607 18351
+f 18350 8103 18351
+f 6481 18352 18351
+f 5607 6481 18351
+f 10699 18353 18352
+f 6481 10699 18352
+f 2800 18354 18353
+f 10699 2800 18353
+f 3833 12210 3834
+f 5084 2970 2969
+f 3524 3523 12552
+f 12550 12552 6825
+f 17688 15214 15174
+f 15910 15414 15446
+f 15097 18246 12365
+f 13955 11566 12708
+f 10206 18211 18185
+f 3697 10206 18185
+f 3369 6620 18397
+f 7757 2962 2964
+f 8506 4650 3015
+f 7348 7347 6530
+f 12708 12709 17872
+f 11511 12708 17872
+f 13497 18355 17872
+f 12709 13497 17872
+f 13496 18356 18355
+f 13497 13496 18355
+f 3903 18357 18356
+f 13496 3903 18356
+f 3903 9057 18358
+f 18357 3903 18358
+f 9056 18359 18358
+f 9057 9056 18358
+f 3699 18360 18359
+f 9056 3699 18359
+f 3698 18361 18360
+f 3699 3698 18360
+f 5714 18362 18361
+f 3698 5714 18361
+f 7828 18363 18362
+f 5714 7828 18362
+f 14416 18364 18363
+f 7828 14416 18363
+f 10308 18365 18364
+f 14416 10308 18364
+f 7728 18366 18365
+f 10308 7728 18365
+f 7537 18367 18366
+f 7728 7537 18366
+f 4093 18368 18367
+f 7537 4093 18367
+f 7430 18369 18368
+f 4093 7430 18368
+f 10750 18370 18369
+f 7430 10750 18369
+f 8547 18371 18370
+f 10750 8547 18370
+f 2717 18372 18371
+f 8547 2717 18371
+f 10459 18373 18372
+f 2717 10459 18372
+f 8571 8570 18373
+f 10459 8571 18373
+f 2223 15334 2224
+f 18398 14482 13884
+f 6066 6068 5758
+f 18374 6066 5758
+f 18037 12149 10749
+f 12150 2716 2715
+f 18384 18399 11516
+f 18147 16749 13656
+f 12575 14489 3718
+f 15291 12416 2217
+f 6721 7635 6067
+f 9498 9497 13225
+f 11723 13769 13767
+f 15907 15290 15291
+f 7753 14022 11392
+f 12426 8273 11480
+f 7207 7209 7351
+f 7540 13118 7352
+f 7658 13768 7854
+f 6161 7658 7854
+f 10838 3114 6023
+f 3115 3119 3116
+f 9153 10983 18159
+f 3905 9153 18159
+f 932 13489 15169
+f 462 464 15566
+f 9177 18400 14576
+f 4370 4549 7726
+f 1027 2724 768
+f 17689 17688 15174
+f 9661 6888 6890
+f 10890 18096 18211
+f 10206 10890 18211
+f 6183 2962 7757
+f 2579 6183 7757
+f 8468 14291 6188
+f 16868 18007 17459
+f 8468 9260 280
+f 14637 14639 15214
+f 2390 18377 9260
+f 8468 2390 9260
+f 2389 18378 18377
+f 2390 2389 18377
+f 12214 18379 18378
+f 2389 12214 18378
+f 12484 18380 18379
+f 12214 12484 18379
+f 13599 18381 18380
+f 12484 13599 18380
+f 18035 18382 18381
+f 13599 18035 18381
+f 18035 18090 18383
+f 18382 18035 18383
+f 18145 18329 18383
+f 18090 18145 18383
+f 7199 7826 7200
+f 10252 10251 18145
+f 9142 13795 13872
+f 6923 6828 6924
+f 6714 13817 1312
+f 1628 6714 1312
+f 17688 14637 15214
+f 14638 15222 14639
+f 11441 18384 11516
+f 18399 18401 11587
+f 18402 18403 18404
+f 11274 2311 308
+f 5773 13657 18386
+f 18385 5773 18386
+f 13657 17900 18388
+f 18386 13657 18388
+f 17900 17970 18389
+f 18388 17900 18389
+f 17970 17977 18390
+f 18389 17970 18390
+f 17977 17921 18391
+f 18390 17977 18391
+f 17921 13862 18392
+f 18391 17921 18392
+f 13862 15053 18393
+f 18392 13862 18393
+f 15053 8026 18394
+f 18393 15053 18394
+f 8026 18319 18395
+f 18394 8026 18395
+f 18319 18374 18396
+f 18395 18319 18396
+f 18374 5758 14431
+f 18396 18374 14431
+f 6616 9827 6825
+f 1298 18405 1286
+f 18406 18407 1287
+f 1286 18406 1287
+f 18407 18408 2107
+f 1287 18407 2107
+f 18408 18409 1434
+f 2107 18408 1434
+f 18410 1435 1434
+f 18409 18410 1434
+f 18411 2058 1435
+f 18410 18411 1435
+f 18412 2279 2058
+f 18411 18412 2058
+f 18413 2280 2279
+f 18412 18413 2279
+f 18414 919 18415
+f 2628 18416 18417
+f 18416 18418 18417
+f 921 6509 18419
+f 18420 8709 2280
+f 1845 18421 18422
+f 18413 18420 2280
+f 18420 18423 9076
+f 8709 18420 9076
+f 18424 8826 9076
+f 18423 18424 9076
+f 18424 18425 8982
+f 8826 18424 8982
+f 18425 18426 8983
+f 1992 1991 18427
+f 8982 18425 8983
+f 18415 919 18428
+f 1681 18429 18430
+f 18431 18414 18415
+f 919 921 18428
+f 18432 18433 18434
+f 18433 18414 18431
+f 18432 18434 18418
+f 18435 18433 18431
+f 18416 18432 18418
+f 18433 18435 18434
+f 18436 18437 1213
+f 18437 18438 1214
+f 2628 18417 18439
+f 9078 18436 1213
+f 1991 18430 18427
+f 18421 2628 18439
+f 18426 18440 9650
+f 18441 18442 18443
+f 8983 18426 9650
+f 18440 18444 9553
+f 4723 4722 1941
+f 9650 18440 9553
+f 18421 18439 18422
+f 18427 18445 18446
+f 1991 1681 18430
+f 1845 18422 18429
+f 18447 18448 700
+f 1681 1845 18429
+f 1213 18437 1214
+f 18438 18447 6076
+f 6076 18447 700
+f 1214 18438 6076
+f 18448 18449 717
+f 700 18448 717
+f 18449 18450 18451
+f 18451 18450 9170
+f 717 18449 18451
+f 18450 18452 9170
+f 18452 18453 18454
+f 9170 18452 18454
+f 18454 18453 18455
+f 18456 18457 18458
+f 18453 18459 18455
+f 18459 18460 18461
+f 1505 18462 18463
+f 4722 1942 1941
+f 18444 18464 9554
+f 9553 18444 9554
+f 18464 18465 8614
+f 18466 14838 18467
+f 9554 18464 8614
+f 18468 18469 18470
+f 9482 17039 3339
+f 18455 18459 18461
+f 18460 18468 18471
+f 18471 18468 18470
+f 18461 18460 18471
+f 18472 18473 18474
+f 18469 18475 18476
+f 654 2185 12589
+f 18477 18472 18474
+f 18478 18479 664
+f 9547 2185 9319
+f 18480 9183 18481
+f 18482 18478 9480
+f 9183 9185 18481
+f 9319 18482 9480
+f 18480 18481 18483
+f 9480 18478 664
+f 18484 18483 18485
+f 18484 18480 18483
+f 18477 18474 18486
+f 18487 18484 18485
+f 18476 18475 18488
+f 18489 18456 18490
+f 7057 3340 18462
+f 18491 18492 18493
+f 18465 18494 8615
+f 18495 8731 14960
+f 8614 18465 8615
+f 18494 18496 8753
+f 5776 18497 5777
+f 8615 18494 8753
+f 18470 18469 18476
+f 15633 4723 2165
+f 18498 18489 18499
+f 18475 18491 18488
+f 18500 18487 18501
+f 18457 18477 18486
+f 18500 18501 18473
+f 18472 18500 18473
+f 18502 18503 18504
+f 18487 18485 18501
+f 14291 279 14879
+f 9184 4599 1764
+f 18505 18506 2430
+f 9411 9189 9191
+f 18507 18502 18504
+f 2604 18508 2429
+f 14445 13172 18509
+f 1967 9594 18510
+f 2796 18511 2797
+f 18512 12057 17780
+f 3397 18513 18514
+f 1710 18515 1411
+f 1519 2101 1520
+f 484 719 18516
+f 18457 18486 18458
+f 18517 18518 18519
+f 18488 18491 18493
+f 18479 1887 665
+f 4723 1941 2165
+f 18492 18520 18521
+f 18496 18522 1266
+f 13198 13101 18523
+f 8753 18496 1266
+f 6366 17226 6367
+f 1266 18522 1097
+f 3394 18524 18525
+f 10892 18526 18095
+f 18527 18528 1209
+f 18529 18530 18531
+f 18525 18527 1209
+f 18493 18492 18521
+f 12977 15633 2165
+f 834 9077 9555
+f 18520 2710 18532
+f 18533 18499 18534
+f 18456 18458 18490
+f 18535 18536 14501
+f 18537 320 406
+f 18414 8841 919
+f 405 18537 406
+f 18538 18539 18540
+f 18354 15428 18297
+f 15428 18354 15426
+f 1240 18541 18542
+f 13860 938 939
+f 6336 3218 3219
+f 10120 10204 10203
+f 2935 2936 11038
+f 715 9422 716
+f 9154 15736 16130
+f 18543 18532 3514
+f 18538 18540 395
+f 17605 18544 18545
+f 9422 18546 716
+f 2807 18547 2808
+f 18541 18548 18542
+f 4919 13860 939
+f 434 437 4922
+f 664 18479 665
+f 18499 18490 18534
+f 18549 14505 556
+f 9222 18484 18487
+f 18550 1336 18551
+f 844 389 779
+f 18528 18552 1210
+f 18553 18554 18555
+f 1209 18528 1210
+f 8873 1373 1334
+f 18552 3223 18541
+f 18556 1992 18557
+f 8940 18558 18559
+f 18560 18553 18561
+f 14212 18560 18561
+f 18562 18563 18564
+f 7133 12977 2165
+f 18565 18566 18500
+f 18490 18458 8603
+f 2054 1482 4912
+f 18455 18461 18567
+f 7148 7151 18568
+f 3395 3394 18569
+f 1284 1283 15426
+f 680 2435 5098
+f 1408 18570 18571
+f 2627 18416 2628
+f 1451 14427 9351
+f 18572 707 18573
+f 15427 18574 15428
+f 10504 5905 7062
+f 18575 18576 15943
+f 18574 555 15428
+f 18577 18578 555
+f 18574 18577 555
+f 18579 18549 18578
+f 18577 18579 18578
+f 18580 4642 14143
+f 18579 18581 18549
+f 18537 18582 318
+f 14544 12604 564
+f 3325 10957 11788
+f 2361 7947 2352
+f 9998 2564 9999
+f 15126 9045 9657
+f 18490 8603 18534
+f 18458 18486 1241
+f 18583 18584 9220
+f 12167 12945 12633
+f 9351 1454 1451
+f 18585 18586 705
+f 16794 18560 14212
+f 52 18005 53
+f 18056 16982 16981
+f 18587 18556 18557
+f 18169 1601 2824
+f 18588 18517 18589
+f 8869 597 324
+f 997 1252 6506
+f 18590 5662 4935
+f 18591 6473 16722
+f 1718 6740 4306
+f 2621 18563 18562
+f 14220 346 14222
+f 18486 1242 1241
+f 11146 18592 18593
+f 13884 3179 2735
+f 346 14220 14221
+f 18398 13884 2735
+f 14505 12116 556
+f 13927 15250 13929
+f 1807 2935 9259
+f 3325 10679 10957
+f 1283 18594 15427
+f 15426 1283 15427
+f 18595 18574 15427
+f 18594 18595 15427
+f 18596 18577 18574
+f 18595 18596 18574
+f 18597 18579 18577
+f 18596 18597 18577
+f 18598 18581 18579
+f 18597 18598 18579
+f 4339 4340 10581
+f 18598 11788 18581
+f 2977 11232 11234
+f 8683 8682 12270
+f 347 346 14221
+f 11908 17407 15396
+f 18474 7764 1242
+f 18486 18474 1242
+f 2289 7008 8698
+f 10154 12146 17851
+f 18599 18471 18600
+f 9171 18454 18601
+f 9106 18602 9107
+f 18603 551 550
+f 1495 15894 8613
+f 9555 18604 18605
+f 2437 16173 16956
+f 16787 17096 16794
+f 15126 9657 18606
+f 18607 18608 18609
+f 18610 18611 18536
+f 13966 9875 9876
+f 14221 9329 15126
+f 18489 18490 18499
+f 15126 18612 14221
+f 18578 18549 556
+f 18612 18613 347
+f 14221 18612 347
+f 18614 15399 18615
+f 12356 12633 13860
+f 18616 18617 1285
+f 14491 1285 2801
+f 18617 18618 1283
+f 1285 18617 1283
+f 18618 18619 18594
+f 1283 18618 18594
+f 18620 18595 18594
+f 18619 18620 18594
+f 18621 18596 18595
+f 18620 18621 18595
+f 18622 18597 18596
+f 18621 18622 18596
+f 18623 18598 18597
+f 18622 18623 18597
+f 18624 11788 18598
+f 18623 18624 18598
+f 3457 1377 13924
+f 3837 3747 8612
+f 4621 18625 18626
+f 14933 14878 18627
+f 18433 9191 18414
+f 18473 7765 7764
+f 14384 7339 10233
+f 15396 453 11908
+f 646 18628 18629
+f 18535 18610 18536
+f 9478 997 6506
+f 1639 18630 1640
+f 18631 18632 2438
+f 17037 18631 2437
+f 18633 18634 2438
+f 18632 18633 2438
+f 18635 18636 18634
+f 18633 18635 18634
+f 8813 9797 10751
+f 18637 18638 1785
+f 8998 546 545
+f 9065 18639 18640
+f 1985 1984 18641
+f 6711 9709 5354
+f 18606 18642 18612
+f 15126 18606 18612
+f 18642 18643 18613
+f 18612 18642 18613
+f 18643 18644 18616
+f 18613 18643 18616
+f 18644 18645 18617
+f 18616 18644 18617
+f 18645 18646 18618
+f 18617 18645 18618
+f 18646 18647 18619
+f 18618 18646 18619
+f 18648 18620 18619
+f 18647 18648 18619
+f 18649 18621 18620
+f 18648 18649 18620
+f 18650 18622 18621
+f 18649 18650 18621
+f 18651 18623 18622
+f 18650 18651 18622
+f 18652 18624 18623
+f 18651 18652 18623
+f 8612 3747 3926
+f 5905 16916 7062
+f 1520 2101 2102
+f 1324 2277 3324
+f 3185 11908 453
+f 6495 6361 5359
+f 18653 18271 18654
+f 9228 224 1850
+f 18454 18455 18601
+f 18610 18655 18656
+f 1824 1925 1924
+f 9105 17124 9106
+f 1817 18638 18637
+f 15591 2099 18657
+f 18658 18659 18636
+f 18635 18658 18636
+f 18660 18661 18659
+f 18658 18660 18659
+f 18662 6507 18663
+f 18664 18665 18661
+f 1176 3713 2123
+f 18666 18667 18668
+f 13299 13301 18669
+f 1537 9564 3651
+f 806 3701 7212
+f 5354 9709 9710
+f 18670 18671 18642
+f 18606 18670 18642
+f 18671 18672 18643
+f 18642 18671 18643
+f 18672 18673 18644
+f 18643 18672 18644
+f 18673 18674 18645
+f 18644 18673 18645
+f 18674 18675 18646
+f 18645 18674 18646
+f 18675 18676 18647
+f 18646 18675 18647
+f 18676 18677 18648
+f 18647 18676 18648
+f 18677 18678 18649
+f 18648 18677 18649
+f 18678 18679 18650
+f 18649 18678 18650
+f 18679 18680 18651
+f 18650 18679 18651
+f 18680 18681 18652
+f 18651 18680 18652
+f 12763 18682 18683
+f 11251 7542 7348
+f 18684 18320 1324
+f 906 9990 904
+f 9002 10423 10422
+f 18217 18272 18275
+f 18685 15396 17407
+f 18686 18685 17407
+f 1525 646 18629
+f 18611 18610 18656
+f 18655 18687 18688
+f 18656 18655 18688
+f 6507 1817 18663
+f 18663 1817 18637
+f 18660 18664 18661
+f 18689 18690 18665
+f 18664 18689 18665
+f 18691 18692 18690
+f 18689 18691 18690
+f 8299 8390 3181
+f 18693 914 18662
+f 8870 8869 324
+f 10698 2801 2800
+f 18694 18695 12166
+f 2143 2145 4100
+f 9659 18696 18670
+f 5211 11221 13332
+f 18696 18697 18671
+f 18670 18696 18671
+f 18697 18698 18672
+f 18671 18697 18672
+f 18699 18673 18672
+f 18698 18699 18672
+f 18700 18674 18673
+f 18699 18700 18673
+f 18701 18675 18674
+f 18700 18701 18674
+f 18702 18676 18675
+f 18701 18702 18675
+f 18702 18703 18677
+f 18676 18702 18677
+f 18703 18704 18678
+f 18677 18703 18678
+f 18704 18705 18679
+f 18678 18704 18679
+f 18705 18706 18680
+f 18679 18705 18680
+f 18706 18707 18681
+f 18680 18706 18681
+f 18707 18708 18684
+f 18681 18707 18684
+f 18709 18710 18711
+f 18684 18708 18320
+f 17336 17270 9180
+f 18712 14072 10885
+f 7954 6425 6424
+f 14999 7357 15000
+f 7736 7735 9660
+f 665 1887 8755
+f 622 914 18693
+f 5243 1299 5376
+f 18713 18714 18692
+f 18715 622 18693
+f 18691 18713 18692
+f 18716 18717 18714
+f 18713 18716 18714
+f 18718 18719 18717
+f 18716 18718 18717
+f 3434 10589 3435
+f 7216 8388 8298
+f 9084 1112 597
+f 9006 9226 9343
+f 17120 18720 14171
+f 18721 9107 11096
+f 18722 18696 9659
+f 18723 14280 18724
+f 18725 18697 18696
+f 18722 18725 18696
+f 18726 18698 18697
+f 18725 18726 18697
+f 18727 18699 18698
+f 18726 18727 18698
+f 18728 18700 18699
+f 18727 18728 18699
+f 18729 18701 18700
+f 18728 18729 18700
+f 18730 18702 18701
+f 18729 18730 18701
+f 18730 18731 18703
+f 18702 18730 18703
+f 18731 18732 18704
+f 18703 18731 18704
+f 18732 18733 18705
+f 18704 18732 18705
+f 18733 18734 18706
+f 18705 18733 18706
+f 18734 18735 18707
+f 18706 18734 18707
+f 18735 18736 18708
+f 18707 18735 18708
+f 8398 9659 18695
+f 7747 7748 4078
+f 18737 9772 9773
+f 11516 18399 11587
+f 9657 18670 18606
+f 15553 14338 16713
+f 5517 3386 695
+f 344 343 709
+f 18738 1641 18739
+f 914 6507 18662
+f 18718 18740 18741
+f 18719 18718 18741
+f 18740 18742 18743
+f 18741 18740 18743
+f 18742 18744 18745
+f 18743 18742 18745
+f 18744 10249 18746
+f 18747 18748 18749
+f 18745 18744 18746
+f 14284 10586 14282
+f 18670 9657 9659
+f 4331 8999 741
+f 1103 16054 16959
+f 14966 18750 14967
+f 8870 324 741
+f 3000 4641 9743
+f 18443 18442 18751
+f 18752 18725 18722
+f 16492 18752 18722
+f 18753 18726 18725
+f 18752 18753 18725
+f 18754 18727 18726
+f 18753 18754 18726
+f 18755 18728 18727
+f 18754 18755 18727
+f 18756 18729 18728
+f 18755 18756 18728
+f 18757 18730 18729
+f 18756 18757 18729
+f 18757 18758 18731
+f 18730 18757 18731
+f 18758 18759 18732
+f 18731 18758 18732
+f 18759 18760 18733
+f 18732 18759 18733
+f 18760 18761 18734
+f 18733 18760 18734
+f 18761 18762 18735
+f 18734 18761 18735
+f 18762 18763 18736
+f 18735 18762 18736
+f 18763 8976 8215
+f 18736 18763 8215
+f 9659 8398 8397
+f 8215 8976 1644
+f 1784 1927 1785
+f 992 15776 780
+f 633 8998 545
+f 6690 6438 14256
+f 620 622 18715
+f 18739 620 18715
+f 10249 10248 18764
+f 18765 3390 18738
+f 18746 10249 18764
+f 18766 10248 18767
+f 18764 10248 18768
+f 18766 18768 10248
+f 18768 18769 18405
+f 8222 6426 8223
+f 927 926 1276
+f 18407 18406 18156
+f 1413 18770 18771
+f 4918 12356 13860
+f 8272 963 7561
+f 8603 18458 1241
+f 8894 1156 9912
+f 18772 671 429
+f 14338 15000 16713
+f 11429 11286 18773
+f 18774 18775 17785
+f 8956 18776 17704
+f 8999 9000 741
+f 14486 16492 8397
+f 18777 18778 18779
+f 18780 18753 18752
+f 16491 18780 18752
+f 18781 18754 18753
+f 18780 18781 18753
+f 18782 18755 18754
+f 18781 18782 18754
+f 18783 18756 18755
+f 18782 18783 18755
+f 18784 18757 18756
+f 18783 18784 18756
+f 18784 18785 18758
+f 18757 18784 18758
+f 18785 18786 18759
+f 18758 18785 18759
+f 18786 18787 18760
+f 18759 18786 18760
+f 18787 18788 18761
+f 18760 18787 18761
+f 18788 18789 18762
+f 18761 18788 18762
+f 18789 18790 18763
+f 18762 18789 18763
+f 18790 18791 8976
+f 18763 18790 8976
+f 18320 1325 1324
+f 18320 1642 1325
+f 580 582 18792
+f 14370 17815 14454
+f 18401 18793 11664
+f 15021 18794 18795
+f 864 588 1683
+f 1682 864 1683
+f 1641 620 18739
+f 417 587 1528
+f 18406 1286 18405
+f 3390 1641 18738
+f 18796 18408 18407
+f 14415 15926 14414
+f 4796 1579 4797
+f 5169 17827 399
+f 1417 18797 10149
+f 9875 13966 18798
+f 15909 14670 14924
+f 15913 15815 18799
+f 1611 17575 992
+f 15553 16713 15581
+f 4781 15874 4782
+f 9403 14295 14294
+f 15554 15553 15581
+f 1602 1890 1603
+f 18800 18801 18802
+f 10025 16421 16655
+f 8478 8999 4331
+f 18803 18780 16491
+f 18121 17064 11388
+f 18804 18781 18780
+f 18803 18804 18780
+f 18805 18782 18781
+f 18804 18805 18781
+f 18806 18783 18782
+f 18805 18806 18782
+f 18807 18784 18783
+f 18806 18807 18783
+f 18807 18808 18785
+f 18784 18807 18785
+f 18808 18809 18786
+f 18785 18808 18786
+f 18809 18810 18787
+f 18786 18809 18787
+f 18810 18811 18788
+f 18787 18810 18788
+f 18811 18812 18789
+f 18788 18811 18789
+f 18812 18813 18790
+f 18789 18812 18790
+f 6040 18791 18790
+f 18813 6040 18790
+f 6040 5938 18791
+f 6039 14275 5938
+f 6900 13371 6901
+f 8458 1708 8549
+f 18814 18815 18816
+f 694 4481 4480
+f 18817 18818 18819
+f 18820 15612 18821
+f 1527 417 1528
+f 505 507 2484
+f 18822 6505 18823
+f 18824 18822 18823
+f 18825 18826 18827
+f 18828 18409 18408
+f 18796 18826 18829
+f 18830 18410 18409
+f 18828 18830 18409
+f 18831 18411 18410
+f 18830 18831 18410
+f 18832 18412 18411
+f 18831 18832 18411
+f 18833 18413 18412
+f 18832 18833 18412
+f 18834 18420 18413
+f 18833 18834 18413
+f 18835 18423 18420
+f 18834 18835 18420
+f 17448 18836 16499
+f 18837 3581 18838
+f 4650 2952 933
+f 17145 16028 16391
+f 18837 3579 3581
+f 17575 1611 1610
+f 2469 2468 2643
+f 15874 3605 4782
+f 14995 17575 1610
+f 16664 15628 15582
+f 18799 6190 17781
+f 2111 1102 2112
+f 15554 15581 15578
+f 17108 2306 13806
+f 4943 18839 953
+f 18840 18803 18841
+f 18841 18842 18843
+f 18844 18804 18803
+f 18840 18844 18803
+f 18845 18805 18804
+f 18844 18845 18804
+f 18846 18806 18805
+f 18845 18846 18805
+f 18847 18807 18806
+f 18846 18847 18806
+f 18847 18848 18808
+f 18807 18847 18808
+f 18848 18849 18809
+f 18808 18848 18809
+f 18849 18850 18810
+f 18809 18849 18810
+f 18850 18851 18811
+f 18810 18850 18811
+f 18852 18812 18811
+f 18851 18852 18811
+f 15006 18813 18812
+f 18852 15006 18812
+f 18853 6040 18813
+f 15006 18853 18813
+f 12148 12353 7259
+f 18853 6039 6040
+f 6358 6360 7260
+f 13372 13373 13286
+f 3394 18525 18569
+f 6039 18853 14701
+f 9015 9014 18854
+f 920 9544 3186
+f 18855 12460 18856
+f 18857 18817 18819
+f 6505 3390 18765
+f 1949 683 1804
+f 18858 18822 18824
+f 18823 6505 18765
+f 18419 18858 18859
+f 18859 18858 18824
+f 18428 18419 18860
+f 18860 18419 18859
+f 18415 18428 18861
+f 18861 18428 18860
+f 18862 18431 18863
+f 18863 18415 18861
+f 18864 18424 18423
+f 18865 18435 18862
+f 18835 18864 18423
+f 18864 18866 18425
+f 18424 18864 18425
+f 18866 18867 18426
+f 18425 18866 18426
+f 18867 18868 18440
+f 18426 18867 18440
+f 18868 18869 18444
+f 15559 18870 18871
+f 7668 7862 16500
+f 5104 5106 14687
+f 18872 16657 18873
+f 17890 6945 6958
+f 18109 2467 10430
+f 17575 15776 992
+f 5509 18874 5510
+f 2787 15566 6191
+f 17448 17447 15543
+f 15628 15554 15578
+f 15628 15578 15582
+f 2786 9488 462
+f 9337 1847 463
+f 18875 18843 18876
+f 14977 18877 18878
+f 18879 18844 18840
+f 18880 18879 18840
+f 18881 18845 18844
+f 18879 18881 18844
+f 18882 18846 18845
+f 18881 18882 18845
+f 18883 18847 18846
+f 18882 18883 18846
+f 18883 18884 18848
+f 18847 18883 18848
+f 18884 18885 18849
+f 18848 18884 18849
+f 18886 18850 18849
+f 18885 18886 18849
+f 18887 18851 18850
+f 18886 18887 18850
+f 1550 18852 18851
+f 18887 1550 18851
+f 9208 15006 18852
+f 1550 9208 18852
+f 4712 18888 18889
+f 13470 18627 14878
+f 9148 11795 14933
+f 18890 1669 6329
+f 7952 851 18891
+f 14072 18712 14401
+f 963 8272 18892
+f 11177 2097 15473
+f 1371 12919 1013
+f 1376 13286 13645
+f 13468 18893 1127
+f 1127 18893 407
+f 822 824 322
+f 5240 9410 5241
+f 587 683 1949
+f 321 822 322
+f 1528 587 1949
+f 683 840 1804
+f 507 18894 8984
+f 2484 507 8984
+f 18894 18895 1818
+f 8984 18894 1818
+f 18895 18896 1814
+f 1818 18895 1814
+f 18431 18415 18863
+f 18896 18897 765
+f 18440 18868 18444
+f 18898 18434 18865
+f 18869 18899 18464
+f 18444 18869 18464
+f 18899 18900 18465
+f 18464 18899 18465
+f 18900 18901 18494
+f 18465 18900 18494
+f 18901 15605 18496
+f 18494 18901 18496
+f 6191 18902 1605
+f 15862 15559 18871
+f 5406 5104 14687
+f 6366 16716 17226
+f 18903 18904 18905
+f 17109 17108 13806
+f 1714 12603 1050
+f 16151 14109 14111
+f 17447 2619 15543
+f 18906 1050 12603
+f 16664 15582 15816
+f 2611 16619 2612
+f 9426 4774 9326
+f 15945 16664 15816
+f 463 1847 1849
+f 4774 12057 9326
+f 18907 18879 18880
+f 18908 18880 18875
+f 18909 18881 18879
+f 18907 18909 18879
+f 18910 18882 18881
+f 18909 18910 18881
+f 18911 18883 18882
+f 18910 18911 18882
+f 18911 18912 18884
+f 18883 18911 18884
+f 18912 18913 18885
+f 18884 18912 18885
+f 18913 18914 18886
+f 18885 18913 18886
+f 18914 1551 18887
+f 18886 18914 18887
+f 18915 17974 18095
+f 18887 1551 1550
+f 8891 9208 8301
+f 15006 14701 18853
+f 2150 2484 2486
+f 2606 8742 15863
+f 375 15486 534
+f 17040 14962 14964
+f 1650 18916 9409
+f 17942 18917 17946
+f 4016 4015 9003
+f 713 551 5945
+f 1376 1872 13286
+f 1669 18890 18918
+f 18919 18920 18921
+f 437 13645 4922
+f 18667 1885 1887
+f 5941 13658 5942
+f 1252 1251 18630
+f 582 394 18792
+f 823 4158 824
+f 14435 17377 18922
+f 1814 18896 765
+f 18897 18923 685
+f 18418 18434 18924
+f 18434 18435 18865
+f 18417 18418 18925
+f 18434 18898 18924
+f 18417 18925 18926
+f 18439 18417 18926
+f 18435 18431 18862
+f 18418 18924 18925
+f 8037 8297 8035
+f 18439 18926 18927
+f 18496 15605 18522
+f 18928 18929 18930
+f 9427 1551 17473
+f 1210 18552 18541
+f 3223 3222 18548
+f 18554 865 18550
+f 17779 18931 18932
+f 17817 17781 1604
+f 14246 14248 18933
+f 18934 18935 18936
+f 18937 18938 18939
+f 18940 18941 18942
+f 16321 18943 17375
+f 55 18004 52
+f 12604 12603 1617
+f 18944 10969 4653
+f 15944 2610 2612
+f 18906 15540 14994
+f 15872 15945 16457
+f 18945 16404 16561
+f 15872 16457 4161
+f 4160 15872 4161
+f 18880 18946 18907
+f 15945 15816 16457
+f 18947 18909 18907
+f 18948 18947 18907
+f 18947 18949 18910
+f 18909 18947 18910
+f 18949 18950 18911
+f 18910 18949 18911
+f 18950 18951 18912
+f 18911 18950 18912
+f 18951 18952 18913
+f 18912 18951 18913
+f 18952 17473 18914
+f 18913 18952 18914
+f 7938 8458 8549
+f 18914 17473 1551
+f 18953 18954 929
+f 5817 3245 3247
+f 18955 18956 18957
+f 14542 14544 564
+f 18958 18959 18960
+f 18961 18962 18116
+f 12654 18963 12652
+f 11932 11935 11934
+f 18964 18965 16940
+f 16697 18966 18967
+f 2794 18968 18969
+f 3723 1974 18970
+f 18971 18972 318
+f 1328 1709 1329
+f 437 1376 13645
+f 18973 18974 18585
+f 4599 1765 1764
+f 6610 6720 1245
+f 17200 613 17201
+f 12282 5321 11332
+f 706 18545 707
+f 17377 18975 18922
+f 765 18897 685
+f 18923 18976 3391
+f 18430 18977 18978
+f 18427 18430 18978
+f 18541 3223 18548
+f 1373 8938 18979
+f 18980 18979 8940
+f 813 951 1997
+f 15001 18981 18982
+f 17064 18983 17065
+f 18422 18439 18927
+f 5757 6926 1942
+f 18517 18519 18589
+f 18430 18429 18977
+f 18687 18984 18985
+f 18986 18489 18498
+f 9716 3386 3182
+f 14370 11113 17882
+f 1561 18987 1562
+f 8693 9427 17473
+f 18988 18989 18990
+f 4580 7206 4581
+f 17609 18991 18962
+f 14018 18992 14019
+f 18993 17587 16930
+f 18994 18995 18996
+f 18997 18998 2745
+f 209 14542 564
+f 18999 6600 457
+f 17870 542 19000
+f 12604 1617 564
+f 219 2844 220
+f 9278 10841 9279
+f 16574 8992 3012
+f 12385 16574 3012
+f 19001 19002 18947
+f 18948 18907 19003
+f 19002 1759 18949
+f 18947 19002 18949
+f 1759 9305 18950
+f 18949 1759 18950
+f 9305 18118 18951
+f 18950 9305 18951
+f 18118 17472 18952
+f 18951 18118 18952
+f 10698 14491 2801
+f 18952 17472 17473
+f 19004 19005 19006
+f 2742 2741 7132
+f 624 353 19007
+f 353 19008 19007
+f 9349 19009 479
+f 19010 9347 9083
+f 11587 18401 11664
+f 8656 8864 19011
+f 15563 19012 16685
+f 19013 6931 4850
+f 19014 16698 18967
+f 2407 19015 9733
+f 2095 2155 19016
+f 19017 19018 18966
+f 19019 19020 19021
+f 15496 10378 17942
+f 18095 10890 10892
+f 1649 19022 19023
+f 347 18613 14491
+f 6317 7936 6431
+f 527 1025 4634
+f 13655 13764 13658
+f 350 18480 18484
+f 19024 19025 4475
+f 685 18923 3391
+f 8755 1886 8872
+f 18429 19026 18977
+f 19027 1689 3391
+f 6601 19028 458
+f 19029 207 15529
+f 19030 19031 18631
+f 17037 19030 18631
+f 207 15541 12602
+f 19032 18632 18631
+f 18422 18927 19026
+f 19033 19034 14543
+f 15528 19034 15529
+f 18429 18422 19026
+f 19031 19032 18631
+f 12475 6537 6538
+f 19035 18633 18632
+f 19032 19035 18632
+f 15562 15563 16685
+f 17770 16577 15455
+f 19036 16692 16685
+f 1659 7121 4543
+f 19037 9658 9044
+f 19038 4543 4566
+f 2514 9099 3022
+f 2990 8957 2991
+f 1847 9338 16386
+f 9670 4162 8992
+f 6037 1757 19002
+f 19003 19001 18948
+f 9389 1747 7650
+f 19002 1757 1759
+f 14791 13124 14404
+f 15806 2276 15807
+f 9305 19039 18118
+f 8694 8693 17473
+f 12919 1371 1370
+f 5935 3933 1660
+f 19040 19041 19042
+f 4372 4371 15312
+f 19043 19006 19044
+f 19045 19043 19044
+f 5372 5243 19046
+f 19047 19048 19049
+f 16522 4891 17787
+f 15486 8553 534
+f 19050 16393 17137
+f 19012 19036 16685
+f 19051 16717 16692
+f 18999 19013 6600
+f 4934 19052 19015
+f 19053 5789 19010
+f 16697 19017 18966
+f 18688 18687 18985
+f 18917 19054 17946
+f 19055 15184 19056
+f 19057 19058 19059
+f 9476 2625 9179
+f 9476 4849 2625
+f 936 6501 9407
+f 15315 17194 16696
+f 2430 18506 1136
+f 18920 19060 19061
+f 19062 19063 19064
+f 18566 9222 18487
+f 18921 18920 19061
+f 18976 19027 3391
+f 9492 580 18792
+f 19034 19029 15529
+f 19065 1690 1689
+f 19066 18635 18633
+f 15541 19067 16618
+f 19035 19066 18633
+f 19068 18658 18635
+f 19066 19068 18635
+f 19069 18660 18658
+f 955 777 15775
+f 19068 19069 18658
+f 17797 15594 15596
+f 19070 19071 15928
+f 207 12602 15529
+f 6827 19072 4494
+f 19073 18664 18660
+f 1798 955 15775
+f 19069 19073 18660
+f 19036 19051 16692
+f 19074 16719 19075
+f 19076 18689 18664
+f 15312 6037 19001
+f 19073 19076 18664
+f 3440 3623 17714
+f 1757 6037 4121
+f 2611 7666 16619
+f 15250 19077 15249
+f 18501 1543 7765
+f 15768 19078 15766
+f 19079 19080 19081
+f 19081 7058 17246
+f 1885 13468 1126
+f 9733 19015 19082
+f 717 18451 19083
+f 19083 18451 9169
+f 19084 19085 19086
+f 19087 19084 19086
+f 19041 19088 19089
+f 19088 19090 19089
+f 19045 19044 19091
+f 19092 19045 19091
+f 19048 5784 1561
+f 19093 19047 19049
+f 1456 395 1457
+f 9327 9329 14220
+f 19090 6221 4645
+f 18540 18605 1841
+f 312 19094 19008
+f 19095 1333 19096
+f 5239 13466 19097
+f 9347 9349 9083
+f 17945 16710 16462
+f 1058 2916 208
+f 1974 2095 18970
+f 9081 14704 9179
+f 2624 1978 3201
+f 19098 19017 16697
+f 19049 1561 1560
+f 4636 1650 9409
+f 19051 16719 16717
+f 19099 4480 1160
+f 19100 5944 18603
+f 8775 4794 5661
+f 19101 19102 916
+f 5520 1327 5521
+f 13052 19103 15185
+f 1886 1126 8872
+f 19027 19065 1689
+f 19104 19105 1690
+f 1252 18630 1639
+f 1929 11566 13955
+f 19106 18691 18689
+f 19076 19106 18689
+f 19107 18713 18691
+f 19106 19107 18691
+f 19108 18716 18713
+f 19107 19108 18713
+f 19108 19109 18718
+f 483 10254 718
+f 18716 19108 18718
+f 777 773 11176
+f 7128 9408 9475
+f 19109 19110 18740
+f 14213 14212 17631
+f 18718 19109 18740
+f 19110 19111 18742
+f 18740 19110 18742
+f 19111 19112 18744
+f 18742 19111 18744
+f 18793 19113 11751
+f 13123 1278 14811
+f 19114 2937 19115
+f 6754 8697 390
+f 18744 19112 10249
+f 2912 19116 3940
+f 6506 1252 1639
+f 1161 18493 18543
+f 19117 19118 19119
+f 19118 19120 18437
+f 18586 19121 706
+f 1285 1284 2801
+f 19122 6499 8874
+f 14879 6188 14291
+f 15468 18149 15469
+f 19080 19123 19081
+f 1523 12828 1369
+f 344 709 13100
+f 19124 849 2473
+f 9170 18454 9171
+f 19125 19126 19127
+f 19128 19129 19130
+f 19088 19131 19090
+f 19131 19132 19090
+f 19133 19134 19135
+f 19136 19137 19138
+f 5784 5786 18987
+f 19049 19048 1561
+f 783 15487 1846
+f 2120 2119 366
+f 19139 19140 19141
+f 19140 19142 19143
+f 19089 19090 4645
+f 19132 6222 6221
+f 5238 19097 18666
+f 5373 5238 18666
+f 19144 17312 17311
+f 4934 5373 19052
+f 1044 8741 3704
+f 19145 17312 19144
+f 8214 7106 2413
+f 15491 19146 15492
+f 18916 1650 19147
+f 19148 19149 19017
+f 1136 19099 1160
+f 848 1525 1524
+f 3148 9564 1537
+f 6317 6431 5085
+f 8360 9946 10049
+f 5359 6361 5506
+f 18499 19150 19151
+f 1126 13468 1127
+f 19065 19104 1690
+f 1998 1999 1685
+f 5918 19152 17917
+f 19104 19117 19119
+f 10250 19112 19153
+f 13631 8031 8209
+f 9634 4760 19154
+f 11038 19155 19156
+f 19157 18637 19158
+f 4640 12378 10228
+f 17149 19159 9325
+f 11321 3442 3441
+f 7224 640 7225
+f 15775 777 11176
+f 18630 19160 1640
+f 14212 18561 17631
+f 18984 19161 19162
+f 18637 1785 19158
+f 18985 18984 19162
+f 19161 19163 19164
+f 1638 19165 19166
+f 19167 18663 19157
+f 19162 19161 19164
+f 18436 19118 18437
+f 19168 9526 10254
+f 19121 19169 706
+f 19120 19170 18438
+f 644 3394 645
+f 8705 19171 19172
+f 17842 16142 19173
+f 18474 18473 7764
+f 2134 16966 16251
+f 19174 19175 19123
+f 19176 19177 19178
+f 12275 9853 11211
+f 19126 19128 19130
+f 551 5944 5945
+f 18526 19179 18095
+f 19087 19086 19129
+f 19134 19136 19138
+f 19180 19181 19132
+f 4480 1159 1160
+f 19092 19091 19137
+f 9081 2624 3201
+f 1561 5784 18987
+f 19182 19183 19184
+f 16566 15841 2616
+f 19185 19186 19187
+f 19188 19140 19143
+f 14110 19189 19190
+f 16411 16784 1753
+f 9141 9150 671
+f 7474 19191 19192
+f 5786 5789 19053
+f 18987 5786 19053
+f 19193 17313 17312
+f 12652 19193 17312
+f 5122 19194 2128
+f 3705 1884 3723
+f 19098 19148 19017
+f 19125 19127 19149
+f 616 4633 1212
+f 19148 19125 19149
+f 13679 5975 4327
+f 19064 19063 19176
+f 6503 5816 7009
+f 12300 12452 19158
+f 407 1372 1128
+f 19195 18507 5785
+f 19196 19197 19198
+f 349 4599 9183
+f 19105 19104 19119
+f 1251 18816 18630
+f 1962 1813 19199
+f 19118 18436 19119
+f 18408 18796 18828
+f 18526 10892 474
+f 472 19200 1244
+f 19201 18831 18830
+f 19202 19201 18830
+f 19203 18832 18831
+f 19201 19203 18831
+f 19204 18833 18832
+f 19205 18662 19167
+f 19203 19204 18832
+f 19206 18693 19205
+f 18662 18663 19167
+f 19207 18715 19206
+f 18693 18662 19205
+f 19208 18739 19207
+f 18715 18693 19206
+f 19209 18834 18833
+f 19204 19209 18833
+f 19210 18835 18834
+f 19209 19210 18834
+f 19211 18864 18835
+f 18738 18739 19208
+f 19212 18738 19208
+f 18438 19170 18447
+f 18437 19120 18438
+f 18974 491 18586
+f 320 19213 1667
+f 19214 19215 19216
+f 9191 8841 18414
+f 19025 412 5941
+f 15493 19217 14543
+f 18818 19218 19219
+f 410 1033 1780
+f 19220 18583 4485
+f 833 19119 9078
+f 19221 19222 19223
+f 19128 19087 19129
+f 1159 972 971
+f 19179 18915 18095
+f 19224 19225 19226
+f 19136 19092 19137
+f 19227 19228 19229
+f 19230 19227 19229
+f 19231 19232 19182
+f 2271 16566 2616
+f 19233 19184 19234
+f 19235 19233 19234
+f 19236 19185 19187
+f 19186 19237 19238
+f 19142 19185 19236
+f 19143 19142 19236
+f 19239 15499 15501
+f 19140 19188 19141
+f 5789 9347 19010
+f 19240 19239 15501
+f 19133 19135 17313
+f 1521 19241 1522
+f 5258 19242 19243
+f 19193 19133 17313
+f 19244 19040 18580
+f 19041 19089 19042
+f 19126 19130 19127
+f 19245 19246 19085
+f 19247 19248 19249
+f 19177 19247 19178
+f 6574 4468 9515
+f 5788 18585 9348
+f 1771 13547 19025
+f 7127 639 760
+f 4481 3183 1159
+f 19250 16789 17699
+f 9582 9624 9576
+f 18816 18815 19251
+f 19170 19252 18447
+f 19253 19254 18450
+f 18765 18738 19212
+f 19255 18765 19212
+f 19256 18824 19257
+f 18823 18765 19255
+f 18663 18637 19157
+f 19257 18823 19255
+f 19210 19211 18835
+f 19258 18859 19256
+f 19211 19259 18866
+f 18864 19211 18866
+f 19259 19260 18867
+f 18866 19259 18867
+f 19260 19261 18868
+f 18867 19260 18868
+f 19261 19262 18869
+f 18868 19261 18869
+f 19262 19263 18899
+f 18869 19262 18899
+f 19263 19264 18900
+f 19265 18860 19258
+f 18899 19263 18900
+f 19252 19266 18448
+f 18739 18715 19207
+f 318 4479 319
+f 18447 19252 18448
+f 19163 19267 1134
+f 1678 1677 1680
+f 1210 18541 1240
+f 17699 15688 16806
+f 1771 19025 19024
+f 18504 18973 5787
+f 2797 18511 19195
+f 18973 18585 5788
+f 19164 19163 1134
+f 19119 18436 9078
+f 19222 19268 19269
+f 19270 19221 19223
+f 1842 17598 17597
+f 496 805 1415
+f 19271 19272 19273
+f 19274 19275 19276
+f 19277 19227 19230
+f 19278 19277 19230
+f 19279 19280 19232
+f 19281 19231 19182
+f 19235 19234 19282
+f 19283 19235 19282
+f 1463 393 1456
+f 1280 18547 1281
+f 1281 19284 1463
+f 19284 393 1463
+f 19139 19141 19285
+f 19286 19139 19285
+f 15487 15488 1846
+f 19287 19288 19289
+f 12931 16801 17565
+f 11146 7930 18592
+f 19134 19138 19135
+f 19043 19004 19006
+f 19290 19244 17869
+f 19040 19042 18580
+f 19084 19245 19085
+f 19291 19292 19246
+f 19095 19096 9011
+f 9214 19095 9011
+f 1414 653 716
+f 5787 18973 5788
+f 2760 16813 8039
+f 19097 13466 1885
+f 12551 13559 2867
+f 18922 5162 14435
+f 10003 9231 19293
+f 18525 1209 19294
+f 18449 19253 18450
+f 19254 19295 18452
+f 19296 18861 19265
+f 18860 18859 19258
+f 19264 15606 18901
+f 18900 19264 18901
+f 19297 18863 19296
+f 19298 15848 15606
+f 18824 18823 19257
+f 18861 18860 19265
+f 18901 15606 15605
+f 19299 18862 19297
+f 246 245 5232
+f 19300 19301 19302
+f 2785 2787 6190
+f 10376 1115 740
+f 3222 2744 19303
+f 11485 17978 11483
+f 18862 18863 19297
+f 19304 19305 19306
+f 19266 19253 18449
+f 18859 18824 19256
+f 18468 19307 18469
+f 18448 19266 18449
+f 19308 19309 18475
+f 18469 19308 18475
+f 19310 18502 18507
+f 485 484 4936
+f 9335 9598 1967
+f 19311 19249 9333
+f 1772 19024 19312
+f 14146 1772 19312
+f 1243 1246 475
+f 18507 18504 5785
+f 9077 9078 4626
+f 19313 18919 19314
+f 19315 19316 19317
+f 19223 19222 19269
+f 18510 2186 19318
+f 15363 9854 12275
+f 19273 19319 19320
+f 19319 19321 19320
+f 19322 19277 19278
+f 19323 19322 19278
+f 19324 19286 19280
+f 19231 19279 19232
+f 19283 19282 19325
+f 19288 19283 19325
+f 13820 2100 6926
+f 15499 19239 15489
+f 285 339 19326
+f 19096 285 19326
+f 19232 19280 19327
+f 19286 19285 19328
+f 19329 19330 19331
+f 19332 19283 19288
+f 6753 8697 6754
+f 6209 14803 14804
+f 19333 19334 19005
+f 19004 19333 19005
+f 19290 17869 18915
+f 19179 19290 18915
+f 19245 19291 19246
+f 19335 19336 19292
+f 19337 8918 8919
+f 19338 18582 18537
+f 18585 705 9348
+f 19339 16809 16789
+f 13467 18893 13468
+f 1772 1771 19024
+f 1711 1389 1329
+f 8843 13905 8844
+f 370 638 640
+f 13289 12939 19340
+f 18450 19254 18452
+f 19295 19341 18453
+f 19342 18898 19343
+f 18865 18862 19299
+f 666 9316 1336
+f 15481 19344 19345
+f 668 813 2157
+f 18924 18898 19346
+f 1334 1336 9316
+f 18863 18861 19296
+f 18898 18865 19343
+f 2435 2257 5099
+f 18925 18924 19347
+f 853 510 987
+f 19250 19339 16789
+f 2157 813 1997
+f 2225 17098 16502
+f 19217 19033 14543
+f 8994 15708 15742
+f 977 5476 1719
+f 1844 467 1842
+f 9587 9423 1249
+f 17239 19348 19030
+f 19026 18927 19349
+f 18927 18926 19350
+f 19026 19349 19351
+f 18926 19352 19350
+f 18977 19026 19351
+f 18927 19350 19349
+f 18475 19309 18491
+f 19309 19353 18491
+f 9410 9409 19354
+f 2796 19355 18511
+f 19356 19357 1544
+f 7765 1543 1545
+f 10048 7770 10120
+f 13099 1269 18224
+f 1647 19358 1648
+f 279 14291 280
+f 18580 14143 17869
+f 19359 19360 18607
+f 19361 19316 19315
+f 19362 19361 19315
+f 18986 19363 18489
+f 19063 974 19177
+f 19321 19364 19320
+f 19364 19365 19320
+f 19366 19322 19323
+f 19367 19366 19323
+f 19368 19139 19286
+f 19279 19324 19280
+f 19288 19325 19330
+f 19289 19288 19330
+f 19369 19370 19371
+f 5757 13820 6926
+f 17869 14142 18915
+f 6231 11418 6229
+f 19280 19286 19328
+f 19042 4643 4642
+f 19287 19332 19288
+f 19280 19328 19327
+f 6725 6185 475
+f 19372 19235 19283
+f 19333 19225 19224
+f 19373 8134 19374
+f 19244 18580 17869
+f 19334 19333 19224
+f 19291 19335 19292
+f 15986 3393 17492
+f 8138 14281 8136
+f 19221 19270 19336
+f 1364 1363 3770
+f 9011 19096 9664
+f 13547 412 19025
+f 17979 9735 19124
+f 18539 18605 18540
+f 18112 14146 19375
+f 637 1362 1364
+f 994 18538 395
+f 18452 19295 18453
+f 19376 19377 18273
+f 19343 18865 19299
+f 19341 19378 18459
+f 761 760 6824
+f 18978 18977 19379
+f 19348 19380 19031
+f 19030 19348 19031
+f 18978 19379 19381
+f 19382 19032 19031
+f 18898 19342 19346
+f 18445 18978 19381
+f 19380 19382 19031
+f 18925 19347 19352
+f 19382 19383 19035
+f 19032 19382 19035
+f 19384 19066 19035
+f 19383 19384 19035
+f 19385 19068 19066
+f 19384 19385 19066
+f 19386 19069 19068
+f 19385 19386 19068
+f 19387 19073 19069
+f 19386 19387 19069
+f 19388 19076 19073
+f 8579 8656 19389
+f 19387 19388 19073
+f 19390 19106 19076
+f 7237 9743 19391
+f 19388 19390 19076
+f 19392 19107 19106
+f 8382 8579 19393
+f 8656 19011 19389
+f 18491 19353 18492
+f 19353 19394 18492
+f 18816 19251 19160
+f 1711 1411 9230
+f 19395 19396 18953
+f 1543 19356 1544
+f 9946 5929 5930
+f 19377 18275 18272
+f 19397 19007 5943
+f 19398 19220 477
+f 19008 19094 19399
+f 9211 9210 8359
+f 10587 14284 19317
+f 19316 19400 19317
+f 19240 15501 15500
+f 19401 13300 13299
+f 19364 19402 19365
+f 19402 19403 19365
+f 19404 19366 19367
+f 19405 19404 19367
+f 19368 19406 19140
+f 19324 19368 19286
+f 19407 19408 19409
+f 19410 2786 2785
+f 19330 19411 19408
+f 2031 2120 366
+f 19412 19413 19414
+f 19415 19416 19417
+f 19418 16845 16809
+f 19339 19418 16809
+f 19233 19182 19184
+f 19232 19327 19183
+f 19332 19372 19283
+f 19419 19233 19235
+f 19228 19373 19374
+f 19229 19228 19374
+f 19225 19274 19226
+f 19226 19274 19276
+f 494 497 18546
+f 5868 3082 2874
+f 19335 19221 19336
+f 19268 19420 19421
+f 19422 16866 16845
+f 3544 9234 3542
+f 6886 6885 19423
+f 16955 838 11321
+f 13333 18112 19375
+f 13334 13333 19375
+f 19294 1209 1211
+f 1546 1548 19357
+f 19418 19422 16845
+f 19422 19424 17042
+f 18453 19341 18459
+f 18492 19394 18520
+f 8382 19393 19425
+f 7761 8382 19425
+f 19390 19392 19106
+f 19392 19426 19108
+f 19107 19392 19108
+f 19426 19427 19109
+f 18977 19351 19379
+f 16797 4166 7439
+f 18926 18925 19352
+f 19378 19428 18460
+f 19034 15528 14543
+f 18924 19346 19347
+f 19108 19426 19109
+f 19429 19430 19431
+f 19427 19432 19110
+f 19109 19427 19110
+f 19432 19433 19111
+f 19110 19432 19111
+f 5781 3221 1979
+f 19111 19433 19112
+f 5232 6495 5359
+f 7533 7428 7427
+f 18797 1417 1416
+f 19434 6522 6515
+f 2971 9323 2746
+f 5516 5371 5370
+f 14276 19201 19202
+f 19435 19436 19437
+f 19438 19203 19201
+f 14276 19438 19201
+f 16551 19204 19203
+f 19439 19440 19165
+f 6233 6643 9096
+f 18470 18476 19441
+f 19394 19442 18520
+f 19443 11776 11091
+f 19444 9492 2807
+f 18954 19445 19446
+f 1290 1289 9400
+f 19218 279 18376
+f 10586 14218 14282
+f 19007 19008 19101
+f 18548 19168 10254
+f 18506 19099 1136
+f 19447 19448 19449
+f 14803 6209 5601
+f 19400 10587 19317
+f 14383 6356 6335
+f 19450 1875 19451
+f 19402 19452 19403
+f 19452 19453 19403
+f 19454 19455 19456
+f 19457 19404 19405
+f 19406 19454 19142
+f 19139 19368 19140
+f 2100 13820 783
+f 2119 7549 356
+f 19325 19458 19411
+f 19331 19330 19408
+f 19459 19413 19412
+f 19460 19459 19412
+f 9008 19461 19462
+f 19463 19464 19465
+f 19182 19232 19183
+f 8917 9008 19462
+f 19372 19419 19235
+f 19089 4645 4643
+f 8134 15363 19374
+f 19281 19182 19233
+f 19275 19272 19271
+f 19466 19324 19279
+f 13099 18224 13100
+f 19276 19275 19271
+f 19269 19268 19421
+f 19467 19468 8138
+f 939 8813 10751
+f 19420 19361 19362
+f 1031 1030 1954
+f 19469 19470 19471
+f 14146 19312 19375
+f 476 478 1676
+f 19176 19178 18815
+f 12095 12096 18920
+f 2310 2454 19472
+f 15148 12645 18709
+f 19442 2548 2710
+f 1968 18510 19473
+f 8579 19389 19393
+f 18520 19442 2710
+f 19438 16551 19203
+f 18561 17632 17631
+f 19474 19209 19204
+f 16551 19474 19204
+f 18542 10254 483
+f 19475 19210 19209
+f 18460 19428 18468
+f 1243 6185 11931
+f 18459 19378 18460
+f 19307 19308 18469
+f 19476 6723 19477
+f 19428 19307 18468
+f 19474 19475 19209
+f 6695 6723 19476
+f 19478 19211 19210
+f 19475 19478 19210
+f 19478 19479 19259
+f 19211 19478 19259
+f 19479 19480 19260
+f 19259 19479 19260
+f 19480 19481 19261
+f 19260 19480 19261
+f 19481 19482 19262
+f 19261 19481 19262
+f 19482 7631 19263
+f 19262 19482 19263
+f 6437 19483 3748
+f 7631 19484 19264
+f 1815 9737 1816
+f 6643 6695 19485
+f 319 19486 19213
+f 19487 19488 19489
+f 12953 1143 1145
+f 19363 18456 18489
+f 18818 13296 19218
+f 19490 9470 8813
+f 19491 19492 19493
+f 19376 278 19377
+f 19447 19494 19495
+f 18539 9555 18605
+f 12827 12168 12167
+f 9409 18916 19354
+f 19360 18608 18607
+f 19496 19497 19498
+f 19467 19499 19453
+f 18890 1962 19199
+f 19406 19500 19454
+f 19452 19467 19453
+f 19140 19406 19142
+f 19456 19457 19405
+f 19501 19240 15500
+f 19454 19456 19185
+f 19330 19325 19411
+f 2624 2120 1978
+f 19502 19459 19460
+f 19282 19503 19458
+f 19504 19412 19505
+f 19413 19415 19414
+f 19506 19507 19508
+f 19464 19463 19509
+f 15490 19510 15491
+f 19328 19511 19512
+f 1333 285 19096
+f 339 341 19062
+f 19419 19281 19233
+f 19278 19230 19513
+f 19514 19515 19281
+f 19516 19279 19231
+f 19272 19319 19273
+f 19080 19174 19123
+f 19517 19468 19467
+f 19452 19517 19467
+f 19421 19420 19362
+f 18608 19313 18609
+f 472 471 19200
+f 19400 4473 10587
+f 1451 14498 14427
+f 473 1545 474
+f 18608 7937 19313
+f 7939 12095 18919
+f 18814 19176 18815
+f 18511 19310 18507
+f 2185 2184 18482
+f 19518 18478 18482
+f 14877 12217 6230
+f 8653 3190 514
+f 16866 19422 17042
+f 1677 19519 1680
+f 19263 7631 19264
+f 19484 19298 15606
+f 19264 19484 15606
+f 7049 7052 6942
+f 482 18542 483
+f 19520 19157 12452
+f 19521 19522 19523
+f 19524 8573 8576
+f 963 962 7561
+f 18503 19525 18974
+f 9095 6643 19485
+f 1768 1767 3715
+f 1474 1240 482
+f 19485 6695 19476
+f 8567 13196 8390
+f 19526 19167 19520
+f 722 712 1650
+f 18543 3513 3712
+f 19527 19528 19529
+f 1483 1482 15970
+f 9734 1782 846
+f 9735 9734 846
+f 18560 9318 18553
+f 19530 14521 8722
+f 1782 1661 847
+f 645 9221 18628
+f 19160 19531 621
+f 18502 19532 18503
+f 646 645 18628
+f 19446 19490 8813
+f 320 319 19213
+f 18817 12427 18818
+f 11485 18100 18046
+f 907 1519 1518
+f 6890 7736 9661
+f 1555 1557 1779
+f 19396 19445 18954
+f 4792 4894 19533
+f 19494 19496 19534
+f 6921 761 6824
+f 19495 19494 19534
+f 8138 8135 19499
+f 7561 7562 8273
+f 19535 19500 19368
+f 19467 8138 19499
+f 19142 19454 19185
+f 19455 19457 19456
+f 9008 9141 19461
+f 19456 19405 19186
+f 19325 19282 19458
+f 13820 15487 783
+f 19536 19502 19537
+f 19234 19538 19503
+f 19414 19417 19539
+f 19537 19502 19460
+f 14218 10586 10588
+f 19505 19414 19539
+f 19507 19464 19509
+f 19464 19540 19465
+f 19327 19328 19512
+f 19511 19506 19541
+f 18580 19042 4642
+f 19285 19506 19511
+f 19542 19278 19513
+f 395 18540 1457
+f 19515 19516 19231
+f 19230 19229 19543
+f 5321 2768 11332
+f 19544 19514 19419
+f 19468 14285 8138
+f 19424 19545 17049
+f 19175 19174 19359
+f 19517 19452 19402
+f 18613 18616 14491
+f 17042 19424 17049
+f 1544 19179 18526
+f 19316 4472 19400
+f 19313 7939 18919
+f 1545 1544 18526
+f 19546 405 407
+f 18005 16135 53
+f 1967 18510 1968
+f 7764 473 1246
+f 3920 5901 3918
+f 701 717 19083
+f 19547 19147 19548
+f 640 7223 370
+f 9316 8873 1334
+f 19205 19167 19526
+f 9320 865 18554
+f 987 668 2157
+f 19549 1334 18979
+f 14282 8138 14285
+f 19206 19205 19550
+f 19551 1918 1917
+f 9329 9328 12491
+f 491 19121 18586
+f 19470 19064 19471
+f 1127 407 1128
+f 19545 19552 17128
+f 716 653 655
+f 18461 18471 18599
+f 19157 19158 12452
+f 8301 8892 8891
+f 19363 19553 18456
+f 19255 19212 19554
+f 951 866 1999
+f 19093 13868 12872
+f 17049 19545 17128
+f 18771 19529 8843
+f 6616 1208 4100
+f 19257 19255 19555
+f 1985 8702 1983
+f 621 19531 912
+f 19167 19157 19520
+f 611 1380 1007
+f 1240 18542 482
+f 19355 4935 19310
+f 1549 1551 8300
+f 8935 9062 19489
+f 19525 491 18974
+f 19060 18892 18817
+f 4936 484 18516
+f 18969 18968 13580
+f 13296 279 19218
+f 19556 16404 18945
+f 1766 1475 5662
+f 19105 5954 3188
+f 9204 7745 7744
+f 4921 12553 17987
+f 15808 17362 15869
+f 18603 17979 19100
+f 1279 13124 19557
+f 19466 19535 19324
+f 905 904 1039
+f 19185 19456 19186
+f 19500 19455 19454
+f 19552 19558 17172
+f 19405 19367 19237
+f 19282 19234 19503
+f 19559 19510 15490
+f 19560 19536 19561
+f 19184 19562 19538
+f 19417 19563 19564
+f 19561 19536 19537
+f 4770 16570 2271
+f 19539 19417 19564
+f 9470 18599 9471
+f 4879 10647 7741
+f 11788 11750 13211
+f 18508 585 18505
+f 19507 19509 19508
+f 5517 695 18506
+f 19328 19285 19511
+f 19512 19511 19565
+f 1457 18540 1841
+f 19141 19507 19506
+f 19513 19230 19543
+f 1813 908 19444
+f 19515 19231 19281
+f 19229 19374 19566
+f 1809 1747 9389
+f 19567 19544 19372
+f 19568 19517 19402
+f 8458 7938 7331
+f 695 694 19099
+f 19568 19402 19364
+f 4473 1148 10587
+f 9410 19354 5241
+f 19357 19290 19179
+f 19361 4474 19316
+f 7937 7939 19313
+f 1544 19357 19179
+f 8800 9145 8801
+f 8915 6895 5468
+f 4937 18516 19532
+f 1765 1475 1766
+f 522 5791 5096
+f 19569 9401 19057
+f 19550 19205 19526
+f 4712 18889 6319
+f 9221 9222 18566
+f 19570 19208 19571
+f 15707 19572 15708
+f 371 2234 372
+f 19573 19206 19550
+f 19555 19255 19554
+f 523 522 5096
+f 19574 2572 14299
+f 18516 19575 19532
+f 19576 19577 19578
+f 3597 3967 18626
+f 19579 15357 498
+f 18451 9170 9169
+f 11729 19077 11721
+f 1804 840 518
+f 18896 19580 18897
+f 19581 19258 19582
+f 19256 19257 19583
+f 19572 19584 17239
+f 15708 19572 17239
+f 19584 19585 19348
+f 17239 19584 19348
+f 19586 19380 19348
+f 19585 19586 19348
+f 19258 19256 19582
+f 19587 19382 19380
+f 4794 4793 5661
+f 19583 19257 19555
+f 18521 18543 18493
+f 6575 9702 776
+f 4937 19532 18502
+f 18145 10251 18329
+f 19575 15390 489
+f 19310 4937 18502
+f 18920 12096 19060
+f 719 15390 19575
+f 19588 18508 2604
+f 12427 13296 18818
+f 9039 9061 8935
+f 19007 19101 5943
+f 19448 19447 19495
+f 877 1094 878
+f 11484 11483 1770
+f 7108 1039 10137
+f 14962 7476 14963
+f 19589 1966 9737
+f 19516 19466 19279
+f 2800 15426 18354
+f 19186 19405 19237
+f 19500 19406 19368
+f 19042 19089 4643
+f 19367 19323 19590
+f 19234 19184 19538
+f 9141 18772 19461
+f 19540 19560 19591
+f 19183 19592 19562
+f 19563 19593 19594
+f 19591 19560 19561
+f 3412 13964 19595
+f 19564 19563 19594
+f 4789 2975 4790
+f 19596 4777 9730
+f 356 7549 357
+f 2145 12100 9828
+f 19146 19597 15492
+f 2166 2074 2075
+f 3232 17901 16123
+f 585 5517 18505
+f 19506 19508 19541
+f 19588 583 18508
+f 19285 19141 19506
+f 19592 19512 19598
+f 19599 552 18986
+f 19188 19464 19507
+f 19543 19229 19566
+f 9740 2626 19519
+f 19514 19281 19419
+f 19374 15363 15364
+f 5239 5372 13467
+f 19600 19567 19332
+f 19601 19568 19364
+f 7312 7195 7194
+f 19174 19360 19359
+f 19601 19364 19321
+f 4472 4473 19400
+f 18769 18154 18405
+f 1548 19244 19290
+f 19420 5792 19361
+f 19602 19603 19604
+f 19357 1548 19290
+f 5241 19354 5242
+f 9948 14257 7362
+f 18518 19605 18519
+f 18668 18667 18479
+f 840 519 518
+f 2473 1524 9295
+f 19207 19206 19573
+f 16507 14276 2358
+f 19212 19208 19570
+f 19571 19207 19573
+f 19554 19212 19570
+f 19208 19207 19571
+f 2806 2808 1670
+f 11664 18793 11751
+f 478 9590 9740
+f 19102 1676 1678
+f 9589 9189 9398
+f 9590 9589 9398
+f 5944 19100 2473
+f 9590 9398 9740
+f 19606 19607 18923
+f 997 996 1252
+f 19582 19256 19583
+f 18897 19606 18923
+f 19586 19587 19380
+f 19265 19258 19581
+f 19587 19608 19383
+f 19382 19587 19383
+f 19609 19384 19383
+f 19608 19609 19383
+f 19610 19385 19384
+f 19611 19297 19612
+f 19296 19265 19613
+f 19614 19615 18976
+f 19580 19606 18897
+f 478 9740 1677
+f 19445 18601 19490
+f 18516 719 19575
+f 19532 19525 18503
+f 18919 12095 18920
+f 19616 19355 2796
+f 5949 19220 4485
+f 18892 12427 18817
+f 1148 1006 10587
+f 2776 19588 2604
+f 19220 5949 477
+f 19080 19617 19618
+f 19619 19620 19272
+f 19621 9200 5101
+f 6080 6228 8394
+f 11816 14401 11917
+f 19622 8998 632
+f 5785 18504 5787
+f 19237 19367 19590
+f 19535 19368 19324
+f 444 19623 438
+f 19323 19278 19542
+f 19184 19183 19562
+f 17128 19552 17172
+f 19503 19538 19624
+f 19327 19512 19592
+f 19593 7426 7428
+f 19465 19540 19591
+f 19463 19465 3396
+f 19594 19593 7428
+f 19062 341 19063
+f 222 575 223
+f 7059 19450 19451
+f 19558 19625 17182
+f 9735 846 849
+f 1679 1681 1991
+f 19626 12713 12715
+f 15697 12977 7133
+f 3396 19465 19627
+f 1173 1143 12953
+f 1526 19628 19629
+f 710 19463 3396
+f 19511 19541 19565
+f 18629 18565 19628
+f 19141 19188 19507
+f 19562 19592 19630
+f 18498 19151 18986
+f 19188 19143 19540
+f 19566 19374 15364
+f 8872 1128 8873
+f 19544 19419 19372
+f 11272 3703 10504
+f 5373 18666 19052
+f 19631 19600 19287
+f 19632 19601 19321
+f 13466 5239 13467
+f 7665 1353 7836
+f 19632 19321 19319
+f 4474 4472 19316
+f 8864 19633 19011
+f 2492 19040 19244
+f 19268 18749 19420
+f 2476 2475 19634
+f 1548 2492 19244
+f 18667 1887 18479
+f 19635 3583 19636
+f 19637 19638 9830
+f 447 10525 9084
+f 19639 19640 18895
+f 1524 1526 9295
+f 18855 19641 505
+f 18894 19639 18895
+f 19642 19639 18894
+f 507 19642 18894
+f 19640 19580 18896
+f 18895 19640 18896
+f 19643 19644 19117
+f 19644 19118 19117
+f 19118 19644 19120
+f 19644 19645 19120
+f 9589 4484 9190
+f 19645 19646 19170
+f 18567 18599 9470
+f 9189 9589 9190
+f 19607 19614 18976
+f 9190 4484 9298
+f 19613 19265 19581
+f 18923 19607 18976
+f 19609 19610 19384
+f 19297 19296 19612
+f 19647 19386 19385
+f 19610 19647 19385
+f 19648 19387 19386
+f 19647 19648 19386
+f 19649 19388 19387
+f 19650 19299 19611
+f 19648 19649 19387
+f 19651 19065 19027
+f 19612 19296 19613
+f 4484 4486 9298
+f 19615 19651 19027
+f 1647 19616 19358
+f 1676 478 1677
+f 2079 662 2080
+f 9190 9298 8841
+f 1246 473 475
+f 12096 18892 19060
+f 19291 19534 19335
+f 19094 19398 476
+f 19498 19652 19221
+f 19335 19498 19221
+f 19009 18573 19653
+f 2429 18505 2430
+f 19654 19619 19275
+f 19274 19654 19275
+f 2185 9547 12589
+f 552 713 18986
+f 2616 15841 8961
+f 19655 19329 19656
+f 11702 5731 8365
+f 19590 19323 19542
+f 9015 18854 439
+f 19657 19623 444
+f 19236 19187 19536
+f 19183 19327 19592
+f 19538 19562 19658
+f 19562 19630 19658
+f 2808 1454 1833
+f 10633 9174 13631
+f 19508 19509 720
+f 19463 710 721
+f 18890 19199 18918
+f 974 275 19177
+f 2029 19659 19660
+f 19661 19504 18515
+f 17172 19558 17182
+f 714 15902 715
+f 655 654 12589
+f 19662 925 2187
+f 1690 19105 3188
+f 19248 1488 19663
+f 19465 19591 19627
+f 18918 1670 1669
+f 9042 9045 12491
+f 19509 721 720
+f 19512 19565 19598
+f 8653 514 513
+f 19464 19188 19540
+f 19538 19658 19624
+f 18854 19241 1521
+f 19143 19236 19560
+f 9592 16460 8310
+f 19664 19657 2101
+f 19567 19372 19332
+f 15173 19665 5088
+f 18858 19666 18822
+f 19600 19332 19287
+f 19667 19632 19319
+f 805 9733 1415
+f 19019 19021 19668
+f 19272 19620 19319
+f 5792 4474 19361
+f 19249 19248 9334
+f 2491 19041 19040
+f 18749 5792 19420
+f 10378 15496 10379
+f 2492 2491 19040
+f 4952 19621 5101
+f 2454 3583 19635
+f 3205 1178 1180
+f 18537 318 320
+f 9545 9010 19669
+f 9213 9010 9545
+f 19651 19670 19065
+f 19670 19643 19117
+f 19671 19343 19650
+f 19299 19297 19611
+f 19342 19343 19672
+f 19343 19299 19650
+f 19342 19672 19673
+f 19346 19342 19673
+f 19120 19645 19170
+f 19343 19671 19672
+f 9010 9012 19669
+f 19646 19674 19252
+f 19469 19471 996
+f 995 19469 996
+f 19615 19027 18976
+f 19674 19675 19266
+f 19352 19347 19676
+f 19346 19673 19677
+f 19649 19678 19390
+f 19388 19649 19390
+f 19678 19679 19392
+f 19390 19678 19392
+f 19679 19156 19426
+f 19392 19679 19426
+f 19156 19680 19427
+f 19352 19676 19681
+f 19350 19352 19681
+f 19266 19675 19253
+f 19670 19104 19065
+f 9544 9213 9545
+f 4486 9213 9544
+f 2139 2138 9345
+f 16953 15968 14355
+f 3583 3597 19636
+f 19472 2454 19635
+f 2491 9212 19041
+f 1545 18526 474
+f 546 19682 5234
+f 18508 18505 2429
+f 19245 19495 19291
+f 19534 19498 19335
+f 18544 15304 18573
+f 7533 7630 7428
+f 19683 19654 19274
+f 19225 19683 19274
+f 497 1414 18546
+f 1535 494 9422
+f 15488 15486 375
+f 1846 15488 375
+f 907 9557 1519
+f 11113 14370 11114
+f 19623 9015 438
+f 2101 19657 444
+f 4792 19533 19684
+f 19053 19010 2229
+f 19625 19685 17233
+f 19592 19598 19630
+f 19591 19561 19686
+f 2808 18547 1454
+f 19630 19598 1220
+f 19509 19463 721
+f 4894 5762 19687
+f 6509 6508 19666
+f 19504 19505 1412
+f 19660 19661 18515
+f 19528 19594 7630
+f 7725 7630 2253
+f 19450 1873 1875
+f 18581 11788 13211
+f 19564 19594 19528
+f 19594 7428 7630
+f 19177 275 19247
+f 16791 15850 19688
+f 19508 720 9586
+f 19541 19508 9586
+f 1670 2808 1833
+f 18547 1280 1454
+f 19503 19624 16827
+f 19458 19503 16827
+f 19540 19143 19560
+f 19560 19236 19536
+f 18604 9557 907
+f 1519 19664 2101
+f 13955 17472 18118
+f 929 18954 930
+f 19239 19559 15489
+f 19689 12975 15697
+f 9478 6506 6505
+f 19105 19119 5954
+f 19275 19619 19272
+f 19620 19667 19319
+f 16677 15834 15832
+f 18572 18573 19009
+f 18747 18749 19268
+f 19222 18747 19268
+f 9212 19088 19041
+f 1648 19131 19088
+f 17182 19625 17233
+f 19690 2310 19472
+f 9220 18584 9214
+f 266 2158 850
+f 9012 19469 995
+f 19669 9012 995
+f 19104 19670 19117
+f 19254 19691 19295
+f 19350 19681 19692
+f 19349 19350 19692
+f 19426 19156 19427
+f 19680 19693 19432
+f 19427 19680 19432
+f 19694 19695 19693
+f 19379 19351 19696
+f 19432 19693 19433
+f 19170 19646 19252
+f 19349 19692 19697
+f 835 834 18538
+f 19295 19698 19341
+f 19252 19674 19266
+f 19699 19700 19309
+f 19347 19346 19677
+f 19675 19701 19253
+f 19702 2261 17771
+f 19351 19697 19696
+f 19703 19433 19693
+f 3015 4650 3016
+f 19704 19705 19706
+f 16000 15610 15591
+f 19381 19379 19707
+f 9560 9563 9561
+f 19701 19691 19254
+f 19347 19677 19676
+f 834 18539 18538
+f 19253 19701 19254
+f 2167 2166 2000
+f 9298 4486 9544
+f 9733 19082 2184
+f 1968 19473 9738
+f 19052 18668 19518
+f 705 707 18572
+f 19015 19052 19518
+f 18546 1414 716
+f 19708 19709 2981
+f 19710 19682 19711
+f 19448 19495 19084
+f 19495 19534 19291
+f 19178 19247 19249
+f 19013 4850 6600
+f 19712 19683 19225
+f 19333 19712 19225
+f 12193 19293 9231
+f 2185 18482 9319
+f 9344 19713 4632
+f 2120 2031 1978
+f 755 18604 907
+f 9557 19664 1519
+f 19566 15364 19714
+f 438 9015 439
+f 15249 19715 14517
+f 9295 19629 19553
+f 19685 19716 17316
+f 7474 7761 19191
+f 19561 19537 19659
+f 19627 19591 19686
+f 19658 19630 1219
+f 19598 9110 1220
+f 18600 19441 11091
+f 9471 18600 11091
+f 19659 19661 19660
+f 18515 19504 1412
+f 3397 3396 18513
+f 19627 19686 2028
+f 18513 19627 2028
+f 19686 19659 2029
+f 19505 19539 18770
+f 19527 19564 19528
+f 4625 4624 12270
+f 17233 19685 17316
+f 19565 9111 9110
+f 19598 19565 9110
+f 923 925 19662
+f 18547 19284 1281
+f 18498 18499 19151
+f 19411 19458 19717
+f 19187 19238 19502
+f 19536 19187 19502
+f 19718 19695 19719
+f 1841 18605 755
+f 624 19007 19397
+f 537 624 19397
+f 7761 19425 19191
+f 17287 14546 14545
+f 19119 833 5954
+f 19716 19720 17318
+f 19721 19722 19045
+f 19723 19004 19043
+f 19096 19326 9664
+f 9349 18572 19009
+f 19652 18747 19222
+f 19221 19652 19222
+f 9212 1648 19088
+f 13466 13468 1885
+f 17316 19716 17318
+f 4894 19687 19533
+f 9471 11091 9797
+f 1415 2184 653
+f 18566 18487 18500
+f 11480 6187 12426
+f 19698 19724 19341
+f 19725 19726 19307
+f 19727 19381 19728
+f 19379 19696 19707
+f 15506 16551 19438
+f 16506 19729 16507
+f 15505 19474 16551
+f 2077 15506 19729
+f 19351 19349 19697
+f 15456 12146 10154
+f 19724 19730 19378
+f 19341 19724 19378
+f 19308 19699 19309
+f 19700 19731 19353
+f 19720 19732 17319
+f 17610 18961 19733
+f 17318 19720 17319
+f 19734 17215 17214
+f 15860 19475 19474
+f 19732 19735 17320
+f 15505 15860 19474
+f 19736 19478 19475
+f 15860 19736 19475
+f 19737 19479 19478
+f 19736 19737 19478
+f 17319 19732 17320
+f 19735 19738 17324
+f 19731 19739 19394
+f 19691 19698 19295
+f 17320 19735 17324
+f 13631 1989 8031
+f 15776 2739 780
+f 1966 1968 9737
+f 1370 1369 12828
+f 648 647 13153
+f 9632 9634 19740
+f 19741 19742 19743
+f 19052 18666 18668
+f 19097 1885 18667
+f 19682 19710 3766
+f 19744 19727 19745
+f 19449 19448 19087
+f 19495 19245 19084
+f 1680 19519 1845
+f 19063 19177 19176
+f 19722 19723 19043
+f 19712 19333 19004
+f 19366 19273 19322
+f 19320 19365 19277
+f 19005 19466 19516
+f 15841 12384 8961
+f 18584 1332 19095
+f 1332 1333 19095
+f 19543 19566 19746
+f 19747 19543 19746
+f 11917 14401 18712
+f 6338 4970 3869
+f 18094 18096 17974
+f 10636 8801 9145
+f 19537 19460 19661
+f 19686 19561 19659
+f 19624 19658 1024
+f 19630 1220 1219
+f 18792 19284 18547
+f 19748 583 19588
+f 19497 19749 19652
+f 11977 9050 16293
+f 711 710 3397
+f 3396 19627 18513
+f 9420 576 1448
+f 2028 19686 2029
+f 1412 19505 18770
+f 19539 19564 19527
+f 19750 17430 17324
+f 5762 9372 19687
+f 19541 9586 9111
+f 19565 19541 9111
+f 7763 1488 19248
+f 19247 7763 19248
+f 4722 5757 1942
+f 19717 19751 19411
+f 19238 19752 19459
+f 19502 19238 19459
+f 13221 2723 1026
+f 18605 18604 755
+f 19090 19132 6221
+f 19181 6223 6222
+f 19738 19750 17324
+f 19750 19753 17433
+f 17430 19750 17433
+f 8917 19462 19633
+f 19754 19721 19092
+f 19722 19043 19045
+f 18573 15304 19653
+f 18556 1990 1992
+f 1874 19449 19128
+f 19448 19084 19087
+f 19358 19180 19131
+f 405 19338 18537
+f 9348 705 18572
+f 707 18544 18573
+f 11091 11776 6358
+f 5551 5407 5679
+f 10151 2740 2742
+f 2741 7130 7132
+f 19428 19725 19307
+f 19739 19755 19442
+f 19753 19756 17455
+f 17433 19753 17455
+f 19737 19000 19480
+f 19479 19737 19480
+f 19000 16550 19481
+f 19480 19000 19481
+f 19381 19707 19728
+f 19756 19757 17515
+f 19730 19725 19428
+f 19378 19730 19428
+f 19309 19700 19353
+f 2807 18792 18547
+f 3967 4621 18626
+f 4768 19684 18625
+f 16550 7632 19482
+f 19481 16550 19482
+f 17337 17339 1717
+f 3646 9516 3647
+f 19482 7632 7631
+f 19758 19759 17548
+f 7631 7633 19484
+f 14534 19760 3229
+f 19761 19762 19763
+f 15537 19764 2601
+f 3187 1211 1474
+f 2383 2548 19755
+f 9948 14256 14257
+f 19353 19731 19394
+f 11483 17592 13661
+f 12920 7645 19765
+f 4935 4937 19310
+f 18686 19766 14434
+f 17455 19756 17515
+f 16218 19767 18686
+f 17917 19152 4639
+f 671 9150 18837
+f 14838 18531 18467
+f 9175 9174 14576
+f 19709 19588 2776
+f 5234 19708 2981
+f 4849 2623 2625
+f 17194 19098 16696
+f 17200 1380 613
+f 14789 14482 18398
+f 19362 19315 19568
+f 19723 19712 19004
+f 19365 19403 19227
+f 19322 19320 19277
+f 19006 19516 19515
+f 19044 19006 19515
+f 18583 1330 18584
+f 1330 1332 18584
+f 19513 19543 19747
+f 19768 19513 19747
+f 6743 11187 16448
+f 1400 9017 1017
+f 811 5657 809
+f 1282 1281 1464
+f 19659 19537 19661
+f 19460 19412 19504
+f 19624 1024 1539
+f 1539 527 526
+f 18628 18566 18565
+f 9295 1526 19629
+f 18144 9665 15293
+f 19769 19449 1874
+f 7951 8466 906
+f 4339 14583 17336
+f 10680 10679 13116
+f 9805 6894 13172
+f 15097 17917 18246
+f 18770 19539 19527
+f 1569 10589 3434
+f 1775 13547 1773
+f 11568 3180 3179
+f 8935 19489 8936
+f 19663 923 19662
+f 514 8445 5522
+f 7549 2167 357
+f 16827 16828 19717
+f 19752 19770 19413
+f 19459 19752 19413
+f 12451 7851 11314
+f 807 7204 9866
+f 19132 19181 6222
+f 19771 6224 6223
+f 19047 19093 19772
+f 19773 19047 19772
+f 19113 19774 11839
+f 562 558 563
+f 19775 19754 19136
+f 19721 19045 19092
+f 9411 18432 18416
+f 2737 18398 2735
+f 1875 1874 19126
+f 19449 19087 19128
+f 18582 18971 318
+f 9298 9544 920
+f 5100 19049 1560
+f 19023 1256 1255
+f 1181 980 1177
+f 15815 6190 18799
+f 11820 11816 11916
+f 19776 2216 2215
+f 19394 19739 19442
+f 18224 1268 879
+f 19531 9332 912
+f 1211 1240 1474
+f 846 1782 847
+f 19100 19124 2473
+f 1661 1662 989
+f 18553 9320 18554
+f 16928 17561 17515
+f 19441 18476 19443
+f 19726 19699 19308
+f 19307 19726 19308
+f 19757 16928 17515
+f 9737 9738 1816
+f 6294 5524 9255
+f 19525 489 491
+f 9318 9320 18553
+f 588 417 1527
+f 865 666 18550
+f 1997 951 1999
+f 866 864 1682
+f 19629 18477 18457
+f 1999 866 1682
+f 17561 16928 16930
+f 19777 18514 2794
+f 7206 6510 4581
+f 11751 19113 11839
+f 9797 7260 10751
+f 6363 6362 13974
+f 6362 380 517
+f 5647 6080 8394
+f 4935 19355 19616
+f 18590 4935 19616
+f 16596 16356 16440
+f 19778 19779 19780
+f 5242 19547 5244
+f 19548 1255 5245
+f 9229 8844 5525
+f 1677 9740 19519
+f 19054 19501 17946
+f 7476 16123 14963
+f 18962 17610 17609
+f 19016 2155 19781
+f 19421 19362 19568
+f 19601 19421 19568
+f 19403 19453 19228
+f 19277 19365 19227
+f 19137 19091 19544
+f 19044 19515 19514
+f 1330 18583 19220
+f 628 1003 19398
+f 19752 19590 19770
+f 19542 19513 19768
+f 19782 15119 8293
+f 1433 17336 9180
+f 19783 19784 19593
+f 19326 339 19062
+f 19412 19414 19505
+f 19661 19460 19504
+f 3463 11231 11235
+f 19658 1219 1024
+f 13124 1279 13123
+f 4919 7259 4920
+f 8723 19785 8721
+f 15612 12714 18821
+f 9666 6078 9667
+f 17336 1433 1291
+f 7427 7426 7429
+f 15293 5919 18033
+f 10497 4016 9003
+f 8401 3794 3313
+f 4638 4639 19152
+f 19786 4638 19152
+f 9337 16330 7463
+f 1930 1929 19039
+f 2915 763 762
+f 19767 18685 18686
+f 19408 19411 19751
+f 366 2119 356
+f 19563 19783 19593
+f 19784 7312 7426
+f 19714 7313 7312
+f 19784 19714 7312
+f 19181 19771 6223
+f 19771 19773 19772
+f 5243 5376 19338
+f 353 312 19008
+f 14321 12976 12975
+f 13573 14542 209
+f 19775 19136 19134
+f 19018 19775 19134
+f 9411 9191 18432
+f 19772 19093 12872
+f 19451 1875 19125
+f 1874 19128 19126
+f 2000 2166 2075
+f 1388 19401 18299
+f 9230 9229 1389
+f 5793 1397 4474
+f 8684 8683 545
+f 9828 12550 6825
+f 19471 18814 1251
+f 996 19471 1251
+f 406 320 1667
+f 10166 19787 10089
+f 19786 19152 5920
+f 7212 3703 11272
+f 14434 16218 18686
+f 275 7763 19247
+f 4128 1716 4306
+f 19155 11038 2936
+f 4487 19294 3187
+f 19520 12452 19776
+f 2291 2135 16250
+f 19442 19755 2548
+f 9336 8622 881
+f 12848 4082 2533
+f 1640 19160 621
+f 3395 5950 9221
+f 6470 6785 6881
+f 19526 19520 19788
+f 4879 7741 4880
+f 18299 19789 15707
+f 7348 2144 2143
+f 19789 19790 19572
+f 15707 19789 19572
+f 19791 19573 19792
+f 19792 19550 19793
+f 19571 19573 19791
+f 19550 19526 19793
+f 19794 19571 19791
+f 19573 19550 19792
+f 6228 6364 8395
+f 8477 6363 13974
+f 19061 19060 18857
+f 18968 19795 13580
+f 19796 2832 2831
+f 1159 3183 368
+f 2794 18514 18968
+f 5245 1255 5374
+f 13905 5527 5526
+f 1393 1392 5240
+f 19501 15500 17946
+f 9150 3579 18837
+f 2155 2250 19781
+f 19797 2796 2795
+f 13926 1139 7950
+f 19315 19517 19568
+f 8665 1008 17200
+f 19227 19403 19228
+f 721 710 712
+f 19091 19044 19514
+f 9111 6500 6499
+f 628 19398 19094
+f 13849 13795 9809
+f 19770 19542 19768
+f 19354 18916 19547
+f 3151 8137 8271
+f 16570 16566 2271
+f 341 974 19063
+f 3940 19116 14561
+f 19795 1328 1327
+f 13792 8571 13790
+f 2736 3180 4638
+f 19798 19799 1533
+f 9350 19798 1533
+f 19799 19800 9666
+f 1533 19799 9666
+f 19800 19801 6078
+f 9666 19800 6078
+f 19801 19802 5920
+f 6078 19801 5920
+f 19802 19803 19786
+f 5920 19802 19786
+f 19804 4638 19786
+f 19803 19804 19786
+f 10679 3325 13116
+f 19804 2736 4638
+f 1488 923 19663
+f 1424 1416 10520
+f 15489 19559 15490
+f 8864 8917 19633
+f 19593 19784 7426
+f 16644 15344 6475
+f 15654 13301 13300
+f 19770 19768 19415
+f 18972 1479 19397
+f 19714 15364 7313
+f 2090 533 18971
+f 1479 537 19397
+f 1603 1890 2729
+f 12653 12652 19145
+f 19754 19092 19136
+f 19018 19134 19133
+f 18854 19805 19241
+f 18627 19806 14933
+f 19451 19125 19148
+f 7060 19451 19148
+f 525 4634 19569
+f 8874 935 9199
+f 1389 9229 1390
+f 8844 5526 5525
+f 14297 2411 15778
+f 369 638 370
+f 407 406 1372
+f 19008 19399 19101
+f 1695 6847 1696
+f 6364 6363 8477
+f 19807 19554 19808
+f 19570 19571 19794
+f 19790 19809 19584
+f 19572 19790 19584
+f 19809 19810 19585
+f 19584 19809 19585
+f 19788 19520 19776
+f 19811 19555 19807
+f 18567 18461 18599
+f 18471 18470 18600
+f 18666 19097 18667
+f 14056 3514 3109
+f 645 3395 9221
+f 19812 8893 2490
+f 19793 19526 19788
+f 7149 7150 19813
+f 19814 19586 19585
+f 19555 19554 19807
+f 19810 19814 19585
+f 19815 19587 19586
+f 19814 19815 19586
+f 19816 19608 19587
+f 19815 19816 19587
+f 19817 19583 19811
+f 19818 19609 19608
+f 19816 19818 19608
+f 19819 19582 19817
+f 19583 19555 19811
+f 19640 19820 19580
+f 8394 6228 8395
+f 18518 19821 19605
+f 15565 15564 19822
+f 8842 18771 8843
+f 477 9590 478
+f 511 19579 498
+f 6711 5354 2920
+f 19823 19824 19825
+f 8844 13905 5526
+f 1709 1711 1329
+f 6601 9476 9179
+f 19821 19826 16142
+f 1711 9230 1389
+f 13124 14790 19557
+f 7542 11251 12097
+f 2711 18532 2710
+f 4306 1716 1718
+f 2384 19776 2215
+f 3977 3976 4192
+f 3701 13662 3702
+f 18599 18600 9471
+f 5952 10168 5953
+f 18070 17929 19827
+f 5506 6079 5647
+f 15473 1173 12953
+f 1386 18299 15707
+f 19116 19828 14561
+f 19829 19830 8572
+f 13070 14576 10633
+f 19830 19831 19798
+f 8572 19830 19798
+f 19831 19832 19799
+f 19798 19831 19799
+f 19832 19833 19800
+f 19799 19832 19800
+f 19833 19834 19801
+f 19800 19833 19801
+f 19834 19835 19802
+f 19801 19834 19802
+f 19835 19836 19803
+f 19802 19835 19803
+f 19836 19837 19804
+f 19803 19836 19804
+f 2737 2736 19804
+f 19837 2737 19804
+f 8273 12426 8272
+f 345 347 14491
+f 8113 11988 11990
+f 3181 8390 13196
+f 713 5945 19363
+f 19510 19146 15491
+f 19413 19770 19415
+f 7194 7311 7429
+f 14404 14789 14791
+f 19768 19747 19416
+f 19046 5243 19338
+f 19746 19566 19714
+f 12559 19838 19839
+f 18582 2090 18971
+f 18966 19018 19133
+f 19224 19500 19535
+f 9038 9341 9061
+f 18966 19133 19193
+f 1875 19126 19125
+f 10678 11750 10957
+f 1392 9410 5240
+f 7106 19483 6437
+f 9401 9400 19840
+f 19841 2030 19795
+f 10154 15568 15456
+f 19842 19843 19059
+f 2807 9492 18792
+f 3547 4926 12293
+f 8395 6364 8477
+f 1886 1885 1126
+f 19808 19570 19794
+f 19844 19845 19639
+f 19846 19610 19609
+f 19847 19581 19819
+f 19818 19846 19609
+f 19848 19647 19610
+f 19846 19848 19610
+f 19554 19570 19808
+f 19849 19613 19847
+f 4083 1472 1471
+f 12751 8667 7335
+f 18686 17407 19766
+f 879 344 18224
+f 4936 18516 4937
+f 18481 9185 1547
+f 8549 1708 1707
+f 19850 19643 19670
+f 19672 19671 19851
+f 19671 19650 19852
+f 19848 19853 19648
+f 19647 19848 19648
+f 19853 19854 19649
+f 19648 19853 19649
+f 19854 10719 19678
+f 19649 19854 19678
+f 10719 11038 19679
+f 19678 10719 19679
+f 3350 17337 1717
+f 19673 19672 19851
+f 19855 19673 19851
+f 19644 19856 19645
+f 19857 19858 19606
+f 7059 19451 7060
+f 19859 18945 18990
+f 498 15357 499
+f 19529 7725 810
+f 921 3186 6509
+f 17298 19860 11228
+f 19010 9083 2230
+f 2230 9083 503
+f 3018 8040 2274
+f 19861 16000 15591
+f 1717 17339 1718
+f 19862 18466 18467
+f 17339 19863 6740
+f 1718 17339 6740
+f 19863 19864 19116
+f 6740 19863 19116
+f 19864 19865 19828
+f 19116 19864 19828
+f 19865 19827 16958
+f 19828 19865 16958
+f 19618 19174 19080
+f 6333 18890 6329
+f 18070 19866 19867
+f 5579 12802 5437
+f 19866 19868 19829
+f 19867 19866 19829
+f 19868 19869 19830
+f 19829 19868 19830
+f 19869 19870 19831
+f 19830 19869 19831
+f 19870 19871 19832
+f 19831 19870 19832
+f 19871 19872 19833
+f 19832 19871 19833
+f 19872 19873 19834
+f 19833 19872 19834
+f 19873 19874 19835
+f 19834 19873 19835
+f 19874 19875 19836
+f 19835 19874 19836
+f 19875 19876 19837
+f 19836 19875 19837
+f 19877 2737 19837
+f 19876 19877 19837
+f 19878 18398 2737
+f 19877 19878 2737
+f 715 9223 9422
+f 19878 14789 18398
+f 19414 19415 19417
+f 19416 19783 19563
+f 16032 19879 9194
+f 19417 19416 19563
+f 19415 19768 19416
+f 17201 613 1212
+f 9387 7737 7736
+f 19747 19746 19783
+f 5376 2090 18582
+f 6224 19771 19772
+f 19334 19224 19535
+f 19338 5376 18582
+f 18967 18966 19193
+f 19224 19226 19455
+f 18972 19397 4479
+f 18967 19193 12652
+f 7060 19148 19098
+f 9545 19669 6508
+f 1710 1411 1711
+f 17194 7060 19098
+f 19843 19569 19059
+f 19652 19749 18747
+f 961 963 12096
+f 9669 2116 4785
+f 8872 1126 1128
+f 9332 9331 19589
+f 19880 14359 14360
+f 14790 13124 14791
+f 19582 19583 19817
+f 19845 19820 19640
+f 19679 11038 19156
+f 19612 19613 19849
+f 19155 19694 19680
+f 19156 19155 19680
+f 19581 19582 19819
+f 19650 19611 19881
+f 19639 19845 19640
+f 19820 19857 19580
+f 18893 19546 407
+f 3570 3569 6588
+f 19519 2626 18421
+f 19314 18919 18921
+f 19882 19850 19670
+f 19708 3768 19709
+f 19883 19671 19852
+f 19850 19856 19644
+f 19695 19718 19884
+f 19677 19673 19855
+f 19680 19694 19693
+f 2278 1324 1323
+f 13974 6362 517
+f 9659 12166 18695
+f 19885 19530 19886
+f 2076 7449 15505
+f 19676 19677 19887
+f 5234 19682 19708
+f 19888 19889 19646
+f 19671 19883 19851
+f 5662 485 4936
+f 19645 19888 19646
+f 8843 19529 810
+f 9664 19326 19470
+f 9310 19890 19891
+f 9521 9419 1447
+f 14080 9521 1719
+f 19530 17059 19886
+f 4768 4792 19684
+f 2571 19053 2229
+f 1144 1057 1145
+f 14859 14701 8890
+f 1833 1454 9351
+f 4797 635 5060
+f 17338 19892 19863
+f 17339 17338 19863
+f 19892 19893 19864
+f 19863 19892 19864
+f 19893 19894 19865
+f 19864 19893 19865
+f 19894 19895 19827
+f 19865 19894 19827
+f 19895 19896 18070
+f 19827 19895 18070
+f 19896 19897 19866
+f 18070 19896 19866
+f 19897 19898 19868
+f 19866 19897 19868
+f 19898 19899 19869
+f 19868 19898 19869
+f 19899 19900 19870
+f 19869 19899 19870
+f 19900 19901 19871
+f 19870 19900 19871
+f 19901 19902 19872
+f 19871 19901 19872
+f 19902 19903 19873
+f 19872 19902 19873
+f 19903 19904 19874
+f 19873 19903 19874
+f 19904 19905 19875
+f 19874 19904 19875
+f 19905 19906 19876
+f 19875 19905 19876
+f 19907 19877 19876
+f 19906 19907 19876
+f 19908 19878 19877
+f 19907 19908 19877
+f 14790 14789 19878
+f 19908 14790 19878
+f 12828 12827 12918
+f 18975 18712 10885
+f 5945 9295 19553
+f 9702 774 776
+f 15119 19909 12647
+f 393 395 1456
+f 19416 19747 19783
+f 19910 19911 19912
+f 533 1479 18972
+f 19746 19714 19784
+f 18971 533 18972
+f 5945 19553 19363
+f 19500 19224 19455
+f 19006 19005 19516
+f 18963 18967 12652
+f 19404 19271 19366
+f 1221 19122 1289
+f 14284 14285 19468
+f 6921 6824 471
+f 18592 7946 10356
+f 583 585 18508
+f 5476 14080 1719
+f 5244 19548 5245
+f 18629 18628 18565
+f 9191 9190 8841
+f 9223 715 15901
+f 19060 18817 18857
+f 9230 8842 8844
+f 19580 19857 19606
+f 350 349 18480
+f 19913 19612 19849
+f 19858 19914 19607
+f 19852 19650 19881
+f 19613 19581 19847
+f 19611 19612 19913
+f 19881 19611 19913
+f 19606 19858 19607
+f 19915 19614 19607
+f 412 13658 5941
+f 1251 18814 18816
+f 8893 1646 9212
+f 19399 476 1676
+f 5938 3920 18791
+f 2252 7917 811
+f 19643 19850 19644
+f 19355 19310 18511
+f 19916 19677 19855
+f 19856 19888 19645
+f 19917 17070 17069
+f 19677 19916 19887
+f 15860 7451 19736
+f 17870 19737 19736
+f 7451 8884 19736
+f 8884 8883 17870
+f 19737 17870 19000
+f 19692 19681 19918
+f 19676 19887 19919
+f 19920 19921 19675
+f 19889 19920 19674
+f 19401 1388 13300
+f 1249 9423 1264
+f 1990 1679 1991
+f 9348 18572 9349
+f 19397 5943 4479
+f 1289 9199 9400
+f 9229 5525 1390
+f 13905 809 5657
+f 9828 9827 2145
+f 18772 9141 671
+f 18609 19313 19314
+f 19922 19923 9156
+f 291 290 4769
+f 19632 19269 19601
+f 13665 19924 19892
+f 17338 13665 19892
+f 19924 19925 19893
+f 19892 19924 19893
+f 19925 19926 19894
+f 19893 19925 19894
+f 19926 19927 19895
+f 19894 19926 19895
+f 19927 19928 19896
+f 19895 19927 19896
+f 19928 19929 19897
+f 19896 19928 19897
+f 19929 19930 19898
+f 19897 19929 19898
+f 19930 19931 19899
+f 19898 19930 19899
+f 19931 19932 19900
+f 19899 19931 19900
+f 19932 19933 19901
+f 19900 19932 19901
+f 19933 19934 19902
+f 19901 19933 19902
+f 19934 19935 19903
+f 19902 19934 19903
+f 19935 19936 19904
+f 19903 19935 19904
+f 19936 19937 19905
+f 19904 19936 19905
+f 19937 19938 19906
+f 19905 19937 19906
+f 19939 19907 19906
+f 19938 19939 19906
+f 19940 19908 19907
+f 19939 19940 19907
+f 19941 14790 19908
+f 19940 19941 19908
+f 15654 13300 15542
+f 19941 19557 14790
+f 19942 19766 11917
+f 1791 6790 1792
+f 19187 19186 19238
+f 19943 19944 1358
+f 19238 19237 19752
+f 19237 19590 19752
+f 19783 19746 19784
+f 19590 19542 19770
+f 6037 6133 6036
+f 1003 1330 19220
+f 19005 19334 19535
+f 13679 4327 7552
+f 19273 19320 19322
+f 19466 19005 19535
+f 19317 14284 19468
+f 19276 19271 19404
+f 19315 19317 19468
+f 19534 19496 19498
+f 13580 19795 1327
+f 19517 19315 19468
+f 17447 7321 2619
+f 18770 19527 18771
+f 18892 12426 12427
+f 18922 18975 19423
+f 18968 19841 19795
+f 19251 9330 19531
+f 7939 8549 12095
+f 1450 14498 1451
+f 19945 19946 19651
+f 349 9183 18480
+f 19914 19915 19607
+f 19615 19945 19651
+f 19945 19615 19614
+f 19915 19945 19614
+f 19882 19670 19651
+f 19946 19882 19651
+f 19947 18590 1647
+f 9185 19812 2490
+f 18419 6509 18858
+f 2626 2628 18421
+f 19623 9013 9015
+f 19241 19395 18953
+f 18511 18507 19195
+f 19797 19616 2796
+f 19646 19889 19674
+f 19948 19949 19691
+f 19697 19692 19950
+f 19681 19919 19918
+f 542 17870 543
+f 19000 542 16550
+f 19761 9566 19951
+f 16550 10453 7632
+f 18519 4165 19952
+f 19692 19918 19950
+f 19953 19954 19955
+f 19674 19920 19675
+f 19681 19676 19919
+f 18503 18974 18973
+f 19921 19948 19701
+f 19956 19957 19958
+f 18792 394 393
+f 15322 461 2139
+f 1547 2492 1548
+f 11977 1212 9050
+f 19959 19797 2795
+f 17811 12887 8692
+f 1067 1345 8870
+f 18958 6523 18959
+f 18970 2095 19016
+f 496 1415 1414
+f 10205 10353 10423
+f 12596 4012 1995
+f 1277 1279 19557
+f 13664 19960 19924
+f 13665 13664 19924
+f 19960 19961 19925
+f 19924 19960 19925
+f 19961 19962 19926
+f 19925 19961 19926
+f 19962 19963 19927
+f 19926 19962 19927
+f 19963 19964 19928
+f 19927 19963 19928
+f 19964 19965 19929
+f 19928 19964 19929
+f 19965 19966 19930
+f 19929 19965 19930
+f 19966 19967 19931
+f 19930 19966 19931
+f 19967 19968 19932
+f 19931 19967 19932
+f 19968 19969 19933
+f 19932 19968 19933
+f 19969 19970 19934
+f 19933 19969 19934
+f 19970 19971 19935
+f 19934 19970 19935
+f 19971 19972 19936
+f 19935 19971 19936
+f 19972 19973 19937
+f 19936 19972 19937
+f 19973 19974 19938
+f 19937 19973 19938
+f 19975 19939 19938
+f 19974 19975 19938
+f 19976 19940 19939
+f 19975 19976 19939
+f 19977 19941 19940
+f 19976 19977 19940
+f 19978 19557 19941
+f 19977 19978 19941
+f 16602 19979 17157
+f 19978 1277 19557
+f 15318 13221 1831
+f 9260 18322 278
+f 7260 9797 6358
+f 14782 19980 19981
+f 19241 18953 1522
+f 439 18854 1521
+f 312 628 19094
+f 1003 19220 19398
+f 19138 19567 19600
+f 19135 19138 19600
+f 19138 19137 19567
+f 19137 19544 19567
+f 19457 19276 19404
+f 19091 19514 19544
+f 19226 19276 19457
+f 19271 19273 19366
+f 1033 1028 1780
+f 19455 19226 19457
+f 18771 19527 19529
+f 1411 1413 9230
+f 472 1245 6720
+f 19982 5793 5792
+f 19160 19251 19531
+f 19983 19984 19985
+f 9335 1967 1966
+f 19251 19311 9330
+f 2806 19444 2807
+f 9185 2490 1547
+f 14701 8891 8890
+f 18504 18503 18973
+f 19986 19947 1646
+f 18815 19311 19251
+f 19986 1646 8893
+f 18590 19616 1647
+f 19812 19986 8893
+f 19947 1647 1646
+f 5102 937 5103
+f 9664 19470 19469
+f 19064 19176 18814
+f 19471 19064 18814
+f 18893 13467 19546
+f 19046 19338 405
+f 19701 19948 19691
+f 19949 19987 19698
+f 19988 19707 19989
+f 19697 19950 19989
+f 17232 17004 8131
+f 17096 728 16794
+f 15480 693 14642
+f 847 1661 989
+f 1662 610 19990
+f 989 1662 19990
+f 19991 19728 19988
+f 19707 19696 19989
+f 19992 19993 19730
+f 19675 19921 19701
+f 19724 19992 19730
+f 19993 19994 19725
+f 3654 3653 19995
+f 19443 1161 11776
+f 19664 19996 19657
+f 1032 13221 1026
+f 3513 18543 3514
+f 19616 19797 19358
+f 1220 19122 1221
+f 6534 1181 1177
+f 6185 1243 475
+f 19326 19062 19470
+f 13560 12550 12101
+f 1413 18771 8842
+f 18400 9175 14576
+f 15707 2582 2581
+f 19997 19998 19960
+f 13664 19997 19960
+f 19998 19999 19961
+f 19960 19998 19961
+f 19999 20000 19962
+f 19961 19999 19962
+f 20000 20001 19963
+f 19962 20000 19963
+f 20001 20002 19964
+f 19963 20001 19964
+f 20002 20003 19965
+f 19964 20002 19965
+f 20003 20004 19966
+f 19965 20003 19966
+f 20004 20005 19967
+f 19966 20004 19967
+f 20005 20006 19968
+f 19967 20005 19968
+f 20006 20007 19969
+f 19968 20006 19969
+f 20007 20008 19970
+f 19969 20007 19970
+f 20008 20009 19971
+f 19970 20008 19971
+f 20009 20010 19972
+f 19971 20009 19972
+f 20010 20011 19973
+f 19972 20010 19973
+f 20011 20012 19974
+f 19973 20011 19974
+f 20013 19975 19974
+f 20012 20013 19974
+f 20014 19976 19975
+f 20013 20014 19975
+f 20015 19977 19976
+f 20014 20015 19976
+f 20016 19978 19977
+f 20015 20016 19977
+f 20017 1277 19978
+f 20016 20017 19978
+f 9854 15363 8134
+f 20017 19077 1277
+f 20018 5533 20019
+f 208 13573 209
+f 6741 1580 1579
+f 12385 3012 8961
+f 19631 17311 17313
+f 20020 20021 20022
+f 17313 19135 19631
+f 19135 19600 19631
+f 2518 2517 1130
+f 18505 5517 18506
+f 19499 8135 19373
+f 11146 18593 3348
+f 19499 19373 19228
+f 19453 19499 19228
+f 1526 18629 19628
+f 8135 8134 19373
+f 1257 2794 18969
+f 19173 3378 2105
+f 19249 9334 9333
+f 1257 18969 5375
+f 18974 18586 18585
+f 527 4634 525
+f 9331 9335 1966
+f 19311 9333 9330
+f 8936 20023 9059
+f 16072 19489 9062
+f 13097 1013 12919
+f 18593 3752 3348
+f 11977 17201 1212
+f 8684 545 547
+f 14144 16109 2087
+f 13665 17338 13666
+f 18481 1547 1546
+f 20024 1678 1679
+f 1372 8938 1373
+f 18483 18481 1546
+f 19356 1546 19357
+f 18668 18479 18478
+f 935 937 9200
+f 19082 19518 18482
+f 19691 19949 19698
+f 432 434 4922
+f 19696 19697 19989
+f 19987 19992 19724
+f 728 9546 16794
+f 19728 19707 19988
+f 610 606 18524
+f 3193 5362 4335
+f 12553 4922 13644
+f 1683 588 1527
+f 19734 19745 17215
+f 17215 19745 19991
+f 20025 16265 20026
+f 19745 19728 19991
+f 19994 20027 19726
+f 19730 19993 19725
+f 9333 9335 9331
+f 18918 19199 2806
+f 20028 9013 19623
+f 18569 18525 19294
+f 4173 3281 6073
+f 6885 18922 19423
+f 17075 14545 15551
+f 18584 19095 9214
+f 9059 20023 8683
+f 18593 20029 3752
+f 3752 20029 19997
+f 19077 11729 1277
+f 20029 20030 19997
+f 15742 17239 19030
+f 20030 20031 19998
+f 19997 20030 19998
+f 20031 20032 19999
+f 19998 20031 19999
+f 20032 20033 20000
+f 19999 20032 20000
+f 20033 20034 20001
+f 20000 20033 20001
+f 20034 20035 20002
+f 20001 20034 20002
+f 20035 20036 20003
+f 20002 20035 20003
+f 20036 20037 20004
+f 20003 20036 20004
+f 20037 20038 20005
+f 20004 20037 20005
+f 20038 20039 20006
+f 20005 20038 20006
+f 20039 20040 20007
+f 20006 20039 20007
+f 20040 20041 20008
+f 20007 20040 20008
+f 20041 20042 20009
+f 20008 20041 20009
+f 20042 20043 20010
+f 20009 20042 20010
+f 20043 20044 20011
+f 20010 20043 20011
+f 20044 20045 20012
+f 20011 20044 20012
+f 20046 20013 20012
+f 20045 20046 20012
+f 20047 20014 20013
+f 20046 20047 20013
+f 20048 20015 20014
+f 20047 20048 20014
+f 20049 20016 20015
+f 20048 20049 20015
+f 19715 20017 20016
+f 20049 19715 20016
+f 15249 19077 20017
+f 19715 15249 20017
+f 6367 5975 13679
+f 9306 9308 801
+f 18954 19446 930
+f 13467 5372 19046
+f 713 19363 18986
+f 17157 19979 4465
+f 20050 15531 19556
+f 1522 18953 929
+f 14281 14282 14217
+f 2629 2631 18463
+f 19619 19336 19620
+f 19223 19667 19620
+f 19223 19269 19632
+f 19270 19223 19620
+f 19269 19421 19601
+f 19667 19223 19632
+f 1357 1356 4760
+f 503 479 481
+f 5374 1257 5375
+f 18969 13580 5377
+f 19843 20051 525
+f 5521 1329 1390
+f 9330 9333 9331
+f 19147 1649 19023
+f 14491 18616 1285
+f 15399 18614 11030
+f 7052 6843 6942
+f 14871 16963 14546
+f 19294 1211 3187
+f 18397 2022 3369
+f 18569 19294 4487
+f 348 18569 4487
+f 1797 7335 8667
+f 547 13196 8684
+f 18485 19356 1543
+f 10183 18776 8956
+f 19099 694 4480
+f 18501 18485 1543
+f 19399 1676 19102
+f 2184 19082 18482
+f 1372 1667 8938
+f 19774 20052 11842
+f 19698 19987 19724
+f 20053 20054 17242
+f 9332 19589 913
+f 913 19589 1815
+f 2285 2284 5362
+f 915 917 19486
+f 2285 679 2286
+f 5163 17221 5164
+f 9331 1966 19589
+f 1525 18629 1526
+f 18476 18488 19443
+f 19443 18488 1161
+f 20024 1679 1990
+f 19725 19994 19726
+f 5943 19101 916
+f 19199 19444 2806
+f 20055 15966 17748
+f 1812 2150 2486
+f 15874 3603 3605
+f 16791 19688 4947
+f 1810 1812 2486
+f 14624 12511 12512
+f 10356 20056 18593
+f 18592 10356 18593
+f 20056 20057 20029
+f 18593 20056 20029
+f 20057 20058 20030
+f 20029 20057 20030
+f 20058 20059 20031
+f 20030 20058 20031
+f 20059 20060 20032
+f 20031 20059 20032
+f 20060 20061 20033
+f 20032 20060 20033
+f 20061 20062 20034
+f 20033 20061 20034
+f 20062 20063 20035
+f 20034 20062 20035
+f 20063 20064 20036
+f 20035 20063 20036
+f 20064 20065 20037
+f 20036 20064 20037
+f 20065 20066 20038
+f 20037 20065 20038
+f 20066 20067 20039
+f 20038 20066 20039
+f 20067 20068 20040
+f 20039 20067 20040
+f 20068 20069 20041
+f 20040 20068 20041
+f 20069 20070 20042
+f 20041 20069 20042
+f 20070 20071 20043
+f 20042 20070 20043
+f 20071 20072 20044
+f 20043 20071 20044
+f 20072 20073 20045
+f 20044 20072 20045
+f 20074 20046 20045
+f 20073 20074 20045
+f 20075 20047 20046
+f 20074 20075 20046
+f 20076 20048 20047
+f 20075 20076 20047
+f 20077 20049 20048
+f 20076 20077 20048
+f 14517 19715 20049
+f 20077 14517 20049
+f 5536 8368 12269
+f 20078 9146 9148
+f 20079 17659 17650
+f 8936 634 20023
+f 19446 8813 930
+f 9083 9349 479
+f 19086 19085 19723
+f 19246 19683 19712
+f 19292 19654 19683
+f 19085 19246 19712
+f 19292 19336 19619
+f 19246 19292 19683
+f 19336 19270 19620
+f 19654 19292 19619
+f 19131 19180 19132
+f 19248 19663 9334
+f 1057 3704 1145
+f 9191 18433 18432
+f 15777 15365 14297
+f 497 496 1414
+f 5375 18969 5377
+f 19122 8874 1289
+f 4635 4636 20080
+f 6500 4635 20080
+f 18485 18483 19356
+f 19023 19022 1256
+f 760 759 7127
+f 4487 4599 349
+f 18514 19841 18968
+f 16966 15905 15904
+f 20081 20079 17650
+f 600 2572 1957
+f 14789 14404 14482
+f 18669 20082 19401
+f 2383 19755 2384
+f 13299 18669 19401
+f 1678 1680 1679
+f 11039 5782 5643
+f 18473 18501 7765
+f 19213 18587 8939
+f 18601 18455 18567
+f 916 19102 20024
+f 666 665 9316
+f 4634 1290 9401
+f 19788 19776 2384
+f 20083 19788 2384
+f 19793 19788 20083
+f 20084 19793 20083
+f 20082 20085 18299
+f 19401 20082 18299
+f 20085 20086 19789
+f 18299 20085 19789
+f 20086 20087 19790
+f 20088 19791 20089
+f 19789 20086 19790
+f 19792 19793 20084
+f 20089 19792 20084
+f 8874 6501 935
+f 9586 720 4635
+f 18601 18567 19490
+f 916 20024 917
+f 7136 10636 9145
+f 6513 6512 7320
+f 16859 16293 9049
+f 19621 4952 4949
+f 5783 20090 10356
+f 3464 11235 11237
+f 20090 20091 20056
+f 10356 20090 20056
+f 20091 20092 20057
+f 20056 20091 20057
+f 20092 20093 20058
+f 20057 20092 20058
+f 20093 20094 20059
+f 20058 20093 20059
+f 20094 20095 20060
+f 20059 20094 20060
+f 20095 20096 20061
+f 20060 20095 20061
+f 20096 20097 20062
+f 20061 20096 20062
+f 20097 20098 20063
+f 20062 20097 20063
+f 20098 20099 20064
+f 20063 20098 20064
+f 20099 20100 20065
+f 20064 20099 20065
+f 20100 20101 20066
+f 20065 20100 20066
+f 20101 20102 20067
+f 20066 20101 20067
+f 20102 20103 20068
+f 20067 20102 20068
+f 20103 20104 20069
+f 20068 20103 20069
+f 20104 20105 20070
+f 20069 20104 20070
+f 20105 20106 20071
+f 20070 20105 20071
+f 20106 20107 20072
+f 20071 20106 20072
+f 20107 20108 20073
+f 20072 20107 20073
+f 20109 20074 20073
+f 20108 20109 20073
+f 20110 20075 20074
+f 20109 20110 20074
+f 20111 20076 20075
+f 20110 20111 20075
+f 20112 20077 20076
+f 20111 20112 20076
+f 20113 14517 20077
+f 20112 20113 20077
+f 14933 19806 20078
+f 20113 14518 14517
+f 6740 19116 2912
+f 8193 8137 8011
+f 5238 5239 19097
+f 19009 19653 480
+f 19129 19086 19722
+f 19085 19712 19723
+f 2797 19195 19048
+f 19047 2797 19048
+f 2797 19047 19773
+f 2795 2797 19773
+f 2795 19773 19771
+f 19959 2795 19771
+f 19959 19771 19181
+f 19180 19959 19181
+f 1809 1745 1747
+f 18428 921 18419
+f 810 809 13905
+f 6509 19666 18858
+f 9665 1534 1533
+f 7058 7060 17194
+f 722 1650 4636
+f 711 19022 1649
+f 18483 1546 19356
+f 4636 9409 9407
+f 917 1990 18556
+f 19486 917 18556
+f 20027 19794 20088
+f 19666 9478 18822
+f 20087 20114 19809
+f 19790 20087 19809
+f 20115 19810 19809
+f 20114 20115 19809
+f 20080 4636 9407
+f 19948 19847 19949
+f 19213 19486 18587
+f 1667 8939 8938
+f 9171 18601 19445
+f 848 990 1525
+f 8691 14141 14143
+f 16572 16570 4770
+f 19921 19849 19948
+f 19847 19819 19949
+f 20116 19814 19810
+f 20115 20116 19810
+f 20117 19815 19814
+f 20116 20117 19814
+f 20118 19816 19815
+f 20117 20118 19815
+f 20119 19818 19816
+f 20118 20119 19816
+f 19920 19913 19921
+f 19849 19847 19948
+f 9665 9667 15293
+f 20120 17683 17659
+f 9169 9171 19396
+f 19396 9171 19445
+f 11484 1772 14146
+f 13396 14043 13394
+f 17336 1291 4339
+f 20121 5196 5195
+f 20122 20123 20090
+f 5783 20122 20090
+f 20123 20124 20091
+f 20090 20123 20091
+f 20124 20125 20092
+f 20091 20124 20092
+f 20125 20126 20093
+f 20092 20125 20093
+f 20126 20127 20094
+f 20093 20126 20094
+f 20127 20128 20095
+f 20094 20127 20095
+f 20128 20129 20096
+f 20095 20128 20096
+f 20129 20130 20097
+f 20096 20129 20097
+f 20130 20131 20098
+f 20097 20130 20098
+f 20131 20132 20099
+f 20098 20131 20099
+f 20132 20133 20100
+f 20099 20132 20100
+f 20133 20134 20101
+f 20100 20133 20101
+f 20134 20135 20102
+f 20101 20134 20102
+f 20135 20136 20103
+f 20102 20135 20103
+f 20136 20137 20104
+f 20103 20136 20104
+f 20137 20138 20105
+f 20104 20137 20105
+f 20138 20139 20106
+f 20105 20138 20106
+f 20139 20140 20107
+f 20106 20139 20107
+f 20140 20141 20108
+f 20107 20140 20108
+f 20142 20109 20108
+f 20141 20142 20108
+f 20143 20110 20109
+f 20142 20143 20109
+f 20144 20111 20110
+f 20143 20144 20110
+f 20145 20112 20111
+f 20144 20145 20111
+f 20146 20113 20112
+f 20145 20146 20112
+f 14106 14518 20113
+f 20146 14106 20113
+f 8919 14279 19337
+f 1201 1202 426
+f 479 19009 480
+f 19653 9910 19579
+f 19130 19129 19721
+f 19086 19723 19722
+f 19195 5785 5784
+f 19048 19195 5784
+f 19519 18421 1845
+f 9598 19662 9594
+f 19663 19662 9598
+f 810 7725 2252
+f 19470 19062 19064
+f 9334 19663 9598
+f 9255 13331 9256
+f 19662 2187 9594
+f 9110 6499 19122
+f 2981 19709 2776
+f 3207 16795 3208
+f 19498 19497 19652
+f 712 711 1649
+f 711 3397 19777
+f 18953 19396 18954
+f 6501 20080 9407
+f 917 20024 1990
+f 19486 18556 18587
+f 19808 19794 20027
+f 19791 19792 20089
+f 20147 19846 19818
+f 20119 20147 19818
+f 20148 19848 19846
+f 20147 20148 19846
+f 19819 19817 19987
+f 20148 20149 19853
+f 19949 19819 19987
+f 19817 19811 19992
+f 1667 19213 8939
+f 1128 1373 8873
+f 19083 9169 19395
+f 19395 9169 19396
+f 20150 19439 604
+f 4328 8137 2773
+f 19889 19881 19920
+f 19913 19849 19921
+f 19848 20148 19853
+f 20149 9258 19854
+f 19853 20149 19854
+f 14499 14498 10252
+f 19854 9258 10719
+f 20151 19155 2936
+f 2854 2853 3039
+f 19888 19852 19889
+f 19881 19913 19920
+f 1237 1282 342
+f 1450 1282 1237
+f 9013 699 9014
+f 699 701 9014
+f 19094 476 19399
+f 19528 7630 7725
+f 13929 14518 13926
+f 19022 711 19777
+f 396 16401 17446
+f 17222 20152 20153
+f 16746 20154 20124
+f 20155 20156 19371
+f 20154 20157 20125
+f 20124 20154 20125
+f 20157 20158 20126
+f 20125 20157 20126
+f 20158 20159 20127
+f 20126 20158 20127
+f 20159 20160 20128
+f 20127 20159 20128
+f 20160 20161 20129
+f 20128 20160 20129
+f 20161 20162 20130
+f 20129 20161 20130
+f 20162 20163 20131
+f 20130 20162 20131
+f 20163 20164 20132
+f 20131 20163 20132
+f 20164 20165 20133
+f 20132 20164 20133
+f 20165 20166 20134
+f 20133 20165 20134
+f 20166 20167 20135
+f 20134 20166 20135
+f 20167 20168 20136
+f 20135 20167 20136
+f 20168 20169 20137
+f 20136 20168 20137
+f 20169 20170 20138
+f 20137 20169 20138
+f 20170 20171 20139
+f 20138 20170 20139
+f 20171 20172 20140
+f 20139 20171 20140
+f 20172 20173 20141
+f 20140 20172 20141
+f 20174 20142 20141
+f 20173 20174 20141
+f 20175 20143 20142
+f 20174 20175 20142
+f 20176 20144 20143
+f 20175 20176 20143
+f 20177 20145 20144
+f 20176 20177 20144
+f 20178 20146 20145
+f 20177 20178 20145
+f 1140 14106 20146
+f 20178 1140 20146
+f 4466 20179 4464
+f 13914 10003 19293
+f 480 19653 19579
+f 2894 9684 2892
+f 19127 19130 19754
+f 19129 19722 19721
+f 2627 9411 18416
+f 18548 3222 19891
+f 19532 19575 19525
+f 18542 18548 10254
+f 19358 19797 19180
+f 20079 20120 17659
+f 1648 19358 19131
+f 19797 19959 19180
+f 13467 19046 19546
+f 19546 19046 405
+f 803 1181 6534
+f 4485 18583 9220
+f 6224 19772 12872
+f 4772 6224 12872
+f 19777 3397 18514
+f 18513 2028 19841
+f 19445 19490 19446
+f 4634 9401 19569
+f 665 8755 9316
+f 9547 9319 9318
+f 19994 19808 20027
+f 19794 19791 20088
+f 19807 19808 19994
+f 19993 19807 19994
+f 19987 19817 19992
+f 19811 19807 19993
+f 19628 18565 18472
+f 19992 19811 19993
+f 9400 9199 19621
+f 19553 19629 18457
+f 19628 18472 18477
+f 1805 1807 9259
+f 9014 701 19805
+f 701 19083 19805
+f 1282 1464 342
+f 342 1464 343
+f 19883 19852 19888
+f 19856 19883 19888
+f 4796 2650 6741
+f 7434 1797 8667
+f 20180 20151 20181
+f 19155 20151 19694
+f 3040 7766 1472
+f 20151 20180 19719
+f 19883 19856 19850
+f 19851 19883 19850
+f 708 1458 8041
+f 1464 7956 343
+f 9199 9200 19621
+f 6077 699 9013
+f 14035 13943 13946
+f 19490 18567 9470
+f 11233 11303 8018
+f 20182 11591 20183
+f 17563 15986 17493
+f 3393 398 17492
+f 1960 3709 3708
+f 16746 20123 16747
+f 20184 20185 20157
+f 20154 20184 20157
+f 20185 20186 20158
+f 20157 20185 20158
+f 20186 20187 20159
+f 20158 20186 20159
+f 20187 20188 20160
+f 20159 20187 20160
+f 20188 20189 20161
+f 20160 20188 20161
+f 20189 20190 20162
+f 20161 20189 20162
+f 20190 20191 20163
+f 20162 20190 20163
+f 20191 20192 20164
+f 20163 20191 20164
+f 20192 20193 20165
+f 20164 20192 20165
+f 20193 20194 20166
+f 20165 20193 20166
+f 20194 20195 20167
+f 20166 20194 20167
+f 20195 20196 20168
+f 20167 20195 20168
+f 20196 20197 20169
+f 20168 20196 20169
+f 20197 20198 20170
+f 20169 20197 20170
+f 20198 20199 20171
+f 20170 20198 20171
+f 20199 20200 20172
+f 20171 20199 20172
+f 20200 20201 20173
+f 20172 20200 20173
+f 20202 20174 20173
+f 20201 20202 20173
+f 20203 20175 20174
+f 20202 20203 20174
+f 20204 20176 20175
+f 20203 20204 20175
+f 20205 20177 20176
+f 20204 20205 20176
+f 20206 20178 20177
+f 20205 20206 20177
+f 14772 1140 20178
+f 20206 14772 20178
+f 20207 17793 20208
+f 8011 4328 7918
+f 16746 20209 20154
+f 927 6753 928
+f 19149 19127 19775
+f 19130 19721 19754
+f 1535 9422 9051
+f 494 18546 9422
+f 9586 4635 6500
+f 19575 489 19525
+f 2250 2310 19690
+f 20210 17687 17683
+f 19312 19024 3150
+f 5786 5787 5789
+f 19547 19548 5244
+f 9593 8914 8386
+f 3131 6309 6641
+f 5788 9348 9347
+f 19840 4949 7866
+f 1327 1329 5521
+f 18514 18513 19841
+f 12945 13860 12633
+f 18815 19178 19311
+f 525 19569 19843
+f 5954 833 835
+f 833 9078 9077
+f 15567 16214 20211
+f 9477 995 997
+f 19669 995 9477
+f 3186 9545 6508
+f 18565 18500 18472
+f 19629 19628 18477
+f 4328 5657 7918
+f 19553 18457 18456
+f 2675 2674 5658
+f 5789 5788 9347
+f 1277 11729 1278
+f 8843 810 13905
+f 19805 19083 19395
+f 12452 2216 19776
+f 7956 1458 708
+f 20028 6077 9013
+f 19852 19881 19889
+f 343 7956 708
+f 10203 10048 10120
+f 19855 19851 19882
+f 20212 20213 20214
+f 20215 20216 20217
+f 20218 20219 20220
+f 20221 20222 20223
+f 20224 20225 20226
+f 19916 19855 19946
+f 19851 19850 19882
+f 8041 1840 1713
+f 1840 754 1713
+f 19785 8723 9527
+f 1215 6077 20028
+f 16251 16966 15904
+f 3516 1930 9305
+f 9197 7338 11305
+f 11234 11233 8018
+f 2568 20227 20228
+f 2568 2567 20227
+f 17050 2568 20228
+f 2567 17564 20227
+f 20229 20230 20185
+f 20154 20209 20184
+f 20230 20231 20186
+f 20185 20230 20186
+f 20231 20232 20187
+f 20186 20231 20187
+f 20232 20233 20188
+f 20187 20232 20188
+f 20233 20234 20189
+f 20188 20233 20189
+f 20234 20235 20190
+f 20189 20234 20190
+f 20235 20236 20191
+f 20190 20235 20191
+f 20236 20237 20192
+f 20191 20236 20192
+f 20237 20238 20193
+f 20192 20237 20193
+f 20238 20239 20194
+f 20193 20238 20194
+f 20239 20240 20195
+f 20194 20239 20195
+f 20240 20241 20196
+f 20195 20240 20196
+f 20241 20242 20197
+f 20196 20241 20197
+f 20242 20243 20198
+f 20197 20242 20198
+f 20243 20244 20199
+f 20198 20243 20199
+f 20244 20245 20200
+f 20199 20244 20200
+f 20245 20246 20201
+f 20200 20245 20201
+f 20247 20202 20201
+f 20246 20247 20201
+f 20248 20203 20202
+f 20247 20248 20202
+f 20249 20204 20203
+f 20248 20249 20203
+f 20250 20205 20204
+f 20249 20250 20204
+f 20251 20206 20205
+f 20250 20251 20205
+f 20252 14772 20206
+f 20251 20252 20206
+f 13644 6884 17928
+f 18712 19942 11917
+f 805 2407 9733
+f 2407 4934 19015
+f 19017 19149 19018
+f 19127 19754 19775
+f 4633 3385 9051
+f 3385 1535 9051
+f 1220 9110 19122
+f 19805 19395 19241
+f 19597 19217 15493
+f 19781 2250 19690
+f 19375 19312 2980
+f 19025 5941 4475
+f 759 7225 7127
+f 7866 7865 19058
+f 17931 9996 15194
+f 8018 11303 11305
+f 8359 9663 9946
+f 12848 13395 13394
+f 19841 2028 2030
+f 9014 19805 18854
+f 627 2116 8752
+f 16403 15530 15532
+f 9419 1448 1447
+f 9230 1413 8842
+f 1025 1221 1290
+f 4919 10751 7260
+f 19102 1678 20024
+f 6508 19669 9477
+f 319 915 19486
+f 2138 9346 9345
+f 19660 18515 1710
+f 5950 350 9222
+f 20120 20210 17683
+f 1255 1257 5374
+f 8563 4026 6323
+f 3753 9390 5722
+f 8563 10077 10872
+f 17979 20253 17980
+f 9401 19840 19057
+f 20254 16250 16182
+f 1458 1840 8041
+f 1713 754 433
+f 19916 19946 19945
+f 19887 19916 19945
+f 20255 19637 14876
+f 544 10453 542
+f 20256 20257 20258
+f 19990 610 18524
+f 20259 20260 14988
+f 19887 19945 19915
+f 19919 19887 19915
+f 2102 1375 436
+f 754 756 433
+f 9971 8504 9906
+f 19996 1215 20028
+f 14551 14685 9253
+f 474 10892 10891
+f 9197 8980 7338
+f 11304 9197 11305
+f 20261 4434 8979
+f 8980 4434 4433
+f 17050 20228 20262
+f 16633 17050 20262
+f 20263 20264 20230
+f 20229 20185 20184
+f 20264 20265 20231
+f 20230 20264 20231
+f 20265 20266 20232
+f 20231 20265 20232
+f 20266 20267 20233
+f 20232 20266 20233
+f 20267 20268 20234
+f 20233 20267 20234
+f 20268 20269 20235
+f 20234 20268 20235
+f 20269 20270 20236
+f 20235 20269 20236
+f 20270 20271 20237
+f 20236 20270 20237
+f 20271 20272 20238
+f 20237 20271 20238
+f 20272 20273 20239
+f 20238 20272 20239
+f 20273 20274 20240
+f 20239 20273 20240
+f 20274 20275 20241
+f 20240 20274 20241
+f 20275 20276 20242
+f 20241 20275 20242
+f 20276 20277 20243
+f 20242 20276 20243
+f 20277 20278 20244
+f 20243 20277 20244
+f 20278 20279 20245
+f 20244 20278 20245
+f 20279 20280 20246
+f 20245 20279 20246
+f 20281 20247 20246
+f 20280 20281 20246
+f 20282 20248 20247
+f 20281 20282 20247
+f 20283 20249 20248
+f 20282 20283 20248
+f 20284 20250 20249
+f 20283 20284 20249
+f 20285 20251 20250
+f 20284 20285 20250
+f 20286 20252 20251
+f 20285 20286 20251
+f 8506 9256 4650
+f 20286 20287 20252
+f 18510 9594 2186
+f 6329 2485 6333
+f 19149 19775 19018
+f 2383 2215 2382
+f 20288 14981 20289
+f 9050 4633 9051
+f 1873 19769 1874
+f 18272 18273 19377
+f 12777 7227 20290
+f 15492 19597 15493
+f 2979 13334 2980
+f 19024 4475 3150
+f 7644 8195 14569
+f 1024 1219 1025
+f 9555 9077 9556
+f 9077 4626 9556
+f 18539 834 9555
+f 9556 4626 19996
+f 582 3189 394
+f 994 3189 18538
+f 3189 835 18538
+f 19093 19049 5100
+f 18506 695 19099
+f 4626 1215 19996
+f 13196 12268 8684
+f 19284 18792 393
+f 3461 8221 20291
+f 20292 20293 20294
+f 9172 19660 1710
+f 11484 1770 1772
+f 6506 1639 3390
+f 18515 1412 1411
+f 19828 16958 14561
+f 640 7127 7225
+f 4693 15672 20295
+f 12550 13560 12551
+f 877 876 5722
+f 9461 3587 9390
+f 17338 17337 13666
+f 20296 17692 17687
+f 756 1518 435
+f 20297 18045 20298
+f 19855 19882 19946
+f 433 756 435
+f 606 758 18527
+f 19918 19919 19914
+f 9546 9318 18560
+f 1043 1172 8740
+f 3193 2285 5362
+f 16794 9546 18560
+f 19950 19918 19858
+f 19919 19915 19914
+f 1520 2102 436
+f 445 1879 1375
+f 15760 9301 20299
+f 16137 1394 16182
+f 1395 1394 16137
+f 13470 13469 20287
+f 16136 1395 16137
+f 1394 20254 16182
+f 11839 19774 11842
+f 20052 20300 12158
+f 16633 20262 16586
+f 16247 16633 16586
+f 20301 20302 20264
+f 20263 20230 20229
+f 20302 20303 20265
+f 20264 20302 20265
+f 20303 20304 20266
+f 20265 20303 20266
+f 20304 20305 20267
+f 20266 20304 20267
+f 20305 20306 20268
+f 20267 20305 20268
+f 20306 20307 20269
+f 20268 20306 20269
+f 20307 20308 20270
+f 20269 20307 20270
+f 20308 20309 20271
+f 20270 20308 20271
+f 20309 20310 20272
+f 20271 20309 20272
+f 20310 20311 20273
+f 20272 20310 20273
+f 20311 20312 20274
+f 20273 20311 20274
+f 20312 20313 20275
+f 20274 20312 20275
+f 20313 20314 20276
+f 20275 20313 20276
+f 20314 20315 20277
+f 20276 20314 20277
+f 20315 20316 20278
+f 20277 20315 20278
+f 20316 20317 20279
+f 20278 20316 20279
+f 20317 20318 20280
+f 20279 20317 20280
+f 20318 20319 20281
+f 20280 20318 20281
+f 20320 20282 20281
+f 20319 20320 20281
+f 20321 20283 20282
+f 20320 20321 20282
+f 20322 20284 20283
+f 20321 20322 20283
+f 20323 20285 20284
+f 20322 20323 20284
+f 20324 20286 20285
+f 20323 20324 20285
+f 20325 20287 20286
+f 20324 20325 20286
+f 12826 12827 12167
+f 20325 13470 20287
+f 14877 13470 14878
+f 648 13153 13152
+f 455 7125 3185
+f 18376 278 19376
+f 20210 20296 17687
+f 19398 477 476
+f 1505 7057 18462
+f 2631 1505 18463
+f 2978 18273 2979
+f 19312 3150 2980
+f 19154 4760 4762
+f 2701 11818 20326
+f 3230 6897 3231
+f 4599 9184 9183
+f 2229 19010 2230
+f 20327 17693 17692
+f 19174 19618 20328
+f 20329 8569 8598
+f 1952 1523 1369
+f 11235 3464 3463
+f 931 12168 12828
+f 1523 931 12828
+f 20330 1739 1741
+f 19124 9735 849
+f 2711 3109 3514
+f 15829 20331 18669
+f 4475 5941 4476
+f 18532 2711 3514
+f 11556 16821 6789
+f 1640 621 620
+f 12551 13560 13559
+f 11569 1095 3588
+f 11106 20332 9461
+f 4922 13645 13644
+f 20332 3588 3587
+f 9461 20332 3587
+f 631 630 6514
+f 20296 20327 17692
+f 15909 16958 14670
+f 11613 3512 11539
+f 1520 436 435
+f 1518 1520 435
+f 19989 19950 19858
+f 19857 19989 19858
+f 9184 1764 19812
+f 3399 4335 4158
+f 1355 9152 6142
+f 5662 4936 4935
+f 16554 17269 15831
+f 19441 19443 11091
+f 19845 19991 19820
+f 19988 19989 19857
+f 8215 1643 18320
+f 2102 445 1375
+f 13172 12847 9805
+f 412 1775 413
+f 4627 10936 4628
+f 4947 19688 4945
+f 1407 1395 16136
+f 13697 1407 16136
+f 10965 10993 20333
+f 11032 15849 20334
+f 20335 2292 2170
+f 20336 20337 20213
+f 20338 20339 20302
+f 20301 20263 17804
+f 20339 20340 20303
+f 20302 20339 20303
+f 20340 20341 20304
+f 20303 20340 20304
+f 20341 20342 20305
+f 20304 20341 20305
+f 20342 20343 20306
+f 20305 20342 20306
+f 20343 20344 20307
+f 20306 20343 20307
+f 20344 20345 20308
+f 20307 20344 20308
+f 20345 20346 20309
+f 20308 20345 20309
+f 20346 20347 20310
+f 20309 20346 20310
+f 20347 20348 20311
+f 20310 20347 20311
+f 20348 20349 20312
+f 20311 20348 20312
+f 20349 20350 20313
+f 20312 20349 20313
+f 20350 20351 20314
+f 20313 20350 20314
+f 20351 20352 20315
+f 20314 20351 20315
+f 20352 20353 20316
+f 20315 20352 20316
+f 20353 20354 20317
+f 20316 20353 20317
+f 20354 20355 20318
+f 20317 20354 20318
+f 20355 20356 20319
+f 20318 20355 20319
+f 20357 20320 20319
+f 20356 20357 20319
+f 20358 20321 20320
+f 20357 20358 20320
+f 20359 20322 20321
+f 20358 20359 20321
+f 20360 20323 20322
+f 20359 20360 20322
+f 20361 20324 20323
+f 20360 20361 20323
+f 20362 20325 20324
+f 20361 20362 20324
+f 20363 13470 20325
+f 20362 20363 20325
+f 16173 8666 16171
+f 20363 18627 13470
+f 1219 1221 1025
+f 20149 9259 9258
+f 1929 18118 19039
+f 19769 19447 19449
+f 19081 7059 7058
+f 20364 17244 17193
+f 2973 19376 2978
+f 13334 19375 2980
+f 13296 14879 279
+f 16173 2437 1009
+f 20365 17700 17693
+f 769 2436 770
+f 20366 6521 17623
+f 3246 2517 2516
+f 17215 19991 19845
+f 19844 17215 19845
+f 944 20367 9421
+f 19991 19988 19820
+f 20368 14209 20369
+f 20370 20371 20372
+f 18916 19147 19547
+f 20327 20365 17693
+f 20373 17701 17700
+f 15279 7932 1988
+f 2301 2275 15802
+f 16722 14707 7336
+f 20374 16233 5818
+f 18322 18275 19377
+f 7936 20375 11106
+f 6431 7936 11106
+f 20375 20376 20332
+f 11106 20375 20332
+f 20376 20377 3588
+f 20332 20376 3588
+f 13211 13210 18581
+f 3588 20377 11569
+f 7019 7056 7055
+f 20378 16207 15709
+f 440 1835 1879
+f 445 440 1879
+f 19918 19914 19858
+f 1952 1369 1835
+f 8306 20379 20380
+f 14124 1005 13946
+f 15829 15813 15951
+f 1013 1015 1371
+f 351 291 16553
+f 20331 20381 18669
+f 19820 19988 19857
+f 20365 20373 17700
+f 1354 9152 1355
+f 1264 7568 1403
+f 4639 11568 18246
+f 7552 15828 6644
+f 20382 14170 20383
+f 15869 17362 15831
+f 16445 20384 16562
+f 4782 15862 4783
+f 1406 1407 13697
+f 16562 1406 13697
+f 9787 6041 12269
+f 2826 16380 14408
+f 17837 20385 20339
+f 20338 17837 20339
+f 20385 20386 20340
+f 20339 20385 20340
+f 20386 20387 20341
+f 20340 20386 20341
+f 20387 20388 20342
+f 20341 20387 20342
+f 20388 20389 20343
+f 20342 20388 20343
+f 20389 20390 20344
+f 20343 20389 20344
+f 20390 20391 20345
+f 20344 20390 20345
+f 20391 20392 20346
+f 20345 20391 20346
+f 20392 20393 20347
+f 20346 20392 20347
+f 20393 20394 20348
+f 20347 20393 20348
+f 20394 20395 20349
+f 20348 20394 20349
+f 20395 20396 20350
+f 20349 20395 20350
+f 20396 20397 20351
+f 20350 20396 20351
+f 20397 20398 20352
+f 20351 20397 20352
+f 20398 20399 20353
+f 20352 20398 20353
+f 20399 20400 20354
+f 20353 20399 20354
+f 20400 20401 20355
+f 20354 20400 20355
+f 20402 20356 20355
+f 20401 20402 20355
+f 20403 20357 20356
+f 20402 20403 20356
+f 20404 20358 20357
+f 20403 20404 20357
+f 20405 20359 20358
+f 20404 20405 20358
+f 20406 20360 20359
+f 20405 20406 20359
+f 20407 20361 20360
+f 20406 20407 20360
+f 20408 20362 20361
+f 20407 20408 20361
+f 20408 20409 20363
+f 20362 20408 20363
+f 20409 19806 18627
+f 20363 20409 18627
+f 12217 14878 11795
+f 4122 4121 6036
+f 6500 20080 6501
+f 13955 8694 17472
+f 19123 19450 7059
+f 19081 19123 7059
+f 1398 18376 2973
+f 18273 13334 2979
+f 6469 13755 6785
+f 15767 20410 15768
+f 19766 19942 17377
+f 14434 19766 17377
+f 756 907 1518
+f 15668 20411 20412
+f 475 10891 6725
+f 1006 1005 14124
+f 10378 18917 17942
+f 20381 20413 20082
+f 18569 348 5950
+f 18669 20381 20082
+f 19589 9737 1815
+f 3395 18569 5950
+f 13301 15829 18669
+f 18918 2806 1670
+f 19795 2030 1328
+f 18628 9221 18566
+f 474 10891 475
+f 18889 6317 6319
+f 7935 20414 20375
+f 7936 7935 20375
+f 20414 20415 20376
+f 20375 20414 20376
+f 20415 20416 20377
+f 20376 20415 20377
+f 9793 9792 20417
+f 4735 10092 7340
+f 4566 11569 19038
+f 6317 18889 7935
+f 1121 1070 1203
+f 13335 18272 18217
+f 440 1952 1835
+f 16673 1778 16027
+f 912 9332 913
+f 14106 1140 1139
+f 20413 20418 20085
+f 20082 20413 20085
+f 20418 20419 20086
+f 20085 20418 20086
+f 17929 18069 13948
+f 18488 18493 1161
+f 2548 2547 2549
+f 1345 446 8869
+f 16026 16673 16027
+f 4637 12557 6822
+f 17269 15832 15831
+f 17362 16554 15831
+f 11842 20052 12158
+f 16244 20420 14236
+f 3392 20384 16445
+f 16383 3392 16445
+f 11542 20421 20422
+f 9099 222 221
+f 20423 20424 20385
+f 17837 20423 20385
+f 20424 20425 20386
+f 20385 20424 20386
+f 20425 20426 20387
+f 20386 20425 20387
+f 20426 20427 20388
+f 20387 20426 20388
+f 20427 20428 20389
+f 20388 20427 20389
+f 20428 20429 20390
+f 20389 20428 20390
+f 20429 20430 20391
+f 20390 20429 20391
+f 20430 20431 20392
+f 20391 20430 20392
+f 20431 20432 20393
+f 20392 20431 20393
+f 20432 20433 20394
+f 20393 20432 20394
+f 20433 20434 20395
+f 20394 20433 20395
+f 20434 20435 20396
+f 20395 20434 20396
+f 20435 20436 20397
+f 20396 20435 20397
+f 20436 20437 20398
+f 20397 20436 20398
+f 20437 20438 20399
+f 20398 20437 20399
+f 20438 20439 20400
+f 20399 20438 20400
+f 20439 20440 20401
+f 20400 20439 20401
+f 20441 20402 20401
+f 20440 20441 20401
+f 20442 20403 20402
+f 20441 20442 20402
+f 20443 20404 20403
+f 20442 20443 20403
+f 20444 20405 20404
+f 20443 20444 20404
+f 20444 20445 20406
+f 20405 20444 20406
+f 20445 20446 20407
+f 20406 20445 20407
+f 20446 20447 20408
+f 20407 20446 20408
+f 20447 20448 20409
+f 20408 20447 20409
+f 20448 20449 19806
+f 20409 20448 19806
+f 20449 20367 20078
+f 19806 20449 20078
+f 1659 19038 20450
+f 10498 6688 13755
+f 19175 1873 19450
+f 19123 19175 19450
+f 19219 19218 1398
+f 19376 18273 2978
+f 9832 8127 20451
+f 6469 6785 6470
+f 18332 19909 20452
+f 20453 20454 20455
+f 1418 10520 1416
+f 2030 2029 9172
+f 3082 5868 11040
+f 653 2184 654
+f 20419 20456 20087
+f 20086 20419 20087
+f 20457 20114 20087
+f 18888 4712 14145
+f 20456 20457 20087
+f 1256 19777 2794
+f 19548 19023 1255
+f 8653 513 8654
+f 9222 350 18484
+f 18889 20458 7935
+f 20459 7475 20460
+f 14325 14491 10698
+f 7935 20458 20414
+f 1537 3651 1538
+f 2144 12100 2145
+f 20461 20462 20416
+f 20415 20461 20416
+f 20462 20463 20450
+f 20416 20462 20450
+f 20463 1660 1659
+f 20450 20463 1659
+f 289 14313 290
+f 20464 2347 20465
+f 6333 1962 18890
+f 10303 10305 15200
+f 19739 20083 19755
+f 18600 18470 19441
+f 20466 20115 20114
+f 20457 20466 20114
+f 20467 20116 20115
+f 20466 20467 20115
+f 9418 889 1020
+f 19731 20084 19739
+f 1650 1649 19147
+f 2903 2711 2549
+f 16673 1776 1778
+f 7836 1355 6625
+f 16927 15808 15869
+f 1803 15803 16927
+f 3015 3017 5380
+f 1605 18902 20468
+f 20384 1406 16562
+f 15385 9207 16383
+f 20469 20470 20471
+f 2825 3413 3020
+f 20472 20473 20424
+f 20423 20472 20424
+f 20473 20474 20425
+f 20424 20473 20425
+f 20474 20475 20426
+f 20425 20474 20426
+f 20475 20476 20427
+f 20426 20475 20427
+f 20476 20477 20428
+f 20427 20476 20428
+f 20477 20478 20429
+f 20428 20477 20429
+f 20478 20479 20430
+f 20429 20478 20430
+f 20479 20480 20431
+f 20430 20479 20431
+f 20480 20481 20432
+f 20431 20480 20432
+f 20481 20482 20433
+f 20432 20481 20433
+f 20482 20483 20434
+f 20433 20482 20434
+f 20483 20484 20435
+f 20434 20483 20435
+f 20484 20485 20436
+f 20435 20484 20436
+f 20485 20486 20437
+f 20436 20485 20437
+f 20486 20487 20438
+f 20437 20486 20438
+f 20487 20488 20439
+f 20438 20487 20439
+f 20488 20489 20440
+f 20439 20488 20440
+f 20490 20441 20440
+f 20489 20490 20440
+f 20491 20442 20441
+f 20490 20491 20441
+f 20491 20492 20443
+f 20442 20491 20443
+f 20492 20493 20444
+f 20443 20492 20444
+f 20493 20494 20445
+f 20444 20493 20445
+f 20494 20495 20446
+f 20445 20494 20446
+f 20495 20496 20447
+f 20446 20495 20447
+f 20496 20497 20448
+f 20447 20496 20448
+f 20497 20498 20449
+f 20448 20497 20449
+f 9421 20367 20449
+f 20498 9421 20449
+f 9972 9971 9906
+f 10149 10148 10374
+f 19359 19769 1873
+f 16682 8706 20499
+f 19218 18376 1398
+f 18819 18818 19219
+f 12096 963 18892
+f 19444 908 9492
+f 19782 20500 15119
+f 4714 14145 4712
+f 20501 20364 17193
+f 6076 700 699
+f 20089 20084 19731
+f 19700 20089 19731
+f 20502 20117 20116
+f 20467 20502 20116
+f 20503 20118 20117
+f 20502 20503 20117
+f 19699 20088 19700
+f 20088 20089 19700
+f 3976 4190 4192
+f 1141 14772 20252
+f 16963 15996 9654
+f 18889 18888 20458
+f 11818 2701 10076
+f 3933 1658 1660
+f 20504 20505 20461
+f 3857 13561 4970
+f 20505 20506 20462
+f 20461 20505 20462
+f 20506 20507 20463
+f 20462 20506 20463
+f 20507 5935 1660
+f 20463 20507 1660
+f 604 19439 605
+f 12802 5579 5711
+f 8212 2777 2432
+f 2029 19660 9172
+f 20027 20088 19699
+f 1693 3724 10090
+f 20508 20119 20118
+f 20503 20508 20118
+f 20508 20509 20147
+f 20119 20508 20147
+f 20083 2384 19755
+f 1297 18768 1298
+f 17650 17649 17260
+f 18543 18521 18532
+f 13764 5942 13658
+f 15803 15808 16927
+f 1275 928 2354
+f 7136 6429 10636
+f 16153 16152 1732
+f 5752 18945 16561
+f 10560 9206 15385
+f 9207 3392 16383
+f 16264 20026 16265
+f 16330 9337 9488
+f 12649 12648 20472
+f 20472 20423 17839
+f 20510 20511 20474
+f 20473 20510 20474
+f 20511 20512 20475
+f 20474 20511 20475
+f 20512 20513 20476
+f 20475 20512 20476
+f 20513 20514 20477
+f 20476 20513 20477
+f 20514 20515 20478
+f 20477 20514 20478
+f 20515 20516 20479
+f 20478 20515 20479
+f 20516 20517 20480
+f 20479 20516 20480
+f 20517 20518 20481
+f 20480 20517 20481
+f 20518 20519 20482
+f 20481 20518 20482
+f 20519 20520 20483
+f 20482 20519 20483
+f 20520 20521 20484
+f 20483 20520 20484
+f 20521 20522 20485
+f 20484 20521 20485
+f 20522 20523 20486
+f 20485 20522 20486
+f 20523 20524 20487
+f 20486 20523 20487
+f 20524 20525 20488
+f 20487 20524 20488
+f 20525 20526 20489
+f 20488 20525 20489
+f 20526 20527 20490
+f 20489 20526 20490
+f 20527 20528 20491
+f 20490 20527 20491
+f 20528 20529 20492
+f 20491 20528 20492
+f 20529 20530 20493
+f 20492 20529 20493
+f 20530 20531 20494
+f 20493 20530 20494
+f 20531 20532 20495
+f 20494 20531 20495
+f 20532 20533 20496
+f 20495 20532 20496
+f 20533 20534 20497
+f 20496 20533 20497
+f 20535 20498 20497
+f 20534 20535 20497
+f 1993 9421 20498
+f 20535 1993 20498
+f 15850 8859 19688
+f 18532 18521 18520
+f 19175 19359 1873
+f 4476 5942 14035
+f 18376 19376 2973
+f 19359 18607 19447
+f 19147 19023 19548
+f 13580 1327 5520
+f 20536 17213 20537
+f 9400 19621 19840
+f 6077 6076 699
+f 20538 12273 12158
+f 20084 20083 19739
+f 1137 1160 7752
+f 20509 20539 20148
+f 18768 18405 1298
+f 20147 20509 20148
+f 20539 1805 9259
+f 20148 20539 20149
+f 15537 3004 19764
+f 16051 20540 20541
+f 18915 14142 17974
+f 8446 7734 20542
+f 4015 3934 5935
+f 7734 20543 20504
+f 20542 7734 20504
+f 20543 20544 20505
+f 20504 20543 20505
+f 20544 20545 20506
+f 20505 20544 20506
+f 20545 5934 20507
+f 20506 20545 20507
+f 3815 3814 9135
+f 20507 5934 5935
+f 18797 1416 1169
+f 20546 17722 17701
+f 1571 1572 9794
+f 491 490 19121
+f 18764 18768 1297
+f 19726 20027 19699
+f 16958 19827 17929
+f 1289 8874 9199
+f 2150 18855 2484
+f 6742 6502 1580
+f 742 18743 743
+f 2086 10580 10579
+f 18743 742 1675
+f 18745 18746 1459
+f 18741 18743 1675
+f 18743 18745 743
+f 944 9421 942
+f 634 633 20023
+f 16299 17076 20547
+f 16561 16404 15695
+f 20548 16299 20547
+f 17310 14836 20547
+f 16507 2358 13323
+f 15940 16507 13323
+f 20549 16666 20550
+f 16190 15833 16754
+f 20551 20552 20511
+f 20510 20551 20511
+f 20552 20553 20512
+f 20511 20552 20512
+f 20553 20554 20513
+f 20512 20553 20513
+f 20554 20555 20514
+f 20513 20554 20514
+f 20555 20556 20515
+f 20514 20555 20515
+f 20556 20557 20516
+f 20515 20556 20516
+f 20557 20558 20517
+f 20516 20557 20517
+f 20558 20559 20518
+f 20517 20558 20518
+f 20559 20560 20519
+f 20518 20559 20519
+f 20560 20561 20520
+f 20519 20560 20520
+f 20561 20562 20521
+f 20520 20561 20521
+f 20562 20563 20522
+f 20521 20562 20522
+f 20563 20564 20523
+f 20522 20563 20523
+f 20564 20565 20524
+f 20523 20564 20524
+f 20565 20566 20525
+f 20524 20565 20525
+f 20567 20526 20525
+f 20566 20567 20525
+f 20567 20568 20527
+f 20526 20567 20527
+f 20568 20569 20528
+f 20527 20568 20528
+f 20569 20570 20529
+f 20528 20569 20529
+f 20570 20571 20530
+f 20529 20570 20530
+f 20571 20572 20531
+f 20530 20571 20531
+f 20573 20532 20531
+f 20572 20573 20531
+f 20574 20533 20532
+f 20573 20574 20532
+f 20575 20534 20533
+f 20574 20575 20533
+f 20576 20535 20534
+f 20575 20576 20534
+f 20577 1993 20535
+f 20576 20577 20535
+f 14123 14124 13946
+f 20577 1994 1993
+f 13172 6894 11100
+f 20578 20579 550
+f 19769 19359 19447
+f 18607 18609 19494
+f 1832 409 9483
+f 9521 1447 1719
+f 5103 1391 1393
+f 2117 541 4786
+f 16596 16564 15905
+f 20580 16745 13324
+f 20581 19599 18986
+f 382 381 523
+f 18717 18719 1517
+f 18741 1675 1374
+f 1245 2151 1812
+f 19666 9477 9478
+f 555 18158 15428
+f 12270 4624 9058
+f 8446 7732 7734
+f 19665 7733 7732
+f 7733 20582 20543
+f 7734 7733 20543
+f 20582 20583 20544
+f 20543 20582 20544
+f 20583 20584 20545
+f 20544 20583 20545
+f 20584 10565 5934
+f 20545 20584 5934
+f 18797 1168 1361
+f 1168 18797 1169
+f 4863 7037 6043
+f 9910 19653 15304
+f 20373 20546 17701
+f 19749 18748 18747
+f 743 18745 1459
+f 1438 18764 1297
+f 18524 606 18527
+f 758 1634 18528
+f 14877 6229 13470
+f 18527 758 18528
+f 1847 9337 9338
+f 551 18603 5944
+f 3399 3193 4335
+f 9346 1409 1408
+f 18717 1517 1516
+f 18714 18717 1516
+f 8299 8298 8389
+f 18070 19867 18069
+f 2135 2134 16251
+f 2134 2790 16596
+f 17076 17310 20547
+f 16678 20585 15835
+f 14276 19202 2359
+f 15458 14978 18067
+f 11234 8018 8017
+f 15835 19741 16754
+f 20586 20587 20552
+f 15118 20510 12648
+f 20587 20588 20553
+f 20552 20587 20553
+f 20588 20589 20554
+f 20553 20588 20554
+f 20589 20590 20555
+f 20554 20589 20555
+f 20590 20591 20556
+f 20555 20590 20556
+f 20591 20592 20557
+f 20556 20591 20557
+f 20592 20593 20558
+f 20557 20592 20558
+f 20593 20594 20559
+f 20558 20593 20559
+f 20594 20595 20560
+f 20559 20594 20560
+f 20595 20596 20561
+f 20560 20595 20561
+f 20597 20562 20561
+f 20596 20597 20561
+f 20598 20563 20562
+f 20597 20598 20562
+f 20598 20599 20564
+f 20563 20598 20564
+f 20599 20600 20565
+f 20564 20599 20565
+f 20600 20601 20566
+f 20565 20600 20566
+f 20601 20602 20567
+f 20566 20601 20567
+f 20602 20603 20568
+f 20567 20602 20568
+f 20603 20604 20569
+f 20568 20603 20569
+f 20604 20605 20570
+f 20569 20604 20570
+f 20606 20571 20570
+f 20605 20606 20570
+f 20607 20572 20571
+f 20606 20607 20571
+f 20608 20573 20572
+f 20607 20608 20572
+f 20609 20574 20573
+f 20608 20609 20573
+f 20610 20575 20574
+f 20609 20610 20574
+f 20611 20576 20575
+f 20610 20611 20575
+f 20612 20577 20576
+f 20611 20612 20576
+f 9177 1994 20577
+f 20612 9177 20577
+f 20613 9652 638
+f 12918 1370 12828
+f 19447 18607 19494
+f 1004 4476 1005
+f 4849 4851 2623
+f 18609 19314 19496
+f 9200 937 5102
+f 6508 9477 19666
+f 2358 2360 16029
+f 5101 9200 5102
+f 633 545 8683
+f 719 718 15390
+f 18719 18741 1374
+f 20023 633 8683
+f 1766 19947 19986
+f 18692 18714 1310
+f 823 3399 4158
+f 9002 10422 10497
+f 1764 1766 19986
+f 5088 19665 7732
+f 19665 20614 20582
+f 7733 19665 20582
+f 20614 20615 20583
+f 20582 20614 20583
+f 20615 20616 20584
+f 20583 20615 20584
+f 20616 20617 10565
+f 20584 20616 10565
+f 20617 10424 9004
+f 10565 20617 9004
+f 10424 9002 9004
+f 14106 13926 14518
+f 12961 14845 15383
+f 2253 7533 7629
+f 18746 18764 1438
+f 1459 18746 1438
+f 18690 18692 752
+f 18719 1374 1517
+f 1532 9350 1533
+f 9846 775 774
+f 9251 9253 14685
+f 10076 2703 9500
+f 14938 20378 14937
+f 18665 18690 614
+f 1010 14144 2087
+f 480 19579 511
+f 19022 19777 1256
+f 10356 7946 5644
+f 13423 5884 5747
+f 16966 2134 16596
+f 1394 328 20254
+f 15834 16678 15835
+f 16678 16299 20548
+f 19682 546 19711
+f 15941 15940 13322
+f 15836 15835 16754
+f 20585 19742 19741
+f 19910 20618 20587
+f 20586 20552 20551
+f 20618 20619 20588
+f 20587 20618 20588
+f 20619 20620 20589
+f 20588 20619 20589
+f 20620 20621 20590
+f 20589 20620 20590
+f 20621 20622 20591
+f 20590 20621 20591
+f 20622 20623 20592
+f 20591 20622 20592
+f 20624 20593 20592
+f 20623 20624 20592
+f 20625 20594 20593
+f 20624 20625 20593
+f 20625 20626 20595
+f 20594 20625 20595
+f 20626 20627 20596
+f 20595 20626 20596
+f 20627 20628 20597
+f 20596 20627 20597
+f 20628 20629 20598
+f 20597 20628 20598
+f 20629 20630 20599
+f 20598 20629 20599
+f 20631 20600 20599
+f 20630 20631 20599
+f 20632 20601 20600
+f 20631 20632 20600
+f 20632 20633 20602
+f 20601 20632 20602
+f 20633 20634 20603
+f 20602 20633 20603
+f 20634 20635 20604
+f 20603 20634 20604
+f 20635 20636 20605
+f 20604 20635 20605
+f 20637 20606 20605
+f 20636 20637 20605
+f 20638 20607 20606
+f 20637 20638 20606
+f 20639 20608 20607
+f 20638 20639 20607
+f 20640 20609 20608
+f 20639 20640 20608
+f 20641 20610 20609
+f 20640 20641 20609
+f 20642 20611 20610
+f 20641 20642 20610
+f 20643 20612 20611
+f 20642 20643 20611
+f 20643 18400 9177
+f 20612 20643 9177
+f 2158 860 850
+f 13658 412 414
+f 4476 14035 1005
+f 5657 811 7918
+f 19494 18609 19496
+f 19314 18921 19497
+f 19354 19547 5242
+f 13868 19093 5100
+f 19840 19621 4949
+f 937 1391 5103
+f 728 12589 9546
+f 2086 4340 1010
+f 10423 10424 20644
+f 547 3181 13196
+f 18661 18665 2106
+f 18690 752 614
+f 1023 1031 20331
+f 20378 15709 14937
+f 1031 1954 20381
+f 20331 1031 20381
+f 19766 17407 11916
+f 19766 11916 11917
+f 19740 19154 20615
+f 20614 19740 20615
+f 19154 4762 20616
+f 20615 19154 20616
+f 4762 20645 20617
+f 20616 4762 20617
+f 20645 20644 10424
+f 20617 20645 10424
+f 10205 10423 20644
+f 14218 10588 14124
+f 12892 20646 1512
+f 12918 13002 12919
+f 19487 20647 20648
+f 8208 8754 4462
+f 18659 18661 612
+f 18714 1516 1310
+f 1954 9415 20413
+f 20381 1954 20413
+f 9415 8887 20418
+f 20413 9415 20418
+f 18661 2106 612
+f 8887 8889 20419
+f 13323 2358 16029
+f 18692 1310 752
+f 19038 1659 4543
+f 2411 15358 15778
+f 20649 20650 20651
+f 19980 14782 14784
+f 2614 2291 16250
+f 13686 13685 18570
+f 20585 16678 20548
+f 20254 2614 16250
+f 2635 15941 13322
+f 17150 14837 14836
+f 15835 20585 19741
+f 16745 2635 13322
+f 19910 20652 19911
+f 20548 19862 19742
+f 20653 20619 20618
+f 3282 3281 4174
+f 20653 20654 20620
+f 20619 20653 20620
+f 20654 20655 20621
+f 20620 20654 20621
+f 20655 20656 20622
+f 20621 20655 20622
+f 20656 20657 20623
+f 20622 20656 20623
+f 20657 20658 20624
+f 20623 20657 20624
+f 20658 20659 20625
+f 20624 20658 20625
+f 20660 20626 20625
+f 20659 20660 20625
+f 20661 20627 20626
+f 20660 20661 20626
+f 20661 20662 20628
+f 20627 20661 20628
+f 20662 20663 20629
+f 20628 20662 20629
+f 20664 20630 20629
+f 20663 20664 20629
+f 20665 20631 20630
+f 20664 20665 20630
+f 20665 20666 20632
+f 20631 20665 20632
+f 20666 20667 20633
+f 20632 20666 20633
+f 20667 20668 20634
+f 20633 20667 20634
+f 20669 20635 20634
+f 20668 20669 20634
+f 20670 20636 20635
+f 20669 20670 20635
+f 20671 20637 20636
+f 20670 20671 20636
+f 20672 20638 20637
+f 20671 20672 20637
+f 20673 20639 20638
+f 20672 20673 20638
+f 20674 20640 20639
+f 20673 20674 20639
+f 20675 20641 20640
+f 20674 20675 20640
+f 20676 20642 20641
+f 20675 20676 20641
+f 20676 20677 20643
+f 20642 20676 20643
+f 20677 20678 18400
+f 20643 20677 18400
+f 9174 10633 14576
+f 20678 9175 18400
+f 13570 5871 4686
+f 3857 4970 6338
+f 19496 19314 19497
+f 14211 16794 14212
+f 19518 18668 18478
+f 9012 9664 19469
+f 367 358 447
+f 1028 770 1781
+f 1215 1214 6077
+f 12589 9547 9546
+f 18892 8272 12426
+f 1008 1380 17200
+f 18659 612 611
+f 18636 18659 611
+f 20418 8887 20419
+f 8888 20456 20419
+f 8889 8888 20419
+f 9009 20457 20456
+f 1716 4123 4124
+f 10204 10120 10202
+f 2534 13525 7748
+f 19740 9634 19154
+f 8311 385 2147
+f 7354 972 368
+f 4761 20679 20645
+f 4762 4761 20645
+f 20679 20680 20644
+f 20645 20679 20644
+f 20680 10203 10205
+f 20644 20680 10205
+f 10885 10884 10986
+f 1653 1687 10090
+f 1163 11776 1161
+f 12072 14174 14525
+f 18636 611 1007
+f 18665 614 2106
+f 8888 9009 20456
+f 8512 20466 20457
+f 9009 8512 20457
+f 18634 1007 1009
+f 9100 20467 20466
+f 13666 17337 3350
+f 2438 18634 1009
+f 2231 2233 18776
+f 20300 20538 12158
+f 10183 2231 18776
+f 20681 12372 12273
+f 17149 9325 9324
+f 20682 20683 20684
+f 2135 16251 16250
+f 329 328 1395
+f 17310 17150 14836
+f 17003 8732 14837
+f 15940 13323 13322
+f 2635 16745 3234
+f 20585 20548 19742
+f 20548 20547 18466
+f 19879 16423 13589
+f 3770 5729 1364
+f 16805 17490 20685
+f 2764 3534 3144
+f 20686 20655 20654
+f 20687 20686 20654
+f 20688 20656 20655
+f 20686 20688 20655
+f 20688 20689 20657
+f 20656 20688 20657
+f 20690 20658 20657
+f 20689 20690 20657
+f 20691 20659 20658
+f 20690 20691 20658
+f 20691 20692 20660
+f 20659 20691 20660
+f 20693 20661 20660
+f 20692 20693 20660
+f 20694 20662 20661
+f 20693 20694 20661
+f 20694 20695 20663
+f 20662 20694 20663
+f 20695 20696 20664
+f 20663 20695 20664
+f 20696 20697 20665
+f 20664 20696 20665
+f 20698 20666 20665
+f 20697 20698 20665
+f 20698 20699 20667
+f 20666 20698 20667
+f 20700 20668 20667
+f 20699 20700 20667
+f 20701 20669 20668
+f 20700 20701 20668
+f 20702 20670 20669
+f 20701 20702 20669
+f 20702 20703 20671
+f 20670 20702 20671
+f 20703 20704 20672
+f 20671 20703 20672
+f 20704 20705 20673
+f 20672 20704 20673
+f 20705 20706 20674
+f 20673 20705 20674
+f 20706 20707 20675
+f 20674 20706 20675
+f 20707 20708 20676
+f 20675 20707 20676
+f 20708 20709 20677
+f 20676 20708 20677
+f 20710 20678 20677
+f 20709 20710 20677
+f 1987 9175 20678
+f 20710 1987 20678
+f 3245 7744 3246
+f 19943 10280 20711
+f 18921 19061 19749
+f 9531 5611 6301
+f 19531 9330 9332
+f 19709 19748 19588
+f 18749 19982 5792
+f 9589 5949 4484
+f 2777 7216 2775
+f 17377 19942 18975
+f 704 703 899
+f 9390 3587 5722
+f 15393 20712 20713
+f 2437 18631 2438
+f 8512 9100 20466
+f 9001 20502 20467
+f 9100 9001 20467
+f 8743 20503 20502
+f 716 655 714
+f 7354 368 370
+f 1796 1795 3685
+f 4760 1356 4761
+f 18273 13335 13334
+f 19942 18712 18975
+f 1356 20714 20679
+f 4761 1356 20679
+f 20714 20715 20680
+f 20679 20714 20680
+f 20715 10048 10203
+f 20680 20715 10203
+f 1484 17922 14227
+f 20716 490 14521
+f 3181 2775 8299
+f 19636 3597 18626
+f 1093 11569 4566
+f 18634 18636 1007
+f 9001 8743 20502
+f 8743 8744 20508
+f 20503 8743 20508
+f 8744 8733 20509
+f 3151 2773 8137
+f 20717 20718 20719
+f 2232 4629 2233
+f 6617 16653 14013
+f 20538 20681 12273
+f 1848 1847 16386
+f 20720 20721 20722
+f 19438 19729 15506
+f 328 2614 20254
+f 9207 2442 3392
+f 17150 17003 14837
+f 17003 17146 2630
+f 3238 2635 3234
+f 1515 17040 9481
+f 19862 20548 18466
+f 14836 14838 18466
+f 16183 16703 16184
+f 13698 16136 16138
+f 17490 2764 3144
+f 16423 19879 16418
+f 20723 20724 20686
+f 20687 20723 20686
+f 20725 20688 20686
+f 20724 20725 20686
+f 20726 20689 20688
+f 20725 20726 20688
+f 20727 20690 20689
+f 20726 20727 20689
+f 20728 20691 20690
+f 20727 20728 20690
+f 20729 20692 20691
+f 20728 20729 20691
+f 20730 20693 20692
+f 20729 20730 20692
+f 20731 20694 20693
+f 20730 20731 20693
+f 20732 20695 20694
+f 20731 20732 20694
+f 20733 20696 20695
+f 20732 20733 20695
+f 20734 20697 20696
+f 20733 20734 20696
+f 20735 20698 20697
+f 20734 20735 20697
+f 20735 20736 20699
+f 20698 20735 20699
+f 20737 20700 20699
+f 20736 20737 20699
+f 20737 20738 20701
+f 20700 20737 20701
+f 20739 20702 20701
+f 20738 20739 20701
+f 20740 20703 20702
+f 20739 20740 20702
+f 20740 20741 20704
+f 20703 20740 20704
+f 20741 20742 20705
+f 20704 20741 20705
+f 20742 20743 20706
+f 20705 20742 20706
+f 20743 20744 20707
+f 20706 20743 20707
+f 20744 20745 20708
+f 20707 20744 20708
+f 20745 20746 20709
+f 20708 20745 20709
+f 20746 20747 20710
+f 20709 20746 20710
+f 20747 1988 1987
+f 20710 20747 1987
+f 7195 4754 4756
+f 12553 17928 17987
+f 19497 18921 19749
+f 19061 18857 18748
+f 18054 12800 1712
+f 15807 351 16553
+f 18604 9555 9557
+f 19996 20028 19657
+f 19199 1813 19444
+f 20748 17729 17722
+f 15449 6644 6646
+f 18586 706 705
+f 16684 2272 8861
+f 19377 278 18322
+f 20508 8744 20509
+f 8939 18587 18558
+f 8733 1805 20539
+f 20509 8733 20539
+f 3639 6302 4281
+f 20539 9259 20149
+f 12353 4920 7259
+f 1412 18770 1413
+f 14214 13661 17592
+f 17145 16026 16028
+f 4621 4768 18625
+f 1358 19944 20714
+f 1356 1358 20714
+f 19944 20749 20715
+f 20714 19944 20715
+f 20749 8503 10048
+f 20715 20749 10048
+f 7946 18592 7930
+f 13570 4686 3095
+f 644 19990 3394
+f 3919 3918 6593
+f 20253 17979 18603
+f 5548 5549 20750
+f 20751 9907 8504
+f 1817 1816 18638
+f 6501 936 935
+f 1634 20752 18552
+f 3752 19997 13664
+f 19990 18524 3394
+f 13511 9109 17315
+f 2299 17393 2300
+f 9338 20753 16488
+f 1340 1342 9000
+f 1408 1410 13686
+f 2182 2344 4499
+f 1348 1350 20384
+f 13511 9108 9109
+f 8732 17003 2630
+f 3392 1348 20384
+f 9209 1515 9481
+f 15896 8213 9219
+f 20547 14836 18466
+f 1499 14962 17040
+f 16137 16182 16184
+f 8732 2630 2629
+f 20754 20755 20756
+f 16138 16137 16184
+f 20757 20724 20723
+f 20758 20757 20723
+f 20757 20759 20725
+f 20724 20757 20725
+f 20760 20726 20725
+f 20759 20760 20725
+f 20761 20727 20726
+f 20760 20761 20726
+f 20761 20762 20728
+f 20727 20761 20728
+f 20762 20763 20729
+f 20728 20762 20729
+f 20764 20730 20729
+f 20763 20764 20729
+f 20765 20731 20730
+f 20764 20765 20730
+f 20766 20732 20731
+f 20765 20766 20731
+f 20767 20733 20732
+f 20766 20767 20732
+f 20768 20734 20733
+f 20767 20768 20733
+f 20769 20735 20734
+f 20768 20769 20734
+f 20770 20736 20735
+f 20769 20770 20735
+f 20770 20771 20737
+f 20736 20770 20737
+f 20771 20772 20738
+f 20737 20771 20738
+f 20772 20773 20739
+f 20738 20772 20739
+f 20773 20774 20740
+f 20739 20773 20740
+f 20774 20775 20741
+f 20740 20774 20741
+f 20775 20776 20742
+f 20741 20775 20742
+f 20776 20777 20743
+f 20742 20776 20743
+f 20777 20778 20744
+f 20743 20777 20744
+f 20778 20779 20745
+f 20744 20778 20745
+f 20779 20780 20746
+f 20745 20779 20746
+f 20780 20781 20747
+f 20746 20780 20747
+f 20781 15279 1988
+f 20747 20781 1988
+f 14220 14222 9327
+f 9256 2952 4650
+f 19749 19061 18748
+f 18857 18819 19982
+f 18819 19219 5793
+f 18748 18857 19982
+f 18630 18816 19160
+f 19982 18819 5793
+f 9557 9556 19664
+f 1989 13631 9174
+f 18748 19982 18749
+f 9556 19996 19664
+f 290 16572 4770
+f 18972 4479 318
+f 20782 20783 20784
+f 6743 16448 6438
+f 9305 1930 19039
+f 18524 18527 18525
+f 477 5949 9590
+f 18528 1634 18552
+f 19529 19528 7725
+f 20785 20786 3228
+f 20787 20788 20789
+f 18822 9478 6505
+f 14811 1278 11729
+f 20078 9148 14933
+f 4327 8199 15828
+f 19152 5918 5920
+f 19943 20790 20749
+f 19944 19943 20749
+f 20790 20751 8503
+f 20749 20790 8503
+f 20751 9772 9907
+f 8503 20751 8504
+f 990 989 644
+f 377 2113 2803
+f 18552 20752 3223
+f 16574 9670 8992
+f 19101 19399 19102
+f 20752 2745 2744
+f 20791 12453 12372
+f 784 377 2803
+f 9228 17393 2299
+f 13929 15249 14517
+f 9344 18109 18108
+f 224 9228 2299
+f 9517 9345 18571
+f 1955 1340 8999
+f 20681 20791 12372
+f 2139 9345 9517
+f 1350 658 1406
+f 8955 10183 8956
+f 15896 9219 1504
+f 20384 1350 1406
+f 1515 1499 17040
+f 9496 15896 1504
+f 8732 8731 18529
+f 1498 7476 14962
+f 20792 20793 20794
+f 14837 8732 18529
+f 20795 20757 20758
+f 13978 20795 20758
+f 20796 20759 20757
+f 20795 20796 20757
+f 20797 20760 20759
+f 20796 20797 20759
+f 20798 20761 20760
+f 20797 20798 20760
+f 20799 20762 20761
+f 20798 20799 20761
+f 20800 20763 20762
+f 20799 20800 20762
+f 20801 20764 20763
+f 20800 20801 20763
+f 20801 20802 20765
+f 20764 20801 20765
+f 20803 20766 20765
+f 20802 20803 20765
+f 20804 20767 20766
+f 20803 20804 20766
+f 20805 20768 20767
+f 20804 20805 20767
+f 20806 20769 20768
+f 20805 20806 20768
+f 20807 20770 20769
+f 20806 20807 20769
+f 1155 20771 20770
+f 20807 1155 20770
+f 1155 1157 20772
+f 20771 1155 20772
+f 1157 1016 20773
+f 20772 1157 20773
+f 1016 1018 20774
+f 20773 1016 20774
+f 1018 1150 20775
+f 20774 1018 20775
+f 1150 1152 20776
+f 20775 1150 20776
+f 1152 1254 20777
+f 20776 1152 20777
+f 1254 1259 20778
+f 20777 1254 20778
+f 1259 1401 20779
+f 20778 1259 20779
+f 1401 1260 20780
+f 20779 1401 20780
+f 1260 1262 20781
+f 20780 1260 20781
+f 1262 1248 15279
+f 20781 1262 15279
+f 8223 7105 8214
+f 2147 19483 7106
+f 8869 9084 597
+f 20808 8839 8717
+f 4473 2974 1148
+f 1147 1004 1006
+f 19219 1398 1397
+f 5793 19219 1397
+f 19657 20028 19623
+f 1398 2973 1399
+f 19178 19249 19311
+f 8210 8126 2431
+f 19015 19518 19082
+f 9334 9598 9335
+f 1115 10377 3594
+f 17036 16146 17037
+f 1893 20809 20810
+f 1200 1202 1201
+f 18217 18215 13335
+f 989 19990 644
+f 4479 5943 915
+f 9184 19812 9185
+f 2097 1173 15473
+f 2484 8984 6333
+f 18987 19053 2571
+f 1562 18987 2571
+f 20791 20811 12544
+f 8303 8607 6625
+f 9595 9597 20790
+f 19943 9595 20790
+f 9597 9772 20751
+f 20790 9597 20751
+f 971 973 7659
+f 9772 18737 9908
+f 848 847 990
+f 7259 4919 7260
+f 1766 5662 18590
+f 1764 19986 19812
+f 11568 12365 18246
+f 17295 11201 20812
+f 19947 1766 18590
+f 785 2802 2092
+f 1405 1250 1264
+f 17393 486 2300
+f 784 2803 2802
+f 2852 13511 17315
+f 488 487 2298
+f 20813 15823 16501
+f 1944 12059 16442
+f 18570 1408 13686
+f 14300 9346 16682
+f 658 660 1407
+f 1409 8981 1410
+f 13678 1559 2630
+f 660 329 1407
+f 1499 1498 14962
+f 17146 13678 2630
+f 14837 18529 14838
+f 3233 3238 3234
+f 1021 20795 13978
+f 20814 16591 20758
+f 1153 20796 20795
+f 1021 1153 20795
+f 891 20797 20796
+f 1153 891 20796
+f 4159 20798 20797
+f 891 4159 20797
+f 883 20799 20798
+f 4159 883 20798
+f 897 20800 20799
+f 883 897 20799
+f 896 20801 20800
+f 897 896 20800
+f 10054 20802 20801
+f 896 10054 20801
+f 10055 20803 20802
+f 10054 10055 20802
+f 10053 20804 20803
+f 10055 10053 20803
+f 10052 20805 20804
+f 10053 10052 20804
+f 10121 20806 20805
+f 10052 10121 20805
+f 9912 20807 20806
+f 10121 9912 20806
+f 1156 1155 20807
+f 9912 1156 20807
+f 1156 1400 1157
+f 20815 20816 5518
+f 2505 2655 10179
+f 9881 9876 9879
+f 20817 20818 20819
+f 20820 20821 20822
+f 20823 20824 20825
+f 20826 20827 20828
+f 12453 20791 12544
+f 19301 20829 20830
+f 14215 9855 8136
+f 20831 19440 20832
+f 14505 18549 14255
+f 20833 20834 20835
+f 20836 20837 20838
+f 20839 20840 14572
+f 10247 2192 10165
+f 20841 19300 19302
+f 19694 19719 19695
+f 20842 20843 20844
+f 8051 8050 20845
+f 20846 20847 20848
+f 7068 7067 20849
+f 20850 20851 20852
+f 20853 20854 20855
+f 20856 20857 20858
+f 19166 20831 20859
+f 20860 18997 20861
+f 2655 2657 10227
+f 20862 20863 20864
+f 20865 20866 20867
+f 20868 20869 20870
+f 20871 20872 20873
+f 20874 9683 20875
+f 20876 20877 20878
+f 20879 20880 20881
+f 20882 20883 20884
+f 4178 20885 20886
+f 20887 20888 20718
+f 20889 20890 20891
+f 8625 9755 8626
+f 20892 20893 20894
+f 20894 20895 20896
+f 20897 6639 20898
+f 20899 18588 20900
+f 20901 4178 20886
+f 19523 20902 20903
+f 20904 20905 8725
+f 6737 6842 20906
+f 3365 219 218
+f 20907 20908 20909
+f 18997 2745 20910
+f 10590 3835 14155
+f 10169 10095 15393
+f 1638 20910 1634
+f 20870 20865 20867
+f 20866 20911 20912
+f 20867 20866 20912
+f 20913 8943 8942
+f 20914 20915 20916
+f 20917 20918 20919
+f 20920 14631 20921
+f 20811 20922 12637
+f 20899 20900 20923
+f 18588 18589 20900
+f 20924 20923 20925
+f 20924 20899 20923
+f 20926 20925 20893
+f 20926 20924 20925
+f 6751 6658 16105
+f 20892 20926 20893
+f 20927 20928 20862
+f 3461 8222 8221
+f 20929 20930 20931
+f 9974 20711 9976
+f 20711 20932 9168
+f 20931 9974 9976
+f 583 19748 870
+f 7767 4912 13903
+f 10095 10094 20712
+f 3228 6353 20933
+f 20934 20935 20936
+f 20752 2744 3223
+f 20937 20938 20939
+f 20911 20937 20877
+f 3432 20940 20941
+f 16189 20942 20943
+f 20944 20945 20946
+f 20947 20948 20949
+f 20950 20951 20952
+f 12544 20811 12637
+f 5968 5972 20953
+f 4966 20954 20955
+f 20913 20956 8943
+f 5365 20957 20958
+f 20959 8483 20960
+f 10226 17231 20961
+f 20962 20963 5250
+f 10166 10170 19787
+f 3216 3215 3425
+f 20452 19909 15119
+f 20964 20965 20224
+f 20966 20782 20967
+f 20968 20969 20970
+f 20971 15037 20972
+f 20825 20973 20974
+f 19891 9311 9310
+f 384 4002 6905
+f 19303 9311 3222
+f 9977 10124 10056
+f 20912 20911 20877
+f 20881 20873 20826
+f 20877 20937 20939
+f 9542 20966 20967
+f 20975 9570 20976
+f 2353 1275 2354
+f 9688 9687 6484
+f 20977 20978 20979
+f 20980 20981 20982
+f 20982 20981 20983
+f 20984 20856 20858
+f 18767 10250 20985
+f 20986 20987 20879
+f 10094 10175 20712
+f 11344 20988 11345
+f 2191 10170 2192
+f 20258 20989 20990
+f 20991 20927 20992
+f 20879 20881 20993
+f 20994 20995 20221
+f 20996 20997 20998
+f 20999 21000 21001
+f 21002 21003 21004
+f 20977 19957 21005
+f 19890 9310 16665
+f 10021 2532 7747
+f 19733 21006 18522
+f 7051 7149 7052
+f 21007 20975 21008
+f 19890 9527 9526
+f 20938 21009 21010
+f 20939 20938 21010
+f 8625 8624 21011
+f 20940 5367 20941
+f 21012 4177 4179
+f 21013 15221 4812
+f 21014 21015 11019
+f 20877 20939 20878
+f 21016 21017 17988
+f 21018 21019 21020
+f 21021 20850 20917
+f 9870 21022 21023
+f 21024 20992 20917
+f 16797 4164 4166
+f 9793 20417 9649
+f 9976 20711 9168
+f 21025 21026 21027
+f 21028 21029 21030
+f 21031 10208 10210
+f 16413 16412 1098
+f 8845 6307 8846
+f 21032 21033 7958
+f 6354 6494 21034
+f 18874 12104 12105
+f 20909 21035 21036
+f 21037 3005 14866
+f 2533 4082 4084
+f 10175 10174 10177
+f 9905 3146 3148
+f 21009 21038 21039
+f 21040 20934 20936
+f 21010 21009 21039
+f 15508 21041 21042
+f 21043 21044 20965
+f 17198 17197 21045
+f 21046 21047 21048
+f 20932 10208 9168
+f 21049 21050 21051
+f 21052 21053 21054
+f 20852 21024 20917
+f 9293 21002 21043
+f 21055 21056 21057
+f 21058 21059 21060
+f 8585 8586 8710
+f 5358 19172 21061
+f 21062 21063 21064
+f 21062 4164 21063
+f 5656 1365 1367
+f 10208 21031 9168
+f 21065 20823 20989
+f 21014 21066 21015
+f 21067 21068 21069
+f 6390 21070 16104
+f 21071 21072 21073
+f 21072 21074 21075
+f 13152 13914 19293
+f 3151 8271 8445
+f 21076 21077 106
+f 12193 13152 19293
+f 21078 1622 21079
+f 10505 9188 10503
+f 21038 21080 21081
+f 21082 5382 5384
+f 21083 21084 16088
+f 21085 21086 21087
+f 21088 21046 21048
+f 21089 21090 21091
+f 21092 21093 21094
+f 21095 20220 21096
+f 21097 13342 13344
+f 10938 12962 14980
+f 2017 2016 13404
+f 21098 21099 2665
+f 21100 21011 21101
+f 21102 21103 21104
+f 19577 20851 20850
+f 3421 9021 3611
+f 21105 21106 8835
+f 21107 21062 21064
+f 16017 21108 21109
+f 9074 21102 20908
+f 21110 21111 21112
+f 21113 21110 21112
+f 21111 21114 21115
+f 21112 21111 21115
+f 19267 1135 1134
+f 4080 3458 3457
+f 2192 10247 2193
+f 7444 2752 2754
+f 8700 6307 8845
+f 8830 8713 8712
+f 14573 21116 1554
+f 20949 21117 21118
+f 1636 17811 8692
+f 3969 21119 8302
+f 21114 21120 21121
+f 21115 21114 21121
+f 21122 21123 21124
+f 21125 21126 21127
+f 21128 21129 20988
+f 21128 21107 21129
+f 11344 21128 20988
+f 21107 21064 21129
+f 21130 21131 21132
+f 21133 21100 21134
+f 20226 20225 21135
+f 3240 3024 21136
+f 4171 4349 4169
+f 21137 21138 21139
+f 13403 21140 21141
+f 19885 21142 21143
+f 21120 1366 334
+f 21121 21120 334
+f 1366 5369 402
+f 334 1366 402
+f 8051 9798 8049
+f 2171 2014 8931
+f 20716 19530 19885
+f 10228 10153 10152
+f 17059 19530 8722
+f 21144 1767 1769
+f 21145 21105 8835
+f 808 8707 13662
+f 9866 8838 8918
+f 10028 10099 10100
+f 5369 5371 403
+f 16540 16543 16541
+f 21020 21146 21018
+f 1695 1895 6847
+f 21091 21125 21127
+f 21124 21071 21073
+f 9074 9073 9294
+f 21147 8628 8521
+f 20417 21023 9649
+f 13587 13486 21148
+f 2214 18006 2050
+f 13152 12193 648
+f 6830 4692 927
+f 8576 8573 21061
+f 21146 3236 3235
+f 6336 6335 15153
+f 402 5369 403
+f 20809 21149 20810
+f 6531 3708 6532
+f 403 5371 1480
+f 21150 21151 2644
+f 21086 21152 21153
+f 8823 21154 8704
+f 2347 2346 2352
+f 16340 20716 16341
+f 16341 19885 21155
+f 1015 13372 13286
+f 8048 21032 7957
+f 9582 9583 9625
+f 5524 13331 9255
+f 21036 21145 8830
+f 9576 9624 20976
+f 10882 7740 16308
+f 21156 13587 21148
+f 2347 2352 20465
+f 21157 21158 21159
+f 7066 7157 9671
+f 21160 17167 17166
+f 21161 14705 21162
+f 8712 8587 8711
+f 5358 8573 5356
+f 8513 8421 8420
+f 8720 8727 8596
+f 9870 9869 21163
+f 20973 21164 20974
+f 1482 2054 2053
+f 21126 8576 21061
+f 21165 9116 9018
+f 21166 18535 21167
+f 21034 21166 21167
+f 21168 18610 18535
+f 21166 21168 18535
+f 21169 21170 8630
+f 20875 9755 21133
+f 7947 6847 21171
+f 2364 5656 2365
+f 21172 16342 16341
+f 21173 18545 19169
+f 5519 5371 5516
+f 7363 13380 7243
+f 5250 20963 8710
+f 7368 7370 7248
+f 19551 21174 1918
+f 21168 21175 18655
+f 18610 21168 18655
+f 674 21176 8629
+f 20864 20821 20820
+f 1918 21177 1916
+f 11070 6522 21178
+f 3051 2515 16888
+f 20618 19912 20653
+f 20500 20452 15119
+f 21179 21180 21181
+f 21024 20991 20992
+f 21073 21075 20256
+f 21182 21183 21184
+f 21053 20990 21054
+f 21175 21185 18687
+f 21186 21187 21184
+f 18655 21175 18687
+f 21185 21188 18984
+f 18687 21185 18984
+f 21188 21189 19161
+f 21190 21191 20991
+f 21192 20907 21193
+f 21194 21195 21196
+f 21197 21194 21196
+f 21198 13309 5353
+f 9873 9872 9875
+f 9908 18737 21199
+f 21200 7151 7153
+f 8424 8423 8519
+f 21201 19551 1917
+f 18984 21188 19161
+f 21189 21202 19163
+f 6946 15448 6944
+f 21203 21204 21205
+f 15602 21019 21206
+f 18012 15602 21206
+f 21207 21208 20257
+f 21209 9624 21210
+f 21211 21212 21213
+f 7067 672 21214
+f 21215 13888 13881
+f 5108 5795 5109
+f 1483 17922 1484
+f 8050 21216 21217
+f 19161 21189 19163
+f 21202 21218 19267
+f 19163 21202 19267
+f 19267 21218 1135
+f 9082 4800 2730
+f 1749 21219 1750
+f 19522 21220 20902
+f 21221 21222 21223
+f 17606 21173 21224
+f 2532 2534 7747
+f 18545 706 19169
+f 19704 21225 19705
+f 9116 8896 8897
+f 21226 14865 3007
+f 20997 20980 20982
+f 15305 18544 17605
+f 5197 5196 17762
+f 8835 3988 3987
+f 20815 3964 10327
+f 21227 21228 21229
+f 20209 16746 16748
+f 21206 21019 21018
+f 1736 1585 1584
+f 5060 635 1569
+f 21230 21231 21232
+f 3431 7268 20940
+f 20854 21233 21234
+f 21235 15447 21236
+f 8145 8052 21033
+f 21218 6515 1135
+f 21237 21238 21239
+f 21240 19115 2733
+f 1754 1914 1755
+f 5956 21241 21242
+f 21243 21077 21076
+f 19813 6842 6843
+f 21022 21244 20883
+f 17685 21245 21246
+f 3313 2245 1377
+f 430 18837 18838
+f 21247 17686 17685
+f 20290 20454 12777
+f 21248 21249 21250
+f 21251 20839 21252
+f 21253 19953 21254
+f 21255 21256 21257
+f 5195 16163 21258
+f 21259 18210 17996
+f 21260 21261 21262
+f 7153 7262 12744
+f 21263 18641 1984
+f 21264 20986 21265
+f 9082 4798 4800
+f 20930 21199 18737
+f 21266 21215 13881
+f 21267 3225 21268
+f 21269 17053 21270
+f 6085 21271 6086
+f 21272 3240 21136
+f 20857 20840 21273
+f 2289 4691 4693
+f 8727 21201 1917
+f 21274 4177 21012
+f 21274 21275 4177
+f 15209 21276 21277
+f 21272 1857 1859
+f 20719 21227 21229
+f 21228 21278 21279
+f 9947 15306 21280
+f 15768 20410 17577
+f 9947 15304 15306
+f 9910 15304 9947
+f 21281 20181 19114
+f 5656 5515 1365
+f 21165 21251 21252
+f 9075 20908 20907
+f 6841 6942 6843
+f 21277 21276 21282
+f 21147 21204 8628
+f 5301 5300 6692
+f 21283 21284 21285
+f 7548 1739 20330
+f 11089 19150 6242
+f 19158 1926 12300
+f 21286 14688 21287
+f 21288 21289 21290
+f 3972 4183 3979
+f 21291 4961 4799
+f 3282 4174 21292
+f 1736 1584 1574
+f 21293 8724 8840
+f 21105 21294 21106
+f 20897 6637 6639
+f 20878 20218 21295
+f 9021 3797 3611
+f 3976 3975 4186
+f 19200 12459 1244
+f 15480 9064 693
+f 9911 9947 21296
+f 21297 21296 21280
+f 8839 20808 20217
+f 20815 5518 3964
+f 2671 842 2672
+f 19169 16340 16342
+f 20821 21298 21299
+f 20817 20819 21300
+f 21301 5775 21302
+f 21272 1859 3437
+f 21303 4176 21304
+f 4181 3972 21304
+f 5267 12320 12319
+f 21305 21306 2179
+f 21305 21307 21306
+f 2179 6484 9687
+f 21307 21308 21309
+f 21308 21310 21309
+f 16266 21311 20537
+f 19762 21312 21313
+f 21314 20999 21001
+f 21315 21316 21317
+f 20906 6842 19813
+f 21318 21059 21319
+f 21320 21303 21304
+f 4170 4172 4176
+f 5502 5751 15275
+f 5518 5937 1899
+f 21321 9911 21296
+f 6830 927 15471
+f 9909 9911 21321
+f 16408 9909 21321
+f 9166 14514 9914
+f 12100 2144 10017
+f 21322 20968 20970
+f 21090 21323 21125
+f 19524 8576 8575
+f 9910 9909 15357
+f 21324 21325 21326
+f 21327 21328 21329
+f 7063 5365 5368
+f 21330 21331 21332
+f 21307 21309 21306
+f 21333 21334 21335
+f 334 402 335
+f 1917 1916 8597
+f 21336 21115 21337
+f 21121 334 333
+f 6429 7135 6430
+f 21337 21121 333
+f 20788 21338 20789
+f 20719 21229 21339
+f 21340 673 9561
+f 8942 8941 8815
+f 4188 4187 9116
+f 21341 21342 21343
+f 21344 10954 16345
+f 16229 4651 5256
+f 15778 16408 11616
+f 7248 13382 7369
+f 15358 9909 16408
+f 15778 15358 16408
+f 21004 21345 21255
+f 8598 8597 1916
+f 6437 6690 10718
+f 14423 15777 11616
+f 21346 21347 6370
+f 19733 18522 15605
+f 21112 21115 21336
+f 21348 20788 20787
+f 21349 21335 21350
+f 1916 21295 21095
+f 21349 21333 21335
+f 21333 21351 3417
+f 21113 21112 21352
+f 21353 21113 21352
+f 21354 20891 21261
+f 21355 21348 20787
+f 21340 21169 21176
+f 21356 20828 21357
+f 21358 21359 21360
+f 21279 21093 21092
+f 21352 21112 21336
+f 21115 21121 21337
+f 21272 3437 3240
+f 5383 21361 5389
+f 21362 21363 21364
+f 5268 5267 12319
+f 21365 19574 14299
+f 14501 21167 18535
+f 2830 3025 3024
+f 14235 16244 14236
+f 673 21176 674
+f 12104 6652 6654
+f 20956 14363 21366
+f 21367 21368 21369
+f 14359 20290 7227
+f 16072 16071 20647
+f 21370 21371 14621
+f 20336 20213 20212
+f 18148 2959 2961
+f 21372 21349 21350
+f 7062 16916 3004
+f 7271 7273 5368
+f 14257 12931 8219
+f 21373 21374 21375
+f 21376 21377 21378
+f 5512 4580 4582
+f 21379 21380 21381
+f 17516 7318 21382
+f 5751 5940 21383
+f 21182 21184 21384
+f 21372 21350 21310
+f 21308 21372 21310
+f 21385 21386 21387
+f 2533 4084 2534
+f 18012 21388 18013
+f 4404 13394 5378
+f 8586 5251 5250
+f 21389 15110 5064
+f 8710 20963 21390
+f 21391 21392 21393
+f 21275 21354 4177
+f 9340 13346 9629
+f 21394 21395 21396
+f 9290 9291 9294
+f 20898 6639 21397
+f 369 20613 638
+f 4921 18054 1712
+f 21398 8511 8562
+f 21399 20784 21180
+f 21400 21401 21402
+f 9542 20967 21403
+f 4179 4178 20901
+f 21404 21379 21381
+f 21265 20879 20993
+f 21210 9625 21348
+f 20880 20871 20881
+f 21405 20994 20225
+f 21096 21406 21404
+f 20935 21407 21408
+f 15079 15883 21409
+f 21334 21333 3417
+f 13560 12634 13561
+f 21410 21411 21412
+f 11160 390 392
+f 21365 14298 21411
+f 21410 21365 21411
+f 21413 7861 7860
+f 21414 21415 21416
+f 21065 21417 20823
+f 21365 14299 14298
+f 9584 9683 20874
+f 21396 21395 21418
+f 14876 19637 14875
+f 21381 21380 21391
+f 21419 4179 20901
+f 9469 9542 21403
+f 20967 20784 21399
+f 21180 20882 21137
+f 21403 20967 21399
+f 20918 20864 21420
+f 21232 21231 20868
+f 21421 20870 21422
+f 21315 21423 21316
+f 9640 14820 14822
+f 21424 21008 21425
+f 20940 3432 3431
+f 6824 6823 19200
+f 10175 10177 10098
+f 20984 20858 20854
+f 7067 21214 20849
+f 21217 21426 21186
+f 21427 21410 17351
+f 17351 21412 17349
+f 19574 21365 21410
+f 21427 19574 21410
+f 524 14297 14299
+f 12268 8567 13984
+f 21345 21428 21256
+f 21200 12744 21274
+f 21429 21050 21049
+f 20986 21430 20987
+f 6638 21192 6639
+f 21124 21073 21431
+f 10982 20890 20889
+f 21421 21422 20905
+f 20784 20882 21180
+f 20891 1891 21261
+f 6497 6636 6737
+f 20868 20870 21421
+f 20908 21104 20909
+f 6656 21432 6653
+f 21324 21433 14868
+f 9540 9469 9468
+f 20840 20857 14573
+f 21030 21434 21392
+f 21392 21237 21393
+f 20919 21420 21417
+f 21435 21436 21437
+f 21408 21130 20871
+f 21438 17351 17350
+f 13071 4735 4734
+f 21439 21427 21438
+f 21440 21439 21438
+f 2734 19574 21427
+f 21439 2734 21427
+f 14363 19880 14360
+f 2734 2572 19574
+f 20993 20826 21356
+f 17197 20975 21327
+f 21441 21040 20936
+f 21021 20917 20919
+f 3749 1979 6743
+f 20992 20862 20918
+f 20218 21010 20219
+f 17579 9998 6742
+f 21093 21431 21442
+f 19521 21443 19522
+f 20882 20884 21137
+f 21444 18155 18154
+f 1642 1644 3919
+f 21445 13966 21378
+f 8399 8313 8483
+f 21446 20868 21421
+f 21447 21448 21449
+f 6637 8823 8949
+f 21450 21267 21451
+f 21450 21451 21452
+f 21453 21454 18640
+f 21455 18777 20208
+f 21456 21440 18778
+f 21455 21456 18778
+f 21240 21439 21440
+f 21456 21240 21440
+f 6638 6637 8949
+f 21457 21458 21459
+f 6365 6367 8144
+f 15556 17931 17918
+f 20934 21460 20935
+f 21460 21461 21462
+f 21463 21123 21122
+f 21123 21071 21124
+f 21139 21138 21464
+f 21369 21368 20846
+f 21465 20453 21263
+f 12744 21275 21274
+f 20220 21406 21096
+f 21466 21065 21467
+f 2896 21468 20946
+f 21445 21378 21220
+f 21469 21470 21471
+f 8461 1642 3919
+f 21472 18555 18551
+f 8147 8053 8145
+f 16883 16884 16243
+f 8423 8422 8518
+f 16232 14044 8798
+f 21473 17516 21382
+f 15284 1752 15285
+f 6482 21474 6483
+f 21475 21450 21452
+f 21267 21268 21451
+f 21476 21455 1733
+f 17793 1733 20208
+f 19114 21456 21455
+f 21476 19114 21455
+f 19115 21240 21456
+f 19114 19115 21456
+f 9772 9908 9907
+f 17989 21477 17990
+f 20885 21354 21261
+f 21434 21478 21238
+f 20881 20871 20873
+f 21479 21480 21481
+f 21238 21482 21322
+f 21483 21484 20927
+f 7368 21485 7477
+f 8625 21011 21100
+f 20991 21483 20927
+f 21056 21486 21057
+f 1347 1048 14441
+f 21487 20999 21314
+f 21368 20847 20846
+f 20880 21408 20871
+f 21446 21421 20904
+f 21488 21489 21490
+f 21132 21491 21492
+f 20905 21422 21493
+f 20996 20998 21494
+f 20833 20835 21103
+f 17549 21495 21496
+f 20873 20872 21497
+f 8846 1578 14421
+f 21498 21028 21379
+f 21133 8625 21100
+f 5065 8221 8223
+f 21499 21500 9019
+f 7740 7739 17000
+f 18056 17139 21501
+f 21502 21110 15607
+f 6517 16017 21109
+f 21502 21503 21111
+f 21110 21502 21111
+f 21504 21505 21448
+f 2363 12371 5650
+f 1047 10919 14440
+f 21468 20944 20946
+f 21506 21507 21508
+f 21509 13396 13395
+f 21475 21452 21510
+f 21511 21475 21510
+f 21512 21513 21514
+f 21511 21510 21474
+f 21515 21516 21453
+f 6482 21511 21474
+f 13332 2951 2952
+f 7445 21517 21518
+f 1732 21476 1733
+f 16153 1732 1731
+f 21281 21476 1732
+f 16152 21281 1732
+f 636 6504 1362
+f 6042 14565 7031
+f 13812 3363 218
+f 4957 1540 8380
+f 20453 21465 5958
+f 21519 21520 21521
+f 6492 8558 6844
+f 21522 21523 21524
+f 21503 21525 21114
+f 21111 21503 21114
+f 21525 1367 21120
+f 21114 21525 21120
+f 2144 6532 10017
+f 20856 20255 21116
+f 21120 1367 1366
+f 20458 21526 20414
+f 21527 21210 21355
+f 21484 20853 20928
+f 21048 21047 20929
+f 21380 21030 21392
+f 20930 9974 20931
+f 21407 21131 21130
+f 20917 20992 20918
+f 21493 21174 19551
+f 21528 21529 1081
+f 20928 20855 20863
+f 21275 20889 21354
+f 21530 21417 21065
+f 9829 9975 2893
+f 21001 21000 21531
+f 21532 21122 21228
+f 21239 21322 21533
+f 3979 3978 3973
+f 21137 20884 21138
+f 21322 20970 21533
+f 20224 21405 20225
+f 1581 1587 1582
+f 5371 5519 1480
+f 21210 21348 21355
+f 17605 18545 17606
+f 20828 20827 21485
+f 21534 20713 9872
+f 8897 9018 9116
+f 3037 3036 21535
+f 17197 9571 20975
+f 21166 21034 6496
+f 21447 21449 20999
+f 3178 7441 10523
+f 21487 21447 20999
+f 14574 21536 3429
+f 9075 21192 6638
+f 6498 21168 21166
+f 9972 9825 9826
+f 21537 21175 21168
+f 6498 21537 21168
+f 21537 21538 21185
+f 21175 21537 21185
+f 21538 21539 21188
+f 20918 20862 20864
+f 21540 21315 21541
+f 21542 21543 21544
+f 14445 21509 13395
+f 21545 21178 6522
+f 20847 21546 20848
+f 21452 21547 21548
+f 21474 21510 21549
+f 21039 21081 21498
+f 8575 8574 19524
+f 16831 16830 21518
+f 8630 21170 21550
+f 5663 10299 5664
+f 19391 10152 17851
+f 21551 16152 2048
+f 21552 21551 2048
+f 20180 21281 16152
+f 21551 20180 16152
+f 672 9559 9561
+f 20180 20181 21281
+f 672 9561 673
+f 8941 8945 8814
+f 5304 11221 5210
+f 1891 1893 21261
+f 21553 19521 19523
+f 21185 21538 21188
+f 21539 21554 21189
+f 21188 21539 21189
+f 21554 21555 21202
+f 21189 21554 21202
+f 6389 14548 13396
+f 21555 21556 21218
+f 21208 21467 20257
+f 21557 20945 20944
+f 20712 15393 10095
+f 21075 21207 20257
+f 21558 9293 21043
+f 20256 21075 20257
+f 10986 10987 19423
+f 8573 5358 21061
+f 21559 1721 1567
+f 21164 21314 20969
+f 21560 2047 2049
+f 21561 17107 17109
+f 505 2484 18855
+f 12538 21561 21562
+f 20833 9294 20834
+f 21563 9550 21564
+f 15570 17332 21565
+f 3919 7211 8461
+f 21509 6389 13396
+f 2181 2343 2182
+f 21566 21567 15569
+f 15571 21566 15569
+f 1894 1896 21567
+f 21566 1894 21567
+f 21199 21101 9908
+f 21568 21569 13051
+f 21375 21570 20841
+f 21030 21571 21434
+f 14869 14617 14548
+f 21572 21573 21574
+f 9742 9671 7157
+f 21047 21199 20930
+f 21202 21555 21218
+f 21177 21295 1916
+f 21556 19434 6515
+f 21218 21556 6515
+f 14459 16715 6366
+f 21178 21575 21576
+f 6389 14869 14548
+f 2050 18006 1922
+f 1591 1586 1589
+f 21422 21577 21493
+f 20217 21293 8840
+f 21578 19551 21201
+f 21579 21580 20215
+f 21581 8726 8725
+f 21582 21580 21579
+f 20216 21293 20217
+f 21106 21582 21579
+f 21134 21199 21047
+f 21580 20216 20215
+f 21583 21584 20984
+f 21295 20220 21095
+f 21585 19638 19637
+f 21484 21583 20853
+f 15569 21194 17332
+f 21586 21565 17332
+f 20151 2936 20181
+f 15569 21567 21195
+f 14868 14647 14617
+f 13880 21587 21588
+f 2047 21589 21590
+f 21590 21591 21592
+f 21593 21552 21590
+f 21592 21593 21590
+f 19718 21551 21552
+f 21593 19718 21552
+f 16795 2171 8931
+f 9563 9562 9568
+f 2729 9082 2730
+f 21594 21173 16342
+f 11223 2823 2460
+f 9584 9583 9680
+f 21228 21122 21278
+f 21595 1983 8576
+f 21596 21597 21055
+f 21406 21498 21379
+f 4176 4181 21304
+f 21571 21478 21434
+f 21439 2733 2734
+f 21598 21356 21357
+f 21599 21356 21598
+f 21600 20055 21388
+f 21392 21434 21237
+f 21051 20717 21601
+f 15357 9909 15358
+f 21602 21603 21604
+f 14731 21605 14732
+f 3581 21518 16830
+f 3036 5406 14688
+f 4972 4973 6090
+f 21600 21606 21607
+f 1444 1445 16804
+f 11883 21608 21609
+f 2972 2748 15828
+f 5111 5110 15321
+f 21610 21611 21612
+f 21613 21614 21615
+f 802 21616 1419
+f 16973 17866 14039
+f 18995 17210 17212
+f 21617 21618 21082
+f 21619 21620 21621
+f 4538 21622 4228
+f 14621 21623 21370
+f 21624 21625 21626
+f 6388 14867 14869
+f 2268 5528 1385
+f 21627 2363 2365
+f 21628 18958 18960
+f 10098 10026 10175
+f 2177 21629 2175
+f 21630 21631 15677
+f 21222 15338 15340
+f 21632 21602 21597
+f 21603 21423 21604
+f 21395 21490 21418
+f 20711 9596 9595
+f 14869 14868 14617
+f 21081 21029 21028
+f 21227 21532 21228
+f 21231 20869 20868
+f 20948 21375 21117
+f 20841 19302 21633
+f 9652 20613 21634
+f 21635 11818 16592
+f 19576 21424 19577
+f 21433 14692 14647
+f 3039 2052 3040
+f 7150 21012 19813
+f 20225 20994 20221
+f 21488 21055 21489
+f 1921 2050 1922
+f 21396 21418 21300
+f 21483 21636 21583
+f 20819 21396 21300
+f 8727 8720 21201
+f 17197 21327 21045
+f 10171 15393 21534
+f 20857 21116 14573
+f 21430 21441 20987
+f 7204 12170 8838
+f 10819 9053 18170
+f 8401 1377 3457
+f 21337 333 21637
+f 335 21638 21637
+f 21336 21337 21639
+f 21639 21337 21637
+f 21640 21641 21107
+f 21642 21336 21639
+f 19952 4164 21062
+f 21641 19952 21062
+f 9681 9683 9584
+f 21219 1749 17306
+f 11017 14433 21587
+f 10176 10258 10180
+f 21643 21591 21644
+f 20834 21558 21645
+f 21646 21593 21592
+f 21647 21646 21592
+f 19884 19718 21593
+f 21646 19884 21593
+f 14868 21433 14647
+f 390 8698 391
+f 7245 10905 7363
+f 7736 6890 15449
+f 12777 20453 5958
+f 20422 18298 15394
+f 21029 21571 21030
+f 20858 20857 21273
+f 20862 20928 20863
+f 8485 8399 8483
+f 21352 21336 21642
+f 5249 20962 5250
+f 21648 21243 21076
+f 21216 9807 9741
+f 21423 21603 21649
+f 21650 21007 21424
+f 21470 18404 21471
+f 21116 20255 14876
+f 21517 21600 21607
+f 21606 21470 21469
+f 21651 21607 21652
+f 21607 21606 21469
+f 21517 21607 21651
+f 21518 21517 21651
+f 14304 8952 21366
+f 21607 21469 21652
+f 21471 21400 21652
+f 21469 21471 21652
+f 6805 21653 6806
+f 21654 21655 21656
+f 21657 21658 21659
+f 16888 3021 21660
+f 21661 21662 21663
+f 16887 16888 5539
+f 4959 21664 4960
+f 14052 14040 14172
+f 10954 21665 4953
+f 4954 21666 4955
+f 14044 2653 2018
+f 21667 21624 21626
+f 21618 5382 21082
+f 21668 21669 21617
+f 4496 6089 4497
+f 21670 13201 21671
+f 21672 21673 21674
+f 5120 6168 2835
+f 4462 3816 4715
+f 21675 21676 21182
+f 21584 21585 20856
+f 21381 21391 8510
+f 21543 21542 21677
+f 9468 9397 9292
+f 20851 21527 21678
+f 21536 3227 3429
+f 10968 5380 5381
+f 20970 21001 21533
+f 20967 20782 20784
+f 18798 13966 21443
+f 21679 14759 14692
+f 21055 21057 21489
+f 15600 21358 21360
+f 21353 21352 21680
+f 21058 21650 19576
+f 21527 21355 21678
+f 21490 21681 21682
+f 2813 2812 2129
+f 21425 21209 21527
+f 21104 21103 21683
+f 20993 20881 20826
+f 19957 21684 21005
+f 21192 9075 20907
+f 21433 21679 14692
+f 19164 1134 21685
+f 18688 18985 21686
+f 21687 18656 21688
+f 19077 15250 14714
+f 2657 2494 2493
+f 18656 21687 21689
+f 9728 9793 9648
+f 21265 20993 21599
+f 20888 21690 21691
+f 21532 21463 21122
+f 18536 18611 7465
+f 9323 9211 8358
+f 2186 1081 21529
+f 21604 21423 21315
+f 21500 9018 9019
+f 335 404 21638
+f 9352 9235 14572
+f 21692 21693 21032
+f 9467 9469 21694
+f 21675 21182 21695
+f 21481 21675 21695
+f 21203 9019 21204
+f 5863 13511 2852
+f 19637 9830 14875
+f 9683 9755 20875
+f 21695 21384 21696
+f 21484 21483 21583
+f 9880 21377 21376
+f 2192 10170 10166
+f 9874 20712 9877
+f 21679 21697 14785
+f 19954 21698 3237
+f 10020 10019 14889
+f 694 9063 4481
+f 21531 8519 8518
+f 20929 20931 21699
+f 21174 21177 1918
+f 19436 21646 21647
+f 21592 21700 21647
+f 19703 19884 21646
+f 19436 19703 21646
+f 5368 5367 7271
+f 9879 9878 9883
+f 14978 21701 18067
+f 4733 7339 4734
+f 5512 4582 3897
+f 20983 1984 1983
+f 21003 21345 21004
+f 5366 5365 20958
+f 13346 21702 11387
+f 10176 10180 10099
+f 21328 21703 21704
+f 21680 21352 21642
+f 21194 15569 21195
+f 20829 20888 20887
+f 21510 21452 21548
+f 21193 20907 21705
+f 7574 20827 21497
+f 21451 21706 21547
+f 16278 1444 16804
+f 2459 2458 3213
+f 21707 14405 21708
+f 6239 2183 6238
+f 21390 21709 8829
+f 1587 1581 1588
+f 21710 21255 21711
+f 21712 21052 21482
+f 21713 21709 21390
+f 21478 21712 21482
+f 21060 21059 21714
+f 2363 21627 12371
+f 21255 21257 21711
+f 21081 21080 21029
+f 8513 21393 8514
+f 21239 21533 8518
+f 7245 7363 7243
+f 21528 1081 1080
+f 20215 20217 20808
+f 13293 13199 13198
+f 21058 19576 21059
+f 20826 20873 20827
+f 10152 10154 17851
+f 14759 21679 14785
+f 14405 1755 21708
+f 1892 20809 1893
+f 6742 9999 6502
+f 14406 14405 21707
+f 5119 5120 2835
+f 21510 21548 21549
+f 21464 21715 21373
+f 21474 21549 14210
+f 21183 21716 21184
+f 20935 21462 21407
+f 19638 9829 9830
+f 21040 21486 20934
+f 21717 21718 21719
+f 19121 20716 16340
+f 20945 21265 21599
+f 7149 19813 6843
+f 9285 9282 9391
+f 21314 21001 20970
+f 15081 104 106
+f 19523 19522 20902
+f 20974 21164 20969
+f 15598 21353 21680
+f 19577 21425 20851
+f 21424 21425 19577
+f 21425 21527 20851
+f 21578 21201 21581
+f 21720 19164 21685
+f 14225 18533 18534
+f 19162 19164 21720
+f 14225 18534 16179
+f 21688 18688 21686
+f 21721 19162 21720
+f 18985 19162 21721
+f 21686 18985 21721
+f 21585 20255 20856
+f 21584 20856 20984
+f 18611 18656 21689
+f 20927 21484 20928
+f 7465 7464 18536
+f 18656 18688 21688
+f 20222 21446 21722
+f 18611 21689 7465
+f 21697 15382 14845
+f 13930 21723 20378
+f 21169 21329 21170
+f 21724 20849 21725
+f 404 1481 21726
+f 21583 20984 20853
+f 333 335 21637
+f 21727 404 21726
+f 21359 21353 15598
+f 404 21727 21638
+f 14209 20368 21728
+f 20847 21464 21546
+f 13055 9252 17271
+f 18798 21443 21163
+f 14785 21697 14845
+f 21729 21730 5508
+f 3472 3474 21731
+f 3869 1099 2754
+f 17937 1272 17938
+f 8941 8814 8815
+f 21698 21685 16178
+f 9755 9683 9682
+f 21732 1866 1868
+f 20936 20935 21408
+f 19437 21647 21733
+f 13375 21635 16592
+f 1363 12293 4926
+f 6532 3708 10017
+f 18639 9065 9064
+f 20940 7268 7271
+f 14876 1552 1554
+f 5780 2997 2399
+f 21734 21500 21499
+f 9773 20930 18737
+f 21299 21504 21447
+f 21735 21627 21503
+f 9585 9625 9583
+f 21502 21735 21503
+f 21736 19523 20903
+f 21737 5511 21738
+f 1891 20890 1892
+f 20542 20504 21526
+f 21452 21451 21547
+f 21567 1896 21739
+f 14256 6438 16448
+f 21268 21740 21706
+f 21295 20218 20220
+f 21741 21742 21743
+f 21708 1755 1914
+f 15358 2411 499
+f 21744 6088 21347
+f 2905 9135 9137
+f 8632 8628 8756
+f 16099 16233 20374
+f 20959 5249 5251
+f 21043 21002 21044
+f 21466 21530 21065
+f 21002 21004 21044
+f 20788 20874 21338
+f 3147 9564 3148
+f 21745 21746 21747
+f 16178 3235 3237
+f 20975 20976 21008
+f 21748 21749 21750
+f 21751 19955 3236
+f 21752 8629 21753
+f 21754 21755 21756
+f 21757 14783 18774
+f 21758 21754 21759
+f 21755 21757 21760
+f 21761 21762 14339
+f 21755 21760 21756
+f 21763 21764 21765
+f 21754 21756 21759
+f 21743 14406 21707
+f 21045 21327 21329
+f 21766 21767 21768
+f 21769 21770 21771
+f 21451 21268 21706
+f 21772 21773 21294
+f 20995 21230 21232
+f 20809 1892 21149
+f 1698 3196 1699
+f 21192 21774 6639
+f 21348 9585 20788
+f 21775 21776 21777
+f 21627 2365 21525
+f 21503 21627 21525
+f 2365 5656 1367
+f 21525 2365 1367
+f 20906 6738 6737
+f 21033 8052 7958
+f 21690 21778 21691
+f 21399 21180 21179
+f 21057 21486 21040
+f 21170 21704 21779
+f 20453 20455 21263
+f 21420 20864 20820
+f 21780 21541 21460
+f 21781 19576 19578
+f 8703 8702 1985
+f 21441 21057 21040
+f 21486 21780 20934
+f 1638 19166 20910
+f 20994 21711 20995
+f 21164 21487 21314
+f 21481 21695 21782
+f 21783 21481 21782
+f 21340 21045 21169
+f 16169 2949 9188
+f 21784 21785 21786
+f 9647 9541 9540
+f 3770 3769 5729
+f 21787 20895 11346
+f 21266 13881 21588
+f 21697 21162 15382
+f 21788 11344 11346
+f 20895 21788 11346
+f 21789 21128 11344
+f 21788 21789 11344
+f 21789 21640 21128
+f 21008 21209 21425
+f 21640 21107 21128
+f 21641 21062 21107
+f 20845 21716 21183
+f 21783 21782 19300
+f 21135 20223 20216
+f 21154 8822 21603
+f 7120 11781 4212
+f 21580 21135 20216
+f 21492 7672 7671
+f 21790 18117 2703
+f 7154 7273 7270
+f 21550 21170 21779
+f 21791 5955 20997
+f 10712 14911 14974
+f 7768 8504 9971
+f 21482 20968 21322
+f 21582 20226 21580
+f 1567 1563 21792
+f 21793 201 178
+f 20226 21135 21580
+f 9649 21023 20782
+f 16836 21751 21019
+f 20985 19435 14967
+f 13375 16592 4640
+f 15742 19030 17037
+f 21794 15383 15382
+f 8502 8501 8696
+f 13006 12925 21762
+f 21423 21649 21316
+f 21795 21488 21395
+f 20956 8952 8943
+f 19433 19153 19112
+f 21357 20828 21796
+f 21131 21692 8048
+f 21294 21773 21582
+f 21494 21090 21089
+f 19435 20985 10250
+f 20219 21498 21406
+f 2898 2704 2699
+f 21334 3417 3225
+f 21797 21798 21799
+f 21398 21404 21800
+f 21801 21802 21803
+f 9792 9865 9868
+f 21804 21805 4813
+f 5530 5537 1723
+f 4955 21666 802
+f 21616 886 1419
+f 21806 21807 21808
+f 12320 21809 12321
+f 21810 6629 21811
+f 21812 21813 21814
+f 21340 9563 17198
+f 21815 18006 5904
+f 8718 8839 8726
+f 18568 7150 7051
+f 9792 9868 20417
+f 2352 7947 21171
+f 21816 21817 21818
+f 21368 21139 20847
+f 21813 21816 21819
+f 21819 21816 21818
+f 21817 21820 21821
+f 21814 21813 21819
+f 21822 21823 21824
+f 21818 21817 21821
+f 21820 21823 21822
+f 21825 18006 21815
+f 21821 21820 21822
+f 21823 21825 21824
+f 21807 21812 21808
+f 21824 21825 21815
+f 4170 4176 21826
+f 21827 21828 21829
+f 21767 21769 21771
+f 6699 7467 1175
+f 20884 21553 21736
+f 21830 21766 21831
+f 20863 20855 21298
+f 5403 21832 5261
+f 21195 21739 21833
+f 4212 4373 7120
+f 21181 21139 21368
+f 21834 2665 2667
+f 2891 2959 779
+f 19153 19433 19703
+f 21835 21036 8830
+f 20904 21421 20905
+f 5518 20816 1480
+f 17839 21836 12649
+f 6739 21537 6498
+f 21261 1893 21262
+f 15148 21837 21838
+f 18767 21839 18769
+f 20912 20877 20876
+f 21603 8822 21649
+f 21443 21445 19522
+f 21094 21053 21052
+f 14444 14361 14360
+f 8710 21390 8711
+f 21649 8822 6637
+f 4551 3838 11494
+f 5368 7273 6944
+f 1581 1583 1584
+f 20943 21557 20944
+f 1730 1734 1736
+f 21476 21281 19114
+f 19114 20181 2937
+f 1575 1574 12667
+f 21059 21318 21714
+f 3972 3979 3973
+f 21449 21205 21000
+f 21796 21485 7368
+f 3224 2175 21629
+f 4177 21354 20885
+f 7766 7767 12801
+f 9794 1564 1571
+f 21195 21567 21739
+f 21739 1896 21559
+f 21310 21350 21475
+f 21335 21267 21450
+f 18013 15603 15602
+f 21540 21604 21315
+f 13372 1015 13285
+f 21251 21165 21500
+f 808 13662 3701
+f 6739 21840 21538
+f 21537 6739 21538
+f 21840 21841 21539
+f 21538 21840 21539
+f 21841 21842 21554
+f 21539 21841 21554
+f 21842 21843 21555
+f 21554 21842 21555
+f 21843 21844 21556
+f 21555 21843 21556
+f 21678 21355 21190
+f 21844 21845 19434
+f 15602 16836 21019
+f 21316 20897 20951
+f 18767 20985 18750
+f 18750 14966 21846
+f 9743 10152 19391
+f 10101 10100 10180
+f 21847 1928 1927
+f 21032 7958 7957
+f 12643 12645 15148
+f 21505 21734 21499
+f 12460 18855 2151
+f 21556 21844 19434
+f 19434 21845 6522
+f 21398 21800 8511
+f 20992 20927 20862
+f 20255 21585 19637
+f 8511 8418 8562
+f 19435 19153 19436
+f 21350 21335 21450
+f 21334 3225 21267
+f 21848 21849 21798
+f 21850 21797 21799
+f 21851 21802 21801
+f 21852 21851 21801
+f 21853 21854 21855
+f 21854 21856 21855
+f 20987 20936 20880
+f 7370 7368 7477
+f 21857 21858 21859
+f 21808 21812 21814
+f 21860 21857 21861
+f 21862 21860 21861
+f 21863 21864 21865
+f 21866 21867 21868
+f 21864 21863 21520
+f 21519 21864 21520
+f 21869 21860 21862
+f 21864 21866 21865
+f 21865 21866 21868
+f 21870 21869 21862
+f 21867 21869 21870
+f 21868 21867 21870
+f 7566 6888 21871
+f 21872 3035 3037
+f 21873 3983 17501
+f 21551 19718 19719
+f 9662 4734 14384
+f 21316 21649 20897
+f 21858 21874 21875
+f 21875 21874 21876
+f 21861 21857 21859
+f 21859 21858 21875
+f 21877 21829 21878
+f 21879 21877 21878
+f 21880 5116 9739
+f 2997 5665 2998
+f 4514 21830 21881
+f 21766 21768 21831
+f 21092 21094 21712
+f 21008 20976 21209
+f 9881 9880 21376
+f 21325 21161 21326
+f 20849 21214 21882
+f 21883 1909 1911
+f 21257 21367 21369
+f 21074 21714 21207
+f 9075 9074 20908
+f 21845 21545 6522
+f 21703 21060 21779
+f 10280 19943 1358
+f 1481 1480 20816
+f 1339 21884 17456
+f 20874 20875 21338
+f 15601 16836 15602
+f 21885 3224 21886
+f 21244 21163 19521
+f 21885 21886 21740
+f 21268 21885 21740
+f 21887 21888 21889
+f 3224 21629 21886
+f 21888 21887 21890
+f 21891 19578 21021
+f 21737 5509 5511
+f 20786 21892 8520
+f 9291 21558 20834
+f 21180 21137 21181
+f 3028 3024 3240
+f 11251 2143 4099
+f 21892 20786 20785
+f 21893 21534 9945
+f 21534 21893 10170
+f 6353 21536 21851
+f 20933 6353 21851
+f 21536 14574 21802
+f 21851 21536 21802
+f 14574 1857 21894
+f 21802 14574 21894
+f 2830 3024 3028
+f 2738 2733 19115
+f 21122 21124 21278
+f 21309 21310 21511
+f 21350 21450 21475
+f 20818 21895 20819
+f 1346 42 1048
+f 21291 4959 4961
+f 5365 7063 20957
+f 21206 21018 18404
+f 16803 16805 16802
+f 21000 21896 21531
+f 1730 1736 1574
+f 21177 20878 21295
+f 21408 21407 21130
+f 20223 20222 21722
+f 21596 21055 21488
+f 21028 21030 21380
+f 20843 21897 20844
+f 20957 21235 21898
+f 20783 21022 20883
+f 18750 21839 18767
+f 2992 2175 2993
+f 21400 21471 18404
+f 7440 19605 19821
+f 20872 21492 21497
+f 20864 20863 20821
+f 9293 9397 21002
+f 10249 19112 10250
+f 12112 2462 16829
+f 10375 9593 8385
+f 21264 21265 20945
+f 21899 20844 21692
+f 20844 21693 21692
+f 20844 21897 21693
+f 3253 1864 3254
+f 21897 21900 21693
+f 21795 21596 21488
+f 21355 20787 21190
+f 16795 8931 14743
+f 1864 13975 1865
+f 21797 21848 21798
+f 21335 21334 21267
+f 21331 21901 21902
+f 21848 21903 21904
+f 21905 21906 21856
+f 21802 21894 21803
+f 21856 21907 21908
+f 21854 21905 21856
+f 5972 6088 20953
+f 21504 21448 21447
+f 21909 21910 21911
+f 21695 21182 21384
+f 21225 19704 21912
+f 20964 20224 21773
+f 21913 21914 21915
+f 9886 9799 21916
+f 21917 21915 21918
+f 21919 21917 21918
+f 21035 21105 21145
+f 21919 21918 21920
+f 8835 21106 3988
+f 21920 21921 21922
+f 21397 21774 21713
+f 3709 5664 7053
+f 9539 9540 9468
+f 21923 21924 19626
+f 21925 21926 21927
+f 21204 8756 8628
+f 7270 7268 7269
+f 21256 21179 21367
+f 9798 9803 8049
+f 21193 21705 21709
+f 3452 3156 17013
+f 1409 14300 14757
+f 21928 21929 21930
+f 21929 21879 21878
+f 21931 8797 2328
+f 12257 21932 5390
+f 14919 10142 14503
+f 21933 21934 21935
+f 2510 21936 2511
+f 17306 17305 21219
+f 5251 8485 20959
+f 20225 20221 21135
+f 10172 10174 10096
+f 10153 15568 10154
+f 21073 21072 21075
+f 21442 20258 21053
+f 21937 21133 21134
+f 5514 5369 1366
+f 20888 21691 20718
+f 20787 20789 21191
+f 15135 15929 4369
+f 21214 21752 21882
+f 21938 21092 21712
+f 1923 1915 1921
+f 8932 21939 8933
+f 21940 21585 21584
+f 21742 14406 21743
+f 21767 21771 21768
+f 21941 21742 21741
+f 21942 21941 21741
+f 21943 21941 21942
+f 21944 21943 21942
+f 21945 21946 21947
+f 21948 21943 21944
+f 21949 21904 21945
+f 21947 21948 21944
+f 21950 21849 21949
+f 21946 21948 21947
+f 21798 21849 21951
+f 21904 21946 21945
+f 21799 21798 21952
+f 21849 21904 21949
+f 21769 21799 21770
+f 21849 21950 21951
+f 21799 21952 21770
+f 21798 21951 21952
+f 20933 21851 21852
+f 21953 20933 21852
+f 21903 21954 21946
+f 21904 21903 21946
+f 21306 21309 6482
+f 21310 21475 21511
+f 17414 18404 21146
+f 5267 4507 12320
+f 21722 21446 20904
+f 1721 1896 1895
+f 21900 21897 8482
+f 21897 20960 8482
+f 21633 19302 21429
+f 5957 21242 7228
+f 20941 21955 20890
+f 21403 21399 21428
+f 20957 21898 21149
+f 21493 21577 21174
+f 20830 20887 21050
+f 21956 21957 2828
+f 21448 21499 21203
+f 19168 19890 9526
+f 10327 14500 16771
+f 2937 20181 2936
+f 3225 21885 21268
+f 10250 18767 10248
+f 21377 21958 21378
+f 21715 21374 21373
+f 2897 3217 21959
+f 8724 20904 8725
+f 19880 20454 20290
+f 14359 19880 20290
+f 19787 10015 10089
+f 20996 21542 21960
+f 9074 9294 21102
+f 12642 20889 21275
+f 7156 7068 21426
+f 9294 9291 20834
+f 20910 20752 1634
+f 2704 2539 2699
+f 21961 21519 21521
+f 4798 21291 4799
+f 3975 3977 3979
+f 4483 5311 3652
+f 8498 8598 8499
+f 21849 21848 21904
+f 15681 16786 1723
+f 5269 21664 5266
+f 20711 9974 9596
+f 21962 21963 21906
+f 21964 21965 21966
+f 21855 21908 21967
+f 21910 21821 21968
+f 21969 21970 21971
+f 21972 21973 21974
+f 21975 21909 21976
+f 21977 5616 4628
+f 10955 4953 9308
+f 21978 16743 21979
+f 4632 19713 21291
+f 21326 21162 21697
+f 21980 21981 21982
+f 21983 21984 21985
+f 5678 4948 16003
+f 802 1419 803
+f 21986 21983 21985
+f 21986 21985 21459
+f 21987 21986 21459
+f 21988 21989 21990
+f 21991 21992 21984
+f 21983 21991 21984
+f 21993 21990 21992
+f 21993 21988 21990
+f 21991 21993 21992
+f 21713 21193 21709
+f 21994 21995 21989
+f 13881 13880 21588
+f 21996 21183 21676
+f 21997 21929 21878
+f 21998 21999 22000
+f 6082 22001 6081
+f 21929 21997 21930
+f 21830 21831 21881
+f 22002 22003 22004
+f 22005 22006 15683
+f 19055 19056 22007
+f 21367 21181 21368
+f 22008 16409 5676
+f 8943 8952 8941
+f 22009 8630 21550
+f 9585 9584 20874
+f 22010 22011 22012
+f 21434 21238 21237
+f 20982 20983 21323
+f 19891 19890 19168
+f 20997 20996 22013
+f 22014 21766 21830
+f 21217 21186 21716
+f 21071 22009 21072
+f 21833 22014 21830
+f 674 8629 21752
+f 21736 20903 21715
+f 21430 21489 21441
+f 1564 21850 1565
+f 21916 21996 21676
+f 1563 1571 1564
+f 13966 21445 21443
+f 21254 19955 21751
+f 22015 21402 20915
+f 14144 1012 1023
+f 15829 15951 20331
+f 22016 22015 20915
+f 16831 22015 22016
+f 16546 16831 22016
+f 22017 22018 22019
+f 9570 9576 20976
+f 15425 21325 14867
+f 2327 2326 5541
+f 22020 6239 5973
+f 11632 17230 1946
+f 21660 3021 22021
+f 22022 22023 22024
+f 20785 20933 21953
+f 22025 20785 21953
+f 21954 1582 21948
+f 21946 21954 21948
+f 6898 1116 5304
+f 21309 21511 6482
+f 22026 20366 17623
+f 4349 4171 21305
+f 20854 20858 21233
+f 21279 21278 21093
+f 14351 6200 6199
+f 19880 20956 20913
+f 9688 6483 21728
+f 22027 22028 22029
+f 22030 5734 5736
+f 21045 21329 21169
+f 21437 21266 21588
+f 21304 3974 21320
+f 3217 21598 21959
+f 21553 19523 21736
+f 20712 9874 20713
+f 10982 20941 20890
+f 21331 21902 21332
+f 5110 22031 21330
+f 21075 21074 21207
+f 4507 5406 3036
+f 16340 19169 19121
+f 12232 2920 5353
+f 20857 20856 21116
+f 21053 20258 20990
+f 21505 21499 21448
+f 21089 21091 21394
+f 20875 21133 21937
+f 21184 21187 22032
+f 20873 21497 20827
+f 22033 22034 21513
+f 14409 22035 22036
+f 22037 22038 22039
+f 22033 22040 22034
+f 21936 22041 22042
+f 1744 22043 22044
+f 9397 21003 21002
+f 21420 20820 20824
+f 21494 20998 21090
+f 21205 21147 21896
+f 8815 1985 18641
+f 21373 21375 20948
+f 19693 19695 19703
+f 21546 21373 20948
+f 8953 8945 8941
+f 20941 5367 21955
+f 15411 22045 22046
+f 16548 22047 16725
+f 20872 21132 21492
+f 1724 22048 1725
+f 21361 22049 22050
+f 10076 9500 8699
+f 5502 15275 1699
+f 21664 5797 5266
+f 22051 21964 22052
+f 12666 22053 21811
+f 21822 21824 22054
+f 21965 21855 21967
+f 22055 22056 21972
+f 21968 21822 22054
+f 9568 9571 17197
+f 21974 21975 21976
+f 22057 22058 22059
+f 22060 21957 22061
+f 17293 16063 16127
+f 22059 22062 22063
+f 20870 20867 21422
+f 20952 20962 5249
+f 22064 6245 6244
+f 12707 22065 20916
+f 11152 21847 1784
+f 1982 1899 5937
+f 9874 9872 20713
+f 21448 21203 21449
+f 22066 21847 11152
+f 22067 22066 11152
+f 22068 22066 22067
+f 22069 22068 22067
+f 21911 22070 22071
+f 22071 22070 22069
+f 21994 22072 21995
+f 22073 22074 22075
+f 21705 20909 21036
+f 20987 20880 20879
+f 22076 21998 22000
+f 21930 22077 21999
+f 22000 22078 22076
+f 21928 21930 21998
+f 21287 5106 22079
+f 19243 19242 4962
+f 17074 3050 14931
+f 22080 22081 22082
+f 4514 4513 21196
+f 22083 22084 17183
+f 21431 20256 21442
+f 21431 21073 20256
+f 7365 21796 7368
+f 3474 14359 7227
+f 21426 21724 21186
+f 20845 21217 21716
+f 1565 21769 21767
+f 20853 20984 20854
+f 21166 6496 6498
+f 3964 5518 1899
+f 14209 14208 22085
+f 2173 2513 2174
+f 18683 21956 12763
+f 22086 22051 22087
+f 22088 22089 21806
+f 21939 8932 14979
+f 22090 22091 22088
+f 22089 21807 21806
+f 22092 22093 22090
+f 22091 22089 22088
+f 22093 22092 22094
+f 22095 22093 22094
+f 22095 22094 22096
+f 22093 22091 22090
+f 22097 22098 22096
+f 22098 22095 22096
+f 21827 22097 21970
+f 21970 22097 22096
+f 21877 21827 21829
+f 21828 21827 21970
+f 4170 4169 4168
+f 21682 21681 21264
+f 21905 21962 21906
+f 22099 22100 21963
+f 8520 21892 22101
+f 21892 20785 22025
+f 1582 22102 21943
+f 21948 1582 21943
+f 3325 18624 3324
+f 4507 3035 12320
+f 4171 21307 21305
+f 21305 2178 4348
+f 21467 20989 20258
+f 21826 21308 21307
+f 21916 21676 21958
+f 21117 20841 21633
+f 21683 21772 21294
+f 16413 1097 18522
+f 21531 21896 8519
+f 8521 21896 21147
+f 5367 5366 21955
+f 21773 20226 21582
+f 14438 836 16955
+f 21899 21692 21131
+f 2937 2738 19115
+f 12642 10982 20889
+f 9501 1552 9600
+f 6294 9255 7007
+f 20415 20414 20461
+f 10098 10027 10026
+f 9595 19943 20711
+f 8953 8952 9283
+f 21187 21725 22103
+f 673 21340 21176
+f 20960 22104 20959
+f 21384 21184 22032
+f 21725 21882 22105
+f 22032 21187 22103
+f 22106 22033 22107
+f 21512 22107 21513
+f 22108 22040 22033
+f 22106 22108 22033
+f 22109 22043 22040
+f 22108 22109 22040
+f 20885 21261 21260
+f 16681 16680 22109
+f 21001 21531 21533
+f 22110 22111 16334
+f 8513 21391 21393
+f 21091 21127 21596
+f 21127 21632 21597
+f 20835 20964 21772
+f 21061 21632 21127
+f 15221 15220 4810
+f 7063 6944 15448
+f 18013 21388 22112
+f 1892 20958 21149
+f 12799 3509 19337
+f 21470 21206 18404
+f 6259 16883 16243
+f 20329 21095 22113
+f 1101 3131 1175
+f 21665 4954 4953
+f 22087 22051 22114
+f 22115 12536 2335
+f 21824 21815 22116
+f 21965 21967 21966
+f 22117 22056 22118
+f 22054 21824 22116
+f 18874 12105 5510
+f 21973 21975 21974
+f 22119 22120 22057
+f 20718 21227 20719
+f 21990 21989 22121
+f 22062 22122 22063
+f 21990 22121 22123
+f 21992 21990 22123
+f 21995 22124 22125
+f 21989 22125 22121
+f 22075 22074 22126
+f 21989 21995 22125
+f 22075 22126 22124
+f 22127 22128 22129
+f 21995 22075 22124
+f 22074 22129 22126
+f 22074 22127 22129
+f 22127 22130 22131
+f 21984 21992 22132
+f 22128 22127 22131
+f 22133 21911 22071
+f 22070 22068 22069
+f 22072 22073 22075
+f 21976 21911 22133
+f 21298 21504 21299
+f 21521 22127 22074
+f 21998 21930 21999
+f 22134 22135 15287
+f 22136 21928 21998
+f 21997 22137 22077
+f 22138 8797 21931
+f 13880 11017 21587
+f 3727 14847 22139
+f 22140 22141 17881
+f 4514 21881 22142
+f 2663 2662 2506
+f 21833 21830 4514
+f 21197 21196 4513
+f 22014 21792 21766
+f 21196 21833 4514
+f 21850 21799 21769
+f 21792 1565 21767
+f 21898 21575 22143
+f 1565 21850 21769
+f 22086 22144 22051
+f 6656 21924 21923
+f 21625 22145 22146
+f 22147 21965 21964
+f 21344 21665 10954
+f 10954 4953 10955
+f 2469 2643 5105
+f 8359 9946 8360
+f 22148 15676 15678
+f 15680 16786 15681
+f 3022 221 10584
+f 5674 2469 5105
+f 22021 3022 10584
+f 22149 22150 22151
+f 20815 22152 21726
+f 1324 3324 18684
+f 2352 21171 20465
+f 15286 22134 15287
+f 22153 2565 10179
+f 2655 10226 10179
+f 14938 13931 13930
+f 21605 22154 22155
+f 20987 21441 20936
+f 5620 3452 17013
+f 21962 22099 21963
+f 20939 21010 20218
+f 22156 21892 22025
+f 22157 22158 22100
+f 22102 22159 21941
+f 2176 8520 22157
+f 21306 6482 6484
+f 21943 22102 21941
+f 12767 5122 2838
+f 21330 21332 22160
+f 4171 21826 21307
+f 1635 22161 2127
+f 21826 21303 21308
+f 21303 21372 21308
+f 21303 21320 21372
+f 21320 21349 21372
+f 22162 22163 22164
+f 3974 21333 21349
+f 21320 3974 21349
+f 22163 9800 22164
+f 3973 21351 21333
+f 3974 3973 21333
+f 14747 14151 14150
+f 1638 757 19165
+f 16579 15989 16577
+f 16314 22165 16632
+f 20257 21467 20258
+f 22166 15359 15287
+f 20785 3228 20933
+f 22159 1591 21883
+f 15393 20713 21534
+f 7262 7153 7258
+f 8630 22009 8631
+f 20852 21678 21024
+f 21272 21894 1857
+f 22167 22106 22168
+f 22169 22168 21512
+f 22170 22108 22106
+f 22167 22170 22106
+f 22171 22109 22108
+f 22170 22171 22108
+f 22172 16681 22171
+f 22171 16681 22109
+f 21126 21061 21127
+f 21778 21463 21532
+f 21691 21778 21532
+f 20903 22173 21374
+f 3581 7445 21518
+f 20824 20973 20825
+f 21118 21633 22174
+f 3035 21872 21809
+f 21600 21388 21606
+f 8822 21154 8823
+f 21327 21007 21328
+f 18012 21206 21470
+f 22175 22176 22177
+f 1916 21095 20329
+f 5402 22178 5403
+f 16800 16799 22179
+f 22085 22087 22180
+f 21832 22008 5261
+f 21815 5904 1928
+f 21964 21966 22052
+f 22181 22117 22182
+f 22116 21815 1928
+f 22135 22166 15287
+f 22056 21973 21972
+f 22183 22184 22185
+f 22166 22186 15413
+f 22187 22060 22188
+f 22058 22062 22059
+f 22189 21937 21046
+f 22190 22187 22188
+f 22191 17259 17258
+f 17236 22192 22193
+f 22194 22191 22195
+f 17818 17259 21914
+f 22196 22197 22198
+f 22191 17258 22195
+f 21103 21772 21683
+f 22199 18375 16978
+f 21719 21873 22200
+f 22201 22194 22195
+f 21985 21984 22132
+f 8819 10585 8820
+f 22202 21300 20942
+f 21992 22123 22132
+f 15359 22166 15413
+f 12767 2838 15085
+f 22203 21976 22133
+f 6638 9072 9075
+f 22073 21521 22074
+f 22204 21974 22203
+f 20454 19880 20913
+f 21520 22130 22127
+f 21930 21997 22077
+f 17198 9563 9568
+f 22136 21998 22076
+f 21997 21878 22205
+f 22206 22207 22208
+f 9550 21436 21435
+f 18798 9873 9875
+f 22209 22210 4887
+f 20828 21485 21796
+f 21550 21779 21074
+f 8631 22009 21071
+f 21123 8631 21071
+f 21645 20965 20964
+f 21149 21898 22143
+f 22211 22212 22213
+f 21710 21711 20994
+f 21952 21827 21877
+f 22214 20179 22215
+f 21768 21771 21929
+f 21770 21952 21877
+f 21770 21877 21879
+f 21771 21770 21879
+f 21951 22097 21827
+f 21952 21951 21827
+f 21949 21945 22093
+f 17885 11541 22216
+f 21951 21950 22097
+f 22095 21949 22093
+f 20961 11631 22153
+f 21950 21949 22095
+f 3363 3365 218
+f 22217 22218 22219
+f 21971 22220 22221
+f 22186 22222 15452
+f 8120 8121 4956
+f 22223 22224 22225
+f 21429 20830 21050
+f 21233 21734 21505
+f 22094 22220 21971
+f 21546 20948 20947
+f 7768 7770 8504
+f 22096 22094 21971
+f 22099 22157 22100
+f 21312 22226 21313
+f 21892 22156 22101
+f 22101 22227 22158
+f 22159 21883 21742
+f 2177 2176 22099
+f 1913 1755 14405
+f 21941 22159 21742
+f 22228 17278 22229
+f 21742 21883 14406
+f 4653 4802 4654
+f 4494 6086 4495
+f 1319 1318 2242
+f 1319 2242 1445
+f 22230 6802 17884
+f 886 3405 1182
+f 22231 22232 22233
+f 1419 886 1182
+f 22234 22235 22236
+f 6899 6802 22230
+f 10955 9308 10097
+f 22237 6899 22230
+f 21272 21136 21894
+f 21462 20842 21899
+f 20417 9870 21023
+f 21163 21244 21022
+f 22238 46 22239
+f 19762 21313 19763
+f 21007 21008 21424
+f 16146 15742 17037
+f 21293 21722 8724
+f 22168 6543 6542
+f 22240 22167 6542
+f 22241 22240 6542
+f 22242 22170 22167
+f 22240 22242 22167
+f 22243 22171 22170
+f 22242 22243 22170
+f 10018 3775 12398
+f 22243 22172 22171
+f 21374 22173 21570
+f 11494 10994 4551
+f 22104 5249 20959
+f 20834 21645 20835
+f 20824 20820 20973
+f 21007 21650 21328
+f 22244 2314 2316
+f 21200 21274 7150
+f 10228 12378 10153
+f 21356 20826 20828
+f 21096 21404 21398
+f 21606 18012 21470
+f 1946 17230 22245
+f 21381 8510 21800
+f 21436 21266 21437
+f 18509 6263 14445
+f 22246 21987 22247
+f 22248 22249 15232
+f 15413 22186 15452
+f 22051 22052 22114
+f 22250 22181 22251
+f 8953 9160 9066
+f 22222 22252 15457
+f 22056 22055 22118
+f 22253 22183 22185
+f 15452 22222 15457
+f 22254 6255 6254
+f 22183 22120 22119
+f 20221 20995 20222
+f 18683 22061 21956
+f 22255 22256 22257
+f 21323 21595 21125
+f 22258 22259 22260
+f 22261 22257 22262
+f 22261 22255 22257
+f 22259 22261 22262
+f 22255 22263 22256
+f 22263 22264 22256
+f 22258 22260 22265
+f 22259 22262 22260
+f 12667 1584 1583
+f 8952 14304 9283
+f 10021 7747 4077
+f 15147 22266 6375
+f 19530 20716 14521
+f 21142 19885 19886
+f 18108 21664 4959
+f 8401 3313 1377
+f 16412 18116 18115
+f 6263 21509 14445
+f 16095 16094 17216
+f 1881 22007 1882
+f 11469 9264 22267
+f 2329 10948 22268
+f 9825 9972 9906
+f 21117 21633 21118
+f 22137 21997 22205
+f 21829 22269 22205
+f 1615 22115 2335
+f 22270 21098 21834
+f 22271 22272 22273
+f 17881 17880 18874
+f 14208 22086 22087
+f 14208 22087 22085
+f 22144 22147 21964
+f 22144 21964 22051
+f 22147 21853 21965
+f 21853 21855 21965
+f 10648 9063 9065
+f 21940 20929 21699
+f 21651 21652 22015
+f 20613 10648 9065
+f 21518 21651 22015
+f 21652 21400 21402
+f 16831 21518 22015
+f 21652 21402 22015
+f 6823 9651 22274
+f 21950 22098 22097
+f 2121 16715 14459
+f 21945 21947 22091
+f 1586 1588 1589
+f 12667 1583 21954
+f 22098 21950 22095
+f 1575 12667 21903
+f 5379 5863 2852
+f 22093 21945 22091
+f 22252 20018 15462
+f 2175 3224 2993
+f 21969 21971 22221
+f 9803 9798 9884
+f 21988 21994 21989
+f 22122 21969 22221
+f 20819 21895 21396
+f 22072 22075 21995
+f 22092 22223 22220
+f 21777 21737 21738
+f 15457 22252 15462
+f 22094 22092 22220
+f 22157 22101 22158
+f 22275 3023 21874
+f 8520 22101 22157
+f 22101 22156 22276
+f 21629 2177 21962
+f 2176 22157 22099
+f 20816 20815 21726
+f 21629 21962 21905
+f 21666 21616 802
+f 8598 1916 20329
+f 21012 4179 20906
+f 9579 9459 13477
+f 21134 21100 21199
+f 22277 4449 16757
+f 20946 21599 21598
+f 21201 8720 21581
+f 21179 21181 21367
+f 21577 20876 21174
+f 14209 22085 20369
+f 21699 9975 9829
+f 22278 22279 22280
+f 4968 5119 5811
+f 21931 2328 21271
+f 20420 17487 17489
+f 16334 22281 16212
+f 22282 10953 22283
+f 21299 21447 21487
+f 21252 22284 4188
+f 20822 21299 21487
+f 22285 15237 22241
+f 22241 6541 12837
+f 22286 22240 22241
+f 15237 22286 22241
+f 22287 22242 22240
+f 22286 22287 22240
+f 22288 22243 22242
+f 22287 22288 22242
+f 22289 22172 22243
+f 22288 22289 22243
+f 21339 21229 22290
+f 16001 16621 1271
+f 7148 18568 7051
+f 19880 14363 20956
+f 19200 471 6824
+f 1744 1743 22040
+f 21779 21060 21714
+f 21074 21779 21714
+f 20965 21405 20224
+f 21369 20846 21231
+f 9469 9540 9542
+f 21196 21195 21833
+f 21102 20833 21103
+f 21095 21096 22113
+f 9339 20055 7445
+f 1945 11632 1946
+f 20018 20019 15524
+f 22076 22291 22136
+f 22023 22022 22177
+f 559 15675 22292
+f 20053 17242 22293
+f 7364 21796 7365
+f 22087 22114 22180
+f 22223 22250 22224
+f 15462 20018 15524
+f 21232 20868 21446
+f 22117 22118 22182
+f 22184 22183 22119
+f 20222 21232 21446
+f 1572 1573 1574
+f 22120 22058 22057
+f 21131 8048 21132
+f 20019 22294 15851
+f 22067 11152 11151
+f 20902 21220 21479
+f 22295 22296 22297
+f 22298 22067 11151
+f 15524 20019 15851
+f 22296 22299 22300
+f 22294 22301 15967
+f 7365 12508 7363
+f 22302 22188 22303
+f 10968 5381 6041
+f 22304 22265 22305
+f 22304 22258 22265
+f 1574 1573 1730
+f 1587 1586 22102
+f 5533 22306 20019
+f 22307 22308 22309
+f 20928 20853 20855
+f 9881 21376 13966
+f 2333 2183 6239
+f 22310 22311 22312
+f 21913 18093 21914
+f 21377 21916 21958
+f 6636 6497 6496
+f 2244 14015 15567
+f 20878 20939 20218
+f 3974 21304 3972
+f 22313 18989 18245
+f 9876 9877 9879
+f 21878 21829 22205
+f 21577 20912 20876
+f 22178 21832 5403
+f 21828 22314 22269
+f 10227 2657 2493
+f 2494 2496 2495
+f 15851 22294 15967
+f 18549 18581 13210
+f 22016 20914 16322
+f 21312 19980 22226
+f 21564 9550 21435
+f 21204 9019 8756
+f 22315 22020 5973
+f 8569 8499 8598
+f 21781 19578 21891
+f 22316 6371 2240
+f 5955 20980 20997
+f 5904 1926 1928
+f 8445 8271 8357
+f 22301 22317 16064
+f 17258 22318 22319
+f 20956 21366 8952
+f 19955 19954 3237
+f 9868 9870 20417
+f 15967 22301 16064
+f 22320 9599 22321
+f 21848 1575 21903
+f 21903 12667 21954
+f 21947 21944 22089
+f 22091 21947 22089
+f 10179 10226 20961
+f 22016 20915 20914
+f 638 9652 639
+f 21678 21190 21024
+f 22220 22225 22221
+f 22314 21969 22122
+f 21521 21520 22127
+f 21130 21132 20872
+f 20966 9542 9541
+f 21520 21863 22322
+f 22090 22250 22223
+f 20951 20897 20898
+f 21858 22275 21874
+f 22092 22090 22223
+f 22227 22101 22276
+f 21857 22323 21858
+f 22276 22156 22324
+f 22156 22025 22324
+f 21886 21629 21905
+f 2177 22099 21962
+f 21886 21905 21854
+f 21740 21886 21854
+f 21740 21854 21853
+f 21706 21740 21853
+f 21706 21853 22147
+f 21547 21706 22147
+f 21547 22147 22144
+f 21548 21547 22144
+f 21549 22086 14208
+f 14210 21549 14208
+f 21548 22144 22086
+f 21549 21548 22086
+f 1472 12801 1473
+f 21557 21264 20945
+f 21895 22325 21396
+f 5539 16888 21660
+f 10170 21893 19787
+f 8942 8815 18641
+f 20454 20453 12777
+f 19844 19642 22326
+f 9376 1770 13661
+f 3797 4192 3985
+f 8754 3816 4462
+f 9447 9446 12746
+f 22327 22286 15237
+f 15239 22327 15237
+f 22328 22287 22286
+f 22327 22328 22286
+f 22329 22288 22287
+f 22328 22329 22287
+f 22330 22289 22288
+f 22329 22330 22288
+f 2601 17851 2600
+f 22330 22313 22289
+f 21571 21938 21478
+f 20329 22113 8569
+f 22317 22331 16629
+f 16064 22317 16629
+f 7227 21731 3474
+f 16848 12370 21735
+f 12371 21627 21735
+f 21422 20867 21577
+f 12370 12371 21735
+f 22331 22332 16992
+f 21405 21710 20994
+f 7135 6429 7136
+f 21559 22014 21833
+f 3021 3022 22021
+f 10145 10147 12377
+f 21881 21831 21928
+f 9619 17015 22245
+f 22333 22138 21931
+f 22136 21881 21928
+f 21691 21532 21227
+f 22085 22180 22246
+f 22220 22223 22225
+f 21570 19300 20841
+f 21597 21604 21056
+f 22181 22182 22251
+f 22212 22334 22213
+f 8445 8357 5522
+f 1927 1784 21847
+f 22335 22253 22336
+f 21220 21480 21479
+f 17101 16848 16849
+f 19891 19168 18548
+f 8050 21217 20845
+f 22295 22337 22338
+f 20180 21551 19719
+f 22126 22129 22339
+f 22337 22295 22297
+f 22124 22126 22340
+f 22129 22341 22339
+f 5517 3182 3386
+f 22126 22339 22340
+f 21083 16090 17762
+f 22342 14147 14779
+f 17807 21688 22343
+f 22344 22304 22305
+f 22345 17365 16833
+f 21558 9291 9293
+f 9308 4955 801
+f 16833 16650 22345
+f 10089 10164 10167
+f 12047 13488 8652
+f 180 9915 181
+f 18657 2099 2098
+f 11468 13812 218
+f 20995 21232 20222
+f 21907 22072 21994
+f 21908 21907 21994
+f 21908 21994 21988
+f 21967 21908 21988
+f 21967 21988 21993
+f 21966 21967 21993
+f 21966 21993 21991
+f 22052 21966 21991
+f 21829 21828 22269
+f 13976 15209 21277
+f 21828 21970 21969
+f 22314 21828 21969
+f 15951 1023 20331
+f 21970 22096 21971
+f 21807 21942 21812
+f 15562 16626 1270
+f 14585 22346 14586
+f 21741 21743 21813
+f 22347 6823 22274
+f 22348 5632 16725
+f 20945 21599 20946
+f 16629 22331 16992
+f 21664 5269 4960
+f 5366 20958 1892
+f 6588 6591 22349
+f 15147 14351 22266
+f 21214 674 21752
+f 6087 6368 12455
+f 21176 8630 8629
+f 22350 15238 22351
+f 22352 19762 19761
+f 3005 3007 14866
+f 9794 21797 21850
+f 21533 21531 8518
+f 22089 21944 21807
+f 21944 21942 21807
+f 22153 10179 20961
+f 20223 21722 21293
+f 22332 22353 17106
+f 21460 21462 20935
+f 22062 22314 22122
+f 22269 22314 22062
+f 21920 21918 22194
+f 22195 22354 22201
+f 22130 21520 22322
+f 22355 21862 22356
+f 2661 3207 9108
+f 8839 20217 8840
+f 22088 22181 22250
+f 21808 21814 21973
+f 21869 22324 21860
+f 22357 22323 21857
+f 22025 21953 22357
+f 22324 22025 22357
+f 22357 21953 22323
+f 21953 21852 22323
+f 21852 21801 22275
+f 22323 21852 22275
+f 22275 21801 3023
+f 21801 21803 3023
+f 16992 22332 17106
+f 2196 1696 7947
+f 21792 21767 21766
+f 20835 21645 20964
+f 21004 21255 21710
+f 21578 21493 19551
+f 20455 20913 8942
+f 22353 22358 17262
+f 21374 21570 21375
+f 21054 20974 20969
+f 21855 21856 21908
+f 21906 22359 21907
+f 9600 1552 14875
+f 17106 22353 17262
+f 21417 20824 20823
+f 22360 9567 22361
+f 21461 21317 20950
+f 21482 21052 20968
+f 3749 5778 1979
+f 22358 22362 17372
+f 22363 22364 22327
+f 15239 22363 22327
+f 22364 22365 22328
+f 22327 22364 22328
+f 22365 22366 22329
+f 22328 22365 22329
+f 22366 22367 22330
+f 22329 22366 22330
+f 18989 22313 22330
+f 22367 18989 22330
+f 20783 20883 20882
+f 18245 18988 5752
+f 12371 12367 5650
+f 21604 21540 21056
+f 22368 22369 22370
+f 5794 5800 5795
+f 21773 20224 20226
+f 21896 8522 8519
+f 21317 21316 20951
+f 21406 21379 21404
+f 22325 21394 21396
+f 21418 21490 21682
+f 3024 21803 21136
+f 21044 21004 21710
+f 21768 21929 21928
+f 17230 6139 22245
+f 1575 21848 21797
+f 21831 21768 21928
+f 17262 22358 17372
+f 22371 22372 22373
+f 22077 22253 22335
+f 21019 21751 21020
+f 20898 21397 20962
+f 22250 22251 22224
+f 22374 22212 22211
+f 11017 1947 1614
+f 17945 16464 22375
+f 22334 22214 22376
+f 22362 22377 17457
+f 21595 8576 21126
+f 19694 20151 19719
+f 17372 22362 17457
+f 22378 22379 22380
+f 9680 9681 9584
+f 21135 20221 20223
+f 22381 22295 22338
+f 13982 7031 14566
+f 22123 22121 16279
+f 16624 15979 14942
+f 9886 9880 9883
+f 16623 22382 16332
+f 16624 16623 16332
+f 22382 22383 15482
+f 16332 22382 15482
+f 22383 22384 22385
+f 15482 22383 22385
+f 22384 22386 15854
+f 22385 22384 15854
+f 22386 22387 15855
+f 15854 22386 15855
+f 22388 16053 15855
+f 22387 22388 15855
+f 22389 2098 16053
+f 22388 22389 16053
+f 305 15591 424
+f 22389 18657 2098
+f 19305 19304 22390
+f 15539 16617 22391
+f 20830 20829 20887
+f 21598 21357 21959
+f 21774 21193 21713
+f 21541 21315 21317
+f 20823 20825 20990
+f 22392 21584 21583
+f 19579 9910 15357
+f 8569 22113 8562
+f 18093 17786 22393
+f 21383 5940 6844
+f 21743 21707 21816
+f 21760 17785 17784
+f 21490 21489 21681
+f 21812 21741 21813
+f 19821 16142 7440
+f 21489 21057 21441
+f 9499 4592 6147
+f 20851 21678 20852
+f 22105 21753 21463
+f 461 22215 459
+f 21499 9019 21203
+f 22163 12546 12461
+f 16716 13526 17226
+f 20932 20711 10280
+f 18510 19318 19473
+f 1914 1915 1923
+f 22394 21568 13051
+f 14061 20182 20183
+f 22395 21312 19762
+f 19951 22352 19761
+f 3432 20941 10982
+f 21380 21392 21391
+f 21707 21708 21817
+f 21942 21741 21812
+f 1722 1721 1895
+f 22102 1582 1587
+f 19153 19435 10250
+f 20940 7271 5367
+f 22058 22269 22062
+f 22205 22269 22058
+f 21915 22191 22194
+f 21918 21915 22194
+f 21861 21859 22396
+f 22118 22261 22259
+f 22377 22397 17544
+f 21870 21862 22398
+f 22056 21808 21973
+f 21233 21273 21734
+f 21860 22357 21857
+f 22181 22088 22117
+f 22324 22357 21860
+f 22323 22275 21858
+f 22276 22324 21869
+f 21867 22276 21869
+f 22227 22276 21867
+f 21866 22227 21867
+f 22158 22227 21866
+f 21864 22158 21866
+f 22158 21864 21519
+f 22100 22158 21519
+f 21963 21961 22359
+f 21906 21963 22359
+f 21856 21906 21907
+f 22100 21519 21961
+f 18993 16929 22399
+f 20465 15571 22400
+f 16929 18993 16930
+f 22399 18991 18993
+f 21963 22100 21961
+f 18991 18116 18962
+f 10172 10168 5952
+f 9950 10175 10026
+f 10174 10094 10096
+f 22348 16725 22401
+f 21599 20993 21356
+f 20951 20898 20952
+f 22402 22403 22363
+f 21506 8129 21507
+f 22403 22404 22364
+f 22363 22403 22364
+f 22404 22405 22365
+f 22364 22404 22365
+f 22405 22406 22366
+f 22365 22405 22366
+f 22407 22367 22366
+f 22406 22407 22366
+f 18990 18989 22367
+f 22407 18990 22367
+f 5752 18988 18945
+f 16462 16710 16709
+f 20930 9773 9974
+f 22178 5402 2341
+f 21780 21540 21541
+f 7671 21497 21492
+f 20848 21546 20947
+f 20219 21039 21498
+f 8510 8419 8511
+f 21938 21712 21478
+f 21208 21466 21467
+f 21328 21650 21703
+f 20943 20942 21557
+f 21803 3024 3023
+f 21063 19981 22408
+f 21064 21063 22408
+f 17457 22377 17544
+f 6840 6942 6841
+f 1926 5904 12300
+f 21817 21708 21820
+f 21771 21879 21929
+f 4171 4170 21826
+f 21954 1583 1582
+f 13966 21376 21378
+f 8629 8631 21753
+f 21999 22335 22409
+f 22000 21999 22409
+f 22397 6796 17546
+f 8932 14980 14979
+f 22105 21882 21753
+f 22375 22374 22211
+f 19524 8574 8573
+f 17214 17213 22410
+f 1081 2187 925
+f 22213 22334 22376
+f 9168 21031 14514
+f 18402 17414 17413
+f 5535 5534 17204
+f 22381 22338 22411
+f 7470 17290 7468
+f 17544 22397 17546
+f 15565 22412 17290
+f 15479 17290 16623
+f 22412 22413 16623
+f 17290 22412 16623
+f 22413 22414 22382
+f 16623 22413 22382
+f 22414 22415 22383
+f 22382 22414 22383
+f 22415 22416 22384
+f 22383 22415 22384
+f 22416 22417 22386
+f 22384 22416 22386
+f 22417 22418 22387
+f 22386 22417 22387
+f 22419 22388 22387
+f 22418 22419 22387
+f 22420 22389 22388
+f 22419 22420 22388
+f 22421 18657 22389
+f 22420 22421 22389
+f 19861 15591 18657
+f 22421 19861 18657
+f 16711 16710 22422
+f 16000 19861 16621
+f 21937 21134 21046
+f 20905 21493 21578
+f 20903 20902 22173
+f 6796 21880 17639
+f 21339 22290 22423
+f 21080 21339 22423
+f 7150 21274 21012
+f 3210 2993 3225
+f 22226 21755 21754
+f 21813 21743 21816
+f 22408 19980 21312
+f 21313 22226 21754
+f 21064 22408 22395
+f 17546 6796 17639
+f 22369 22368 22424
+f 21129 21064 22395
+f 21880 9739 17694
+f 20843 20950 22104
+f 20983 1983 21595
+f 19436 19153 19703
+f 9600 14875 9684
+f 21468 20383 20944
+f 8144 13679 6889
+f 20465 21566 15571
+f 21129 22395 22352
+f 20988 21129 22352
+f 16360 16359 15856
+f 22352 22395 19762
+f 3577 22425 22426
+f 21313 21754 21758
+f 21816 21707 21817
+f 21708 1914 21820
+f 15601 16149 16148
+f 17784 18093 21913
+f 20966 9649 20782
+f 8725 20905 21578
+f 22120 22205 22058
+f 22137 22205 22120
+f 21914 17259 22191
+f 21915 21914 22191
+f 22182 22118 22259
+f 22409 22335 17995
+f 21862 21861 22356
+f 22118 22055 22255
+f 10095 10169 10096
+f 21868 21870 22427
+f 21806 21808 22056
+f 7264 3433 7263
+f 22090 22088 22250
+f 22117 21806 22056
+f 21814 21819 21975
+f 22088 21806 22117
+f 21819 21818 21909
+f 21973 21814 21975
+f 21818 21821 21910
+f 21975 21819 21909
+f 21821 21822 21968
+f 21909 21818 21910
+f 22428 22429 22039
+f 22037 22039 22430
+f 22399 16929 22429
+f 22038 22428 22039
+f 22431 22399 22429
+f 22428 22431 22429
+f 18114 18991 22399
+f 22431 18114 22399
+f 7543 12097 1178
+f 18114 18116 18991
+f 2573 2572 2734
+f 8719 8726 21581
+f 12368 12367 12370
+f 9624 9625 21210
+f 20887 20718 20717
+f 8931 2014 8932
+f 22369 22432 22403
+f 22402 22370 22369
+f 22432 22433 22404
+f 22403 22432 22404
+f 22433 22434 22405
+f 22404 22433 22405
+f 22434 22435 22406
+f 22405 22434 22406
+f 22435 22436 22407
+f 22406 22435 22407
+f 19859 18990 22407
+f 22436 19859 22407
+f 6944 7069 6945
+f 19859 20050 18945
+f 19954 21720 21698
+f 17160 4344 22437
+f 21500 21165 9018
+f 21165 21252 4188
+f 21418 21682 20942
+f 21300 21418 20942
+f 2830 2829 3025
+f 7150 18568 21200
+f 21244 19521 21553
+f 17639 21880 17694
+f 15274 5751 21383
+f 9064 9063 693
+f 14250 11321 3441
+f 17587 18991 17609
+f 6738 21419 21840
+f 6739 6738 21840
+f 21419 20901 21841
+f 21840 21419 21841
+f 20901 20886 21842
+f 21841 20901 21842
+f 20886 21260 21843
+f 21842 20886 21843
+f 21253 21686 19953
+f 21721 21720 19954
+f 21171 6847 1894
+f 21530 20919 21417
+f 20988 22352 19951
+f 62 22438 17439
+f 21229 21279 22290
+f 21052 21054 20968
+f 9684 14875 9830
+f 18069 19867 13791
+f 21820 1914 21823
+f 1914 1923 21823
+f 21238 21322 21239
+f 1564 9794 21850
+f 17782 10434 15054
+f 21338 21937 22189
+f 2662 2507 2506
+f 22439 22440 22441
+f 4632 21291 4798
+f 22442 14969 14968
+f 16718 16717 16719
+f 21597 21056 21055
+f 2519 2342 2344
+f 2287 20295 8671
+f 9516 3646 5237
+f 19578 19577 20850
+f 22184 22443 22444
+f 22185 22184 22444
+f 5469 22445 9592
+f 22379 22381 22411
+f 19822 22446 15565
+f 15478 15564 7469
+f 22446 22447 22412
+f 15565 22446 22412
+f 22447 22448 22413
+f 22412 22447 22413
+f 22448 22449 22414
+f 22413 22448 22414
+f 22449 22450 22415
+f 22414 22449 22415
+f 22450 22451 22416
+f 22415 22450 22416
+f 22451 22452 22417
+f 22416 22451 22417
+f 22453 22418 22417
+f 22452 22453 22417
+f 22454 22419 22418
+f 22453 22454 22418
+f 22455 22420 22419
+f 22454 22455 22419
+f 22456 22421 22420
+f 22455 22456 22420
+f 22457 19861 22421
+f 22456 22457 22421
+f 13487 8652 13488
+f 22457 16621 19861
+f 21432 6656 21923
+f 22458 17854 17694
+f 21778 22105 21463
+f 22032 22103 21690
+f 21753 8631 21123
+f 22103 22105 21778
+f 9633 14708 10502
+f 21690 22103 21778
+f 21229 21228 21279
+f 3421 3211 3417
+f 9739 22458 17694
+f 22395 22408 21312
+f 21146 21020 3236
+f 21621 17871 17854
+f 22343 21688 21253
+f 14360 14361 14363
+f 21260 21262 21844
+f 21686 21721 19953
+f 21843 21260 21844
+f 21262 20810 21845
+f 19980 14784 22226
+f 21688 21686 21253
+f 16725 5632 15319
+f 21171 1894 21566
+f 20867 20912 21577
+f 21242 5957 5956
+f 21146 18404 21018
+f 22408 19981 19980
+f 19763 21313 21758
+f 22458 21621 17854
+f 9579 13477 13954
+f 9158 17877 17871
+f 21760 17784 21913
+f 21760 21913 21917
+f 21558 21043 21645
+f 22202 16189 16188
+f 22183 22137 22120
+f 21999 22077 22335
+f 21050 20887 20717
+f 18093 17817 17816
+f 22253 22185 22336
+f 22176 22459 22177
+f 22261 22118 22255
+f 22381 22427 22295
+f 21862 22355 22398
+f 22055 21972 22263
+f 20871 21130 20872
+f 21868 22427 22460
+f 22066 22116 21847
+f 22113 21398 8562
+f 22068 22054 22066
+f 22116 1928 21847
+f 22070 21968 22068
+f 22054 22116 22066
+f 21911 21910 22070
+f 21968 22054 22068
+f 21976 21909 21911
+f 21910 21968 22070
+f 22461 22038 15558
+f 18870 15559 15558
+f 22462 22428 22038
+f 22461 22462 22038
+f 22463 22431 22428
+f 22462 22463 22428
+f 18115 18114 22431
+f 22463 18115 22431
+f 1473 12801 22464
+f 21693 21900 8145
+f 18769 18766 18767
+f 8704 21154 19171
+f 18769 21839 18154
+f 21621 9158 17871
+f 18519 19605 4165
+f 20869 20865 20870
+f 22424 22432 22369
+f 22465 22370 22402
+f 22466 22433 22432
+f 22424 22466 22432
+f 22466 22467 22434
+f 22433 22466 22434
+f 22467 22468 22435
+f 22434 22467 22435
+f 22468 22469 22436
+f 22435 22468 22436
+f 22469 20050 19859
+f 22436 22469 19859
+f 20465 21171 21566
+f 22209 22470 22471
+f 9157 17972 17877
+f 16179 18534 16894
+f 21844 21262 21845
+f 20810 22143 21545
+f 21845 20810 21545
+f 4494 19072 6085
+f 21720 21685 21698
+f 21772 20964 21773
+f 18534 8603 16894
+f 9158 9157 17877
+f 9467 9397 9468
+f 21174 20876 21177
+f 9252 13055 22472
+f 12367 5651 5650
+f 21650 21424 19576
+f 7069 7273 7154
+f 12193 9231 9637
+f 19953 21721 19954
+f 22143 21575 21545
+f 21578 21581 8725
+f 21898 21576 21575
+f 8522 8424 8519
+f 3196 5502 1699
+f 20214 18071 17972
+f 21543 21677 21895
+f 18994 18996 15339
+f 9157 20214 17972
+f 21635 13375 2890
+f 18991 17587 18993
+f 21298 21234 21504
+f 14437 22473 836
+f 22474 18091 18071
+f 21823 1923 21825
+f 1923 1922 21825
+f 21439 21240 2733
+f 8521 8522 21896
+f 13984 8567 14347
+f 2896 20946 21598
+f 6139 9619 22245
+f 5620 17013 17015
+f 1927 1926 19158
+f 19912 22475 20653
+f 3053 3258 3054
+f 14633 14747 14746
+f 5379 2852 2854
+f 20214 22474 18071
+f 22476 22477 22212
+f 20910 2745 20752
+f 22166 22478 22186
+f 22336 22479 17993
+f 22131 22378 22480
+f 14242 14147 13865
+f 22481 22482 22446
+f 16272 19822 15564
+f 22482 22483 22447
+f 22446 22482 22447
+f 22483 22484 22448
+f 22447 22483 22448
+f 22484 22485 22449
+f 22448 22484 22449
+f 22485 22486 22450
+f 22449 22485 22450
+f 22486 22487 22451
+f 22450 22486 22451
+f 22487 22488 22452
+f 22451 22487 22452
+f 22489 22453 22452
+f 22488 22489 22452
+f 22490 22454 22453
+f 22489 22490 22453
+f 22491 22455 22454
+f 22490 22491 22454
+f 22492 22456 22455
+f 22491 22492 22455
+f 22493 22457 22456
+f 22492 22493 22456
+f 22494 16621 22457
+f 22493 22494 22457
+f 1270 16626 1271
+f 22494 1271 16621
+f 22495 22032 21690
+f 9048 4081 14536
+f 21216 7156 21426
+f 5543 2843 6749
+f 20055 21600 21517
+f 20472 17839 12649
+f 19200 6823 22347
+f 22496 11151 15422
+f 21090 21125 21091
+f 22284 14572 9235
+f 22152 19821 18518
+f 21677 21089 21394
+f 3542 9234 9233
+f 21726 22152 18518
+f 21407 21899 21131
+f 20969 21314 20970
+f 20718 21691 21227
+f 21638 21727 18588
+f 21726 18518 18517
+f 21960 21542 21544
+f 22497 22498 22499
+f 16178 1133 6081
+f 5358 8705 19172
+f 21705 21036 21835
+f 15221 4810 4812
+f 22361 19763 21758
+f 22009 21550 21072
+f 21722 20904 8724
+f 9585 20874 20788
+f 21756 21760 21917
+f 21756 21917 21919
+f 18108 10430 5797
+f 21664 18108 5797
+f 22137 22183 22253
+f 22077 22137 22253
+f 8830 8834 8713
+f 20216 20223 21293
+f 22335 22336 17995
+f 1481 20816 21726
+f 22398 22355 22296
+f 10948 2020 22268
+f 22255 22055 22263
+f 22379 22460 22381
+f 21865 21868 22460
+f 21972 21974 22204
+f 21863 21865 22460
+f 21870 22398 22427
+f 22356 21861 22396
+f 22322 21863 22460
+f 22396 21859 22500
+f 21859 21875 22500
+f 22500 21875 22187
+f 21875 21876 22187
+f 22187 21876 22060
+f 21876 21957 22060
+f 14295 22461 15557
+f 15558 15557 22461
+f 22501 22462 22461
+f 14295 22501 22461
+f 22502 22463 22462
+f 22501 22502 22462
+f 22503 18115 22463
+f 22502 22503 22463
+f 8147 8145 8224
+f 22503 16412 18115
+f 15304 18544 15305
+f 21204 21147 21205
+f 21338 20875 21937
+f 21224 22504 17606
+f 21428 21179 21256
+f 21694 21428 21345
+f 8129 14135 22505
+f 18523 13101 21762
+f 22506 22466 22424
+f 22507 22506 22424
+f 22508 22467 22466
+f 22506 22508 22466
+f 22509 22468 22467
+f 22508 22509 22467
+f 22510 22469 22468
+f 22509 22510 22468
+f 22510 15531 20050
+f 22469 22510 20050
+f 707 18545 18544
+f 18777 20207 20208
+f 21687 21688 17807
+f 18931 22343 21253
+f 20902 21479 22173
+f 21638 18588 20899
+f 21699 19638 21585
+f 21704 21703 21779
+f 18148 2961 2999
+f 3110 6511 9188
+f 21637 20899 20924
+f 20986 20879 21265
+f 19522 21445 21220
+f 14363 14362 21366
+f 21960 22013 20996
+f 21378 21958 21480
+f 20863 21298 20821
+f 22511 18146 18091
+f 21216 21426 21217
+f 21498 21081 21028
+f 22474 22511 18091
+f 21777 21738 22512
+f 21036 21035 21145
+f 20948 21117 20949
+f 21125 21595 21126
+f 21677 21494 21089
+f 16835 21253 21254
+f 14210 14209 21728
+f 21602 21604 21597
+f 8704 19171 8705
+f 2014 10938 8932
+f 14784 21757 21755
+f 9311 19891 3222
+f 22513 18225 18146
+f 21709 21705 21835
+f 2129 2128 2813
+f 21825 1922 18006
+f 2507 2056 2055
+f 19955 3237 3236
+f 17994 22409 17995
+f 10226 10227 6137
+f 22284 4189 4188
+f 18956 21978 18957
+f 22514 22515 22516
+f 9884 9886 9883
+f 22511 22513 18146
+f 2332 19055 1881
+f 8705 5358 5357
+f 1948 22115 1615
+f 17995 22336 17993
+f 22477 22517 22214
+f 22518 22519 4631
+f 22185 22444 22479
+f 20299 9300 17863
+f 22379 22411 22380
+f 12890 22520 22482
+f 22481 12890 22482
+f 22520 22521 22483
+f 22482 22520 22483
+f 22521 22522 22484
+f 22483 22521 22484
+f 22522 22523 22485
+f 22484 22522 22485
+f 22523 22524 22486
+f 22485 22523 22486
+f 22524 22525 22487
+f 22486 22524 22487
+f 22525 22526 22488
+f 22487 22525 22488
+f 22527 22489 22488
+f 22526 22527 22488
+f 22528 22490 22489
+f 22527 22528 22489
+f 22529 22491 22490
+f 22528 22529 22490
+f 22530 22492 22491
+f 22529 22530 22491
+f 22531 22493 22492
+f 22530 22531 22492
+f 22532 22494 22493
+f 22531 22532 22493
+f 1272 1271 22494
+f 22532 1272 22494
+f 3869 4971 1099
+f 9869 9873 21163
+f 11018 1614 1616
+f 19242 4963 4962
+f 15675 16786 15680
+f 21163 21443 19521
+f 432 4921 1712
+f 21139 21464 20847
+f 21319 21781 21891
+f 21021 20919 21530
+f 7364 10905 18375
+f 4687 4212 11781
+f 20782 21023 20783
+f 2572 600 14299
+f 21955 5366 1892
+f 22112 21388 17748
+f 21891 21530 21466
+f 21727 21726 18517
+f 8051 20845 21996
+f 21891 21021 21530
+f 21739 21559 21833
+f 21091 21795 21394
+f 15865 12228 3366
+f 20220 20219 21406
+f 22533 18330 18225
+f 16799 22002 22179
+f 21460 21541 21461
+f 20968 21054 20969
+f 21759 21756 21919
+f 21759 21919 21763
+f 21679 21326 21697
+f 17267 17304 17306
+f 13212 2770 4079
+f 21526 20461 20414
+f 16463 16462 17140
+f 17332 21194 21197
+f 4851 7550 2118
+f 21234 21233 21505
+f 3425 3228 20786
+f 12537 17107 21561
+f 22427 22398 22295
+f 21480 21675 21481
+f 22263 21972 22204
+f 22378 22322 22379
+f 22251 22182 22258
+f 21974 21976 22203
+f 22224 22251 22304
+f 22182 22259 22258
+f 22225 22224 22344
+f 22251 22258 22304
+f 22225 22344 22534
+f 22221 22225 22534
+f 22221 22534 22063
+f 22224 22304 22344
+f 15861 14293 15557
+f 22122 22221 22063
+f 22535 22501 14295
+f 9403 22535 14295
+f 22536 22502 22501
+f 22535 22536 22501
+f 22537 22503 22502
+f 22536 22537 22502
+f 22538 16412 22503
+f 22537 22538 22503
+f 15481 14642 19344
+f 22538 1098 16412
+f 21256 21367 21257
+f 12368 17102 12458
+f 21645 21043 20965
+f 21044 21710 21405
+f 22290 21092 21938
+f 22539 22540 22507
+f 13101 13006 21762
+f 22541 22506 22507
+f 22540 22541 22507
+f 22542 22508 22506
+f 22541 22542 22506
+f 22543 22509 22508
+f 22542 22543 22508
+f 22544 22510 22509
+f 22543 22544 22509
+f 15532 15531 22510
+f 22544 15532 22510
+f 17899 16235 22545
+f 22546 22547 22545
+f 21677 22325 21895
+f 21544 21543 21895
+f 21637 21638 20899
+f 21727 18517 18588
+f 20717 20719 21601
+f 20892 21680 20926
+f 9469 21403 21694
+f 5782 5644 5643
+f 21639 21637 20924
+f 22548 15600 20894
+f 20818 21544 21895
+f 21596 21127 21597
+f 21145 8835 8834
+f 10993 11032 20334
+f 21681 21430 20986
+f 20936 21408 20880
+f 22174 21429 21049
+f 20892 20894 15599
+f 9825 21011 8624
+f 20855 20854 21234
+f 6483 14210 21728
+f 9396 9292 9291
+f 9755 8625 21133
+f 20883 21244 21553
+f 21461 20950 20843
+f 21542 21494 21677
+f 22104 20952 5249
+f 22513 22533 18225
+f 22226 14784 21755
+f 21033 21693 8145
+f 20053 22549 20054
+f 10918 3328 10919
+f 3983 21873 9796
+f 8575 8702 8574
+f 17231 10226 6137
+f 8834 8830 21145
+f 12549 2661 9108
+f 6372 22315 5969
+f 22248 15232 22550
+f 22274 9651 9653
+f 22551 22552 2467
+f 1889 4632 4798
+f 22214 22517 20179
+f 9619 5620 17015
+f 21100 21101 21199
+f 1721 21559 1896
+f 22553 9264 9266
+f 20784 20783 20882
+f 22519 22551 18109
+f 22336 22185 22479
+f 20646 12892 12891
+f 22378 22380 22480
+f 22554 22555 12890
+f 12892 22554 12890
+f 22555 22556 22520
+f 12890 22555 22520
+f 22556 22557 22521
+f 22520 22556 22521
+f 22557 22558 22522
+f 22521 22557 22522
+f 22558 22559 22523
+f 22522 22558 22523
+f 22559 22560 22524
+f 22523 22559 22524
+f 22560 22561 22525
+f 22524 22560 22525
+f 22561 22562 22526
+f 22525 22561 22526
+f 22563 22527 22526
+f 22562 22563 22526
+f 22564 22528 22527
+f 22563 22564 22527
+f 22565 22529 22528
+f 22564 22565 22528
+f 22566 22530 22529
+f 22565 22566 22529
+f 22567 22531 22530
+f 22566 22567 22530
+f 22568 22532 22531
+f 22567 22568 22531
+f 22569 1272 22532
+f 22568 22569 22532
+f 22570 17936 17938
+f 22569 17938 1272
+f 9799 8051 21996
+f 4953 4955 9308
+f 20855 21234 21298
+f 21059 21781 21319
+f 5958 21465 5955
+f 15563 1270 17937
+f 20455 8942 18641
+f 20989 20823 20990
+f 8829 8711 21390
+f 9648 9793 9649
+f 6443 3018 1425
+f 19302 20830 21429
+f 21319 21466 21208
+f 22290 21279 21092
+f 21480 21958 21675
+f 21319 21891 21466
+f 1898 3964 1899
+f 21693 21033 21032
+f 9787 10968 6041
+f 21428 21399 21179
+f 21395 21488 21490
+f 20960 8483 8482
+f 16716 7748 13526
+f 21463 21753 21123
+f 21464 21373 21546
+f 21317 20951 20950
+f 21920 22571 21763
+f 12549 9108 13511
+f 22572 21628 22573
+f 21222 15340 21223
+f 22016 16322 16324
+f 22574 22575 22576
+f 16502 22577 16503
+f 16504 16503 16463
+f 21924 12713 19626
+f 9019 8897 8756
+f 3543 22578 14324
+f 22020 2333 6239
+f 22579 18384 18330
+f 22374 22577 22212
+f 22460 22427 22381
+f 20975 21007 21327
+f 22130 22322 22378
+f 22131 22130 22378
+f 22295 22398 22296
+f 22322 22460 22379
+f 22355 22356 22299
+f 22296 22355 22299
+f 22356 22396 22580
+f 22299 22356 22580
+f 22396 22500 22581
+f 22581 22500 22190
+f 22580 22396 22581
+f 22500 22187 22190
+f 9402 22535 9403
+f 14294 2811 9403
+f 22582 22536 22535
+f 9402 22582 22535
+f 22583 22537 22536
+f 22582 22583 22536
+f 22584 22538 22537
+f 22583 22584 22537
+f 1096 1098 22538
+f 22584 1096 22538
+f 21542 20996 21494
+f 12707 20915 21402
+f 22423 22290 21938
+f 21601 21339 21080
+f 21038 21601 21080
+f 22585 22586 22540
+f 22587 10712 14974
+f 22588 22541 22540
+f 22586 22588 22540
+f 22589 22542 22541
+f 22588 22589 22541
+f 22590 22543 22542
+f 22589 22590 22542
+f 22591 22544 22543
+f 22590 22591 22543
+f 22591 22592 15532
+f 22544 22591 15532
+f 22592 22593 16403
+f 15532 22592 16403
+f 20721 15695 22594
+f 22594 17517 22593
+f 21318 21319 21208
+f 21714 21318 21208
+f 21639 20924 20926
+f 22189 21046 21088
+f 15598 21680 20892
+f 21642 21639 20926
+f 15599 15598 20892
+f 21680 21642 20926
+f 21207 21714 21208
+f 21190 20787 21191
+f 21220 21378 21480
+f 20842 20844 21899
+f 21101 9906 9908
+f 20950 20952 22104
+f 22113 21096 21398
+f 19578 20850 21021
+f 21461 20842 21462
+f 7863 21132 8048
+f 7068 20849 21724
+f 21263 20455 18641
+f 17895 12068 20540
+f 3236 21020 21751
+f 22595 22596 10981
+f 5905 3001 16916
+f 16158 22597 22598
+f 16442 17074 2267
+f 2266 16442 2267
+f 22599 22600 17255
+f 5668 884 21616
+f 21616 884 886
+f 1881 19055 22007
+f 8727 1917 8597
+f 22533 22579 18330
+f 14301 5385 14302
+f 22132 22123 16279
+f 2171 16795 3207
+f 9653 9652 21634
+f 22601 22602 22603
+f 15993 17104 7236
+f 22579 22604 18399
+f 22334 22477 22214
+f 18384 22579 18399
+f 924 1097 1096
+f 22517 4464 20179
+f 18878 22605 22606
+f 1511 22606 22605
+f 22605 22607 1511
+f 22554 12892 1512
+f 22607 22608 22554
+f 1511 22607 22554
+f 22608 22609 22555
+f 22554 22608 22555
+f 22609 22610 22556
+f 22555 22609 22556
+f 22610 22611 22557
+f 22556 22610 22557
+f 22611 22612 22558
+f 22557 22611 22558
+f 22612 22613 22559
+f 22558 22612 22559
+f 22613 22614 22560
+f 22559 22613 22560
+f 22614 22615 22561
+f 22560 22614 22561
+f 22615 22616 22562
+f 22561 22615 22562
+f 22617 22563 22562
+f 22616 22617 22562
+f 22618 22564 22563
+f 22617 22618 22563
+f 22619 22565 22564
+f 22618 22619 22564
+f 22620 22566 22565
+f 22619 22620 22565
+f 22621 22567 22566
+f 22620 22621 22566
+f 22622 22568 22567
+f 22621 22622 22567
+f 22623 22569 22568
+f 22622 22623 22568
+f 22624 17938 22569
+f 22623 22624 22569
+f 9870 21163 21022
+f 16793 15850 16791
+f 21557 21682 21264
+f 20890 1891 20891
+f 21465 20980 5955
+f 16010 22625 22626
+f 21694 21403 21428
+f 20789 21338 22189
+f 19576 21781 21059
+f 21181 21137 21139
+f 21649 6637 20897
+f 21449 21203 21205
+f 21257 21369 21230
+f 21535 14688 21362
+f 21940 21699 21585
+f 21958 21676 21675
+f 21478 21482 21238
+f 10178 10177 10174
+f 21384 22032 22495
+f 3978 3977 3797
+f 21541 21317 21461
+f 21711 21230 20995
+f 13661 1770 11483
+f 20965 21044 21405
+f 21375 20841 21117
+f 20934 21780 21460
+f 22604 22627 18401
+f 22549 20053 17153
+f 4955 802 801
+f 4628 15648 21977
+f 6639 21774 21397
+f 757 605 19165
+f 17098 22476 22577
+f 2225 16504 7231
+f 21237 21239 8514
+f 22475 19912 18043
+f 22628 22629 22630
+f 2172 2174 19103
+f 22477 22334 22212
+f 16464 16503 22374
+f 21031 10210 14514
+f 22184 22119 22631
+f 7151 21200 18568
+f 18399 22604 18401
+f 1913 1756 1755
+f 3178 10499 3135
+f 21636 22392 21583
+f 3979 4183 3975
+f 9541 9727 9648
+f 22627 16154 18793
+f 2191 2193 10169
+f 1586 1591 22159
+f 18401 22627 18793
+f 14255 18549 13210
+f 22632 9402 9404
+f 9404 2811 2810
+f 22633 22582 9402
+f 22632 22633 9402
+f 22634 22583 22582
+f 22633 22634 22582
+f 1080 22584 22583
+f 22634 1080 22583
+f 1082 1096 22584
+f 1080 1082 22584
+f 20883 21553 20884
+f 20915 12707 20916
+f 21273 20840 21251
+f 20886 20885 21260
+f 21051 21601 21038
+f 21009 21051 21038
+f 16154 16156 19113
+f 22635 22586 22585
+f 8584 22585 22636
+f 22635 22637 22588
+f 22586 22635 22588
+f 22637 22638 22589
+f 22588 22637 22589
+f 22638 22639 22590
+f 22589 22638 22590
+f 22639 22640 22591
+f 22590 22639 22591
+f 22640 22641 22592
+f 22591 22640 22592
+f 22641 22642 22593
+f 22592 22641 22593
+f 22642 20722 22594
+f 22593 22642 22594
+f 21280 21296 9947
+f 20721 20720 2976
+f 21650 21058 21703
+f 9391 13477 9459
+f 22643 22189 21088
+f 21047 20930 20929
+f 20789 22189 22643
+f 21191 20789 22643
+f 20842 21461 20843
+f 21329 21328 21704
+f 18793 16154 19113
+f 16156 22236 19774
+f 21011 9825 9906
+f 20919 20918 21420
+f 9397 9467 21003
+f 21056 21540 21780
+f 18337 22644 22645
+f 19113 16156 19774
+f 9445 3134 9446
+f 22646 14922 22647
+f 5798 22648 5799
+f 5261 22008 5676
+f 13052 2172 19103
+f 21569 2173 2172
+f 4841 20421 6801
+f 6800 4841 6801
+f 2267 17074 5529
+f 17074 14931 5529
+f 16160 17600 22649
+f 15306 17604 22650
+f 21393 21237 8514
+f 22651 22652 22653
+f 8050 9807 21216
+f 2163 3252 2164
+f 21634 20613 9065
+f 12707 21402 21401
+f 2342 16228 17883
+f 22195 22319 22196
+f 22654 22655 22656
+f 9311 19303 9309
+f 2837 22657 5812
+f 10567 10566 22658
+f 18878 22606 22659
+f 6093 6092 15189
+f 22660 22661 22605
+f 18878 22660 22605
+f 22661 22662 22607
+f 22605 22661 22607
+f 22662 22663 22608
+f 22607 22662 22608
+f 22663 22664 22609
+f 22608 22663 22609
+f 22664 22665 22610
+f 22609 22664 22610
+f 22665 22666 22611
+f 22610 22665 22611
+f 22666 22667 22612
+f 22611 22666 22612
+f 22667 22668 22613
+f 22612 22667 22613
+f 22668 22669 22614
+f 22613 22668 22614
+f 22669 22670 22615
+f 22614 22669 22615
+f 22670 22671 22616
+f 22615 22670 22616
+f 22672 22617 22616
+f 22671 22672 22616
+f 22673 22618 22617
+f 22672 22673 22617
+f 22674 22619 22618
+f 22673 22674 22618
+f 22675 22620 22619
+f 22674 22675 22619
+f 22676 22621 22620
+f 22675 22676 22620
+f 22677 22622 22621
+f 22676 22677 22621
+f 22678 22623 22622
+f 22677 22678 22622
+f 11097 22624 22623
+f 22678 11097 22623
+f 18602 11097 11096
+f 11097 18602 22624
+f 7844 9058 7842
+f 21072 21550 21074
+f 21559 1567 22014
+f 4179 21419 6738
+f 9883 9880 9879
+f 21703 21058 21060
+f 21138 21715 21464
+f 9880 9886 21377
+f 3511 19337 3509
+f 21103 20835 21772
+f 21787 20896 20895
+f 21711 21257 21230
+f 8932 10938 14980
+f 9886 21916 21377
+f 19158 1785 1927
+f 14876 1554 21116
+f 21782 21695 21696
+f 22173 21479 21783
+f 21692 21032 8048
+f 22392 21940 21584
+f 21050 20717 21051
+f 801 6533 15133
+f 21023 21022 20783
+f 3217 2896 21598
+f 3225 3224 21885
+f 22679 19782 22680
+f 17994 22553 9266
+f 558 15673 559
+f 16835 21254 16836
+f 9794 1575 21797
+f 17603 22477 22476
+f 17098 17603 22476
+f 4176 21303 21826
+f 22681 22682 18244
+f 16802 22683 9915
+f 703 15647 899
+f 22577 22476 22212
+f 21676 21183 21182
+f 22443 22184 22631
+f 22119 22057 22684
+f 22204 22685 22264
+f 22263 22204 22264
+f 22203 22686 22685
+f 22204 22203 22685
+f 22203 22133 22687
+f 22687 22133 22688
+f 22686 22203 22687
+f 22133 22071 22688
+f 22071 22069 22689
+f 22688 22071 22689
+f 22069 22067 22298
+f 22689 22069 22298
+f 22690 22632 22691
+f 22691 9404 2810
+f 22692 22633 22632
+f 22690 22692 22632
+f 22693 22634 22633
+f 22692 22693 22633
+f 21528 1080 22634
+f 22693 21528 22634
+f 3440 17714 3444
+f 718 8723 15390
+f 21024 21190 20991
+f 21094 21442 21053
+f 21273 21251 21734
+f 19638 21699 9829
+f 21049 21051 21009
+f 20938 21049 21009
+f 19764 7237 19391
+f 15520 8847 14421
+f 22694 8967 3309
+f 22236 22695 20052
+f 19774 22236 20052
+f 22696 22697 22635
+f 22698 9627 11387
+f 22697 22699 22637
+f 22635 22697 22637
+f 22699 22700 22638
+f 22637 22699 22638
+f 22700 22701 22639
+f 22638 22700 22639
+f 22701 22702 22640
+f 22639 22701 22640
+f 22702 22703 22641
+f 22640 22702 22641
+f 22703 22704 22642
+f 22641 22703 22642
+f 22704 22705 20722
+f 22642 22704 20722
+f 22705 22706 20720
+f 20722 22705 20720
+f 22599 17255 11232
+f 22706 22599 20720
+f 3987 8714 8834
+f 18769 18768 18766
+f 20850 20852 20917
+f 22585 8584 22707
+f 9559 672 7066
+f 20909 21104 21035
+f 22423 21938 21571
+f 21029 22423 21571
+f 21570 21783 19300
+f 21278 21124 21431
+f 12744 12642 21275
+f 21774 21192 21193
+f 22695 22708 20300
+f 20052 22695 20300
+f 16411 16410 22709
+f 22710 22711 22712
+f 22709 22713 16411
+f 10153 12379 15568
+f 22714 22715 22716
+f 13051 21569 2172
+f 22717 5549 17281
+f 19767 16218 16217
+f 5529 14931 5537
+f 14931 9277 5537
+f 10584 5668 21666
+f 18992 22652 22651
+f 14019 18992 22651
+f 16144 14109 16151
+f 22718 16143 16145
+f 5252 5254 5796
+f 8797 2329 2328
+f 22719 22720 5263
+f 12801 13009 22464
+f 15320 14886 22721
+f 22722 1750 22723
+f 9500 5168 7064
+f 22724 22333 6085
+f 14177 14045 22725
+f 15449 6646 10590
+f 18877 22726 22660
+f 22727 22728 22661
+f 22660 22727 22661
+f 22728 22729 22662
+f 22661 22728 22662
+f 22729 22730 22663
+f 22662 22729 22663
+f 22730 22731 22664
+f 22663 22730 22664
+f 22731 22732 22665
+f 22664 22731 22665
+f 22732 22733 22666
+f 22665 22732 22666
+f 22733 22734 22667
+f 22666 22733 22667
+f 22734 22735 22668
+f 22667 22734 22668
+f 22735 22736 22669
+f 22668 22735 22669
+f 22736 22737 22670
+f 22669 22736 22670
+f 22737 22738 22671
+f 22670 22737 22671
+f 22738 22739 22672
+f 22671 22738 22672
+f 22739 22740 22673
+f 22672 22739 22673
+f 22740 22741 22674
+f 22673 22740 22674
+f 22741 22742 22675
+f 22674 22741 22675
+f 22742 22743 22676
+f 22675 22742 22676
+f 22744 22677 22676
+f 22743 22744 22676
+f 22745 22678 22677
+f 22744 22745 22677
+f 11095 11097 22678
+f 22745 11095 22678
+f 22746 18751 22747
+f 22748 17654 21496
+f 21696 22495 20829
+f 21011 9906 21101
+f 20980 21465 20981
+f 19301 21696 20829
+f 21323 20983 21595
+f 20906 4179 6738
+f 20829 22495 20888
+f 18554 18550 18555
+f 17720 16276 22749
+f 21093 21442 21094
+f 21683 21294 21105
+f 20893 21788 20895
+f 21200 7153 12744
+f 22708 22750 20538
+f 21252 20839 22284
+f 20300 22708 20538
+f 21000 21205 21896
+f 21696 21384 22495
+f 20822 21487 21164
+f 20973 20822 21164
+f 20998 21323 21090
+f 21262 1893 20810
+f 22180 22114 21986
+f 22114 22052 21983
+f 22180 21986 21987
+f 22052 21991 21983
+f 22246 22180 21987
+f 22114 21983 21986
+f 16502 17098 22577
+f 22376 22214 22215
+f 17603 17105 22517
+f 22477 17603 22517
+f 8514 21239 8518
+f 21791 20997 22013
+f 8837 12170 4580
+f 19713 18108 4959
+f 16503 22577 22374
+f 22750 22751 20681
+f 22631 22119 22684
+f 22057 22059 22752
+f 22190 22188 22302
+f 22061 22753 22754
+f 22581 22190 22755
+f 22755 22190 22302
+f 22580 22581 22756
+f 22756 22581 22755
+f 22299 22580 22757
+f 22757 22580 22756
+f 22297 22296 22300
+f 22300 22299 22757
+f 22691 16056 22758
+f 22758 16055 22759
+f 22760 22690 22758
+f 22759 22760 22758
+f 22761 22692 22690
+f 22760 22761 22690
+f 22762 22693 22692
+f 22761 22762 22692
+f 21529 21528 22693
+f 22762 21529 22693
+f 925 1082 1081
+f 2495 2496 1697
+f 21191 22643 21483
+f 21417 21420 20824
+f 21234 21505 21504
+f 21132 7863 21491
+f 22174 21049 20938
+f 20937 22174 20938
+f 1245 12460 2151
+f 20866 20949 20911
+f 21106 21579 3988
+f 10167 10166 10089
+f 20840 20839 21251
+f 21467 21065 20989
+f 22325 21677 21394
+f 3541 15676 22148
+f 15513 15512 16343
+f 22763 22764 22697
+f 22707 8583 22696
+f 22764 22765 22699
+f 22697 22764 22699
+f 22765 22766 22700
+f 22699 22765 22700
+f 22766 22767 22701
+f 22700 22766 22701
+f 22767 22768 22702
+f 22701 22767 22702
+f 22768 22769 22703
+f 22702 22768 22703
+f 22769 22770 22704
+f 22703 22769 22704
+f 22770 22771 22705
+f 22704 22770 22705
+f 22771 22772 22706
+f 22705 22771 22706
+f 22773 22599 22706
+f 22772 22773 22706
+f 22600 11233 17255
+f 22773 22600 22599
+f 12459 19200 22347
+f 22774 13687 16774
+f 21104 21683 21035
+f 21035 21683 21105
+f 21489 21430 21681
+f 20925 21789 21788
+f 18589 18519 19952
+f 21782 21696 19301
+f 21795 21091 21596
+f 19172 21602 21632
+f 22775 22776 22777
+f 4336 22778 4337
+f 22779 22780 18653
+f 22781 13479 22782
+f 21415 22783 14024
+f 14025 22442 14026
+f 18654 22779 18653
+f 16409 22784 5397
+f 4840 22785 22786
+f 22315 5973 5969
+f 5537 9277 1724
+f 9277 9279 1724
+f 22021 10584 4954
+f 21665 22021 4954
+f 22787 15108 22788
+f 15236 21732 1868
+f 22789 22233 22790
+f 21276 22791 22718
+f 19923 22792 9156
+f 2316 5257 5673
+f 22793 22794 22795
+f 16217 14434 5164
+f 22796 22797 6246
+f 22798 22799 3031
+f 11198 22800 9614
+f 2317 2319 11015
+f 13660 22801 5774
+f 21286 21362 14688
+f 22802 22803 22728
+f 22727 22802 22728
+f 22803 22804 22729
+f 22728 22803 22729
+f 22804 22805 22730
+f 22729 22804 22730
+f 22805 22806 22731
+f 22730 22805 22731
+f 22806 22807 22732
+f 22731 22806 22732
+f 22807 22808 22733
+f 22732 22807 22733
+f 22808 22809 22734
+f 22733 22808 22734
+f 22809 22810 22735
+f 22734 22809 22735
+f 22810 22811 22736
+f 22735 22810 22736
+f 22811 22812 22737
+f 22736 22811 22737
+f 22812 22813 22738
+f 22737 22812 22738
+f 22814 22739 22738
+f 22813 22814 22738
+f 22815 22740 22739
+f 22814 22815 22739
+f 22816 22741 22740
+f 22815 22816 22740
+f 22816 22817 22742
+f 22741 22816 22742
+f 22817 22818 22743
+f 22742 22817 22743
+f 22818 22819 22744
+f 22743 22818 22744
+f 22819 22820 22745
+f 22744 22819 22745
+f 22821 22822 22823
+f 22820 3538 22745
+f 6088 6087 12455
+f 22824 21933 22825
+f 22826 19020 19019
+f 14014 16215 16214
+f 21061 19172 21632
+f 19172 19171 21602
+f 19171 21603 21602
+f 21715 20903 21374
+f 21874 3023 3025
+f 1696 6847 7947
+f 18589 19952 21641
+f 20894 20893 20895
+f 21294 21582 21106
+f 19302 19301 20830
+f 19761 19763 22361
+f 22827 80 22828
+f 21479 21481 21783
+f 15216 22134 15286
+f 10170 10171 21534
+f 6432 3896 3898
+f 22829 22830 22831
+f 4735 7340 7339
+f 20820 20822 20973
+f 2288 8673 6294
+f 22359 22073 22072
+f 21907 22359 22072
+f 18093 17816 21914
+f 21917 21913 21915
+f 22832 21236 22833
+f 21209 21210 21527
+f 16836 21254 21751
+f 18245 18244 22682
+f 4465 4464 17157
+f 22517 17105 4464
+f 20997 20982 20998
+f 10099 10177 10176
+f 19713 4959 21291
+f 16414 18116 16412
+f 22504 21224 22834
+f 672 674 21214
+f 22684 22057 22752
+f 22059 22063 22835
+f 22519 21939 22551
+f 12058 14874 3048
+f 22125 22836 22837
+f 22121 22125 22837
+f 22129 22128 22838
+f 22341 22129 22838
+f 22128 22131 22480
+f 22838 22128 22480
+f 1483 11224 17922
+f 22121 22837 16279
+f 22839 22759 22840
+f 22841 22840 16055
+f 22842 22760 22759
+f 22839 22842 22759
+f 22843 22761 22760
+f 22842 22843 22760
+f 22844 22762 22761
+f 22843 22844 22761
+f 22844 22845 21529
+f 22762 22844 21529
+f 4165 19605 4166
+f 21391 8513 8510
+f 20991 21191 21483
+f 9236 9235 9352
+f 21003 21694 21345
+f 20840 14573 14572
+f 21118 22174 20937
+f 20865 20947 20866
+f 20958 20957 21149
+f 20911 21118 20937
+f 20026 19844 22326
+f 22173 21783 21570
+f 22495 21690 20888
+f 19300 21782 19301
+f 20884 21736 21138
+f 21734 21251 21500
+f 21138 21736 21715
+f 20821 21299 20822
+f 21529 22845 2186
+f 18878 18877 22660
+f 22846 2124 2126
+f 22847 22848 22764
+f 22763 22847 22764
+f 22848 22849 22765
+f 22764 22848 22765
+f 22849 22850 22766
+f 22765 22849 22766
+f 22850 22851 22767
+f 22766 22850 22767
+f 22851 22852 22768
+f 22767 22851 22768
+f 22852 22853 22769
+f 22768 22852 22769
+f 22853 22854 22770
+f 22769 22853 22770
+f 22854 22855 22771
+f 22770 22854 22771
+f 22855 22856 22772
+f 22771 22855 22772
+f 22857 22773 22772
+f 22856 22857 22772
+f 22858 22600 22773
+f 22857 22858 22773
+f 22774 16774 22600
+f 22858 22774 22600
+f 21633 21429 22174
+f 22859 13685 22774
+f 20893 20925 21788
+f 20900 21641 21640
+f 21176 21169 8630
+f 21264 21681 20986
+f 21379 21028 21380
+f 21426 7068 21724
+f 4641 4640 10228
+f 11390 11389 12932
+f 22860 22861 22862
+f 14634 14633 14746
+f 22863 16784 16411
+f 22864 18654 18271
+f 13903 13734 4326
+f 6372 5969 2240
+f 22865 22864 18181
+f 1724 9279 22048
+f 9279 10842 22048
+f 21660 22021 21665
+f 21344 21660 21665
+f 5796 5254 7359
+f 22652 15272 22653
+f 22866 22865 18181
+f 17109 13806 15341
+f 22867 22868 5672
+f 6511 11272 10503
+f 8144 6367 13679
+f 19429 22869 22870
+f 22871 22872 22873
+f 22874 22710 22875
+f 7451 7450 15696
+f 22725 14045 14046
+f 4924 2353 2356
+f 22876 9234 10840
+f 22877 22878 22803
+f 22802 22877 22803
+f 22878 22879 22804
+f 22803 22878 22804
+f 22879 22880 22805
+f 22804 22879 22805
+f 22880 22881 22806
+f 22805 22880 22806
+f 22881 22882 22807
+f 22806 22881 22807
+f 22882 22883 22808
+f 22807 22882 22808
+f 22883 22884 22809
+f 22808 22883 22809
+f 22884 22885 22810
+f 22809 22884 22810
+f 22885 22886 22811
+f 22810 22885 22811
+f 22886 22887 22812
+f 22811 22886 22812
+f 22887 22888 22813
+f 22812 22887 22813
+f 22888 22889 22814
+f 22813 22888 22814
+f 22889 22890 22815
+f 22814 22889 22815
+f 22890 22891 22816
+f 22815 22890 22816
+f 22891 22892 22817
+f 22816 22891 22817
+f 22892 22893 22818
+f 22817 22892 22818
+f 22893 22894 22819
+f 22818 22893 22819
+f 22894 3536 22820
+f 22819 22894 22820
+f 9527 19890 16665
+f 22820 3536 3538
+f 3036 14688 21535
+f 21985 22210 21459
+f 20998 20982 21323
+f 7673 7672 7771
+f 8719 21581 8720
+f 22895 22896 21211
+f 7273 7069 6944
+f 21959 21357 21796
+f 11087 2898 2699
+f 21462 21899 21407
+f 16791 4947 22897
+f 20900 18589 21641
+f 18335 18337 22898
+f 16793 16792 22899
+f 22899 22900 16793
+f 16793 22900 22901
+f 22900 22902 22901
+f 14535 8100 13924
+f 22902 22903 2463
+f 15148 18709 21837
+f 22904 2461 2463
+f 22903 22904 2463
+f 16093 16359 13584
+f 22904 13583 2461
+f 21961 21521 22073
+f 22359 21961 22073
+f 15857 15856 22905
+f 15856 16359 22905
+f 22906 975 15671
+f 22907 15857 22908
+f 20976 9624 21209
+f 1614 1948 1615
+f 10918 6094 3328
+f 1486 1485 3282
+f 17198 21045 21340
+f 20843 22104 20960
+f 22909 22910 22911
+f 21628 18960 22573
+f 21803 21894 21136
+f 2320 22912 22913
+f 22752 22059 22835
+f 22534 22914 22835
+f 14149 12072 3049
+f 15850 16793 22901
+f 22124 22340 22836
+f 22125 22124 22836
+f 15989 15453 15455
+f 16120 7632 10453
+f 22915 15453 22916
+f 16579 15988 15989
+f 22840 22915 22839
+f 15988 22916 15453
+f 22917 22839 22915
+f 22916 22917 22915
+f 22918 22842 22839
+f 22917 22918 22839
+f 22919 22843 22842
+f 22918 22919 22842
+f 22920 22844 22843
+f 22919 22920 22843
+f 22920 19318 22845
+f 22844 22920 22845
+f 524 2411 14297
+f 9120 22284 9235
+f 8612 11494 3838
+f 22643 21088 21636
+f 20869 20848 20865
+f 19639 19642 19844
+f 20949 21118 20911
+f 21231 20846 20869
+f 20454 20913 20455
+f 20947 20949 20866
+f 15784 22921 20471
+f 7364 21959 21796
+f 506 22326 507
+f 22326 20025 20026
+f 19171 21154 21603
+f 22922 22923 22924
+f 7771 21491 7863
+f 20890 21955 1892
+f 18154 21839 21444
+f 21404 21381 21800
+f 10177 10099 10098
+f 20999 21449 21000
+f 21601 20719 21339
+f 22925 16914 22847
+f 6042 5381 9154
+f 22926 22848 22847
+f 22927 22926 22847
+f 22928 22849 22848
+f 22926 22928 22848
+f 22928 22929 22850
+f 22849 22928 22850
+f 22929 22930 22851
+f 22850 22929 22851
+f 22930 22931 22852
+f 22851 22930 22852
+f 22931 22932 22853
+f 22852 22931 22853
+f 22932 22933 22854
+f 22853 22932 22854
+f 22933 22934 22855
+f 22854 22933 22855
+f 22934 22935 22856
+f 22855 22934 22856
+f 22936 22857 22856
+f 22935 22936 22856
+f 22937 22858 22857
+f 22936 22937 22857
+f 22938 22774 22858
+f 22937 22938 22858
+f 18571 22859 22939
+f 22938 22859 22774
+f 20923 20900 21640
+f 22195 17258 22319
+f 10227 2493 6138
+f 21329 21704 21170
+f 2186 22845 19318
+f 20908 21102 21104
+f 22940 22941 22942
+f 16987 22943 22944
+f 17819 3053 3052
+f 3056 3055 11024
+f 22945 14905 14907
+f 14905 22946 18011
+f 16158 22649 22597
+f 22947 22948 22949
+f 22950 15928 15135
+f 10842 2845 22048
+f 307 2668 2670
+f 21344 22951 5539
+f 15184 15185 19056
+f 2415 2413 10718
+f 21562 21561 22952
+f 22233 22953 22954
+f 18183 22866 18181
+f 22955 22956 22957
+f 22958 4652 22959
+f 22960 22961 22962
+f 21221 21223 21622
+f 4538 21221 21622
+f 22963 21615 22964
+f 22140 5509 21737
+f 5268 12319 6168
+f 5120 5268 6168
+f 22965 22966 22878
+f 22877 22802 22869
+f 22966 22967 22879
+f 22878 22966 22879
+f 22967 22968 22880
+f 22879 22967 22880
+f 22968 22969 22881
+f 22880 22968 22881
+f 22969 22970 22882
+f 22881 22969 22882
+f 22970 22971 22883
+f 22882 22970 22883
+f 22971 22972 22884
+f 22883 22971 22884
+f 22972 22973 22885
+f 22884 22972 22885
+f 22973 22974 22886
+f 22885 22973 22886
+f 22974 22975 22887
+f 22886 22974 22887
+f 22975 22976 22888
+f 22887 22975 22888
+f 22976 22977 22889
+f 22888 22976 22889
+f 22977 22978 22890
+f 22889 22977 22890
+f 22978 22979 22891
+f 22890 22978 22891
+f 22980 22892 22891
+f 22979 22980 22891
+f 22980 22981 22893
+f 22892 22980 22893
+f 22982 22894 22893
+f 22981 22982 22893
+f 9472 3536 22894
+f 22982 9472 22894
+f 2340 22178 2341
+f 16360 15856 16353
+f 21716 21186 21184
+f 21724 21725 21187
+f 21010 21039 20219
+f 8514 8422 8421
+f 20990 20825 20974
+f 21054 20990 20974
+f 11931 16894 8603
+f 16549 15319 15129
+f 18270 22983 7738
+f 17315 9109 15971
+f 22984 17846 18061
+f 4080 4081 12888
+f 16442 12059 17074
+f 22985 22986 22900
+f 22899 22985 22900
+f 22986 22987 22902
+f 22900 22986 22902
+f 22987 22988 22903
+f 22902 22987 22903
+f 22989 22904 22903
+f 22988 22989 22903
+f 22990 13583 22904
+f 22989 22990 22904
+f 17434 13584 16360
+f 22990 22991 13583
+f 22992 22905 16093
+f 22991 22992 16093
+f 22993 15857 22905
+f 22992 22993 22905
+f 22994 22995 22996
+f 22993 22908 15857
+f 13734 14227 8198
+f 22908 22997 22907
+f 21897 20843 20960
+f 15558 22038 22037
+f 17296 17298 2911
+f 22998 21042 17845
+f 19813 21012 20906
+f 7767 13903 13009
+f 22063 22534 22835
+f 22344 22305 22914
+f 22999 18964 17644
+f 17748 21388 20055
+f 17796 21301 23000
+f 16578 17710 16351
+f 23001 16579 16578
+f 16350 23001 16578
+f 23002 15988 16579
+f 23001 23002 16579
+f 23003 22916 15988
+f 23002 23003 15988
+f 23004 22917 22916
+f 23003 23004 22916
+f 23005 22918 22917
+f 23004 23005 22917
+f 23006 22919 22918
+f 23005 23006 22918
+f 23007 22920 22919
+f 23006 23007 22919
+f 9292 9466 9468
+f 22920 23007 19318
+f 21483 22643 21636
+f 9945 21534 9872
+f 21278 21431 21093
+f 4912 13734 13903
+f 21230 21369 21231
+f 20848 20947 20865
+f 21039 21038 21081
+f 20846 20848 20869
+f 6629 12666 21811
+f 6842 6737 6736
+f 506 20025 22326
+f 20753 7463 7465
+f 22922 22924 20025
+f 506 22922 20025
+f 20923 21640 21789
+f 8225 8224 8313
+f 16732 9832 13377
+f 20925 20923 21789
+f 18245 22682 22313
+f 23008 23009 15422
+f 21254 19953 19955
+f 9799 9884 9798
+f 20383 20943 20944
+f 14406 21883 1911
+f 13477 9391 9282
+f 16776 15750 16650
+f 16943 16942 22926
+f 5340 14923 23010
+f 16942 23011 22928
+f 22926 16942 22928
+f 23012 22929 22928
+f 23011 23012 22928
+f 23013 22930 22929
+f 23012 23013 22929
+f 23013 23014 22931
+f 22930 23013 22931
+f 23014 23015 22932
+f 22931 23014 22932
+f 23015 23016 22933
+f 22932 23015 22933
+f 23016 23017 22934
+f 22933 23016 22934
+f 23017 23018 22935
+f 22934 23017 22935
+f 23018 23019 22936
+f 22935 23018 22936
+f 23019 23020 22937
+f 22936 23019 22937
+f 23021 22938 22937
+f 23020 23021 22937
+f 22939 22859 22938
+f 23021 22939 22938
+f 9517 9519 2139
+f 18571 9345 1408
+f 9571 9570 20975
+f 8830 8829 21835
+f 1097 16413 1098
+f 11223 2460 13471
+f 17846 22984 17976
+f 15310 15217 15450
+f 23022 23023 23024
+f 1207 1178 12097
+f 14152 17819 3052
+f 2468 20288 2644
+f 16653 1851 1853
+f 1880 1882 23025
+f 6372 6371 23026
+f 23027 3539 23028
+f 15033 23029 15034
+f 5539 21660 21344
+f 22648 23025 5799
+f 17619 2474 2476
+f 5673 5257 5259
+f 981 2268 1385
+f 22952 17109 15341
+f 5397 5544 5398
+f 22984 18061 18063
+f 22958 23030 22004
+f 22959 4652 4654
+f 22572 22573 23031
+f 23032 22572 23031
+f 22140 17881 5509
+f 17881 18874 5509
+f 4968 5811 14694
+f 6084 4968 14694
+f 19431 23033 22966
+f 22878 22877 22965
+f 23033 23034 22967
+f 22966 23033 22967
+f 23034 23035 22968
+f 22967 23034 22968
+f 23035 23036 22969
+f 22968 23035 22969
+f 23036 23037 22970
+f 22969 23036 22970
+f 23037 23038 22971
+f 22970 23037 22971
+f 23038 23039 22972
+f 22971 23038 22972
+f 23039 23040 22973
+f 22972 23039 22973
+f 23041 22974 22973
+f 23040 23041 22973
+f 23042 22975 22974
+f 23041 23042 22974
+f 23043 22976 22975
+f 23042 23043 22975
+f 23043 23044 22977
+f 22976 23043 22977
+f 23044 23045 22978
+f 22977 23044 22978
+f 23045 23046 22979
+f 22978 23045 22979
+f 23046 23047 22980
+f 22979 23046 22980
+f 23047 23048 22981
+f 22980 23047 22981
+f 23048 23049 22982
+f 22981 23048 22982
+f 23049 18205 9472
+f 22982 23049 9472
+f 22551 14979 22552
+f 9472 18205 9473
+f 21046 21134 21047
+f 20849 21882 21725
+f 7745 4461 3634
+f 8757 8756 8897
+f 8957 5866 5865
+f 2991 5865 6537
+f 2047 21590 21552
+f 10950 23050 11019
+f 13344 13343 15311
+f 9109 3209 18331
+f 3209 16576 18331
+f 23051 11335 11933
+f 23052 17160 22437
+f 23053 23054 22986
+f 22985 23053 22986
+f 23054 23055 22987
+f 22986 23054 22987
+f 23055 23056 22988
+f 22987 23055 22988
+f 23057 22989 22988
+f 23056 23057 22988
+f 23058 22990 22989
+f 23057 23058 22989
+f 23059 22991 22990
+f 23058 23059 22990
+f 23060 22992 22991
+f 23059 23060 22991
+f 23061 22993 22992
+f 23060 23061 22992
+f 23062 22908 22993
+f 23061 23062 22993
+f 23063 22997 22908
+f 23062 23063 22908
+f 23064 23065 22997
+f 23063 23064 22997
+f 23066 22998 23065
+f 23064 23066 23065
+f 15509 15508 22998
+f 23066 15509 22998
+f 22534 22344 22914
+f 19058 15952 19842
+f 16351 17949 16349
+f 16349 17949 17209
+f 23067 16350 16349
+f 23068 23067 16349
+f 23069 23001 16350
+f 23067 23069 16350
+f 23070 23002 23001
+f 23069 23070 23001
+f 23071 23003 23002
+f 23070 23071 23002
+f 23072 23004 23003
+f 23071 23072 23003
+f 23073 23005 23004
+f 23072 23073 23004
+f 23073 23074 23006
+f 23005 23073 23006
+f 23074 23075 23007
+f 23006 23074 23007
+f 17102 12368 12370
+f 6723 6722 19298
+f 21088 21048 22392
+f 15133 9306 801
+f 9563 21340 9561
+f 21149 22143 20810
+f 20963 21713 21390
+f 21080 22423 21029
+f 20952 20898 20962
+f 21709 21835 8829
+f 21397 21713 20963
+f 506 505 19641
+f 9625 9585 21348
+f 6842 6736 6841
+f 18855 18856 19641
+f 19641 22922 506
+f 8511 21800 8510
+f 8224 8482 8313
+f 19641 23076 22922
+f 7440 4166 19605
+f 16139 16141 23077
+f 9116 21165 4188
+f 21442 20256 20258
+f 7066 7068 7157
+f 23078 15570 21565
+f 21186 21724 21187
+f 21394 21795 21395
+f 20962 21397 20963
+f 2193 5953 10168
+f 4178 4177 20885
+f 7744 3634 3246
+f 23079 23080 23081
+f 23082 23011 16942
+f 16944 23082 16942
+f 23082 23083 23012
+f 23011 23082 23012
+f 23083 23084 23013
+f 23012 23083 23013
+f 23084 18000 23014
+f 23013 23084 23014
+f 18000 23085 23015
+f 23014 18000 23015
+f 23085 23086 23016
+f 23015 23085 23016
+f 23086 23087 23017
+f 23016 23086 23017
+f 23088 23018 23017
+f 23087 23088 23017
+f 23089 23019 23018
+f 23088 23089 23018
+f 23090 23020 23019
+f 23089 23090 23019
+f 23090 23091 23021
+f 23020 23090 23021
+f 23091 9518 22939
+f 23021 23091 22939
+f 19979 16602 16601
+f 22939 9518 9517
+f 23092 23093 14778
+f 22102 1586 22159
+f 23094 16606 23095
+f 23096 20922 6940
+f 2565 23097 2503
+f 779 2959 8707
+f 9109 18331 15971
+f 11920 856 858
+f 3209 3208 16576
+f 14743 16497 16496
+f 18109 22551 2467
+f 22552 20288 2468
+f 22023 23098 22024
+f 23098 21563 22024
+f 14441 14440 15800
+f 1725 23099 15679
+f 23100 23101 23102
+f 23103 22309 2509
+f 5528 5530 1385
+f 5530 15674 1385
+f 6089 6090 4497
+f 5262 5676 5396
+f 22179 22002 22004
+f 23030 22958 22959
+f 23104 6381 6383
+f 23105 23106 6383
+f 21924 6656 22964
+f 17880 12104 18874
+f 5119 2835 5811
+f 3212 6084 14693
+f 23107 23033 19431
+f 384 4000 4002
+f 23108 23034 23033
+f 23107 23108 23033
+f 23109 23035 23034
+f 23108 23109 23034
+f 23109 23110 23036
+f 23035 23109 23036
+f 23110 23111 23037
+f 23036 23110 23037
+f 23112 23038 23037
+f 23111 23112 23037
+f 23112 23113 23039
+f 23038 23112 23039
+f 23113 23114 23040
+f 23039 23113 23040
+f 23115 23041 23040
+f 23114 23115 23040
+f 23116 23042 23041
+f 23115 23116 23041
+f 23117 23043 23042
+f 23116 23117 23042
+f 23118 23044 23043
+f 23117 23118 23043
+f 23118 23119 23045
+f 23044 23118 23045
+f 23119 23120 23046
+f 23045 23119 23046
+f 23120 23121 23047
+f 23046 23120 23047
+f 23121 23122 23048
+f 23047 23121 23048
+f 23122 23123 23049
+f 23048 23122 23049
+f 23123 23124 18205
+f 23049 23123 18205
+f 22518 4631 1888
+f 6353 3227 21536
+f 22014 1567 21792
+f 15455 16577 15989
+f 22783 14025 14024
+f 22965 22869 19429
+f 103 23125 101
+f 16881 20451 16882
+f 23126 23127 23128
+f 23129 23130 23131
+f 3365 16990 219
+f 8933 22518 16497
+f 3208 16496 16576
+f 11585 18120 14158
+f 2467 22552 2468
+f 22267 23132 23054
+f 23053 22267 23054
+f 23132 23133 23055
+f 23054 23132 23055
+f 23133 23134 23056
+f 23055 23133 23056
+f 23135 23057 23056
+f 23134 23135 23056
+f 23136 23058 23057
+f 23135 23136 23057
+f 23137 23059 23058
+f 23136 23137 23058
+f 23138 23060 23059
+f 23137 23138 23059
+f 23139 23061 23060
+f 23138 23139 23060
+f 23140 23062 23061
+f 23139 23140 23061
+f 23141 23063 23062
+f 23140 23141 23062
+f 23142 23064 23063
+f 23141 23142 23063
+f 23143 23066 23064
+f 23142 23143 23064
+f 23144 15509 23066
+f 23143 23144 23066
+f 23145 15510 15509
+f 23144 23145 15509
+f 23146 23068 15510
+f 23145 23146 15510
+f 23147 23067 23068
+f 23146 23147 23068
+f 23148 23069 23067
+f 23147 23148 23067
+f 23149 23070 23069
+f 23148 23149 23069
+f 23150 23071 23070
+f 23149 23150 23070
+f 23151 23072 23071
+f 23150 23151 23071
+f 23151 23152 23073
+f 23072 23151 23073
+f 23152 23153 23074
+f 23073 23152 23074
+f 23153 23009 23075
+f 23074 23153 23075
+f 19695 19884 19703
+f 3443 7639 6503
+f 21636 21088 22392
+f 1563 1565 21792
+f 20907 20909 21705
+f 20858 21273 21233
+f 9467 21694 21003
+f 9799 21996 21916
+f 8485 8483 20959
+f 20889 20891 21354
+f 21486 21056 21780
+f 21712 21094 21052
+f 20981 21263 1984
+f 2150 2151 18855
+f 21699 20931 9975
+f 20931 9976 9975
+f 7863 8048 7864
+f 21098 2665 21834
+f 18856 23154 23076
+f 19641 18856 23076
+f 23155 16141 23076
+f 23154 23155 23076
+f 23156 23157 23158
+f 23155 23077 16141
+f 3714 4078 16715
+f 23077 23156 23159
+f 18157 17936 22570
+f 23156 21454 23157
+f 1783 23008 15422
+f 9106 22570 18602
+f 20981 1984 20983
+f 9294 20833 21102
+f 20932 10209 10208
+f 23160 23161 21787
+f 9565 23160 21787
+f 23162 23082 16944
+f 23163 23162 16944
+f 6619 23083 23082
+f 23162 6619 23082
+f 6619 17999 23084
+f 23083 6619 23084
+f 3369 1657 14376
+f 23084 17999 18000
+f 16982 17999 14376
+f 18000 16982 23085
+f 18056 21501 23086
+f 23085 18056 23086
+f 21501 22422 23087
+f 23086 21501 23087
+f 22422 23164 23088
+f 23087 22422 23088
+f 23164 23165 23089
+f 23088 23164 23089
+f 23165 23166 23090
+f 23089 23165 23090
+f 23167 23091 23090
+f 23166 23167 23090
+f 23167 23168 9518
+f 23091 23167 9518
+f 23168 15322 9519
+f 9518 23168 9519
+f 10246 10165 10167
+f 14714 11721 19077
+f 23169 23170 15280
+f 1569 637 5730
+f 14174 14178 10946
+f 14525 14174 10946
+f 21939 14979 22551
+f 3208 14743 16496
+f 8383 17295 3156
+f 3452 8383 3156
+f 3051 2668 307
+f 23171 21563 21564
+f 177 176 5677
+f 9053 2471 18170
+f 16776 16775 16779
+f 23172 23173 19995
+f 15674 5530 16786
+f 5530 1723 16786
+f 23174 23175 23176
+f 19194 3430 2128
+f 23177 23178 23179
+f 22003 22958 22004
+f 17114 200 201
+f 23180 23181 6795
+f 21924 23182 12713
+f 2487 2489 2307
+f 23183 15079 21409
+f 6084 14694 14693
+f 13810 23184 23107
+f 13808 23107 19431
+f 23184 23185 23108
+f 23107 23184 23108
+f 23185 23186 23109
+f 23108 23185 23109
+f 23186 23187 23110
+f 23109 23186 23110
+f 23187 23188 23111
+f 23110 23187 23111
+f 23188 23189 23112
+f 23111 23188 23112
+f 23190 23113 23112
+f 23189 23190 23112
+f 23190 23191 23114
+f 23113 23190 23114
+f 23191 23192 23115
+f 23114 23191 23115
+f 23193 23116 23115
+f 23192 23193 23115
+f 23194 23117 23116
+f 23193 23194 23116
+f 23195 23118 23117
+f 23194 23195 23117
+f 23195 23196 23119
+f 23118 23195 23119
+f 23196 23197 23120
+f 23119 23196 23120
+f 23197 23198 23121
+f 23120 23197 23121
+f 23198 23199 23122
+f 23121 23198 23122
+f 23199 23200 23123
+f 23122 23199 23123
+f 15186 13533 13535
+f 3143 3145 23201
+f 23202 17588 15424
+f 12378 12379 10153
+f 17400 23203 16348
+f 10687 14930 10688
+f 21005 21684 23204
+f 20932 10280 10209
+f 23205 23206 23207
+f 10922 10808 12058
+f 1961 1960 6531
+f 14743 8933 16497
+f 20978 20977 21005
+f 16497 22518 1888
+f 21939 22519 22518
+f 9264 23208 22267
+f 22047 22401 16725
+f 23208 23209 23132
+f 22267 23208 23132
+f 23209 23210 23133
+f 23132 23209 23133
+f 23210 23211 23134
+f 23133 23210 23134
+f 23212 23135 23134
+f 23211 23212 23134
+f 23212 23213 23136
+f 23135 23212 23136
+f 23214 23137 23136
+f 23213 23214 23136
+f 23215 23138 23137
+f 23214 23215 23137
+f 23216 23139 23138
+f 23215 23216 23138
+f 23217 23140 23139
+f 23216 23217 23139
+f 23218 23141 23140
+f 23217 23218 23140
+f 23219 23142 23141
+f 23218 23219 23141
+f 23220 23143 23142
+f 23219 23220 23142
+f 23221 23144 23143
+f 23220 23221 23143
+f 23222 23145 23144
+f 23221 23222 23144
+f 23223 23146 23145
+f 23222 23223 23145
+f 23224 23147 23146
+f 23223 23224 23146
+f 23225 23148 23147
+f 23224 23225 23147
+f 23226 23149 23148
+f 23225 23226 23148
+f 23226 23227 23150
+f 23149 23226 23150
+f 23227 23228 23151
+f 23150 23227 23151
+f 23228 23229 23152
+f 23151 23228 23152
+f 23229 22496 23153
+f 23152 23229 23153
+f 15422 23009 23153
+f 22496 15422 23153
+f 10499 3178 10523
+f 21366 14362 14304
+f 21048 20929 21940
+f 22392 21048 21940
+f 21345 21256 21255
+f 13865 11584 14242
+f 20839 14572 22284
+f 21465 21263 20981
+f 8584 8583 22707
+f 1568 1571 1563
+f 22103 21725 22105
+f 14514 9166 9168
+f 20942 21682 21557
+f 9167 9976 9168
+f 12460 1245 1244
+f 10648 4481 9063
+f 21515 18640 18639
+f 12460 12459 23154
+f 18856 12460 23154
+f 12459 22347 23155
+f 23154 12459 23155
+f 22347 22274 23077
+f 23155 22347 23077
+f 9653 23156 23077
+f 22274 9653 23077
+f 21634 21454 23156
+f 9653 21634 23156
+f 9065 18640 21454
+f 21634 9065 21454
+f 20966 9541 9649
+f 15481 18639 9064
+f 21996 20845 21183
+f 2703 5168 9500
+f 21882 21752 21753
+f 6620 23162 23163
+f 19711 19622 23230
+f 23162 6620 6619
+f 21034 6494 6496
+f 23231 18397 6620
+f 20876 20878 21177
+f 9525 15148 21838
+f 694 693 9063
+f 20383 16189 20943
+f 19437 21733 19435
+f 21733 14965 14967
+f 19435 21733 14967
+f 21501 16711 22422
+f 16710 17945 23164
+f 22422 16710 23164
+f 17945 22375 23165
+f 23164 17945 23165
+f 22375 22211 23166
+f 23165 22375 23166
+f 22211 22213 23167
+f 23166 22211 23167
+f 22213 22376 23168
+f 23167 22213 23168
+f 22376 22215 15322
+f 23168 22376 15322
+f 15422 11151 1784
+f 19764 16916 7237
+f 7064 7065 6306
+f 3973 3978 9021
+f 18943 23232 17375
+f 14178 13812 11468
+f 3049 12072 14525
+f 6263 6387 21509
+f 2512 2664 2513
+f 20179 4466 459
+f 8383 11201 17295
+f 23233 23024 23023
+f 21563 23171 22024
+f 23234 23235 23236
+f 5259 5258 19243
+f 10430 2469 5674
+f 5797 10430 5674
+f 23237 23238 15676
+f 23239 5616 23240
+f 23241 23242 17211
+f 22146 22145 23243
+f 12320 3035 21809
+f 16231 8798 8797
+f 22698 23244 23245
+f 1337 12767 15085
+f 23246 22142 23247
+f 2465 3654 19995
+f 23107 13808 13810
+f 4888 16279 13810
+f 22837 23184 13810
+f 16279 22837 13810
+f 22836 23185 23184
+f 22837 22836 23184
+f 22340 23186 23185
+f 22836 22340 23185
+f 22339 23187 23186
+f 22340 22339 23186
+f 22339 22341 23188
+f 23187 22339 23188
+f 22341 22838 23189
+f 23188 22341 23189
+f 22480 23190 23189
+f 22838 22480 23189
+f 22380 23191 23190
+f 22480 22380 23190
+f 22411 23192 23191
+f 22380 22411 23191
+f 22338 23193 23192
+f 22411 22338 23192
+f 22337 23194 23193
+f 22338 22337 23193
+f 22297 23195 23194
+f 22337 22297 23194
+f 22297 22300 23196
+f 23195 22297 23196
+f 22300 22757 23197
+f 23196 22300 23197
+f 22757 22756 23198
+f 23197 22757 23198
+f 22756 22755 23199
+f 23198 22756 23199
+f 22755 22302 23200
+f 23199 22755 23200
+f 10018 10020 3773
+f 23248 23249 22303
+f 22648 1880 23025
+f 6091 6087 5972
+f 22289 22682 22172
+f 2312 14930 10687
+f 17725 23250 17726
+f 16464 22374 22375
+f 22571 21920 21922
+f 23251 13168 23252
+f 3048 14149 3049
+f 14874 14149 3048
+f 14979 14981 22552
+f 8933 21939 22518
+f 9344 22519 18109
+f 22519 9344 4631
+f 22553 17993 23208
+f 14693 3213 3212
+f 17993 22479 23209
+f 23208 17993 23209
+f 22479 22444 23210
+f 23209 22479 23210
+f 22443 23211 23210
+f 22444 22443 23210
+f 22443 22631 23212
+f 23211 22443 23212
+f 22631 22684 23213
+f 23212 22631 23213
+f 22684 22752 23214
+f 23213 22684 23214
+f 22835 23215 23214
+f 22752 22835 23214
+f 22914 23216 23215
+f 22835 22914 23215
+f 22305 23217 23216
+f 22914 22305 23216
+f 22265 23218 23217
+f 22305 22265 23217
+f 22260 23219 23218
+f 22265 22260 23218
+f 22262 23220 23219
+f 22260 22262 23219
+f 22257 23221 23220
+f 22262 22257 23220
+f 22256 23222 23221
+f 22257 22256 23221
+f 22264 23223 23222
+f 22256 22264 23222
+f 22685 23224 23223
+f 22264 22685 23223
+f 22686 23225 23224
+f 22685 22686 23224
+f 22687 23226 23225
+f 22686 22687 23225
+f 22687 22688 23227
+f 23226 22687 23227
+f 22688 22689 23228
+f 23227 22688 23228
+f 22689 22298 23229
+f 23228 22689 23229
+f 22298 11151 22496
+f 23229 22298 22496
+f 14276 16507 19729
+f 5162 18922 6887
+f 23253 8400 3456
+f 23253 8556 8400
+f 23254 23255 23256
+f 23257 17178 23258
+f 23259 22027 23260
+f 23261 23262 8555
+f 23263 23264 23265
+f 2393 23266 23267
+f 1580 6502 6504
+f 23268 2393 23267
+f 19150 6240 6242
+f 23269 23270 23271
+f 23272 14898 23273
+f 23274 23275 23276
+f 23277 23278 23279
+f 23280 23281 1165
+f 23282 23283 23284
+f 23285 23286 23287
+f 23288 23289 23290
+f 5603 5721 14803
+f 23255 17357 23291
+f 23292 23254 23256
+f 23259 23260 23293
+f 23294 23259 23293
+f 23266 2393 8791
+f 23295 23263 23265
+f 23296 23269 23297
+f 2393 2395 8791
+f 3981 9795 23298
+f 23299 23296 23297
+f 23300 7448 10522
+f 5378 13394 14043
+f 23301 16819 16818
+f 20546 20748 17722
+f 5814 5813 23302
+f 2481 23303 23304
+f 23305 23306 23279
+f 2482 2481 23304
+f 23307 5548 23308
+f 23309 23305 23279
+f 23099 2845 5548
+f 23310 23282 23284
+f 22822 2727 2520
+f 16071 18332 23311
+f 1106 1513 17302
+f 23256 23255 23291
+f 22895 23312 16252
+f 22027 23313 22028
+f 23314 23296 23299
+f 2395 23315 8792
+f 23316 23317 23318
+f 14888 23314 23299
+f 23319 8990 22784
+f 23317 23320 23318
+f 3092 3739 23321
+f 23322 23323 23324
+f 23303 23325 23326
+f 23327 23301 16818
+f 23304 23303 23326
+f 23325 23328 23329
+f 23326 23325 23329
+f 23330 2945 23331
+f 23328 23332 23333
+f 3739 4448 17672
+f 23321 3739 17672
+f 23334 23335 23336
+f 23337 23338 23339
+f 23340 7329 23341
+f 22346 23342 14586
+f 23343 23344 4338
+f 5111 4338 23344
+f 23344 5112 5111
+f 5110 21330 22160
+f 5112 23345 5110
+f 23345 22031 5110
+f 23346 6240 23347
+f 14224 14223 23347
+f 23348 23349 23350
+f 23351 23352 16935
+f 17811 1636 2812
+f 23353 23354 23355
+f 23331 2947 23356
+f 23356 3092 23321
+f 23329 23328 23333
+f 23332 23357 23358
+f 20748 23359 17746
+f 10175 9950 20712
+f 17729 20748 17746
+f 23333 23332 23358
+f 2945 2947 23331
+f 23357 23360 23361
+f 2947 3092 23356
+f 11223 13471 9322
+f 17289 10310 10312
+f 13168 23251 19194
+f 8787 23362 23363
+f 23364 23365 23366
+f 23252 23367 23343
+f 23368 23343 4337
+f 23369 23344 23343
+f 23367 23369 23343
+f 23369 23370 5112
+f 23344 23369 5112
+f 23370 23371 23345
+f 5112 23370 23345
+f 23371 23372 23373
+f 23345 23371 23373
+f 23372 23374 22598
+f 5391 23375 23376
+f 14958 5392 23377
+f 23376 5392 5391
+f 23378 23379 16159
+f 15594 23380 15595
+f 23379 23381 23382
+f 12974 23383 3042
+f 18840 18875 18880
+f 23381 23384 23382
+f 23359 23385 17748
+f 17746 23359 17748
+f 23358 23357 23361
+f 2125 2945 23386
+f 23360 23387 14880
+f 23388 23389 19985
+f 17456 12768 1337
+f 23390 13167 12768
+f 23391 23390 12768
+f 23392 13168 13167
+f 23390 23392 13167
+f 23343 23251 23252
+f 23392 23393 13168
+f 23393 23394 23367
+f 23252 23393 23367
+f 23394 23395 23369
+f 23367 23394 23369
+f 23395 23396 23370
+f 23369 23395 23370
+f 23396 23397 23371
+f 23370 23396 23371
+f 23397 23398 23372
+f 23371 23397 23372
+f 23398 23399 23374
+f 23372 23398 23374
+f 23399 23400 23378
+f 23374 23399 23378
+f 23400 23401 23379
+f 23378 23400 23379
+f 23401 23402 23381
+f 23379 23401 23381
+f 23403 23384 23381
+f 23402 23403 23381
+f 544 678 677
+f 17922 9322 14227
+f 23361 23360 14880
+f 23387 23404 14881
+f 21884 23405 17456
+f 16210 23406 16211
+f 23407 23391 23405
+f 23408 23407 23405
+f 23409 23390 23391
+f 23407 23409 23391
+f 23410 23392 23390
+f 23409 23410 23390
+f 23411 23393 23392
+f 23410 23411 23392
+f 23411 23412 23394
+f 23393 23411 23394
+f 23412 23413 23395
+f 23394 23412 23395
+f 23413 23414 23396
+f 23395 23413 23396
+f 23414 23415 23397
+f 23396 23414 23397
+f 23415 23416 23398
+f 23397 23415 23398
+f 23416 23417 23399
+f 23398 23416 23399
+f 23417 23418 23400
+f 23399 23417 23400
+f 23418 23419 23401
+f 23400 23418 23401
+f 23419 23420 23402
+f 23401 23419 23402
+f 23421 21745 23422
+f 23423 23424 23425
+f 15995 16602 17104
+f 14880 23387 14881
+f 23426 17331 14817
+f 22475 18043 23427
+f 23428 23408 23429
+f 23430 23428 23429
+f 23431 23407 23408
+f 23428 23431 23408
+f 23432 23409 23407
+f 23431 23432 23407
+f 23433 23410 23409
+f 23432 23433 23409
+f 23434 23411 23410
+f 23433 23434 23410
+f 23434 23435 23412
+f 23411 23434 23412
+f 23435 23436 23413
+f 23412 23435 23413
+f 23436 23437 23414
+f 23413 23436 23414
+f 23437 23438 23415
+f 23414 23437 23415
+f 23438 23439 23416
+f 23415 23438 23416
+f 23439 23440 23417
+f 23416 23439 23417
+f 23440 23441 23418
+f 23417 23440 23418
+f 23441 23442 23419
+f 23418 23441 23419
+f 23442 2140 23420
+f 23419 23442 23420
+f 14155 3835 3836
+f 3702 2999 3001
+f 23404 23443 16738
+f 23444 23445 23446
+f 14881 23404 16738
+f 23447 23430 15410
+f 15410 22045 15411
+f 23448 23428 23430
+f 23447 23448 23430
+f 23449 23431 23428
+f 23448 23449 23428
+f 23450 23432 23431
+f 23449 23450 23431
+f 23451 23433 23432
+f 23450 23451 23432
+f 23451 23452 23434
+f 23433 23451 23434
+f 23452 23453 23435
+f 23434 23452 23435
+f 23453 23454 23436
+f 23435 23453 23436
+f 23454 23455 23437
+f 23436 23454 23437
+f 23455 23456 23438
+f 23437 23455 23438
+f 23456 23457 23439
+f 23438 23456 23439
+f 23457 23458 23440
+f 23439 23457 23440
+f 23458 23459 23441
+f 23440 23458 23441
+f 23459 23460 23442
+f 23441 23459 23442
+f 23460 2141 2140
+f 23442 23460 2140
+f 15091 13563 14675
+f 10921 15417 10922
+f 9734 23403 1782
+f 23443 23461 16739
+f 23462 23463 15412
+f 17675 23464 4649
+f 23465 23447 15412
+f 23463 23465 15412
+f 23466 23448 23447
+f 23465 23466 23447
+f 23467 23449 23448
+f 23466 23467 23448
+f 23468 23450 23449
+f 23467 23468 23449
+f 23468 23469 23451
+f 23450 23468 23451
+f 23469 23470 23452
+f 23451 23469 23452
+f 23470 23471 23453
+f 23452 23470 23453
+f 23471 23472 23454
+f 23453 23471 23454
+f 23472 23473 23455
+f 23454 23472 23455
+f 23473 23474 23456
+f 23455 23473 23456
+f 23474 23475 23457
+f 23456 23474 23457
+f 23475 23476 23458
+f 23457 23475 23458
+f 23476 23477 23459
+f 23458 23476 23459
+f 23477 23478 23460
+f 23459 23477 23460
+f 20150 2141 23460
+f 23478 20150 23460
+f 17528 7231 16504
+f 16055 22758 16056
+f 4971 7650 1100
+f 23479 23480 23462
+f 17579 6742 6741
+f 23481 23463 23462
+f 23480 23481 23462
+f 23482 23465 23463
+f 23481 23482 23463
+f 23483 23466 23465
+f 23482 23483 23465
+f 23484 23467 23466
+f 23483 23484 23466
+f 23485 23468 23467
+f 23484 23485 23467
+f 23485 23486 23469
+f 23468 23485 23469
+f 23486 23487 23470
+f 23469 23486 23470
+f 23487 23488 23471
+f 23470 23487 23471
+f 23488 23489 23472
+f 23471 23488 23472
+f 23489 23490 23473
+f 23472 23489 23473
+f 23490 23491 23474
+f 23473 23490 23474
+f 23491 23492 23475
+f 23474 23491 23475
+f 23492 23493 23476
+f 23475 23492 23476
+f 23493 23494 23477
+f 23476 23493 23477
+f 23494 23495 23478
+f 23477 23494 23478
+f 23495 19439 23478
+f 2747 8360 7010
+f 677 676 15656
+f 9854 8134 8136
+f 16131 16132 23479
+f 16862 16643 16861
+f 23496 23497 23480
+f 23479 23496 23480
+f 23498 23481 23480
+f 23497 23498 23480
+f 23498 23499 23482
+f 23481 23498 23482
+f 23500 23483 23482
+f 23499 23500 23482
+f 23501 23484 23483
+f 23500 23501 23483
+f 23501 23502 23485
+f 23484 23501 23485
+f 23502 23503 23486
+f 23485 23502 23486
+f 23503 23504 23487
+f 23486 23503 23487
+f 23504 23505 23488
+f 23487 23504 23488
+f 23505 23506 23489
+f 23488 23505 23489
+f 23506 23507 23490
+f 23489 23506 23490
+f 23507 23508 23491
+f 23490 23507 23491
+f 23508 23509 23492
+f 23491 23508 23492
+f 23509 23510 23493
+f 23492 23509 23493
+f 23510 20832 23494
+f 23493 23510 23494
+f 20832 19440 23495
+f 23494 20832 23495
+f 610 1556 604
+f 530 7744 3245
+f 4796 400 17827
+f 23272 23273 20259
+f 16738 23443 16739
+f 23511 23497 23496
+f 2487 16798 2488
+f 23512 23498 23497
+f 23511 23512 23497
+f 23513 23499 23498
+f 23512 23513 23498
+f 23513 23514 23500
+f 23499 23513 23500
+f 23515 23501 23500
+f 23514 23515 23500
+f 23515 23516 23502
+f 23501 23515 23502
+f 23516 23517 23503
+f 23502 23516 23503
+f 23517 23518 23504
+f 23503 23517 23504
+f 23518 23519 23505
+f 23504 23518 23505
+f 23519 23520 23506
+f 23505 23519 23506
+f 23520 23521 23507
+f 23506 23520 23507
+f 23521 23522 23508
+f 23507 23521 23508
+f 23522 23523 23509
+f 23508 23522 23509
+f 23523 23524 23510
+f 23509 23523 23510
+f 23524 20859 20832
+f 23510 23524 20832
+f 17105 17157 4464
+f 22690 22691 22758
+f 23525 17435 16477
+f 20832 20859 20831
+f 23461 23526 23527
+f 23528 15668 23529
+f 14225 14506 18533
+f 23530 23511 23531
+f 23532 23530 23531
+f 23533 23512 23511
+f 23530 23533 23511
+f 23534 23513 23512
+f 23533 23534 23512
+f 23534 23535 23514
+f 23513 23534 23514
+f 23536 23515 23514
+f 23535 23536 23514
+f 23536 23537 23516
+f 23515 23536 23516
+f 23537 23538 23517
+f 23516 23537 23517
+f 23538 23539 23518
+f 23517 23538 23518
+f 23539 23540 23519
+f 23518 23539 23519
+f 23540 23541 23520
+f 23519 23540 23520
+f 23541 23542 23521
+f 23520 23541 23521
+f 23542 23543 23522
+f 23521 23542 23522
+f 23543 23544 23523
+f 23522 23543 23523
+f 23544 20860 23524
+f 23523 23544 23524
+f 20860 20861 20859
+f 23524 20860 20859
+f 23545 23546 23547
+f 19166 20859 20861
+f 14029 18576 18575
+f 22872 23548 23549
+f 14841 17799 17286
+f 16739 23461 23527
+f 23550 23528 23529
+f 23529 15668 20412
+f 23551 23530 23532
+f 21730 23551 23532
+f 23552 23533 23530
+f 23551 23552 23530
+f 23553 23534 23533
+f 23552 23553 23533
+f 23553 23554 23535
+f 23534 23553 23535
+f 23554 23555 23536
+f 23535 23554 23536
+f 23555 23556 23537
+f 23536 23555 23537
+f 23556 23557 23538
+f 23537 23556 23538
+f 23557 23558 23539
+f 23538 23557 23539
+f 23558 23559 23540
+f 23539 23558 23540
+f 23559 23560 23541
+f 23540 23559 23541
+f 23560 23561 23542
+f 23541 23560 23542
+f 23561 23562 23543
+f 23542 23561 23543
+f 23562 23563 23544
+f 23543 23562 23544
+f 23563 18998 20860
+f 23544 23563 20860
+f 20647 19487 16072
+f 16052 2098 304
+f 23564 23565 2190
+f 18998 18997 20860
+f 23566 22390 23567
+f 23568 11469 22995
+f 23569 23570 23571
+f 23572 21730 21729
+f 23573 23572 21729
+f 23574 23551 21730
+f 23572 23574 21730
+f 23575 23552 23551
+f 23574 23575 23551
+f 23576 23553 23552
+f 23575 23576 23552
+f 23576 23577 23554
+f 23553 23576 23554
+f 23577 23578 23555
+f 23554 23577 23555
+f 23578 23579 23556
+f 23555 23578 23556
+f 23579 23580 23557
+f 23556 23579 23557
+f 23580 23581 23558
+f 23557 23580 23558
+f 23581 23582 23559
+f 23558 23581 23559
+f 23582 23583 23560
+f 23559 23582 23560
+f 23583 23584 23561
+f 23560 23583 23561
+f 23584 23585 23562
+f 23561 23584 23562
+f 23585 23586 23563
+f 23562 23585 23563
+f 23586 2743 18998
+f 23563 23586 18998
+f 16330 14500 7464
+f 23587 23588 23589
+f 17576 23590 15768
+f 16771 16770 19410
+f 2745 18998 2743
+f 14437 23591 23573
+f 23592 5508 5507
+f 23593 23572 23573
+f 23591 23593 23573
+f 23594 23574 23572
+f 23593 23594 23572
+f 23595 23575 23574
+f 23594 23595 23574
+f 23596 23576 23575
+f 23595 23596 23575
+f 23596 23597 23577
+f 23576 23596 23577
+f 23597 23598 23578
+f 23577 23597 23578
+f 23598 23599 23579
+f 23578 23598 23579
+f 23599 23600 23580
+f 23579 23599 23580
+f 23600 23601 23581
+f 23580 23600 23581
+f 23601 23602 23582
+f 23581 23601 23582
+f 23602 23603 23583
+f 23582 23602 23583
+f 23603 23604 23584
+f 23583 23603 23584
+f 23604 23605 23585
+f 23584 23604 23585
+f 23605 9309 23586
+f 23585 23605 23586
+f 7236 17105 17603
+f 21643 23606 21700
+f 18776 23607 17704
+f 23608 17696 15732
+f 16422 23564 2190
+f 23609 16622 19488
+f 19785 23610 23611
+f 23612 23591 14437
+f 23613 23612 14437
+f 23614 23593 23591
+f 23612 23614 23591
+f 23615 23594 23593
+f 23614 23615 23593
+f 23616 23595 23594
+f 23615 23616 23594
+f 23616 23617 23596
+f 23595 23616 23596
+f 23617 23618 23597
+f 23596 23617 23597
+f 23618 23619 23598
+f 23597 23618 23598
+f 23619 23620 23599
+f 23598 23619 23599
+f 23620 23621 23600
+f 23599 23620 23600
+f 23621 23622 23601
+f 23600 23621 23601
+f 23622 23623 23602
+f 23601 23622 23602
+f 23623 23624 23603
+f 23602 23623 23603
+f 23624 23625 23604
+f 23603 23624 23604
+f 23625 15706 23605
+f 23604 23625 23605
+f 23547 23626 23545
+f 23605 15706 9309
+f 12701 953 12702
+f 5664 1809 7053
+f 2112 1104 9224
+f 4942 4333 4332
+f 17296 2911 2562
+f 3131 6641 1175
+f 23627 23612 23613
+f 23628 23627 23613
+f 23629 23614 23612
+f 23627 23629 23612
+f 23630 23615 23614
+f 23629 23630 23614
+f 23631 23616 23615
+f 23630 23631 23615
+f 23631 23632 23617
+f 23616 23631 23617
+f 23632 23633 23618
+f 23617 23632 23618
+f 23633 23634 23619
+f 23618 23633 23619
+f 23634 23635 23620
+f 23619 23634 23620
+f 23635 23636 23621
+f 23620 23635 23621
+f 23636 23637 23622
+f 23621 23636 23622
+f 23637 23638 23623
+f 23622 23637 23623
+f 23638 23639 23624
+f 23623 23638 23624
+f 23639 23640 23625
+f 23624 23639 23625
+f 23640 15705 15706
+f 23625 23640 15706
+f 17999 6619 3369
+f 14227 2971 8198
+f 1102 3142 1103
+f 18003 18002 23641
+f 23642 12541 12540
+f 10025 12886 23643
+f 23644 11228 23645
+f 13563 12796 14675
+f 925 1096 1082
+f 23646 23627 23628
+f 23644 23647 21119
+f 23648 23629 23627
+f 23646 23648 23627
+f 23649 23630 23629
+f 23648 23649 23629
+f 23650 23631 23630
+f 23649 23650 23630
+f 23650 23651 23632
+f 23631 23650 23632
+f 23651 23652 23633
+f 23632 23651 23633
+f 23652 23653 23634
+f 23633 23652 23634
+f 23653 23654 23635
+f 23634 23653 23635
+f 23654 23655 23636
+f 23635 23654 23636
+f 23655 23656 23637
+f 23636 23655 23637
+f 23656 23657 23638
+f 23637 23656 23638
+f 23657 23658 23639
+f 23638 23657 23639
+f 23658 23659 23640
+f 23639 23658 23640
+f 23659 16665 15705
+f 23640 23659 15705
+f 16698 23660 16696
+f 22629 15419 17992
+f 16006 6647 2620
+f 7667 7319 17447
+f 17287 14871 14546
+f 985 15216 986
+f 22840 22841 15454
+f 16443 16327 23661
+f 23662 23423 23425
+f 16329 14018 23663
+f 23647 23646 21119
+f 23664 23648 23646
+f 23647 23664 23646
+f 23665 23649 23648
+f 23664 23665 23648
+f 23666 23650 23649
+f 23665 23666 23649
+f 23666 23667 23651
+f 23650 23666 23651
+f 23667 23668 23652
+f 23651 23667 23652
+f 23668 23669 23653
+f 23652 23668 23653
+f 23669 23670 23654
+f 23653 23669 23654
+f 23670 23671 23655
+f 23654 23670 23655
+f 23671 23672 23656
+f 23655 23671 23656
+f 23672 23673 23657
+f 23656 23672 23657
+f 23673 23674 23658
+f 23657 23673 23658
+f 23674 23610 23659
+f 23658 23674 23659
+f 15479 16624 14942
+f 23659 23610 16665
+f 18839 16857 8046
+f 20081 17650 17260
+f 12538 12537 21561
+f 3378 16771 19410
+f 21515 21453 18640
+f 18545 21173 17606
+f 23675 20081 17260
+f 3456 3458 6595
+f 23676 23647 23644
+f 23645 23676 23644
+f 23677 23664 23647
+f 23676 23677 23647
+f 23677 23678 23665
+f 23664 23677 23665
+f 23678 23679 23666
+f 23665 23678 23666
+f 23679 23680 23667
+f 23666 23679 23667
+f 23680 23681 23668
+f 23667 23680 23668
+f 23681 23682 23669
+f 23668 23681 23669
+f 23682 23683 23670
+f 23669 23682 23670
+f 23683 23684 23671
+f 23670 23683 23671
+f 23684 23685 23672
+f 23671 23684 23672
+f 23685 23686 23673
+f 23672 23685 23673
+f 23686 23687 23674
+f 23673 23686 23674
+f 23687 23611 23610
+f 23674 23687 23610
+f 14500 10327 3963
+f 23610 19785 16665
+f 17060 19886 17059
+f 9301 17771 17772
+f 18751 18442 22747
+f 15453 22915 15454
+f 23385 22112 17748
+f 16159 16158 23378
+f 22326 19642 507
+f 9854 8136 9855
+f 9309 19303 23586
+f 16857 4332 16858
+f 18775 15814 15913
+f 4779 4778 22907
+f 22659 21701 14978
+f 17769 3008 14294
+f 15508 17209 17949
+f 16791 22897 16792
+f 3969 11228 23644
+f 22283 10953 6377
+f 23688 23676 23645
+f 19860 23688 23645
+f 23689 23677 23676
+f 23688 23689 23676
+f 23690 23678 23677
+f 23689 23690 23677
+f 23690 23691 23679
+f 23678 23690 23679
+f 23691 23692 23680
+f 23679 23691 23680
+f 23692 23693 23681
+f 23680 23692 23681
+f 23693 23694 23682
+f 23681 23693 23682
+f 23694 23695 23683
+f 23682 23694 23683
+f 23695 23696 23684
+f 23683 23695 23684
+f 23696 23697 23685
+f 23684 23696 23685
+f 23697 23698 23686
+f 23685 23697 23686
+f 23698 23699 23687
+f 23686 23698 23687
+f 23699 17058 23611
+f 23687 23699 23611
+f 4779 8043 9731
+f 9339 15966 20055
+f 1849 1848 23700
+f 17258 17260 22318
+f 23526 23701 23702
+f 23703 23704 23705
+f 23527 23526 23702
+f 23706 23707 23708
+f 23709 23706 23708
+f 6504 7009 1362
+f 7366 13293 23710
+f 23711 16971 23712
+f 23713 23714 23715
+f 23716 23717 23718
+f 23719 16616 16734
+f 16259 16258 17494
+f 23720 23721 23722
+f 17500 3983 3982
+f 10955 10097 10956
+f 23723 23724 23725
+f 23726 16352 23727
+f 14870 23728 14871
+f 976 23729 6225
+f 15482 7571 16332
+f 14782 19981 17843
+f 15685 14872 17287
+f 23730 16522 17787
+f 23731 23732 15892
+f 14061 20183 14062
+f 9302 16007 17147
+f 14018 14017 23663
+f 17296 20649 17297
+f 8721 19785 17058
+f 23733 19860 17298
+f 17297 23733 17298
+f 23734 23688 19860
+f 23733 23734 19860
+f 23735 23689 23688
+f 23734 23735 23688
+f 23736 23690 23689
+f 23735 23736 23689
+f 23736 23737 23691
+f 23690 23736 23691
+f 23737 23738 23692
+f 23691 23737 23692
+f 23738 23739 23693
+f 23692 23738 23693
+f 23739 23740 23694
+f 23693 23739 23694
+f 23740 23741 23695
+f 23694 23740 23695
+f 23741 23742 23696
+f 23695 23741 23696
+f 23742 23743 23697
+f 23696 23742 23697
+f 23743 23744 23698
+f 23697 23743 23698
+f 23744 17060 23699
+f 23698 23744 23699
+f 23159 23158 16139
+f 23699 17060 17058
+f 16353 4777 19596
+f 11233 22600 16774
+f 14960 2629 18463
+f 23745 16494 23746
+f 23701 23747 23748
+f 23702 23701 23748
+f 23749 23750 23748
+f 23747 23749 23748
+f 23751 23752 23750
+f 23749 23751 23750
+f 17186 17196 23753
+f 23754 23755 23752
+f 23756 23757 23758
+f 23759 17186 23753
+f 23320 16106 16203
+f 23760 23761 23762
+f 23763 23764 21249
+f 3982 3981 23765
+f 16615 23766 16735
+f 23767 23713 23715
+f 23768 23769 39
+f 4641 10228 9743
+f 23770 16820 23771
+f 23772 23773 23774
+f 16820 23775 23771
+f 23776 23777 17401
+f 23727 15665 23778
+f 20156 23779 19371
+f 18946 19003 18907
+f 6293 6075 6355
+f 797 6225 23780
+f 23781 23782 23783
+f 23784 549 23785
+f 767 797 23780
+f 603 767 23780
+f 23785 603 23780
+f 540 1939 17164
+f 23786 23787 23788
+f 16711 17139 16709
+f 4765 18123 16303
+f 7632 16120 7633
+f 20649 23789 17297
+f 20650 20649 17296
+f 23790 23733 17297
+f 23789 23790 17297
+f 23790 23791 23734
+f 23733 23790 23734
+f 23792 23735 23734
+f 23791 23792 23734
+f 23793 23736 23735
+f 23792 23793 23735
+f 23793 23794 23737
+f 23736 23793 23737
+f 23794 23795 23738
+f 23737 23794 23738
+f 23795 23796 23739
+f 23738 23795 23739
+f 23796 23797 23740
+f 23739 23796 23740
+f 23797 23798 23741
+f 23740 23797 23741
+f 23798 23799 23742
+f 23741 23798 23742
+f 23799 23800 23743
+f 23742 23799 23743
+f 23800 21142 23744
+f 23743 23800 23744
+f 21142 19886 17060
+f 23744 21142 17060
+f 23801 871 870
+f 19431 22965 19429
+f 16479 16353 19596
+f 4777 4779 9730
+f 17947 23802 4940
+f 8045 8044 12885
+f 23751 23754 23752
+f 7574 7477 21485
+f 23754 23803 23804
+f 2945 23330 23386
+f 23805 23806 23807
+f 23808 23809 15667
+f 2125 23386 23810
+f 16037 23811 16240
+f 12228 17833 3366
+f 23812 23813 23814
+f 23815 23816 23817
+f 23718 23818 23819
+f 23820 23812 23814
+f 23821 23822 23823
+f 23824 23825 23826
+f 23827 855 16339
+f 11707 6212 5928
+f 23775 16824 23828
+f 17567 23829 17568
+f 23830 23831 23832
+f 17801 17846 17371
+f 23833 23831 23830
+f 23778 23833 23830
+f 23834 23835 23836
+f 23831 23723 23832
+f 23837 23838 23839
+f 23840 23786 23841
+f 23782 23842 23783
+f 23843 23844 23781
+f 541 540 10381
+f 23845 23846 23847
+f 4786 541 10381
+f 23848 23849 23850
+f 10381 540 17164
+f 1939 1794 17165
+f 23851 23852 15958
+f 23853 466 23784
+f 23854 23855 23856
+f 17897 23857 23858
+f 17894 23859 23860
+f 23861 23862 23789
+f 20649 23861 23789
+f 23863 23790 23789
+f 23862 23863 23789
+f 23864 23791 23790
+f 23863 23864 23790
+f 23865 23792 23791
+f 23864 23865 23791
+f 23865 23866 23793
+f 23792 23865 23793
+f 23866 23867 23794
+f 23793 23866 23794
+f 23867 23868 23795
+f 23794 23867 23795
+f 23868 23869 23796
+f 23795 23868 23796
+f 23869 23870 23797
+f 23796 23869 23797
+f 23870 23871 23798
+f 23797 23870 23798
+f 23871 23872 23799
+f 23798 23871 23799
+f 23872 23873 23800
+f 23799 23872 23800
+f 23873 21143 21142
+f 23800 23873 21142
+f 4954 10584 21666
+f 20461 21526 20504
+f 17771 9301 15760
+f 9403 2811 9404
+f 8047 17759 17138
+f 17435 16478 16477
+f 9301 9300 20299
+f 23755 23754 23804
+f 23803 23874 23875
+f 23804 23803 23875
+f 23876 23877 23875
+f 23874 23876 23875
+f 9136 15012 9996
+f 23876 22254 23877
+f 23878 23879 23880
+f 23881 23882 16209
+f 17177 23883 23884
+f 18876 23885 23886
+f 23887 23888 23889
+f 23890 23891 23892
+f 926 928 1275
+f 23893 23894 23895
+f 23384 9736 17980
+f 23896 23897 23898
+f 23297 23269 23271
+f 23899 17341 17343
+f 16616 16615 16735
+f 23270 15845 23900
+f 23901 23902 23903
+f 23904 22777 22726
+f 17573 23905 23906
+f 23907 23908 23909
+f 23725 23724 23910
+f 17574 23906 23910
+f 23911 23912 23913
+f 17648 17574 23910
+f 6656 22963 22964
+f 22963 21613 21615
+f 21615 23914 22964
+f 23915 23182 22964
+f 23182 23916 12713
+f 23914 23915 22964
+f 12714 23916 18821
+f 23915 23917 23182
+f 16796 19981 21063
+f 23917 18821 23916
+f 23918 23919 23920
+f 23921 23922 18820
+f 23923 15700 23924
+f 23925 23926 23726
+f 549 603 23785
+f 17164 1939 17165
+f 15678 15677 23927
+f 466 549 23784
+f 23856 23928 16756
+f 6255 23929 6253
+f 6235 6237 3813
+f 15884 14052 12666
+f 23930 23931 23862
+f 23861 23930 23862
+f 23932 23863 23862
+f 23931 23932 23862
+f 23933 23864 23863
+f 23932 23933 23863
+f 23934 23865 23864
+f 23933 23934 23864
+f 23934 23935 23866
+f 23865 23934 23866
+f 23935 23936 23867
+f 23866 23935 23867
+f 23936 23937 23868
+f 23867 23936 23868
+f 23937 23938 23869
+f 23868 23937 23869
+f 23938 23939 23870
+f 23869 23938 23870
+f 23939 23940 23871
+f 23870 23939 23871
+f 23940 23941 23872
+f 23871 23940 23872
+f 23941 23942 23873
+f 23872 23941 23873
+f 21155 21143 23873
+f 23942 21155 23873
+f 19885 21143 21155
+f 22995 22985 22899
+f 23943 2455 17148
+f 16341 21155 21172
+f 23944 14782 2104
+f 16465 17808 892
+f 23882 20750 22717
+f 23945 17404 23946
+f 16221 16223 23947
+f 15667 23809 23948
+f 23949 23950 23951
+f 23952 331 330
+f 23273 23953 15666
+f 23954 23955 23956
+f 11161 11160 8367
+f 23957 23958 16615
+f 23809 23805 23948
+f 3329 4958 23959
+f 16614 23957 16615
+f 23960 15885 23961
+f 23962 23963 23831
+f 21212 21211 22896
+f 23964 4471 23965
+f 21888 23966 21889
+f 22512 21889 23967
+f 23966 21775 23967
+f 21775 21777 23967
+f 21775 23968 21776
+f 23969 21776 23968
+f 23968 23970 23969
+f 23969 23970 22141
+f 23970 23971 22141
+f 22141 17879 17881
+f 23971 23972 17879
+f 21614 17879 23972
+f 23972 23973 21614
+f 21614 21613 17880
+f 23974 21615 21614
+f 23973 23974 21614
+f 23975 23914 21615
+f 23974 23975 21615
+f 23976 23915 23914
+f 23975 23976 23914
+f 23977 23917 23915
+f 23976 23977 23915
+f 23978 18821 23917
+f 23977 23978 23917
+f 23979 18820 18821
+f 23978 23979 18821
+f 23980 23981 23982
+f 23983 23921 23984
+f 23985 23986 23708
+f 23983 23922 23921
+f 23987 425 23853
+f 17277 16221 23947
+f 17137 4944 1672
+f 2344 2342 17883
+f 20722 20721 22594
+f 23988 16089 23930
+f 3812 6235 3813
+f 16089 23989 23931
+f 23930 16089 23931
+f 23990 23932 23931
+f 23989 23990 23931
+f 23991 23933 23932
+f 23990 23991 23932
+f 23992 23934 23933
+f 23991 23992 23933
+f 23992 23993 23935
+f 23934 23992 23935
+f 23993 23994 23936
+f 23935 23993 23936
+f 23994 23995 23937
+f 23936 23994 23937
+f 23995 23996 23938
+f 23937 23995 23938
+f 23996 23997 23939
+f 23938 23996 23939
+f 23997 23998 23940
+f 23939 23997 23940
+f 23998 23999 23941
+f 23940 23998 23941
+f 23999 24000 23942
+f 23941 23999 23942
+f 24000 21172 21155
+f 23942 24000 21155
+f 12890 22481 12891
+f 553 24001 778
+f 12159 8661 13812
+f 17817 1604 17818
+f 1096 925 924
+f 12886 12885 23642
+f 24002 8921 24003
+f 24004 24005 24006
+f 24007 24008 24009
+f 24010 23945 23946
+f 24011 16765 16764
+f 24012 24013 24014
+f 19704 24002 21912
+f 10377 24013 24012
+f 3594 10377 24012
+f 24015 23957 16614
+f 24013 24015 24014
+f 23958 24016 23766
+f 24014 24015 16614
+f 2480 2816 2481
+f 16615 23958 23766
+f 24017 22080 24018
+f 24019 24020 24021
+f 24018 24022 24017
+f 21957 2829 2828
+f 24022 24023 21888
+f 24017 24022 21888
+f 24023 24024 23966
+f 21888 24023 23966
+f 24024 24025 21775
+f 23966 24024 21775
+f 24025 24026 23968
+f 21775 24025 23968
+f 24026 24027 23970
+f 23968 24026 23970
+f 24027 24028 23971
+f 23970 24027 23971
+f 24028 24029 23972
+f 23971 24028 23972
+f 24030 23973 23972
+f 24029 24030 23972
+f 24031 23974 23973
+f 24030 24031 23973
+f 24032 23975 23974
+f 24031 24032 23974
+f 24033 23976 23975
+f 24032 24033 23975
+f 24034 23977 23976
+f 24033 24034 23976
+f 24035 23978 23977
+f 24034 24035 23977
+f 24036 23979 23978
+f 24035 24036 23978
+f 24037 23921 23979
+f 24036 24037 23979
+f 23951 24038 23984
+f 24037 24039 23921
+f 23949 24040 24041
+f 24039 24040 23984
+f 16233 15094 6200
+f 425 466 23853
+f 801 803 6533
+f 16332 7571 7570
+f 20651 18097 23988
+f 16089 16088 23989
+f 21084 24042 16088
+f 24043 23990 23989
+f 24042 24043 23989
+f 24044 23991 23990
+f 24043 24044 23990
+f 24045 23992 23991
+f 24044 24045 23991
+f 24045 24046 23993
+f 23992 24045 23993
+f 24046 24047 23994
+f 23993 24046 23994
+f 24047 24048 23995
+f 23994 24047 23995
+f 24048 24049 23996
+f 23995 24048 23996
+f 24049 24050 23997
+f 23996 24049 23997
+f 24050 24051 23998
+f 23997 24050 23998
+f 24051 24052 23999
+f 23998 24051 23999
+f 24052 24053 24000
+f 23999 24052 24000
+f 24053 21594 21172
+f 24000 24053 21172
+f 461 15322 22215
+f 6085 21931 21271
+f 953 18839 12702
+f 6190 6191 17781
+f 16386 9338 16488
+f 17148 17149 16494
+f 18113 5602 5601
+f 19079 17245 19617
+f 24054 24055 24056
+f 24057 24058 24059
+f 24060 24010 23946
+f 24016 24061 24062
+f 24063 22656 24064
+f 23756 24065 23757
+f 23766 24016 24062
+f 24066 24019 24021
+f 17585 24067 24068
+f 24069 15772 15774
+f 24070 24071 23352
+f 24072 24073 24069
+f 24074 24069 24073
+f 24073 24075 24074
+f 22082 24076 24074
+f 24075 24077 24018
+f 24074 24075 24018
+f 24077 24078 24022
+f 24018 24077 24022
+f 24078 24079 24023
+f 24022 24078 24023
+f 24079 24080 24024
+f 24023 24079 24024
+f 24080 24081 24025
+f 24024 24080 24025
+f 24081 24082 24026
+f 24025 24081 24026
+f 24082 24083 24027
+f 24026 24082 24027
+f 24083 24084 24028
+f 24027 24083 24028
+f 24084 24085 24029
+f 24028 24084 24029
+f 24085 24086 24030
+f 24029 24085 24030
+f 24087 24031 24030
+f 24086 24087 24030
+f 24088 24032 24031
+f 24087 24088 24031
+f 24089 24033 24032
+f 24088 24089 24032
+f 24090 24034 24033
+f 24089 24090 24033
+f 24091 24035 24034
+f 24090 24091 24034
+f 24092 24036 24035
+f 24091 24092 24035
+f 24093 24037 24036
+f 24092 24093 24036
+f 24094 24039 24037
+f 24093 24094 24037
+f 24041 24040 24039
+f 24094 24041 24039
+f 24095 306 23987
+f 9414 24096 17488
+f 21701 18068 18067
+f 16617 841 1799
+f 15483 14934 14899
+f 19822 18124 22481
+f 16090 21083 16088
+f 16088 24042 23989
+f 24097 24043 24042
+f 21084 24097 24042
+f 24098 24044 24043
+f 24097 24098 24043
+f 24099 24045 24044
+f 24098 24099 24044
+f 24099 24100 24046
+f 24045 24099 24046
+f 24100 24101 24047
+f 24046 24100 24047
+f 24101 24102 24048
+f 24047 24101 24048
+f 24102 24103 24049
+f 24048 24102 24049
+f 24103 24104 24050
+f 24049 24103 24050
+f 24104 24105 24051
+f 24050 24104 24051
+f 24105 24106 24052
+f 24051 24105 24052
+f 24106 24107 24053
+f 24052 24106 24053
+f 24107 21224 21594
+f 24053 24107 21594
+f 15483 22385 15548
+f 8721 17058 8722
+f 18563 23943 23745
+f 11556 24108 16822
+f 14934 15483 15548
+f 22722 24109 1748
+f 24110 24111 24112
+f 24113 2124 22846
+f 24061 24114 24115
+f 24059 24060 23946
+f 24116 24117 24118
+f 24062 24061 24115
+f 24119 24120 24121
+f 2926 6886 13565
+f 24122 24123 24124
+f 15773 24121 24124
+f 24123 24125 24072
+f 24124 24123 24072
+f 24125 24126 24073
+f 24072 24125 24073
+f 24126 24127 24075
+f 24073 24126 24075
+f 24127 24128 24077
+f 24075 24127 24077
+f 24128 24129 24078
+f 24077 24128 24078
+f 24129 24130 24079
+f 24078 24129 24079
+f 24130 24131 24080
+f 24079 24130 24080
+f 24131 24132 24081
+f 24080 24131 24081
+f 24132 24133 24082
+f 24081 24132 24082
+f 24133 24134 24083
+f 24082 24133 24083
+f 24134 24135 24084
+f 24083 24134 24084
+f 24135 24136 24085
+f 24084 24135 24085
+f 24136 24137 24086
+f 24085 24136 24086
+f 24138 24087 24086
+f 24137 24138 24086
+f 24139 24088 24087
+f 24138 24139 24087
+f 24140 24089 24088
+f 24139 24140 24088
+f 24141 24090 24089
+f 24140 24141 24089
+f 24142 24091 24090
+f 24141 24142 24090
+f 24143 24092 24091
+f 24142 24143 24091
+f 24144 24093 24092
+f 24143 24144 24092
+f 24145 24094 24093
+f 24144 24145 24093
+f 24146 24041 24094
+f 24145 24146 24094
+f 19493 24147 24148
+f 24146 24147 24041
+f 24149 18110 18068
+f 21701 24149 18068
+f 21173 19169 16342
+f 23384 23403 9734
+f 17761 21084 21083
+f 22901 22902 2463
+f 24150 24097 21084
+f 17761 24150 21084
+f 24151 24098 24097
+f 24150 24151 24097
+f 24152 24099 24098
+f 24151 24152 24098
+f 24152 24153 24100
+f 24099 24152 24100
+f 24153 24154 24101
+f 24100 24153 24101
+f 24154 24155 24102
+f 24101 24154 24102
+f 24155 24156 24103
+f 24102 24155 24103
+f 24156 24157 24104
+f 24103 24156 24104
+f 24157 24158 24105
+f 24104 24157 24105
+f 24158 24159 24106
+f 24105 24158 24106
+f 24159 22834 24107
+f 24106 24159 24107
+f 1672 4944 952
+f 24107 22834 21224
+f 18298 20422 22786
+f 2460 2459 13471
+f 16860 9732 16045
+f 16770 16330 9488
+f 20646 18111 18110
+f 24149 20646 18110
+f 12891 18124 18111
+f 20646 12891 18111
+f 17517 22594 15695
+f 4164 16797 21063
+f 18836 17448 24160
+f 15041 15040 24161
+f 24162 2944 2124
+f 24113 24162 2124
+f 24163 24110 24112
+f 24162 24164 2946
+f 24114 24165 24166
+f 24058 24057 24111
+f 23813 24118 24167
+f 24115 24114 24166
+f 24120 24168 24122
+f 16695 24169 24170
+f 24171 24172 24122
+f 24168 24171 24122
+f 24172 24173 24123
+f 24122 24172 24123
+f 24173 24174 24125
+f 24123 24173 24125
+f 24174 24175 24126
+f 24125 24174 24126
+f 24175 24176 24127
+f 24126 24175 24127
+f 24176 24177 24128
+f 24127 24176 24128
+f 24177 24178 24129
+f 24128 24177 24129
+f 24178 24179 24130
+f 24129 24178 24130
+f 24179 24180 24131
+f 24130 24179 24131
+f 24180 24181 24132
+f 24131 24180 24132
+f 24181 24182 24133
+f 24132 24181 24133
+f 24182 24183 24134
+f 24133 24182 24134
+f 24183 24184 24135
+f 24134 24183 24135
+f 24184 24185 24136
+f 24135 24184 24136
+f 24185 24186 24137
+f 24136 24185 24137
+f 24186 24187 24138
+f 24137 24186 24138
+f 24188 24139 24138
+f 24187 24188 24138
+f 24189 24140 24139
+f 24188 24189 24139
+f 24190 24141 24140
+f 24189 24190 24140
+f 24191 24142 24141
+f 24190 24191 24141
+f 24192 24143 24142
+f 24191 24192 24142
+f 24193 24144 24143
+f 24192 24193 24143
+f 24194 24145 24144
+f 24193 24194 24144
+f 24195 24146 24145
+f 24194 24195 24145
+f 19493 24148 24196
+f 24195 24148 24146
+f 15543 14093 24197
+f 17790 24198 24199
+f 2612 16619 24200
+f 1218 8108 19909
+f 16498 16385 24201
+f 14293 14295 15557
+f 23319 23388 19985
+f 24202 24150 17761
+f 5196 24202 17761
+f 24203 24151 24150
+f 24202 24203 24150
+f 24204 24152 24151
+f 24203 24204 24151
+f 24204 24205 24153
+f 24152 24204 24153
+f 24205 24206 24154
+f 24153 24205 24154
+f 24206 24207 24155
+f 24154 24206 24155
+f 24207 24208 24156
+f 24155 24207 24156
+f 24208 24209 24157
+f 24156 24208 24157
+f 24209 24210 24158
+f 24157 24209 24158
+f 24210 24211 24159
+f 24158 24210 24159
+f 24211 22650 22834
+f 24159 24211 22834
+f 22504 22834 22650
+f 22831 24212 24213
+f 22345 16650 16651
+f 24214 21153 21259
+f 3379 19410 2785
+f 16387 16490 24215
+f 7668 16500 16620
+f 15943 2612 24216
+f 16619 16620 24200
+f 24217 411 24095
+f 17790 411 24217
+f 17737 17790 24199
+f 306 425 23987
+f 15943 24216 18336
+f 14935 17736 24218
+f 18575 15943 18336
+f 18331 18169 15970
+f 2944 24162 2946
+f 5636 17813 24219
+f 24164 24220 3091
+f 24110 24058 24111
+f 24221 24163 23305
+f 24165 24222 23822
+f 24058 24060 24059
+f 24118 24223 24167
+f 24166 24165 23822
+f 24224 24171 24225
+f 24117 24226 24118
+f 23424 24227 24171
+f 24224 23424 24171
+f 24227 24228 24172
+f 24171 24227 24172
+f 24228 24229 24173
+f 24172 24228 24173
+f 24229 24230 24174
+f 24173 24229 24174
+f 24230 24231 24175
+f 24174 24230 24175
+f 24231 24232 24176
+f 24175 24231 24176
+f 24232 24233 24177
+f 24176 24232 24177
+f 24233 24234 24178
+f 24177 24233 24178
+f 24234 24235 24179
+f 24178 24234 24179
+f 24235 24236 24180
+f 24179 24235 24180
+f 24236 24237 24181
+f 24180 24236 24181
+f 24237 24238 24182
+f 24181 24237 24182
+f 24238 24239 24183
+f 24182 24238 24183
+f 24239 24240 24184
+f 24183 24239 24184
+f 24240 24241 24185
+f 24184 24240 24185
+f 24241 24242 24186
+f 24185 24241 24186
+f 24242 24243 24187
+f 24186 24242 24187
+f 24244 24188 24187
+f 24243 24244 24187
+f 24245 24189 24188
+f 24244 24245 24188
+f 24246 24190 24189
+f 24245 24246 24189
+f 24247 24191 24190
+f 24246 24247 24190
+f 24248 24192 24191
+f 24247 24248 24191
+f 24249 24193 24192
+f 24248 24249 24192
+f 24250 24194 24193
+f 24249 24250 24193
+f 24251 24195 24194
+f 24250 24251 24194
+f 24252 19491 24196
+f 24251 24196 24195
+f 14935 24253 24254
+f 14936 14935 24254
+f 2612 24200 24216
+f 15971 18331 15970
+f 21297 21280 24255
+f 19487 19489 16072
+f 21258 20121 5195
+f 8108 12647 19909
+f 18826 18825 18829
+f 24256 24202 5196
+f 20121 24256 5196
+f 24257 24203 24202
+f 24256 24257 24202
+f 24258 24204 24203
+f 24257 24258 24203
+f 24258 24259 24205
+f 24204 24258 24205
+f 24259 24260 24206
+f 24205 24259 24206
+f 24260 24261 24207
+f 24206 24260 24207
+f 24261 24262 24208
+f 24207 24261 24208
+f 24262 24263 24209
+f 24208 24262 24209
+f 24263 24264 24210
+f 24209 24263 24210
+f 24264 24265 24211
+f 24210 24264 24211
+f 18124 19822 16272
+f 24211 24265 22650
+f 24266 24267 20366
+f 15128 17691 15994
+f 24268 23642 12540
+f 15483 14899 7571
+f 24269 24270 24271
+f 16770 9488 2786
+f 22753 22303 22754
+f 24160 15543 24197
+f 24218 17736 24199
+f 17736 17737 24199
+f 24198 17790 24217
+f 411 306 24095
+f 1793 16475 17165
+f 17514 16472 16475
+f 24253 14935 24218
+f 1794 1793 17165
+f 14093 18562 24272
+f 14900 14936 24273
+f 17448 15543 24160
+f 4941 15550 9656
+f 15886 24274 15887
+f 24275 23287 23365
+f 2946 24164 3091
+f 24222 23287 24275
+f 23822 24222 24275
+f 24276 24277 24278
+f 23287 24279 23365
+f 24280 24281 24282
+f 24170 24169 24283
+f 23423 24284 23424
+f 21746 24285 21747
+f 24284 24286 24227
+f 23424 24284 24227
+f 24286 24287 24228
+f 24227 24286 24228
+f 24287 24288 24229
+f 24228 24287 24229
+f 24288 24289 24230
+f 24229 24288 24230
+f 24289 24290 24231
+f 24230 24289 24231
+f 24290 24291 24232
+f 24231 24290 24232
+f 24291 24292 24233
+f 24232 24291 24233
+f 24292 24293 24234
+f 24233 24292 24234
+f 24293 24294 24235
+f 24234 24293 24235
+f 24294 24295 24236
+f 24235 24294 24236
+f 24295 24296 24237
+f 24236 24295 24237
+f 24296 24297 24238
+f 24237 24296 24238
+f 24297 24298 24239
+f 24238 24297 24239
+f 24298 24299 24240
+f 24239 24298 24240
+f 24300 24241 24240
+f 24299 24300 24240
+f 24300 24301 24242
+f 24241 24300 24242
+f 24301 24302 24243
+f 24242 24301 24243
+f 24302 24303 24244
+f 24243 24302 24244
+f 24304 24245 24244
+f 24303 24304 24244
+f 24305 24246 24245
+f 24304 24305 24245
+f 24306 24247 24246
+f 24305 24306 24246
+f 24307 24248 24247
+f 24306 24307 24247
+f 24308 24249 24248
+f 24307 24308 24248
+f 24309 24250 24249
+f 24308 24309 24249
+f 24310 24251 24250
+f 24309 24310 24250
+f 24252 24196 24251
+f 24310 24252 24251
+f 14936 24254 24273
+f 24311 24312 24313
+f 24197 14093 24272
+f 4783 24314 24315
+f 6097 6096 6250
+f 6092 5804 15189
+f 16162 24316 21258
+f 5255 24317 5385
+f 24318 20121 21258
+f 24316 24318 21258
+f 24319 24256 20121
+f 24318 24319 20121
+f 24320 24257 24256
+f 24319 24320 24256
+f 24321 24258 24257
+f 24320 24321 24257
+f 24321 24322 24259
+f 24258 24321 24259
+f 24322 24323 24260
+f 24259 24322 24260
+f 24323 24324 24261
+f 24260 24323 24261
+f 24324 24325 24262
+f 24261 24324 24262
+f 24325 24326 24263
+f 24262 24325 24263
+f 24326 24327 24264
+f 24263 24326 24264
+f 24327 24255 24265
+f 24264 24327 24265
+f 671 18837 430
+f 19860 23645 11228
+f 17759 2188 3589
+f 3963 21167 14501
+f 17772 2110 16007
+f 24328 14901 24329
+f 4332 4334 16858
+f 24330 17147 4775
+f 18799 17781 17817
+f 4775 17147 15874
+f 6647 6649 24331
+f 7321 16006 2620
+f 6649 2455 23943
+f 7862 17448 16499
+f 16474 17948 4939
+f 6844 10093 6378
+f 15566 13960 18902
+f 17780 4783 24315
+f 16490 16489 18932
+f 24220 24332 3738
+f 24333 24334 24335
+f 24336 24337 24338
+f 24279 24339 24340
+f 24337 24341 24342
+f 24343 24344 24345
+f 24341 18711 18710
+f 11569 20377 20450
+f 24346 6235 3812
+f 16089 23988 16090
+f 3244 22798 3031
+f 14943 17666 23731
+f 14900 24273 23732
+f 17781 6191 1605
+f 1849 23700 16459
+f 23255 24347 17357
+f 18931 16148 18932
+f 24348 16758 16757
+f 24349 24348 16757
+f 24340 24339 24117
+f 24350 24351 24352
+f 24353 24350 24226
+f 24117 24353 24226
+f 14585 24354 23423
+f 1725 22048 23099
+f 24354 24355 24284
+f 23423 24354 24284
+f 24355 24356 24286
+f 24284 24355 24286
+f 24356 24357 24287
+f 24286 24356 24287
+f 24357 24358 24288
+f 24287 24357 24288
+f 24358 24359 24289
+f 24288 24358 24289
+f 24359 24360 24290
+f 24289 24359 24290
+f 24360 24361 24291
+f 24290 24360 24291
+f 24361 24362 24292
+f 24291 24361 24292
+f 24362 24363 24293
+f 24292 24362 24293
+f 24363 24364 24294
+f 24293 24363 24294
+f 24364 24365 24295
+f 24294 24364 24295
+f 24365 24366 24296
+f 24295 24365 24296
+f 24366 24367 24297
+f 24296 24366 24297
+f 24367 24368 24298
+f 24297 24367 24298
+f 24368 24369 24299
+f 24298 24368 24299
+f 24369 24370 24300
+f 24299 24369 24300
+f 24371 24301 24300
+f 24370 24371 24300
+f 24371 24372 24302
+f 24301 24371 24302
+f 24372 24373 24303
+f 24302 24372 24303
+f 24374 24304 24303
+f 24373 24374 24303
+f 24375 24305 24304
+f 24374 24375 24304
+f 24376 24306 24305
+f 24375 24376 24305
+f 5538 24307 24306
+f 24376 5538 24306
+f 5540 24308 24307
+f 5538 5540 24307
+f 16345 24309 24308
+f 21344 5540 22951
+f 10956 24310 24309
+f 16345 5540 21344
+f 24377 24252 24310
+f 10956 24377 24310
+f 16205 24252 9307
+f 22210 22132 4887
+f 22784 10425 5544
+f 17948 17947 4939
+f 21719 21718 24378
+f 5479 9387 10590
+f 8307 8306 20380
+f 21956 2828 12763
+f 18802 24379 24318
+f 24316 18802 24318
+f 24380 24319 24318
+f 24379 24380 24318
+f 24381 24320 24319
+f 24380 24381 24319
+f 24382 24321 24320
+f 24381 24382 24320
+f 24382 24383 24322
+f 24321 24382 24322
+f 24383 24384 24323
+f 24322 24383 24323
+f 24384 24385 24324
+f 24323 24384 24324
+f 24385 24386 24325
+f 24324 24385 24325
+f 24386 24387 24326
+f 24325 24386 24326
+f 24387 24388 24327
+f 24326 24387 24327
+f 24388 21297 24255
+f 24327 24388 24255
+f 17290 7470 15565
+f 15124 22546 22545
+f 16771 14500 16330
+f 2194 6512 4890
+f 2893 2892 9829
+f 15455 15454 22841
+f 3091 24220 3738
+f 24332 24389 4447
+f 3738 24332 4447
+f 24389 24390 8459
+f 4447 24389 8459
+f 24390 24391 8475
+f 321 323 1078
+f 14882 14881 24392
+f 24393 17821 17823
+f 24378 14516 13379
+f 16495 9324 17758
+f 19688 8859 17848
+f 6335 3219 14383
+f 2774 3151 386
+f 24394 24395 24336
+f 24394 24396 24397
+f 24398 24337 24336
+f 24395 24398 24336
+f 24399 24341 24337
+f 24398 24399 24337
+f 24400 18711 24341
+f 24399 24400 24341
+f 24401 21837 18711
+f 24400 24401 18711
+f 24402 16840 21837
+f 24401 24402 21837
+f 17666 14900 23732
+f 14565 6042 16130
+f 12057 18512 17758
+f 14944 14943 23852
+f 17937 17936 19012
+f 8459 24390 8475
+f 8790 8789 23881
+f 23278 24403 23309
+f 24348 16036 16035
+f 24221 23305 23309
+f 24404 24221 23309
+f 24405 24406 14585
+f 22346 14585 23423
+f 24406 24407 24354
+f 14585 24406 24354
+f 24407 24408 24355
+f 24354 24407 24355
+f 24408 24409 24356
+f 24355 24408 24356
+f 24409 24410 24357
+f 24356 24409 24357
+f 24410 24411 24358
+f 24357 24410 24358
+f 24411 24412 24359
+f 24358 24411 24359
+f 24412 24413 24360
+f 24359 24412 24360
+f 24413 24414 24361
+f 24360 24413 24361
+f 24414 24415 24362
+f 24361 24414 24362
+f 24415 24416 24363
+f 24362 24415 24363
+f 24416 24417 24364
+f 24363 24416 24364
+f 24417 24418 24365
+f 24364 24417 24365
+f 24418 24419 24366
+f 24365 24418 24366
+f 24419 24420 24367
+f 24366 24419 24367
+f 24420 24421 24368
+f 24367 24420 24368
+f 24421 24422 24369
+f 24368 24421 24369
+f 24422 24423 24370
+f 24369 24422 24370
+f 24424 24371 24370
+f 24423 24424 24370
+f 24425 24372 24371
+f 24424 24425 24371
+f 24425 24426 24373
+f 24372 24425 24373
+f 24426 24427 24374
+f 24373 24426 24374
+f 24428 24375 24374
+f 24427 24428 24374
+f 24429 24376 24375
+f 24428 24429 24375
+f 23076 16140 22923
+f 24429 3051 16887
+f 2308 2307 2489
+f 24430 14203 24431
+f 24432 24433 24434
+f 24403 24404 23309
+f 16534 24435 24436
+f 330 332 24437
+f 24391 24438 9086
+f 24439 24440 23362
+f 15563 17937 19012
+f 24441 19036 19012
+f 17936 24441 19012
+f 24442 19051 19036
+f 18571 22939 9517
+f 24443 18801 18800
+f 17577 20410 23097
+f 22747 24444 24445
+f 18801 24446 24379
+f 18802 18801 24379
+f 24447 24380 24379
+f 24446 24447 24379
+f 24448 24381 24380
+f 24447 24448 24380
+f 24448 24449 24382
+f 24381 24448 24382
+f 24449 24450 24383
+f 24382 24449 24383
+f 24450 24451 24384
+f 24383 24450 24384
+f 24451 24452 24385
+f 24384 24451 24385
+f 24452 24453 24386
+f 24385 24452 24386
+f 24453 24454 24387
+f 24386 24453 24387
+f 24454 24455 24388
+f 24387 24454 24388
+f 24455 11614 21297
+f 24388 24455 21297
+f 22606 1511 1510
+f 22840 15454 22915
+f 18563 23745 18564
+f 12541 15853 17291
+f 893 16521 16522
+f 17770 15455 10301
+f 8475 24391 9086
+f 24438 24456 11412
+f 16740 24403 23278
+f 24277 16740 23278
+f 16731 2967 12651
+f 24457 24458 24459
+f 24460 24461 24462
+f 24463 24464 24465
+f 24466 24467 24468
+f 8793 24469 8794
+f 10688 15131 10921
+f 24470 24471 24472
+f 3142 17770 10301
+f 24273 15640 15639
+f 24441 24442 19036
+f 17152 24473 24395
+f 21497 7671 7575
+f 24474 24398 24395
+f 24473 24474 24395
+f 24475 24399 24398
+f 24474 24475 24398
+f 24476 24400 24399
+f 24475 24476 24399
+f 24477 24401 24400
+f 24476 24477 24400
+f 24478 24402 24401
+f 24477 24478 24401
+f 932 934 13489
+f 24478 24479 24402
+f 17666 23732 23731
+f 1793 17514 16475
+f 24480 24481 19075
+f 9713 14940 24001
+f 24442 24480 19051
+f 9086 24438 11412
+f 24456 14819 14041
+f 11412 24456 14041
+f 24482 17704 24483
+f 24276 24392 24277
+f 24484 24485 24406
+f 24405 24484 24406
+f 24485 24486 24407
+f 24406 24485 24407
+f 24486 24487 24408
+f 24407 24486 24408
+f 24487 24488 24409
+f 24408 24487 24409
+f 24488 24489 24410
+f 24409 24488 24410
+f 24489 24490 24411
+f 24410 24489 24411
+f 24490 24491 24412
+f 24411 24490 24412
+f 24491 24492 24413
+f 24412 24491 24413
+f 24492 24493 24414
+f 24413 24492 24414
+f 24493 24494 24415
+f 24414 24493 24415
+f 24494 24495 24416
+f 24415 24494 24416
+f 24495 24496 24417
+f 24416 24495 24417
+f 24496 24497 24418
+f 24417 24496 24418
+f 24497 24498 24419
+f 24418 24497 24419
+f 24498 24499 24420
+f 24419 24498 24420
+f 24499 24500 24421
+f 24420 24499 24421
+f 24500 24501 24422
+f 24421 24500 24422
+f 24501 24502 24423
+f 24422 24501 24423
+f 24502 24503 24424
+f 24423 24502 24424
+f 24504 24425 24424
+f 24503 24504 24424
+f 24504 24505 24426
+f 24425 24504 24426
+f 24505 24506 24427
+f 24426 24505 24427
+f 24506 2668 24428
+f 24427 24506 24428
+f 2670 308 307
+f 24428 2668 24429
+f 16826 24430 24431
+f 24392 16740 24277
+f 10582 5638 13934
+f 7552 4327 15828
+f 22826 24507 19020
+f 24508 15545 15547
+f 15659 24509 24510
+f 15660 15659 24510
+f 24511 24512 24513
+f 17741 15080 12457
+f 18150 15796 18151
+f 24514 22310 22312
+f 15042 24515 18227
+f 18750 24516 21839
+f 13479 14819 13480
+f 15482 22385 15483
+f 24517 4966 20955
+f 24443 24518 24446
+f 18801 24443 24446
+f 24519 24447 24446
+f 24518 24519 24446
+f 24520 24448 24447
+f 24519 24520 24447
+f 24521 24449 24448
+f 24520 24521 24448
+f 24521 24522 24450
+f 24449 24521 24450
+f 24522 24523 24451
+f 24450 24522 24451
+f 24523 24524 24452
+f 24451 24523 24452
+f 24524 24525 24453
+f 24452 24524 24453
+f 24525 24526 24454
+f 24453 24525 24454
+f 24526 11615 24455
+f 24454 24526 24455
+f 17714 17713 3444
+f 24455 11615 11614
+f 19050 17137 11714
+f 24527 17349 21412
+f 16478 16353 16479
+f 17843 17842 24528
+f 2261 12540 3141
+f 12542 17770 3142
+f 24529 24530 24531
+f 17806 17795 18212
+f 24532 24533 4840
+f 14882 24392 24276
+f 24534 14882 24276
+f 24226 24350 24352
+f 24535 24536 23839
+f 267 374 1700
+f 24537 24538 24539
+f 1114 1115 3595
+f 24540 24541 24353
+f 23732 24273 15639
+f 24542 24543 24544
+f 24545 24546 22797
+f 24547 24548 24549
+f 17151 24473 17152
+f 17152 24394 24397
+f 24550 24474 24473
+f 17151 24550 24473
+f 24551 24475 24474
+f 24550 24551 24474
+f 24552 24476 24475
+f 24551 24552 24475
+f 24553 24477 24476
+f 24552 24553 24476
+f 24554 24478 24477
+f 24553 24554 24477
+f 17487 9414 17488
+f 24554 24555 24478
+f 17514 17513 16763
+f 2111 3141 1102
+f 14944 23852 23851
+f 16472 17514 16763
+f 24556 24557 24558
+f 14940 14944 23851
+f 24559 24560 24561
+f 16111 14840 14839
+f 17886 17885 22216
+f 19058 7865 15952
+f 2398 24562 24484
+f 13535 13436 24405
+f 24562 24563 24485
+f 24484 24562 24485
+f 24563 24564 24486
+f 24485 24563 24486
+f 24564 24565 24487
+f 24486 24564 24487
+f 24565 24566 24488
+f 24487 24565 24488
+f 24566 24567 24489
+f 24488 24566 24489
+f 24567 24568 24490
+f 24489 24567 24490
+f 24568 24569 24491
+f 24490 24568 24491
+f 24569 24570 24492
+f 24491 24569 24492
+f 24570 24571 24493
+f 24492 24570 24493
+f 24571 24572 24494
+f 24493 24571 24494
+f 24572 24573 24495
+f 24494 24572 24495
+f 24573 24574 24496
+f 24495 24573 24496
+f 24574 24575 24497
+f 24496 24574 24497
+f 24575 24576 24498
+f 24497 24575 24498
+f 24576 24577 24499
+f 24498 24576 24499
+f 24577 24578 24500
+f 24499 24577 24500
+f 24578 24579 24501
+f 24500 24578 24501
+f 24579 24580 24502
+f 24501 24579 24502
+f 24580 24581 24503
+f 24502 24580 24503
+f 21977 15648 24582
+f 24503 24581 24504
+f 24583 24582 20333
+f 24504 24583 24505
+f 20333 24584 24583
+f 24505 24584 24506
+f 24506 24584 24585
+f 24506 24585 2668
+f 16737 14882 24534
+f 24585 15849 2669
+f 15953 24586 15954
+f 24587 16737 24534
+f 14213 24588 17638
+f 24589 24590 16861
+f 15442 15143 15145
+f 24591 19250 24592
+f 24592 19250 17699
+f 23732 15639 15892
+f 24593 24594 24595
+f 24596 24597 24443
+f 24598 18795 18794
+f 24597 24599 24518
+f 24443 24597 24518
+f 24600 24519 24518
+f 24599 24600 24518
+f 24601 24520 24519
+f 24600 24601 24519
+f 24601 24602 24521
+f 24520 24601 24521
+f 24602 24603 24522
+f 24521 24602 24522
+f 24603 24604 24523
+f 24522 24603 24523
+f 24604 24605 24524
+f 24523 24604 24524
+f 24605 24606 24525
+f 24524 24605 24525
+f 24606 24607 24526
+f 24525 24606 24526
+f 24607 14423 11615
+f 24526 24607 11615
+f 24608 24609 24610
+f 21042 8044 17845
+f 24611 24612 24608
+f 24613 11029 6799
+f 23643 24268 23564
+f 14448 15240 15165
+f 3141 12542 3142
+f 24614 15956 15955
+f 24615 24614 15955
+f 24616 24617 24618
+f 24619 16737 24587
+f 24351 24620 24352
+f 24620 24621 24352
+f 16534 16536 24435
+f 24622 24623 24624
+f 23256 23291 23294
+f 24625 23259 23294
+f 14940 23851 24001
+f 1237 879 10251
+f 24626 19339 19250
+f 24591 24626 19250
+f 22293 17151 17153
+f 22549 17152 24397
+f 24627 24550 17151
+f 22293 24627 17151
+f 24628 24551 24550
+f 24627 24628 24550
+f 24629 24552 24551
+f 24628 24629 24551
+f 24630 24553 24552
+f 24629 24630 24552
+f 24631 24554 24553
+f 24630 24631 24553
+f 5933 24555 24554
+f 24631 5933 24554
+f 15570 23078 24632
+f 15461 21341 24096
+f 17747 15211 16763
+f 2141 20150 604
+f 14943 23731 23852
+f 17513 17747 16763
+f 24633 2396 23721
+f 23722 23721 24634
+f 2398 24484 13436
+f 24633 2397 2396
+f 2397 24635 24562
+f 2398 2397 24562
+f 24635 24636 24563
+f 24562 24635 24563
+f 24636 24637 24564
+f 24563 24636 24564
+f 24637 24638 24565
+f 24564 24637 24565
+f 24638 24639 24566
+f 24565 24638 24566
+f 24639 24640 24567
+f 24566 24639 24567
+f 24640 24641 24568
+f 24567 24640 24568
+f 24641 24642 24569
+f 24568 24641 24569
+f 24642 24643 24570
+f 24569 24642 24570
+f 24643 24644 24571
+f 24570 24643 24571
+f 24644 24645 24572
+f 24571 24644 24572
+f 24645 24646 24573
+f 24572 24645 24573
+f 24646 24647 24574
+f 24573 24646 24574
+f 24647 24648 24575
+f 24574 24647 24575
+f 24648 24649 24576
+f 24575 24648 24576
+f 24649 24650 24577
+f 24576 24649 24577
+f 24650 24651 24578
+f 24577 24650 24578
+f 24651 24652 24579
+f 24578 24651 24579
+f 24652 24653 24580
+f 24579 24652 24580
+f 24653 24582 24581
+f 24580 24653 24581
+f 17311 19656 19144
+f 23816 24654 23817
+f 24655 24656 24657
+f 18695 18694 8398
+f 238 237 1701
+f 24658 16098 16100
+f 16397 16556 16398
+f 17354 24659 17352
+f 24660 24661 24662
+f 24663 24660 24662
+f 24020 24664 24665
+f 24666 19418 19339
+f 24626 24666 19339
+f 24667 19422 19418
+f 24666 24667 19418
+f 24668 24669 24670
+f 389 24671 24596
+f 18800 24596 24443
+f 24671 24672 24597
+f 24596 24671 24597
+f 24672 24673 24599
+f 24597 24672 24599
+f 24674 24600 24599
+f 24673 24674 24599
+f 24675 24601 24600
+f 24674 24675 24600
+f 24675 24676 24602
+f 24601 24675 24602
+f 24676 24677 24603
+f 24602 24676 24603
+f 24677 24678 24604
+f 24603 24677 24604
+f 24678 24679 24605
+f 24604 24678 24605
+f 24679 24680 24606
+f 24605 24679 24606
+f 24680 24681 24607
+f 24606 24680 24607
+f 24681 17012 14423
+f 24607 24681 14423
+f 22603 24682 24683
+f 15365 15777 17012
+f 18932 16150 24215
+f 24684 24685 24686
+f 23643 23564 16422
+f 24268 12540 2261
+f 24664 24687 24688
+f 16556 24071 24070
+f 24689 24690 24621
+f 24618 24619 24587
+f 19289 19655 19287
+f 24620 24689 24621
+f 15188 11884 24691
+f 24692 24693 24694
+f 22597 21330 22031
+f 24695 24696 24697
+f 24698 24699 24700
+f 24695 24698 24696
+f 24701 19424 19422
+f 9713 24001 553
+f 24667 24701 19422
+f 17242 17241 22293
+f 24589 24702 24703
+f 24704 24627 22293
+f 17241 24704 22293
+f 24705 24628 24627
+f 24704 24705 24627
+f 24706 24629 24628
+f 24705 24706 24628
+f 24707 24630 24629
+f 24706 24707 24629
+f 24708 24631 24630
+f 24707 24708 24630
+f 24709 5933 24631
+f 24708 24709 24631
+f 24710 18935 24711
+f 24709 5931 5933
+f 22040 22043 1744
+f 770 2436 1781
+f 24712 24633 23721
+f 17569 17568 24713
+f 24714 24633 24712
+f 17568 24714 24712
+f 24715 2397 24633
+f 24714 24715 24633
+f 24715 24716 24635
+f 2397 24715 24635
+f 24716 24717 24636
+f 24635 24716 24636
+f 24717 24718 24637
+f 24636 24717 24637
+f 24718 24719 24638
+f 24637 24718 24638
+f 24720 24639 24638
+f 24719 24720 24638
+f 24720 24721 24640
+f 24639 24720 24640
+f 24721 24722 24641
+f 24640 24721 24641
+f 24722 24723 24642
+f 24641 24722 24642
+f 24723 24724 24643
+f 24642 24723 24643
+f 24724 24725 24644
+f 24643 24724 24644
+f 24725 24726 24645
+f 24644 24725 24645
+f 24726 24727 24646
+f 24645 24726 24646
+f 24727 24728 24647
+f 24646 24727 24647
+f 24728 24729 24648
+f 24647 24728 24648
+f 24729 24730 24649
+f 24648 24729 24649
+f 24730 24731 24650
+f 24649 24730 24650
+f 24731 24732 24651
+f 24650 24731 24651
+f 24732 23240 24652
+f 24651 24732 24652
+f 23240 21977 24653
+f 24652 23240 24653
+f 2233 4629 5616
+f 24701 24733 19545
+f 19424 24701 19545
+f 24733 24734 19552
+f 19545 24733 19552
+f 24734 24735 19558
+f 19552 24734 19558
+f 24735 24736 19625
+f 19558 24735 19625
+f 24736 24737 19685
+f 19625 24736 19685
+f 24737 24738 19716
+f 19685 24737 19716
+f 24738 24739 19720
+f 19716 24738 19720
+f 24739 24740 19732
+f 19720 24739 19732
+f 15635 24668 24741
+f 8211 3896 6432
+f 15392 24742 24671
+f 389 15392 24671
+f 24742 24743 24672
+f 24671 24742 24672
+f 24743 24744 24673
+f 24672 24743 24673
+f 24745 24674 24673
+f 24744 24745 24673
+f 24746 24675 24674
+f 24745 24746 24674
+f 24746 24747 24676
+f 24675 24746 24676
+f 24747 24748 24677
+f 24676 24747 24677
+f 24748 24749 24678
+f 24677 24748 24678
+f 24749 24750 24679
+f 24678 24749 24679
+f 24750 24751 24680
+f 24679 24750 24680
+f 24751 24752 24681
+f 24680 24751 24681
+f 24752 15365 17012
+f 24681 24752 17012
+f 223 572 884
+f 22780 22576 22575
+f 6648 15533 6649
+f 11281 21731 5077
+f 16421 23643 16422
+f 24268 19702 23564
+f 19862 24753 24754
+f 19742 19862 24754
+f 17585 24755 24067
+f 24756 23836 24757
+f 23951 23984 24040
+f 24758 24759 24760
+f 24761 24762 16096
+f 22961 22960 24763
+f 24764 24695 22961
+f 24763 24764 22961
+f 24765 24699 24766
+f 24764 24766 24695
+f 3733 9713 553
+f 19556 15530 16404
+f 24740 24767 19735
+f 19732 24740 19735
+f 17243 24768 17241
+f 24702 21717 24703
+f 24769 24704 17241
+f 24768 24769 17241
+f 24770 24705 24704
+f 24769 24770 24704
+f 24771 24706 24705
+f 24770 24771 24705
+f 24772 24707 24706
+f 24771 24772 24706
+f 24773 24708 24707
+f 24772 24773 24707
+f 24774 24709 24708
+f 24773 24774 24708
+f 24775 5931 24709
+f 24774 24775 24709
+f 764 5475 4787
+f 17567 15821 24776
+f 24777 4342 4341
+f 2436 764 4787
+f 24778 24714 17568
+f 23829 24778 17568
+f 24779 24715 24714
+f 24778 24779 24714
+f 24779 24780 24716
+f 24715 24779 24716
+f 24780 24781 24717
+f 24716 24780 24717
+f 24781 24782 24718
+f 24717 24781 24718
+f 24782 24783 24719
+f 24718 24782 24719
+f 24783 24784 24720
+f 24719 24783 24720
+f 24784 24785 24721
+f 24720 24784 24721
+f 24785 24786 24722
+f 24721 24785 24722
+f 24786 24787 24723
+f 24722 24786 24723
+f 24787 24788 24724
+f 24723 24787 24724
+f 24788 24789 24725
+f 24724 24788 24725
+f 24789 24790 24726
+f 24725 24789 24726
+f 24790 24791 24727
+f 24726 24790 24727
+f 24791 24792 24728
+f 24727 24791 24728
+f 24792 24793 24729
+f 24728 24792 24729
+f 24482 5867 5866
+f 24729 24793 24730
+f 17704 24482 5866
+f 24730 24483 24731
+f 24483 17704 23607
+f 24731 23607 24732
+f 23239 23607 2233
+f 24732 23239 23240
+f 23240 5616 21977
+f 16557 16556 24070
+f 24794 15844 24795
+f 24796 24797 24759
+f 17581 24798 17582
+f 24799 24800 24801
+f 24767 24802 19738
+f 19735 24767 19738
+f 24803 19750 19738
+f 24802 24803 19738
+f 24803 24804 19753
+f 19750 24803 19753
+f 24804 24805 19756
+f 19753 24804 19756
+f 3734 3733 422
+f 22430 19757 19756
+f 13475 3734 421
+f 3733 553 422
+f 24805 22430 19756
+f 20326 2702 2701
+f 2992 2994 3216
+f 2503 15216 15286
+f 1091 2774 378
+f 23746 16494 16495
+f 21119 23646 23628
+f 17759 3589 24806
+f 899 15647 421
+f 3734 422 421
+f 18576 15944 15943
+f 13475 421 15647
+f 2357 2355 4483
+f 23420 2140 1555
+f 18961 21006 19733
+f 2225 2227 17098
+f 24331 23943 18563
+f 23675 17259 17818
+f 4943 4332 16857
+f 843 15392 844
+f 24807 24808 24809
+f 843 24810 24742
+f 15392 843 24742
+f 24810 24811 24743
+f 24742 24810 24743
+f 24811 24812 24744
+f 24743 24811 24744
+f 24812 24813 24745
+f 24744 24812 24745
+f 24814 24746 24745
+f 24813 24814 24745
+f 24814 24815 24747
+f 24746 24814 24747
+f 24815 24816 24748
+f 24747 24815 24748
+f 24816 24817 24749
+f 24748 24816 24749
+f 24817 24818 24750
+f 24749 24817 24750
+f 24818 24819 24751
+f 24750 24818 24751
+f 22907 22997 17844
+f 24751 24819 24752
+f 23159 23156 23158
+f 16408 21321 11614
+f 10025 8045 12886
+f 24820 9107 18721
+f 19702 24268 2261
+f 9731 8045 10025
+f 12540 12542 3141
+f 16459 23700 24821
+f 16745 20580 11072
+f 24822 24823 6951
+f 14838 18529 18531
+f 3234 16745 11072
+f 21671 24763 21670
+f 3729 24824 24825
+f 24826 24764 24763
+f 21671 24826 24763
+f 24827 24766 24764
+f 24826 24827 24764
+f 24254 12921 15640
+f 24765 24828 24829
+f 24273 24254 15640
+f 20452 20500 24830
+f 21611 24831 24768
+f 21612 17243 17242
+f 24832 24769 24768
+f 24831 24832 24768
+f 24833 24770 24769
+f 24832 24833 24769
+f 24834 24771 24770
+f 24833 24834 24770
+f 24835 24772 24771
+f 24834 24835 24771
+f 24836 24773 24772
+f 24835 24836 24772
+f 24837 24774 24773
+f 24836 24837 24773
+f 24444 24775 24774
+f 24837 24444 24774
+f 17678 1049 17608
+f 24444 18441 24775
+f 3729 3728 24838
+f 18441 24776 15821
+f 24839 24778 23829
+f 24776 24839 23829
+f 24840 24779 24778
+f 24839 24840 24778
+f 24840 24841 24780
+f 24779 24840 24780
+f 24841 24842 24781
+f 24780 24841 24781
+f 24842 24843 24782
+f 24781 24842 24782
+f 24843 24844 24783
+f 24782 24843 24783
+f 24844 24845 24784
+f 24783 24844 24784
+f 24845 24846 24785
+f 24784 24845 24785
+f 24846 24847 24786
+f 24785 24846 24786
+f 24847 24848 24787
+f 24786 24847 24787
+f 24848 24849 24788
+f 24787 24848 24788
+f 24849 24850 24789
+f 24788 24849 24789
+f 24850 24851 24790
+f 24789 24850 24790
+f 24851 24852 24791
+f 24790 24851 24791
+f 24852 24853 24792
+f 24791 24852 24792
+f 24853 24482 24793
+f 24792 24853 24793
+f 24854 16693 24071
+f 24855 24856 21658
+f 21658 24857 21659
+f 24858 24859 24856
+f 24855 24858 24856
+f 17647 17574 17648
+f 24860 24861 24862
+f 20613 369 10648
+f 22112 15603 18013
+f 1606 20079 20081
+f 23675 1606 20081
+f 20468 20120 20079
+f 1606 20468 20079
+f 13962 20210 20120
+f 20468 13962 20120
+f 13961 20296 20210
+f 13331 13332 9256
+f 5524 5660 13331
+f 13962 13961 20210
+f 24821 20327 20296
+f 13961 24821 20296
+f 24863 20365 20327
+f 24821 24863 20327
+f 24864 20373 20365
+f 24863 24864 20365
+f 24201 20546 20373
+f 24864 24201 20373
+f 24201 24865 20748
+f 20546 24201 20748
+f 24865 24215 23359
+f 20748 24865 23359
+f 842 24866 843
+f 14280 18723 14277
+f 24866 24867 24810
+f 843 24866 24810
+f 24867 24868 24811
+f 24810 24867 24811
+f 24868 24869 24812
+f 24811 24868 24812
+f 24870 24813 24812
+f 24869 24870 24812
+f 24871 24814 24813
+f 24870 24871 24813
+f 24871 24872 24815
+f 24814 24871 24815
+f 24872 24873 24816
+f 24815 24872 24816
+f 24873 24874 24817
+f 24816 24873 24817
+f 24874 24875 24818
+f 24817 24874 24818
+f 24875 24527 24819
+f 24818 24875 24819
+f 8145 21900 8224
+f 24876 24877 24878
+f 14028 16465 16466
+f 17844 22997 23065
+f 16490 18932 24215
+f 6513 7320 7319
+f 23565 17771 15760
+f 24879 24880 15172
+f 16150 23385 23359
+f 24215 16150 23359
+f 16149 22112 23385
+f 16653 1853 14013
+f 16221 24881 16222
+f 24882 21671 13201
+f 19917 17066 17070
+f 24883 24826 21671
+f 24882 24883 21671
+f 24884 24827 24826
+f 24883 24884 24826
+f 24884 24885 24828
+f 24884 24828 24827
+f 24886 15766 24887
+f 16150 16149 23385
+f 24888 24831 21611
+f 21612 21611 17243
+f 24889 24832 24831
+f 24888 24889 24831
+f 24890 24833 24832
+f 24889 24890 24832
+f 24891 24834 24833
+f 24890 24891 24833
+f 24892 24835 24834
+f 24891 24892 24834
+f 24892 24893 24836
+f 24835 24892 24836
+f 24894 24837 24836
+f 24893 24894 24836
+f 24895 24444 24837
+f 24894 24895 24837
+f 4735 13071 5812
+f 24896 19070 22950
+f 18442 18441 24444
+f 13419 14007 1060
+f 24897 24839 24776
+f 24886 24897 24776
+f 24898 24840 24839
+f 24897 24898 24839
+f 24898 24899 24841
+f 24840 24898 24841
+f 24899 24900 24842
+f 24841 24899 24842
+f 24900 24901 24843
+f 24842 24900 24843
+f 24901 24902 24844
+f 24843 24901 24844
+f 24902 24903 24845
+f 24844 24902 24845
+f 24903 24904 24846
+f 24845 24903 24846
+f 24904 24905 24847
+f 24846 24904 24847
+f 24905 24906 24848
+f 24847 24905 24848
+f 24906 24907 24849
+f 24848 24906 24849
+f 24907 24908 24850
+f 24849 24907 24850
+f 24908 24909 24851
+f 24850 24908 24851
+f 24909 24910 24852
+f 24851 24909 24852
+f 24910 5867 24853
+f 24852 24910 24853
+f 5867 6538 5865
+f 24911 24860 24862
+f 14204 24276 24278
+f 2976 15695 20721
+f 21589 21591 21590
+f 21041 15508 17949
+f 13960 16459 13961
+f 17788 6513 7319
+f 17351 21438 21427
+f 17772 2260 2110
+f 20333 24582 15648
+f 21173 21594 21224
+f 19440 20831 19165
+f 23728 24912 16963
+f 14871 23728 16963
+f 16796 7439 17842
+f 21297 11614 21296
+f 187 9447 188
+f 24444 22747 18442
+f 24330 9302 17147
+f 24913 20299 17863
+f 16522 4889 4891
+f 16004 954 16005
+f 21733 21647 21700
+f 9253 24914 14551
+f 18961 17610 18962
+f 9302 24330 17863
+f 5818 16233 14351
+f 2671 24915 24866
+f 842 2671 24866
+f 24915 24916 24867
+f 24866 24915 24867
+f 24916 24917 24868
+f 24867 24916 24868
+f 24917 24918 24869
+f 24868 24917 24869
+f 24919 24870 24869
+f 24918 24919 24869
+f 24920 24871 24870
+f 24919 24920 24870
+f 24920 24921 24872
+f 24871 24920 24872
+f 24921 24922 24873
+f 24872 24921 24873
+f 24922 24923 24874
+f 24873 24922 24874
+f 24923 24924 24875
+f 24874 24923 24875
+f 24924 17349 24527
+f 24875 24924 24527
+f 24925 15766 19078
+f 7633 19477 19484
+f 13771 6537 12474
+f 24926 11714 11713
+f 894 893 23730
+f 23611 17058 19785
+f 2190 23565 15760
+f 6649 15533 2455
+f 7464 14501 18536
+f 22138 16231 8797
+f 22659 1510 21701
+f 22859 18570 13685
+f 17138 17759 24806
+f 19483 2147 2149
+f 5812 13071 14693
+f 24927 24928 24929
+f 16119 15212 15211
+f 24930 24883 24882
+f 24931 24930 24882
+f 24932 24884 24883
+f 24930 24932 24883
+f 12381 12383 18005
+f 24932 24930 24933
+f 1510 24149 21701
+f 22659 22606 1510
+f 24934 24935 24888
+f 24936 24934 24888
+f 24937 24889 24888
+f 24935 24937 24888
+f 24938 24890 24889
+f 24937 24938 24889
+f 24939 24891 24890
+f 24938 24939 24890
+f 24940 24892 24891
+f 24939 24940 24891
+f 24941 24893 24892
+f 24940 24941 24892
+f 24942 24894 24893
+f 24941 24942 24893
+f 22921 24895 24894
+f 24942 22921 24894
+f 24943 24944 24945
+f 17226 22464 5975
+f 14007 1061 1060
+f 6519 14635 6520
+f 24887 24897 24886
+f 15767 24886 18443
+f 24946 24898 24897
+f 24887 24946 24897
+f 24947 24899 24898
+f 24946 24947 24898
+f 24947 24948 24900
+f 24899 24947 24900
+f 24948 24949 24901
+f 24900 24948 24901
+f 24949 24950 24902
+f 24901 24949 24902
+f 24950 24951 24903
+f 24902 24950 24903
+f 24951 24952 24904
+f 24903 24951 24904
+f 24952 24953 24905
+f 24904 24952 24905
+f 24953 24954 24906
+f 24905 24953 24906
+f 24954 24955 24907
+f 24906 24954 24907
+f 24955 24956 24908
+f 24907 24955 24908
+f 24956 24957 24909
+f 24908 24956 24909
+f 24957 6538 24910
+f 24909 24957 24910
+f 24957 12475 6538
+f 17586 24068 15845
+f 15663 24958 15664
+f 16661 23962 15664
+f 6258 24959 6256
+f 24960 24961 24962
+f 24963 23320 23317
+f 24964 22865 22866
+f 562 982 558
+f 24965 24966 24967
+f 23181 5117 5116
+f 15673 15675 559
+f 14351 14350 22266
+f 3308 6530 7347
+f 16521 15552 4889
+f 22237 22230 24968
+f 1512 20646 24149
+f 2103 2105 15814
+f 1510 1512 24149
+f 15726 24969 16215
+f 22481 18124 12891
+f 16495 17758 24970
+f 24805 18870 22037
+f 24971 16495 24970
+f 17758 18512 24972
+f 18512 17780 24315
+f 24970 17758 24972
+f 24973 24974 24975
+f 24972 18512 24315
+f 15418 15420 24976
+f 23802 24926 11713
+f 18562 18564 24977
+f 15783 984 24978
+f 18564 23746 24979
+f 24272 18562 24977
+f 23746 16495 24971
+f 24977 18564 24979
+f 4783 15862 24314
+f 24979 23746 24971
+f 464 16459 13960
+f 15862 18871 24314
+f 16387 16488 16490
+f 6191 15566 18902
+f 2673 24980 24915
+f 932 4650 933
+f 24980 24981 24916
+f 24915 24980 24916
+f 24981 24982 24917
+f 24916 24981 24917
+f 24982 24983 24918
+f 24917 24982 24918
+f 24983 24984 24919
+f 24918 24983 24919
+f 24984 24985 24920
+f 24919 24984 24920
+f 24985 24986 24921
+f 24920 24985 24921
+f 24986 24987 24922
+f 24921 24986 24922
+f 24987 24988 24923
+f 24922 24987 24923
+f 24988 24989 24924
+f 24923 24988 24924
+f 24989 17350 17349
+f 24924 24989 17349
+f 21087 23589 23588
+f 21253 16835 18931
+f 21876 3025 2829
+f 9499 2123 7759
+f 2311 2508 309
+f 1848 16498 23700
+f 10808 14874 12058
+f 16489 17779 18932
+f 5397 22784 5544
+f 22570 9106 18157
+f 5817 3247 3547
+f 24212 22831 22830
+f 16329 23663 1054
+f 17747 16119 15211
+f 16120 15656 15212
+f 18119 24990 24991
+f 24931 24992 24993
+f 24994 24930 24931
+f 24993 24994 24931
+f 20500 24995 24933
+f 24994 24933 24930
+f 2103 15814 18775
+f 19202 15202 2359
+f 12057 4776 17780
+f 20653 24996 20687
+f 24997 24998 24935
+f 24934 24997 24935
+f 24999 24937 24935
+f 24998 24999 24935
+f 25000 24938 24937
+f 24999 25000 24937
+f 25001 24939 24938
+f 25000 25001 24938
+f 25002 24940 24939
+f 25001 25002 24939
+f 25003 24941 24940
+f 25002 25003 24940
+f 25004 24942 24941
+f 25003 25004 24941
+f 9915 22683 3132
+f 20685 17741 3133
+f 15783 22921 15784
+f 22683 20685 3133
+f 18040 14235 17635
+f 2743 19303 2744
+f 24925 24887 15766
+f 25005 24946 24887
+f 24925 25005 24887
+f 25006 24947 24946
+f 25005 25006 24946
+f 25006 25007 24948
+f 24947 25006 24948
+f 25007 25008 24949
+f 24948 25007 24949
+f 25008 25009 24950
+f 24949 25008 24950
+f 25009 25010 24951
+f 24950 25009 24951
+f 25010 25011 24952
+f 24951 25010 24952
+f 25011 25012 24953
+f 24952 25011 24953
+f 25012 25013 24954
+f 24953 25012 24954
+f 25013 25014 24955
+f 24954 25013 24955
+f 25014 14625 24956
+f 24955 25014 24956
+f 6376 14625 25014
+f 24956 14625 24957
+f 12475 24957 14625
+f 23358 23361 24619
+f 14881 16738 24392
+f 25015 25016 25017
+f 23717 23818 23718
+f 25018 25019 25020
+f 25021 25022 24457
+f 25022 23292 24457
+f 25023 25015 24612
+f 23292 23256 24458
+f 24961 25024 24962
+f 16867 23963 23962
+f 25025 25026 25027
+f 25028 25029 25030
+f 14691 25031 25032
+f 19569 19057 19059
+f 25033 25034 25035
+f 25036 25037 25038
+f 16119 16120 15212
+f 25039 25040 14424
+f 18774 2103 18775
+f 22624 18602 22570
+f 954 16004 6512
+f 25041 22601 22603
+f 10425 25042 5545
+f 19461 18772 2247
+f 23249 22302 22303
+f 9326 12057 17758
+f 17938 22624 22570
+f 4779 17844 8043
+f 19011 19633 1876
+f 19462 13677 4780
+f 2313 2312 10687
+f 2457 19159 17149
+f 21383 10952 12272
+f 25043 17531 25044
+f 19633 4780 1876
+f 16466 892 894
+f 15913 22393 17786
+f 19393 19389 1655
+f 24805 22037 22430
+f 18157 24441 17936
+f 22746 24978 984
+f 17123 24442 24441
+f 18157 17123 24441
+f 25045 24481 24442
+f 18157 17124 17123
+f 21884 23429 23405
+f 22186 25046 22222
+f 5394 22237 25047
+f 25048 5531 22252
+f 6523 6373 18959
+f 21324 21326 21433
+f 8380 1542 25049
+f 14631 8380 25049
+f 25050 25051 24981
+f 24980 25050 24981
+f 25051 25052 24982
+f 24981 25051 24982
+f 25053 24983 24982
+f 25052 25053 24982
+f 25053 25054 24984
+f 24983 25053 24984
+f 25054 25055 24985
+f 24984 25054 24985
+f 25055 25056 24986
+f 24985 25055 24986
+f 25056 25057 24987
+f 24986 25056 24987
+f 25057 25058 24988
+f 24987 25057 24988
+f 25058 18779 24989
+f 24988 25058 24989
+f 22109 16680 22043
+f 24989 18779 17350
+f 23764 23763 25059
+f 22210 22471 21459
+f 16006 16005 6647
+f 14930 15131 10688
+f 15417 10808 10922
+f 6648 12702 15533
+f 22644 24591 24592
+f 19713 9344 18108
+f 19191 18397 23231
+f 15274 21383 12272
+f 25060 22044 16680
+f 17350 21440 21438
+f 24993 24992 25061
+f 25062 25063 21364
+f 25064 24993 25061
+f 25065 25064 25061
+f 25066 24994 24993
+f 25064 25066 24993
+f 24830 24933 24994
+f 25066 24830 24994
+f 20500 24933 24830
+f 23675 17260 17259
+f 23423 23662 22346
+f 25067 24998 24997
+f 25068 25067 24997
+f 25069 24999 24998
+f 25067 25069 24998
+f 25070 25000 24999
+f 25069 25070 24999
+f 25071 25001 25000
+f 25070 25071 25000
+f 25072 25002 25001
+f 25071 25072 25001
+f 25073 25003 25002
+f 25072 25073 25002
+f 20469 25004 25003
+f 25073 20469 25003
+f 15784 20471 15728
+f 20469 20471 25004
+f 24216 24591 22644
+f 18336 24216 22644
+f 8964 19476 8965
+f 24200 24626 24591
+f 16788 17637 16790
+f 25074 25005 24925
+f 19078 25074 24925
+f 25075 25006 25005
+f 25074 25075 25005
+f 25075 25076 25007
+f 25006 25075 25007
+f 25076 25077 25008
+f 25007 25076 25008
+f 25077 25078 25009
+f 25008 25077 25009
+f 25078 25079 25010
+f 25009 25078 25010
+f 25079 25080 25011
+f 25010 25079 25011
+f 25080 25081 25012
+f 25011 25080 25012
+f 25081 25082 25013
+f 25012 25081 25013
+f 25082 6376 25014
+f 25013 25082 25014
+f 25082 6377 6376
+f 25083 25084 25085
+f 23270 17586 15845
+f 7861 25086 7859
+f 4449 14738 24349
+f 25087 25088 23285
+f 20022 25089 25090
+f 19910 20586 15118
+f 25091 25092 15132
+f 25093 8785 25094
+f 24457 23292 24458
+f 17574 17573 23906
+f 25095 9274 9273
+f 17350 18779 18778
+f 24959 17364 6256
+f 25096 25097 25098
+f 25099 25100 25101
+f 5394 5393 6899
+f 25102 25103 25104
+f 25105 25106 23912
+f 25107 25105 23912
+f 14546 9654 14547
+f 25108 23848 23850
+f 18571 18570 22859
+f 8572 19798 9350
+f 17434 16360 16478
+f 18060 25109 25110
+f 17775 16649 17794
+f 17435 17434 16478
+f 16981 14377 17775
+f 17411 14649 17518
+f 14376 14377 16981
+f 16649 17411 17794
+f 22840 22759 16055
+f 14377 16649 17775
+f 14998 15127 17154
+f 19462 19461 13677
+f 19633 19462 4780
+f 18772 1632 2247
+f 16714 17453 17519
+f 19461 2247 13677
+f 17794 17411 17518
+f 14648 16714 17519
+f 14648 17519 17518
+f 14649 14648 17518
+f 16714 15127 14998
+f 17453 16714 14998
+f 19011 1876 7567
+f 15127 15128 17154
+f 19425 19393 2022
+f 19389 19011 7567
+f 19191 19425 18397
+f 19389 7567 1655
+f 19192 19191 23231
+f 19393 1655 2022
+f 11032 11067 15849
+f 19425 2022 18397
+f 24216 24200 24591
+f 9408 19485 8964
+f 16620 24666 24626
+f 24200 16620 24626
+f 24808 24807 18183
+f 7669 25111 25050
+f 2671 2673 24915
+f 25111 25112 25051
+f 25050 25111 25051
+f 25112 25113 25052
+f 25051 25112 25052
+f 25113 25114 25053
+f 25052 25113 25053
+f 25114 25115 25054
+f 25053 25114 25054
+f 25115 25116 25055
+f 25054 25115 25055
+f 25116 25117 25056
+f 25055 25116 25056
+f 25117 25118 25057
+f 25056 25117 25057
+f 25118 20207 25058
+f 25057 25118 25058
+f 20207 18777 18779
+f 25058 20207 18779
+f 18206 25119 18281
+f 1512 1511 22554
+f 1673 952 2194
+f 17138 24806 19159
+f 6512 16004 7320
+f 15860 15505 7449
+f 9338 7463 20753
+f 15552 16331 4889
+f 16500 24667 24666
+f 16620 16500 24666
+f 386 3151 8445
+f 9096 9095 7128
+f 5529 5537 5530
+f 5387 25120 5388
+f 25121 25065 25122
+f 21363 25122 25065
+f 25123 25064 25065
+f 25121 25123 25065
+f 18334 25066 25064
+f 25123 18334 25064
+f 18333 24830 25066
+f 18334 18333 25066
+f 9796 13378 16881
+f 11228 2911 17298
+f 25124 25125 25067
+f 25068 25124 25067
+f 25126 25069 25067
+f 25125 25126 25067
+f 25127 25070 25069
+f 25126 25127 25069
+f 25128 25071 25070
+f 25127 25128 25070
+f 25129 25072 25071
+f 25128 25129 25071
+f 25130 25073 25072
+f 25129 25130 25072
+f 25131 20469 25073
+f 25130 25131 25073
+f 25132 15732 15728
+f 25131 20470 20469
+f 16499 24701 24667
+f 16500 16499 24667
+f 18836 24733 24701
+f 23590 19078 15768
+f 2905 9137 2906
+f 25133 25074 19078
+f 23590 25133 19078
+f 25134 25075 25074
+f 25133 25134 25074
+f 25134 25135 25076
+f 25075 25134 25076
+f 25135 25136 25077
+f 25076 25135 25077
+f 25136 25137 25078
+f 25077 25136 25078
+f 25137 25138 25079
+f 25078 25137 25079
+f 25138 25139 25080
+f 25079 25138 25080
+f 25139 22282 25081
+f 25080 25139 25081
+f 17014 3155 25140
+f 25081 22282 25082
+f 23183 21409 20293
+f 25141 17189 25142
+f 17281 219 16990
+f 14898 25143 23953
+f 25144 25145 17642
+f 15732 25132 23608
+f 25146 24348 24349
+f 16378 16371 17066
+f 24689 25147 24690
+f 25148 25146 24349
+f 21656 25149 21654
+f 25150 25087 23285
+f 25151 25152 17824
+f 18752 16492 16491
+f 15886 25153 24274
+f 25038 25037 23883
+f 8929 25154 25155
+f 25156 25157 25158
+f 25097 25099 25101
+f 6306 2153 2152
+f 25159 16668 25160
+f 25026 14689 25100
+f 25106 25161 25162
+f 25163 23327 25164
+f 25165 22216 16416
+f 23912 25106 25162
+f 25166 25167 19751
+f 11541 17885 6801
+f 25168 25169 24038
+f 25170 17581 25171
+f 17369 17939 17941
+f 25172 25173 25174
+f 23844 23782 23781
+f 2475 20294 19634
+f 9575 9574 24508
+f 24508 25175 15545
+f 24926 19050 11714
+f 16755 17682 17645
+f 14872 14871 17287
+f 893 16522 23730
+f 17785 18775 17786
+f 16005 6648 6647
+f 17154 15128 15994
+f 678 544 8384
+f 17691 16545 16544
+f 15994 17691 16544
+f 20055 21517 7445
+f 3768 19708 3766
+f 544 543 8384
+f 12860 9455 15978
+f 19477 19298 19484
+f 19736 8884 17870
+f 567 12858 2236
+f 18775 15913 17786
+f 18828 19202 18830
+f 16290 12858 567
+f 25176 24517 22751
+f 21932 5391 5390
+f 8047 16858 17759
+f 4334 2189 2188
+f 574 16442 2266
+f 14015 14014 16214
+f 2267 5529 5528
+f 885 574 2266
+f 19476 19477 8965
+f 25177 12545 12638
+f 16499 18836 24701
+f 9095 19485 9408
+f 18836 24160 24734
+f 24733 18836 24734
+f 24160 24197 24735
+f 15992 25178 21341
+f 13378 9796 13379
+f 12799 25179 25111
+f 7669 12799 25111
+f 25179 25180 25112
+f 25111 25179 25112
+f 25180 25181 25113
+f 25112 25180 25113
+f 25181 25182 25114
+f 25113 25181 25114
+f 25182 25183 25115
+f 25114 25182 25115
+f 25183 25184 25116
+f 25115 25183 25116
+f 25184 25185 25117
+f 25116 25184 25117
+f 25186 25118 25117
+f 25185 25186 25117
+f 25186 17793 20207
+f 25118 25186 20207
+f 2810 16056 22691
+f 21700 21592 21643
+f 4945 17848 23728
+f 21914 17816 17818
+f 7319 7321 17447
+f 25187 16174 16176
+f 2261 3141 2111
+f 7321 2620 2619
+f 23565 23564 17771
+f 24734 24160 24735
+f 24197 24272 24736
+f 24735 24197 24736
+f 6790 9096 7128
+f 1790 9372 1791
+f 17317 18999 456
+f 457 456 18999
+f 25188 25121 25189
+f 25122 25189 25121
+f 25190 25123 25121
+f 25188 25190 25121
+f 23311 18334 25123
+f 25190 23311 25123
+f 11539 3512 14056
+f 14056 11540 11539
+f 17604 15305 17605
+f 4778 15857 22907
+f 25191 25125 25124
+f 11153 25191 25124
+f 25192 25126 25125
+f 25191 25192 25125
+f 25193 25127 25126
+f 25192 25193 25126
+f 25194 25128 25127
+f 25193 25194 25127
+f 25195 25129 25128
+f 25194 25195 25128
+f 25196 25130 25129
+f 25195 25196 25129
+f 25197 25131 25130
+f 25196 25197 25130
+f 25132 20470 25131
+f 25197 25132 25131
+f 24272 24977 24737
+f 20537 16264 16266
+f 3836 1537 1536
+f 17577 23097 17578
+f 212 25133 23590
+f 17576 212 23590
+f 17073 25134 25133
+f 212 17073 25133
+f 17073 17072 25135
+f 25134 17073 25135
+f 22245 17015 214
+f 25135 17072 25136
+f 25198 25140 25137
+f 25136 25198 25137
+f 25140 3157 25138
+f 25137 25140 25138
+f 3157 20812 25139
+f 25138 3157 25139
+f 25139 20812 22282
+f 25199 25200 25201
+f 25202 25203 25204
+f 17799 25205 17800
+f 25206 25207 25208
+f 15731 15730 25209
+f 25210 25211 24616
+f 25212 25090 20682
+f 25213 5801 25214
+f 24617 24619 24618
+f 25215 25216 25217
+f 25147 17531 25043
+f 25218 24343 24345
+f 17356 17280 17357
+f 25019 24014 25219
+f 23547 25220 25221
+f 25222 25223 25224
+f 25015 25017 24612
+f 24974 25225 25226
+f 8930 8929 25155
+f 185 9916 186
+f 25099 25026 25100
+f 25227 25228 25229
+f 19759 17440 17548
+f 129 25230 130
+f 24527 21412 24819
+f 25231 25232 25233
+f 21412 21411 24819
+f 25234 25235 25236
+f 25237 24537 24539
+f 25238 23844 23843
+f 25239 25240 25236
+f 17932 24542 17933
+f 25241 25242 25243
+f 8552 10522 8551
+f 23847 24710 24711
+f 3757 5059 3728
+f 25244 25245 25246
+f 9573 25247 25248
+f 13377 9832 20451
+f 25249 25250 22150
+f 25245 9573 25248
+f 2779 14079 5475
+f 15690 3595 3594
+f 19867 19829 13792
+f 210 10150 17340
+f 678 8384 6902
+f 15768 17577 17576
+f 2236 12860 15978
+f 16924 678 6902
+f 16924 6902 15978
+f 9455 16924 15978
+f 764 2779 5475
+f 211 17340 9520
+f 1059 9520 14079
+f 2779 1059 14079
+f 566 16290 567
+f 1059 211 9520
+f 16289 16290 566
+f 12858 12860 2236
+f 15164 16289 216
+f 216 16289 566
+f 15164 1063 1061
+f 1063 15164 216
+f 13383 13419 1490
+f 14007 15164 1061
+f 25251 19013 18999
+f 13419 1060 1490
+f 7128 9095 9408
+f 17317 25251 18999
+f 9372 9373 1791
+f 19485 19476 8964
+f 24736 24272 24737
+f 19684 9046 418
+f 24977 24979 24738
+f 14279 25252 12799
+f 19337 14279 12799
+f 25252 25253 25179
+f 12799 25252 25179
+f 25253 25254 25180
+f 25179 25253 25180
+f 25254 25255 25181
+f 25180 25254 25181
+f 25255 25256 25182
+f 25181 25255 25182
+f 25257 25183 25182
+f 25256 25257 25182
+f 25257 25258 25184
+f 25183 25257 25184
+f 25258 25259 25185
+f 25184 25258 25185
+f 25260 25186 25185
+f 25259 25260 25185
+f 25260 1731 17793
+f 25186 25260 17793
+f 17604 22504 22650
+f 13687 11303 16774
+f 2457 17138 19159
+f 17848 16922 16474
+f 20753 17778 16489
+f 16394 16860 16045
+f 953 12701 954
+f 2261 2260 17771
+f 24737 24977 24738
+f 24979 24971 24739
+f 24738 24979 24739
+f 24971 24970 24740
+f 24739 24971 24740
+f 19687 9372 12711
+f 19533 16917 9046
+f 9373 9096 6790
+f 1791 9373 6790
+f 9481 17041 17039
+f 17829 5681 7367
+f 25261 25188 20792
+f 25189 20792 25188
+f 20648 25190 25188
+f 25261 20648 25188
+f 20647 23311 25190
+f 20648 20647 25190
+f 2455 2457 17148
+f 16055 16054 22841
+f 18332 20452 18333
+f 21687 17807 17778
+f 25262 24311 25263
+f 5681 10905 7367
+f 13850 25262 25264
+f 15171 25194 25193
+f 9529 15947 12012
+f 25265 25195 25194
+f 15171 25265 25194
+f 25266 25196 25195
+f 5049 5682 25267
+f 25268 25197 25196
+f 25195 25265 25266
+f 25196 25266 25268
+f 25268 23608 25197
+f 24970 24972 24767
+f 24753 19862 18467
+f 24740 24970 24767
+f 17640 25269 3726
+f 213 212 17576
+f 17576 22153 11631
+f 1945 17576 11631
+f 25270 25271 20260
+f 25271 25270 23550
+f 214 213 1946
+f 20412 20411 25272
+f 25273 23444 25274
+f 17015 17014 17072
+f 25198 17014 25140
+f 25140 3155 3157
+f 17070 17066 16983
+f 5050 25267 14970
+f 25275 17252 17256
+f 23877 23945 24010
+f 23804 23875 24060
+f 25024 25275 17256
+f 25049 6392 6236
+f 24002 19704 25276
+f 17442 25277 17443
+f 25278 25279 25210
+f 25211 24617 24616
+f 25280 25281 21657
+f 24991 25281 25280
+f 17302 10376 1106
+f 24741 24668 24670
+f 24343 25282 24344
+f 25282 25283 24344
+f 15397 454 453
+f 25284 25285 25286
+f 8121 14970 4957
+f 23277 23279 23985
+f 16742 25287 25288
+f 16743 16742 25288
+f 25287 25289 25227
+f 25288 25287 25227
+f 25289 25290 25228
+f 25227 25289 25228
+f 25290 25291 16640
+f 25228 25290 16640
+f 25291 25292 25232
+f 16640 25291 25232
+f 25292 25293 25233
+f 25294 25233 25293
+f 25293 25295 25294
+f 25294 25296 25297
+f 25295 25298 25296
+f 25297 25299 21099
+f 25298 25300 25299
+f 25301 25299 25300
+f 25300 25302 25301
+f 16743 25288 25303
+f 25304 25305 25306
+f 25302 25307 25301
+f 25308 24963 23317
+f 2125 23810 2126
+f 14323 14322 14771
+f 23985 24796 23986
+f 15667 23948 20411
+f 25309 25310 23348
+f 25311 25312 25313
+f 16987 25314 22943
+f 15662 15660 25315
+f 3336 25316 25317
+f 23833 23962 23831
+f 16669 15662 25315
+f 211 210 17340
+f 25318 25319 25320
+f 15055 983 1227
+f 9718 15055 1227
+f 9615 565 9616
+f 337 15616 1613
+f 565 9615 10150
+f 1618 1715 17478
+f 210 565 10150
+f 565 1618 9616
+f 9616 1618 17478
+f 1715 1049 17678
+f 17478 1715 17678
+f 1049 1051 17608
+f 17777 16873 789
+f 13040 617 786
+f 1177 562 561
+f 16873 786 789
+f 25321 12512 19013
+f 22060 22754 22188
+f 18625 19684 418
+f 3578 25322 25251
+f 24972 24315 24802
+f 23851 15958 17043
+f 24767 24972 24802
+f 24315 24314 24803
+f 14278 25323 25252
+f 5235 1236 5236
+f 25323 25324 25253
+f 25252 25323 25253
+f 25324 25325 25254
+f 25253 25324 25254
+f 25325 25326 25255
+f 25254 25325 25255
+f 25326 25327 25256
+f 25255 25326 25256
+f 25327 25328 25257
+f 25256 25327 25257
+f 25328 25329 25258
+f 25257 25328 25258
+f 21560 25259 25258
+f 25329 21560 25258
+f 2049 25260 25259
+f 21560 2049 25259
+f 6039 14319 14275
+f 25260 2049 1731
+f 17947 4940 4939
+f 16071 23311 20647
+f 16922 9138 17948
+f 16474 16922 17948
+f 2621 24331 18563
+f 16488 20753 16489
+f 952 954 2194
+f 3337 3160 25330
+f 24802 24315 24803
+f 18871 24804 24803
+f 24314 18871 24803
+f 18870 24805 24804
+f 18871 18870 24804
+f 18626 18625 8568
+f 19635 19636 18064
+f 19684 19533 9046
+f 9372 1790 12711
+f 19687 12711 16917
+f 19533 19687 16917
+f 6539 1177 561
+f 17010 2929 14321
+f 20793 25331 20794
+f 18446 18445 25332
+f 25333 25261 20794
+f 25334 25333 20794
+f 23609 20648 25261
+f 25333 23609 25261
+f 23609 19487 20648
+f 18578 556 555
+f 11540 14056 3109
+f 14782 23944 14783
+f 1731 2049 16153
+f 21723 7431 17502
+f 8520 3216 20786
+f 15530 19556 15531
+f 760 9651 6823
+f 25335 25265 15171
+f 3330 3329 23959
+f 25336 25337 24529
+f 25338 24540 24279
+f 8787 24439 23362
+f 12923 15771 19501
+f 16659 16661 25339
+f 25340 23821 25341
+f 25342 25343 25344
+f 17844 4779 22907
+f 25345 25346 25347
+f 12650 23762 17445
+f 23762 25348 17445
+f 11149 25349 25350
+f 17735 23338 23337
+f 25351 25352 25353
+f 24347 17355 17357
+f 23818 25354 23819
+f 16667 25355 25356
+f 8707 18148 13662
+f 25357 25358 17524
+f 18044 17523 17525
+f 25359 18615 25360
+f 25204 25361 25362
+f 2609 25363 25364
+f 16911 2609 25364
+f 25365 25366 25367
+f 16217 17221 25368
+f 25369 25370 25371
+f 19767 25368 25372
+f 25282 25373 25283
+f 25373 5265 25283
+f 3647 16871 11141
+f 14972 10712 15045
+f 22793 22795 16742
+f 21978 16741 16743
+f 22795 25374 25287
+f 16742 22795 25287
+f 25374 25375 25289
+f 25287 25374 25289
+f 25375 25376 25290
+f 25289 25375 25290
+f 25376 25377 25291
+f 25290 25376 25291
+f 25377 25378 25292
+f 25291 25377 25292
+f 25378 25379 25293
+f 25292 25378 25293
+f 25379 25380 25295
+f 25293 25379 25295
+f 25380 25381 25298
+f 25295 25380 25298
+f 25381 25382 25300
+f 25298 25381 25300
+f 25382 25383 25302
+f 25300 25382 25302
+f 25383 25384 25307
+f 25302 25383 25307
+f 25385 15049 25307
+f 25384 25385 25307
+f 22953 22233 22789
+f 25385 15050 15049
+f 23273 25270 20259
+f 8502 3320 12557
+f 25386 25387 25388
+f 25387 25389 25388
+f 25390 25391 25392
+f 25319 23334 25320
+f 24612 25017 24609
+f 25393 25394 25395
+f 25396 25397 23307
+f 25398 25399 25400
+f 5476 977 983
+f 15055 5476 983
+f 9717 9718 1227
+f 446 447 9084
+f 15616 9717 1613
+f 1613 9717 1227
+f 9551 696 854
+f 9552 9551 854
+f 993 782 16569
+f 16568 993 16569
+f 15632 15631 570
+f 16810 1076 1854
+f 17777 789 1076
+f 15631 16810 1854
+f 19239 15763 19559
+f 15765 15963 19510
+f 15965 3009 19597
+f 19559 15765 19510
+f 17010 17045 2929
+f 19054 12923 19501
+f 24001 23851 17043
+f 15561 3706 15503
+f 23852 15891 15958
+f 24806 20299 24913
+f 24001 17043 778
+f 11220 308 2670
+f 14277 25401 25323
+f 14278 25252 14279
+f 25401 25402 25324
+f 25323 25401 25324
+f 25402 25403 25325
+f 25324 25402 25325
+f 25403 25404 25326
+f 25325 25403 25326
+f 25404 25405 25327
+f 25326 25404 25327
+f 25405 25406 25328
+f 25327 25405 25328
+f 25406 25407 25329
+f 25328 25406 25329
+f 2048 16153 2049
+f 25329 25407 21560
+f 2893 9913 9831
+f 9831 2894 2893
+f 19822 22481 22446
+f 16506 2077 19729
+f 17848 24912 23728
+f 2512 2662 2664
+f 24865 16387 24215
+f 4945 23728 14870
+f 3589 15760 20299
+f 8858 9138 16922
+f 4944 953 952
+f 4491 25408 4492
+f 19159 24806 24913
+f 8482 8224 21900
+f 15485 19472 18059
+f 19690 19472 15485
+f 18059 19635 18064
+f 18625 418 8568
+f 19636 18626 8568
+f 18064 19636 8568
+f 4644 17010 14321
+f 17045 2930 2929
+f 25409 25410 10426
+f 21151 25086 25409
+f 18559 18557 18446
+f 25086 23230 25409
+f 19622 25334 25411
+f 23230 19622 25411
+f 632 25333 25334
+f 19622 632 25334
+f 16622 23609 25333
+f 632 16622 25333
+f 18826 18796 18407
+f 23068 16349 17209
+f 2620 6647 24331
+f 16385 16387 24865
+f 16413 18522 21006
+f 9302 17772 16007
+f 2462 12112 8858
+f 17038 10090 15574
+f 18249 18174 11414
+f 3794 8401 8400
+f 17291 17710 16577
+f 15800 15915 17064
+f 6137 10227 6138
+f 15643 10378 7131
+f 3705 3723 15504
+f 15641 15643 7131
+f 22786 20422 20421
+f 17038 15574 15576
+f 1604 1606 23675
+f 17818 1604 23675
+f 6098 15170 24880
+f 23757 25412 23758
+f 2774 386 378
+f 19369 17441 25355
+f 23779 19369 19371
+f 25413 25414 25415
+f 25364 25363 25416
+f 24765 24827 24828
+f 25417 3819 25418
+f 25419 25279 25278
+f 2480 2482 2447
+f 9487 9203 9202
+f 3410 25420 23303
+f 25421 25422 25221
+f 2481 3410 23303
+f 25420 25423 23325
+f 18043 18045 23427
+f 23303 25420 23325
+f 4336 14946 8556
+f 25363 25419 25416
+f 25424 25353 25425
+f 22721 2675 7362
+f 25373 5263 5265
+f 23304 23326 25419
+f 25369 25371 25426
+f 25427 25428 25373
+f 16825 24430 16826
+f 6885 6887 18922
+f 22794 25429 22795
+f 18956 22793 16741
+f 22721 2676 2675
+f 22795 25429 25374
+f 25430 25429 25431
+f 25374 25430 25375
+f 25432 25433 25376
+f 25375 25432 25376
+f 25433 25434 25377
+f 25376 25433 25377
+f 25434 25435 25378
+f 25377 25434 25378
+f 25435 25436 25379
+f 25378 25435 25379
+f 25437 25380 25379
+f 25436 25437 25379
+f 25437 25438 25381
+f 25380 25437 25381
+f 25438 25439 25382
+f 25381 25438 25382
+f 25439 25440 25383
+f 25382 25439 25383
+f 25440 25441 25384
+f 25383 25440 25384
+f 25442 25385 25384
+f 25441 25442 25384
+f 25443 15050 25385
+f 25442 25443 25385
+f 8918 19337 3511
+f 25443 22244 15050
+f 25318 25320 25388
+f 25389 25318 25388
+f 25397 15679 23307
+f 25444 25445 25446
+f 25447 25396 23307
+f 25394 25448 25395
+f 25449 25396 8788
+f 15679 23099 23307
+f 447 689 15819
+f 25450 25451 25452
+f 10525 447 15819
+f 689 691 17274
+f 15819 689 17274
+f 691 818 17268
+f 2115 2114 3760
+f 3759 2115 3760
+f 782 25453 16567
+f 16569 782 16567
+f 15623 15632 569
+f 15631 1854 570
+f 3011 15534 19033
+f 19217 3011 19033
+f 15963 15965 19146
+f 19510 15963 19146
+f 841 23280 15577
+f 15894 15576 15575
+f 25454 22511 22474
+f 8613 15575 15577
+f 12931 14256 16448
+f 22333 21931 6085
+f 25423 25455 23328
+f 17888 16230 5400
+f 22160 23261 8554
+f 14342 19001 19003
+f 22682 25456 22172
+f 18245 5752 17071
+f 21455 20208 1733
+f 4115 4929 14516
+f 18723 25457 25401
+f 14277 18723 25401
+f 25457 25458 25402
+f 25401 25457 25402
+f 25458 25459 25403
+f 25402 25458 25403
+f 25459 25460 25404
+f 25403 25459 25404
+f 25460 25461 25405
+f 25404 25460 25405
+f 25461 25462 25406
+f 25405 25461 25406
+f 25462 25463 25407
+f 25406 25462 25407
+f 2995 2996 7362
+f 25463 21589 25407
+f 15124 22545 16235
+f 18931 17779 22343
+f 14782 17843 2104
+f 9339 7445 3580
+f 24912 17848 16474
+f 15691 23802 17947
+f 25464 25465 25466
+f 23943 17148 23745
+f 19727 19744 25467
+f 24331 6649 23943
+f 3581 16830 18838
+f 1632 18772 429
+f 3182 584 871
+f 15725 15800 18121
+f 3706 3705 15503
+f 10090 3724 15573
+f 15484 19690 15485
+f 19472 19635 18059
+f 17088 15051 2930
+f 17045 17088 2930
+f 25468 21413 25469
+f 25470 24329 14901
+f 15725 18121 24969
+f 25471 25468 25469
+f 25472 25086 7861
+f 25468 25472 7861
+f 19710 23230 25086
+f 25472 19710 25086
+f 19710 19711 23230
+f 19711 8998 19622
+f 17139 16711 21501
+f 15913 18799 22393
+f 634 19488 16622
+f 7431 21723 13930
+f 25473 15335 13952
+f 23253 3456 6595
+f 24330 4774 9426
+f 21150 7860 7859
+f 13687 22774 13685
+f 3724 15572 15573
+f 6225 15592 15597
+f 13462 19016 15475
+f 15475 19781 15484
+f 15502 18970 13462
+f 19781 19690 15484
+f 15503 3705 15504
+f 19016 19781 15475
+f 3723 18970 15502
+f 15504 3723 15502
+f 16034 15641 7131
+f 7130 16034 7131
+f 12943 18917 10378
+f 15643 12943 10378
+f 15894 17038 15576
+f 10090 15573 15574
+f 23065 22998 17845
+f 8613 15894 15575
+f 19303 2743 23586
+f 14014 15726 16215
+f 23361 14880 16737
+f 2977 11234 4869
+f 23325 25423 23328
+f 25455 25474 23332
+f 23328 25455 23332
+f 25474 25475 23357
+f 24657 20156 20155
+f 23332 25474 23357
+f 25416 25419 25278
+f 25476 23258 25477
+f 25478 21152 25479
+f 25279 25211 25210
+f 18794 15021 15023
+f 23806 25480 25481
+f 14566 10018 13347
+f 25482 25483 25484
+f 25475 25485 23360
+f 23357 25475 23360
+f 25485 25486 23387
+f 23360 25485 23387
+f 3133 17741 12457
+f 23814 25487 8786
+f 25488 25489 25490
+f 25491 6380 25280
+f 17311 19655 19656
+f 16694 25492 24169
+f 4470 374 14352
+f 25493 25494 25495
+f 25496 25497 24466
+f 25015 25023 24598
+f 25154 25498 25499
+f 25500 25501 25502
+f 25503 16937 25504
+f 22794 22793 15233
+f 17583 17582 25505
+f 25506 25507 25508
+f 17542 25509 25510
+f 23338 25511 25512
+f 25513 25514 25433
+f 25432 25513 25433
+f 25514 25515 25434
+f 25433 25514 25434
+f 25515 25516 25435
+f 25434 25515 25435
+f 25517 25436 25435
+f 25516 25517 25435
+f 25518 25437 25436
+f 25517 25518 25436
+f 25518 25519 25438
+f 25437 25518 25438
+f 25519 25520 25439
+f 25438 25519 25439
+f 25520 25521 25440
+f 25439 25520 25440
+f 25522 25441 25440
+f 25521 25522 25440
+f 25523 25442 25441
+f 25522 25523 25441
+f 25524 25443 25442
+f 25523 25524 25442
+f 25525 22244 25443
+f 25524 25525 25443
+f 24995 22679 24885
+f 25525 2314 22244
+f 25526 23257 25527
+f 2315 2314 19306
+f 25445 25528 25446
+f 24529 25529 24530
+f 25530 25531 17449
+f 25529 25337 18933
+f 25167 25532 25533
+f 25534 17462 25535
+f 16463 17528 16504
+f 25532 25311 25536
+f 17274 691 17268
+f 818 795 17118
+f 2114 9304 1074
+f 3760 2114 1074
+f 25453 25537 15842
+f 15842 25537 16814
+f 16058 15627 25538
+f 25537 16058 25538
+f 15534 15536 19034
+f 19033 15534 19034
+f 23785 23780 15597
+f 15535 23785 15597
+f 23784 23785 15535
+f 8668 23784 15535
+f 21643 21644 25539
+f 15131 15417 10921
+f 4165 4164 19952
+f 21006 16414 16413
+f 21647 19437 19436
+f 16093 22905 16359
+f 3004 16916 19764
+f 604 1556 2141
+f 11232 2976 22599
+f 19885 16341 20716
+f 18012 21606 21388
+f 18333 20452 24830
+f 14277 25323 14278
+f 5508 23532 23531
+f 18724 25540 25457
+f 18723 18724 25457
+f 25540 25541 25458
+f 25457 25540 25458
+f 25541 25542 25459
+f 25458 25541 25459
+f 25543 25460 25459
+f 25542 25543 25459
+f 25544 25461 25460
+f 25543 25544 25460
+f 25544 25545 25462
+f 25461 25544 25462
+f 25545 21644 25463
+f 25462 25545 25463
+f 21644 21591 25463
+f 424 15591 15610
+f 24864 16498 24201
+f 17762 17761 21083
+f 16477 19050 24926
+f 4891 6513 17788
+f 10301 22841 16054
+f 17018 14870 14872
+f 25546 25547 25548
+f 19711 546 8998
+f 17863 24330 9426
+f 3216 8520 2992
+f 16342 21172 21594
+f 17785 21760 21757
+f 25549 5977 5976
+f 23729 15587 15592
+f 3724 3706 15561
+f 15572 3724 15561
+f 15383 23274 25470
+f 23275 2861 25550
+f 23340 14696 7329
+f 25550 23276 23275
+f 25551 25471 23274
+f 23276 25551 23274
+f 25552 25468 25471
+f 25551 25552 25471
+f 3767 25472 25468
+f 25552 3767 25468
+f 3766 19710 25472
+f 3767 3766 25472
+f 18154 18406 18405
+f 15481 15480 14642
+f 19745 19727 19728
+f 18930 22780 22575
+f 16982 18056 23085
+f 19477 7633 8965
+f 9224 1104 2809
+f 2620 24331 2621
+f 308 2311 309
+f 583 870 584
+f 23780 6225 15597
+f 15646 23987 3010
+f 17044 7471 15051
+f 17044 15959 7471
+f 17088 17044 15051
+f 15959 2740 7471
+f 15893 2741 2740
+f 15959 15893 2740
+f 15893 16034 7130
+f 2741 15893 7130
+f 12943 12923 19054
+f 18917 12943 19054
+f 15763 19239 19240
+f 16873 13040 786
+f 15764 15763 19240
+f 15763 15765 19559
+f 19911 18044 18043
+f 25553 20020 20022
+f 25486 25554 23404
+f 2244 15567 3534
+f 23387 25486 23404
+f 25554 25555 23443
+f 23404 25554 23443
+f 25555 25556 23461
+f 20297 25557 25558
+f 23443 25555 23461
+f 25142 20755 25141
+f 16102 25559 16103
+f 3134 12457 21077
+f 24807 24809 25560
+f 14885 25561 25562
+f 25563 5113 25564
+f 16989 16988 3817
+f 2122 7759 2123
+f 16882 21508 25565
+f 23854 20020 25553
+f 25556 25566 23526
+f 22787 22788 25567
+f 23461 25556 23526
+f 25566 25568 23701
+f 23702 23748 24404
+f 23526 25566 23701
+f 25569 25570 25571
+f 11267 2965 25572
+f 24610 20682 20684
+f 25489 25569 25571
+f 25573 25574 25575
+f 20684 20683 25576
+f 3594 24012 25577
+f 25235 25239 25236
+f 25155 25154 25499
+f 25017 25212 24609
+f 25578 25579 25580
+f 11080 25581 25498
+f 15729 25582 15730
+f 25583 25503 25504
+f 25432 25584 25513
+f 25585 25586 17188
+f 25587 25588 25513
+f 9795 25565 25589
+f 25588 25590 25514
+f 25513 25588 25514
+f 25590 25591 25515
+f 25514 25590 25515
+f 25591 25592 25516
+f 25515 25591 25516
+f 25593 25517 25516
+f 25592 25593 25516
+f 25593 25594 25518
+f 25517 25593 25518
+f 25594 25595 25519
+f 25518 25594 25519
+f 25595 25596 25520
+f 25519 25595 25520
+f 25596 25597 25521
+f 25520 25596 25521
+f 25598 25522 25521
+f 25597 25598 25521
+f 25599 25523 25522
+f 25598 25599 25522
+f 25600 25524 25523
+f 25599 25600 25523
+f 25601 25525 25524
+f 25600 25601 25524
+f 25602 2314 25525
+f 25601 25602 25525
+f 385 2148 2147
+f 25602 19306 2314
+f 1837 25603 1838
+f 24403 23527 24404
+f 15915 18983 17064
+f 25604 17405 25605
+f 25606 25607 6798
+f 25608 15547 25609
+f 25610 25284 25611
+f 25284 25286 25612
+f 17268 818 17118
+f 15998 15658 15662
+f 9552 854 1074
+f 795 2004 2003
+f 24274 25573 25575
+f 1507 25613 25614
+f 15623 569 25538
+f 24112 25615 23306
+f 15593 19029 19034
+f 15593 205 19029
+f 15964 24095 15646
+f 23987 23853 3010
+f 22385 15854 15548
+f 5399 17888 5400
+f 17697 17696 23608
+f 21666 5668 21616
+f 22653 15272 15235
+f 25616 25617 25618
+f 25619 16274 17721
+f 6356 25620 18724
+f 6357 6356 18724
+f 25620 25621 25540
+f 18724 25620 25540
+f 25621 25622 25541
+f 25540 25621 25541
+f 25622 25623 25542
+f 25541 25622 25542
+f 25623 25624 25543
+f 25542 25623 25543
+f 25625 25544 25543
+f 25624 25625 25543
+f 25625 25626 25545
+f 25544 25625 25545
+f 25626 25539 21644
+f 25545 25626 21644
+f 23374 16158 22598
+f 20687 20654 20653
+f 16394 4333 4942
+f 24201 16385 24865
+f 9139 15691 17947
+f 23525 16477 24926
+f 4333 16394 16045
+f 2112 1102 1104
+f 19682 3766 19708
+f 16959 16056 2810
+f 2225 16502 16504
+f 20720 22599 2976
+f 3010 23853 8668
+f 15843 24217 15964
+f 6225 23729 15592
+f 25627 15084 15587
+f 15764 19240 19501
+f 15771 15764 19501
+f 25628 25550 2863
+f 25629 15590 15589
+f 25630 23276 25550
+f 25628 25630 25550
+f 25631 25551 23276
+f 25630 25631 23276
+f 25632 25552 25551
+f 25631 25632 25551
+f 15584 3767 25552
+f 25632 15584 25552
+f 3025 21876 21874
+f 22037 18870 15558
+f 22746 22747 24978
+f 21440 17350 18778
+f 19981 16796 17843
+f 17807 22343 17779
+f 23700 24863 24821
+f 16503 16464 16463
+f 21643 21592 21591
+f 4941 1671 15550
+f 17898 23858 25633
+f 7571 14899 7572
+f 23853 23784 8668
+f 15762 24198 15843
+f 3009 3011 19217
+f 19597 3009 19217
+f 16810 17777 1076
+f 15627 15623 25538
+f 13039 13214 618
+f 13214 13383 1607
+f 13040 13039 617
+f 13383 1490 1607
+f 13039 618 617
+f 13214 1607 618
+f 24542 24544 17933
+f 23206 23205 5028
+f 1180 3337 4185
+f 23783 23842 25634
+f 20022 20021 25089
+f 25353 25635 17934
+f 17822 20755 20754
+f 20021 24280 25089
+f 24109 25636 25637
+f 25103 25638 25639
+f 16103 25559 25640
+f 25465 25641 25642
+f 23854 25016 23855
+f 17801 17371 14129
+f 23264 25643 24928
+f 17647 17572 17574
+f 23446 23445 25644
+f 25645 23268 17573
+f 25646 25647 25648
+f 20683 25424 25576
+f 25569 3817 25570
+f 25649 25650 25651
+f 23748 24221 24404
+f 5539 5538 16887
+f 25568 25652 23747
+f 23701 25568 23747
+f 25652 25653 23749
+f 23747 25652 23749
+f 23335 8790 23336
+f 17697 23608 25268
+f 5538 24376 16887
+f 3817 25654 25570
+f 24609 20682 24610
+f 23903 23902 23295
+f 25655 25357 17523
+f 25154 11080 25498
+f 22776 22726 22777
+f 25656 25503 25583
+f 22683 3133 3132
+f 25657 24466 25658
+f 25580 25656 25583
+f 23710 18523 25659
+f 25660 25661 25662
+f 25663 25664 25587
+f 25040 23710 25659
+f 25664 25665 25588
+f 25587 25664 25588
+f 25665 25666 25590
+f 25588 25665 25590
+f 25666 25667 25591
+f 25590 25666 25591
+f 25667 25668 25592
+f 25591 25667 25592
+f 25668 25669 25593
+f 25592 25668 25593
+f 25669 25670 25594
+f 25593 25669 25594
+f 25670 25671 25595
+f 25594 25670 25595
+f 25671 25672 25596
+f 25595 25671 25596
+f 25672 25673 25597
+f 25596 25672 25597
+f 25674 25598 25597
+f 25673 25674 25597
+f 25675 25599 25598
+f 25674 25675 25598
+f 25676 25600 25599
+f 25675 25676 25599
+f 25677 25601 25600
+f 25676 25677 25600
+f 25678 25602 25601
+f 25677 25678 25601
+f 25679 19306 25602
+f 25678 25679 25602
+f 16805 20685 22683
+f 25679 19304 19306
+f 25680 25681 25682
+f 24096 21343 25683
+f 25681 25608 25684
+f 15547 25685 25609
+f 25611 25284 25612
+f 25286 25686 25687
+f 25167 25688 25532
+f 25533 25532 25536
+f 23316 23318 25244
+f 25689 25690 25691
+f 25692 17543 25693
+f 25694 25695 15886
+f 16097 25696 25697
+f 25697 25698 25699
+f 25083 25700 16110
+f 25701 1837 25702
+f 24199 24198 15770
+f 25703 17348 25704
+f 19867 13792 13791
+f 15707 2581 1386
+f 25503 16935 16937
+f 25705 25706 25707
+f 17997 25708 17998
+f 2591 25709 9383
+f 22956 25683 11429
+f 25710 8793 23283
+f 14250 2564 3968
+f 25711 24166 23821
+f 15675 15680 22292
+f 23336 25712 23835
+f 17388 24115 25711
+f 25713 23751 23749
+f 25696 25698 25697
+f 25653 25713 23749
+f 25714 23754 23751
+f 25713 25714 23751
+f 25715 23803 23754
+f 25716 22955 6102
+f 15153 6335 6357
+f 25717 25718 25620
+f 6356 25717 25620
+f 25718 25719 25621
+f 25620 25718 25621
+f 25719 25720 25622
+f 25621 25719 25622
+f 25720 25721 25623
+f 25622 25720 25623
+f 25722 25624 25623
+f 25721 25722 25623
+f 25722 25723 25625
+f 25624 25722 25625
+f 25723 25724 25626
+f 25625 25723 25626
+f 25724 23606 25539
+f 25626 25724 25539
+f 25142 17345 5801
+f 21643 25539 23606
+f 2110 2112 16007
+f 16093 13583 22991
+f 23525 24926 23802
+f 15691 23525 23802
+f 25632 870 15584
+f 18902 13962 20468
+f 9138 9139 17948
+f 23745 17148 16494
+f 17604 17606 22504
+f 25725 21454 21453
+f 24095 23987 15646
+f 24198 15762 15770
+f 19146 15965 19597
+f 8731 18495 18530
+f 25628 2863 25726
+f 9321 19021 25726
+f 25727 25628 25726
+f 25728 25727 25726
+f 25729 25630 25628
+f 25727 25729 25628
+f 25730 25631 25630
+f 25729 25730 25630
+f 23801 25632 25631
+f 25730 23801 25631
+f 15584 870 19748
+f 25731 25732 25733
+f 18174 11113 11414
+f 17204 9858 11695
+f 16477 16479 19050
+f 16474 15996 16963
+f 15399 11029 25734
+f 16498 24864 24863
+f 19159 24913 9325
+f 24913 17863 9325
+f 2461 13584 8871
+f 16835 15601 16148
+f 21412 17351 21410
+f 24217 24095 15964
+f 24198 24217 15843
+f 15536 15593 19034
+f 205 207 19029
+f 15632 570 569
+f 781 16057 25453
+f 1051 1612 16571
+f 16571 1612 16573
+f 17608 1051 16571
+f 1612 1079 16573
+f 1079 993 16568
+f 16573 1079 16568
+f 23327 16818 25164
+f 1336 18550 666
+f 25735 25736 25737
+f 25447 23308 8789
+f 25425 25353 17934
+f 23849 25738 25739
+f 25089 24280 25740
+f 25576 25424 25425
+f 25740 24282 25741
+f 24282 25742 25741
+f 25741 25742 25490
+f 25742 25488 25490
+f 8122 23092 25743
+f 25489 25571 25490
+f 25744 24549 25745
+f 25745 24549 24548
+f 25746 25747 3261
+f 24548 24547 25748
+f 25749 25750 25240
+f 1078 4157 16339
+f 15320 22721 7362
+f 25751 25752 18214
+f 25714 25715 23754
+f 25564 25753 6247
+f 25754 23874 23803
+f 25715 25754 23803
+f 25755 25399 25398
+f 25754 25756 23876
+f 21167 3963 6293
+f 25208 25757 25033
+f 25758 25250 25759
+f 25760 25761 22601
+f 25041 22441 22440
+f 22440 22439 25762
+f 22441 25763 22439
+f 180 16802 9915
+f 22550 22439 22248
+f 25762 22439 22550
+f 22940 25764 22941
+f 15130 14958 25765
+f 25764 25766 25663
+f 22941 25764 25663
+f 25766 25767 25664
+f 25663 25766 25664
+f 25767 25768 25665
+f 25664 25767 25665
+f 25768 25769 25666
+f 25665 25768 25666
+f 25769 25770 25667
+f 25666 25769 25667
+f 25770 25771 25668
+f 25667 25770 25668
+f 25771 25772 25669
+f 25668 25771 25669
+f 25772 25773 25670
+f 25669 25772 25670
+f 25773 25774 25671
+f 25670 25773 25671
+f 25774 25775 25672
+f 25671 25774 25672
+f 25776 25673 25672
+f 25775 25776 25672
+f 25777 25674 25673
+f 25776 25777 25673
+f 25778 25675 25674
+f 25777 25778 25674
+f 25779 25676 25675
+f 25778 25779 25675
+f 25780 25677 25676
+f 25779 25780 25676
+f 25781 25678 25677
+f 25780 25781 25677
+f 25782 25679 25678
+f 25781 25782 25678
+f 25783 19304 25679
+f 25782 25783 25679
+f 25784 22390 19304
+f 25783 25784 19304
+f 17488 24096 25683
+f 25784 25785 22390
+f 25612 25286 25687
+f 6800 6899 5393
+f 20152 5677 25786
+f 2659 4964 4963
+f 25787 3138 3140
+f 2660 25788 2658
+f 2954 2953 25787
+f 20153 20152 25786
+f 25789 25790 25791
+f 25792 25793 16656
+f 25794 25345 25795
+f 15699 25796 25797
+f 25482 25798 25483
+f 25084 25083 16110
+f 18529 8731 18530
+f 18970 19016 13462
+f 15922 25799 25800
+f 2047 21552 2048
+f 25801 25802 25803
+f 25804 25805 25803
+f 16110 25700 16111
+f 25083 25806 25700
+f 25582 25807 15730
+f 25808 25809 25810
+f 25811 25812 25813
+f 24614 25814 15956
+f 25815 25816 25817
+f 17343 25818 25819
+f 2816 2480 2296
+f 18722 8397 16492
+f 25310 25820 23349
+f 25807 25821 25822
+f 25708 1702 17998
+f 25203 25823 25824
+f 25825 25826 25827
+f 25567 25828 22787
+f 16101 16103 25829
+f 25830 25825 25827
+f 25563 25564 24545
+f 7952 850 851
+f 24166 23822 23821
+f 17308 25563 24545
+f 25635 17932 17934
+f 24062 24115 17388
+f 16590 25831 5635
+f 25832 16590 5635
+f 23874 25754 23876
+f 17254 17253 16101
+f 25833 21793 25834
+f 23876 25756 22254
+f 19704 25835 25276
+f 16210 23882 22717
+f 21346 25836 25717
+f 25837 25838 25839
+f 25836 25840 25718
+f 25717 25836 25718
+f 25840 25841 25719
+f 25718 25840 25719
+f 25841 25842 25720
+f 25719 25841 25720
+f 25842 25843 25721
+f 25720 25842 25721
+f 25844 25722 25721
+f 25843 25844 25721
+f 25844 25845 25723
+f 25722 25844 25723
+f 25845 25846 25724
+f 25723 25845 25724
+f 25847 23606 25724
+f 25846 25847 25724
+f 25847 21733 21700
+f 23606 25847 21700
+f 12702 18839 8046
+f 23546 25220 23547
+f 15566 464 13960
+f 16479 16393 19050
+f 17863 9426 9325
+f 25632 23801 870
+f 9732 16655 16045
+f 22552 14981 20288
+f 2342 2341 16228
+f 22924 25848 20025
+f 25833 25834 17222
+f 15769 24218 15770
+f 19020 25728 19021
+f 25415 24507 22826
+f 25849 25728 19020
+f 24507 25849 19020
+f 25850 25727 25728
+f 25849 25850 25728
+f 25851 25729 25727
+f 25850 25851 25727
+f 25852 25730 25729
+f 25851 25852 25729
+f 871 23801 25730
+f 25852 871 25730
+f 18930 22575 25853
+f 21729 23592 22473
+f 24516 18750 21846
+f 16459 24821 13961
+f 18798 21163 9873
+f 11714 17137 1672
+f 21041 17949 15853
+f 3008 2811 14294
+f 3369 14376 17999
+f 25166 19717 16828
+f 19001 18947 18948
+f 25854 25855 25856
+f 23427 20814 24996
+f 15588 206 205
+f 17572 25645 17573
+f 782 781 25453
+f 16057 16058 25537
+f 16567 25453 15842
+f 25537 25538 16814
+f 9304 9552 1074
+f 2804 2115 3759
+f 15616 337 696
+f 9551 15616 696
+f 25857 25858 6100
+f 25500 25155 25501
+f 25859 25860 25861
+f 23341 7329 7331
+f 24975 25862 24973
+f 20411 25273 25272
+f 25863 14621 14623
+f 25864 25865 25866
+f 25863 21623 14621
+f 14622 14621 21371
+f 21623 25867 21370
+f 8122 25743 8123
+f 25867 25868 25744
+f 21370 25867 25744
+f 25868 25869 24549
+f 25744 25868 24549
+f 25869 25746 24547
+f 24549 25869 24547
+f 25870 25871 23254
+f 25872 25873 25874
+f 5549 2845 2844
+f 16736 25875 17387
+f 24800 25876 24801
+f 25712 23881 25877
+f 16558 25878 16559
+f 23354 14885 25562
+f 25879 25449 25880
+f 25753 25367 6247
+f 17129 17131 17345
+f 25202 25204 25688
+f 24683 25881 25041
+f 22603 24683 25041
+f 25881 25882 22441
+f 25041 25881 22441
+f 25882 25883 25763
+f 22441 25882 25763
+f 25883 25884 22940
+f 25763 25883 22940
+f 25884 25885 25764
+f 22940 25884 25764
+f 25885 25886 25766
+f 25764 25885 25766
+f 25886 25887 25767
+f 25766 25886 25767
+f 25887 25888 25768
+f 25767 25887 25768
+f 25888 25889 25769
+f 25768 25888 25769
+f 25889 25890 25770
+f 25769 25889 25770
+f 25890 25891 25771
+f 25770 25890 25771
+f 25891 25892 25772
+f 25771 25891 25772
+f 25892 25893 25773
+f 25772 25892 25773
+f 25893 25894 25774
+f 25773 25893 25774
+f 25894 25895 25775
+f 25774 25894 25775
+f 25896 25776 25775
+f 25895 25896 25775
+f 25897 25777 25776
+f 25896 25897 25776
+f 25898 25778 25777
+f 25897 25898 25777
+f 25899 25779 25778
+f 25898 25899 25778
+f 25899 25900 25780
+f 25779 25899 25780
+f 25901 25781 25780
+f 25900 25901 25780
+f 25902 25782 25781
+f 25901 25902 25781
+f 25903 25783 25782
+f 25902 25903 25782
+f 25904 25784 25783
+f 25903 25904 25783
+f 25905 25785 25784
+f 25904 25905 25784
+f 25906 25907 25785
+f 25905 25906 25785
+f 25908 2660 25907
+f 25906 25908 25907
+f 25909 25788 2660
+f 25908 25909 2660
+f 25910 25911 25788
+f 25909 25910 25788
+f 16656 25793 25911
+f 25910 16656 25911
+f 25912 15653 15698
+f 14847 22278 22280
+f 25700 25810 16111
+f 17160 17159 4344
+f 25913 25914 25482
+f 24313 24312 25915
+f 25483 25916 25917
+f 25914 25798 25482
+f 16111 25810 14840
+f 25916 25918 25917
+f 25800 25919 25920
+f 25810 25804 14840
+f 25700 25808 25810
+f 25809 25805 25804
+f 25034 25921 25922
+f 25923 25921 25924
+f 25816 25208 25033
+f 25208 25925 25926
+f 25927 25928 25929
+f 25452 25930 25931
+f 25932 25828 25933
+f 25934 24965 24967
+f 17364 25935 6256
+f 14689 25032 25936
+f 24118 24226 24223
+f 25937 25938 24960
+f 15108 22787 15109
+f 25708 17997 25939
+f 25940 16101 25829
+f 25932 22787 25828
+f 6247 25367 6248
+f 25941 25942 25943
+f 25875 24062 17388
+f 24545 25564 24546
+f 23349 14989 23350
+f 24115 24166 25711
+f 25944 23901 23903
+f 25945 14896 25310
+f 23953 23808 15666
+f 6250 6380 6097
+f 17253 16102 16101
+f 25101 25946 25634
+f 25717 2841 21346
+f 25934 24967 25947
+f 25948 25949 25840
+f 25836 25948 25840
+f 25949 25950 25841
+f 25840 25949 25841
+f 25950 25951 25842
+f 25841 25950 25842
+f 25951 25952 25843
+f 25842 25951 25843
+f 25953 25844 25843
+f 25952 25953 25843
+f 25953 25954 25845
+f 25844 25953 25845
+f 25954 25955 25846
+f 25845 25954 25846
+f 14965 25847 25846
+f 25955 14965 25846
+f 21296 11614 21321
+f 25847 14965 21733
+f 16479 19596 16394
+f 16835 16148 18931
+f 15559 15861 15557
+f 18777 21455 18778
+f 7320 16006 7321
+f 14029 14028 18576
+f 16350 16578 16351
+f 20334 15849 24585
+f 24218 24199 15770
+f 12922 24253 15769
+f 3334 25956 25879
+f 25415 14604 25413
+f 25957 24507 25415
+f 25414 25957 25415
+f 25958 25849 24507
+f 25957 25958 24507
+f 19345 25850 25849
+f 25958 19345 25849
+f 19344 25851 25850
+f 19345 19344 25850
+f 14643 25852 25851
+f 19344 14643 25851
+f 9716 871 25852
+f 14643 9716 25852
+f 16158 23374 23378
+f 17002 17223 15992
+f 10301 15455 22841
+f 23644 21119 3969
+f 23802 11713 4940
+f 14028 16466 18576
+f 6200 14961 6201
+f 871 9716 3182
+f 25959 15885 23960
+f 16735 25875 16736
+f 25960 25961 25962
+f 23265 23264 24928
+f 7360 23773 7361
+f 7359 25963 25964
+f 25453 16057 25537
+f 23774 1663 23772
+f 569 571 16814
+f 25538 569 16814
+f 2004 2804 3759
+f 794 2804 2004
+f 15711 25965 15712
+f 7925 7927 25966
+f 25967 25968 25969
+f 25966 25967 25969
+f 25970 25858 25968
+f 25967 25970 25968
+f 25971 25972 25973
+f 25970 25974 25858
+f 25975 25863 25976
+f 25974 25975 25976
+f 25975 25977 21623
+f 25863 25975 21623
+f 25977 25978 25867
+f 21623 25977 25867
+f 25978 25979 25868
+f 25867 25978 25868
+f 25979 25980 25869
+f 25868 25979 25869
+f 25747 25981 3262
+f 25869 25980 25746
+f 4078 7748 16716
+f 25982 25983 25984
+f 25859 25985 25860
+f 15711 6256 22111
+f 25986 23301 23327
+f 24990 25987 25281
+f 25988 16254 18903
+f 25835 17511 17510
+f 25989 25990 25991
+f 23824 23826 25992
+f 25993 24682 25994
+f 25995 25994 24682
+f 24682 25996 24683
+f 25996 25997 25881
+f 24683 25996 25881
+f 25997 25998 25882
+f 25881 25997 25882
+f 25998 25999 25883
+f 25882 25998 25883
+f 25999 26000 25884
+f 25883 25999 25884
+f 26000 26001 25885
+f 25884 26000 25885
+f 26001 26002 25886
+f 25885 26001 25886
+f 26002 26003 25887
+f 25886 26002 25887
+f 26003 26004 25888
+f 25887 26003 25888
+f 26004 26005 25889
+f 25888 26004 25889
+f 26005 26006 25890
+f 25889 26005 25890
+f 26006 26007 25891
+f 25890 26006 25891
+f 26007 26008 25892
+f 25891 26007 25892
+f 26008 26009 25893
+f 25892 26008 25893
+f 26009 26010 25894
+f 25893 26009 25894
+f 26011 25895 25894
+f 26010 26011 25894
+f 26012 25896 25895
+f 26011 26012 25895
+f 26013 25897 25896
+f 26012 26013 25896
+f 26014 25898 25897
+f 26013 26014 25897
+f 26014 26015 25899
+f 25898 26014 25899
+f 26015 26016 25900
+f 25899 26015 25900
+f 26017 25901 25900
+f 26016 26017 25900
+f 26018 25902 25901
+f 26017 26018 25901
+f 26019 25903 25902
+f 26018 26019 25902
+f 26020 25904 25903
+f 26019 26020 25903
+f 26021 25905 25904
+f 26020 26021 25904
+f 26022 25906 25905
+f 26021 26022 25905
+f 26023 25908 25906
+f 26022 26023 25906
+f 26024 25909 25908
+f 26023 26024 25908
+f 26025 25910 25909
+f 26024 26025 25909
+f 18873 16656 25910
+f 26025 18873 25910
+f 26026 6102 22279
+f 24822 18873 26025
+f 26027 25701 26028
+f 25824 26027 26028
+f 1838 26029 26030
+f 17620 26031 26032
+f 25021 2394 25645
+f 26033 26034 26035
+f 26036 25241 26037
+f 26038 26039 25941
+f 25803 25800 25920
+f 25799 26040 25919
+f 13949 26041 14036
+f 2080 662 2081
+f 25034 25922 23079
+f 25921 26042 25924
+f 25757 25208 25926
+f 25925 26037 26043
+f 26037 26044 26045
+f 25926 25925 26043
+f 26044 24693 24692
+f 26043 26037 26045
+f 26045 26044 24692
+f 25938 24961 24960
+f 26046 22864 22865
+f 24964 26046 22865
+f 26047 16002 10022
+f 24798 26048 25207
+f 15659 25697 24509
+f 25206 24798 25207
+f 5115 25365 25753
+f 23895 23894 26049
+f 25023 24612 24611
+f 26050 25023 24611
+f 11543 11542 26051
+f 26052 25094 23363
+f 26053 24461 26054
+f 24462 24535 23839
+f 26055 25102 26056
+f 26057 24800 24799
+f 25948 21346 6370
+f 26047 25786 16002
+f 26058 25949 25948
+f 26059 26058 25948
+f 26058 26060 25950
+f 25949 26058 25950
+f 26060 26061 25951
+f 25950 26060 25951
+f 26061 26062 25952
+f 25951 26061 25952
+f 26063 25953 25952
+f 26062 26063 25952
+f 26063 26064 25954
+f 25953 26063 25954
+f 26065 25955 25954
+f 26064 26065 25954
+f 26065 14966 14965
+f 25955 26065 14965
+f 22682 22289 22313
+f 1023 15951 14144
+f 24806 3589 20299
+f 16393 16479 16394
+f 3769 12274 5729
+f 18997 20910 20861
+f 894 23730 2610
+f 16140 23076 16141
+f 26066 26067 9379
+f 400 4797 401
+f 21247 25414 25413
+f 24253 24218 15769
+f 26068 25414 21247
+f 21246 26068 21247
+f 26069 25957 25414
+f 26068 26069 25414
+f 26070 25958 25957
+f 26069 26070 25957
+f 26071 19345 25958
+f 26070 26071 25958
+f 26071 15481 19345
+f 21515 15481 26071
+f 14642 14643 19344
+f 25848 22924 22923
+f 23495 19440 19439
+f 23260 8928 26072
+f 16466 894 15944
+f 17808 16605 892
+f 26073 14029 18575
+f 18576 16466 15944
+f 23730 17787 2611
+f 15944 894 2610
+f 25913 25482 26074
+f 17204 11695 5535
+f 16652 24854 16397
+f 16971 26075 23712
+f 22789 25964 22953
+f 22925 26076 16912
+f 26077 23774 25964
+f 22789 26077 25964
+f 570 1856 571
+f 20685 3144 17741
+f 16662 25966 7927
+f 3144 3534 3145
+f 26078 25966 16662
+f 1664 26078 16662
+f 26079 25967 25966
+f 26078 26079 25966
+f 26080 25970 25967
+f 26079 26080 25967
+f 26081 25974 25970
+f 26080 26081 25970
+f 26082 25975 25974
+f 26081 26082 25974
+f 26082 26083 25977
+f 25975 26082 25977
+f 26083 26084 25978
+f 25977 26083 25978
+f 26084 26085 25979
+f 25978 26084 25979
+f 26085 26086 25980
+f 25979 26085 25980
+f 26086 25981 25747
+f 25980 26086 25747
+f 17668 17487 20420
+f 17549 3260 3262
+f 25860 25986 23327
+f 23445 24757 25644
+f 24113 22846 26087
+f 25930 25705 25707
+f 25991 14303 25993
+f 25878 26088 16559
+f 26089 26090 25993
+f 14303 26089 25993
+f 26090 26091 24682
+f 25993 26090 24682
+f 26091 26092 25996
+f 24682 26091 25996
+f 26092 26093 25997
+f 25996 26092 25997
+f 26093 26094 25998
+f 25997 26093 25998
+f 26094 26095 25999
+f 25998 26094 25999
+f 26095 26096 26000
+f 25999 26095 26000
+f 26096 26097 26001
+f 26000 26096 26001
+f 26097 26098 26002
+f 26001 26097 26002
+f 26098 26099 26003
+f 26002 26098 26003
+f 26099 26100 26004
+f 26003 26099 26004
+f 26100 26101 26005
+f 26004 26100 26005
+f 26101 26102 26006
+f 26005 26101 26006
+f 26102 26103 26007
+f 26006 26102 26007
+f 26103 26104 26008
+f 26007 26103 26008
+f 26104 26105 26009
+f 26008 26104 26009
+f 26105 26106 26010
+f 26009 26105 26010
+f 26106 26107 26011
+f 26010 26106 26011
+f 26108 26012 26011
+f 26107 26108 26011
+f 26109 26013 26012
+f 26108 26109 26012
+f 26110 26014 26013
+f 26109 26110 26013
+f 26111 26015 26014
+f 26110 26111 26014
+f 26111 26112 26016
+f 26015 26111 26016
+f 26113 26017 26016
+f 26112 26113 26016
+f 26114 26018 26017
+f 26113 26114 26017
+f 26115 26019 26018
+f 26114 26115 26018
+f 26116 26020 26019
+f 26115 26116 26019
+f 26117 26021 26020
+f 26116 26117 26020
+f 26118 26022 26021
+f 26117 26118 26021
+f 26119 26023 26022
+f 26118 26119 26022
+f 26120 26024 26023
+f 26119 26120 26023
+f 24823 26025 26024
+f 26120 24823 26024
+f 6951 24823 26121
+f 18956 15233 22793
+f 25699 25789 25791
+f 25790 26122 26123
+f 25702 1839 18204
+f 18203 25702 18204
+f 25203 25824 25361
+f 26028 25702 18203
+f 25791 25790 26123
+f 25361 26028 18203
+f 26124 25737 26125
+f 25737 25495 26125
+f 16758 16035 26126
+f 1539 16827 19624
+f 26127 26128 26129
+f 26130 17824 17826
+f 23080 23079 25922
+f 25921 25923 25922
+f 26131 11885 26132
+f 25815 25817 26133
+f 18615 22595 25360
+f 25505 26133 26132
+f 5947 15188 24691
+f 15514 16552 16654
+f 24693 26134 24694
+f 26135 26136 26137
+f 17485 17509 17483
+f 25505 25815 26133
+f 25399 24529 24531
+f 14689 14691 25032
+f 25862 24975 24964
+f 26138 26139 26140
+f 22866 18183 26141
+f 26142 17641 26143
+f 26144 26145 24560
+f 25740 25741 25351
+f 24612 24609 24608
+f 25205 26146 26147
+f 25023 26050 26148
+f 24598 25023 26148
+f 17668 9412 17487
+f 4345 21226 4369
+f 6369 26149 26059
+f 26150 26151 26152
+f 26153 26059 26149
+f 26151 26153 26149
+f 26154 26058 26059
+f 26153 26154 26059
+f 26155 26060 26058
+f 26154 26155 26058
+f 26155 26156 26061
+f 26060 26155 26061
+f 26156 26157 26062
+f 26061 26156 26062
+f 26157 26158 26063
+f 26062 26157 26063
+f 26159 26064 26063
+f 26158 26159 26063
+f 26160 26065 26064
+f 26159 26160 26064
+f 26160 21846 14966
+f 26065 26160 14966
+f 2104 17843 24528
+f 15861 17769 14293
+f 19596 9730 16860
+f 10965 20333 15648
+f 7319 7667 7666
+f 2610 23730 2611
+f 16624 16332 15979
+f 21006 18961 16414
+f 12921 24254 12922
+f 24254 24253 12922
+f 26161 24162 24113
+f 3810 26162 6947
+f 26163 26068 21246
+f 26164 26163 21246
+f 26165 26069 26068
+f 26163 26165 26068
+f 26166 26070 26069
+f 26165 26166 26069
+f 21516 26071 26070
+f 26166 21516 26070
+f 22996 22995 22899
+f 18069 13791 13948
+f 10993 20334 20333
+f 23852 23731 15891
+f 17787 17788 7666
+f 26167 26161 24113
+f 2611 17787 7666
+f 15190 3006 3005
+f 3378 19410 3379
+f 24063 24064 6254
+f 14967 18750 20985
+f 26161 26168 24164
+f 25832 5635 26169
+f 24162 26161 24164
+f 22953 25963 22954
+f 8921 23314 14888
+f 26170 26077 22789
+f 22790 26170 22789
+f 25508 1663 26077
+f 26170 25508 26077
+f 26171 1664 1663
+f 795 794 2004
+f 26172 26078 1664
+f 26171 26172 1664
+f 26173 26079 26078
+f 26172 26173 26078
+f 26174 26080 26079
+f 26173 26174 26079
+f 26175 26081 26080
+f 26174 26175 26080
+f 26176 26082 26081
+f 26175 26176 26081
+f 26176 26177 26083
+f 26082 26176 26083
+f 26177 26178 26084
+f 26083 26177 26084
+f 26178 26179 26085
+f 26084 26178 26085
+f 26179 26180 26086
+f 26085 26179 26086
+f 26180 21495 25981
+f 26086 26180 25981
+f 16244 17668 20420
+f 25981 21495 17549
+f 26168 26181 24220
+f 24317 26182 5385
+f 26182 26183 14302
+f 14302 26089 14303
+f 26183 26184 26089
+f 14302 26183 26089
+f 26184 26185 26090
+f 26089 26184 26090
+f 26185 26186 26091
+f 26090 26185 26091
+f 26186 26187 26092
+f 26091 26186 26092
+f 26187 26188 26093
+f 26092 26187 26093
+f 26188 26189 26094
+f 26093 26188 26094
+f 26189 26190 26095
+f 26094 26189 26095
+f 26190 26191 26096
+f 26095 26190 26096
+f 26191 26192 26097
+f 26096 26191 26097
+f 26192 26193 26098
+f 26097 26192 26098
+f 26193 26194 26099
+f 26098 26193 26099
+f 26194 26195 26100
+f 26099 26194 26100
+f 26195 26196 26101
+f 26100 26195 26101
+f 26196 26197 26102
+f 26101 26196 26102
+f 26197 26198 26103
+f 26102 26197 26103
+f 26198 26199 26104
+f 26103 26198 26104
+f 26199 26200 26105
+f 26104 26199 26105
+f 26200 26201 26106
+f 26105 26200 26106
+f 26201 26202 26107
+f 26106 26201 26107
+f 26203 26108 26107
+f 26202 26203 26107
+f 26204 26109 26108
+f 26203 26204 26108
+f 26205 26110 26109
+f 26204 26205 26109
+f 26206 26111 26110
+f 26205 26206 26110
+f 26206 26207 26112
+f 26111 26206 26112
+f 26208 26113 26112
+f 26207 26208 26112
+f 26209 26114 26113
+f 26208 26209 26113
+f 26210 26115 26114
+f 26209 26210 26114
+f 26211 26116 26115
+f 26210 26211 26115
+f 26212 26117 26116
+f 26211 26212 26116
+f 26213 26118 26117
+f 26212 26213 26117
+f 26214 26119 26118
+f 26213 26214 26118
+f 26215 26120 26119
+f 26214 26215 26119
+f 26121 24823 26120
+f 26215 26121 26120
+f 18045 17525 20298
+f 2238 6951 26216
+f 17264 17263 25692
+f 17194 20501 17193
+f 25814 26217 15956
+f 25510 25509 26218
+f 26219 17801 11226
+f 25553 20022 25212
+f 26220 25531 25530
+f 26221 26220 25530
+f 14901 15383 25470
+f 3160 1179 15343
+f 26222 26223 26038
+f 26224 26225 26226
+f 26227 26228 26229
+f 26230 26231 26232
+f 23097 20410 22746
+f 26233 23954 26234
+f 15216 2503 986
+f 20410 15767 18751
+f 23829 17567 24776
+f 22746 20410 18751
+f 18751 15767 18443
+f 24110 23752 24058
+f 16097 25697 15659
+f 26235 26236 26237
+f 25816 25033 25817
+f 25924 26042 26238
+f 25642 25641 26239
+f 25098 25101 25634
+f 17343 17342 25818
+f 26240 17256 26241
+f 25681 25684 25682
+f 17529 26242 25170
+f 23268 23267 23905
+f 22901 8857 15850
+f 18794 25015 24598
+f 17573 23268 23905
+f 15929 4345 4369
+f 26243 26244 17180
+f 26245 26150 18003
+f 23641 26245 18003
+f 26246 26151 26150
+f 26245 26246 26150
+f 26247 26153 26151
+f 26246 26247 26151
+f 26248 26154 26153
+f 26247 26248 26153
+f 26249 26155 26154
+f 26248 26249 26154
+f 26250 26156 26155
+f 26249 26250 26155
+f 26251 26157 26156
+f 26250 26251 26156
+f 26252 26158 26157
+f 26251 26252 26157
+f 26253 26159 26158
+f 26252 26253 26158
+f 26253 26254 26160
+f 26159 26253 26160
+f 26254 24516 21846
+f 26160 26254 21846
+f 17550 17549 21496
+f 21496 21495 26255
+f 18639 15481 21515
+f 16394 19596 16860
+f 2148 5779 5778
+f 6844 6378 10952
+f 17845 17844 23065
+f 20831 19166 19165
+f 21245 23980 26164
+f 26256 26257 23982
+f 26258 26164 23980
+f 26257 26258 23980
+f 26259 26163 26164
+f 26258 26259 26164
+f 26260 26165 26163
+f 26259 26260 26163
+f 26261 26166 26165
+f 26260 26261 26165
+f 21453 21516 26166
+f 26261 21453 26166
+f 26071 21516 21515
+f 26262 5197 16090
+f 649 22680 8292
+f 21902 6242 6241
+f 10947 9379 26067
+f 24516 21444 21839
+f 23721 2396 26263
+f 25587 25584 26264
+f 24164 26168 24220
+f 26181 26265 24332
+f 24220 26181 24332
+f 26265 26266 24389
+f 21034 21167 6354
+f 24634 26263 18268
+f 26267 26170 22790
+f 26076 22925 26268
+f 26267 26269 25506
+f 26267 25506 26170
+f 17118 795 2003
+f 2004 3759 2005
+f 26270 26172 26171
+f 26271 19340 20813
+f 26272 26173 26172
+f 26270 26272 26172
+f 26273 26174 26173
+f 26272 26273 26173
+f 26274 26175 26174
+f 26273 26274 26174
+f 26275 26176 26175
+f 26274 26275 26175
+f 26275 26276 26177
+f 26176 26275 26177
+f 26276 26277 26178
+f 26177 26276 26178
+f 26277 26278 26179
+f 26178 26277 26179
+f 26278 26279 26180
+f 26179 26278 26180
+f 26279 26255 21495
+f 26180 26279 21495
+f 22748 26280 17052
+f 9412 9414 17487
+f 26281 26282 26182
+f 17640 17635 25269
+f 26282 26283 26183
+f 26182 26282 26183
+f 26283 26284 26184
+f 26183 26283 26184
+f 26284 26285 26185
+f 26184 26284 26185
+f 26285 26286 26186
+f 26185 26285 26186
+f 26286 26287 26187
+f 26186 26286 26187
+f 26287 26288 26188
+f 26187 26287 26188
+f 26288 26289 26189
+f 26188 26288 26189
+f 26289 26290 26190
+f 26189 26289 26190
+f 26290 26291 26191
+f 26190 26290 26191
+f 26291 26292 26192
+f 26191 26291 26192
+f 26292 26293 26193
+f 26192 26292 26193
+f 26293 26294 26194
+f 26193 26293 26194
+f 26294 26295 26195
+f 26194 26294 26195
+f 26295 26296 26196
+f 26195 26295 26196
+f 26296 26297 26197
+f 26196 26296 26197
+f 26297 26298 26198
+f 26197 26297 26198
+f 26298 26299 26199
+f 26198 26298 26199
+f 26299 26300 26200
+f 26199 26299 26200
+f 26300 26301 26201
+f 26200 26300 26201
+f 26301 26302 26202
+f 26201 26301 26202
+f 26303 26203 26202
+f 26302 26303 26202
+f 26304 26204 26203
+f 26303 26304 26203
+f 26305 26205 26204
+f 26304 26305 26204
+f 26306 26206 26205
+f 26305 26306 26205
+f 26307 26207 26206
+f 26306 26307 26206
+f 26308 26208 26207
+f 26307 26308 26207
+f 26309 26209 26208
+f 26308 26309 26208
+f 26310 26210 26209
+f 26309 26310 26209
+f 26311 26211 26210
+f 26310 26311 26210
+f 26312 26212 26211
+f 26311 26312 26211
+f 26313 26213 26212
+f 26312 26313 26212
+f 26314 26214 26213
+f 26313 26314 26213
+f 26315 26215 26214
+f 26314 26315 26214
+f 26216 26121 26215
+f 26315 26216 26215
+f 26316 17438 26317
+f 26121 26216 6951
+f 26318 25398 25400
+f 26319 26318 25400
+f 26123 25530 17449
+f 23831 23963 23723
+f 25090 26320 20683
+f 26321 26322 26323
+f 26324 25752 25751
+f 25752 18212 18214
+f 19145 23350 12653
+f 16454 17352 26325
+f 26326 26327 26328
+f 26039 26329 25941
+f 26330 26331 6245
+f 6245 22064 26328
+f 21067 6244 23169
+f 26331 6243 6245
+f 21067 23169 26332
+f 6243 23170 6244
+f 23170 26333 15280
+f 26332 15280 23389
+f 19985 23389 15282
+f 26333 15281 15280
+f 19985 19984 23319
+f 15281 19983 15282
+f 26334 26335 26336
+f 23319 19984 8990
+f 25100 25936 25946
+f 26042 26334 26238
+f 656 657 26337
+f 25101 25100 25946
+f 17342 17529 25170
+f 17735 17734 23338
+f 26338 22717 17281
+f 17529 25579 25578
+f 2242 2244 2764
+f 17852 17640 3726
+f 26339 23641 26340
+f 22219 26339 26340
+f 26341 26245 23641
+f 26339 26341 23641
+f 26342 26246 26245
+f 26341 26342 26245
+f 26343 26247 26246
+f 26342 26343 26246
+f 26344 26248 26247
+f 26343 26344 26247
+f 26345 26249 26248
+f 26344 26345 26248
+f 26346 26250 26249
+f 26345 26346 26249
+f 26347 26251 26250
+f 26346 26347 26250
+f 26348 26252 26251
+f 26347 26348 26251
+f 26349 26253 26252
+f 26348 26349 26252
+f 26350 26254 26253
+f 26349 26350 26253
+f 21444 24516 26254
+f 26350 21444 26254
+f 16665 19785 9527
+f 25100 14689 25936
+f 13382 7248 7142
+f 24912 16474 16963
+f 954 12701 16005
+f 18116 16414 18961
+f 26257 23980 23982
+f 17852 3726 3725
+f 26351 26257 26256
+f 26352 26351 26256
+f 26353 26258 26257
+f 26351 26353 26257
+f 26354 26259 26258
+f 26353 26354 26258
+f 26355 26260 26259
+f 26354 26355 26259
+f 25725 26261 26260
+f 26355 25725 26260
+f 22998 15508 21042
+f 26261 25725 21453
+f 9301 17772 9302
+f 836 22473 5507
+f 4782 15861 15862
+f 19410 16770 2786
+f 2189 16422 2190
+f 22232 26356 22233
+f 23895 26049 26357
+f 26358 22232 26359
+f 1742 26358 26359
+f 26356 26267 22790
+f 26358 26360 22232
+f 26361 26267 26356
+f 26360 26361 26356
+f 26269 26361 26362
+f 26361 26269 26267
+f 16832 16831 16546
+f 22632 9404 22691
+f 26363 26270 26364
+f 26171 26364 26270
+f 26365 26272 26270
+f 26363 26365 26270
+f 26366 26273 26272
+f 26365 26366 26272
+f 26367 26274 26273
+f 26366 26367 26273
+f 26368 26275 26274
+f 26367 26368 26274
+f 26369 26276 26275
+f 26368 26369 26275
+f 26369 26370 26277
+f 26276 26369 26277
+f 26370 26371 26278
+f 26277 26370 26278
+f 26371 26372 26279
+f 26278 26371 26279
+f 26372 26280 26255
+f 26279 26372 26255
+f 21270 17053 17052
+f 26255 26280 22748
+f 26373 17468 17467
+f 26281 15221 21013
+f 26374 26375 26283
+f 26282 26374 26283
+f 26375 26376 26284
+f 26283 26375 26284
+f 26376 26377 26285
+f 26284 26376 26285
+f 26377 26378 26286
+f 26285 26377 26286
+f 26378 26379 26287
+f 26286 26378 26287
+f 26379 26380 26288
+f 26287 26379 26288
+f 26381 26289 26288
+f 26380 26381 26288
+f 26381 26382 26290
+f 26289 26381 26290
+f 26382 26383 26291
+f 26290 26382 26291
+f 26383 26384 26292
+f 26291 26383 26292
+f 26384 26385 26293
+f 26292 26384 26293
+f 26385 26386 26294
+f 26293 26385 26294
+f 26386 26387 26295
+f 26294 26386 26295
+f 26387 26388 26296
+f 26295 26387 26296
+f 26388 26389 26297
+f 26296 26388 26297
+f 26389 26390 26298
+f 26297 26389 26298
+f 26390 26391 26299
+f 26298 26390 26299
+f 26391 26392 26300
+f 26299 26391 26300
+f 26392 26393 26301
+f 26300 26392 26301
+f 26393 26394 26302
+f 26301 26393 26302
+f 26394 26395 26303
+f 26302 26394 26303
+f 26396 26304 26303
+f 26395 26396 26303
+f 26397 26305 26304
+f 26396 26397 26304
+f 26398 26306 26305
+f 26397 26398 26305
+f 26399 26307 26306
+f 26398 26399 26306
+f 26400 26308 26307
+f 26399 26400 26307
+f 26401 26309 26308
+f 26400 26401 26308
+f 26402 26310 26309
+f 26401 26402 26309
+f 26403 26311 26310
+f 26402 26403 26310
+f 26404 26312 26311
+f 26403 26404 26311
+f 26405 26313 26312
+f 26404 26405 26312
+f 26406 26314 26313
+f 26405 26406 26313
+f 26407 26315 26314
+f 26406 26407 26314
+f 2239 26216 26315
+f 26407 2239 26315
+f 26408 26409 26410
+f 17361 26411 15585
+f 26409 26412 26413
+f 26414 26408 26410
+f 9274 25095 25360
+f 25603 26415 1838
+f 24509 25699 26416
+f 25791 26123 26417
+f 26418 26419 26420
+f 26420 26324 25751
+f 26421 26327 26326
+f 25337 25529 24529
+f 26422 26423 26330
+f 26421 26422 26330
+f 26423 26424 26331
+f 26330 26423 26331
+f 26425 6243 26331
+f 26424 26425 26331
+f 26425 26426 23170
+f 6243 26425 23170
+f 26427 26333 23170
+f 26426 26427 23170
+f 26428 15281 26333
+f 26427 26428 26333
+f 26429 19983 15281
+f 26428 26429 15281
+f 26430 19984 19983
+f 26429 26430 19983
+f 17159 3725 4344
+f 26430 26431 19984
+f 16891 8989 8991
+f 26431 8991 8990
+f 2081 656 26432
+f 22784 8989 10425
+f 26242 17529 25578
+f 3042 23715 3043
+f 22218 22217 5545
+f 25579 25656 25580
+f 26433 26339 22219
+f 26434 26433 22219
+f 26435 26341 26339
+f 26433 26435 26339
+f 26436 26342 26341
+f 26435 26436 26341
+f 26437 26343 26342
+f 26436 26437 26342
+f 26438 26344 26343
+f 26437 26438 26343
+f 26439 26345 26344
+f 26438 26439 26344
+f 26440 26346 26345
+f 26439 26440 26345
+f 26441 26347 26346
+f 26440 26441 26346
+f 26442 26348 26347
+f 26441 26442 26347
+f 26443 26349 26348
+f 26442 26443 26348
+f 26444 26350 26349
+f 26443 26444 26349
+f 18155 21444 26350
+f 26444 18155 26350
+f 16681 22172 25456
+f 18736 8215 18708
+f 23642 15852 12541
+f 18932 16148 16150
+f 26352 26445 26446
+f 19439 20150 23478
+f 26447 26352 26446
+f 26448 26447 26446
+f 26449 26351 26352
+f 26447 26449 26352
+f 26450 26353 26351
+f 26449 26450 26351
+f 26451 26354 26353
+f 26450 26451 26353
+f 26452 26355 26354
+f 26451 26452 26354
+f 24996 20653 22475
+f 26355 26452 25725
+f 23643 12886 24268
+f 8043 17844 8044
+f 23564 19702 17771
+f 3604 3008 3605
+f 25463 21591 21589
+f 8936 19488 634
+f 21837 16840 21838
+f 22044 26358 1742
+f 1744 22044 1742
+f 26453 26360 26358
+f 22044 26453 26358
+f 26454 26361 26360
+f 26453 26454 26360
+f 26455 26456 26362
+f 26454 26362 26361
+f 1601 1603 2824
+f 26457 26458 14311
+f 26459 26363 26460
+f 26460 26364 25507
+f 26461 26365 26363
+f 26459 26461 26363
+f 26462 26366 26365
+f 26461 26462 26365
+f 26463 26367 26366
+f 26462 26463 26366
+f 26464 26368 26367
+f 26463 26464 26367
+f 26465 26369 26368
+f 26464 26465 26368
+f 26465 26466 26370
+f 26369 26465 26370
+f 26466 26467 26371
+f 26370 26466 26371
+f 26467 26468 26372
+f 26371 26467 26372
+f 26468 21269 26280
+f 26372 26468 26280
+f 15928 19071 22437
+f 24584 24505 24583
+f 10092 4735 5812
+f 26469 26470 26375
+f 17467 17466 26282
+f 26470 26471 26376
+f 26375 26470 26376
+f 26471 26472 26377
+f 26376 26471 26377
+f 26472 26473 26378
+f 26377 26472 26378
+f 26473 26474 26379
+f 26378 26473 26379
+f 26474 26475 26380
+f 26379 26474 26380
+f 26475 26476 26381
+f 26380 26475 26381
+f 26476 26477 26382
+f 26381 26476 26382
+f 26477 26478 26383
+f 26382 26477 26383
+f 26478 26479 26384
+f 26383 26478 26384
+f 26479 26480 26385
+f 26384 26479 26385
+f 26480 26481 26386
+f 26385 26480 26386
+f 26481 26482 26387
+f 26386 26481 26387
+f 26482 26483 26388
+f 26387 26482 26388
+f 26483 26484 26389
+f 26388 26483 26389
+f 26484 26485 26390
+f 26389 26484 26390
+f 26485 26486 26391
+f 26390 26485 26391
+f 26487 26392 26391
+f 26486 26487 26391
+f 26487 26488 26393
+f 26392 26487 26393
+f 26488 26489 26394
+f 26393 26488 26394
+f 26489 26490 26395
+f 26394 26489 26395
+f 26490 26491 26396
+f 26395 26490 26396
+f 26492 26397 26396
+f 26491 26492 26396
+f 26493 26398 26397
+f 26492 26493 26397
+f 26494 26399 26398
+f 26493 26494 26398
+f 26495 26400 26399
+f 26494 26495 26399
+f 26496 26401 26400
+f 26495 26496 26400
+f 26497 26402 26401
+f 26496 26497 26401
+f 26498 26403 26402
+f 26497 26498 26402
+f 26499 26404 26403
+f 26498 26499 26403
+f 26500 26405 26404
+f 26499 26500 26404
+f 26501 26406 26405
+f 26500 26501 26405
+f 26502 26407 26406
+f 26501 26502 26406
+f 26503 2239 26407
+f 26502 26503 26407
+f 22950 19070 15928
+f 19071 23052 22437
+f 22316 26504 6371
+f 6372 23026 26505
+f 26504 26506 23026
+f 23026 26506 12386
+f 26506 26507 12386
+f 12387 12386 26507
+f 26507 26508 12387
+f 26422 26509 12387
+f 26508 26510 26422
+f 12387 26508 26422
+f 26510 26511 26423
+f 26422 26510 26423
+f 26511 26512 26424
+f 26423 26511 26424
+f 26513 26425 26424
+f 26512 26513 26424
+f 26513 26514 26426
+f 26425 26513 26426
+f 26515 26427 26426
+f 26514 26515 26426
+f 26516 26428 26427
+f 26515 26516 26427
+f 26517 26429 26428
+f 26516 26517 26428
+f 26518 26430 26429
+f 26517 26518 26429
+f 26519 26431 26430
+f 26518 26519 26430
+f 26520 8991 26431
+f 26519 26520 26431
+f 26521 16891 8991
+f 26520 26521 8991
+f 16890 26522 26523
+f 26521 16889 16891
+f 26524 25812 25450
+f 26525 26526 26522
+f 26434 22219 22218
+f 25812 25451 25450
+f 26527 26435 26433
+f 26525 26527 26433
+f 26528 26436 26435
+f 26527 26528 26435
+f 26529 26437 26436
+f 26528 26529 26436
+f 26530 26438 26437
+f 26529 26530 26437
+f 26530 26531 26439
+f 26438 26530 26439
+f 26532 26440 26439
+f 26531 26532 26439
+f 26533 26441 26440
+f 26532 26533 26440
+f 26534 26442 26441
+f 26533 26534 26441
+f 26535 26443 26442
+f 26534 26535 26442
+f 18827 26444 26443
+f 26535 18827 26443
+f 18156 18155 26444
+f 18827 18156 26444
+f 9736 23384 9734
+f 17490 3144 20685
+f 12886 23642 24268
+f 23700 16498 24863
+f 17802 20263 20229
+f 24945 26536 26448
+f 26537 26447 26448
+f 26536 26537 26448
+f 26538 26449 26447
+f 26537 26538 26447
+f 26539 26450 26449
+f 26538 26539 26449
+f 26539 26540 26451
+f 26450 26539 26451
+f 26540 23158 26452
+f 26451 26540 26452
+f 21687 17778 21689
+f 20723 20687 24996
+f 9731 8043 8045
+f 24528 19173 2105
+f 16680 22044 22043
+f 1103 10301 16054
+f 19688 17848 4945
+f 3183 10648 369
+f 18990 18945 18988
+f 16846 15993 7236
+f 16680 16679 25060
+f 25060 26453 22044
+f 18154 18156 18406
+f 26541 26454 26453
+f 25060 26541 26453
+f 26455 26362 26454
+f 26541 26455 26454
+f 598 1113 9206
+f 16733 24896 22950
+f 26542 26459 26543
+f 5209 5660 2418
+f 26544 26461 26459
+f 26542 26544 26459
+f 26545 26462 26461
+f 26544 26545 26461
+f 26546 26463 26462
+f 26545 26546 26462
+f 26547 26464 26463
+f 26546 26547 26463
+f 26548 26465 26464
+f 26547 26548 26464
+f 26548 26549 26466
+f 26465 26548 26466
+f 26549 26550 26467
+f 26466 26549 26467
+f 26550 26551 26468
+f 26467 26550 26468
+f 26552 21573 21572
+f 26468 26551 21269
+f 24583 24581 24582
+f 4956 8121 4957
+f 16961 26553 17055
+f 24896 16733 16732
+f 17466 26469 26374
+f 26554 26470 26555
+f 26470 26554 26471
+f 26556 22036 26472
+f 26471 26556 26472
+f 22036 26557 26473
+f 26472 22036 26473
+f 26557 26558 26474
+f 26473 26557 26474
+f 26558 26559 26475
+f 26474 26558 26475
+f 26559 26560 26476
+f 26475 26559 26476
+f 26560 26561 26477
+f 26476 26560 26477
+f 26561 26562 26478
+f 26477 26561 26478
+f 26562 26563 26479
+f 26478 26562 26479
+f 26563 26564 26480
+f 26479 26563 26480
+f 26564 26565 26481
+f 26480 26564 26481
+f 26565 26566 26482
+f 26481 26565 26482
+f 26566 26567 26483
+f 26482 26566 26483
+f 26567 26568 26484
+f 26483 26567 26484
+f 26568 26569 26485
+f 26484 26568 26485
+f 26569 26570 26486
+f 26485 26569 26486
+f 26571 26487 26486
+f 26570 26571 26486
+f 26572 26488 26487
+f 26571 26572 26487
+f 26572 26573 26489
+f 26488 26572 26489
+f 26573 26574 26490
+f 26489 26573 26490
+f 26574 26575 26491
+f 26490 26574 26491
+f 26575 26576 26492
+f 26491 26575 26492
+f 26577 26493 26492
+f 26576 26577 26492
+f 26578 26494 26493
+f 26577 26578 26493
+f 26579 26495 26494
+f 26578 26579 26494
+f 26580 26496 26495
+f 26579 26580 26495
+f 26581 26497 26496
+f 26580 26581 26496
+f 26582 26498 26497
+f 26581 26582 26497
+f 26583 26499 26498
+f 26582 26583 26498
+f 26584 26500 26499
+f 26583 26584 26499
+f 26585 26501 26500
+f 26584 26585 26500
+f 26586 26502 26501
+f 26585 26586 26501
+f 26587 26503 26502
+f 26586 26587 26502
+f 26587 26588 22316
+f 26503 26587 22316
+f 26588 26589 26504
+f 22316 26588 26504
+f 26589 26590 26506
+f 26504 26589 26506
+f 26590 26591 26507
+f 26506 26590 26507
+f 26591 26592 26508
+f 26507 26591 26508
+f 26592 26593 26510
+f 26508 26592 26510
+f 26593 26594 26511
+f 26510 26593 26511
+f 26595 26512 26511
+f 26594 26595 26511
+f 26596 26513 26512
+f 26595 26596 26512
+f 26596 26597 26514
+f 26513 26596 26514
+f 26598 26515 26514
+f 26597 26598 26514
+f 26599 26516 26515
+f 26598 26599 26515
+f 26600 26517 26516
+f 26599 26600 26516
+f 26601 26518 26517
+f 26600 26601 26517
+f 26602 26519 26518
+f 26601 26602 26518
+f 26603 26520 26519
+f 26602 26603 26519
+f 26604 26521 26520
+f 26603 26604 26520
+f 26605 16889 26521
+f 26604 26605 26521
+f 26606 26522 16889
+f 26605 26606 16889
+f 3221 3220 1979
+f 26606 26607 26522
+f 26608 26527 26525
+f 26607 26608 26525
+f 26609 26528 26527
+f 26608 26609 26527
+f 26610 26529 26528
+f 26609 26610 26528
+f 26610 26611 26530
+f 26529 26610 26530
+f 26611 26612 26531
+f 26530 26611 26531
+f 26613 26532 26531
+f 26612 26613 26531
+f 26614 26533 26532
+f 26613 26614 26532
+f 26615 26534 26533
+f 26614 26615 26533
+f 26616 26535 26534
+f 26615 26616 26534
+f 18825 18827 26535
+f 26616 18825 26535
+f 1461 13908 13910
+f 18829 15202 18796
+f 1605 20468 1606
+f 15603 22112 16149
+f 20910 19166 20861
+f 10093 13771 12474
+f 26617 26536 26618
+f 20420 17489 25716
+f 26619 26537 26536
+f 26617 26619 26536
+f 26620 26538 26537
+f 26619 26620 26537
+f 26620 26621 26539
+f 26538 26620 26539
+f 26621 16139 26540
+f 26539 26621 26540
+f 885 2266 3405
+f 26540 16139 23158
+f 14093 2621 18562
+f 24528 17842 19173
+f 16331 2195 4890
+f 3008 17769 3605
+f 4889 16331 4890
+f 2809 16959 2810
+f 16421 10025 23643
+f 18902 13960 13962
+f 9655 4941 9656
+f 16681 25456 16679
+f 8936 19489 19488
+f 26622 26541 25060
+f 16679 26622 25060
+f 26623 26455 26541
+f 26622 26623 26541
+f 26624 26625 26455
+f 26623 26624 26455
+f 26626 26542 26625
+f 26624 26626 26625
+f 26627 26544 26542
+f 26626 26627 26542
+f 26628 26545 26544
+f 26627 26628 26544
+f 26629 26546 26545
+f 26628 26629 26545
+f 26630 26547 26546
+f 26629 26630 26546
+f 26631 26548 26547
+f 26630 26631 26547
+f 26631 26632 26549
+f 26548 26631 26549
+f 26632 26633 26550
+f 26549 26632 26550
+f 26633 26634 26551
+f 26550 26633 26551
+f 21573 26635 21574
+f 26551 26634 26552
+f 26636 16732 13376
+f 25232 16638 16640
+f 24732 23607 23239
+f 15274 12272 11200
+f 15275 15274 11200
+f 4395 24857 21658
+f 5545 22217 5546
+f 14409 26637 14410
+f 26637 26556 26471
+f 22035 26638 26557
+f 22036 22035 26557
+f 26638 26639 26558
+f 26557 26638 26558
+f 26639 26640 26559
+f 26558 26639 26559
+f 26640 26641 26560
+f 26559 26640 26560
+f 26641 26642 26561
+f 26560 26641 26561
+f 26642 26643 26562
+f 26561 26642 26562
+f 26643 26644 26563
+f 26562 26643 26563
+f 26644 26645 26564
+f 26563 26644 26564
+f 26645 26646 26565
+f 26564 26645 26565
+f 26646 26647 26566
+f 26565 26646 26566
+f 26647 26648 26567
+f 26566 26647 26567
+f 26648 26649 26568
+f 26567 26648 26568
+f 26649 26650 26569
+f 26568 26649 26569
+f 26650 26651 26570
+f 26569 26650 26570
+f 26652 26571 26570
+f 26651 26652 26570
+f 26653 26572 26571
+f 26652 26653 26571
+f 26654 26573 26572
+f 26653 26654 26572
+f 26654 26655 26574
+f 26573 26654 26574
+f 26655 26656 26575
+f 26574 26655 26575
+f 26656 26657 26576
+f 26575 26656 26576
+f 26658 26577 26576
+f 26657 26658 26576
+f 26659 26578 26577
+f 26658 26659 26577
+f 26660 26579 26578
+f 26659 26660 26578
+f 26661 26580 26579
+f 26660 26661 26579
+f 26662 26581 26580
+f 26661 26662 26580
+f 26663 26582 26581
+f 26662 26663 26581
+f 26664 26583 26582
+f 26663 26664 26582
+f 26665 26584 26583
+f 26664 26665 26583
+f 26666 26585 26584
+f 26665 26666 26584
+f 26667 26586 26585
+f 26666 26667 26585
+f 26667 26668 26587
+f 26586 26667 26587
+f 26668 26669 26588
+f 26587 26668 26588
+f 26669 26670 26589
+f 26588 26669 26589
+f 26670 26671 26590
+f 26589 26670 26590
+f 26671 26672 26591
+f 26590 26671 26591
+f 26672 26673 26592
+f 26591 26672 26592
+f 26673 26674 26593
+f 26592 26673 26593
+f 26674 26675 26594
+f 26593 26674 26594
+f 26676 26595 26594
+f 26675 26676 26594
+f 26677 26596 26595
+f 26676 26677 26595
+f 26677 26678 26597
+f 26596 26677 26597
+f 26679 26598 26597
+f 26678 26679 26597
+f 26680 26599 26598
+f 26679 26680 26598
+f 26681 26600 26599
+f 26680 26681 26599
+f 26682 26601 26600
+f 26681 26682 26600
+f 26683 26602 26601
+f 26682 26683 26601
+f 26684 26603 26602
+f 26683 26684 26602
+f 26685 26604 26603
+f 26684 26685 26603
+f 26686 26605 26604
+f 26685 26686 26604
+f 26687 26606 26605
+f 26686 26687 26605
+f 26688 26607 26606
+f 26687 26688 26606
+f 26689 26608 26607
+f 26688 26689 26607
+f 26690 26609 26608
+f 26689 26690 26608
+f 26691 26610 26609
+f 26690 26691 26609
+f 26691 26692 26611
+f 26610 26691 26611
+f 26693 26612 26611
+f 26692 26693 26611
+f 26694 26613 26612
+f 26693 26694 26612
+f 26695 26614 26613
+f 26694 26695 26613
+f 26696 26615 26614
+f 26695 26696 26614
+f 26697 26616 26615
+f 26696 26697 26615
+f 18829 18825 26616
+f 26697 18829 26616
+f 18796 15202 18828
+f 13771 2991 6537
+f 23731 15892 15891
+f 25370 26698 23764
+f 18839 4943 16857
+f 5668 223 884
+f 14236 20420 25716
+f 26536 24945 26618
+f 26699 26619 26617
+f 21311 26699 26617
+f 22923 26620 26619
+f 26699 22923 26619
+f 22923 16140 26621
+f 26620 22923 26621
+f 20050 19556 18945
+f 26621 16140 16139
+f 15603 16149 15601
+f 7320 16004 16006
+f 2104 24528 2105
+f 18774 23944 2103
+f 26133 26700 26131
+f 16858 4334 2188
+f 21383 6844 10952
+f 4774 24330 4775
+f 17789 15855 16053
+f 15584 19748 3768
+f 25456 22681 26622
+f 16679 25456 26622
+f 26701 26623 26622
+f 22681 26701 26622
+f 26702 26624 26623
+f 26701 26702 26623
+f 26703 26626 26624
+f 26702 26703 26624
+f 26704 26627 26626
+f 26703 26704 26626
+f 26705 26628 26627
+f 26704 26705 26627
+f 26705 26706 26629
+f 26628 26705 26629
+f 26706 26707 26630
+f 26629 26706 26630
+f 26707 26708 26631
+f 26630 26707 26631
+f 26709 26632 26631
+f 26708 26709 26631
+f 26710 26633 26632
+f 26709 26710 26632
+f 26710 26635 26634
+f 26633 26710 26634
+f 26711 5500 12543
+f 26634 26635 21573
+f 26356 22232 26360
+f 26340 22217 22219
+f 1697 3450 5619
+f 2495 1697 5619
+f 11632 20961 17230
+f 20961 17231 17230
+f 4816 4657 4976
+f 22947 22949 26712
+f 16379 16381 26638
+f 22035 16379 26638
+f 16381 26713 26639
+f 26638 16381 26639
+f 16672 26714 26713
+f 26639 26713 26640
+f 26715 26716 26641
+f 26640 26715 26641
+f 26716 26717 26642
+f 26641 26716 26642
+f 26717 26718 26643
+f 26642 26717 26643
+f 26718 26719 26644
+f 26643 26718 26644
+f 26719 26720 26645
+f 26644 26719 26645
+f 26720 26721 26646
+f 26645 26720 26646
+f 26721 26722 26647
+f 26646 26721 26647
+f 26722 26723 26648
+f 26647 26722 26648
+f 26723 26724 26649
+f 26648 26723 26649
+f 26724 26725 26650
+f 26649 26724 26650
+f 26725 26726 26651
+f 26650 26725 26651
+f 26727 26652 26651
+f 26726 26727 26651
+f 26728 26653 26652
+f 26727 26728 26652
+f 26729 26654 26653
+f 26728 26729 26653
+f 26729 26730 26655
+f 26654 26729 26655
+f 26730 26731 26656
+f 26655 26730 26656
+f 26731 26732 26657
+f 26656 26731 26657
+f 26733 26658 26657
+f 26732 26733 26657
+f 26734 26659 26658
+f 26733 26734 26658
+f 26735 26660 26659
+f 26734 26735 26659
+f 26736 26661 26660
+f 26735 26736 26660
+f 26737 26662 26661
+f 26736 26737 26661
+f 26738 26663 26662
+f 26737 26738 26662
+f 26739 26664 26663
+f 26738 26739 26663
+f 26740 26665 26664
+f 26739 26740 26664
+f 26741 26666 26665
+f 26740 26741 26665
+f 26742 26667 26666
+f 26741 26742 26666
+f 26742 26743 26668
+f 26667 26742 26668
+f 26743 26744 26669
+f 26668 26743 26669
+f 26744 26745 26670
+f 26669 26744 26670
+f 26745 26746 26671
+f 26670 26745 26671
+f 26746 26747 26672
+f 26671 26746 26672
+f 26747 26748 26673
+f 26672 26747 26673
+f 26748 26749 26674
+f 26673 26748 26674
+f 19743 26675 26674
+f 26749 19743 26674
+f 24754 26676 26675
+f 19743 24754 26675
+f 24753 26677 26676
+f 24754 24753 26676
+f 24753 18467 26678
+f 26677 24753 26678
+f 18531 26679 26678
+f 18467 18531 26678
+f 18530 26680 26679
+f 18531 18530 26679
+f 18495 26681 26680
+f 18530 18495 26680
+f 18495 14960 26682
+f 26681 18495 26682
+f 14960 18463 26683
+f 26682 14960 26683
+f 18462 26684 26683
+f 18463 18462 26683
+f 3340 26685 26684
+f 18462 3340 26684
+f 3339 26686 26685
+f 3340 3339 26685
+f 17039 26687 26686
+f 3339 17039 26686
+f 17041 26688 26687
+f 17039 17041 26687
+f 14964 26689 26688
+f 17041 14964 26688
+f 14963 26690 26689
+f 14964 14963 26689
+f 16123 26691 26690
+f 14963 16123 26690
+f 16123 17901 26692
+f 26691 16123 26692
+f 11072 26693 26692
+f 17901 11072 26692
+f 20580 26694 26693
+f 11072 20580 26693
+f 13324 26695 26694
+f 20580 13324 26694
+f 16029 26696 26695
+f 13324 16029 26695
+f 2360 26697 26696
+f 16029 2360 26696
+f 15202 18829 26697
+f 2360 15202 26697
+f 19748 19709 3768
+f 20464 20465 22400
+f 18564 23745 23746
+f 15852 21041 15853
+f 13401 17620 26032
+f 18774 14783 23944
+f 26750 5802 26751
+f 17131 26751 5802
+f 25848 26699 21311
+f 16266 25848 21311
+f 16139 23077 23159
+f 26699 25848 22923
+f 19438 14276 19729
+f 16351 17710 17949
+f 16829 17435 23525
+f 12885 15852 23642
+f 17788 7319 7666
+f 15691 16829 23525
+f 22016 16324 16546
+f 15510 23068 17209
+f 16655 16421 2189
+f 25456 22682 22681
+f 15853 17710 17291
+f 23609 19488 19487
+f 23944 2104 2103
+f 20366 6519 6521
+f 19202 18828 15202
+f 18244 26701 22681
+f 13526 1473 22464
+f 17071 26702 26701
+f 18244 17071 26701
+f 5753 26703 26702
+f 17071 5753 26702
+f 4789 26704 26703
+f 5753 4789 26703
+f 4789 4790 26705
+f 26704 4789 26705
+f 4790 4869 26706
+f 26705 4790 26706
+f 4869 8017 26707
+f 26706 4869 26707
+f 8017 8019 26708
+f 26707 8017 26708
+f 7137 26709 26708
+f 8019 7137 26708
+f 5499 26710 26709
+f 7137 5499 26709
+f 5499 5500 26635
+f 26710 5499 26635
+f 4435 12543 5500
+f 14949 14948 26752
+f 23129 26753 26754
+f 1699 15275 3451
+f 1699 3451 3450
+f 6138 9619 6139
+f 17231 6137 6139
+f 7317 17727 14820
+f 5666 16991 11026
+f 16380 16672 16381
+f 16379 22035 14408
+f 16672 26755 26714
+f 16381 16672 26713
+f 24558 16155 16154
+f 26756 14968 26757
+f 2264 10577 26716
+f 26640 26713 2265
+f 10577 10562 26717
+f 26716 10577 26717
+f 10562 10561 26718
+f 26717 10562 26718
+f 10561 15386 26719
+f 26718 10561 26719
+f 15386 16382 26720
+f 26719 15386 26720
+f 16382 16384 26721
+f 26720 16382 26721
+f 16384 16985 26722
+f 26721 16384 26722
+f 16985 13696 26723
+f 26722 16985 26723
+f 13696 13698 26724
+f 26723 13696 26724
+f 13698 16138 26725
+f 26724 13698 26725
+f 16138 16184 26726
+f 26725 16138 26726
+f 16703 26727 26726
+f 16184 16703 26726
+f 15906 26728 26727
+f 16703 15906 26727
+f 16565 26729 26728
+f 15906 16565 26728
+f 16565 16785 26730
+f 26729 16565 26730
+f 16785 16446 26731
+f 26730 16785 26731
+f 16446 16441 26732
+f 26731 16446 26732
+f 16586 26733 26732
+f 16441 16586 26732
+f 20262 26734 26733
+f 16586 20262 26733
+f 20228 26735 26734
+f 20262 20228 26734
+f 20227 26736 26735
+f 20228 20227 26735
+f 17564 26737 26736
+f 20227 17564 26736
+f 17493 26738 26737
+f 17564 17493 26737
+f 17492 26739 26738
+f 17493 17492 26738
+f 398 26740 26739
+f 17492 398 26739
+f 397 26741 26740
+f 398 397 26740
+f 17446 26742 26741
+f 397 17446 26741
+f 17446 16701 26743
+f 26742 17446 26743
+f 16701 16702 26744
+f 26743 16701 26744
+f 16702 16525 26745
+f 26744 16702 26745
+f 16525 16527 26746
+f 26745 16525 26746
+f 16527 16675 26747
+f 26746 16527 26747
+f 16675 16190 26748
+f 26747 16675 26748
+f 16190 16754 26749
+f 26748 16190 26749
+f 19741 19743 26749
+f 16754 19741 26749
+f 19742 24754 19743
+f 24332 26265 24389
+f 16090 23988 26758
+f 24775 18441 15821
+f 23776 17401 23893
+f 26759 23776 23893
+f 26760 23891 23890
+f 26761 26760 23890
+f 19910 15118 17444
+f 26266 26762 24390
+f 17582 25206 25815
+f 15022 15021 26763
+f 20652 26764 19911
+f 26765 25158 26075
+f 26766 25655 26764
+f 19910 19912 20618
+f 23898 26767 26768
+f 26769 26770 23626
+f 25174 26771 26772
+f 25200 25174 26772
+f 25157 25209 26773
+f 24538 25240 25239
+f 17582 25815 25505
+f 24665 24664 24688
+f 23315 26072 8792
+f 25878 26774 26088
+f 17307 17309 25856
+f 14213 17631 24588
+f 19734 17214 22410
+f 18055 15003 15004
+f 13332 11221 6746
+f 17939 17368 18014
+f 14391 10804 13309
+f 18015 17940 17939
+f 24661 26775 26776
+f 12383 16933 16134
+f 18603 20579 20253
+f 24280 24282 25740
+f 15317 20501 15315
+f 20302 20301 20338
+f 23384 17980 23382
+f 25701 26777 1837
+f 17991 17499 17941
+f 15604 19733 15605
+f 26778 26779 23714
+f 23282 25710 23283
+f 23095 16606 16612
+f 16048 25855 26780
+f 25410 25411 25331
+f 25640 26781 23713
+f 26243 11150 26782
+f 23352 16695 24170
+f 16557 24070 26783
+f 23352 24170 16935
+f 16536 17462 26784
+f 24975 26046 24964
+f 26785 25390 25392
+f 26786 24794 25161
+f 25106 26786 25161
+f 26787 26788 25156
+f 25928 17181 25929
+f 24389 26266 24390
+f 26789 24391 24390
+f 26790 26791 23100
+f 26762 26789 24390
+f 17533 2967 17288
+f 6797 6799 11028
+f 26789 26792 24438
+f 7039 9771 14051
+f 26793 26794 26795
+f 5494 5325 10524
+f 7543 7542 12097
+f 16697 18967 16698
+f 23274 25471 25470
+f 22192 2765 25249
+f 24070 23352 23351
+f 26796 26797 26139
+f 24281 26798 24282
+f 26799 26800 26801
+f 18986 19151 20581
+f 23965 23960 25102
+f 11149 26802 25349
+f 15546 15545 17264
+f 14452 15817 26803
+f 26804 25558 16591
+f 26805 26806 26807
+f 16651 26803 17366
+f 24391 26789 24438
+f 26806 26808 24004
+f 14987 20259 14988
+f 26792 13480 24456
+f 23787 26809 26810
+f 7053 1809 9389
+f 25017 25553 25212
+f 26811 26812 26813
+f 26814 26805 26807
+f 21249 21248 23763
+f 26807 26806 24004
+f 17444 17445 20652
+f 16318 16317 15761
+f 17445 25348 26766
+f 26044 25243 24693
+f 25348 26815 26766
+f 25561 26759 26760
+f 26816 26761 26815
+f 25348 26816 26815
+f 25562 25561 26760
+f 25562 26760 26761
+f 26816 25562 26761
+f 26817 23776 26759
+f 24438 26792 24456
+f 25020 25219 23719
+f 26818 26819 17733
+f 26820 26821 25646
+f 24958 26822 25339
+f 20550 16668 26823
+f 26824 26035 25347
+f 19151 15146 19599
+f 25561 26817 26759
+f 9201 26224 26226
+f 21719 24378 9796
+f 25021 24457 26825
+f 17601 26826 20578
+f 19150 15146 19151
+f 5311 11161 3652
+f 25016 25553 25017
+f 26827 3409 3411
+f 15723 16307 15724
+f 24393 17823 18935
+f 22921 24445 24895
+f 23366 24340 24116
+f 26321 26828 23846
+f 25410 25409 23230
+f 17371 17847 17731
+f 26829 25917 26830
+f 17525 17524 20298
+f 25917 25085 26830
+f 26831 26234 26832
+f 24006 24005 26833
+f 25247 25681 25680
+f 24282 26798 25742
+f 26834 26835 25346
+f 23279 23306 23985
+f 26836 26837 26838
+f 26839 17177 17176
+f 23884 26840 24655
+f 26838 26839 17176
+f 26768 26767 26841
+f 17178 23884 24655
+f 17442 25347 25277
+f 26760 26759 23891
+f 24656 26768 26841
+f 6787 21078 26842
+f 26843 25797 26844
+f 25697 25699 24509
+f 25585 25648 25586
+f 25956 3336 25397
+f 24685 26845 24686
+f 19656 25309 19144
+f 23952 26846 331
+f 26847 26824 17442
+f 25796 26848 26844
+f 25347 25346 25277
+f 26849 26824 26850
+f 236 656 234
+f 26824 25347 17442
+f 11012 14181 11013
+f 26851 26852 25960
+f 2396 13534 26263
+f 6241 6240 23346
+f 14506 14224 19150
+f 22921 24978 22747
+f 4796 6741 1579
+f 16757 16756 22277
+f 24876 24878 26853
+f 3758 3730 3729
+f 26767 26849 26841
+f 26824 26847 26850
+f 26854 26855 26856
+f 2489 16753 16752
+f 26828 26857 23846
+f 26858 26033 23896
+f 23320 24963 16106
+f 26859 26860 26861
+f 23775 26862 16824
+f 25821 26859 26861
+f 2394 25021 26825
+f 26863 18614 25359
+f 11150 11149 25350
+f 3758 3729 9449
+f 24555 5932 24479
+f 9384 26864 15366
+f 25985 8140 16911
+f 24825 26865 18092
+f 25208 25207 25925
+f 17177 23884 17178
+f 26866 22831 24213
+f 26834 26867 23907
+f 26868 26869 26870
+f 26138 26871 26870
+f 24669 26872 26873
+f 25638 26874 26875
+f 26052 25093 25094
+f 25084 26876 26830
+f 9272 9274 26877
+f 25350 25141 20755
+f 16819 26878 16820
+f 24456 13480 14819
+f 26865 26879 18015
+f 18092 26865 18015
+f 26879 26880 17940
+f 4015 5934 10565
+f 18015 26879 17940
+f 16612 16608 16613
+f 25212 20022 25090
+f 17309 24545 22797
+f 21925 21927 131
+f 17028 26881 16548
+f 9265 11469 23568
+f 25870 26882 24440
+f 26883 26884 26885
+f 25686 26886 26887
+f 23347 7443 7442
+f 22630 26888 22628
+f 26880 22630 17940
+f 25737 25493 25495
+f 26777 25603 1837
+f 23846 24710 23847
+f 23894 17403 26889
+f 23883 25830 23884
+f 23756 23758 17826
+f 5780 2399 3221
+f 11150 25350 26782
+f 26860 26859 25610
+f 26890 25285 25284
+f 26891 26890 26859
+f 26892 26891 26859
+f 25160 26863 25359
+f 25095 25160 25359
+f 26893 26894 26228
+f 26895 26896 26897
+f 23814 23813 25487
+f 24167 16611 16613
+f 9202 8601 9487
+f 25362 15997 25312
+f 26898 26899 16950
+f 16952 17192 26900
+f 17696 22005 15732
+f 26901 26227 26229
+f 26902 26903 26904
+f 24655 26840 24656
+f 26759 23893 23891
+f 26905 26906 26907
+f 26908 26909 26910
+f 26911 26836 26912
+f 25636 330 25637
+f 26913 26914 26787
+f 23315 24459 26072
+f 21658 21657 24855
+f 17805 13850 17795
+f 26915 16826 25087
+f 25759 25250 25249
+f 26916 26855 26854
+f 23764 26698 21249
+f 26874 24021 23816
+f 26917 26918 16107
+f 26509 26422 26421
+f 9575 25608 25681
+f 9575 24508 25608
+f 24509 26416 26919
+f 25572 26920 26801
+f 26234 23956 26921
+f 20473 20472 12648
+f 26922 24539 25239
+f 9194 8141 8143
+f 17760 12099 12098
+f 2762 3314 7442
+f 2763 2762 7442
+f 21085 23588 25368
+f 3313 2762 2637
+f 26075 25158 26773
+f 24510 24509 26919
+f 26923 26924 26893
+f 11148 26925 11149
+f 26919 26416 26926
+f 26927 24109 26902
+f 23705 26142 26143
+f 26416 26417 26926
+f 17825 23756 17826
+f 25158 25157 26773
+f 25871 24347 23255
+f 13851 16469 18213
+f 25610 26890 25284
+f 25412 23757 25199
+f 25143 26928 26929
+f 5077 16343 5078
+f 26930 26931 25604
+f 26932 25912 26933
+f 26886 26932 26933
+f 25286 26934 25686
+f 26935 26936 26937
+f 26918 15948 26938
+f 26839 25038 17177
+f 20297 20298 25557
+f 17795 13851 18213
+f 15821 15820 24775
+f 26856 25811 25813
+f 25637 24437 26925
+f 26796 26939 26837
+f 26940 26941 25153
+f 10092 5812 22657
+f 17379 16557 26783
+f 15653 26942 15698
+f 23283 8793 8795
+f 22722 26943 24109
+f 25092 26944 16205
+f 26945 24881 26946
+f 15970 18169 11224
+f 22630 17992 17940
+f 26947 15613 26948
+f 8216 455 454
+f 21246 21247 17685
+f 1338 15085 3922
+f 25794 26949 26867
+f 17346 17348 25703
+f 26909 26950 26891
+f 25831 2940 17813
+f 2638 2763 7443
+f 17932 26951 24542
+f 25395 26952 26953
+f 18045 20297 26804
+f 20298 26954 26955
+f 26808 26956 24005
+f 9499 1176 2123
+f 26957 26958 26959
+f 2638 2637 2763
+f 26543 26625 26542
+f 26960 26961 24702
+f 16278 16804 16803
+f 17760 14997 2597
+f 17604 15306 15305
+f 2666 2665 26962
+f 5076 5078 16934
+f 8838 12170 8837
+f 19655 17311 19631
+f 24004 26808 24005
+f 20450 19038 11569
+f 26963 23952 25636
+f 6473 13963 16722
+f 1992 18446 18557
+f 26964 26965 26224
+f 26966 26967 25806
+f 26128 25159 25095
+f 25270 23273 23528
+f 23892 23895 26357
+f 23894 26889 26049
+f 14884 26817 25561
+f 14885 14884 25561
+f 26244 26857 26828
+f 17180 26244 26828
+f 26968 26967 26966
+f 26857 26244 24393
+f 17189 17345 25142
+f 15956 15982 15957
+f 12974 26969 26970
+f 23959 14631 20920
+f 26971 26969 26972
+f 26329 26971 26972
+f 26223 26973 26039
+f 25660 25662 26146
+f 16748 17803 17802
+f 7367 7366 17830
+f 24965 24470 24966
+f 26974 26975 26976
+f 25650 26897 26977
+f 25085 25084 26830
+f 26836 26838 26912
+f 24471 26978 26979
+f 25170 26242 17581
+f 25152 26980 26981
+f 26982 24006 24065
+f 26543 26459 26460
+f 26980 26983 26981
+f 26936 26230 26984
+f 7475 16591 20460
+f 26985 25983 25982
+f 26986 26038 26987
+f 23427 18045 26804
+f 26988 26989 25105
+f 26990 16861 24590
+f 10980 26991 10981
+f 26992 25755 25398
+f 26993 26971 26329
+f 26039 26993 26329
+f 26817 23819 23776
+f 23819 23777 23776
+f 23819 25354 26994
+f 23777 23819 26994
+f 26874 23816 23815
+f 26995 23364 26996
+f 25207 26036 25925
+f 26825 24457 24459
+f 25816 25206 25208
+f 17851 2601 19764
+f 24827 24765 24766
+f 18062 26997 18063
+f 24808 18183 18182
+f 18268 16098 24658
+f 26878 26862 23775
+f 25153 26941 25573
+f 1663 23774 26077
+f 26998 20549 20550
+f 26999 5948 27000
+f 27001 25758 23908
+f 25709 2591 27002
+f 26050 19706 19705
+f 27003 24054 24056
+f 25807 26892 25821
+f 25162 26968 27004
+f 26892 26859 25821
+f 27005 27006 26934
+f 27007 27008 27009
+f 26980 26807 26983
+f 25706 27010 25938
+f 25451 27011 25930
+f 17264 25692 27012
+f 24798 26242 26048
+f 24021 24665 23816
+f 26974 26976 27013
+f 11884 11883 21609
+f 17223 17222 20153
+f 23720 23722 27014
+f 27015 17886 25165
+f 24634 18268 24658
+f 27016 26923 26227
+f 16175 7001 7000
+f 17464 27017 26052
+f 24687 23726 27018
+f 26819 27019 27020
+f 26832 26234 26921
+f 238 26055 16691
+f 22785 26219 11226
+f 12653 27021 27022
+f 23832 23723 23725
+f 26833 27023 27024
+f 26983 24006 26982
+f 21836 26229 23760
+f 26228 23353 23761
+f 16691 26056 27025
+f 26229 26228 23761
+f 27026 27027 27028
+f 17275 17277 27029
+f 10458 14997 12098
+f 27030 2497 2499
+f 27016 26227 26901
+f 25928 27031 17181
+f 25095 25359 25360
+f 26800 26067 27032
+f 24402 24479 27033
+f 26837 26939 26839
+f 27034 23889 16415
+f 24020 27035 24664
+f 24021 24020 24665
+f 27036 27037 24054
+f 16731 25709 27002
+f 17366 26803 27038
+f 16108 16107 27039
+f 27040 27041 26957
+f 21225 27042 19705
+f 12099 5058 10140
+f 26237 26236 14883
+f 17823 17822 27043
+f 26964 27044 26965
+f 27045 16970 27046
+f 24664 23925 24687
+f 25274 23444 23446
+f 26765 16971 16970
+f 26828 26321 25929
+f 27047 25246 25680
+f 26927 26904 1749
+f 9087 11413 17196
+f 10139 5059 12099
+f 22943 23753 27048
+f 16305 17141 16451
+f 13982 13347 15020
+f 18125 17838 25866
+f 26924 27049 27050
+f 26923 26893 26227
+f 25866 27016 26901
+f 23366 24116 23812
+f 27002 2591 16449
+f 15729 27051 25582
+f 26802 25585 17188
+f 27052 25610 25611
+f 11543 26051 16417
+f 27053 26980 23717
+f 23716 26236 23717
+f 26981 26983 26982
+f 24006 26833 24065
+f 26894 27054 23353
+f 26228 26894 23353
+f 14721 451 158
+f 16377 27055 16372
+f 17804 25864 20338
+f 24226 24352 24223
+f 6925 27056 6923
+f 27057 27058 27059
+f 27060 16843 15722
+f 27038 15818 22281
+f 15730 25822 25209
+f 19409 25533 27061
+f 17342 25170 25818
+f 23761 23355 23762
+f 24824 27062 24825
+f 24838 24824 3729
+f 27062 27063 26865
+f 24825 27062 26865
+f 27063 27064 26879
+f 26865 27063 26879
+f 27065 26880 26879
+f 27064 27065 26879
+f 26318 27066 25398
+f 27067 27068 25357
+f 24055 27069 27070
+f 27071 27069 24055
+f 16651 14453 14452
+f 16451 17141 8960
+f 10311 27072 27027
+f 25037 27073 27074
+f 27023 24007 24009
+f 26236 23716 14883
+f 4389 15620 27075
+f 24710 24393 18935
+f 27076 24659 21078
+f 25661 25262 17805
+f 26978 27000 26979
+f 15546 17264 27077
+f 25178 26047 21342
+f 25734 24613 25614
+f 27065 26888 26880
+f 22720 5264 5263
+f 5265 5264 24877
+f 27078 25309 19656
+f 26950 27079 25285
+f 15730 25807 25822
+f 25648 27080 25586
+f 25819 27081 17343
+f 25171 17581 17583
+f 27082 19014 18963
+f 16036 23811 16037
+f 22943 27048 22944
+f 24437 25585 26802
+f 15783 24978 22921
+f 25755 25336 25399
+f 26980 25152 23717
+f 26236 27053 23717
+f 25200 26772 27083
+f 26772 27084 27085
+f 26237 14883 27054
+f 26894 26237 27054
+f 27086 6255 27087
+f 17263 5637 17543
+f 6379 24991 6380
+f 24467 27088 25393
+f 21457 21459 22471
+f 25016 23854 25553
+f 27089 26940 25695
+f 641 18119 6379
+f 27037 27071 24054
+f 24054 27071 24055
+f 25209 25445 26773
+f 27090 25314 27091
+f 27092 27093 25808
+f 16103 25640 27094
+f 26996 23812 23820
+f 27049 26805 26235
+f 27095 26996 23820
+f 27096 24659 27076
+f 26848 27097 26844
+f 16766 17765 27098
+f 27070 27096 27076
+f 27099 25992 23955
+f 26803 15818 27038
+f 27085 26949 25794
+f 27100 25649 25651
+f 25607 25928 1508
+f 24008 26975 26974
+f 25690 27101 16823
+f 26954 26957 26959
+f 23888 27015 25165
+f 6954 27102 6961
+f 23353 27054 23354
+f 26140 26836 26911
+f 24065 26833 27024
+f 17196 15924 23753
+f 23571 20122 27103
+f 21248 18938 18937
+f 24513 27104 27105
+f 27106 27107 27108
+f 27108 27107 27036
+f 27060 27106 27108
+f 27107 27037 27036
+f 24009 26974 25173
+f 18208 7952 18891
+f 18113 5493 5602
+f 26976 26818 27109
+f 8476 9087 17187
+f 26219 18061 17801
+f 24622 24624 27110
+f 27083 23896 27111
+f 25795 25345 25347
+f 27112 24622 27110
+f 25277 27113 27114
+f 26035 25795 25347
+f 25483 25917 26829
+f 20460 27115 27116
+f 14844 26795 27117
+f 27118 27119 25826
+f 25812 27120 25451
+f 10311 27121 27072
+f 27122 27123 25690
+f 27101 27124 16823
+f 27017 25093 26052
+f 27069 27096 27070
+f 9201 26226 26827
+f 27115 27125 27116
+f 24687 27018 24688
+f 24540 24339 24279
+f 18004 12381 18005
+f 23333 23358 24617
+f 26409 26926 26412
+f 25497 27088 24467
+f 24283 26057 24799
+f 3336 25317 25397
+f 24659 17354 21078
+f 23307 23099 5548
+f 27126 25388 23834
+f 27127 27016 25866
+f 15395 27128 16842
+f 4471 25959 23965
+f 25574 27129 27130
+f 8293 8292 19782
+f 27041 27131 26958
+f 25211 23333 24617
+f 27132 16110 16112
+f 17524 25358 26954
+f 6887 25478 5163
+f 26357 27133 27041
+f 17665 24561 27134
+f 17627 17626 26785
+f 17626 25390 26785
+f 26925 24437 26802
+f 27135 26905 26907
+f 21078 17354 1622
+f 25856 17356 17355
+f 24461 24460 26054
+f 25919 26040 17799
+f 26138 26140 26871
+f 26782 25350 20755
+f 17940 17991 17941
+f 24995 24884 24932
+f 25984 27136 26993
+f 25063 27137 13203
+f 27138 26240 26231
+f 26241 25940 26985
+f 27139 24962 27138
+f 26240 26241 26231
+f 27140 24960 27139
+f 24962 26240 27138
+f 27100 25651 27125
+f 27141 8960 27142
+f 25209 25822 25445
+f 2394 26825 2395
+f 27143 6101 14623
+f 25279 23329 25211
+f 23962 23833 15665
+f 25874 16841 27033
+f 1335 18551 1336
+f 26984 26230 27144
+f 25827 25826 27145
+f 26951 27146 24542
+f 4342 8305 4343
+f 26128 25095 9273
+f 27147 27148 25234
+f 25219 16616 23719
+f 21248 26790 18938
+f 27149 16766 27150
+f 27098 25689 27151
+f 26125 26924 26923
+f 25865 27127 25866
+f 23960 23961 25103
+f 26858 27085 26033
+f 25044 27152 23094
+f 27046 16970 27153
+f 23713 26778 23714
+f 5265 24877 24876
+f 25314 16989 27091
+f 26798 27154 25742
+f 17130 27057 27059
+f 24513 24512 27104
+f 26956 27155 27156
+f 23329 23333 25211
+f 27155 27157 24007
+f 27158 26895 25650
+f 27159 16417 16842
+f 27123 27101 25690
+f 22371 13819 4967
+f 25354 23818 27160
+f 11389 3812 12932
+f 23948 23805 23807
+f 25864 17838 20338
+f 14897 25536 25143
+f 16698 19014 23660
+f 27161 23767 23383
+f 27094 23767 27161
+f 26231 26241 26985
+f 25940 25829 25983
+f 26799 27162 27163
+f 27164 26799 27163
+f 27162 26799 27165
+f 26799 26801 27165
+f 27165 26801 27166
+f 26801 26920 27166
+f 27167 27026 27168
+f 27169 27170 27166
+f 25310 23349 23348
+f 25309 23348 19144
+f 26833 27156 27023
+f 18694 25308 8398
+f 24005 26956 27156
+f 27157 27171 24008
+f 27156 27155 24007
+f 27171 27172 26975
+f 24007 27157 24008
+f 27173 27174 26223
+f 24008 27171 26975
+f 27175 27144 27173
+f 26973 26993 26039
+f 26905 26870 26906
+f 27176 26908 26906
+f 22921 22747 24445
+f 27177 17289 27167
+f 27177 27167 27178
+f 27179 27177 27178
+f 27171 25450 27172
+f 27180 26125 26923
+f 25200 27083 25201
+f 26835 26834 27181
+f 25388 25320 23834
+f 25732 27182 25733
+f 26222 26038 26986
+f 27183 26222 26986
+f 26870 26905 27135
+f 25358 26957 26954
+f 25354 27160 27073
+f 27174 26973 26223
+f 26994 25354 27073
+f 27160 26130 27184
+f 27073 27160 27184
+f 26130 17826 27118
+f 27184 26130 27118
+f 26847 19369 23779
+f 26766 26815 25655
+f 27185 26932 27006
+f 16491 16493 18842
+f 26772 26858 27083
+f 25689 25691 27186
+f 23907 23909 27187
+f 20156 26841 23779
+f 27188 27094 27161
+f 23767 23715 23383
+f 16747 23571 27189
+f 23570 27190 27191
+f 27192 26793 26795
+f 16747 27189 16748
+f 23571 27191 27189
+f 26431 8990 19984
+f 25205 26040 26146
+f 25690 16823 25691
+f 26925 26802 11149
+f 27125 27193 27044
+f 11148 27194 27195
+f 27196 24439 8787
+f 20259 25270 20260
+f 27044 26964 9203
+f 27197 27198 24015
+f 24109 25637 26902
+f 24109 26927 1748
+f 26959 26958 27158
+f 23758 27119 27118
+f 14352 264 27089
+f 25203 20051 25823
+f 25084 16110 27132
+f 17284 23316 25244
+f 26953 26952 27199
+f 26952 23284 27199
+f 15824 20813 12829
+f 25638 24066 26874
+f 26041 17682 14036
+f 26911 26912 27200
+f 17760 27201 12099
+f 15724 27134 15722
+f 27201 27202 10139
+f 12099 27201 10139
+f 27202 27203 24838
+f 10139 27202 24838
+f 27203 27204 24824
+f 24838 27203 24824
+f 27204 27205 27062
+f 24824 27204 27062
+f 27205 27206 27063
+f 27062 27205 27063
+f 11089 15146 19150
+f 27050 26235 26237
+f 26869 26868 27207
+f 27142 8960 27208
+f 23571 23570 27191
+f 27164 27163 27190
+f 25829 27094 27188
+f 25452 25931 27209
+f 24657 24656 20156
+f 20682 25090 20683
+f 27210 16764 27149
+f 26929 23920 23808
+f 27121 27141 27072
+f 23825 25879 23826
+f 27131 27207 27051
+f 26870 26871 26906
+f 27211 27064 27063
+f 27206 27211 27063
+f 27212 27065 27064
+f 27211 27212 27064
+f 27213 26888 27065
+f 27212 27213 27065
+f 25637 330 24437
+f 26958 27131 26913
+f 25350 25349 25141
+f 24511 25145 17406
+f 23095 16612 16611
+f 27161 23383 26970
+f 27214 25872 17569
+f 27151 25689 27186
+f 27150 27098 27151
+f 17312 19145 12652
+f 25806 27092 25808
+f 26912 26838 25526
+f 23889 23888 25165
+f 6293 6354 21167
+f 23283 8795 27199
+f 8556 8555 8400
+f 5932 24555 5933
+f 24766 24698 24695
+f 23571 16747 20122
+f 17130 27059 17131
+f 25089 25740 26320
+f 25641 27215 24011
+f 14486 17283 17282
+f 24437 332 25585
+f 26040 27216 26146
+f 27217 27218 27219
+f 25361 18203 25362
+f 25147 25043 24690
+f 25826 27220 27145
+f 27221 17389 27222
+f 25340 25341 27223
+f 27224 27225 26866
+f 26035 26824 26849
+f 18981 17618 27226
+f 27111 23896 23898
+f 16668 27227 25160
+f 25189 20793 20792
+f 27228 18614 26863
+f 27044 27193 26965
+f 17187 17186 23759
+f 27229 17187 23759
+f 26145 17706 27055
+f 22712 23102 23101
+f 26846 26820 331
+f 26849 26850 26841
+f 25965 15711 22110
+f 25166 25202 25688
+f 26815 27067 25655
+f 27176 26911 27230
+f 26840 26768 24656
+f 26908 27176 27230
+f 25038 23883 17177
+f 26927 1749 1748
+f 26871 27176 26906
+f 27231 27070 27232
+f 23763 21248 18937
+f 27233 23265 24927
+f 24699 24698 24766
+f 25029 17282 25030
+f 27174 25982 26973
+f 26924 27050 26893
+f 23965 25959 23960
+f 26926 17451 26412
+f 25615 24797 24796
+f 26919 26926 26409
+f 17389 25711 25340
+f 27234 27195 27235
+f 27236 26951 17932
+f 27158 26913 26895
+f 23383 23715 3042
+f 25983 25829 27188
+f 27180 26923 27016
+f 27127 27180 27016
+f 27237 27028 27238
+f 16766 27098 27150
+f 26973 25984 26993
+f 23339 25512 22151
+f 27207 26868 27051
+f 26868 27135 27051
+f 27131 26914 26913
+f 26868 26870 27135
+f 27239 23261 27240
+f 26914 27131 27051
+f 17308 24545 17309
+f 26769 23626 27114
+f 25855 16048 17307
+f 17360 27241 26411
+f 27242 27243 27244
+f 27245 25872 25874
+f 25984 27188 27136
+f 27246 25275 25024
+f 6922 6475 6474
+f 2967 27247 17288
+f 332 25648 25585
+f 27187 23909 2767
+f 27027 25464 27028
+f 27248 24801 27249
+f 26140 27176 26871
+f 25172 24009 25173
+f 23708 23986 25338
+f 27134 27250 27106
+f 13401 26032 18497
+f 13565 19423 10987
+f 14623 6101 13816
+f 24961 27246 25024
+f 27148 24694 25235
+f 18795 27251 27252
+f 25876 26853 27253
+f 14898 23953 23273
+f 27254 27058 24213
+f 26853 24878 27253
+f 25586 27080 17130
+f 23750 23752 24163
+f 25608 25609 25684
+f 27255 24876 26853
+f 2482 23304 25363
+f 26925 11148 26903
+f 14280 8919 15153
+f 27256 24147 19493
+f 27257 27258 24614
+f 16106 26917 16107
+f 18441 24886 24776
+f 17567 27259 15821
+f 19599 20581 19151
+f 19381 19727 25332
+f 25877 17386 27260
+f 17829 7367 17830
+f 24962 25024 26240
+f 16417 26051 16842
+f 17181 26828 25929
+f 19037 7446 12166
+f 20808 8716 3986
+f 7446 18694 12166
+f 25201 27111 27220
+f 2942 12165 2940
+f 13933 27261 16258
+f 17533 27262 27263
+f 25317 15679 25397
+f 25173 27013 26771
+f 27172 27209 27264
+f 26893 27050 26894
+f 26460 26363 26364
+f 27209 27265 27266
+f 26975 27172 27264
+f 27267 26984 27175
+f 27264 27209 27266
+f 26937 26984 27267
+f 27144 27174 27173
+f 25511 26937 27267
+f 26984 27144 27175
+f 27083 26858 23896
+f 24467 25393 27268
+f 27120 27011 25451
+f 6961 27102 16627
+f 23908 25758 25759
+f 22868 22244 2316
+f 18842 25029 25028
+f 26224 27046 27153
+f 25495 27049 26924
+f 26125 25495 26924
+f 27178 27167 27168
+f 25466 25642 27269
+f 26904 26903 17265
+f 24543 22872 16865
+f 27270 27271 27272
+f 25879 25956 25449
+f 25426 25371 22829
+f 26821 27273 25647
+f 27136 26970 26971
+f 331 26820 25646
+f 27259 25872 27245
+f 27274 26138 26870
+f 15732 22005 15215
+f 25735 25737 26124
+f 1542 15043 6392
+f 25049 1542 6392
+f 25424 25351 25353
+f 26906 26908 26910
+f 27096 26325 24659
+f 23707 23985 23708
+f 16823 27124 16821
+f 17387 17389 27221
+f 24056 27231 27101
+f 27275 27003 17764
+f 27003 24056 27123
+f 17763 27275 17764
+f 8958 15722 16843
+f 27250 27276 27107
+f 24459 24458 23293
+f 26910 26909 26891
+f 25248 25247 25680
+f 24468 24467 27268
+f 25412 27277 27119
+f 17826 23758 27118
+f 23758 25412 27119
+f 25199 25201 27277
+f 20422 15394 11542
+f 16937 27278 27279
+f 3442 11321 528
+f 9736 9735 17979
+f 7565 8144 6888
+f 7443 15016 2638
+f 15997 18204 15998
+f 17189 17129 17345
+f 17308 16048 25563
+f 26217 27280 15982
+f 19911 26764 18044
+f 27039 25832 25175
+f 15982 27280 26988
+f 2966 11268 12651
+f 27281 27282 25047
+f 21413 24329 25469
+f 27283 2597 18591
+f 26875 26874 23815
+f 18015 18014 18092
+f 5638 5603 15441
+f 27032 25572 26801
+f 19331 19408 19407
+f 27261 13933 13934
+f 16730 17494 25709
+f 23570 27164 27190
+f 27234 27235 17180
+f 20755 25142 20756
+f 26943 25636 24109
+f 27284 27285 27286
+f 27106 27250 27107
+f 5682 17829 17831
+f 17188 25586 17129
+f 27283 27287 17760
+f 25563 27288 5113
+f 27287 27289 27201
+f 17760 27287 27201
+f 27084 27007 27009
+f 27289 27290 27202
+f 27201 27289 27202
+f 26804 20297 25558
+f 27290 27291 27203
+f 27202 27290 27203
+f 27292 27204 27203
+f 27291 27292 27203
+f 27031 17266 17179
+f 27055 17706 16372
+f 27293 27294 27069
+f 20459 20460 27116
+f 27019 26935 27020
+f 1373 18979 1334
+f 16616 16735 16734
+f 27295 27296 25480
+f 25813 26524 27155
+f 26524 25450 27171
+f 27026 27028 27237
+f 27168 27026 27237
+f 27238 25466 27269
+f 27028 25466 27238
+f 27297 26239 27210
+f 25642 26239 27297
+f 27269 25642 27297
+f 16764 16766 27149
+f 27298 27299 27179
+f 26239 16764 27210
+f 26926 26417 17451
+f 27300 27299 27298
+f 27194 11150 26243
+f 26234 23954 23956
+f 331 25646 332
+f 26908 27230 27301
+f 14970 27302 1540
+f 26909 27301 27079
+f 17213 16264 20537
+f 2597 14997 2577
+f 26914 27051 26788
+f 16668 16667 27227
+f 26929 23918 23920
+f 27051 27135 25582
+f 23569 5782 11039
+f 6210 18113 5601
+f 16644 6475 6922
+f 26067 26800 27303
+f 25201 27083 27111
+f 25391 27304 27305
+f 27306 27205 27204
+f 27292 27306 27204
+f 27307 27206 27205
+f 23718 23819 26817
+f 6588 3926 3570
+f 23897 26035 26849
+f 7330 7329 14696
+f 27308 16734 27309
+f 15847 24345 27310
+f 27311 27312 17625
+f 25656 23351 25503
+f 27313 15847 27310
+f 25499 25498 27314
+f 27315 27248 3341
+f 27316 27317 26989
+f 25581 27318 27319
+f 1334 19549 1335
+f 26989 27317 26786
+f 6536 15712 27320
+f 27044 27321 27116
+f 27306 27307 27205
+f 3409 26226 27322
+f 27323 27211 27206
+f 25636 23952 330
+f 20021 27324 24280
+f 27325 24038 25169
+f 23762 23355 25348
+f 23355 26816 25348
+f 26914 26788 26787
+f 25526 17176 23257
+f 26985 25940 25983
+f 27276 27326 27037
+f 24713 23720 27014
+f 7952 18208 18207
+f 27107 27276 27037
+f 27307 27323 27206
+f 20652 26766 26764
+f 27327 27212 27211
+f 27323 27327 27211
+f 8142 27328 27329
+f 27330 27213 27212
+f 27327 27330 27212
+f 27331 25811 26856
+f 27219 27330 27332
+f 27330 27219 27213
+f 2940 15369 17813
+f 14896 14898 23272
+f 27222 25340 27223
+f 27167 10312 27026
+f 25341 26995 27333
+f 27071 27293 27069
+f 25651 25650 26977
+f 25243 23843 24693
+f 27294 26325 27096
+f 9564 4482 3651
+f 25873 27159 16841
+f 17280 17279 24625
+f 14897 25143 14898
+f 27157 26524 27171
+f 25450 25452 27172
+f 26956 27334 27155
+f 26524 27157 27155
+f 24465 27334 26956
+f 26808 24465 26956
+f 24463 24465 26808
+f 26806 24463 26808
+f 25494 26805 27049
+f 25495 25494 27049
+f 25494 24463 26806
+f 26805 25494 26806
+f 27335 27300 27298
+f 27334 25813 27155
+f 27169 27300 27335
+f 27299 27177 27179
+f 26920 27169 27166
+f 27170 27169 27335
+f 27336 27337 27338
+f 15948 15947 16589
+f 17764 27003 27123
+f 25607 1508 1507
+f 25476 25477 27339
+f 25356 25421 25221
+f 23898 23897 26767
+f 7448 23300 7446
+f 17672 16729 27340
+f 27341 17672 27340
+f 23804 24060 24058
+f 27194 11148 11150
+f 27068 27040 25358
+f 17282 17284 27342
+f 2764 2244 3534
+f 27049 26235 27050
+f 13201 13203 27137
+f 3970 14250 3968
+f 18210 17783 2928
+f 16953 7061 15897
+f 25703 25704 25799
+f 27309 16736 27343
+f 16736 17387 27343
+f 27344 27345 17626
+f 27346 27347 21670
+f 24345 24344 27255
+f 27310 24345 27255
+f 27278 27315 3341
+f 16936 27315 27278
+f 25498 25581 27319
+f 25267 2500 27302
+f 25658 24468 24794
+f 26988 27316 26989
+f 27348 27066 26318
+f 24532 4840 4842
+f 17523 25357 17524
+f 16606 27349 16607
+f 25339 16661 15664
+f 27156 24007 27023
+f 26958 26913 27158
+f 27350 18060 25110
+f 27011 25705 25930
+f 15072 26129 9273
+f 1700 23964 1701
+f 25215 27351 3043
+f 19727 25467 25332
+f 17347 21609 24313
+f 23913 25162 27004
+f 27326 27293 27071
+f 17500 3982 27352
+f 26815 26761 27067
+f 27037 27326 27071
+f 16731 27247 2967
+f 27353 27354 27355
+f 16048 17308 17307
+f 16731 27002 27356
+f 8217 9635 9231
+f 27002 16449 27121
+f 19329 19289 19330
+f 19057 7866 19058
+f 27247 16731 27356
+f 9632 19665 15173
+f 16449 16451 27141
+f 27356 27002 27121
+f 7240 11481 12554
+f 26934 27006 25686
+f 27121 16449 27141
+f 27069 27294 27096
+f 27160 25151 26130
+f 25942 25369 27357
+f 11082 11081 18904
+f 23322 23324 23101
+f 26818 27266 26819
+f 24223 27358 16611
+f 26791 23322 23101
+f 26906 26910 26907
+f 27008 17735 27359
+f 26337 16691 27025
+f 25104 25103 25639
+f 27360 27331 26856
+f 17441 17443 25421
+f 26243 26782 17821
+f 17821 26782 17822
+f 20550 16666 16668
+f 25122 21363 21286
+f 19370 19369 25355
+f 21836 23760 12649
+f 27061 14897 14896
+f 26229 23761 23760
+f 25937 24960 27140
+f 19369 26847 17441
+f 27172 25452 27209
+f 27265 25937 27140
+f 25931 25937 27265
+f 27209 25931 27265
+f 15726 15725 24969
+f 24960 24962 27139
+f 2082 27361 27362
+f 23827 851 855
+f 25151 17824 26130
+f 23959 4958 14631
+f 5635 25831 5636
+f 10155 27187 2767
+f 22775 22869 22802
+f 27265 27140 27019
+f 26943 26963 25636
+f 21413 25468 7861
+f 25469 25470 25471
+f 19423 13565 6886
+f 27363 23321 27341
+f 23356 23321 27363
+f 9181 17598 922
+f 10376 27364 10377
+f 17389 25340 27222
+f 27365 23719 27308
+f 12012 12764 8550
+f 18891 27312 27311
+f 25283 24876 27255
+f 24344 25283 27255
+f 16937 16936 27278
+f 17379 26783 25579
+f 25581 11082 27318
+f 16970 16972 27153
+f 27317 25658 26786
+f 15956 26217 15982
+f 25560 24809 24532
+f 9573 16108 9574
+f 15922 25703 25799
+f 27366 25083 25085
+f 27266 27265 27019
+f 27140 27139 26935
+f 25477 26848 27339
+f 26955 26959 25649
+f 27232 6787 6789
+f 27124 27232 6789
+f 25336 24529 25399
+f 26918 12764 15948
+f 24996 22475 23427
+f 24056 24055 27231
+f 656 26337 26432
+f 25313 16669 23918
+f 27079 26934 25285
+f 17991 17496 17499
+f 17764 27123 27122
+f 3897 2948 2819
+f 27274 26889 26138
+f 17765 17764 27122
+f 5495 5494 15367
+f 26139 26797 26140
+f 26901 26229 21836
+f 13934 5495 15367
+f 2288 6294 7007
+f 27331 27120 25812
+f 26787 25156 26896
+f 27185 15653 25912
+f 26819 27020 17734
+f 16217 25368 19767
+f 17734 27020 25511
+f 17733 26819 17734
+f 27020 26937 25511
+f 25412 25199 27277
+f 2812 1636 2129
+f 23897 26849 26767
+f 27145 23898 26768
+f 24797 23705 26143
+f 26897 26896 25158
+f 26941 27367 25573
+f 21871 9661 9660
+f 25315 15660 27368
+f 23324 22710 22712
+f 17803 27286 17804
+f 26983 24004 24006
+f 27009 27359 27001
+f 26949 27009 27001
+f 27084 27009 26949
+f 27085 27084 26949
+f 27369 14135 18010
+f 26858 26772 27085
+f 18983 23959 20920
+f 17463 27017 17464
+f 18983 20920 17065
+f 24775 15820 5931
+f 14605 14604 22826
+f 19843 25823 20051
+f 25203 27370 20051
+f 5776 13401 18497
+f 27122 25690 25689
+f 8959 8958 16843
+f 27322 27371 25455
+f 25423 27322 25455
+f 24005 27156 26833
+f 20501 17194 15315
+f 23101 23324 22712
+f 25204 25362 27372
+f 18121 11388 27373
+f 6133 6037 15312
+f 27215 27374 27375
+f 27009 27008 27359
+f 26814 27053 26236
+f 16765 17763 17765
+f 27376 25172 25174
+f 9658 9657 9044
+f 7337 7336 14707
+f 15947 9529 16589
+f 27089 264 266
+f 16721 27377 27283
+f 16722 16721 27283
+f 27377 27378 27287
+f 27283 27377 27287
+f 27371 27379 25474
+f 25455 27371 25474
+f 27379 27380 25475
+f 27381 23331 27382
+f 23330 23331 27381
+f 27382 23356 27363
+f 23321 17672 27341
+f 24013 27197 24015
+f 27198 27383 23957
+f 16734 16736 27309
+f 27384 25020 27365
+f 18208 18891 27311
+f 27312 27344 17625
+f 25283 5265 24876
+f 23900 15847 27313
+f 17529 17379 25579
+f 26783 23351 25656
+f 20459 27321 9486
+f 20211 16214 16216
+f 27280 27316 26988
+f 26337 27025 27385
+f 27386 25027 25099
+f 26051 15395 16842
+f 25812 26524 25813
+f 25810 25809 25804
+f 25308 23317 8396
+f 25702 1837 1839
+f 25477 20155 27097
+f 23827 18891 851
+f 11268 2966 11267
+f 2518 1132 11466
+f 8697 2289 8698
+f 24469 25934 25947
+f 19289 19329 19655
+f 18841 18803 16491
+f 25311 25313 26928
+f 25536 25311 26928
+f 17631 17630 24588
+f 24619 23361 16737
+f 22960 27346 21670
+f 6516 6518 27387
+f 22151 27388 22149
+f 17403 26139 26889
+f 26408 26919 26409
+f 25657 25496 24466
+f 18210 2928 17996
+f 8121 5050 14970
+f 27389 26222 27183
+f 3410 3409 25420
+f 14247 22872 22871
+f 17166 16575 17638
+f 17583 25505 19823
+f 8960 16844 27208
+f 24277 23278 23277
+f 3535 15567 20211
+f 27378 27390 27289
+f 23254 25871 23255
+f 27287 27378 27289
+f 27391 27290 27289
+f 27390 27391 27289
+f 26841 26850 23779
+f 26807 26980 27053
+f 27029 17277 27392
+f 26944 19492 19491
+f 24959 17365 17364
+f 27338 27337 27393
+f 20301 17804 20338
+f 27394 2589 2599
+f 25651 26977 27193
+f 17803 27284 27286
+f 27001 27359 25758
+f 27359 23337 25758
+f 10499 3159 3299
+f 25758 23337 25250
+f 26913 26787 26895
+f 27395 24964 22866
+f 16378 27055 16377
+f 4396 27396 21932
+f 17618 15470 27226
+f 3178 3137 7325
+f 27397 27398 18980
+f 18559 27397 18980
+f 27398 27399 19549
+f 18980 27398 19549
+f 27399 27400 1335
+f 19549 27399 1335
+f 27401 18551 1335
+f 27400 27401 1335
+f 13198 23710 13293
+f 27401 21472 18551
+f 5460 5459 5735
+f 9529 3154 2941
+f 17364 27038 25935
+f 25802 25800 25803
+f 26964 26224 9201
+f 2967 17533 2965
+f 25395 25448 26952
+f 17357 17280 23291
+f 27264 27266 26818
+f 27402 26846 26963
+f 27403 27291 27290
+f 26847 17442 17441
+f 27391 27403 27290
+f 27404 27292 27291
+f 27403 27404 27291
+f 25474 27379 25475
+f 27380 27405 25485
+f 25475 27380 25485
+f 23386 23330 25148
+f 24756 27406 23836
+f 25146 23330 27381
+f 23331 23356 27382
+f 24015 27198 23957
+f 27407 27408 24016
+f 27383 27407 23958
+f 23957 27383 23958
+f 23719 16734 27308
+f 25018 25020 27384
+f 17625 27344 17626
+f 27345 27233 25390
+f 27409 23900 27313
+f 23271 23900 27409
+f 25579 26783 25656
+f 23351 16935 25503
+f 27336 25819 27410
+f 25501 25499 27411
+f 26432 26337 27385
+f 27025 27258 27257
+f 23300 24963 25308
+f 18694 23300 25308
+f 25805 25801 25803
+f 25916 23913 25918
+f 25917 25918 25085
+f 25918 27366 25085
+f 26822 27412 25339
+f 16241 14843 14842
+f 27413 26030 16097
+f 26030 25696 16097
+f 15846 26319 25218
+f 26072 8928 8930
+f 16669 25315 23919
+f 27414 27415 24347
+f 23918 16669 23919
+f 25315 27368 27416
+f 15546 27077 25685
+f 25528 26861 27417
+f 8716 20808 8717
+f 25880 23335 23334
+f 2576 18591 2597
+f 25030 17282 27342
+f 25948 25836 21346
+f 26765 26897 25158
+f 26928 25313 23918
+f 27286 25865 25864
+f 20794 25261 20792
+f 27262 17534 27299
+f 21245 17685 23981
+f 26170 25506 25508
+f 24274 25575 24019
+f 27097 20549 26998
+f 18694 7446 23300
+f 17348 25915 25704
+f 27405 27418 25486
+f 20754 27043 17822
+f 27419 27306 27292
+f 17279 27420 24625
+f 27404 27419 27292
+f 27421 27307 27306
+f 27419 27421 27306
+f 27422 27323 27307
+f 27421 27422 27307
+f 10312 27027 27026
+f 25877 16209 17386
+f 19124 19100 17979
+f 17401 17403 23894
+f 25485 27405 25486
+f 17366 27038 17364
+f 27423 15651 27185
+f 17213 20536 22410
+f 26797 26796 26837
+f 16765 17765 16766
+f 27418 27424 25554
+f 23337 23339 25250
+f 17276 24881 16221
+f 17569 25872 27259
+f 25486 27418 25554
+f 27370 526 525
+f 7542 2466 3508
+f 18149 18151 15469
+f 25332 25467 27397
+f 23289 27425 23290
+f 25467 27426 27398
+f 27397 25467 27398
+f 27426 27427 27399
+f 27398 27426 27399
+f 27427 27428 27400
+f 27399 27427 27400
+f 27429 27401 27400
+f 27428 27429 27400
+f 27430 21472 27401
+f 27429 27430 27401
+f 27431 17632 21472
+f 27430 27431 21472
+f 16449 2591 16450
+f 27431 17630 17632
+f 26072 8930 8792
+f 23752 24110 24163
+f 25928 25927 1508
+f 17445 26766 20652
+f 27432 27327 27323
+f 27422 27432 27323
+f 27433 27330 27327
+f 25831 17813 5636
+f 1663 25507 26171
+f 25860 23327 25163
+f 23386 25148 5027
+f 22254 6254 24064
+f 23810 5027 5029
+f 23330 25146 25148
+f 23958 27407 24016
+f 27434 27435 24114
+f 27408 27434 24061
+f 24016 27408 24061
+f 27436 27437 27438
+f 4156 27437 27436
+f 27438 25018 27384
+f 25020 23719 27365
+f 17626 27345 25390
+f 27233 24927 25391
+f 25492 23271 27409
+f 23297 23271 25492
+f 27248 27249 3342
+f 3341 27248 3342
+f 25498 27319 27314
+f 25502 25501 27439
+f 27385 27025 27257
+f 27258 25814 24614
+f 26976 27264 26818
+f 25219 16614 16616
+f 27004 26966 27366
+f 25918 27004 27366
+f 25804 25803 25920
+f 14840 25804 25920
+f 26329 26972 25942
+f 25355 25421 25356
+f 1839 26030 27413
+f 18204 1839 27413
+f 26321 23846 23845
+f 16740 16739 24403
+f 27440 27441 15077
+f 27442 27414 25870
+f 27416 27368 26414
+f 23919 25315 27416
+f 25446 25528 27417
+f 26860 27443 27417
+f 25319 25880 23334
+f 25880 25449 23335
+f 27196 27442 24439
+f 27414 25871 25870
+f 8140 27444 2446
+f 19599 15146 11088
+f 7866 19057 19840
+f 14451 17458 7323
+f 15653 15652 26942
+f 26939 25038 26839
+f 24338 27445 27446
+f 25245 25248 25246
+f 15089 4136 4135
+f 26352 26256 26445
+f 14640 15900 1485
+f 25247 9573 9575
+f 17734 25511 23338
+f 3794 8400 8555
+f 26950 25285 26890
+f 657 16691 26337
+f 27424 27447 25555
+f 26891 26950 26890
+f 27432 27433 27327
+f 18843 18842 25028
+f 27448 27332 27433
+f 27433 27332 27330
+f 26982 17825 17824
+f 25554 27424 25555
+f 27449 16415 27159
+f 23772 1663 1665
+f 26783 24070 23351
+f 27450 25556 25555
+f 27447 27450 25555
+f 26127 26823 25159
+f 26146 25662 17806
+f 27451 25566 25556
+f 19843 19842 25823
+f 24328 12962 14901
+f 3144 3143 17741
+f 26957 27041 26958
+f 25527 15652 15651
+f 16844 27374 27215
+f 18587 18557 18558
+f 16844 8960 8959
+f 27452 19744 19745
+f 7061 14355 10505
+f 14355 7061 16953
+f 19744 27453 27426
+f 25467 19744 27426
+f 27453 27454 27427
+f 27426 27453 27427
+f 27454 27455 27428
+f 27427 27454 27428
+f 27455 27456 27429
+f 27428 27455 27429
+f 27456 27457 27430
+f 27429 27456 27430
+f 27458 27431 27430
+f 27457 27458 27430
+f 27459 17630 27431
+f 27458 27459 27431
+f 24825 9449 3729
+f 27459 17166 17630
+f 27450 27451 25556
+f 25236 17275 27029
+f 25829 16103 27094
+f 27223 25341 27333
+f 26995 26996 27095
+f 27067 23890 27068
+f 23891 23895 23892
+f 17187 27229 27340
+f 26417 17449 17451
+f 16729 17187 27340
+f 7009 5816 12293
+f 16450 16305 16451
+f 25150 23285 24222
+f 27460 27461 27462
+f 24061 27434 24114
+f 24165 25150 24222
+f 27435 25150 24165
+f 24114 27435 24165
+f 16820 26878 23775
+f 16048 27349 16046
+f 4157 4156 27436
+f 27437 25018 27438
+f 25390 27233 25391
+f 24929 27463 26822
+f 24927 24929 27304
+f 25391 24927 27304
+f 16694 23297 25492
+f 24854 14888 16693
+f 27464 27465 3342
+f 27249 27464 3342
+f 25499 27314 27411
+f 25224 25502 27466
+f 26786 25658 24794
+f 24468 27268 15844
+f 27467 25047 22237
+f 27468 17884 17886
+f 26966 25806 25083
+f 27366 26966 25083
+f 25800 25799 25919
+f 27469 25914 25913
+f 25422 27114 23547
+f 25823 26027 25824
+f 26122 26221 25530
+f 26123 26122 25530
+f 25929 26321 26323
+f 23723 27470 23724
+f 26900 27471 27472
+f 27473 27474 27475
+f 27368 26408 26414
+f 7443 23347 14223
+f 26861 26860 27417
+f 25610 27052 27443
+f 6595 27476 23253
+f 23909 25759 27477
+f 25281 25987 24855
+f 13950 13949 14036
+f 19409 25167 25533
+f 27372 25312 25311
+f 18213 16469 16471
+f 17284 25244 25246
+f 27005 27423 27185
+f 26889 26139 26138
+f 25822 25528 25445
+f 25036 26994 25037
+f 17637 16788 14213
+f 25197 23608 25132
+f 9574 25175 24508
+f 25175 26169 15545
+f 17246 19079 19081
+f 25243 25238 23843
+f 24861 24860 25021
+f 3776 2080 4950
+f 10524 6058 5494
+f 5059 5058 12099
+f 25982 25984 26973
+f 23981 19956 23982
+f 24942 25004 22921
+f 7323 15749 15817
+f 27451 27478 25568
+f 27479 17625 17627
+f 17444 20652 19910
+f 26231 26985 26232
+f 12764 12012 15947
+f 9915 3132 9916
+f 17068 16455 16454
+f 21871 10559 7566
+f 25527 25476 27339
+f 15847 15846 24345
+f 26056 25102 25104
+f 27480 25205 26147
+f 27481 25823 19842
+f 27482 25527 15651
+f 26993 27136 26971
+f 525 20051 27370
+f 27483 27484 23926
+f 24439 25870 24440
+f 24066 24021 26874
+f 26937 26936 26984
+f 23592 21729 5508
+f 25566 27451 25568
+f 27452 27485 27453
+f 19744 27452 27453
+f 27485 27486 27454
+f 27453 27485 27454
+f 27486 27487 27455
+f 27454 27486 27455
+f 27488 27456 27455
+f 27487 27488 27455
+f 27489 27457 27456
+f 27488 27489 27456
+f 27490 27458 27457
+f 27489 27490 27457
+f 27491 27459 27458
+f 27490 27491 27458
+f 27491 21160 17166
+f 27459 27491 17166
+f 23628 14438 8302
+f 22168 22106 22107
+f 27478 27492 25652
+f 23759 23753 26794
+f 8940 8939 18558
+f 17301 27444 25859
+f 26967 27092 25806
+f 6798 25607 1507
+f 27324 16037 24281
+f 25818 25170 25171
+f 16240 14842 26798
+f 5325 5494 5493
+f 27493 24755 17585
+f 24281 16240 26798
+f 17402 25036 26939
+f 17584 27493 17585
+f 3595 4156 323
+f 25736 26916 24464
+f 23318 23320 16203
+f 1114 3595 323
+f 27304 24929 26822
+f 24435 16659 27412
+f 27463 24436 27412
+f 26822 27463 27412
+f 14888 23299 16693
+f 8923 8922 23312
+f 23299 23297 16694
+f 16693 23299 16694
+f 27494 27495 27465
+f 27464 27494 27465
+f 25501 27411 27439
+f 8806 25224 25710
+f 24794 24468 15844
+f 27268 27496 14852
+f 18591 2576 6473
+f 27497 27468 27015
+f 25834 177 20152
+f 27498 27499 27500
+f 26415 27469 25913
+f 27501 27469 26415
+f 27462 19917 17069
+f 24656 26841 20156
+f 17285 27502 25531
+f 21017 17989 17988
+f 25871 27414 24347
+f 17586 17585 24068
+f 25613 1507 1509
+f 1508 25927 27503
+f 23257 23258 25476
+f 27504 15397 15396
+f 26860 25610 27443
+f 24148 24195 24196
+f 27505 16632 22165
+f 15920 15922 25802
+f 24116 24118 23813
+f 25929 26323 27503
+f 25532 27372 25311
+f 25312 15999 25313
+f 27342 17284 25246
+f 24163 24112 23305
+f 27506 26773 25444
+f 25527 23257 25476
+f 16204 25092 16205
+f 24311 24313 21608
+f 19037 9044 13972
+f 27444 25985 25859
+f 9256 13332 2952
+f 27507 23950 23949
+f 27508 25168 24038
+f 23951 24040 23949
+f 16223 22018 25169
+f 25750 17276 17275
+f 5947 24691 27509
+f 25240 25750 17275
+f 21226 22139 14865
+f 27449 27034 16415
+f 25875 17388 17387
+f 25568 27478 25652
+f 26800 27032 26801
+f 24969 18121 27373
+f 22711 22710 27510
+f 25334 20794 25331
+f 25093 23820 8785
+f 22829 25059 22830
+f 27511 11281 5076
+f 2677 2520 2728
+f 27318 26978 24471
+f 25167 25166 25688
+f 15652 25527 27339
+f 27070 27076 27232
+f 25511 27267 25512
+f 25646 26821 25647
+f 14887 6210 6209
+f 25203 25361 25204
+f 15461 15992 21341
+f 14884 23718 26817
+f 26938 15948 16590
+f 26805 26814 26235
+f 25586 17130 17129
+f 19070 4112 19071
+f 14015 16214 15567
+f 22410 27512 27485
+f 27452 22410 27485
+f 27512 27513 27486
+f 27485 27512 27486
+f 27514 27487 27486
+f 27513 27514 27486
+f 27515 27488 27487
+f 27514 27515 27487
+f 27516 27489 27488
+f 27515 27516 27488
+f 27517 27490 27489
+f 27516 27517 27489
+f 27517 27518 27491
+f 27490 27517 27491
+f 27518 27519 21160
+f 27491 27518 21160
+f 20587 20586 19910
+f 3044 12973 3042
+f 9414 15461 24096
+f 27520 18120 12590
+f 27521 22018 27522
+f 6426 14383 3219
+f 23271 23270 23900
+f 26220 16112 17285
+f 27523 14748 14886
+f 5734 27523 9374
+f 22371 27524 13819
+f 27525 27526 22371
+f 25535 27527 16558
+f 24755 27348 24067
+f 25534 25535 16658
+f 27527 25878 16558
+f 25534 16658 16660
+f 26784 25534 16660
+f 24436 24435 27412
+f 25535 16558 16658
+f 26784 16660 16659
+f 24435 26784 16659
+f 23805 27528 23806
+f 8923 23312 22895
+f 8922 14888 24854
+f 16652 8922 24854
+f 27529 27386 27495
+f 27529 27530 27386
+f 27494 27529 27495
+f 27530 25027 27386
+f 25502 27439 27466
+f 8806 25710 23282
+f 15844 27268 14852
+f 27496 26953 27531
+f 17884 27532 22230
+f 23888 16100 27015
+f 8786 27196 8787
+f 25362 18203 15997
+f 25603 27501 26415
+f 27533 27501 25603
+f 1839 1838 26030
+f 26029 26074 25696
+f 25824 26028 25361
+f 26362 26456 26269
+f 24609 25212 20682
+f 27415 25854 17355
+f 1509 1508 27503
+f 25145 24513 17642
+f 27534 27535 23923
+f 26843 27536 25797
+f 19491 19493 24196
+f 24617 23358 24619
+f 27115 27100 27125
+f 24433 6516 27387
+f 25741 25490 25352
+f 25061 21363 25065
+f 25448 27537 26952
+f 27470 27538 23724
+f 25399 24531 25400
+f 25088 14205 23709
+f 15728 20470 25132
+f 20470 15728 20471
+f 19492 27256 19493
+f 5931 15820 5932
+f 16592 10075 12378
+f 25246 25248 25680
+f 23170 23169 6244
+f 14784 14783 21757
+f 27539 27540 27541
+f 27232 27076 6787
+f 26036 27542 25241
+f 25242 25238 25243
+f 22216 11541 11543
+f 8805 25222 8806
+f 23889 25165 16416
+f 22216 11543 16416
+f 16415 23889 16416
+f 20423 17837 17839
+f 16843 27374 16844
+f 25582 27135 26907
+f 6890 6644 15449
+f 15818 16212 22281
+f 27543 18936 27043
+f 16667 25356 27227
+f 18843 18875 18841
+f 27357 25369 25426
+f 26773 25445 25444
+f 27544 21654 25149
+f 27545 27544 25149
+f 18209 27479 26941
+f 27133 26869 27207
+f 25710 27466 8793
+f 27013 26976 27109
+f 27273 27225 27224
+f 26320 25740 25351
+f 17267 17266 27031
+f 6240 19150 14224
+f 12939 13289 12940
+f 20536 27546 22410
+f 14803 5601 5603
+f 24515 27512 22410
+f 27546 24515 22410
+f 27547 27513 27512
+f 24515 27547 27512
+f 15041 27514 27513
+f 24515 15042 27547
+f 24161 27515 27514
+f 27547 15041 27513
+f 27548 27516 27515
+f 24161 27548 27515
+f 27549 27517 27516
+f 27548 27549 27516
+f 27550 27518 27517
+f 27549 27550 27517
+f 27550 27551 27519
+f 27518 27550 27519
+f 27551 27552 27553
+f 27519 27551 27553
+f 27552 27554 22030
+f 27553 27552 22030
+f 27554 27555 5734
+f 22030 27554 5734
+f 27555 27556 27523
+f 5734 27555 27523
+f 27556 27557 14748
+f 27523 27556 14748
+f 26882 25870 23254
+f 15451 27558 27559
+f 23809 27560 23805
+f 27047 25680 25682
+f 16730 25709 16731
+f 23022 23024 27557
+f 19407 27061 25945
+f 16758 24348 16035
+f 27528 27295 23806
+f 7041 4001 4000
+f 19197 8923 22895
+f 6884 13373 6882
+f 23949 24147 27507
+f 8922 16652 23312
+f 2409 25025 25027
+f 25750 26946 17276
+f 27530 2409 25027
+f 17065 20920 24346
+f 27561 8807 23310
+f 27561 23310 27537
+f 8807 8806 23282
+f 25224 27466 25710
+f 14852 27496 27531
+f 26953 27199 27562
+f 27468 17886 27015
+f 23887 24658 23888
+f 22942 22941 27563
+f 23950 27508 23951
+f 26777 27533 25603
+f 15954 27533 26777
+f 26030 26029 25696
+f 26074 25484 25698
+f 14844 27192 26795
+f 25794 26867 26834
+f 14853 27531 27564
+f 24621 24690 27358
+f 23963 27470 23723
+f 22292 25316 27565
+f 27130 27483 23926
+f 27484 15663 16352
+f 11039 26067 27303
+f 18591 16722 27283
+f 24068 24067 26319
+f 26029 25913 26074
+f 25019 25219 25020
+f 26320 25351 25424
+f 6385 21630 27566
+f 18209 27311 27479
+f 26220 17285 25531
+f 17286 27567 27502
+f 22597 23373 22598
+f 6804 6806 26961
+f 19037 13972 7446
+f 27319 27318 24471
+f 17902 9143 14399
+f 1099 1101 7444
+f 21608 24313 21609
+f 24146 24148 24147
+f 1624 1623 16091
+f 23306 25615 24796
+f 21838 16840 27128
+f 25313 15999 16669
+f 27214 27014 27449
+f 27014 27034 27449
+f 17646 17648 23724
+f 15998 27413 15658
+f 5395 24807 25560
+f 24886 15767 15766
+f 27019 27140 26935
+f 25159 26128 26127
+f 27568 18062 24533
+f 27139 27138 26936
+f 26935 27139 26936
+f 9379 9378 26066
+f 15846 25218 24345
+f 25352 27236 25635
+f 26928 23918 26929
+f 23308 5548 20750
+f 24530 25529 25427
+f 25447 23307 23308
+f 17662 21654 27569
+f 16824 16826 26915
+f 27133 27207 27131
+f 16317 16319 9704
+f 27045 26977 26765
+f 25285 26934 25286
+f 27138 26231 26230
+f 26751 17131 27059
+f 14237 14236 26026
+f 4344 4345 15929
+f 24690 23095 27358
+f 24944 24515 27546
+f 22437 4344 15929
+f 18227 24515 24944
+f 24944 24943 27570
+f 23363 23362 26774
+f 27527 23363 26774
+f 23362 24440 24911
+f 24440 24860 24911
+f 25269 14237 22278
+f 24440 26882 25022
+f 27571 27572 25171
+f 6246 22797 24546
+f 27573 10568 3360
+f 24860 24440 25022
+f 27574 27551 27550
+f 5170 399 11253
+f 27574 14947 27552
+f 27551 27574 27552
+f 14947 27575 27554
+f 27552 14947 27554
+f 27575 27576 27555
+f 27554 27575 27555
+f 27577 27556 27555
+f 27576 27577 27555
+f 23022 27557 27556
+f 27577 23022 27556
+f 22896 22895 16252
+f 27578 23244 23023
+f 27023 24009 25172
+f 23312 16253 16252
+f 25695 25153 15886
+f 26148 27042 27251
+f 4470 14352 25694
+f 16660 16867 16661
+f 238 1701 23964
+f 26169 5635 5637
+f 23721 23720 24712
+f 27061 25533 14897
+f 25497 24663 27088
+f 26048 27542 26036
+f 24662 26776 25394
+f 27088 24662 25394
+f 27579 27580 27537
+f 25448 27579 27537
+f 27580 27561 27537
+f 8807 23282 23310
+f 27531 26953 27562
+f 8794 24461 26053
+f 8795 26053 27562
+f 27199 8795 27562
+f 16100 27497 27015
+f 24634 24658 23887
+f 16112 16111 14839
+f 3417 21351 3421
+f 27481 15954 26777
+f 15952 15954 27481
+f 24458 23256 23294
+f 25696 26074 25698
+f 26882 23254 23292
+f 16752 2308 2489
+f 26803 15817 15818
+f 13807 16751 27581
+f 3335 25316 3336
+f 27466 24469 8793
+f 26410 26409 26413
+f 26921 25387 26413
+f 23752 23755 24058
+f 15664 23962 15665
+f 25508 25507 1663
+f 25649 27158 25650
+f 27412 16659 25339
+f 25711 23821 25340
+f 16471 16470 3335
+f 27280 23815 27316
+f 17285 17286 27502
+f 17800 26419 27567
+f 8556 23253 4336
+f 12700 17731 27582
+f 19705 27042 26148
+f 26933 27535 27583
+f 27076 21078 6787
+f 27028 25464 25466
+f 20578 550 27584
+f 11224 1483 15970
+f 24692 24694 27148
+f 27585 24692 27148
+f 26043 26045 26335
+f 26334 26043 26335
+f 25757 25921 25034
+f 25033 25757 25034
+f 27586 26700 25035
+f 17294 6467 8392
+f 23813 24167 25487
+f 17886 22216 25165
+f 21280 15306 22650
+f 19001 14342 15312
+f 19423 18975 10986
+f 18092 18014 18055
+f 1796 3921 7335
+f 9631 5902 14275
+f 27587 20818 27588
+f 5495 13934 15441
+f 27235 27194 26243
+f 25635 27236 17932
+f 25320 23334 23834
+f 23712 26075 27506
+f 26950 26909 27079
+f 27154 14844 27117
+f 15700 15699 27536
+f 26844 27097 26998
+f 27589 16721 7336
+f 17451 26832 26412
+f 14343 27589 7336
+f 27589 27590 27377
+f 16721 27589 27377
+f 27590 27591 27378
+f 25490 25571 27236
+f 25206 25816 25815
+f 14237 26026 22278
+f 26133 25817 26700
+f 25878 27527 26774
+f 23362 24911 26774
+f 26807 24004 26983
+f 26814 26807 27053
+f 23716 23718 14884
+f 14883 23716 14884
+f 27592 25749 24538
+f 25143 26929 23953
+f 27545 25149 22874
+f 25269 22278 14847
+f 25992 23826 25319
+f 27375 27593 17763
+f 27277 25201 27220
+f 17289 10312 27167
+f 22710 23324 22875
+f 17283 8396 23316
+f 14948 14947 27574
+f 14947 14949 27575
+f 27594 27576 27575
+f 27595 27594 27575
+f 27594 27596 27577
+f 27576 27594 27577
+f 27596 27578 23022
+f 27577 27596 23022
+f 23244 22698 27597
+f 23022 27578 23023
+f 27393 26999 26978
+f 27530 25939 2409
+f 23816 24665 24654
+f 27318 27393 26978
+f 24654 24688 25496
+f 24688 27598 25496
+f 25496 27598 25497
+f 27598 24663 25497
+f 26776 27579 25448
+f 24663 24662 27088
+f 24966 24472 23837
+f 25394 26776 25448
+f 24966 23837 24536
+f 24967 24966 24536
+f 24967 24536 24535
+f 24472 27112 23837
+f 8795 8794 26053
+f 25947 24967 24535
+f 25947 24535 24461
+f 8794 25947 24461
+f 2746 8358 2747
+f 15589 20330 25629
+f 23722 24634 23887
+f 24658 16100 23888
+f 15921 17346 25703
+f 26876 25084 27132
+f 27599 25859 25861
+f 26280 21270 17052
+f 27600 27601 27602
+f 23102 27603 18938
+f 27604 16753 27601
+f 27600 27604 27601
+f 27605 16751 24335
+f 27604 16751 16753
+f 26825 24459 23315
+f 26142 25144 17641
+f 25992 25319 25318
+f 26412 26921 26413
+f 17511 17584 17512
+f 17512 17584 17586
+f 10097 9307 24377
+f 2676 22721 11199
+f 16212 15818 15748
+f 18710 24342 24341
+f 18214 16471 3334
+f 16470 25316 3335
+f 17286 17800 27567
+f 17800 27480 26324
+f 22161 1635 4614
+f 23365 24279 24340
+f 25704 27216 26040
+f 25799 25704 26040
+f 27606 27342 27047
+f 986 22746 984
+f 23720 17568 24712
+f 24713 27014 27214
+f 26045 24692 27585
+f 26335 26045 27585
+f 23843 23781 26134
+f 24693 23843 26134
+f 25946 24537 25237
+f 23781 23783 27607
+f 25946 25936 24537
+f 25634 25946 25237
+f 25936 25032 27592
+f 25032 27608 27592
+f 21497 7575 7574
+f 27364 27197 24013
+f 27377 27590 27378
+f 27609 27390 27378
+f 27591 27609 27378
+f 27610 27391 27390
+f 18842 18841 16491
+f 24470 24472 24966
+f 26909 26908 27301
+f 17266 17265 27234
+f 22373 23927 27611
+f 25298 25299 25296
+f 332 25646 25648
+f 27301 27423 27005
+f 26994 27073 25037
+f 27334 26856 25813
+f 27609 27610 27390
+f 27612 27403 27391
+f 27610 27612 27391
+f 26049 26889 26869
+f 27613 27404 27403
+f 23826 25880 25319
+f 3725 3727 4345
+f 16841 16840 27033
+f 25698 25789 25699
+f 24690 25043 23095
+f 7342 7344 18298
+f 17158 9641 17159
+f 3425 20786 3216
+f 24339 24540 24353
+f 24541 24758 24350
+f 24760 17643 24620
+f 24353 24541 24350
+f 27105 24689 24620
+f 24351 24760 24620
+f 27104 25147 24689
+f 17643 27105 24620
+f 17804 27286 25864
+f 27105 27104 24689
+f 26931 27614 17532
+f 23258 24655 24657
+f 27104 17532 25147
+f 27066 26992 25398
+f 27595 26752 27615
+f 27575 14949 27595
+f 27616 27617 27596
+f 27594 27616 27596
+f 27617 23245 27578
+f 27596 27617 27578
+f 10567 22658 23052
+f 27578 23245 23244
+f 23260 22027 22029
+f 11082 27393 27318
+f 26999 27337 27618
+f 27566 21630 15677
+f 27000 5948 24623
+f 5946 15188 5947
+f 26979 27000 24622
+f 5948 5947 24623
+f 26979 24622 27112
+f 24472 26979 27112
+f 27608 27619 27620
+f 27000 24623 24622
+f 16203 16108 9573
+f 26939 25036 25038
+f 16556 24854 24071
+f 7348 6530 2144
+f 24796 27621 23986
+f 23721 26263 24634
+f 25245 16203 9573
+f 16108 27039 9574
+f 27546 20536 26618
+f 26982 24065 23756
+f 5636 24219 17542
+f 25922 27622 23080
+f 17347 24313 17348
+f 27623 25877 27260
+f 27600 27602 27624
+f 27602 27625 27626
+f 27627 27600 27624
+f 27628 27627 27624
+f 27629 27604 27600
+f 27627 27629 27600
+f 15191 22950 15135
+f 27629 24335 27604
+f 26921 23956 25389
+f 23956 23955 25389
+f 25387 26921 25389
+f 23955 25318 25389
+f 22797 22229 17309
+f 17356 25856 17278
+f 27535 15700 23923
+f 27314 27319 24470
+f 11267 25572 27032
+f 18843 25028 23885
+f 23825 25751 3334
+f 16471 3335 3334
+f 26419 17800 26324
+f 27480 26147 25752
+f 24339 24353 24117
+f 24878 25933 27253
+f 25915 25660 27216
+f 25704 25915 27216
+f 25914 27630 25798
+f 23911 23913 25916
+f 23913 27004 25918
+f 25798 23911 25916
+f 25757 25926 26042
+f 25921 25757 26042
+f 26134 23781 27607
+f 23783 25634 25237
+f 14604 17686 25413
+f 23964 23965 26055
+f 25931 25707 25937
+f 26126 27324 20021
+f 26942 25796 15699
+f 25707 25938 25937
+f 24333 24335 27629
+f 26066 11267 27032
+f 27612 27613 27403
+f 11039 27303 23569
+f 27631 27419 27404
+f 27613 27631 27404
+f 27632 27421 27419
+f 7441 3178 7325
+f 26889 27274 26869
+f 18555 18561 18553
+f 27230 27200 27423
+f 27585 27148 27147
+f 23334 23336 23834
+f 22876 10840 4230
+f 25043 23094 23095
+f 27631 27632 27419
+f 26903 27195 17265
+f 27633 27422 27421
+f 27632 27633 27421
+f 25938 27010 24961
+f 27634 27432 27422
+f 27116 27125 27044
+f 26761 23890 27067
+f 21245 26164 21246
+f 26872 23289 23288
+f 25022 26882 23292
+f 21684 19957 19956
+f 17245 27635 27636
+f 18445 18427 18978
+f 9833 16733 15191
+f 27637 26885 16314
+f 24758 24760 24351
+f 24350 24758 24351
+f 5163 25478 17221
+f 14896 25820 25310
+f 24169 25492 26057
+f 18908 18876 23886
+f 2394 2393 23268
+f 26057 27409 24800
+f 27638 24059 27639
+f 22655 17404 23945
+f 23946 17404 27639
+f 27316 23817 27317
+f 25094 8785 8787
+f 24067 27348 26318
+f 27522 27640 27521
+f 27641 27642 16410
+f 27643 9628 27617
+f 27616 27643 27617
+f 9628 9627 23245
+f 27617 9628 23245
+f 4928 4112 19070
+f 16733 9833 9832
+f 2348 4637 15012
+f 27025 26056 27258
+f 2649 18117 21790
+f 14236 25716 26026
+f 25024 17256 26240
+f 3031 3030 3244
+f 16589 2940 25831
+f 25802 15922 25800
+f 16535 27644 16536
+f 24537 27592 24538
+f 27471 26336 27645
+f 25090 25089 26320
+f 26238 26336 27471
+f 17192 26238 27471
+f 27646 27147 27474
+f 26336 27646 27645
+f 26899 25923 16951
+f 25924 26238 17192
+f 25922 25923 27622
+f 16951 25924 17192
+f 26884 26883 23080
+f 25923 25924 16951
+f 27647 27648 27649
+f 25923 26899 27622
+f 27649 27650 27647
+f 21343 15560 11284
+f 27650 27651 27628
+f 27647 27650 27628
+f 27652 27627 27628
+f 27651 27652 27628
+f 24333 27629 27627
+f 27652 24333 27627
+f 15928 22437 15929
+f 14298 15365 21411
+f 27090 27091 27117
+f 27653 27654 14690
+f 26795 27090 27117
+f 16826 24431 25087
+f 26413 25387 25386
+f 27296 26413 25386
+f 25510 25693 17543
+f 27542 25242 25241
+f 18876 18843 23885
+f 25028 25030 27655
+f 26420 23824 27099
+f 26418 26420 27099
+f 26324 27480 25752
+f 26147 17806 18212
+f 20459 9486 1019
+f 13347 13982 14566
+f 24312 25661 25660
+f 25915 24312 25660
+f 27469 27656 25914
+f 27630 23911 25798
+f 2081 26432 2082
+f 7447 8551 7448
+f 25926 26043 26334
+f 26042 25926 26334
+f 27607 23783 25237
+f 25936 27592 24537
+f 27008 17733 17735
+f 26764 25655 17523
+f 17388 25711 17389
+f 18979 18980 19549
+f 18654 22864 26046
+f 6374 24974 24973
+f 27072 27141 27142
+f 27657 18654 26046
+f 10559 21871 9660
+f 26933 25912 27535
+f 27633 27634 27422
+f 2591 2590 16450
+f 27658 27433 27432
+f 27634 27658 27432
+f 26954 26959 26955
+f 27448 27659 27660
+f 27553 22030 10519
+f 23900 15845 15847
+f 15441 5602 5495
+f 27553 10519 17452
+f 15283 27661 27396
+f 27185 15651 15653
+f 27658 27448 27433
+f 16590 16589 25831
+f 27296 25386 27406
+f 27333 26995 27095
+f 27492 27662 25653
+f 27229 23759 26793
+f 15004 9457 9449
+f 25821 26861 25528
+f 9449 24825 15004
+f 24958 25339 15664
+f 23204 21684 17684
+f 17685 21684 23981
+f 15660 24510 27368
+f 7108 10149 2304
+f 8140 25985 27444
+f 26810 25366 25365
+f 23704 24057 27638
+f 24059 23946 27639
+f 24111 24057 23703
+f 24057 24059 27638
+f 25652 27492 25653
+f 27663 25713 25653
+f 27662 27663 25653
+f 27664 25714 25713
+f 27663 27664 25713
+f 27665 25715 25714
+f 24112 24111 25615
+f 24057 23704 23703
+f 25650 26895 26897
+f 27527 26052 23363
+f 27437 25577 25018
+f 8396 23317 23316
+f 27666 2465 19995
+f 27616 27615 23172
+f 22658 18247 23052
+f 8396 17283 14486
+f 7018 3229 3231
+f 19071 10567 23052
+f 21702 27667 26135
+f 22698 23245 9627
+f 27667 27668 26136
+f 26135 27667 26136
+f 23174 27669 27670
+f 23176 27671 23174
+f 25234 25236 27029
+f 27672 25234 27029
+f 27645 27646 27474
+f 27147 25234 27672
+f 27389 27173 26222
+f 27474 27147 27672
+f 27673 27520 12590
+f 26223 26039 26038
+f 5818 15147 5815
+f 27045 26765 16970
+f 21290 27674 21288
+f 5964 27675 27676
+f 27677 27678 27674
+f 27675 27679 21290
+f 27648 23177 27649
+f 27679 27677 27674
+f 27680 27649 27678
+f 27677 27680 27678
+f 27681 27650 27649
+f 27680 27681 27649
+f 27681 27682 27651
+f 27650 27681 27651
+f 27683 27652 27651
+f 27682 27683 27651
+f 27684 24333 27652
+f 27683 27684 27652
+f 27608 27620 25749
+f 17488 25683 22956
+f 18113 5498 5493
+f 23722 23887 27034
+f 9628 9340 9629
+f 17371 17731 12700
+f 26410 26413 27296
+f 27295 26410 27296
+f 26965 27045 27046
+f 25481 24756 23445
+f 25059 23763 27270
+f 25396 25956 25397
+f 26420 25751 23825
+f 23824 26420 23825
+f 25752 26147 18212
+f 17795 18213 18212
+f 15395 21838 27128
+f 24560 27685 27686
+f 21608 25263 24311
+f 24312 24311 25661
+f 27501 27687 27469
+f 27656 27630 25914
+f 26432 27385 27361
+f 2082 26432 27361
+f 23926 16352 23726
+f 25575 25574 27035
+f 5395 25560 5393
+f 27130 23926 23925
+f 26781 26778 23713
+f 27109 17733 27008
+f 27621 24796 24759
+f 27657 26046 24975
+f 26088 27688 17646
+f 24862 17572 17647
+f 27470 16560 27538
+f 26088 17646 27538
+f 27483 25392 27484
+f 27305 24958 15663
+f 27689 8924 27561
+f 27484 27305 15663
+f 25420 27322 25423
+f 19665 19740 20614
+f 17825 26982 23756
+f 17221 21085 25368
+f 25874 25873 16841
+f 15652 27339 26942
+f 27664 27665 25714
+f 27665 27690 25754
+f 20155 19371 20549
+f 25173 26974 27013
+f 27691 27493 17584
+f 23284 23283 27199
+f 15118 20551 20510
+f 27692 14948 27574
+f 26848 25477 27097
+f 26959 27158 25649
+f 5771 5928 6212
+f 15043 17797 17798
+f 3728 10139 24838
+f 25715 27665 25754
+f 17684 17686 27693
+f 25873 27449 27159
+f 15817 14451 7323
+f 550 20579 18603
+f 23788 26810 25365
+f 4451 27694 26809
+f 23305 24112 23306
+f 24111 23703 25615
+f 27087 25756 25754
+f 27690 27087 25754
+f 27086 23923 23924
+f 25756 27087 6255
+f 23948 23807 25273
+f 15668 15667 20411
+f 17705 17217 17219
+f 27325 27695 27696
+f 23710 13198 18523
+f 26867 27001 23908
+f 16418 19879 16604
+f 15690 25577 27437
+f 14821 18040 17635
+f 27643 3653 9628
+f 11387 9629 13346
+f 18247 17160 23052
+f 9847 27697 21702
+f 13346 9847 21702
+f 27697 27698 27667
+f 21702 27697 27667
+f 27698 27669 27668
+f 27667 27698 27668
+f 27670 27699 18940
+f 27668 27669 23174
+f 25494 25493 24463
+f 26244 17821 24393
+f 25607 25606 25928
+f 25493 24464 24463
+f 26830 26876 26122
+f 27103 5783 5782
+f 25484 26829 25789
+f 25698 25484 25789
+f 26829 26830 25790
+f 25789 26829 25790
+f 27700 27675 27701
+f 5964 27701 27675
+f 27702 27679 27675
+f 27700 27702 27675
+f 27703 27677 27679
+f 27702 27703 27679
+f 27703 27704 27680
+f 27677 27703 27680
+f 27705 27681 27680
+f 27704 27705 27680
+f 27705 27706 27682
+f 27681 27705 27682
+f 27707 27683 27682
+f 27706 27707 27682
+f 27708 27684 27683
+f 27707 27708 27683
+f 17489 17488 22956
+f 27708 27709 27684
+f 27528 26414 27295
+f 4813 27709 21804
+f 23920 23919 27560
+f 27416 26414 27528
+f 26414 26410 27295
+f 27560 27416 27528
+f 23444 25481 23445
+f 18555 18550 18551
+f 25371 23764 25059
+f 23763 18937 27270
+f 25751 18214 3334
+f 27685 27461 27460
+f 27646 27585 27147
+f 25160 27227 26863
+f 5393 4842 6800
+f 27465 25096 3343
+f 27311 17625 27479
+f 23926 27484 16352
+f 24586 27710 27533
+f 15954 24586 27533
+f 27385 27257 27711
+f 27361 27385 27711
+f 27712 27532 27468
+f 27035 27130 23925
+f 3342 27465 3343
+f 27495 25097 25096
+f 17534 17288 17289
+f 14275 5902 5901
+f 25226 24975 24974
+f 265 264 14352
+f 16559 26088 27538
+f 27688 17647 17646
+f 21912 24002 24003
+f 24002 25276 23314
+f 23296 17510 23269
+f 8921 24002 23314
+f 15845 24068 15846
+f 17512 17586 23270
+f 24068 26319 15846
+f 19079 17246 17245
+f 27018 27598 24688
+f 23703 23705 24797
+f 15750 14453 16651
+f 23882 16210 16209
+f 26955 25649 27100
+f 26862 16825 16824
+f 25557 26955 27100
+f 17991 15418 17496
+f 17288 27247 10310
+f 26800 26799 27164
+f 27303 26800 27164
+f 25558 25557 27115
+f 27303 27164 23570
+f 5654 5653 5771
+f 20411 23948 25273
+f 23312 16652 16253
+f 22279 6102 650
+f 25396 25447 8788
+f 26896 25156 25158
+f 14604 14603 17686
+f 24478 24555 24479
+f 25174 25173 26771
+f 27013 27109 27007
+f 26810 27694 25366
+f 14352 25695 25694
+f 24278 24277 23277
+f 23278 23309 23279
+f 27502 27567 26831
+f 25712 25877 27623
+f 26419 26418 26233
+f 24222 23285 23287
+f 27713 27714 27715
+f 23569 27303 23570
+f 5050 5049 25267
+f 15342 3160 15343
+f 17114 201 21793
+f 27716 26877 26991
+f 4189 22284 9120
+f 16243 17668 16244
+f 16242 16244 14235
+f 9117 10739 9847
+f 3869 3868 6338
+f 10739 27717 27697
+f 9847 10739 27697
+f 27717 27718 27698
+f 27697 27717 27698
+f 27718 27699 27669
+f 27698 27718 27669
+f 10979 10981 22596
+f 27669 27699 27670
+f 16112 26220 26221
+f 27132 16112 26221
+f 25790 26830 26122
+f 27132 26221 26122
+f 25941 26329 25942
+f 26876 27132 26122
+f 26034 25794 25795
+f 26972 25370 25369
+f 27701 27719 27700
+f 27720 27719 23464
+f 27721 27700 27719
+f 27720 27721 27719
+f 27722 27702 27700
+f 27721 27722 27700
+f 27722 27723 27703
+f 27702 27722 27703
+f 27723 27724 27704
+f 27703 27723 27704
+f 27724 27725 27705
+f 27704 27724 27705
+f 27725 27726 27706
+f 27705 27725 27706
+f 27727 27707 27706
+f 27726 27727 27706
+f 27728 27708 27707
+f 27727 27728 27707
+f 27729 27709 27708
+f 27728 27729 27708
+f 21804 27729 15112
+f 27729 21804 27709
+f 19196 24003 8923
+f 16455 17068 17067
+f 24459 23293 26072
+f 27395 26141 25047
+f 1541 17797 15043
+f 18169 2824 11224
+f 27128 16840 16842
+f 16828 1539 526
+f 6354 6293 6355
+f 27686 27685 27460
+f 26051 15394 15395
+f 17851 19764 19391
+f 24561 24560 27686
+f 27730 8216 16938
+f 23947 16223 25168
+f 22019 22018 16222
+f 27710 27687 27501
+f 27533 27710 27501
+f 27257 24614 24615
+f 27711 27257 24615
+f 20374 27497 16100
+f 16099 20374 16100
+f 27465 27495 25096
+f 27386 25099 25097
+f 27689 27561 27580
+f 27731 27689 27580
+f 15748 15818 15749
+f 17277 23947 27392
+f 16661 16867 23962
+f 16867 16560 27470
+f 25276 17510 23296
+f 23314 25276 23296
+f 27732 27733 2642
+f 17462 25534 26784
+f 26416 25791 26417
+f 23349 14987 14989
+f 26226 3409 26827
+f 26419 26324 26420
+f 17458 15752 17744
+f 22019 16222 27734
+f 21670 13202 13201
+f 27103 23569 23571
+f 26895 26787 26896
+f 24464 26916 26854
+f 18125 26901 21836
+f 2767 27477 2765
+f 27136 27161 26970
+f 8940 18559 18980
+f 26055 23965 25102
+f 17179 27234 17180
+f 26769 27181 26770
+f 15855 15549 15548
+f 16107 26938 27039
+f 14903 14902 24703
+f 27259 17567 17569
+f 23707 23277 23985
+f 17400 16348 16347
+f 16865 25337 25336
+f 24885 22679 24828
+f 27148 25235 25234
+f 27567 26419 26233
+f 24544 16865 25336
+f 27735 23854 23856
+f 27154 27117 25488
+f 24534 24276 14204
+f 14203 24534 14204
+f 3988 21579 20215
+f 15666 23808 15667
+f 19734 27452 19745
+f 26167 26087 10980
+f 27736 17114 21793
+f 25866 26901 18125
+f 27376 25174 25200
+f 23286 25338 24279
+f 24113 26087 26167
+f 24809 27568 24532
+f 26162 6914 6947
+f 27374 16843 27060
+f 3205 4185 10739
+f 9118 9117 9847
+f 4185 27737 27717
+f 10739 4185 27717
+f 27737 27738 27718
+f 27717 27737 27718
+f 27738 18941 27699
+f 27718 27738 27699
+f 27739 16943 27740
+f 27699 18941 18940
+f 27244 26124 27180
+f 27266 27019 26819
+f 26034 25795 26035
+f 26124 26125 27180
+f 17674 17673 27741
+f 21286 27742 25122
+f 21805 4814 4813
+f 27743 27741 17673
+f 27744 27720 17674
+f 27741 27744 17674
+f 27745 27721 27720
+f 27744 27745 27720
+f 27745 27746 27722
+f 27721 27745 27722
+f 27746 27747 27723
+f 27722 27746 27723
+f 27747 27748 27724
+f 27723 27747 27724
+f 27748 27749 27725
+f 27724 27748 27725
+f 27749 27750 27726
+f 27725 27749 27726
+f 27751 27727 27726
+f 27750 27751 27726
+f 27752 27728 27727
+f 27751 27752 27727
+f 27753 27729 27728
+f 27752 27753 27728
+f 27626 27624 27602
+f 27753 15112 27729
+f 26946 27754 26945
+f 8398 25308 8396
+f 6828 6923 6922
+f 15698 26942 15699
+f 23528 15666 15668
+f 27098 27122 25689
+f 27356 27121 10311
+f 27072 27142 25464
+f 27461 19917 27462
+f 24539 24538 25239
+f 23877 24064 23945
+f 14631 25049 20921
+f 24458 23294 23293
+f 16666 19370 16667
+f 27392 23947 27508
+f 16223 25169 25168
+f 27687 27656 27469
+f 25504 16937 27279
+f 27413 16097 15658
+f 26857 24393 24710
+f 27712 27468 27497
+f 20374 27712 27497
+f 27495 27386 25097
+f 25027 25026 25099
+f 27755 27731 27580
+f 27579 27755 27580
+f 25945 27061 14896
+f 27756 27757 22029
+f 23963 16867 27470
+f 16560 16559 27538
+f 17510 17512 23269
+f 23269 17512 23270
+f 27607 25237 24539
+f 26922 27607 24539
+f 27117 27091 25488
+f 16989 25569 25489
+f 23815 23817 27316
+f 27091 16989 25489
+f 25016 25015 18794
+f 23855 25016 18794
+f 27758 27759 27760
+f 26840 25827 26768
+f 21901 11089 6242
+f 16037 16240 24281
+f 27510 22710 27761
+f 26936 27138 26230
+f 25276 25835 17510
+f 18555 21472 17632
+f 19331 27078 19329
+f 26235 26814 26236
+f 25728 25726 19021
+f 26910 26891 26892
+f 25550 2861 2863
+f 27762 26168 26161
+f 9321 2862 19668
+f 26885 27637 26883
+f 24544 25336 25755
+f 17933 24544 25755
+f 26625 26543 26456
+f 24469 25947 8794
+f 25742 27154 25488
+f 27091 25489 25488
+f 24587 24534 14203
+f 24430 24587 14203
+f 27763 27762 26161
+f 27762 27764 26181
+f 26168 27762 26181
+f 27764 27765 26265
+f 18908 27766 18880
+f 27767 14343 14342
+f 27284 27242 27285
+f 24169 26057 24283
+f 18614 18615 25359
+f 25811 27331 25812
+f 26981 26982 17824
+f 17645 24559 17665
+f 3205 3655 3206
+f 15821 27259 15822
+f 3337 27768 27737
+f 4185 3337 27737
+f 27768 27769 27738
+f 27737 27768 27738
+f 27769 27770 18941
+f 27738 27769 18941
+f 27770 27771 18942
+f 18941 27770 18942
+f 27771 27772 27773
+f 14831 14833 15617
+f 27772 27774 27775
+f 27743 17673 27776
+f 27777 27743 27775
+f 27774 27777 27775
+f 27778 27741 27743
+f 27777 27778 27743
+f 27778 27779 27744
+f 27741 27778 27744
+f 27779 27780 27745
+f 27744 27779 27745
+f 27780 27781 27746
+f 27745 27780 27746
+f 27781 27782 27747
+f 27746 27781 27747
+f 27782 27783 27748
+f 27747 27782 27748
+f 27783 27784 27749
+f 27748 27783 27749
+f 27784 27785 27750
+f 27749 27784 27750
+f 27786 27751 27750
+f 27785 27786 27750
+f 23131 27752 27751
+f 27786 23131 27751
+f 23130 27753 27752
+f 23131 23130 27752
+f 27787 15112 27753
+f 22215 20179 459
+f 27244 27180 27127
+f 25942 26972 25369
+f 25103 23961 25638
+f 25370 26972 27788
+f 25345 25794 26834
+f 23961 24066 25638
+f 7475 20459 1019
+f 26867 23908 23907
+f 16841 27159 16842
+f 27285 27244 27127
+f 26850 26847 23779
+f 27235 26243 17180
+f 6379 18119 24991
+f 23774 7360 25964
+f 23950 27475 27508
+f 23947 25168 27508
+f 22786 7342 18298
+f 25223 25502 25224
+f 27540 27789 27790
+f 24691 11884 21609
+f 27532 23302 24968
+f 27007 27109 27008
+f 25862 24964 27395
+f 27282 25862 27395
+f 26775 27755 27579
+f 26776 26775 27579
+f 23920 27560 23809
+f 27078 19407 25945
+f 27200 26912 27482
+f 17176 17178 23257
+f 27406 27126 23836
+f 17642 24513 27105
+f 27214 27449 25873
+f 24623 27509 24624
+f 3818 16988 27791
+f 25569 16989 3817
+f 24618 24587 24430
+f 16825 24618 24430
+f 24616 24618 16825
+f 26862 24616 16825
+f 24392 16738 16740
+f 19003 27767 14342
+f 27792 27589 14343
+f 27767 27792 14343
+f 27793 27590 27589
+f 27792 27793 27589
+f 26834 23907 27181
+f 27793 27794 27591
+f 26907 26892 25807
+f 25199 27376 25200
+f 26907 26910 26892
+f 26319 25400 25218
+f 21794 15382 27795
+f 26778 27186 26779
+f 2861 27795 14705
+f 15722 27106 27060
+f 17933 25755 26992
+f 17934 17933 26992
+f 26417 26123 17449
+f 25927 25929 27503
+f 25210 24616 26862
+f 26878 25210 26862
+f 25278 25210 26878
+f 16819 25278 26878
+f 26181 27764 26265
+f 27765 27796 26266
+f 26265 27765 26266
+f 27797 26762 26266
+f 27590 27793 27591
+f 27794 27798 27609
+f 24466 25497 24467
+f 25487 16613 8786
+f 22084 27799 17238
+f 17665 24559 24561
+f 26774 27688 26088
+f 24860 25022 25021
+f 14822 17640 17852
+f 27285 27127 25865
+f 22229 25856 17309
+f 19824 15188 19825
+f 25330 27800 27769
+f 27768 25330 27769
+f 27800 27801 27770
+f 27769 27800 27770
+f 27801 27802 27771
+f 27770 27801 27771
+f 27802 27803 27772
+f 27771 27802 27772
+f 27803 27804 27774
+f 27772 27803 27774
+f 27805 27777 27774
+f 27804 27805 27774
+f 27806 27778 27777
+f 27805 27806 27777
+f 27806 27807 27779
+f 27778 27806 27779
+f 27807 27808 27780
+f 27779 27807 27780
+f 27808 27809 27781
+f 27780 27808 27781
+f 27809 27810 27782
+f 27781 27809 27782
+f 27810 27811 27783
+f 27782 27810 27783
+f 27812 27784 27783
+f 27811 27812 27783
+f 27813 27785 27784
+f 27812 27813 27784
+f 27814 27786 27785
+f 27813 27814 27785
+f 27815 23131 27786
+f 27814 27815 27786
+f 25330 27768 3337
+f 27815 23129 23131
+f 25449 8788 23335
+f 17817 18093 22393
+f 27816 26811 27787
+f 23130 27787 27753
+f 27475 27672 27392
+f 1945 213 17576
+f 2965 27263 25572
+f 26241 17254 25940
+f 25826 27119 27220
+f 10947 26067 11039
+f 19409 27061 19407
+f 26837 26839 26838
+f 27481 26777 25701
+f 25422 23547 25221
+f 23777 17402 17401
+f 16758 27735 16756
+f 27507 27473 23950
+f 27475 27392 27508
+f 24533 26219 22785
+f 4840 24533 22785
+f 24691 21609 17347
+f 27509 24691 17347
+f 25688 27372 25532
+f 10885 10986 18975
+f 25862 27282 27281
+f 27281 25047 27467
+f 26771 27013 27007
+f 23896 26033 23897
+f 25386 25388 27126
+f 23808 23920 23809
+f 23291 24625 23294
+f 17279 23313 27420
+f 27054 14883 14885
+f 23856 15023 23928
+f 24623 5947 27509
+f 27319 24471 24470
+f 23726 23727 27018
+f 21794 23275 23274
+f 23301 25416 16819
+f 27796 27797 26266
+f 27797 27817 26789
+f 16739 23527 24403
+f 26762 27797 26789
+f 27591 27794 27609
+f 27798 27818 27610
+f 27609 27798 27610
+f 27819 27612 27610
+f 8960 27141 16451
+f 25345 26834 25346
+f 27134 24561 27250
+f 25582 26907 25807
+f 16823 16822 25691
+f 26781 27151 26778
+f 27079 27301 27005
+f 27735 16758 26126
+f 8552 8550 12764
+f 26325 17352 24659
+f 25425 17934 26992
+f 27066 25425 26992
+f 16210 22717 23406
+f 25531 17450 17449
+f 25986 25364 23301
+f 25416 25278 16819
+f 27817 27820 26792
+f 26789 27817 26792
+f 27820 13478 13480
+f 26792 27820 13480
+f 27623 27260 25644
+f 27818 27819 27610
+f 27819 27821 27613
+f 17686 14603 27693
+f 26230 26232 27144
+f 27250 27686 27276
+f 24561 27686 27250
+f 27267 27175 27388
+f 25559 27150 26781
+f 15636 15635 24741
+f 27322 25420 3409
+f 15342 27822 25330
+f 15188 19824 11884
+f 27822 27823 27800
+f 25330 27822 27800
+f 27823 27824 27801
+f 27800 27823 27801
+f 27824 27825 27802
+f 27801 27824 27802
+f 27825 27826 27803
+f 27802 27825 27803
+f 27827 27804 27803
+f 27826 27827 27803
+f 27828 27805 27804
+f 27827 27828 27804
+f 27828 27829 27806
+f 27805 27828 27806
+f 27829 27830 27807
+f 27806 27829 27807
+f 27830 27831 27808
+f 27807 27830 27808
+f 27831 27832 27809
+f 27808 27831 27809
+f 27832 27833 27810
+f 27809 27832 27810
+f 27833 27834 27811
+f 27810 27833 27811
+f 27835 27812 27811
+f 27834 27835 27811
+f 27836 27813 27812
+f 27835 27836 27812
+f 27837 27814 27813
+f 27836 27837 27813
+f 27838 27815 27814
+f 27837 27838 27814
+f 27839 23129 27815
+f 27838 27839 27815
+f 26754 27816 27787
+f 27839 26753 23129
+f 27840 27816 26754
+f 26753 27840 26754
+f 27840 27841 27842
+f 27840 27842 27816
+f 15215 985 15727
+f 17785 21757 18774
+f 25662 17805 17806
+f 15727 984 15783
+f 8302 14438 16955
+f 25956 3334 3336
+f 15820 15822 5932
+f 15822 27245 5932
+f 24711 27843 13478
+f 985 984 15727
+f 27256 27472 27507
+f 27473 27475 23950
+f 18062 18061 26219
+f 24533 18062 26219
+f 27509 17347 17346
+f 24624 27509 17346
+f 27159 16415 16417
+f 27024 25172 27376
+f 23827 16339 25944
+f 16339 23901 25944
+f 23837 27112 23838
+f 15549 15855 17789
+f 27129 26785 27483
+f 25392 27305 27484
+f 24625 27420 23259
+f 27844 27606 27845
+f 23893 17401 23894
+f 17402 26796 17403
+f 24223 24352 27358
+f 18624 3325 11788
+f 26754 27787 23130
+f 23812 24116 23813
+f 4015 9004 9003
+f 25687 25686 26887
+f 19733 15604 17610
+f 27612 27819 27613
+f 27846 27631 27613
+f 26933 27583 26887
+f 26902 25637 26925
+f 27276 27460 27326
+f 27686 27460 27276
+f 16536 26784 24435
+f 27151 27186 26778
+f 25247 9575 25681
+f 9021 21351 3973
+f 24531 24343 25218
+f 25400 24531 25218
+f 24755 20684 27348
+f 25576 25425 27066
+f 27224 26866 27057
+f 25272 25273 25274
+f 16911 25364 25986
+f 25985 16911 25986
+f 24508 15547 25608
+f 23885 25028 27655
+f 27342 25246 27047
+f 26831 26233 26234
+f 27821 27846 27613
+f 27847 27632 27631
+f 26233 26418 23954
+f 27048 23753 15924
+f 27293 17069 27294
+f 27460 27462 27326
+f 27598 27018 24663
+f 16102 27149 25559
+f 18107 13098 12800
+f 27638 25144 26142
+f 15344 27848 27822
+f 15342 15344 27822
+f 27848 27849 27823
+f 27822 27848 27823
+f 27849 27850 27824
+f 27823 27849 27824
+f 27850 27851 27825
+f 27824 27850 27825
+f 27851 27852 27826
+f 27825 27851 27826
+f 27852 27853 27827
+f 27826 27852 27827
+f 27853 27854 27828
+f 27827 27853 27828
+f 27854 27855 27829
+f 27828 27854 27829
+f 27855 27856 27830
+f 27829 27855 27830
+f 27856 27857 27831
+f 27830 27856 27831
+f 27857 27858 27832
+f 27831 27857 27832
+f 27858 27859 27833
+f 27832 27858 27833
+f 27860 27834 27833
+f 27859 27860 27833
+f 27861 27835 27834
+f 27860 27861 27834
+f 27862 27836 27835
+f 27861 27862 27835
+f 27863 27837 27836
+f 27862 27863 27836
+f 27864 27838 27837
+f 27863 27864 27837
+f 27865 27839 27838
+f 27864 27865 27838
+f 27866 26753 27839
+f 27865 27866 27839
+f 27867 27840 26753
+f 27866 27867 26753
+f 27868 27842 27841
+f 27867 27841 27840
+f 25487 24167 16613
+f 24444 24895 24445
+f 19492 26900 27256
+f 27472 27473 27507
+f 25092 16950 26944
+f 16952 26900 19492
+f 27869 26898 22165
+f 16950 25092 25091
+f 6802 17885 17884
+f 27088 25394 25393
+f 27869 22165 16314
+f 27268 25393 27496
+f 25029 14486 17282
+f 17283 23316 17284
+f 24624 17346 15921
+f 27110 24624 15921
+f 16536 27644 17462
+f 27112 27110 23838
+f 23875 23877 24010
+f 27474 27672 27475
+f 4156 15690 27437
+f 4470 25694 25959
+f 27367 17627 27129
+f 26785 25392 27483
+f 26970 23383 12974
+f 24530 25427 25282
+f 27493 24610 24755
+f 20684 25576 27348
+f 24352 24621 27358
+f 25341 23823 26995
+f 26899 16951 16950
+f 26917 10522 26918
+f 14693 13071 3213
+f 27321 27044 9203
+f 16589 2941 2940
+f 27846 27847 27631
+f 24713 27214 17569
+f 27870 27633 27632
+f 27462 17069 27293
+f 24589 26960 24702
+f 27297 27210 17253
+f 27326 27462 27293
+f 23527 23702 24404
+f 19174 20328 23341
+f 19734 22410 27452
+f 20551 15118 20586
+f 24530 25282 24343
+f 17627 26785 27129
+f 27348 25576 27066
+f 24531 24530 24343
+f 17302 17301 27599
+f 24610 20684 24755
+f 25364 25416 23301
+f 25222 25224 8806
+f 8052 7959 7958
+f 23258 24657 25477
+f 27317 25657 25658
+f 374 4471 1700
+f 27847 27870 27632
+f 26788 15729 15731
+f 27871 27634 27633
+f 16626 16001 1271
+f 27054 14885 23354
+f 16487 16645 6922
+f 25156 15731 25157
+f 27150 27151 26781
+f 27149 27150 25559
+f 13098 13100 12800
+f 23724 17648 23910
+f 16644 27872 27848
+f 15344 16644 27848
+f 27872 27873 27849
+f 27848 27872 27849
+f 27873 27874 27850
+f 27849 27873 27850
+f 27874 27875 27851
+f 27850 27874 27851
+f 27876 27852 27851
+f 27875 27876 27851
+f 27876 27877 27853
+f 27852 27876 27853
+f 27877 27878 27854
+f 27853 27877 27854
+f 27878 27879 27855
+f 27854 27878 27855
+f 27879 27880 27856
+f 27855 27879 27856
+f 27880 27881 27857
+f 27856 27880 27857
+f 27881 27882 27858
+f 27857 27881 27858
+f 27882 27883 27859
+f 27858 27882 27859
+f 27884 27860 27859
+f 27883 27884 27859
+f 27885 27861 27860
+f 27884 27885 27860
+f 27886 27862 27861
+f 27885 27886 27861
+f 27887 27863 27862
+f 27886 27887 27862
+f 27888 27864 27863
+f 27887 27888 27863
+f 27889 27865 27864
+f 27888 27889 27864
+f 27890 27866 27865
+f 27889 27890 27865
+f 27891 27867 27866
+f 27890 27891 27866
+f 27892 27841 27867
+f 27891 27892 27867
+f 14804 6705 6209
+f 6384 27892 6385
+f 26944 16952 19492
+f 26900 27472 27256
+f 27339 26848 25796
+f 27262 17533 17534
+f 25512 27267 27388
+f 25144 17642 17641
+f 4951 27362 7865
+f 27173 27389 27388
+f 27893 27894 24586
+f 19787 21893 9944
+f 17403 26796 26139
+f 25358 27040 26957
+f 27110 15921 15920
+f 23838 27110 15920
+f 23549 27895 27896
+f 25738 16535 25739
+f 24928 25643 25108
+f 24694 26134 26922
+f 4471 4470 25959
+f 25694 15886 15885
+f 27479 17627 27367
+f 26941 27479 27367
+f 25699 25791 26416
+f 23908 25759 23909
+f 24608 24610 27493
+f 27691 24608 27493
+f 23961 15887 24066
+f 24461 24535 24462
+f 15982 26988 15983
+f 26074 25482 25484
+f 1700 4471 23964
+f 27278 3341 15649
+f 26899 26898 27869
+f 16840 24402 27033
+f 27870 27871 27633
+f 27897 27658 27634
+f 25969 25968 27898
+f 17598 467 922
+f 25465 27208 25641
+f 17069 17068 27294
+f 25985 25986 25860
+f 27173 26223 26222
+f 7860 24329 21413
+f 27899 26445 27900
+f 8217 27730 9635
+f 7860 24328 24329
+f 24065 27024 23757
+f 17254 16101 25940
+f 25427 18933 25428
+f 27502 26831 17450
+f 24611 24608 27691
+f 27901 24611 27691
+f 27562 26053 26054
+f 25270 23528 23550
+f 8140 2446 2447
+f 20683 26320 25424
+f 7865 15953 15952
+f 15983 26988 25105
+f 27871 27897 27634
+f 27658 27897 27902
+f 26869 27274 26870
+f 23787 26810 23788
+f 27056 16487 6923
+f 27208 27215 25641
+f 17253 27210 16102
+f 17252 27297 17253
+f 6925 14696 27056
+f 26989 26786 25106
+f 5493 5495 5602
+f 27361 27711 27893
+f 27903 27872 16644
+f 16645 27903 16644
+f 27903 27904 27873
+f 27872 27903 27873
+f 27904 27905 27874
+f 27873 27904 27874
+f 27906 27875 27874
+f 27905 27906 27874
+f 27906 27907 27876
+f 27875 27906 27876
+f 27907 27908 27877
+f 27876 27907 27877
+f 27908 27909 27878
+f 27877 27908 27878
+f 27909 27910 27879
+f 27878 27909 27879
+f 27910 27911 27880
+f 27879 27910 27880
+f 27911 27912 27881
+f 27880 27911 27881
+f 27912 27913 27882
+f 27881 27912 27882
+f 27913 27914 27883
+f 27882 27913 27883
+f 27915 27884 27883
+f 27914 27915 27883
+f 27916 27885 27884
+f 27915 27916 27884
+f 27917 27886 27885
+f 27916 27917 27885
+f 27918 27887 27886
+f 27917 27918 27886
+f 27919 27888 27887
+f 27918 27919 27887
+f 27920 27889 27888
+f 27919 27920 27888
+f 27921 27890 27889
+f 27920 27921 27889
+f 27922 27891 27890
+f 27921 27922 27890
+f 27923 27892 27891
+f 27922 27923 27891
+f 27924 25193 15172
+f 27923 6385 27892
+f 26898 16950 25091
+f 16950 16952 26944
+f 10522 12764 26918
+f 24465 26854 27334
+f 23838 15920 27925
+f 23839 23838 27925
+f 24460 24462 27926
+f 27927 24460 27926
+f 27564 26054 27928
+f 27093 27564 27928
+f 24795 14851 26967
+f 26968 24795 26967
+f 26967 14851 27092
+f 14851 14853 27092
+f 23811 16241 16240
+f 24543 23548 22872
+f 26134 27607 26922
+f 19329 27078 19656
+f 25959 25694 15885
+f 15887 24274 24019
+f 18207 18209 26940
+f 27089 18207 26940
+f 18213 16471 18214
+f 26978 26999 27000
+f 26050 24611 27901
+f 19706 26050 27901
+f 16691 26055 26056
+f 27220 27111 27145
+f 19912 19911 18043
+f 26764 17523 18044
+f 25105 26989 25106
+f 17180 26828 17181
+f 17497 17496 15418
+f 26048 25578 27542
+f 8127 8129 21506
+f 27560 27528 23805
+f 26225 26224 27153
+f 25175 25832 26169
+f 23883 27074 25830
+f 25580 25583 25242
+f 21836 17839 18125
+f 21151 7859 25086
+f 26126 16035 27324
+f 19704 19706 25835
+f 24861 25021 25645
+f 27144 26232 27174
+f 27685 27055 27461
+f 27055 16378 27461
+f 21151 25409 10426
+f 26445 24943 26446
+f 24943 26445 27899
+f 27542 25580 25242
+f 12962 24328 14980
+f 10180 10100 10099
+f 26772 26771 27084
+f 60 56 27929
+f 25560 24532 4842
+f 16416 11543 16417
+f 27511 5076 16933
+f 26238 26334 26336
+f 27215 27375 24011
+f 27358 23095 16611
+f 25205 27480 17800
+f 26244 26243 17821
+f 27930 27081 27336
+f 23899 17343 27081
+f 17511 27691 17584
+f 26798 14842 27154
+f 25912 15698 27535
+f 15107 15109 5264
+f 15731 25209 25157
+f 27231 27232 27124
+f 27210 27149 16102
+f 25275 27269 17252
+f 26846 23952 26963
+f 9796 24378 13379
+f 27931 16645 16487
+f 27056 27931 16487
+f 27932 27903 16645
+f 27931 27932 16645
+f 27932 27933 27904
+f 27903 27932 27904
+f 27934 27905 27904
+f 27933 27934 27904
+f 27935 27906 27905
+f 27934 27935 27905
+f 27935 27936 27907
+f 27906 27935 27907
+f 27936 27937 27908
+f 27907 27936 27908
+f 27937 27938 27909
+f 27908 27937 27909
+f 27938 27939 27910
+f 27909 27938 27910
+f 27939 27940 27911
+f 27910 27939 27911
+f 27940 27941 27912
+f 27911 27940 27912
+f 27941 27942 27913
+f 27912 27941 27913
+f 27942 27943 27914
+f 27913 27942 27914
+f 27944 27915 27914
+f 27943 27944 27914
+f 27945 27916 27915
+f 27944 27945 27915
+f 27946 27917 27916
+f 27945 27946 27916
+f 27947 27918 27917
+f 27946 27947 27917
+f 27948 27919 27918
+f 27947 27948 27918
+f 27949 27920 27919
+f 27948 27949 27919
+f 27950 27921 27920
+f 27949 27950 27920
+f 27951 27922 27921
+f 27950 27951 27921
+f 27952 27923 27922
+f 27951 27952 27922
+f 6097 6380 25491
+f 27952 21630 27923
+f 80 54 22828
+f 26898 25091 22165
+f 26854 26856 27334
+f 15728 15727 15784
+f 24462 23839 27925
+f 27926 24462 27925
+f 27004 26968 26966
+f 5637 5636 17542
+f 26873 26872 23288
+f 24311 25262 25661
+f 15094 16099 16098
+f 26263 18267 18268
+f 23302 27712 5818
+f 22717 26338 23406
+f 27622 26899 27869
+f 23308 20750 23882
+f 8789 23882 23881
+f 26996 23366 23812
+f 25575 27035 24020
+f 24019 25575 24020
+f 9574 27039 25175
+f 25817 25033 25035
+f 26415 25913 26029
+f 27592 27608 25749
+f 25421 17443 25422
+f 27953 27655 27844
+f 25153 25573 24274
+f 15887 24019 24066
+f 25559 26781 25640
+f 26147 26146 17806
+f 24798 25206 17582
+f 7859 21151 21150
+f 26322 26321 23845
+f 24546 6247 6246
+f 14842 14844 27154
+f 8599 8601 9202
+f 20122 5783 27103
+f 17462 17464 25535
+f 26965 27046 26224
+f 16751 27605 27581
+f 1507 6799 6798
+f 18446 1992 18427
+f 17266 27234 17179
+f 23326 23329 25279
+f 25419 23326 25279
+f 23569 27103 5782
+f 10377 27364 24013
+f 27397 18559 18446
+f 26140 26797 26836
+f 16107 26918 26938
+f 26145 27055 27685
+f 27519 27553 17452
+f 25410 23230 25411
+f 24560 26145 27685
+f 27954 27955 27956
+f 2940 12165 15369
+f 48 47 22238
+f 27957 15717 27958
+f 25641 24011 26239
+f 25481 25480 24756
+f 25855 25854 27415
+f 26780 25855 27415
+f 16608 27442 27196
+f 16613 16608 27196
+f 16608 16607 27442
+f 16607 27414 27442
+f 15885 15887 23961
+f 25392 25391 27305
+f 21730 23532 5508
+f 17813 3137 24219
+f 18061 17846 17801
+f 23875 24010 24060
+f 25606 17267 27031
+f 27060 27108 27593
+f 27544 27569 21654
+f 25736 25493 25737
+f 27123 24056 27101
+f 24559 26144 24560
+f 26325 17068 16454
+f 27269 27297 17252
+f 23340 27056 14696
+f 16352 15665 23727
+f 27959 27931 27056
+f 23340 27959 27056
+f 27960 27932 27931
+f 27959 27960 27931
+f 27961 27933 27932
+f 27960 27961 27932
+f 27962 27934 27933
+f 27961 27962 27933
+f 27963 27935 27934
+f 27962 27963 27934
+f 27963 27964 27936
+f 27935 27963 27936
+f 27964 27965 27937
+f 27936 27964 27937
+f 27965 27966 27938
+f 27937 27965 27938
+f 27966 27967 27939
+f 27938 27966 27939
+f 27967 27968 27940
+f 27939 27967 27940
+f 27968 27969 27941
+f 27940 27968 27941
+f 27969 27970 27942
+f 27941 27969 27942
+f 27971 27943 27942
+f 27970 27971 27942
+f 27971 27972 27944
+f 27943 27971 27944
+f 27973 27945 27944
+f 27972 27973 27944
+f 27974 27946 27945
+f 27973 27974 27945
+f 27975 27947 27946
+f 27974 27975 27946
+f 27976 27948 27947
+f 27975 27976 27947
+f 27977 27949 27948
+f 27976 27977 27948
+f 27978 27950 27949
+f 27977 27978 27949
+f 27979 27951 27950
+f 27978 27979 27950
+f 27980 27952 27951
+f 27979 27980 27951
+f 5975 22464 4325
+f 27980 21631 27952
+f 15921 25703 15922
+f 25393 25395 27496
+f 7058 17244 17246
+f 27362 27893 15953
+f 26054 24460 27927
+f 27928 26054 27927
+f 25477 24657 20155
+f 17159 17852 3725
+f 27395 22866 26141
+f 24854 16556 16397
+f 27568 27981 26997
+f 24973 25862 27281
+f 25533 25536 14897
+f 26033 26035 23897
+f 17221 25478 25479
+f 24670 24669 26873
+f 26999 27618 5948
+f 27537 23310 23284
+f 27035 23925 24664
+f 23727 23778 24660
+f 25606 27031 25928
+f 26791 23101 23100
+f 26336 26335 27646
+f 27216 25660 26146
+f 25855 17307 25856
+f 12098 10140 10458
+f 24071 16695 23352
+f 27305 27304 24958
+f 23748 23750 24221
+f 5477 7737 5478
+f 27531 27562 27564
+f 23750 24163 24221
+f 4795 9134 4793
+f 25854 25856 17355
+f 24694 26922 25235
+f 27108 27036 27275
+f 8785 23814 8786
+f 27374 27060 27593
+f 25464 27142 25465
+f 27085 26034 26033
+f 18946 27767 19003
+f 26067 26066 27032
+f 16822 16821 11556
+f 27593 27108 27275
+f 18946 27766 27767
+f 27519 17452 21160
+f 27508 24038 23951
+f 17665 17224 17645
+f 25145 24511 24513
+f 18446 25332 27397
+f 27079 27005 26934
+f 27982 17706 26145
+f 27766 27983 27792
+f 27767 27766 27792
+f 27688 24862 17647
+f 27093 27928 25809
+f 27593 27275 17763
+f 21079 6788 26842
+f 7937 18608 19360
+f 12800 13100 709
+f 25331 27732 10426
+f 25410 25331 10426
+f 5105 2642 27733
+f 27732 2642 10426
+f 18204 27413 15998
+f 26771 27007 27084
+f 26780 27415 27414
+f 16607 26780 27414
+f 25189 25122 27742
+f 26938 16590 25832
+f 25512 27388 22151
+f 27039 26938 25832
+f 27304 26822 24958
+f 25094 8787 23363
+f 23755 23804 24058
+f 16253 16399 16254
+f 26144 27982 26145
+f 2841 25717 2842
+f 27983 27984 27793
+f 27792 27983 27793
+f 27984 27985 27794
+f 26797 26837 26836
+f 26859 26890 25610
+f 6787 26842 6788
+f 27142 27208 25465
+f 25661 17805 25662
+f 27238 27269 25275
+f 25411 25334 25331
+f 20229 20209 17802
+f 20328 27959 23340
+f 23341 20328 23340
+f 19618 27960 27959
+f 20328 19618 27959
+f 27986 27961 27960
+f 19618 27986 27960
+f 27987 27962 27961
+f 27986 27987 27961
+f 27987 27988 27963
+f 27962 27987 27963
+f 27988 27989 27964
+f 27963 27988 27964
+f 27989 27990 27965
+f 27964 27989 27965
+f 27990 27991 27966
+f 27965 27990 27966
+f 27991 27992 27967
+f 27966 27991 27967
+f 27992 27993 27968
+f 27967 27992 27968
+f 27993 27994 27969
+f 27968 27993 27969
+f 27994 27995 27970
+f 27969 27994 27970
+f 27995 27996 27971
+f 27970 27995 27971
+f 27996 27997 27972
+f 27971 27996 27972
+f 27998 27973 27972
+f 27997 27998 27972
+f 27999 27974 27973
+f 27998 27999 27973
+f 28000 27975 27974
+f 27999 28000 27974
+f 28001 27976 27975
+f 28000 28001 27975
+f 28002 27977 27976
+f 28001 28002 27976
+f 28003 27978 27977
+f 28002 28003 27977
+f 28004 27979 27978
+f 28003 28004 27978
+f 27611 27980 27979
+f 28004 27611 27979
+f 15678 23927 22373
+f 18523 21761 28005
+f 14840 25920 14841
+f 27279 27278 15649
+f 7865 27362 15953
+f 15953 27893 24586
+f 14853 27564 27093
+f 27092 14853 27093
+f 17637 14213 17638
+f 28006 16047 25044
+f 26075 26773 27506
+f 16535 16534 25739
+f 27755 23725 27731
+f 23906 27689 27731
+f 23905 23267 8924
+f 23910 23906 27731
+f 25222 23266 25223
+f 23266 25222 8805
+f 8792 8930 25500
+f 8791 8792 25500
+f 27018 23727 24660
+f 23725 23910 27731
+f 17992 15419 17991
+f 18875 18840 18841
+f 24536 23837 23839
+f 15690 3594 25577
+f 27017 27095 25093
+f 23820 23814 8785
+f 24347 27415 17355
+f 20750 5549 22717
+f 27068 23892 27040
+f 28007 18270 18122
+f 25166 19751 19717
+f 25707 25706 25938
+f 27010 27246 24961
+f 15367 5494 6058
+f 27793 27984 27794
+f 27985 28008 27798
+f 27794 27985 27798
+f 27655 27606 27844
+f 28008 28009 27818
+f 15822 27259 27245
+f 27125 25651 27193
+f 25686 27006 26886
+f 26832 26921 26412
+f 4926 3770 1363
+f 25363 23304 25419
+f 23777 26994 25036
+f 23817 24654 25657
+f 24119 24225 24168
+f 27343 27221 25738
+f 27221 27222 25738
+f 6257 6536 27320
+f 21912 24003 19196
+f 17682 13574 14036
+f 18208 27311 18209
+f 23354 25562 26816
+f 23355 23354 26816
+f 27798 28008 27818
+f 28010 27819 27818
+f 27073 27184 27074
+f 25466 25465 25642
+f 16258 26864 17494
+f 27299 17534 27177
+f 14275 5901 5938
+f 19408 19751 25167
+f 20793 22079 27732
+f 25331 20793 27732
+f 22079 5106 27733
+f 22079 27733 27732
+f 23891 23893 23895
+f 9202 26827 8599
+f 27309 27343 23849
+f 23848 27309 23849
+f 27024 27023 25172
+f 21794 27795 2861
+f 24911 24862 27688
+f 26774 24911 27688
+f 27111 23898 27145
+f 23806 27295 25480
+f 23925 23726 24687
+f 24662 24661 26776
+f 23884 25830 26840
+f 25827 27145 26768
+f 28009 28010 27818
+f 28011 27821 27819
+f 27078 19331 19407
+f 17402 23777 25036
+f 16990 26338 17281
+f 17265 27195 27234
+f 26965 27193 27045
+f 23272 20259 14987
+f 27246 27238 25275
+f 27237 27238 27246
+f 23892 26357 27040
+f 26940 18209 26941
+f 19019 14605 22826
+f 19079 19617 19080
+f 26171 25507 26364
+f 25470 25469 24329
+f 19617 27986 19618
+f 25577 25019 25018
+f 19617 17245 27987
+f 27986 19617 27987
+f 17245 27636 27988
+f 27987 17245 27988
+f 27636 28012 27989
+f 27988 27636 27989
+f 28012 28013 27990
+f 27989 28012 27990
+f 28013 28014 27991
+f 27990 28013 27991
+f 28014 28015 27992
+f 27991 28014 27992
+f 28015 28016 27993
+f 27992 28015 27993
+f 28016 28017 27994
+f 27993 28016 27994
+f 28017 28018 27995
+f 27994 28017 27995
+f 28018 28019 27996
+f 27995 28018 27996
+f 28020 27997 27996
+f 28019 28020 27996
+f 28021 27998 27997
+f 28020 28021 27997
+f 28022 27999 27998
+f 28021 28022 27998
+f 28023 28000 27999
+f 28022 28023 27999
+f 28024 28001 28000
+f 28023 28024 28000
+f 28025 28002 28001
+f 28024 28025 28001
+f 28026 28003 28002
+f 28025 28026 28002
+f 28027 28004 28003
+f 28026 28027 28003
+f 28028 27611 28004
+f 28027 28028 28004
+f 24255 21280 24265
+f 22373 27524 22371
+f 18682 3031 22799
+f 27925 15920 25802
+f 27894 28029 27710
+f 24586 27894 27710
+f 25161 24795 26968
+f 25162 25161 26968
+f 4395 24856 28030
+f 5818 27712 20374
+f 22281 25935 27038
+f 17256 17254 26241
+f 23905 8924 27689
+f 23906 23905 27689
+f 9658 19037 12166
+f 23335 8788 8790
+f 27564 27562 26054
+f 8789 23308 23882
+f 25806 25808 25700
+f 25798 25916 25483
+f 18441 18443 24886
+f 25861 25860 25163
+f 23341 19360 19174
+f 23771 23775 23828
+f 1379 1378 2638
+f 27692 28031 28032
+f 27308 27309 23848
+f 25643 27308 23848
+f 24543 16865 24544
+f 23714 26779 25215
+f 27146 23548 24543
+f 24542 27146 24543
+f 25357 27068 25358
+f 27193 26977 27045
+f 3158 3299 3159
+f 25355 17441 25421
+f 28010 28011 27819
+f 28033 27846 27821
+f 23818 25151 27160
+f 26049 26869 27133
+f 24011 27375 16765
+f 26456 26455 26625
+f 17760 2597 27283
+f 20758 24996 20814
+f 25563 16048 27288
+f 5771 6212 5654
+f 25349 17188 17189
+f 22149 27389 27183
+f 15665 23833 23778
+f 26802 17188 25349
+f 14661 14392 14394
+f 5602 15441 5603
+f 9795 9796 16881
+f 23849 27343 25738
+f 4949 4950 7866
+f 25655 27067 25357
+f 16493 14486 25029
+f 24795 15844 14851
+f 17443 27114 25422
+f 17450 26832 17451
+f 28011 28033 27821
+f 28034 27847 27846
+f 17796 23000 22876
+f 9704 9703 16317
+f 26788 15731 25156
+f 2081 662 234
+f 6719 15873 4388
+f 24275 23365 23364
+f 27742 22079 20793
+f 7952 18207 266
+f 21286 21287 27742
+f 27742 21287 22079
+f 27018 24660 24663
+f 234 656 2081
+f 27365 27308 25643
+f 23264 27365 25643
+f 27074 27184 25825
+f 23890 23892 27068
+f 27471 27645 27472
+f 9944 21893 9945
+f 26827 9202 9201
+f 19787 9944 10015
+f 17192 27471 26900
+f 26226 26225 27322
+f 13934 15367 27261
+f 26225 27153 27371
+f 28033 28034 27846
+f 27442 25870 24439
+f 28035 27870 27847
+f 27375 17763 16765
+f 25695 26940 25153
+f 26977 26897 26765
+f 21301 21302 23000
+f 27010 27237 27246
+f 27011 27179 25705
+f 24012 24014 25019
+f 27635 17245 17244
+f 27322 26225 27371
+f 27472 27645 27473
+f 14384 10233 5929
+f 27693 23204 17684
+f 16575 5458 17638
+f 16591 20814 26804
+f 12865 5479 10590
+f 23825 3334 25879
+f 16047 27288 16048
+f 14887 18113 6210
+f 27635 28036 28012
+f 27636 27635 28012
+f 28036 28037 28013
+f 28012 28036 28013
+f 28037 28038 28014
+f 28013 28037 28014
+f 28038 28039 28015
+f 28014 28038 28015
+f 28039 28040 28016
+f 28015 28039 28016
+f 28040 28041 28017
+f 28016 28040 28017
+f 28041 28042 28018
+f 28017 28041 28018
+f 28042 28043 28019
+f 28018 28042 28019
+f 28044 28020 28019
+f 28043 28044 28019
+f 28045 28021 28020
+f 28044 28045 28020
+f 28046 28022 28021
+f 28045 28046 28021
+f 28047 28023 28022
+f 28046 28047 28022
+f 28048 28024 28023
+f 28047 28048 28023
+f 28049 28025 28024
+f 28048 28049 28024
+f 28050 28026 28025
+f 28049 28050 28025
+f 28051 28027 28026
+f 28050 28051 28026
+f 28052 28028 28027
+f 28051 28052 28027
+f 27524 22373 28028
+f 28052 27524 28028
+f 25919 17799 14841
+f 17830 25040 25039
+f 28029 28053 27687
+f 27710 28029 27687
+f 15983 25105 25107
+f 28054 15983 25107
+f 3627 6809 3628
+f 2904 2906 3381
+f 23757 27024 27376
+f 25930 25707 25931
+f 23267 8805 8924
+f 23267 23266 8805
+f 17301 25859 27599
+f 28055 26809 23206
+f 27614 17530 17532
+f 20184 20209 20229
+f 27324 24281 24280
+f 14486 16493 16492
+f 27094 25640 23767
+f 17568 23720 24713
+f 25152 26981 17824
+f 25640 23713 23767
+f 23850 25739 24436
+f 25577 24012 25019
+f 23902 27438 23263
+f 27384 27365 23264
+f 27368 24510 26408
+f 25830 25827 26840
+f 24309 16345 10956
+f 8924 8807 27561
+f 27153 16972 27379
+f 27371 27153 27379
+f 23711 27380 27379
+f 16972 23711 27379
+f 28034 28035 27847
+f 23919 27416 27560
+f 28056 27871 27870
+f 6209 8548 14887
+f 26357 26049 27133
+f 4189 9120 9022
+f 2121 3714 16715
+f 28057 28058 28059
+f 28060 28057 25335
+f 12590 14148 27673
+f 2941 16589 9529
+f 1078 323 4157
+f 15366 26864 15367
+f 23772 28061 23773
+f 23712 27405 27380
+f 28062 28063 25745
+f 27302 2500 2502
+f 27222 16535 25738
+f 27095 23820 25093
+f 24510 26919 26408
+f 23760 23762 12650
+f 14852 27531 14853
+f 27644 17463 17462
+f 23711 23712 27380
+f 23712 27506 27418
+f 28035 28056 27870
+f 28064 28065 28066
+f 26927 26902 26904
+f 26902 26925 26903
+f 27300 27262 27299
+f 25796 26844 25797
+f 27168 27237 27010
+f 25705 27178 25706
+f 23311 18332 18334
+f 7058 17193 17244
+f 27338 11082 18904
+f 21363 25062 21364
+f 25164 16818 23770
+f 24014 16614 25219
+f 23901 27436 23902
+f 27438 27384 23263
+f 26903 11148 27195
+f 27496 25395 26953
+f 27372 25362 25312
+f 9306 16204 9307
+f 27405 23712 27418
+f 27506 25444 27424
+f 27418 27506 27424
+f 25444 25446 27447
+f 27424 25444 27447
+f 28056 28064 27871
+f 17998 1702 28067
+f 26027 27481 25701
+f 25692 28068 27012
+f 17534 17289 27177
+f 27263 27169 26920
+f 27178 27168 25706
+f 27120 27298 27011
+f 8380 1540 1542
+f 27349 26780 16607
+f 25446 27417 27450
+f 23854 27735 20020
+f 23339 22151 25250
+f 6588 22349 3926
+f 23821 23823 25341
+f 25658 24466 24468
+f 2294 2480 2447
+f 20813 19340 12939
+f 17244 20364 27635
+f 18113 14887 7328
+f 20364 28069 28036
+f 27635 20364 28036
+f 28069 28070 28037
+f 28036 28069 28037
+f 28070 28071 28038
+f 28037 28070 28038
+f 28071 28072 28039
+f 28038 28071 28039
+f 28072 28073 28040
+f 28039 28072 28040
+f 28073 28074 28041
+f 28040 28073 28041
+f 28074 28075 28042
+f 28041 28074 28042
+f 28075 28076 28043
+f 28042 28075 28043
+f 28077 28044 28043
+f 28076 28077 28043
+f 28078 28045 28044
+f 28077 28078 28044
+f 28079 28046 28045
+f 28078 28079 28045
+f 28080 28047 28046
+f 28079 28080 28046
+f 28081 28048 28047
+f 28080 28081 28047
+f 28082 28049 28048
+f 28081 28082 28048
+f 28083 28050 28049
+f 28082 28083 28049
+f 28084 28051 28050
+f 28083 28084 28050
+f 28085 28052 28051
+f 28084 28085 28051
+f 13818 27524 28052
+f 28085 13818 28052
+f 4965 4967 13819
+f 13818 13819 27524
+f 28053 28054 27656
+f 24757 27623 25644
+f 15957 15983 28054
+f 28053 15957 28054
+f 8788 25447 8789
+f 25047 26141 5395
+f 23842 3343 25098
+f 25097 25101 25098
+f 23266 8791 25223
+f 25223 8791 25500
+f 28057 28060 28058
+f 27014 23722 27034
+f 13549 13661 14214
+f 27176 26140 26911
+f 20459 27116 27321
+f 4157 27436 23901
+f 25037 27074 23883
+f 21243 3134 21077
+f 27242 27244 27285
+f 24067 26318 26319
+f 27243 26124 27244
+f 23818 23717 25151
+f 23263 27384 23264
+f 26796 17402 26939
+f 24147 27256 27507
+f 10376 17302 27364
+f 17263 17543 25692
+f 25688 25204 27372
+f 27447 25446 27450
+f 27417 27443 27451
+f 27450 27417 27451
+f 27443 27052 27478
+f 27282 27395 25047
+f 23293 23260 26072
+f 27451 27443 27478
+f 27370 25203 25202
+f 25159 25160 25095
+f 14148 12590 13865
+f 8808 6786 8602
+f 19408 25167 19409
+f 23427 26804 20814
+f 27052 25611 27492
+f 23846 26857 24710
+f 6615 6475 15343
+f 19121 490 20716
+f 24996 20758 20723
+f 1665 28086 28061
+f 23772 1665 28061
+f 6524 6526 28061
+f 28086 6524 28061
+f 23706 24278 23707
+f 28087 28088 28089
+f 12649 23760 12650
+f 27222 27223 27644
+f 25161 24794 24795
+f 17443 25277 27114
+f 24038 27325 27696
+f 18684 3324 18652
+f 18710 12645 12644
+f 27756 22029 22028
+f 27006 26932 26886
+f 26932 27185 25912
+f 26942 27339 25796
+f 18445 19381 25332
+f 27335 27331 27360
+f 27227 25356 28090
+f 23827 25944 27312
+f 25706 27168 27010
+f 14604 25415 22826
+f 8217 8216 27730
+f 24963 26917 16106
+f 27766 18946 18880
+f 27200 27482 27423
+f 15545 26169 17263
+f 16339 4157 23901
+f 27436 27438 23902
+f 17302 27599 27364
+f 27599 25861 27197
+f 27192 27340 26793
+f 23759 26794 26793
+f 27478 27052 27492
+f 25611 25612 27662
+f 27492 25611 27662
+f 25612 25687 27663
+f 17836 21152 25478
+f 27845 27047 25682
+f 27901 27691 17511
+f 27535 27534 27583
+f 14506 19150 18533
+f 27262 27300 27169
+f 26790 23100 18938
+f 27179 27178 25705
+f 27331 27335 27120
+f 454 15397 28091
+f 14887 8548 3743
+f 27645 27474 27473
+f 27735 26126 20020
+f 22149 27183 27402
+f 19173 16142 3378
+f 22193 22149 27402
+f 27183 26986 26846
+f 25240 17275 25236
+f 25451 25930 25452
+f 26028 25701 25702
+f 20263 17802 17804
+f 20501 15317 28069
+f 20364 20501 28069
+f 15317 28092 28070
+f 28069 15317 28070
+f 28092 28093 28071
+f 28070 28092 28071
+f 28093 28094 28072
+f 28071 28093 28072
+f 28094 28095 28073
+f 28072 28094 28073
+f 28095 28096 28074
+f 28073 28095 28074
+f 28096 28097 28075
+f 28074 28096 28075
+f 28098 28076 28075
+f 28097 28098 28075
+f 28099 28077 28076
+f 28098 28099 28076
+f 28100 28078 28077
+f 28099 28100 28077
+f 28101 28079 28078
+f 28100 28101 28078
+f 28102 28080 28079
+f 28101 28102 28079
+f 28103 28081 28080
+f 28102 28103 28080
+f 28104 28082 28081
+f 28103 28104 28081
+f 28105 28083 28082
+f 28104 28105 28082
+f 28106 28084 28083
+f 28105 28106 28083
+f 28107 28085 28084
+f 28106 28107 28084
+f 6941 13818 28085
+f 28107 6941 28085
+f 26087 28108 26991
+f 10980 26087 26991
+f 27687 28053 27656
+f 28054 25107 27630
+f 15955 15957 28053
+f 28029 15955 28053
+f 5394 25047 5395
+f 26141 18183 24807
+f 23782 15649 23842
+f 3343 25096 25098
+f 8930 25155 25500
+f 27406 25386 27126
+f 23787 28109 23207
+f 25574 27130 27035
+f 27027 27072 25464
+f 17543 17542 25510
+f 26227 26893 26228
+f 26242 25578 26048
+f 25163 25164 27383
+f 27198 25163 27383
+f 23771 23828 27434
+f 25164 23770 27407
+f 23828 26915 27435
+f 27408 23771 27434
+f 23715 23714 3043
+f 27434 23828 27435
+f 25417 23548 27146
+f 25654 25417 27146
+f 14843 27341 27192
+f 27340 27229 26793
+f 27662 25612 27663
+f 26887 27664 27663
+f 25687 26887 27663
+f 27583 27665 27664
+f 25835 27901 17511
+f 19706 27901 25835
+f 21225 28110 28111
+f 20813 12939 12829
+f 9203 26964 9201
+f 15722 27134 27106
+f 27227 28090 26863
+f 16668 25159 26823
+f 16971 23711 16972
+f 26887 27583 27664
+f 28090 27228 26863
+f 16662 28112 16663
+f 4370 4372 7337
+f 1088 16807 1089
+f 16663 28113 28086
+f 1665 16663 28086
+f 28114 6524 28086
+f 28113 28114 28086
+f 28089 28088 6524
+f 28114 28089 6524
+f 16535 27222 27644
+f 23375 28115 28089
+f 27113 26769 27114
+f 27223 27333 17463
+f 18684 18652 18681
+f 26242 24798 17581
+f 28116 16410 1753
+f 15284 28116 1753
+f 14771 15451 3103
+f 14839 14841 17286
+f 19371 19370 20549
+f 27583 27534 27690
+f 23981 23980 21245
+f 25572 27263 26920
+f 26916 27165 26855
+f 27166 27170 27360
+f 17838 17837 20338
+f 24882 27137 24931
+f 15132 16204 15133
+f 7927 28112 16662
+f 26335 27585 27646
+f 18891 23827 27312
+f 16735 23766 25875
+f 28116 27641 16410
+f 16733 22950 15191
+f 23904 22726 18877
+f 27364 27599 27197
+f 25861 25163 27198
+f 16241 27363 14843
+f 27341 27340 27192
+f 27665 27583 27690
+f 27534 23923 27087
+f 27690 27534 27087
+f 28117 23924 27536
+f 15724 17665 27134
+f 27097 20155 20549
+f 27051 15729 26788
+f 24055 27070 27231
+f 19370 16666 20549
+f 27461 16378 19917
+f 25356 25221 28090
+f 27298 27179 27011
+f 27170 27335 27360
+f 27080 27057 17130
+f 25825 27118 25826
+f 17280 24625 23291
+f 16035 16037 27324
+f 16613 27196 8786
+f 15952 27481 19842
+f 26986 26987 26820
+f 27402 27183 26846
+f 23757 27376 25199
+f 26169 5637 17263
+f 25087 24431 25088
+f 24654 25496 25657
+f 17067 17069 17070
+f 18722 9659 8397
+f 15316 28118 28092
+f 15317 15316 28092
+f 28118 28119 28093
+f 28092 28118 28093
+f 28119 28120 28094
+f 28093 28119 28094
+f 28120 28121 28095
+f 28094 28120 28095
+f 28121 28122 28096
+f 28095 28121 28096
+f 28122 28123 28097
+f 28096 28122 28097
+f 28124 28098 28097
+f 28123 28124 28097
+f 28125 28099 28098
+f 28124 28125 28098
+f 28126 28100 28099
+f 28125 28126 28099
+f 28126 28127 28101
+f 28100 28126 28101
+f 28127 28128 28102
+f 28101 28127 28102
+f 28129 28103 28102
+f 28128 28129 28102
+f 28130 28104 28103
+f 28129 28130 28103
+f 28131 28105 28104
+f 28130 28131 28104
+f 28132 28106 28105
+f 28131 28132 28105
+f 28133 28107 28106
+f 28132 28133 28106
+f 26262 28134 5197
+f 5197 28134 16161
+f 26040 25205 17799
+f 25920 25919 14841
+f 27656 28054 27630
+f 25107 23912 23911
+f 24615 15955 28029
+f 27894 24615 28029
+f 5395 26141 24807
+f 17741 3143 17742
+f 23844 27279 23782
+f 15649 3343 23842
+f 23953 26929 23808
+f 24538 25749 25240
+f 27188 27161 27136
+f 23850 23849 25739
+f 16695 16694 24169
+f 27074 25825 25830
+f 17237 22723 2766
+f 18710 18709 12645
+f 27383 25164 27407
+f 23770 23771 27408
+f 23811 27382 16241
+f 27363 27341 14843
+f 27381 27382 23811
+f 16036 27381 23811
+f 26915 25087 25150
+f 27382 27363 16241
+f 25571 25570 27236
+f 25654 27146 26951
+f 19150 18499 18533
+f 25493 25736 24464
+f 27087 23923 27086
+f 25820 23272 14987
+f 23273 15666 23528
+f 25413 17686 21247
+f 9321 25726 2863
+f 25558 27115 20460
+f 25557 27100 27115
+f 25872 27214 25873
+f 19370 25355 16667
+f 27181 27187 26770
+f 16591 25558 20460
+f 24003 8921 8923
+f 27031 17179 17181
+f 19197 19196 8923
+f 20510 20473 12648
+f 28112 28135 28113
+f 16663 28112 28113
+f 23376 28114 28113
+f 28135 23376 28113
+f 7009 12293 1363
+f 23376 23375 28114
+f 15547 15546 25685
+f 23717 25152 25151
+f 27644 27223 17463
+f 27286 27285 25865
+f 27333 27095 27017
+f 17463 27333 27017
+f 28136 28116 15284
+f 1752 15284 1753
+f 24995 20500 19782
+f 20020 26126 20021
+f 26835 27181 26769
+f 26855 27360 26856
+f 10298 28137 28138
+f 10312 10311 27027
+f 26855 27166 27360
+f 23807 25481 23444
+f 17765 27122 27098
+f 26239 24011 16764
+f 24928 25108 24929
+f 24009 24008 26974
+f 25944 23903 27344
+f 23823 23364 26995
+f 24829 24699 24765
+f 9486 27321 9203
+f 23709 23708 25338
+f 23286 23709 25338
+f 27197 25861 27198
+f 27435 26915 25150
+f 25146 27381 16036
+f 24348 25146 16036
+f 25273 23807 23444
+f 23835 25712 27623
+f 23881 16209 25877
+f 186 9445 9447
+f 27275 27036 27003
+f 27036 24054 27003
+f 25820 14987 23349
+f 1542 1541 15043
+f 27113 26835 26769
+f 27208 16844 27215
+f 27374 27593 27375
+f 27335 27298 27120
+f 27165 27166 26855
+f 24512 17532 27104
+f 27034 23887 23889
+f 25983 27188 25984
+f 26232 25982 27174
+f 24861 25645 17572
+f 24862 24861 17572
+f 26987 25943 26821
+f 26846 26986 26820
+f 25956 25396 25449
+f 16718 22906 15671
+f 18876 18908 18875
+f 14205 23706 23709
+f 14016 7106 6437
+f 19483 2149 3748
+f 23660 28139 28118
+f 15316 23660 28118
+f 28139 28140 28119
+f 28118 28139 28119
+f 28140 28141 28120
+f 28119 28140 28120
+f 28141 28142 28121
+f 28120 28141 28121
+f 28142 28143 28122
+f 28121 28142 28122
+f 28143 28144 28123
+f 28122 28143 28123
+f 28144 28145 28124
+f 28123 28144 28124
+f 28146 28125 28124
+f 28145 28146 28124
+f 28146 28147 28126
+f 28125 28146 28126
+f 28148 28127 28126
+f 28147 28148 28126
+f 28149 28128 28127
+f 28148 28149 28127
+f 28150 28129 28128
+f 28149 28150 28128
+f 28151 28130 28129
+f 28150 28151 28129
+f 28152 28131 28130
+f 28151 28152 28130
+f 28153 28132 28131
+f 28152 28153 28131
+f 28154 28133 28132
+f 28153 28154 28132
+f 28155 20922 23096
+f 28154 23096 28133
+f 25808 27093 25809
+f 27928 27927 25805
+f 27630 25107 23911
+f 23912 25162 23913
+f 27711 24615 27894
+f 27893 27711 27894
+f 26838 17176 25526
+f 17542 24219 25509
+f 25238 25504 23844
+f 27279 15649 23782
+f 25480 27296 27406
+f 27050 26237 26894
+f 4966 4965 6940
+f 23954 27099 23955
+f 27020 26935 26937
+f 27312 25944 27344
+f 22785 11226 7342
+f 23766 24062 25875
+f 27407 23770 27408
+f 25088 23709 23286
+f 23834 23336 23835
+f 14605 28156 14603
+f 9274 25360 26877
+f 3134 21243 9446
+f 25480 27406 24756
+f 22595 10981 26877
+f 25570 25654 26951
+f 23336 8790 25712
+f 23761 23353 23355
+f 25352 25490 27236
+f 18044 17525 18045
+f 25360 22595 26877
+f 23445 24756 24757
+f 24896 4928 19070
+f 23835 27623 24757
+f 16821 27124 6789
+f 17066 19917 16378
+f 25969 7925 25966
+f 18908 23886 27983
+f 27766 18908 27983
+f 23886 27953 27984
+f 27983 23886 27984
+f 27953 27844 27985
+f 25349 17189 25141
+f 25277 25346 27113
+f 26877 27716 9272
+f 21635 20326 11818
+f 28112 7927 28135
+f 7926 28157 7927
+f 23377 23376 28135
+f 28157 23377 28135
+f 24696 24698 24700
+f 24696 28158 27956
+f 25061 24992 25062
+f 23832 23725 27755
+f 26782 20755 17822
+f 19668 19021 9321
+f 7205 806 7212
+f 2349 3814 28159
+f 28160 28136 28161
+f 27396 28160 28161
+f 27984 27953 27985
+f 27844 27845 28008
+f 23341 7937 19360
+f 27040 26357 27041
+f 27343 17387 27221
+f 23836 23835 24757
+f 740 1106 10376
+f 19002 19001 6037
+f 26232 26985 25982
+f 27359 17735 23337
+f 25484 25483 26829
+f 2673 2672 7669
+f 24759 26143 24760
+f 27162 25736 25735
+f 16307 17224 17665
+f 17404 17406 27639
+f 23986 24540 25338
+f 8571 13792 8572
+f 25820 14896 23272
+f 8790 23881 25712
+f 27078 25945 25309
+f 27126 23834 23836
+f 25613 27762 27763
+f 22711 28162 22712
+f 25613 1509 27764
+f 27762 25613 27764
+f 27985 27844 28008
+f 24877 25932 24878
+f 27845 25682 28009
+f 26971 26970 26969
+f 14352 27089 25695
+f 27163 27162 25735
+f 27225 22831 26866
+f 27162 27165 26916
+f 25736 27162 26916
+f 17178 24655 23258
+f 22923 22922 23076
+f 24759 24797 26143
+f 25092 16204 15132
+f 25943 27357 27273
+f 26820 26987 26821
+f 25645 2394 23268
+f 27099 23824 25992
+f 23287 23286 24279
+f 19014 18967 18963
+f 19098 16697 16696
+f 1509 27503 27765
+f 19014 27082 28139
+f 23660 19014 28139
+f 27082 28163 28140
+f 28139 27082 28140
+f 28163 28164 28141
+f 28140 28163 28141
+f 28164 28165 28142
+f 28141 28164 28142
+f 28166 28143 28142
+f 28165 28166 28142
+f 28167 28144 28143
+f 28166 28167 28143
+f 28168 28145 28144
+f 28167 28168 28144
+f 28168 28169 28146
+f 28145 28168 28146
+f 28170 28147 28146
+f 28169 28170 28146
+f 28171 28148 28147
+f 28170 28171 28147
+f 28172 28149 28148
+f 28171 28172 28148
+f 28172 28173 28150
+f 28149 28172 28150
+f 28174 28151 28150
+f 28173 28174 28150
+f 28175 28152 28151
+f 28174 28175 28151
+f 28176 28153 28152
+f 28175 28176 28152
+f 28177 28154 28153
+f 28176 28177 28153
+f 28178 12637 28155
+f 28177 28155 28154
+f 25809 27928 25805
+f 27927 27926 25801
+f 27409 27313 24800
+f 27101 27231 27124
+f 24963 23300 26917
+f 23300 10522 26917
+f 24265 21280 22650
+f 23338 25512 23339
+f 25242 25583 25238
+f 25504 27279 23844
+f 27538 17646 23724
+f 16254 28179 18903
+f 21342 26047 10022
+f 1769 10847 28138
+f 23903 23295 27345
+f 27344 23903 27345
+f 21286 21363 21362
+f 16398 16557 17341
+f 23285 25088 23286
+f 27621 24541 24540
+f 25945 25310 25309
+f 24991 24990 25281
+f 27764 1509 27765
+f 27503 26323 27796
+f 27765 27503 27796
+f 23885 27655 27953
+f 26323 26322 27797
+f 25570 26951 27236
+f 10310 27356 10311
+f 27796 26323 27797
+f 26322 23845 27817
+f 27797 26322 27817
+f 7925 25969 28180
+f 28008 27845 28009
+f 27129 27483 27130
+f 25684 28010 28009
+f 25371 25059 22829
+f 25346 26835 27113
+f 23845 23847 27820
+f 27639 17406 25145
+f 27817 23845 27820
+f 7927 28157 28135
+f 28181 23377 28157
+f 7926 28181 28157
+f 17065 24346 11389
+f 28181 14958 23377
+f 26775 23832 27755
+f 25643 23848 25108
+f 27606 27047 27845
+f 24660 23778 24661
+f 5390 5392 14958
+f 21079 1622 1624
+f 28182 28160 27396
+f 4396 28182 27396
+f 25682 25684 28009
+f 25609 28011 28010
+f 22680 9636 22679
+f 22679 9636 24828
+f 3411 8599 26827
+f 24828 9636 24829
+f 27114 23626 23547
+f 183 16278 16803
+f 28183 641 6379
+f 8572 13792 19829
+f 26975 27264 26976
+f 3730 3757 3728
+f 27163 25735 27243
+f 27190 27163 27243
+f 27041 27133 27131
+f 20298 26955 25557
+f 23817 25657 27317
+f 28184 25217 25216
+f 27638 27639 25144
+f 27082 18963 12654
+f 25972 28185 24269
+f 23847 24711 27820
+f 27843 24711 18934
+f 25492 27409 26057
+f 26886 26933 26887
+f 17348 24313 25915
+f 25684 25609 28010
+f 25685 28033 28011
+f 25609 25685 28011
+f 27243 25735 26124
+f 25281 24855 21657
+f 27119 27277 27220
+f 23588 25372 25368
+f 27189 27191 27284
+f 27190 27243 27242
+f 26034 27085 25794
+f 25987 24858 24855
+f 238 23964 26055
+f 25102 23960 25103
+f 27357 25426 27225
+f 26821 25943 27273
+f 27057 26866 27058
+f 23826 25879 25880
+f 27367 27129 25574
+f 25573 27367 25574
+f 2965 17533 27263
+f 10519 22030 5736
+f 16651 14452 26803
+f 26794 27090 26795
+f 12654 27022 28163
+f 27082 12654 28163
+f 27022 28186 28164
+f 28163 27022 28164
+f 28186 28187 28165
+f 28164 28186 28165
+f 28188 28166 28165
+f 28187 28188 28165
+f 28189 28167 28166
+f 28188 28189 28166
+f 28190 28168 28167
+f 28189 28190 28167
+f 28190 28191 28169
+f 28168 28190 28169
+f 28191 28192 28170
+f 28169 28191 28170
+f 28192 28193 28171
+f 28170 28192 28171
+f 28193 28194 28172
+f 28171 28193 28172
+f 28194 28195 28173
+f 28172 28194 28173
+f 28196 28174 28173
+f 28195 28196 28173
+f 28197 28175 28174
+f 28196 28197 28174
+f 28198 28176 28175
+f 28197 28198 28175
+f 28199 28177 28176
+f 28198 28199 28176
+f 28065 28064 28056
+f 28199 28178 28177
+f 25805 27927 25801
+f 27925 25802 25801
+f 17267 25606 6797
+f 27184 27118 25825
+f 25104 25639 25814
+f 27258 25104 25814
+f 25221 25220 28090
+f 26056 25104 27258
+f 25536 26928 25143
+f 13373 6900 6882
+f 27930 18904 18903
+f 25818 25171 27572
+f 25171 17583 27571
+f 16399 23899 28179
+f 23295 23265 27233
+f 1703 1702 25708
+f 27672 27029 27392
+f 27345 23295 27233
+f 23986 27621 24540
+f 19458 16827 19717
+f 23807 23806 25481
+f 27621 24759 24758
+f 17264 27012 27077
+f 27639 25145 25144
+f 28200 23425 24224
+f 25030 27342 27606
+f 23704 27638 26142
+f 27655 25030 27606
+f 17450 26831 26832
+f 26418 27099 23954
+f 22786 4841 4840
+f 27898 28180 25969
+f 27077 28034 28033
+f 25685 27077 28033
+f 28201 26790 21250
+f 24665 24688 24654
+f 27388 27389 22149
+f 25647 27273 27224
+f 25155 25499 25501
+f 12257 4396 21932
+f 28202 7926 7925
+f 15240 27898 25857
+f 25765 28181 7926
+f 28203 28202 28180
+f 2471 9053 2472
+f 28202 25765 7926
+f 12865 10590 8832
+f 23886 23885 27953
+f 23830 23832 26775
+f 27393 27337 26999
+f 23778 23830 24661
+f 24661 23830 26775
+f 28030 28182 4396
+f 16862 16641 16643
+f 28030 28204 28182
+f 18561 18555 17632
+f 25312 15997 15999
+f 22680 12192 9636
+f 28091 28158 24700
+f 9636 9635 24829
+f 27730 16938 24699
+f 24829 27730 24699
+f 16938 28091 24700
+f 24699 16938 24700
+f 24995 19782 22679
+f 27504 25372 28158
+f 27191 27190 27242
+f 9378 11267 26066
+f 25353 25352 25635
+f 23828 16824 26915
+f 24170 24283 16936
+f 26952 27537 23284
+f 24377 9307 24252
+f 27012 28035 28034
+f 20301 20264 20263
+f 27022 12654 12653
+f 16971 26765 26075
+f 27077 27012 28034
+f 28068 28056 28035
+f 27109 26818 17733
+f 24801 25876 27253
+f 28205 28206 2587
+f 27005 27185 27006
+f 16748 27189 17803
+f 27191 27242 27284
+f 25639 25638 26875
+f 25925 26036 26037
+f 25241 25243 26044
+f 26037 25241 26044
+f 25426 22829 22831
+f 27273 27357 27225
+f 27080 27224 27057
+f 24213 24212 27254
+f 27567 26233 26831
+f 25531 27502 17450
+f 27622 27869 26885
+f 103 20211 23125
+f 23822 24275 23823
+f 27021 12653 23350
+f 15004 24825 18092
+f 23097 2565 17578
+f 28207 28186 27022
+f 27021 28207 27022
+f 28208 28187 28186
+f 28207 28208 28186
+f 28208 28209 28188
+f 28187 28208 28188
+f 28210 28189 28188
+f 28209 28210 28188
+f 28211 28190 28189
+f 28210 28211 28189
+f 28212 28191 28190
+f 28211 28212 28190
+f 28212 28213 28192
+f 28191 28212 28192
+f 28214 28193 28192
+f 28213 28214 28192
+f 28214 28215 28194
+f 28193 28214 28194
+f 28215 28216 28195
+f 28194 28215 28195
+f 28216 28217 28196
+f 28195 28216 28196
+f 28218 28197 28196
+f 28217 28218 28196
+f 28219 28198 28197
+f 28218 28219 28197
+f 28220 28199 28198
+f 28219 28220 28198
+f 28221 28178 28199
+f 28220 28221 28199
+f 27926 27925 25801
+f 25177 26338 16990
+f 16203 25245 25244
+f 23318 16203 25244
+f 25639 26875 26217
+f 25814 25639 26217
+f 27411 24965 25934
+f 27439 27411 25934
+f 27411 27314 24965
+f 27314 24470 24965
+f 16935 24170 16936
+f 24283 24799 27315
+f 16254 16399 28179
+f 16398 17341 23899
+f 25567 22788 25939
+f 1838 26415 26029
+f 23265 24928 24927
+f 25108 23850 27463
+f 23823 24275 23364
+f 16046 27349 27152
+f 24541 27621 24758
+f 26143 17641 17643
+f 25615 23703 24797
+f 23704 26142 23705
+f 24340 24117 24116
+f 24464 26854 24465
+f 27175 27173 27388
+f 4951 2082 27362
+f 23306 24796 23985
+f 27362 27361 27893
+f 25943 25942 27357
+f 26987 25941 25943
+f 16832 16545 431
+f 27012 28068 28035
+f 19796 17359 2832
+f 26038 25941 26987
+f 23922 15612 18820
+f 17524 26954 20298
+f 25189 27742 20793
+f 25223 25500 25502
+f 23079 27586 25035
+f 27315 24799 27248
+f 26754 23130 23129
+f 25933 27464 27249
+f 24801 27253 27249
+f 25828 27494 27464
+f 27253 25933 27249
+f 25567 27529 27494
+f 25933 25828 27464
+f 25939 27530 27529
+f 25828 25567 27494
+f 25939 17997 2409
+f 25567 25939 27529
+f 14516 26636 13376
+f 28222 28223 28224
+f 24859 28204 28030
+f 24856 24859 28030
+f 20124 20123 16746
+f 24471 26979 24472
+f 13978 20758 16591
+f 21077 12457 15081
+f 238 657 236
+f 25578 25580 27542
+f 25583 25504 25238
+f 15397 27504 28158
+f 16938 454 28091
+f 23955 25992 25318
+f 28091 15397 28158
+f 27195 27194 27235
+f 14843 27192 14844
+f 25822 25821 25528
+f 19740 19665 9632
+f 25207 26048 26036
+f 2395 26825 23315
+f 23350 19145 23348
+f 16399 16398 23899
+f 23260 22029 8928
+f 28225 28110 19196
+f 19287 19655 19631
+f 27247 27356 10310
+f 27301 27230 27423
+f 27482 15651 27423
+f 20209 16748 17802
+f 27189 27284 17803
+f 27181 23907 27187
+f 26949 27001 26867
+f 18842 16493 25029
+f 25235 26922 25239
+f 24212 22830 27272
+f 27225 25426 22831
+f 25647 27224 27080
+f 25648 25647 27080
+f 26052 27527 25535
+f 17464 26052 25535
+f 16557 17379 17341
+f 24431 14205 25088
+f 27230 26911 27200
+f 26912 25526 27482
+f 23348 19145 19144
+f 24877 15109 25932
+f 14989 28207 27021
+f 23350 14989 27021
+f 14988 28208 28207
+f 14989 14988 28207
+f 20260 28209 28208
+f 14988 20260 28208
+f 25271 28210 28209
+f 20260 25271 28209
+f 25271 23550 28211
+f 28210 25271 28211
+f 23550 23529 28212
+f 28211 23550 28212
+f 23529 20412 28213
+f 28212 23529 28213
+f 20412 25272 28214
+f 28213 20412 28214
+f 25272 25274 28215
+f 28214 25272 28215
+f 25274 23446 28216
+f 28215 25274 28216
+f 23446 25644 28217
+f 28216 23446 28217
+f 27260 28218 28217
+f 25644 27260 28217
+f 17386 28219 28218
+f 27260 17386 28218
+f 16211 28220 28219
+f 17386 16211 28219
+f 23406 28221 28220
+f 16211 23406 28220
+f 26338 25177 28221
+f 23406 26338 28221
+f 24532 27568 24533
+f 5169 399 5170
+f 26875 23815 27280
+f 26217 26875 27280
+f 27439 25934 24469
+f 27466 27439 24469
+f 16818 16820 23770
+f 27263 27262 27169
+f 16936 24283 27315
+f 24799 24801 27248
+f 27310 27255 26853
+f 25876 27310 26853
+f 27313 27310 25876
+f 24800 27313 25876
+f 24929 25108 27463
+f 27463 23850 24436
+f 23902 23263 23295
+f 23365 24340 23366
+f 24760 26143 17643
+f 17642 27105 17643
+f 14205 14204 23706
+f 24278 23277 23707
+f 28179 23899 27081
+f 25739 16534 24436
+f 19059 19058 19842
+f 10979 25614 27763
+f 14204 24278 23706
+f 18979 8938 8940
+f 23364 23366 26996
+f 24431 14203 14205
+f 24167 24223 16611
+f 25351 25741 25352
+f 2609 2482 25363
+f 11267 2966 2965
+f 23842 25098 25634
+f 6887 17836 25478
+f 266 18207 27089
+f 27482 25526 25527
+f 24878 25932 25933
+f 27535 15698 15700
+f 25220 27228 28090
+f 25823 27481 26027
+f 20122 16747 20123
+f 24071 16693 16695
+f 27981 24809 24808
+f 28226 28227 26812
+f 24338 24337 24342
+f 9614 28228 2674
+f 28229 28230 21832
+f 24069 24074 24076
+f 4498 4497 28231
+f 28232 25618 28233
+f 28234 28235 28236
+f 28237 21667 28238
+f 15037 20971 28239
+f 28240 15037 28239
+f 24122 24124 24120
+f 28241 28242 28243
+f 28244 28245 28246
+f 25307 15049 26962
+f 3330 23959 18983
+f 17644 18964 16940
+f 2658 4964 2659
+f 2906 9997 14160
+f 28247 28248 28249
+f 17226 13526 22464
+f 22050 22049 28250
+f 28241 28243 28251
+f 5389 21361 22050
+f 28252 28253 28250
+f 28240 28239 28254
+f 22049 28255 28250
+f 28235 28241 28251
+f 28242 28240 28254
+f 28235 28251 28236
+f 28242 28254 28243
+f 23157 21454 25725
+f 28256 28257 28249
+f 26452 23157 25725
+f 23566 23567 4963
+f 19242 23566 4963
+f 23567 2659 4963
+f 26618 24944 27546
+f 15143 23104 28258
+f 28257 28247 28249
+f 4648 28259 4649
+f 28260 28261 28248
+f 28247 28260 28248
+f 19189 28262 2337
+f 22791 28263 16143
+f 28264 26509 26421
+f 21834 2667 28265
+f 28266 28263 22791
+f 15699 25797 27536
+f 28255 28252 28250
+f 28267 28266 22791
+f 28252 28266 28267
+f 28253 28252 28267
+f 28268 28256 28249
+f 28263 28269 16143
+f 15144 15143 28258
+f 28270 28256 28268
+f 23104 6383 28271
+f 26960 6804 26961
+f 28272 28270 28273
+f 28258 23104 28271
+f 28274 28234 28275
+f 28273 28270 28268
+f 28274 28275 28261
+f 28260 28274 28261
+f 28276 28277 14110
+f 28234 28236 28275
+f 14109 28276 14110
+f 28277 28262 19189
+f 28278 28279 2338
+f 2337 28278 2338
+f 10452 28280 22909
+f 9413 15461 9414
+f 28281 28282 28283
+f 4647 4649 28284
+f 1751 28281 28285
+f 28285 28281 28283
+f 10251 879 18329
+f 28286 18872 24822
+f 28279 28287 28288
+f 28288 28287 28289
+f 28290 28272 28291
+f 28292 28290 28291
+f 24822 26025 24823
+f 102 3535 103
+f 28293 16224 16657
+f 28294 28290 28292
+f 18872 28293 16657
+f 16144 28295 14109
+f 28291 28272 28273
+f 28269 28295 16144
+f 16143 28269 16144
+f 14110 28277 19189
+f 28295 28276 14109
+f 28296 28297 22604
+f 28262 28278 2337
+f 2324 2323 5386
+f 22270 21834 28298
+f 28299 28300 28301
+f 28302 22913 28303
+f 21276 22718 21282
+f 16753 2488 27601
+f 28304 28305 10813
+f 28306 28307 22947
+f 14519 10812 10814
+f 10812 28304 10813
+f 28308 28309 22175
+f 6796 6795 21880
+f 28310 28311 28312
+f 28311 28313 3585
+f 26757 28294 28314
+f 28315 26757 28314
+f 28316 5399 16224
+f 28293 28316 16224
+f 28317 17888 5399
+f 28318 26756 28315
+f 28316 28317 5399
+f 2338 28279 28288
+f 28314 28294 28292
+f 3535 20211 103
+f 28287 28310 28289
+f 8393 8392 6467
+f 21162 27795 15382
+f 28319 28320 28321
+f 14767 27565 16470
+f 28322 28323 28305
+f 5543 28324 2841
+f 28304 28322 28305
+f 28325 28326 28323
+f 28322 28325 28323
+f 28306 22947 28326
+f 28325 28306 28326
+f 28307 22948 22947
+f 28327 23234 22948
+f 28307 28327 22948
+f 28328 28329 23234
+f 28327 28328 23234
+f 28330 10558 28331
+f 17742 3143 23201
+f 28312 28311 3585
+f 28313 28332 12271
+f 28333 28334 28318
+f 26756 26757 28315
+f 28335 16229 17888
+f 28317 28335 17888
+f 28336 4651 16229
+f 28335 28336 16229
+f 28337 4496 4651
+f 21416 28334 28333
+f 28338 21416 28333
+f 28332 28339 1053
+f 28289 28310 28312
+f 24809 27981 27568
+f 18939 27603 28340
+f 5655 6212 5936
+f 21159 28341 28342
+f 6595 12887 2814
+f 2598 27394 2599
+f 11387 27597 22698
+f 4112 10567 19071
+f 20451 8127 21506
+f 2023 2025 28343
+f 1237 10252 1450
+f 28344 28246 28345
+f 27568 26997 18062
+f 2024 19839 2025
+f 28346 5666 11025
+f 28347 28348 28349
+f 28350 28244 28329
+f 28328 28350 28329
+f 25837 28351 18928
+f 28352 21586 21197
+f 3585 28313 12271
+f 28353 16329 16328
+f 21414 21416 28338
+f 28354 21414 28338
+f 28336 28337 4651
+f 28355 6089 4496
+f 28337 28355 4496
+f 28356 28357 28354
+f 28358 4972 6089
+f 12271 28332 1053
+f 28334 26756 28318
+f 28359 5246 5675
+f 28360 16328 1053
+f 6524 28088 6525
+f 3299 3300 3135
+f 3300 28361 3135
+f 25004 20471 22921
+f 28361 26218 3136
+f 3135 28361 3136
+f 26218 25509 3136
+f 12228 15865 12229
+f 28362 28299 28301
+f 5117 28363 28364
+f 28299 28365 28366
+f 28300 28299 28366
+f 26136 27671 26137
+f 28366 28365 27899
+f 28259 28367 28368
+f 23176 23175 28369
+f 28370 28245 28244
+f 28350 28370 28244
+f 22780 28371 18653
+f 25837 18928 18930
+f 28360 28353 16328
+f 28353 28372 14018
+f 28373 28374 28375
+f 28376 28357 28356
+f 28355 28358 6089
+f 28377 4804 4972
+f 28358 28377 4972
+f 28377 28378 4805
+f 28265 28374 28373
+f 28379 28265 28373
+f 28380 28381 18992
+f 28339 28360 1053
+f 24219 3136 25509
+f 16252 16254 22896
+f 3303 28382 3300
+f 3138 3303 3158
+f 28382 28383 28361
+f 3300 28382 28361
+f 28383 28384 26218
+f 28361 28383 26218
+f 26523 26526 26434
+f 28222 26469 17466
+f 28227 26813 26812
+f 28385 28386 17550
+f 28387 28388 28389
+f 28390 28391 28392
+f 27640 27325 27521
+f 23175 27670 28393
+f 28367 23176 28369
+f 25232 25292 25233
+f 28370 28394 28395
+f 12560 28396 28397
+f 28398 28399 28400
+f 28303 22270 28298
+f 16329 28353 14018
+f 28380 18992 14018
+f 28375 28376 28356
+f 28357 21414 28354
+f 4804 28377 4805
+f 28401 28298 28379
+f 28378 28402 5810
+f 4805 28378 5810
+f 28298 28265 28379
+f 28402 28403 6092
+f 28381 28404 15272
+f 28374 28376 28375
+f 20211 16216 23125
+f 3140 2954 25787
+f 3302 28405 3303
+f 3138 3158 3139
+f 28405 28406 28382
+f 3303 28405 28382
+f 28406 28407 28383
+f 28382 28406 28383
+f 28407 28408 28384
+f 28383 28407 28384
+f 3132 3134 9445
+f 28068 25692 28065
+f 23106 28409 28271
+f 28203 27898 15240
+f 28389 28390 28392
+f 8989 22784 8990
+f 4491 14819 22781
+f 15216 15682 22134
+f 8691 468 1844
+f 28348 28410 28349
+f 28245 28370 28395
+f 28394 28396 12560
+f 28411 13050 28412
+f 28298 21834 28265
+f 28372 28380 14018
+f 28381 22652 18992
+f 28302 28303 28413
+f 28414 28302 28413
+f 5810 28402 6092
+f 28303 28298 28401
+f 28403 28415 5804
+f 6092 28403 5804
+f 28415 28416 5805
+f 28417 2321 28418
+f 2321 28302 28414
+f 28065 25692 25693
+f 22652 28381 15272
+f 25787 8690 3302
+f 8689 28419 8690
+f 28420 28421 28405
+f 3302 28420 28405
+f 28421 28422 28406
+f 28405 28421 28406
+f 28422 28423 28407
+f 28406 28422 28407
+f 28066 28408 28407
+f 28423 28066 28407
+f 3811 6947 6949
+f 14748 27557 23024
+f 27954 23587 23589
+f 4764 18123 4765
+f 28391 28226 27868
+f 28392 28391 27868
+f 5546 22217 28424
+f 26332 28229 21068
+f 4649 28259 17675
+f 22309 2510 2509
+f 28395 28394 12560
+f 28396 28425 28397
+f 28426 28427 28428
+f 28429 28430 27694
+f 28404 28431 15236
+f 15236 28431 21732
+f 2321 28432 28418
+f 28413 28303 28401
+f 5804 28415 5805
+f 28416 28433 5967
+f 5805 28416 5967
+f 28434 28435 27799
+f 28433 28436 6091
+f 27549 28031 27550
+f 28432 2321 28414
+f 28437 25994 25995
+f 28438 11014 28439
+f 28419 28440 28420
+f 8690 28420 3302
+f 28440 28441 28421
+f 28420 28440 28421
+f 28441 28442 28422
+f 28421 28441 28422
+f 28442 28443 28423
+f 28422 28442 28423
+f 16131 23479 28159
+f 16131 3814 6906
+f 3157 17295 20812
+f 4490 15923 14042
+f 28444 28388 28387
+f 17831 17830 25039
+f 28445 28444 28446
+f 28447 28445 28446
+f 24992 24931 27137
+f 22064 21067 21069
+f 28259 28368 17675
+f 28367 28369 28368
+f 28448 28449 28397
+f 28425 28448 28397
+f 5542 21744 28324
+f 28450 28411 28412
+f 15272 28404 15236
+f 28431 28451 21732
+f 28452 2008 28453
+f 2008 28417 28418
+f 5967 28433 6091
+f 28454 6087 6091
+f 13535 14584 28455
+f 28436 28454 6091
+f 21099 25299 25301
+f 14280 6357 18724
+f 12917 28456 8689
+f 27956 28158 23587
+f 28456 28457 28419
+f 8689 28456 28419
+f 28457 28458 28440
+f 28419 28457 28440
+f 28458 28459 28441
+f 28440 28458 28441
+f 28459 28460 28442
+f 28441 28459 28442
+f 28460 27659 28443
+f 28442 28460 28443
+f 24590 28461 28462
+f 24482 24853 5867
+f 22954 25963 5254
+f 25747 25746 25980
+f 28463 28203 14448
+f 28464 28465 28447
+f 13342 21659 13343
+f 14447 28463 14448
+f 28284 27701 5966
+f 21659 28466 13343
+f 25220 23546 11030
+f 25418 27895 25417
+f 28467 28468 28449
+f 28448 28467 28449
+f 1767 21144 8819
+f 20152 177 5677
+f 28451 28469 1866
+f 21732 28451 1866
+f 14764 28452 28470
+f 28471 2008 28418
+f 28454 28472 6368
+f 6087 28454 6368
+f 18800 18802 28473
+f 27955 22962 24697
+f 27900 23982 19956
+f 22245 214 1946
+f 12934 13287 14767
+f 27559 28474 28456
+f 12917 27559 28456
+f 28474 28475 28457
+f 28456 28474 28457
+f 28475 28476 28458
+f 28457 28475 28458
+f 28476 28477 28459
+f 28458 28476 28459
+f 28477 28478 28460
+f 28459 28477 28460
+f 27660 27659 28460
+f 28478 27660 28460
+f 2669 15849 2670
+f 25857 6100 15240
+f 14448 28203 15240
+f 28479 28480 22911
+f 28481 28482 28483
+f 8473 15169 12322
+f 28484 28485 28482
+f 28486 28487 28488
+f 28489 28490 28491
+f 28487 28492 28493
+f 28490 28494 28491
+f 28494 28495 25617
+f 28467 28490 28489
+f 28468 28467 28489
+f 17594 25833 17001
+f 17000 17594 17001
+f 28469 28496 14920
+f 1866 28469 14920
+f 2008 28471 28453
+f 28496 28497 2169
+f 18827 18826 18156
+f 28452 28453 28470
+f 6368 28472 6369
+f 3543 14324 3545
+f 27281 5819 24973
+f 5813 27467 24968
+f 22793 16742 16741
+f 16868 16287 18007
+f 27558 28498 27559
+f 14322 27558 15451
+f 28498 28499 28474
+f 27559 28498 28474
+f 28499 28500 28475
+f 28474 28499 28475
+f 28500 28501 28476
+f 28475 28500 28476
+f 28501 28502 28477
+f 28476 28501 28477
+f 28502 28503 28478
+f 28477 28502 28478
+f 28503 28504 27660
+f 28478 28503 27660
+f 27668 23174 27671
+f 16625 22110 16334
+f 28484 28505 28506
+f 28507 21672 21674
+f 28508 28509 28510
+f 28492 28481 28483
+f 28511 28512 25617
+f 28513 28508 28510
+f 2019 28514 28515
+f 28491 28494 25617
+f 2020 2019 28515
+f 28516 28228 28514
+f 2019 28516 28514
+f 2674 28516 5658
+f 20335 28517 2292
+f 28516 2674 28228
+f 2169 28497 20335
+f 28517 28518 2292
+f 14920 28496 2169
+f 28497 28517 20335
+f 14764 28470 28519
+f 14765 14764 28519
+f 16470 16469 14767
+f 25303 14765 28520
+f 28521 22912 2320
+f 28522 21098 22270
+f 3543 6164 22578
+f 6528 28523 6529
+f 28524 15794 28525
+f 16988 3818 3817
+f 6262 6387 6263
+f 14324 28526 14322
+f 5048 9533 5049
+f 28526 28527 27558
+f 14322 28526 27558
+f 28527 28528 28498
+f 27558 28527 28498
+f 28528 28529 28499
+f 28498 28528 28499
+f 28529 28530 28500
+f 28499 28529 28500
+f 28530 28531 28501
+f 28500 28530 28501
+f 28532 28502 28501
+f 28531 28532 28501
+f 28533 28503 28502
+f 28532 28533 28502
+f 28533 27217 28504
+f 28503 28533 28504
+f 184 16803 16802
+f 15620 15636 28534
+f 28510 28509 28535
+f 28536 28537 28538
+f 28539 28540 28541
+f 28509 28542 28535
+f 28543 28544 28545
+f 28544 28539 28541
+f 28546 28543 28547
+f 28544 28541 28545
+f 15411 28159 23462
+f 25837 28548 28351
+f 28548 25837 28549
+f 25793 28550 28551
+f 28518 28552 15110
+f 2292 28518 15110
+f 25303 28520 28553
+f 21979 25303 28553
+f 21979 28553 28554
+f 14765 28519 28520
+f 28555 5108 5107
+f 21978 21979 28554
+f 14301 28555 5107
+f 25792 28556 28550
+f 16158 16160 22649
+f 15039 14177 28557
+f 6164 6163 22578
+f 28557 14177 22725
+f 15037 15039 20972
+f 28558 21663 28559
+f 15234 15233 18955
+f 20972 15039 28557
+f 28560 15234 28561
+f 15233 18956 18955
+f 25760 28560 25761
+f 6517 21109 6518
+f 214 17015 17072
+f 22578 28562 28526
+f 14324 22578 28526
+f 28562 28563 28527
+f 28526 28562 28527
+f 28563 28564 28528
+f 28527 28563 28528
+f 28564 28565 28529
+f 28528 28564 28529
+f 28565 28566 28530
+f 28529 28565 28530
+f 28566 28567 28531
+f 28530 28566 28531
+f 28568 28532 28531
+f 28567 28568 28531
+f 28569 28533 28532
+f 28568 28569 28532
+f 28569 28570 27217
+f 28533 28569 27217
+f 22140 21737 23969
+f 12104 21613 6652
+f 21435 21437 28571
+f 3869 2754 3870
+f 28572 21435 28571
+f 21588 28573 28571
+f 23236 28574 28575
+f 24328 14981 14980
+f 28226 26812 27842
+f 28576 28577 4810
+f 1779 1782 23403
+f 28064 27897 27871
+f 28578 28579 28580
+f 22602 28581 25995
+f 28411 22394 13050
+f 25041 22440 25760
+f 15234 18955 28561
+f 20953 21744 5542
+f 15169 12419 12322
+f 28560 28561 25761
+f 28582 28362 28583
+f 28584 25176 22750
+f 22050 28250 3253
+f 22601 25761 22602
+f 28362 28301 28583
+f 13814 28585 28586
+f 28587 28588 28589
+f 28590 28587 28589
+f 28591 22708 22695
+f 16302 16304 16884
+f 28586 28592 28593
+f 22478 28594 25046
+f 28595 28582 28596
+f 17752 28597 22306
+f 15683 28598 15684
+f 4497 6090 28599
+f 28600 16021 25048
+f 28555 14301 14303
+f 28601 28602 28603
+f 28346 28604 5253
+f 22627 24558 16154
+f 28605 28606 28607
+f 21326 21679 21433
+f 22712 28162 23102
+f 28608 2512 2173
+f 5809 2339 28609
+f 22961 24695 24697
+f 22235 28610 22236
+f 14970 25267 27302
+f 21341 25178 21342
+f 28611 28612 28562
+f 22578 28611 28562
+f 28612 28613 28563
+f 28562 28612 28563
+f 28613 28614 28564
+f 28563 28613 28564
+f 28614 28615 28565
+f 28564 28614 28565
+f 28615 28616 28566
+f 28565 28615 28566
+f 28616 28617 28567
+f 28566 28616 28567
+f 28618 28568 28567
+f 28617 28618 28567
+f 28619 28569 28568
+f 28618 28619 28568
+f 28619 28620 28570
+f 28569 28619 28570
+f 20153 25786 26047
+f 25178 20153 26047
+f 24096 21341 21343
+f 3380 1131 3381
+f 25042 26523 22218
+f 28621 28601 25990
+f 2024 28395 12559
+f 28349 28410 28622
+f 28623 28624 28625
+f 28626 28627 28628
+f 28629 10427 10429
+f 28624 28626 28628
+f 15209 28267 21276
+f 6261 6263 18509
+f 7442 23346 23347
+f 2329 22268 2330
+f 28180 27898 28203
+f 16768 16767 4647
+f 27526 28630 22372
+f 28631 28632 4648
+f 17229 17706 17566
+f 28633 19216 28634
+f 28320 28584 28591
+f 28233 28635 28237
+f 18957 21978 28636
+f 28637 25176 28584
+f 18957 28636 28588
+f 28587 18957 28588
+f 4929 26636 14516
+f 21978 28554 28636
+f 19214 28398 19215
+f 15187 5946 27618
+f 28341 28633 28634
+f 28638 22146 28639
+f 21626 22146 28638
+f 21667 21626 28238
+f 28556 28640 28550
+f 22146 23243 28639
+f 28238 21626 28638
+f 23243 28641 28642
+f 28643 28449 28644
+f 22780 18929 28371
+f 28639 23243 28642
+f 28590 28589 28581
+f 8360 10049 7010
+f 28399 6528 6527
+f 22602 28590 28581
+f 28645 28646 28647
+f 11016 6749 28648
+f 28449 28643 12561
+f 27816 26812 26811
+f 25616 25618 28232
+f 6163 28649 28611
+f 26326 28264 26421
+f 28649 28650 28612
+f 28611 28649 28612
+f 28650 28651 28613
+f 28612 28650 28613
+f 28651 28652 28614
+f 28613 28651 28614
+f 28652 28653 28615
+f 28614 28652 28615
+f 28653 28654 28616
+f 28615 28653 28616
+f 28654 28655 28617
+f 28616 28654 28617
+f 28655 28656 28618
+f 28617 28655 28618
+f 28656 28657 28619
+f 28618 28656 28619
+f 28657 28658 28620
+f 28619 28657 28620
+f 28658 22629 22628
+f 28620 28658 22628
+f 24881 26945 27734
+f 27393 11082 27338
+f 25989 28621 25990
+f 5459 16575 10519
+f 20972 28557 28659
+f 28660 20972 28659
+f 25618 28635 28233
+f 28557 22725 28661
+f 28662 25616 28232
+f 28449 28468 28644
+f 8929 27757 28663
+f 28664 28393 27773
+f 28254 28239 28665
+f 24480 16719 19051
+f 25716 17489 22955
+f 16987 16989 25314
+f 18930 18929 22780
+f 18181 22864 18271
+f 2371 2370 2535
+f 28346 5253 5252
+f 8221 15507 20291
+f 15110 28552 7544
+f 28666 3412 19595
+f 18122 18270 10882
+f 28667 28668 28669
+f 10905 9533 18375
+f 28637 28670 25176
+f 6094 16728 6095
+f 28398 28400 19215
+f 28671 28672 28673
+f 28674 28399 6527
+f 28633 19214 19216
+f 28549 25565 21508
+f 25964 25963 22953
+f 27775 27776 28664
+f 28641 28675 28676
+f 15094 16098 14950
+f 28642 28641 28676
+f 17855 15423 28677
+f 22351 28678 22350
+f 28463 28202 28203
+f 15410 23430 22045
+f 23179 28679 23177
+f 6749 2843 3462
+f 25565 28549 25837
+f 22709 16410 27642
+f 28680 11016 28648
+f 17731 17847 17732
+f 28158 24696 24700
+f 28681 14046 28682
+f 2304 10149 2305
+f 25507 25506 26269
+f 26026 25716 6102
+f 17055 16962 16961
+f 11186 6743 1981
+f 27868 28226 27842
+f 15915 3330 18983
+f 28663 11080 8929
+f 24584 20333 20334
+f 10569 28683 28649
+f 6163 10569 28649
+f 28683 28684 28650
+f 28649 28683 28650
+f 28684 28685 28651
+f 28650 28684 28651
+f 28685 28686 28652
+f 28651 28685 28652
+f 28686 28687 28653
+f 28652 28686 28653
+f 28687 28688 28654
+f 28653 28687 28654
+f 28689 28655 28654
+f 28688 28689 28654
+f 28689 28690 28656
+f 28655 28689 28656
+f 28690 28691 28657
+f 28656 28690 28657
+f 28691 15420 28658
+f 28657 28691 28658
+f 15419 22629 28658
+f 15420 15419 28658
+f 12973 27788 26969
+f 5803 25214 5801
+f 28236 28251 28692
+f 28321 28320 28591
+f 28693 28694 28695
+f 28243 28696 28697
+f 28225 28698 28110
+f 9916 3132 9445
+f 6951 28286 24822
+f 28286 6951 6950
+f 20971 28699 28700
+f 3727 22139 21226
+f 28701 28702 28703
+f 28239 20971 28700
+f 28668 28704 28705
+f 28706 28707 28708
+f 27678 28679 27674
+f 28704 28359 15076
+f 27676 5965 5964
+f 27213 27219 27218
+f 28709 28667 28710
+f 28668 28705 28669
+f 28711 28712 28713
+f 28712 28711 28714
+f 28704 15038 28705
+f 5247 28715 2318
+f 26509 12388 12387
+f 15076 28359 5675
+f 28510 28535 28675
+f 25792 28550 25793
+f 28344 28345 28716
+f 28641 28510 28675
+f 183 16803 184
+f 28283 28282 6525
+f 22228 22229 28717
+f 14301 5107 5385
+f 25148 14738 5027
+f 28718 28452 14764
+f 12511 704 28719
+f 26990 28720 28721
+f 28648 6749 3462
+f 26359 22232 22231
+f 2842 3460 3462
+f 2843 2842 3462
+f 28722 28604 28723
+f 869 28722 28723
+f 22909 22911 22235
+f 11018 1616 28724
+f 11015 11016 28680
+f 25793 28551 25120
+f 28661 22725 28681
+f 28682 11015 28680
+f 28659 28557 28661
+f 14046 11015 28682
+f 28239 28700 28665
+f 22725 14046 28681
+f 28725 28293 18872
+f 28251 28243 28697
+f 28286 28725 18872
+f 28726 28316 28293
+f 28725 28726 28293
+f 4450 4449 22277
+f 28727 28317 28316
+f 10568 28728 28683
+f 10569 10568 28683
+f 28728 28729 28684
+f 28683 28728 28684
+f 28729 28730 28685
+f 28684 28729 28685
+f 28730 28731 28686
+f 28685 28730 28686
+f 28731 28732 28687
+f 28686 28731 28687
+f 28732 28733 28688
+f 28687 28732 28688
+f 28733 28734 28689
+f 28688 28733 28689
+f 28734 28735 28690
+f 28689 28734 28690
+f 28735 28736 28691
+f 28690 28735 28691
+f 24976 15420 28691
+f 28736 24976 28691
+f 15399 22595 18615
+f 22630 22629 17992
+f 23275 21794 2861
+f 23382 16159 23379
+f 28726 28727 28316
+f 28737 28335 28317
+f 28727 28737 28317
+f 28738 28336 28335
+f 28737 28738 28335
+f 28739 28337 28336
+f 28738 28739 28336
+f 28740 28355 28337
+f 28248 28261 28741
+f 28739 28740 28337
+f 20971 20972 28660
+f 28275 28742 28743
+f 28744 28602 28601
+f 28699 20971 28660
+f 28621 28744 28601
+f 28745 28578 28602
+f 28746 21564 28572
+f 23171 21564 28747
+f 28748 28749 28547
+f 28543 28545 28547
+f 2020 28515 28750
+f 22268 2020 28750
+f 22268 28750 28714
+f 2330 22268 28714
+f 28751 28711 28713
+f 28711 2330 28714
+f 28751 28713 28752
+f 28753 28751 28752
+f 28753 28752 28540
+f 28539 28753 28540
+f 27602 16800 27625
+f 27626 27625 28748
+f 28754 28755 28434
+f 14847 22280 22139
+f 22278 26026 22279
+f 17833 11184 3367
+f 28756 28707 28706
+f 28757 23663 28758
+f 14017 14019 28759
+f 28760 28761 28762
+f 15233 15232 22794
+f 27584 17601 20578
+f 28763 20836 20838
+f 16882 21506 21508
+f 28722 28764 28765
+f 28604 28722 28765
+f 24147 23949 24041
+f 28765 28764 22231
+f 28766 11018 28724
+f 1616 2334 28767
+f 27396 28161 15283
+f 21587 14433 28768
+f 21290 27676 27675
+f 25993 25994 25989
+f 28667 28669 28710
+f 2320 22913 28302
+f 28709 28710 28769
+f 28599 28709 28769
+f 28254 28665 28696
+f 15396 18685 27504
+f 28261 28743 28741
+f 28243 28254 28696
+f 28770 28358 28355
+f 28771 28268 28772
+f 28740 28770 28355
+f 27573 28773 10568
+f 21737 21777 21776
+f 28773 28774 28728
+f 10568 28773 28728
+f 28774 28775 28729
+f 28728 28774 28729
+f 28775 28776 28730
+f 28729 28775 28730
+f 28776 28777 28731
+f 28730 28776 28731
+f 28777 28778 28732
+f 28731 28777 28732
+f 28779 28733 28732
+f 28778 28779 28732
+f 28779 28780 28734
+f 28733 28779 28734
+f 28780 28781 28735
+f 28734 28780 28735
+f 28782 28736 28735
+f 28781 28782 28735
+f 28783 24976 28736
+f 28782 28783 28736
+f 24974 6374 28784
+f 18873 16657 16656
+f 28785 28377 28358
+f 28770 28785 28358
+f 28786 28315 28787
+f 28785 28788 28378
+f 28251 28697 28692
+f 28249 28248 28772
+f 28261 28275 28743
+f 28236 28692 28742
+f 28789 28790 28791
+f 28275 28236 28742
+f 28744 28745 28602
+f 28789 28791 28578
+f 28745 28789 28578
+f 28790 28792 28791
+f 21564 28746 28747
+f 22022 22024 28793
+f 21564 21435 28572
+f 28794 21069 2343
+f 28512 28511 28795
+f 28542 28796 28797
+f 28495 28511 25617
+f 28798 28799 21624
+f 28795 28798 21624
+f 28511 28798 28795
+f 21624 28799 21625
+f 28799 28800 21625
+f 21625 28800 22145
+f 28800 28801 22145
+f 22145 28801 28513
+f 28801 28508 28513
+f 2489 2488 16753
+f 27625 28749 28748
+f 22458 21619 21621
+f 16854 28721 28802
+f 4337 23343 4338
+f 27604 24335 16751
+f 23496 16132 5508
+f 23235 28716 28574
+f 15341 13807 27581
+f 28749 28546 28547
+f 22952 15341 28803
+f 28803 15341 27581
+f 21562 22952 28804
+f 28804 22952 28803
+f 2336 21562 28805
+f 28805 21562 28804
+f 28724 1616 28767
+f 28806 2336 28805
+f 2334 2336 28806
+f 28767 2334 28806
+f 14433 11018 28766
+f 28807 28808 16768
+f 21588 21587 28573
+f 28809 14433 28766
+f 21437 21588 28571
+f 14433 28809 28768
+f 22024 28810 28793
+f 21587 28768 28573
+f 28811 28411 28450
+f 22022 28793 28812
+f 28813 28450 28792
+f 28813 28811 28450
+f 28248 28741 28772
+f 28790 28813 28792
+f 28377 28785 28378
+f 28315 28314 28787
+f 28788 28814 28402
+f 22283 25082 22282
+f 28815 28816 28773
+f 27573 28815 28773
+f 28816 28817 28774
+f 28773 28816 28774
+f 28817 28818 28775
+f 28774 28817 28775
+f 28818 28819 28776
+f 28775 28818 28776
+f 28819 28820 28777
+f 28776 28819 28777
+f 28820 28821 28778
+f 28777 28820 28778
+f 28821 28822 28779
+f 28778 28821 28779
+f 28822 28823 28780
+f 28779 28822 28780
+f 28824 28781 28780
+f 28823 28824 28780
+f 17217 28782 28781
+f 28824 17217 28781
+f 19825 27571 19823
+f 28782 17217 28783
+f 28378 28788 28402
+f 28814 28825 28403
+f 28402 28814 28403
+f 28825 28826 28415
+f 28314 28292 28827
+f 28403 28825 28415
+f 28828 28829 22394
+f 28787 28314 28827
+f 28828 22394 28411
+f 28811 28828 28411
+f 28830 28831 21568
+f 28829 21568 22394
+f 22175 28832 28833
+f 28829 28830 21568
+f 22024 23171 28810
+f 28308 22175 28833
+f 23171 28747 28810
+f 28794 2343 2181
+f 6090 4973 28709
+f 28359 5121 5246
+f 28386 28342 17550
+f 10452 22909 22235
+f 17329 17855 6262
+f 20337 21674 25454
+f 28506 28505 28347
+f 28481 28484 28482
+f 28487 28493 28488
+f 27425 28834 28835
+f 28492 28483 28493
+f 28836 28486 28837
+f 14968 11222 26757
+f 25297 21099 28522
+f 28838 28839 28840
+f 28841 28842 28843
+f 28843 28838 28840
+f 28839 28844 28845
+f 28844 28846 28845
+f 28846 28847 28845
+f 28840 28839 28845
+f 22830 27270 27272
+f 28842 28838 28843
+f 10979 27763 26167
+f 28535 28542 28797
+f 25262 13850 17805
+f 23290 27425 28835
+f 28797 28796 24334
+f 5392 23376 23377
+f 28764 26359 22231
+f 20421 4841 22786
+f 28848 5965 27676
+f 21289 28848 27676
+f 28807 16768 5965
+f 28848 28807 5965
+f 28808 16767 16768
+f 28849 28631 16767
+f 28808 28849 16767
+f 28850 28851 28631
+f 28850 28852 28851
+f 28849 28850 28631
+f 28852 28853 28851
+f 28854 28855 28853
+f 28852 28854 28853
+f 22177 22022 28812
+f 28856 28857 28855
+f 21663 21662 28858
+f 10429 28859 28860
+f 28861 21669 28831
+f 21361 28862 22049
+f 28318 28315 28786
+f 28863 28318 28786
+f 28826 28864 28416
+f 28865 28333 28863
+f 28415 28826 28416
+f 14990 28866 28815
+f 17219 17220 17705
+f 28866 28867 28816
+f 28815 28866 28816
+f 28867 28868 28817
+f 28816 28867 28817
+f 28868 28869 28818
+f 28817 28868 28818
+f 28869 28870 28819
+f 28818 28869 28819
+f 28870 28871 28820
+f 28819 28870 28820
+f 28871 28872 28821
+f 28820 28871 28821
+f 28872 28873 28822
+f 28821 28872 28822
+f 28874 28823 28822
+f 28873 28874 28822
+f 17218 28824 28823
+f 28874 17218 28823
+f 24980 2673 7669
+f 28824 17218 17217
+f 28875 28273 28771
+f 28268 28249 28772
+f 28876 28291 28875
+f 28273 28268 28771
+f 28292 28291 28876
+f 28827 28292 28876
+f 5382 28877 5383
+f 28291 28273 28875
+f 21662 10429 28860
+f 28878 28862 21361
+f 17385 22110 16625
+f 28879 28308 28880
+f 5271 4806 28704
+f 22177 28812 28832
+f 7366 23710 25040
+f 22175 22177 28832
+f 14867 21324 14868
+f 21620 19922 21621
+f 11099 18509 11100
+f 28854 28856 28855
+f 28594 22478 15684
+f 25048 16021 5531
+f 28881 28882 2333
+f 22377 28883 22397
+f 28884 28885 24556
+f 27602 27601 2488
+f 28466 28886 15310
+f 13343 28466 15310
+f 15310 28886 15217
+f 28886 28887 15217
+f 15217 28887 14447
+f 28887 28463 14447
+f 25316 16470 27565
+f 12466 28888 5622
+f 28676 21805 15111
+f 28889 28676 15111
+f 28639 28642 28890
+f 28891 28639 28890
+f 28892 28238 28893
+f 28638 28639 28891
+f 28237 28238 28892
+f 28893 28638 28891
+f 28894 28237 28892
+f 28238 28638 28893
+f 28642 28676 28889
+f 28890 28642 28889
+f 28233 28237 28894
+f 28505 28348 28347
+f 28232 28233 28895
+f 28895 28233 28894
+f 28662 28232 28896
+f 28896 28232 28895
+f 28647 28662 28897
+f 28897 28662 28896
+f 28898 28645 28899
+f 28899 28647 28897
+f 28900 28645 28898
+f 28901 28900 28898
+f 28902 28900 28901
+f 28645 28647 28899
+f 28903 28904 28905
+f 28905 28902 28901
+f 28716 21222 21221
+f 28574 28716 21221
+f 28906 23233 28857
+f 15316 16696 23660
+f 21663 28858 28907
+f 28559 21663 28907
+f 28908 28255 22049
+f 28909 28908 22049
+f 28338 28333 28865
+f 28910 28338 28865
+f 28864 28911 28433
+f 28416 28864 28433
+f 28911 28912 28436
+f 28433 28911 28436
+f 18001 28454 28436
+f 15421 28913 28866
+f 14990 15421 28866
+f 28913 28914 28867
+f 28866 28913 28867
+f 28914 28915 28868
+f 28867 28914 28868
+f 28915 28916 28869
+f 28868 28915 28869
+f 28916 28917 28870
+f 28869 28916 28870
+f 28917 28918 28871
+f 28870 28917 28871
+f 28918 28919 28872
+f 28871 28918 28872
+f 28919 28920 28873
+f 28872 28919 28873
+f 28920 17303 28874
+f 28873 28920 28874
+f 8128 9833 15190
+f 28874 17303 17218
+f 28830 28861 28831
+f 27597 23233 23244
+f 28861 28921 21669
+f 28921 21618 21669
+f 21618 28921 5382
+f 28921 28877 5382
+f 5383 28878 21361
+f 28877 28878 5383
+f 10428 28922 28859
+f 28862 28909 22049
+f 28906 23024 23233
+f 10429 10428 28859
+f 24697 22962 22961
+f 9549 28923 21436
+f 28856 28906 28857
+f 5533 17752 22306
+f 28885 28884 21673
+f 24517 20955 22751
+f 23241 19838 28903
+f 24557 28924 10450
+f 19838 23241 17210
+f 28904 28902 28905
+f 19839 19838 17210
+f 19838 28904 28903
+f 5118 21619 22458
+f 14150 14152 2016
+f 28925 21141 28926
+f 28927 28928 28929
+f 28446 28444 28387
+f 28388 28390 28389
+f 28930 28931 28932
+f 28932 28931 28464
+f 17532 17531 25147
+f 5121 6093 5246
+f 28364 22825 21619
+f 17831 25039 2501
+f 22574 22576 27657
+f 2500 17831 2501
+f 17847 17975 17732
+f 23927 27980 27611
+f 1751 16783 28281
+f 3261 25748 24547
+f 28933 15655 28282
+f 25976 13816 25858
+f 28281 28933 28282
+f 25748 22572 23032
+f 28934 14605 19019
+f 16155 22234 16156
+f 17276 26946 24881
+f 18336 22644 18337
+f 26554 28935 28936
+f 4345 3727 21226
+f 28937 21628 22572
+f 25748 28937 22572
+f 28938 18958 21628
+f 28937 28938 21628
+f 28939 6523 18958
+f 28938 28939 18958
+f 13485 3055 2848
+f 21148 2847 6523
+f 28939 21148 6523
+f 13486 13485 2848
+f 13486 2848 2847
+f 21148 13486 2847
+f 28345 15338 21222
+f 13485 14634 11023
+f 28702 28756 28940
+f 28574 21221 4538
+f 21662 28860 28858
+f 28622 28701 28703
+f 28908 28941 28252
+f 28559 28907 28942
+f 28333 28318 28863
+f 28255 28908 28252
+f 28912 18001 28436
+f 28354 28338 28910
+f 28943 27761 21656
+f 28454 18001 28472
+f 3653 27643 19995
+f 15590 28944 28913
+f 15421 15590 28913
+f 28944 28945 28914
+f 28913 28944 28914
+f 28945 28946 28915
+f 28914 28945 28915
+f 28946 28947 28916
+f 28915 28946 28916
+f 28947 28948 28917
+f 28916 28947 28917
+f 28948 28949 28918
+f 28917 28948 28918
+f 28950 28919 28918
+f 28949 28950 28918
+f 24761 28920 28919
+f 28950 24761 28919
+f 26327 26421 26330
+f 28920 24761 17303
+f 20019 22306 22294
+f 27572 27410 25819
+f 28295 28951 28276
+f 28952 28953 28277
+f 28276 28952 28277
+f 28953 28954 28262
+f 28955 28956 28957
+f 28958 28955 28957
+f 28879 28880 28922
+f 10428 28879 28922
+f 2813 27476 2814
+f 28308 28833 28880
+f 28716 28345 21222
+f 16072 9062 1216
+f 2025 18995 18994
+f 28345 28343 15338
+f 19839 17210 18995
+f 28343 2025 18994
+f 28959 28960 28137
+f 2025 19839 18995
+f 14746 14150 2015
+f 28961 28962 28963
+f 3055 13485 11023
+f 1861 14746 2015
+f 14634 14746 1861
+f 11023 14634 1861
+f 2015 14150 2016
+f 14152 3052 13403
+f 28964 1862 28965
+f 2017 13404 28966
+f 23106 28967 28968
+f 6383 23106 28271
+f 28969 28930 28932
+f 28931 28465 28464
+f 28970 28930 28969
+f 28971 28970 28969
+f 11088 11090 28972
+f 28973 28970 28974
+f 16627 27102 1624
+f 14820 18039 14821
+f 27571 19825 15187
+f 17635 14237 25269
+f 15321 8556 14946
+f 27643 23172 19995
+f 28673 23105 6382
+f 28975 28924 24557
+f 28976 28673 6382
+f 28673 28672 28977
+f 23105 28673 28977
+f 28973 28974 28977
+f 28672 28973 28977
+f 28970 28971 28974
+f 28978 28976 6382
+f 28465 28445 28447
+f 28979 28978 6381
+f 6381 28978 6382
+f 28980 28979 28981
+f 28981 28979 6381
+f 28982 28980 15443
+f 15443 28980 28981
+f 28982 28983 28984
+f 28983 28982 15443
+f 28538 28984 28985
+f 28538 28982 28984
+f 1862 2017 28965
+f 28986 28538 28985
+f 28987 4228 28988
+f 1860 1862 28964
+f 28575 28574 4538
+f 21622 21223 28536
+f 28989 1703 25708
+f 28575 4538 3259
+f 28990 28559 28942
+f 27694 26810 26809
+f 28941 28991 28266
+f 28990 28942 28992
+f 28993 28354 28910
+f 28252 28941 28266
+f 28994 27043 20754
+f 28356 28354 28993
+f 21569 28608 2173
+f 6138 2493 5619
+f 26152 28472 18001
+f 25629 28995 28944
+f 15590 25629 28944
+f 28995 28996 28945
+f 28944 28995 28945
+f 28996 28997 28946
+f 28945 28996 28946
+f 28997 28998 28947
+f 28946 28997 28947
+f 28998 28999 28948
+f 28947 28998 28948
+f 29000 28949 28948
+f 28999 29000 28948
+f 29001 28950 28949
+f 29000 29001 28949
+f 29001 24762 24761
+f 28950 29001 24761
+f 23386 5027 23810
+f 23313 29002 29003
+f 28401 28379 29004
+f 28373 28375 29005
+f 28379 28373 29006
+f 29007 28379 29006
+f 28954 29008 28278
+f 28277 28953 28262
+f 28958 28957 29009
+f 29010 28958 29009
+f 3145 3535 102
+f 6914 27929 6948
+f 14151 6529 17819
+f 12560 28397 12561
+f 21140 3054 28987
+f 28343 18994 15338
+f 13403 3052 21140
+f 3054 4228 28987
+f 2016 14152 13403
+f 3052 3054 21140
+f 29011 29012 13814
+f 28988 28536 28986
+f 29013 29014 22792
+f 19923 29013 22792
+f 28926 28927 28929
+f 28928 28986 28985
+f 21141 28927 28926
+f 28929 28928 28985
+f 28965 2017 28966
+f 13404 21141 28925
+f 29015 2584 16277
+f 28966 13404 28925
+f 29016 29017 29018
+f 29019 29016 29018
+f 29017 29020 29018
+f 29020 29021 29018
+f 29020 29022 29021
+f 29022 29023 29021
+f 29024 27048 15923
+f 28455 14584 14586
+f 6954 29025 27102
+f 9062 1217 1216
+f 29025 29026 21079
+f 27102 29025 21079
+f 28427 29027 28428
+f 7007 8506 8505
+f 2953 8690 25787
+f 18112 13333 18100
+f 29028 29029 29030
+f 20330 15589 29031
+f 29022 29028 29032
+f 29032 29028 29030
+f 29033 29016 29019
+f 29023 29022 29032
+f 28409 23106 28968
+f 29034 29033 29019
+f 29033 29034 28968
+f 28967 29033 28968
+f 29029 29035 29036
+f 29030 29029 29036
+f 29035 29037 29038
+f 29036 29035 29038
+f 17590 2862 14705
+f 29037 29039 29040
+f 29038 29037 29040
+f 25217 27351 25215
+f 21411 24752 24819
+f 29039 29041 6384
+f 29042 1860 28964
+f 29043 26823 26127
+f 28988 21622 28536
+f 11024 1860 29042
+f 29044 28575 3259
+f 21223 15340 28537
+f 14224 23347 6240
+f 29044 3259 3258
+f 28607 28990 28992
+f 22597 21331 21330
+f 28991 29045 28263
+f 28607 28992 29046
+f 29047 28356 28993
+f 28266 28991 28263
+f 2007 28521 2320
+f 29006 28373 29005
+f 22912 28522 22913
+f 19922 9158 21621
+f 29048 10427 28629
+f 1740 29049 25629
+f 26152 18003 26150
+f 29049 29050 28995
+f 25629 29049 28995
+f 29050 29051 28996
+f 28995 29050 28996
+f 29051 29052 28997
+f 28996 29051 28997
+f 29052 29053 28998
+f 28997 29052 28998
+f 29053 29054 28999
+f 28998 29053 28999
+f 29055 29000 28999
+f 29054 29055 28999
+f 29055 17485 29001
+f 29000 29055 29001
+f 8474 8473 12322
+f 29001 17485 24762
+f 12767 13169 5122
+f 29056 28413 29004
+f 29057 28559 28990
+f 23126 29058 29059
+f 29060 28414 29056
+f 28413 28401 29004
+f 29008 29061 28279
+f 28262 28954 28278
+f 29010 29009 29062
+f 29063 29010 29062
+f 28117 29064 23924
+f 28410 28701 28622
+f 6527 6529 14151
+f 14747 6527 14151
+f 17211 29065 29066
+f 4228 21622 28988
+f 29067 28600 28594
+f 2849 14265 29068
+f 29069 29070 23180
+f 29012 28585 13814
+f 29070 29071 23181
+f 23180 29070 23181
+f 19190 5808 5807
+f 5808 2339 5809
+f 5271 28668 28667
+f 4973 5271 28667
+f 27595 27615 27594
+f 29072 3540 3539
+f 2585 1317 2586
+f 17711 17723 17768
+f 29073 29019 29074
+f 29075 29076 29077
+f 29078 29079 29080
+f 29018 29021 29081
+f 15911 15910 15446
+f 29079 29082 29080
+f 9833 8128 8127
+f 28280 22910 22909
+f 6953 29083 6954
+f 7433 11185 7431
+f 29083 29084 29025
+f 6954 29083 29025
+f 29084 29085 29026
+f 29025 29084 29026
+f 5391 28115 23375
+f 29026 6788 21079
+f 18099 18100 18215
+f 29085 11557 6788
+f 25177 16990 12545
+f 27923 21630 6385
+f 29086 29087 29088
+f 28924 10451 10450
+f 25785 23567 22390
+f 28695 29072 3539
+f 3540 23237 3541
+f 17409 16364 16363
+f 29040 6384 6386
+f 9156 20212 9157
+f 29038 29040 6386
+f 29040 29039 6384
+f 29036 29038 29089
+f 29089 29038 6386
+f 29030 29036 29090
+f 29090 29036 29089
+f 29032 29030 29091
+f 29091 29030 29090
+f 29019 29018 29074
+f 29092 29032 29091
+f 29093 29075 29077
+f 29034 29019 29073
+f 29094 11024 29042
+f 28300 29095 29096
+f 28536 21223 28537
+f 3056 11024 29094
+f 28627 29044 3258
+f 15340 15339 29097
+f 22597 22649 21331
+f 28627 3258 3053
+f 29098 28607 29046
+f 22649 21901 21331
+f 29045 29099 28269
+f 29098 29046 28956
+f 28375 28356 29047
+f 28263 29045 28269
+f 28379 29007 29004
+f 29005 28375 29047
+f 1616 1615 2334
+f 28414 28413 29056
+f 29100 28032 23128
+f 6472 29101 29049
+f 1740 6472 29049
+f 29101 29102 29050
+f 29049 29101 29050
+f 29102 29103 29051
+f 29050 29102 29051
+f 29103 29104 29052
+f 29051 29103 29052
+f 29104 28426 29053
+f 29052 29104 29053
+f 28426 29105 29054
+f 29053 28426 29054
+f 29105 17509 29055
+f 29054 29105 29055
+f 22141 22140 23969
+f 29055 17509 17485
+f 29106 23126 23128
+f 23607 18776 2233
+f 27692 28032 29100
+f 29107 27692 29100
+f 27692 29107 29108
+f 29109 28418 29110
+f 28432 28414 29060
+f 29061 29111 28287
+f 28278 29008 28279
+f 29063 29062 29112
+f 29113 29063 29112
+f 10297 29114 10298
+f 28580 22648 5798
+f 29115 29116 21025
+f 6529 28625 17819
+f 29117 29067 28594
+f 16727 16978 7557
+f 21066 29118 21015
+f 29067 29119 16021
+f 22011 20977 20979
+f 23050 21014 11019
+f 20681 22751 20791
+f 20955 20954 20811
+f 15320 14257 8219
+f 20791 20955 20811
+f 22792 29014 29120
+f 29121 29122 20337
+f 29023 29032 29092
+f 29123 29023 29092
+f 29074 29018 29081
+f 29021 29023 29123
+f 29124 3586 29125
+f 29081 29021 29123
+f 29126 29048 28629
+f 29127 28309 29128
+f 2410 2409 17998
+f 5247 15189 28715
+f 27302 2502 1541
+f 3362 27573 3360
+f 24269 29083 6953
+f 24270 24269 6953
+f 29129 29084 29083
+f 24269 29129 29083
+f 29129 29130 29085
+f 29084 29129 29085
+f 29130 29131 11557
+f 29085 29130 11557
+f 29131 29132 11556
+f 11557 29131 11556
+f 4450 28429 27694
+f 16822 24108 25691
+f 4806 5121 28359
+f 27616 27594 27615
+f 29133 22020 22315
+f 15518 6517 6516
+f 14520 6528 28399
+f 1052 1054 29134
+f 28883 28593 6794
+f 29135 14520 28399
+f 19072 1868 22724
+f 2170 16231 22138
+f 5673 5259 22442
+f 19243 4962 2322
+f 29136 28274 28260
+f 29137 28247 28257
+f 29137 29138 28247
+f 28270 28551 28256
+f 28640 29137 28257
+f 22783 5672 14025
+f 29139 29034 29073
+f 2666 26962 12466
+f 28366 29140 29095
+f 28968 29034 29139
+f 29141 3056 29094
+f 28980 29142 28979
+f 28537 15340 29097
+f 14265 3056 29141
+f 28628 28627 3053
+f 18996 29142 29097
+f 17600 11090 21901
+f 28628 3053 17819
+f 28955 29098 28956
+f 22649 17600 21901
+f 28269 29099 28295
+f 29143 29144 22862
+f 29099 28951 28295
+f 28951 28952 28276
+f 28418 29109 29145
+f 28471 28418 29145
+f 28032 29106 23128
+f 25560 4842 5393
+f 6629 21810 29101
+f 6472 6629 29101
+f 21810 29146 29102
+f 29101 21810 29102
+f 29146 29147 29103
+f 29102 29146 29103
+f 29147 28427 29104
+f 29103 29147 29104
+f 17509 29105 17486
+f 29104 28427 28426
+f 22249 22794 15232
+f 13377 20451 16881
+f 27869 16314 26885
+f 15023 23856 23855
+f 21794 23274 15383
+f 14948 27692 29108
+f 28453 29148 29149
+f 23235 28344 28716
+f 28279 29061 28287
+f 29110 28432 29060
+f 29113 29112 29144
+f 29111 29150 28310
+f 21325 21324 14867
+f 24969 27373 16216
+f 16728 16727 8120
+f 24992 27137 25063
+f 20811 20954 20922
+f 16460 14345 8310
+f 21156 21148 28939
+f 23029 29151 29152
+f 20538 22750 20681
+f 29153 21156 28939
+f 28705 28240 28242
+f 22751 20955 20791
+f 29120 20212 9156
+f 20954 6940 20922
+f 23202 15423 17855
+f 17590 17589 2862
+f 28550 28640 28257
+f 29154 25297 28522
+f 2665 21099 25301
+f 28256 28550 28257
+f 24396 24394 29155
+f 22877 22869 22965
+f 20540 12068 29156
+f 21959 22199 2897
+f 27648 27647 29157
+f 25627 15587 23729
+f 17662 13289 19340
+f 29158 25192 29159
+f 11390 12932 101
+f 25973 25972 27544
+f 2844 219 17281
+f 24511 25604 24512
+f 28185 29129 24269
+f 16638 25232 25231
+f 28185 29160 29130
+f 29129 28185 29130
+f 29160 29161 29131
+f 29130 29160 29131
+f 25216 24108 29132
+f 29131 29161 29132
+f 2842 25717 6356
+f 26149 26152 26151
+f 25691 24108 27186
+f 24944 27570 18227
+f 24517 28670 4966
+f 2511 21936 22042
+f 29162 29163 29164
+f 29165 28842 28841
+f 29163 29165 29166
+f 29167 29163 29166
+f 29168 29162 29169
+f 29166 29165 28841
+f 29170 29171 29169
+f 29163 29167 29164
+f 29172 29171 29173
+f 29162 29164 29169
+f 29174 29172 29175
+f 29171 29168 29169
+f 29176 29177 29178
+f 29171 29170 29173
+f 25627 29179 15082
+f 29180 29181 29182
+f 29183 28968 29139
+f 27714 29184 16542
+f 29066 29065 28978
+f 28258 29185 29186
+f 29187 14265 29141
+f 15048 22867 29188
+f 15339 18996 29097
+f 22573 18960 29189
+f 28625 28628 17819
+f 17212 29066 29142
+f 29190 16151 29191
+f 28634 19216 29153
+f 29144 22860 22862
+f 17600 17602 28972
+f 28310 29150 28311
+f 2812 2814 17811
+f 28418 28432 29110
+f 29192 29193 28313
+f 14948 29108 23173
+f 28519 28470 29194
+f 23238 27566 15676
+f 10252 14498 1450
+f 8044 21042 12885
+f 21811 29195 29146
+f 21810 21811 29146
+f 29195 29196 29147
+f 29146 29195 29147
+f 29196 29027 28427
+f 29147 29196 28427
+f 1750 22722 1748
+f 28428 29027 23203
+f 22794 22249 25429
+f 26751 27059 29197
+f 29198 29199 29200
+f 28246 28343 28345
+f 22913 22270 28303
+f 26525 26433 26526
+f 28470 28453 29149
+f 5385 26182 14302
+f 28287 29111 28310
+f 28453 28471 29145
+f 28450 28412 2332
+f 29150 29192 28311
+f 13807 2308 16752
+f 29143 29113 29144
+f 28674 6527 14633
+f 23840 28109 23786
+f 16461 22716 14345
+f 8308 8310 14345
+f 15683 22006 28598
+f 29117 28594 28598
+f 29201 27899 27900
+f 25734 25614 22596
+f 28928 28988 28986
+f 13404 13403 21141
+f 29202 29203 22023
+f 29204 14519 14520
+f 21935 19923 19922
+f 22792 29120 9156
+f 29205 29174 29206
+f 29172 29173 29175
+f 29176 29205 29177
+f 29174 29175 29206
+f 29207 29176 29178
+f 29205 29206 29177
+f 15451 12917 3104
+f 4514 22142 4515
+f 25787 3302 3138
+f 27544 24271 27569
+f 21655 17662 19340
+f 26271 21655 19340
+f 17334 29208 17612
+f 16543 179 200
+f 28230 23388 22008
+f 22178 28229 21832
+f 3726 25269 14847
+f 25371 25370 23764
+f 21586 17332 21197
+f 14950 16098 18267
+f 25971 29209 29160
+f 28185 25971 29160
+f 29209 28184 29161
+f 29160 29209 29161
+f 29161 28184 25216
+f 26779 24108 25216
+f 2642 5105 2643
+f 22046 2349 15411
+f 29210 29211 29212
+f 29213 29214 29215
+f 29216 29217 29218
+f 28059 28058 29219
+f 29220 29216 29221
+f 29222 29223 29224
+f 29225 29220 29226
+f 29217 29224 29218
+f 29225 29226 29227
+f 29216 29218 29221
+f 29228 29225 29227
+f 29220 29221 29226
+f 29217 29222 29224
+f 29229 29230 29223
+f 29222 29229 29223
+f 29231 29232 29230
+f 29229 29231 29230
+f 29233 29234 29232
+f 29235 29236 29231
+f 29237 29182 29233
+f 29238 16273 182
+f 28138 29239 21144
+f 22311 15145 29240
+f 15144 29186 29241
+f 5622 15048 29188
+f 22653 15235 6827
+f 22573 29189 29242
+f 23031 22573 29242
+f 18996 17212 29142
+f 29243 29244 29245
+f 28634 29153 29246
+f 29247 28634 29246
+f 1053 16328 1054
+f 21932 27396 27661
+f 23201 3145 102
+f 22715 6261 11099
+f 28311 29192 28313
+f 29248 29249 28339
+f 28519 29194 29250
+f 28520 28519 29250
+f 21157 21159 28386
+f 26752 14948 23173
+f 21041 15852 12885
+f 12885 21042 21041
+f 22053 29251 29195
+f 21811 22053 29195
+f 29251 29252 29196
+f 29195 29251 29196
+f 17716 29027 29196
+f 29252 17716 29196
+f 1484 14227 13734
+f 19473 19318 23007
+f 28201 26791 26790
+f 17654 17550 21496
+f 29253 21157 28386
+f 28554 28553 29254
+f 28520 29250 29255
+f 29193 29256 28332
+f 29148 28453 29145
+f 28313 29193 28332
+f 29256 29248 28339
+f 22949 23236 28575
+f 28265 2667 28374
+f 29257 28296 22533
+f 3586 12271 1052
+f 28400 28674 14633
+f 13484 28400 14633
+f 17211 23242 29258
+f 17212 17211 29066
+f 29259 29117 28598
+f 22459 22023 22177
+f 22309 22308 2510
+f 29260 29012 29011
+f 22716 22715 11099
+f 29261 29260 22041
+f 28668 5271 28704
+f 28882 2181 2333
+f 29237 29180 29182
+f 29207 29178 29181
+f 29182 29262 29234
+f 29231 29233 29232
+f 22281 16334 25935
+f 29233 29182 29234
+f 24856 4395 21658
+f 3655 9118 3653
+f 12917 15451 27559
+f 27570 24943 28365
+f 16501 29263 26271
+f 20813 16501 26271
+f 29263 21656 26271
+f 27251 29264 27252
+f 4498 28231 29265
+f 16230 5256 29266
+f 5256 4498 29265
+f 5400 16230 29267
+f 22943 25314 23753
+f 23207 28109 23205
+f 23323 23322 29268
+f 16627 16628 6961
+f 25971 23323 29209
+f 24910 6538 5867
+f 29268 29269 28184
+f 29209 29268 28184
+f 29269 27351 25217
+f 28184 29269 25217
+f 5113 25753 25564
+f 15170 29270 15171
+f 29271 29272 29273
+f 28884 28296 29257
+f 29274 29275 29212
+f 29215 29271 29273
+f 5681 17829 5682
+f 29219 29274 29212
+f 2644 20288 21150
+f 28058 29274 29219
+f 29276 19214 28633
+f 29277 29276 28633
+f 15171 29270 28060
+f 29278 29127 29128
+f 2323 4964 5387
+f 29279 28115 29280
+f 29136 29281 28274
+f 29282 29135 29283
+f 29181 29284 29262
+f 2335 12538 2336
+f 29236 29237 29233
+f 29182 29181 29262
+f 29285 29286 29287
+f 29236 29233 29231
+f 15145 15144 29241
+f 29239 29285 29287
+f 14019 22651 18944
+f 15145 29241 29240
+f 18960 29288 29189
+f 10969 22653 6827
+f 29244 29289 29290
+f 28062 23031 29291
+f 19216 21156 29153
+f 29292 29244 29290
+f 16216 27373 11390
+f 3260 29247 29293
+f 29294 28346 11025
+f 27661 29280 28115
+f 29295 28353 28360
+f 17304 14736 17305
+f 28470 29149 29194
+f 29249 29295 28360
+f 29296 29297 28955
+f 28553 29255 29254
+f 29253 28386 28385
+f 2821 29298 22053
+f 12666 2821 22053
+f 29298 29299 29251
+f 22053 29298 29251
+f 29299 29300 29252
+f 29251 29299 29252
+f 29300 17717 17716
+f 29252 29300 17716
+f 23008 19473 23075
+f 23009 23008 23075
+f 25990 29301 28555
+f 28554 29254 29302
+f 28605 28607 29098
+f 28332 29256 28339
+f 28553 28520 29255
+f 29249 28360 28339
+f 27582 17731 27445
+f 24944 26618 24945
+f 28161 28136 15284
+f 25330 3160 15342
+f 21731 15513 5077
+f 19215 13587 21156
+f 22579 28296 22604
+f 29065 17211 29258
+f 6527 14747 14633
+f 6373 29303 29304
+f 23242 29305 29306
+f 6373 2849 29303
+f 14265 29187 29068
+f 29307 29308 29297
+f 28305 28624 28623
+f 28409 28968 29183
+f 29309 28271 29310
+f 15080 17742 104
+f 1769 28138 21144
+f 9322 13471 9323
+f 29180 29207 29181
+f 17497 15418 24976
+f 12638 28178 28221
+f 6338 3868 4478
+f 23125 11390 101
+f 14246 25337 16865
+f 2995 5659 2415
+f 9705 29311 16501
+f 17601 23382 26826
+f 29312 29263 16501
+f 29311 29312 16501
+f 25935 22111 6256
+f 29312 28943 29263
+f 25213 25142 5801
+f 17375 17374 17190
+f 16230 29266 29267
+f 16304 16310 9413
+f 23323 29268 29209
+f 5256 29265 29266
+f 16309 17002 15460
+f 12934 16469 13851
+f 29026 29085 6788
+f 2665 25301 26962
+f 29313 29269 29268
+f 9136 9135 2349
+f 29313 3044 27351
+f 29269 29313 27351
+f 14771 12464 14323
+f 3043 27351 3044
+f 29314 29315 29213
+f 17549 3262 25981
+f 29316 29317 29318
+f 29319 29315 29314
+f 29272 29317 29316
+f 29320 29321 29318
+f 29273 29272 29316
+f 29317 29322 29318
+f 29322 29320 29318
+f 29320 29323 29324
+f 29325 29326 29327
+f 29214 29271 29215
+f 29321 29320 29324
+f 29328 29325 29327
+f 29328 29327 29324
+f 29323 29328 29324
+f 29297 29098 28955
+f 5532 29329 17752
+f 29178 29330 29284
+f 29181 29178 29284
+f 29235 29231 29229
+f 29331 29235 29229
+f 29332 29333 29286
+f 29285 29332 29286
+f 22312 22311 29240
+f 29334 22312 29240
+f 28759 14019 18944
+f 22651 22653 10969
+f 28063 28062 29335
+f 23031 29242 29291
+f 29289 29336 29337
+f 29290 29289 29337
+f 1507 25614 24613
+f 29247 29246 29293
+f 20337 25454 20213
+f 15923 4490 14830
+f 29338 28285 28087
+f 17265 17306 26904
+f 29339 28372 28353
+f 29295 29339 28353
+f 28636 29302 29340
+f 28588 28636 29340
+f 27566 15677 15676
+f 29301 5794 5108
+f 2820 29341 29298
+f 2821 2820 29298
+f 29341 29342 29299
+f 29298 29341 29299
+f 29342 29343 29300
+f 29299 29342 29300
+f 29343 16346 17717
+f 29300 29343 17717
+f 17717 16346 16348
+f 5253 28765 22954
+f 27582 12644 12700
+f 22791 16143 22718
+f 19824 19823 26132
+f 28636 28554 29302
+f 21659 13342 21657
+f 25365 23841 23788
+f 17832 12228 17063
+f 13479 29344 22782
+f 27735 23856 16756
+f 17366 17365 22345
+f 19216 19215 21156
+f 15283 29280 27661
+f 29258 23242 29306
+f 28400 13484 13587
+f 18960 18959 29288
+f 29305 29345 28671
+f 18959 6373 29304
+f 2849 29068 29303
+f 10813 28305 28623
+f 29346 29347 29348
+f 29349 29350 28558
+f 29126 28629 21661
+f 25744 25745 28063
+f 29310 28409 29183
+f 23097 986 2503
+f 25990 28555 25991
+f 16775 29351 16779
+f 16724 17173 16761
+f 29351 29352 16319
+f 16779 29351 16319
+f 29352 29353 9704
+f 16319 29352 9704
+f 29353 29354 9705
+f 9704 29353 9705
+f 29354 29355 29311
+f 9705 29354 29311
+f 29356 29312 29311
+f 29355 29356 29311
+f 29357 28943 29312
+f 29356 29357 29312
+f 27510 27761 28943
+f 29357 27510 28943
+f 7574 21485 20827
+f 28472 26152 26149
+f 1630 29358 16806
+f 21832 28230 22008
+f 16409 23319 22784
+f 16318 15756 16776
+f 22008 23388 16409
+f 23982 27900 26256
+f 22239 46 5959
+f 9276 1536 9275
+f 29313 21250 3044
+f 29313 28201 21250
+f 17223 20153 25178
+f 29359 12973 3044
+f 15992 17223 25178
+f 16801 16448 16447
+f 29360 29319 29314
+f 26282 17466 26374
+f 29319 29360 29361
+f 29315 29214 29213
+f 29362 29361 29363
+f 29362 29319 29361
+f 29364 29363 29365
+f 29364 29362 29363
+f 29366 29367 29368
+f 29367 29364 29365
+f 29366 29368 29369
+f 29370 29366 29369
+f 29371 29372 29326
+f 29325 29371 29326
+f 28769 28235 28234
+f 23313 17279 29002
+f 29177 29373 29330
+f 29178 29177 29330
+f 29374 29375 29217
+f 29331 29229 29222
+f 29376 29377 29333
+f 29332 29376 29333
+f 29378 28708 29379
+f 28762 22312 29334
+f 2021 22333 22724
+f 1867 2021 22724
+f 28063 29335 29380
+f 21371 28063 29380
+f 29336 29381 29382
+f 29337 29336 29382
+f 17376 29383 17374
+f 16537 16286 17611
+f 25618 28512 28635
+f 14345 22716 11098
+f 7017 5209 2418
+f 18933 25337 14246
+f 29384 28380 28372
+f 29339 29384 28372
+f 28581 28589 29385
+f 28588 29340 29386
+f 28555 29301 5108
+f 21271 2328 28711
+f 4801 23426 29341
+f 2820 4801 29341
+f 23426 4397 29342
+f 29341 23426 29342
+f 17662 27569 17661
+f 29342 4397 29343
+f 12228 12230 17063
+f 14817 8392 14814
+f 7433 3368 3367
+f 9558 17996 2928
+f 27373 11388 11390
+f 8367 8368 5536
+f 25229 25228 16639
+f 12796 5648 14675
+f 21216 9741 7157
+f 21723 18943 16207
+f 15132 6533 6535
+f 13930 20378 14938
+f 24396 27446 17730
+f 29306 29305 28671
+f 19215 28400 13587
+f 10208 10122 10210
+f 29243 29245 28671
+f 2493 2495 5619
+f 18904 27930 27338
+f 15235 1868 19072
+f 2765 27477 25249
+f 6827 15235 19072
+f 18944 22651 10969
+f 986 23097 22746
+f 15144 28258 29186
+f 2409 2408 25025
+f 28162 22711 29387
+f 16833 29388 16775
+f 21371 21370 25744
+f 29388 29389 29351
+f 16775 29388 29351
+f 29389 29390 29352
+f 29351 29389 29352
+f 29390 29391 29353
+f 29352 29390 29353
+f 29391 29392 29354
+f 29353 29391 29354
+f 29392 29393 29355
+f 29354 29392 29355
+f 29394 29356 29355
+f 29393 29394 29355
+f 29395 29357 29356
+f 29394 29395 29356
+f 29387 27510 29357
+f 29395 29387 29357
+f 11201 10953 22282
+f 23253 27476 4336
+f 17143 16096 24762
+f 17483 17509 17484
+f 29396 29119 29067
+f 26698 29359 21249
+f 29397 29329 29119
+f 29398 29396 29067
+f 17565 5460 12931
+f 29396 29397 29119
+f 14674 5648 14020
+f 13930 7432 7431
+f 27788 12973 29359
+f 26698 27788 29359
+f 5540 16345 24308
+f 11198 23024 28906
+f 6260 16242 18040
+f 29399 29400 29401
+f 23250 1869 1871
+f 5471 22445 5469
+f 18266 17867 1870
+f 6259 16243 16242
+f 22064 21069 28794
+f 9592 10375 5469
+f 26328 22064 28794
+f 28987 28988 28928
+f 29367 29365 29368
+f 29402 29403 22445
+f 29404 29405 29372
+f 29370 29369 29406
+f 28606 29057 28990
+f 29371 29404 29372
+f 29206 29407 29373
+f 14969 19243 2322
+f 29375 29331 29222
+f 29177 29206 29373
+f 29408 29409 29377
+f 29410 29374 29216
+f 29379 28762 29334
+f 29376 29408 29377
+f 2168 22138 22333
+f 29411 28706 29378
+f 28062 29291 29335
+f 2021 2168 22333
+f 29381 29412 29413
+f 21371 29380 29414
+f 3260 29293 3261
+f 29382 29381 29413
+f 27696 23983 23984
+f 5622 29188 5623
+f 28285 28283 28087
+f 26509 28264 12388
+f 29384 29415 28381
+f 13172 11100 18509
+f 28589 28588 29386
+f 28380 29384 28381
+f 14111 14110 19190
+f 25995 28581 28437
+f 21271 28711 28751
+f 2822 17331 4801
+f 29416 29417 29418
+f 4801 17331 23426
+f 2589 2588 16653
+f 9272 29418 29419
+f 10450 10452 22234
+f 25280 21657 13342
+f 16155 10450 22234
+f 29420 29086 29421
+f 17880 17879 21614
+f 17832 29422 11184
+f 17833 17832 11184
+f 29422 29423 17502
+f 11184 29422 17502
+f 29423 18943 21723
+f 17502 29423 21723
+f 6245 26328 26327
+f 16321 16207 18943
+f 29345 29243 28671
+f 20550 26823 29424
+f 27895 23549 23548
+f 29244 29292 29245
+f 17385 29425 22110
+f 8295 6698 6640
+f 22111 25935 16334
+f 16625 17436 17385
+f 29426 28802 29427
+f 17072 17014 25198
+f 28271 29309 29185
+f 28271 28409 29310
+f 12068 12067 29156
+f 28258 28271 29185
+f 29428 29429 16833
+f 25744 28063 21371
+f 29429 29430 29388
+f 16833 29429 29388
+f 29430 29431 29389
+f 29388 29430 29389
+f 29431 29432 29390
+f 29389 29431 29390
+f 29432 29433 29391
+f 29390 29432 29391
+f 29433 29434 29392
+f 29391 29433 29392
+f 29434 29435 29393
+f 29392 29434 29393
+f 29436 29394 29393
+f 29435 29436 29393
+f 29437 29395 29394
+f 29436 29437 29394
+f 29438 29387 29395
+f 29437 29438 29395
+f 29438 29439 28162
+f 29387 29438 28162
+f 14412 29440 17719
+f 29441 16012 16014
+f 27445 17730 27446
+f 25370 27788 26698
+f 29442 29443 29444
+f 29445 29442 29444
+f 29445 29444 29329
+f 29397 29445 29329
+f 26969 27788 26972
+f 26505 22315 6372
+f 16301 17727 7317
+f 22955 22957 6103
+f 29446 29447 29448
+f 16625 16213 17436
+f 29449 28630 27526
+f 29450 29372 29451
+f 29452 29453 29399
+f 29401 29449 27526
+f 29448 29447 29452
+f 29400 29449 29401
+f 1751 28285 1752
+f 29453 29400 29399
+f 16151 14111 29191
+f 23262 27239 3314
+f 5471 29402 22445
+f 28584 22750 22708
+f 29454 29370 29406
+f 29455 29456 29403
+f 29404 29457 29446
+f 29454 29406 29458
+f 25614 25613 27763
+f 29405 29404 29446
+f 29175 29454 29407
+f 19194 13169 13168
+f 29375 29222 29217
+f 29206 29175 29407
+f 29408 23204 29459
+f 29460 29410 29220
+f 28708 28762 29379
+f 29409 29408 29459
+f 2168 2170 22138
+f 29461 28940 29411
+f 14622 21371 29414
+f 15220 28576 4810
+f 29412 29462 29463
+f 14622 29414 27143
+f 27661 28115 5391
+f 29413 29412 29463
+f 3136 24219 3137
+f 23251 23343 23368
+f 28792 28450 2332
+f 22603 22602 25995
+f 29464 28404 28381
+f 2667 12467 28374
+f 28589 29386 29385
+f 29415 29464 28381
+f 6086 21271 28751
+f 25858 25857 25968
+f 16767 28631 4648
+f 10985 17294 17331
+f 2822 10985 17331
+f 15383 14901 12961
+f 29418 27716 29416
+f 9310 9309 15706
+f 6247 24546 25564
+f 2328 2330 28711
+f 28631 28851 28632
+f 22911 28321 28610
+f 28851 29465 28632
+f 13336 9276 10958
+f 25034 23079 25035
+f 29466 29467 29422
+f 17832 29466 29422
+f 29467 29468 29423
+f 29422 29467 29423
+f 29468 23232 18943
+f 29423 29468 18943
+f 27678 27649 23177
+f 23921 18820 23979
+f 25863 13816 25976
+f 18959 29304 29288
+f 24512 25604 26931
+f 22110 15711 22111
+f 29425 25965 22110
+f 29383 29425 17385
+f 7442 3314 27239
+f 15460 17002 15992
+f 29239 29287 21144
+f 6258 6257 27320
+f 25365 5115 23841
+f 3156 3155 17013
+f 6258 29469 29428
+f 29470 29471 29472
+f 29469 29473 29429
+f 29428 29469 29429
+f 29473 29474 29430
+f 29429 29473 29430
+f 29474 29475 29431
+f 29430 29474 29431
+f 29475 29476 29432
+f 29431 29475 29432
+f 29476 29477 29433
+f 29432 29476 29433
+f 29477 29478 29434
+f 29433 29477 29434
+f 29479 29435 29434
+f 29478 29479 29434
+f 29480 29436 29435
+f 29479 29480 29435
+f 29481 29437 29436
+f 29480 29481 29436
+f 29482 29438 29437
+f 29481 29482 29437
+f 29482 29483 29439
+f 29438 29482 29439
+f 29483 28340 27603
+f 29439 29483 27603
+f 16095 17216 17219
+f 26794 23753 25314
+f 29442 29484 22307
+f 21674 29485 25454
+f 29486 29487 28975
+f 28885 29486 28975
+f 27603 23102 29439
+f 29487 29488 28924
+f 28927 28987 28928
+f 15058 29489 29490
+f 29442 29491 29484
+f 25250 22151 22150
+f 29405 29446 29492
+f 29493 29494 29495
+f 29326 29372 29450
+f 29451 29405 29492
+f 29488 29326 29450
+f 29372 29405 29451
+f 29492 29446 29448
+f 29447 29453 29452
+f 29058 24161 15040
+f 29496 27549 27548
+f 29416 27716 28108
+f 22005 15682 15215
+f 29402 29455 29403
+f 3625 16465 14027
+f 29407 29454 29458
+f 29497 29498 29456
+f 29457 29499 29447
+f 29373 29407 29500
+f 23405 23391 17456
+f 29446 29457 29447
+f 29173 29370 29454
+f 29501 28156 14605
+f 29374 29217 29216
+f 29175 29173 29454
+f 14846 1347 1851
+f 29410 29216 29220
+f 28706 28708 29378
+f 29459 23204 27693
+f 25762 25760 22440
+f 28940 28706 29411
+f 24933 24995 24932
+f 2293 16232 16231
+f 29462 29502 29503
+f 29504 6101 27143
+f 25990 28601 29301
+f 29463 29462 29503
+f 28603 28580 5798
+f 27716 29418 9272
+f 22045 8500 22046
+f 28624 28628 28625
+f 29464 29505 28431
+f 28374 12467 28376
+f 28581 29385 28437
+f 28404 29464 28431
+f 28342 28341 29247
+f 28602 28578 28580
+f 28853 29506 29465
+f 16890 26523 25042
+f 10985 6467 17294
+f 28320 28637 28584
+f 5264 15109 24877
+f 28342 29247 3260
+f 17550 28342 3260
+f 14771 14322 15451
+f 28341 28634 29247
+f 17063 17062 29466
+f 14026 14968 26756
+f 17062 29507 29466
+f 21250 29359 3044
+f 29507 29508 29467
+f 29466 29507 29467
+f 29508 29509 29468
+f 29467 29508 29468
+f 29509 29510 23232
+f 29468 29509 23232
+f 29510 29511 17376
+f 23232 29510 17376
+f 29511 29512 29383
+f 17376 29511 29383
+f 29512 29513 29425
+f 29383 29512 29425
+f 29514 25965 29425
+f 29513 29514 29425
+f 28783 17217 17703
+f 29514 15712 25965
+f 28067 2410 17998
+f 4397 23426 7265
+f 27320 29515 6258
+f 27271 29516 27272
+f 29515 29517 29469
+f 6258 29515 29469
+f 29517 29518 29473
+f 29469 29517 29473
+f 29518 29519 29474
+f 29473 29518 29474
+f 29519 29520 29475
+f 29474 29519 29475
+f 29520 29521 29476
+f 29475 29520 29476
+f 29521 29522 29477
+f 29476 29521 29477
+f 29522 29523 29478
+f 29477 29522 29478
+f 29524 29479 29478
+f 29523 29524 29478
+f 29525 29480 29479
+f 29524 29525 29479
+f 29525 29526 29481
+f 29480 29525 29481
+f 29527 29482 29481
+f 29526 29527 29481
+f 29528 29483 29482
+f 29527 29528 29482
+f 29528 29516 28340
+f 29483 29528 28340
+f 17611 17465 16537
+f 24934 24936 21610
+f 11153 25124 642
+f 27271 27270 18937
+f 29529 29486 21672
+f 17991 15419 15418
+f 29450 29451 28280
+f 10451 29450 28280
+f 13814 28586 13815
+f 15424 17590 21161
+f 29530 29491 29442
+f 5118 28364 21619
+f 29495 29494 29531
+f 29532 29533 29396
+f 29484 29493 29495
+f 29534 29535 29531
+f 29491 29493 29484
+f 29494 29536 29531
+f 29445 29530 29442
+f 28031 27692 27574
+f 24161 27514 15041
+f 22150 22193 22192
+f 28032 28031 29106
+f 27693 14603 28156
+f 28669 28242 28241
+f 6102 22955 6103
+f 29455 29497 29456
+f 29537 29538 29498
+f 29373 29500 29539
+f 29330 29373 29539
+f 29540 29453 29447
+f 29499 29540 29447
+f 29541 28156 29501
+f 29537 29541 29501
+f 29170 29366 29370
+f 29173 29170 29370
+f 29542 29543 29228
+f 29460 29220 29225
+f 29154 22912 28521
+f 27271 18937 18939
+f 29544 28622 29545
+f 28703 28940 29461
+f 28761 24514 22312
+f 5255 15219 24317
+f 6099 6101 29504
+f 29546 6099 29504
+f 29502 29547 29548
+f 29503 29502 29548
+f 2319 2327 11016
+f 28399 28674 28400
+f 28357 5623 21414
+f 28710 28241 28235
+f 28791 28792 2331
+f 28792 2332 2331
+f 29505 29549 28451
+f 28431 29505 28451
+f 27261 26864 16258
+f 29550 14763 14765
+f 641 28183 29551
+f 22694 3309 29552
+f 6954 6960 6952
+f 10425 8989 25042
+f 16008 15914 16009
+f 4973 28667 28709
+f 28088 28087 28283
+f 29553 17671 18007
+f 28635 28795 21667
+f 29553 29554 29507
+f 17062 29553 29507
+f 29554 29555 29508
+f 29507 29554 29508
+f 29555 29556 29509
+f 29508 29555 29509
+f 29556 29557 29510
+f 29509 29556 29510
+f 29557 29558 29511
+f 29510 29557 29511
+f 29558 29559 29512
+f 29511 29558 29512
+f 29559 29560 29513
+f 29512 29559 29513
+f 29561 29514 29513
+f 29560 29561 29513
+f 29562 15712 29514
+f 29561 29562 29514
+f 29562 29563 27320
+f 15712 29562 27320
+f 29563 29564 29515
+f 27320 29563 29515
+f 29564 29565 29517
+f 29515 29564 29517
+f 29565 29566 29518
+f 29517 29565 29518
+f 29566 29567 29519
+f 29518 29566 29519
+f 29567 29568 29520
+f 29519 29567 29520
+f 29569 29521 29520
+f 29568 29569 29520
+f 29570 29522 29521
+f 29569 29570 29521
+f 29571 29523 29522
+f 29570 29571 29522
+f 29572 29524 29523
+f 29571 29572 29523
+f 29573 29525 29524
+f 29572 29573 29524
+f 29573 29574 29526
+f 29525 29573 29526
+f 29574 29575 29527
+f 29526 29574 29527
+f 29576 29528 29527
+f 29575 29576 29527
+f 29576 29577 29516
+f 29528 29576 29516
+f 29577 29578 27272
+f 29516 29577 27272
+f 6849 29579 6958
+f 29578 24212 27272
+f 3366 15867 15865
+f 26526 26433 26434
+f 29451 29492 22910
+f 29580 29529 28507
+f 22445 16460 9592
+f 28280 29451 22910
+f 6377 25082 22283
+f 21545 21575 21178
+f 29530 29445 29397
+f 22349 15167 3926
+f 29532 29396 29398
+f 29533 29530 29397
+f 29581 29532 29398
+f 29533 29397 29396
+f 2765 22192 17236
+f 28959 22010 28960
+f 2765 17237 2766
+f 22874 22875 27545
+f 5164 14435 5162
+f 27510 29387 22711
+f 22280 25305 25304
+f 29361 29582 29583
+f 29497 29537 29498
+f 5401 5400 28556
+f 29407 29458 29500
+f 29537 29501 29584
+f 29540 23027 29400
+f 29330 29539 29585
+f 5258 19305 19242
+f 29453 29540 29400
+f 29169 29367 29366
+f 29586 29587 29455
+f 29543 29460 29225
+f 29170 29169 29366
+f 22046 2350 2349
+f 29543 29225 29228
+f 29545 28703 29461
+f 25231 29154 28521
+f 29128 28309 28308
+f 28622 28703 29545
+f 24885 24884 24995
+f 15442 15145 22311
+f 29547 29588 29589
+f 29590 15165 29546
+f 29550 14765 25303
+f 29548 29547 29589
+f 29591 29253 17653
+f 24483 24793 24482
+f 12467 5621 28376
+f 17654 17653 28385
+f 29549 29592 28469
+f 15038 28704 15076
+f 14763 28718 14764
+f 28451 29549 28469
+f 5680 5684 5551
+f 28577 29113 29143
+f 17327 17329 22715
+f 10427 29128 10428
+f 22910 28479 22911
+f 25268 25266 29593
+f 2169 20335 2170
+f 21981 26948 21982
+f 28943 21656 29263
+f 18008 29594 29554
+f 29553 18008 29554
+f 29594 29595 29555
+f 29554 29594 29555
+f 29595 29596 29556
+f 29555 29595 29556
+f 29596 29597 29557
+f 29556 29596 29557
+f 29597 29598 29558
+f 29557 29597 29558
+f 29598 29599 29559
+f 29558 29598 29559
+f 29600 29560 29559
+f 29599 29600 29559
+f 29601 29561 29560
+f 29600 29601 29560
+f 29602 29562 29561
+f 29601 29602 29561
+f 29602 29603 29563
+f 29562 29602 29563
+f 29603 29604 29564
+f 29563 29603 29564
+f 29604 29605 29565
+f 29564 29604 29565
+f 29605 29606 29566
+f 29565 29605 29566
+f 29606 29607 29567
+f 29566 29606 29567
+f 29607 29608 29568
+f 29567 29607 29568
+f 29609 29569 29568
+f 29608 29609 29568
+f 29610 29570 29569
+f 29609 29610 29569
+f 29611 29571 29570
+f 29610 29611 29570
+f 29612 29572 29571
+f 29611 29612 29571
+f 29613 29573 29572
+f 29612 29613 29572
+f 29613 29614 29574
+f 29573 29613 29574
+f 29614 29615 29575
+f 29574 29614 29575
+f 29616 29576 29575
+f 29615 29616 29575
+f 29616 29617 29577
+f 29576 29616 29577
+f 29617 29618 29578
+f 29577 29617 29578
+f 27254 24212 29578
+f 29618 27254 29578
+f 13290 17661 17711
+f 27899 28365 24943
+f 29486 28885 21672
+f 29443 29442 22307
+f 29492 29448 28479
+f 29619 29580 29122
+f 16978 5048 7557
+f 22910 29492 28479
+f 29456 22714 16461
+f 6260 6259 16242
+f 25907 2659 23567
+f 29403 29456 16461
+f 2021 14920 2168
+f 22445 29403 16460
+f 22723 26943 22722
+f 29498 17327 22714
+f 16347 16346 17571
+f 23244 23233 23023
+f 6746 2951 13332
+f 6249 29620 28183
+f 29363 29361 29583
+f 16728 8120 6095
+f 15038 15037 28240
+f 29360 29621 29582
+f 29538 29537 29584
+f 3584 3586 29124
+f 29284 29330 29585
+f 29501 14605 28934
+f 23027 23028 29449
+f 29284 29585 29534
+f 29541 29537 29497
+f 29400 23027 29449
+f 29164 29364 29367
+f 29587 29541 29497
+f 29622 29542 29623
+f 20336 29121 20337
+f 22956 11429 22957
+f 27573 3362 28815
+f 28347 28349 29624
+f 28622 29544 29625
+f 28703 28702 28940
+f 21932 27661 5391
+f 14449 15165 29590
+f 29626 14449 29590
+f 29588 29627 28227
+f 29589 29588 28227
+f 25762 28560 25760
+f 2510 29628 21936
+f 29629 21157 29253
+f 29591 29629 29253
+f 3043 23714 25215
+f 28391 29589 28226
+f 29592 29630 28496
+f 28469 29592 28496
+f 868 1274 29631
+f 22006 17696 17695
+f 29282 29204 29135
+f 13051 2172 13052
+f 28334 14026 26756
+f 29133 28881 22020
+f 28675 4814 21805
+f 2321 2320 28302
+f 14020 5648 9380
+f 17374 29383 17385
+f 24653 21977 24582
+f 8686 29632 18008
+f 18007 18008 29553
+f 29632 29633 29594
+f 18008 29632 29594
+f 29633 29634 29595
+f 29594 29633 29595
+f 29634 29635 29596
+f 29595 29634 29596
+f 29635 29636 29597
+f 29596 29635 29597
+f 29636 29637 29598
+f 29597 29636 29598
+f 29637 29638 29599
+f 29598 29637 29599
+f 29639 29600 29599
+f 29638 29639 29599
+f 29640 29601 29600
+f 29639 29640 29600
+f 29640 29641 29602
+f 29601 29640 29602
+f 29641 29642 29603
+f 29602 29641 29603
+f 29642 29643 29604
+f 29603 29642 29604
+f 29643 29644 29605
+f 29604 29643 29605
+f 29644 29645 29606
+f 29605 29644 29606
+f 29645 29646 29607
+f 29606 29645 29607
+f 29646 29647 29608
+f 29607 29646 29608
+f 29647 29648 29609
+f 29608 29647 29609
+f 29649 29610 29609
+f 29648 29649 29609
+f 29650 29611 29610
+f 29649 29650 29610
+f 29651 29612 29611
+f 29650 29651 29611
+f 29652 29613 29612
+f 29651 29652 29612
+f 29652 29653 29614
+f 29613 29652 29614
+f 29653 29654 29615
+f 29614 29653 29615
+f 29655 29616 29615
+f 29654 29655 29615
+f 29655 29656 29617
+f 29616 29655 29617
+f 29656 29657 29618
+f 29617 29656 29618
+f 29197 27254 29618
+f 29657 29197 29618
+f 18407 18156 18826
+f 5168 5170 7064
+f 29484 29495 22308
+f 29398 29067 29117
+f 29529 21672 28507
+f 22307 29484 22308
+f 29448 29452 28480
+f 29658 29619 29122
+f 26256 27900 26445
+f 28479 29448 28480
+f 4812 5823 21013
+f 16871 9516 7670
+f 27653 25025 2408
+f 17183 22084 17238
+f 21351 9021 3421
+f 5197 17762 16090
+f 29659 2766 22723
+f 1750 29659 22723
+f 19668 17589 19019
+f 29660 23545 10155
+f 2658 29661 4964
+f 22578 6163 28611
+f 29361 29360 29582
+f 29363 29583 29662
+f 28593 23180 6794
+f 29314 29663 29621
+f 29584 29501 28934
+f 22459 29664 22023
+f 29262 29284 29534
+f 17001 25833 17222
+f 23028 22148 28630
+f 29262 29534 29536
+f 5966 4647 28284
+f 29449 23028 28630
+f 28507 21674 20337
+f 28386 21159 28342
+f 29665 29551 29159
+f 21935 21934 19923
+f 28349 28622 29625
+f 29620 24879 29158
+f 28879 29128 28308
+f 28349 29625 29624
+f 15165 6099 29546
+f 27254 29197 27058
+f 29627 29666 26813
+f 29667 15218 29626
+f 836 838 16955
+f 28227 29627 26813
+f 29668 21158 21157
+f 16783 28933 28281
+f 22954 22231 22233
+f 29629 29668 21157
+f 29630 29669 28497
+f 15189 5806 28715
+f 15774 15773 24124
+f 28496 29630 28497
+f 29191 14111 29670
+f 4758 17622 4759
+f 28715 29671 2325
+f 26823 29043 29424
+f 2238 26216 2239
+f 28397 28449 12561
+f 18939 28340 27271
+f 1274 29672 29631
+f 16243 16884 17668
+f 25584 25432 25430
+f 8686 18007 16287
+f 24270 17768 17723
+f 8685 29673 29632
+f 8686 8685 29632
+f 29673 29674 29633
+f 29632 29673 29633
+f 29674 29675 29634
+f 29633 29674 29634
+f 29675 29676 29635
+f 29634 29675 29635
+f 29676 29677 29636
+f 29635 29676 29636
+f 29677 29678 29637
+f 29636 29677 29637
+f 29678 29679 29638
+f 29637 29678 29638
+f 29680 29639 29638
+f 29679 29680 29638
+f 29681 29640 29639
+f 29680 29681 29639
+f 29681 29682 29641
+f 29640 29681 29641
+f 29682 29683 29642
+f 29641 29682 29642
+f 29683 29684 29643
+f 29642 29683 29643
+f 29684 29685 29644
+f 29643 29684 29644
+f 29685 29686 29645
+f 29644 29685 29645
+f 29686 29687 29646
+f 29645 29686 29646
+f 29687 29688 29647
+f 29646 29687 29647
+f 29688 29689 29648
+f 29647 29688 29648
+f 29690 29649 29648
+f 29689 29690 29648
+f 29691 29650 29649
+f 29690 29691 29649
+f 29692 29651 29650
+f 29691 29692 29650
+f 29693 29652 29651
+f 29692 29693 29651
+f 29693 29694 29653
+f 29652 29693 29653
+f 29694 29695 29654
+f 29653 29694 29654
+f 29695 29696 29655
+f 29654 29695 29655
+f 29696 29697 29656
+f 29655 29696 29656
+f 29697 29698 29657
+f 29656 29697 29657
+f 26751 29197 29657
+f 29698 26751 29657
+f 28182 28204 29699
+f 18117 5169 5168
+f 29700 29398 29117
+f 23388 23319 16409
+f 29531 29628 22308
+f 29701 29700 29259
+f 29121 29658 29122
+f 29495 29531 22308
+f 29401 27526 27525
+f 29702 29703 29014
+f 29399 29401 29704
+f 29704 29401 27525
+f 29452 29399 28319
+f 28319 29399 29704
+f 27143 14623 14622
+f 28480 29452 28319
+f 21219 29659 1750
+f 3322 3921 1796
+f 27102 21079 1624
+f 21219 29660 29659
+f 29659 10155 2766
+f 29660 10155 29659
+f 29365 29363 29662
+f 23172 27643 27616
+f 29360 29314 29621
+f 29365 29662 29705
+f 29706 29707 29708
+f 29314 29213 29702
+f 21793 178 25834
+f 21159 29277 28341
+f 29234 29262 29536
+f 6193 13850 25264
+f 28366 27899 29201
+f 29140 28366 29201
+f 17752 29444 28597
+f 29709 22307 22309
+f 22825 21933 21935
+f 21934 29013 19923
+f 16223 16222 22018
+f 29158 24879 15172
+f 28506 28347 29624
+f 29710 28506 29624
+f 26505 12386 12388
+f 16205 26944 19491
+f 29711 15450 29667
+f 15218 14449 29626
+f 15112 26811 15113
+f 29666 15113 26811
+f 29712 28491 25616
+f 15040 15042 18226
+f 29713 29714 21158
+f 29668 29713 21158
+f 7858 8393 6466
+f 9916 9445 186
+f 29669 29715 28517
+f 28497 29669 28517
+f 22861 4811 22862
+f 26963 17236 22193
+f 8309 6893 8914
+f 2326 20953 5542
+f 23426 14817 7265
+f 28556 29267 28640
+f 22222 25048 22252
+f 2660 2659 25907
+f 6093 15189 5247
+f 16537 29716 16538
+f 9384 9383 25709
+f 29716 29717 8687
+f 16538 29716 8687
+f 29717 29718 8685
+f 8687 29717 8685
+f 29718 29719 29673
+f 8685 29718 29673
+f 29719 29720 29674
+f 29673 29719 29674
+f 29720 29721 29675
+f 29674 29720 29675
+f 29721 29722 29676
+f 29675 29721 29676
+f 29722 29723 29677
+f 29676 29722 29677
+f 29723 29724 29678
+f 29677 29723 29678
+f 29724 29725 29679
+f 29678 29724 29679
+f 29726 29680 29679
+f 29725 29726 29679
+f 29727 29681 29680
+f 29726 29727 29680
+f 29727 29728 29682
+f 29681 29727 29682
+f 29728 29729 29683
+f 29682 29728 29683
+f 29729 29730 29684
+f 29683 29729 29684
+f 29730 29731 29685
+f 29684 29730 29685
+f 29731 29732 29686
+f 29685 29731 29686
+f 29732 29733 29687
+f 29686 29732 29687
+f 29733 29734 29688
+f 29687 29733 29688
+f 29734 29735 29689
+f 29688 29734 29689
+f 29736 29690 29689
+f 29735 29736 29689
+f 29737 29691 29690
+f 29736 29737 29690
+f 29738 29692 29691
+f 29737 29738 29691
+f 29739 29693 29692
+f 29738 29739 29692
+f 29739 29740 29694
+f 29693 29739 29694
+f 29740 29741 29695
+f 29694 29740 29695
+f 29741 29742 29696
+f 29695 29741 29696
+f 29743 29697 29696
+f 29742 29743 29696
+f 29743 29744 29698
+f 29697 29743 29698
+f 29744 26750 26751
+f 29698 29744 26751
+f 16346 29343 4399
+f 27569 24271 17723
+f 29745 29701 22006
+f 29700 29117 29259
+f 27658 27902 27448
+f 29701 29259 22006
+f 29535 29746 29260
+f 17695 29745 22006
+f 29703 29658 29121
+f 29261 29535 29260
+f 29702 29014 29013
+f 29747 29703 29121
+f 29663 29702 29013
+f 29703 29747 29014
+f 9878 9877 9950
+f 29580 28507 29122
+f 2047 21560 21589
+f 21589 21560 25407
+f 29748 29660 21219
+f 17305 29748 21219
+f 23546 23545 29660
+f 29748 23546 29660
+f 29749 16484 16486
+f 25654 3819 25417
+f 29368 29365 29705
+f 5111 15321 14946
+f 29663 29314 29702
+f 29368 29705 29750
+f 29276 29283 19214
+f 29213 29215 29703
+f 29329 29444 17752
+f 29127 29751 28309
+f 29114 28959 28137
+f 22358 13813 22362
+f 29270 15170 11920
+f 29169 29164 29367
+f 28364 22824 22825
+f 29752 29622 29210
+f 24271 27544 25972
+f 29753 29754 16642
+f 28482 28485 29755
+f 28506 29710 29756
+f 21140 28987 28927
+f 22218 5545 25042
+f 15311 15450 29711
+f 29757 15311 29711
+f 27498 16718 27499
+f 23402 1779 23403
+f 25617 28512 25618
+f 19838 12559 28904
+f 29758 29759 29714
+f 29713 29758 29714
+f 17622 22026 17623
+f 2243 14015 2244
+f 29715 29760 28518
+f 28517 29715 28518
+f 28637 29704 28670
+f 28670 27525 4967
+f 16802 16805 22683
+f 29208 17334 17333
+f 1541 2502 17797
+f 7347 3508 10500
+f 17365 24959 29428
+f 28670 24517 25176
+f 17612 29761 16537
+f 28160 28182 29699
+f 29761 29762 29716
+f 16537 29761 29716
+f 29762 29763 29717
+f 29716 29762 29717
+f 29763 29764 29718
+f 29717 29763 29718
+f 29764 29765 29719
+f 29718 29764 29719
+f 29765 29766 29720
+f 29719 29765 29720
+f 29766 29767 29721
+f 29720 29766 29721
+f 29767 29768 29722
+f 29721 29767 29722
+f 29768 29769 29723
+f 29722 29768 29723
+f 29769 29770 29724
+f 29723 29769 29724
+f 29770 29771 29725
+f 29724 29770 29725
+f 29772 29726 29725
+f 29771 29772 29725
+f 29773 29727 29726
+f 29772 29773 29726
+f 29773 29774 29728
+f 29727 29773 29728
+f 29774 29775 29729
+f 29728 29774 29729
+f 29775 29776 29730
+f 29729 29775 29730
+f 29776 29777 29731
+f 29730 29776 29731
+f 29777 29778 29732
+f 29731 29777 29732
+f 29778 29779 29733
+f 29732 29778 29733
+f 29779 29780 29734
+f 29733 29779 29734
+f 29780 29781 29735
+f 29734 29780 29735
+f 29781 29782 29736
+f 29735 29781 29736
+f 29783 29737 29736
+f 29782 29783 29736
+f 29784 29738 29737
+f 29783 29784 29737
+f 29785 29739 29738
+f 29784 29785 29738
+f 29785 29786 29740
+f 29739 29785 29740
+f 29786 29787 29741
+f 29740 29786 29741
+f 29787 29788 29742
+f 29741 29787 29742
+f 29789 29743 29742
+f 29788 29789 29742
+f 29790 29744 29743
+f 29789 29790 29743
+f 29790 5803 26750
+f 29744 29790 26750
+f 4284 5508 16132
+f 15041 27547 15042
+f 29791 28592 28585
+f 29792 29791 28585
+f 29791 29793 28592
+f 29793 29069 28592
+f 29793 29750 29069
+f 29750 29070 29069
+f 29792 28585 29012
+f 29705 29071 29070
+f 29794 29012 29260
+f 29794 29792 29012
+f 29535 29261 29628
+f 29746 29794 29260
+f 11028 14736 17304
+f 29531 29535 29628
+f 13590 13589 16423
+f 23324 23323 22875
+f 14736 29748 17305
+f 11028 17304 6797
+f 14736 14735 23546
+f 29748 14736 23546
+f 1665 1664 16663
+f 18989 18988 18245
+f 28705 15038 28240
+f 21069 21068 2519
+f 29369 29368 29750
+f 14920 2169 2168
+f 29702 29213 29703
+f 29458 29406 29791
+f 4648 28632 28259
+f 29215 29273 29658
+f 28883 6794 22397
+f 28600 29067 16021
+f 29164 29167 29362
+f 29587 29497 29455
+f 29542 29228 29623
+f 29364 29164 29362
+f 5682 17831 2500
+f 29622 29623 29210
+f 28485 28506 29756
+f 29270 29795 28060
+f 28384 25510 26218
+f 28485 29756 29755
+f 15450 15218 29667
+f 7925 28180 28202
+f 29796 29797 29082
+f 29798 13344 29757
+f 22863 16783 16784
+f 29079 29796 29082
+f 29799 29282 29759
+f 29093 29077 29800
+f 22233 26356 22790
+f 29758 29799 29759
+f 29760 29801 28552
+f 26137 29802 26135
+f 29267 29137 28640
+f 28518 29760 28552
+f 10500 29803 29552
+f 5117 28364 5118
+f 29119 29329 5532
+f 7347 10500 29552
+f 26904 17306 1749
+f 27674 21290 27679
+f 5802 26750 5803
+f 29208 29804 29761
+f 17612 29208 29761
+f 29804 29805 29762
+f 29761 29804 29762
+f 29805 29806 29763
+f 29762 29805 29763
+f 29806 29807 29764
+f 29763 29806 29764
+f 29807 29808 29765
+f 29764 29807 29765
+f 29808 29809 29766
+f 29765 29808 29766
+f 29809 29810 29767
+f 29766 29809 29767
+f 29810 29811 29768
+f 29767 29810 29768
+f 29811 29812 29769
+f 29768 29811 29769
+f 29812 29813 29770
+f 29769 29812 29770
+f 29813 29814 29771
+f 29770 29813 29771
+f 29815 29772 29771
+f 29814 29815 29771
+f 29816 29773 29772
+f 29815 29816 29772
+f 29816 29817 29774
+f 29773 29816 29774
+f 29817 29818 29775
+f 29774 29817 29775
+f 29818 29819 29776
+f 29775 29818 29776
+f 29819 29820 29777
+f 29776 29819 29777
+f 29820 29821 29778
+f 29777 29820 29778
+f 29821 29822 29779
+f 29778 29821 29779
+f 29822 29823 29780
+f 29779 29822 29780
+f 29824 29781 29780
+f 29823 29824 29780
+f 29824 29825 29782
+f 29781 29824 29782
+f 29826 29783 29782
+f 29825 29826 29782
+f 29827 29784 29783
+f 29826 29827 29783
+f 29827 29828 29785
+f 29784 29827 29785
+f 29828 29829 29786
+f 29785 29828 29786
+f 29829 29830 29787
+f 29786 29829 29787
+f 29831 29788 29787
+f 29830 29831 29787
+f 29832 29789 29788
+f 29831 29832 29788
+f 29832 29833 29790
+f 29789 29832 29790
+f 29833 25214 5803
+f 29790 29833 5803
+f 17375 23232 17376
+f 20756 25213 29834
+f 24377 10956 10097
+f 28384 28065 25693
+f 29621 29663 21934
+f 18936 17823 27043
+f 29582 29621 21933
+f 29663 29013 21934
+f 22824 29583 21933
+f 29621 21934 21933
+f 28363 29662 22824
+f 29583 29582 21933
+f 29705 29662 29071
+f 29662 29583 22824
+f 29750 29705 29070
+f 29662 28363 29071
+f 27902 28443 27659
+f 6797 25606 6798
+f 25431 25429 22249
+f 28834 24777 29835
+f 13566 10987 10884
+f 10974 15990 15734
+f 13566 10974 15734
+f 6356 3460 2842
+f 27622 26884 23080
+f 21161 17590 14705
+f 28669 28705 28242
+f 15038 15076 15039
+f 29369 29750 29793
+f 28769 28710 28235
+f 29424 26998 20550
+f 29406 29369 29793
+f 28065 28408 28066
+f 25786 5678 16002
+f 29151 29836 29152
+f 17303 24761 16096
+f 29167 29166 29319
+f 29362 29167 29319
+f 29837 29752 29210
+f 29275 29837 29210
+f 10969 6827 4802
+f 29795 29838 29839
+f 28482 29755 29840
+f 28483 28482 29840
+f 17410 17409 16363
+f 16364 17471 16365
+f 25491 21097 29798
+f 13344 15311 29757
+f 28670 4967 4966
+f 8968 28596 23661
+f 28704 4806 28359
+f 28643 28902 28904
+f 29841 29204 29282
+f 29799 29841 29282
+f 22011 20979 22012
+f 2238 5971 6950
+f 29801 20291 15507
+f 28552 29801 15507
+f 28244 28246 28344
+f 29306 28671 28673
+f 21655 21654 17662
+f 29842 28725 28286
+f 29427 28721 28720
+f 26523 26434 22218
+f 14111 19190 29670
+f 17333 29843 29208
+f 29834 25213 25214
+f 29843 29844 29804
+f 29208 29843 29804
+f 29844 29845 29805
+f 29804 29844 29805
+f 29845 29846 29806
+f 29805 29845 29806
+f 29846 29847 29807
+f 29806 29846 29807
+f 29847 29848 29808
+f 29807 29847 29808
+f 29848 29849 29809
+f 29808 29848 29809
+f 29849 29850 29810
+f 29809 29849 29810
+f 29850 29851 29811
+f 29810 29850 29811
+f 29851 29852 29812
+f 29811 29851 29812
+f 29852 29853 29813
+f 29812 29852 29813
+f 29853 29854 29814
+f 29813 29853 29814
+f 29855 29815 29814
+f 29854 29855 29814
+f 29856 29816 29815
+f 29855 29856 29815
+f 29856 29857 29817
+f 29816 29856 29817
+f 29857 29858 29818
+f 29817 29857 29818
+f 29858 29859 29819
+f 29818 29858 29819
+f 29859 29860 29820
+f 29819 29859 29820
+f 29860 29861 29821
+f 29820 29860 29821
+f 29861 29862 29822
+f 29821 29861 29822
+f 29862 29863 29823
+f 29822 29862 29823
+f 29863 29864 29824
+f 29823 29863 29824
+f 29865 29825 29824
+f 29864 29865 29824
+f 29866 29826 29825
+f 29865 29866 29825
+f 29867 29827 29826
+f 29866 29867 29826
+f 29867 29868 29828
+f 29827 29867 29828
+f 29868 29869 29829
+f 29828 29868 29829
+f 29869 29870 29830
+f 29829 29869 29830
+f 29871 29831 29830
+f 29870 29871 29830
+f 29872 29832 29831
+f 29871 29872 29831
+f 29872 29873 29833
+f 29832 29872 29833
+f 29873 29874 25214
+f 29833 29873 25214
+f 22150 22149 22193
+f 29874 29834 25214
+f 29834 28994 20756
+f 28065 28056 28068
+f 17354 1623 1622
+f 17830 7366 25040
+f 17638 24588 17166
+f 17630 17166 24588
+f 3324 18624 18652
+f 29157 27628 27624
+f 28694 28693 28962
+f 29836 28961 28963
+f 28961 28694 28962
+f 22317 2509 22331
+f 22042 29875 22353
+f 13813 13815 22362
+f 9550 9549 21436
+f 25454 29485 22511
+f 6244 21067 22064
+f 23420 1779 23402
+f 10974 13566 10884
+f 6799 11029 11028
+f 9374 27523 14886
+f 26522 26526 26523
+f 25042 16891 16890
+f 9548 21563 23098
+f 13202 21670 27347
+f 28408 28065 28384
+f 29593 29876 17697
+f 6090 28709 28599
+f 17697 25268 29593
+f 22951 5540 5539
+f 28117 26843 29424
+f 29043 28117 29424
+f 28384 25693 25510
+f 29877 29878 29879
+f 29166 28841 29315
+f 28585 28592 28586
+f 29880 29837 29275
+f 29274 29880 29275
+f 28060 29795 29839
+f 29838 29881 29880
+f 28483 29840 29882
+f 28493 28483 29882
+f 29883 18247 22658
+f 29884 29883 22658
+f 22550 15234 28560
+f 21097 13344 29798
+f 27715 27714 16540
+f 28296 28884 28297
+f 27239 23262 23261
+f 29885 29093 29800
+f 29886 14519 29204
+f 29841 29886 29204
+f 5623 21415 21414
+f 21776 23969 21737
+f 22983 14780 7738
+f 3461 3460 8222
+f 28596 29887 23661
+f 29245 28973 28672
+f 6950 29842 28286
+f 29888 28726 28725
+f 16164 29889 17292
+f 16128 16164 17292
+f 29889 29890 17333
+f 6531 6530 3308
+f 29890 29891 29843
+f 17333 29890 29843
+f 29891 29892 29844
+f 29843 29891 29844
+f 29892 29893 29845
+f 29844 29892 29845
+f 29893 29894 29846
+f 29845 29893 29846
+f 29894 29895 29847
+f 29846 29894 29847
+f 29895 29896 29848
+f 29847 29895 29848
+f 29896 29897 29849
+f 29848 29896 29849
+f 29897 29898 29850
+f 29849 29897 29850
+f 29898 29899 29851
+f 29850 29898 29851
+f 29899 29900 29852
+f 29851 29899 29852
+f 29900 29901 29853
+f 29852 29900 29853
+f 29901 29902 29854
+f 29853 29901 29854
+f 29902 29903 29855
+f 29854 29902 29855
+f 29904 29856 29855
+f 29903 29904 29855
+f 29904 29905 29857
+f 29856 29904 29857
+f 29905 29906 29858
+f 29857 29905 29858
+f 29906 29907 29859
+f 29858 29906 29859
+f 29907 29908 29860
+f 29859 29907 29860
+f 29908 29909 29861
+f 29860 29908 29861
+f 29909 29910 29862
+f 29861 29909 29862
+f 29910 29911 29863
+f 29862 29910 29863
+f 29911 29912 29864
+f 29863 29911 29864
+f 29913 29865 29864
+f 29912 29913 29864
+f 29914 29866 29865
+f 29913 29914 29865
+f 29915 29867 29866
+f 29914 29915 29866
+f 29915 29916 29868
+f 29867 29915 29868
+f 29916 29917 29869
+f 29868 29916 29869
+f 29917 29918 29870
+f 29869 29917 29870
+f 29919 29871 29870
+f 29918 29919 29870
+f 29920 29872 29871
+f 29919 29920 29871
+f 29920 29921 29873
+f 29872 29920 29873
+f 29921 29922 29874
+f 29873 29921 29874
+f 29922 29923 29834
+f 29874 29922 29834
+f 29923 27543 28994
+f 29834 29923 28994
+f 23096 28154 28155
+f 23092 14778 25743
+f 5400 29267 28556
+f 26779 25216 25215
+f 29708 29707 29924
+f 16800 2488 16798
+f 29664 29202 22023
+f 29925 29706 29926
+f 29283 28398 19214
+f 29751 29664 22176
+f 29002 22228 29927
+f 29277 28633 28341
+f 29097 28982 28538
+f 23024 11198 14748
+f 2488 16800 27602
+f 17855 28677 6262
+f 27349 16606 23094
+f 14437 14438 23613
+f 20921 6236 6235
+f 29086 29088 29421
+f 8309 9592 8310
+f 10451 28280 10452
+f 21620 21935 19922
+f 29403 16461 16460
+f 29928 29929 26129
+f 28986 28536 28538
+f 26128 9273 26129
+f 7360 23774 23773
+f 29064 28117 29043
+f 29929 29064 29043
+f 2126 29930 22846
+f 25765 28887 15130
+f 29319 29166 29315
+f 23181 29071 5117
+f 29839 29880 29274
+f 28058 29839 29274
+f 29839 29838 29880
+f 29881 29931 29837
+f 28488 29932 29933
+f 28837 28488 29933
+f 16444 10297 11791
+f 11791 10299 5663
+f 26326 26328 28882
+f 27081 25819 27336
+f 28465 29382 28445
+f 29413 29463 28444
+f 29934 14959 15130
+f 22372 15678 22373
+f 29935 10812 14519
+f 29886 29935 14519
+f 29011 13814 13813
+f 14767 16469 12934
+f 2501 25039 23380
+f 28376 5621 28357
+f 29258 29306 28976
+f 17614 21473 17615
+f 29842 29888 28725
+f 28596 28583 29887
+f 29936 28727 28726
+f 18936 27543 18934
+f 16164 17055 29889
+f 26553 29937 29890
+f 29889 26553 29890
+f 29937 29938 29891
+f 29890 29937 29891
+f 29938 29939 29892
+f 29891 29938 29892
+f 29939 29940 29893
+f 29892 29939 29893
+f 29940 29941 29894
+f 29893 29940 29894
+f 29941 29942 29895
+f 29894 29941 29895
+f 29942 29943 29896
+f 29895 29942 29896
+f 29943 29944 29897
+f 29896 29943 29897
+f 29944 29945 29898
+f 29897 29944 29898
+f 29945 29946 29899
+f 29898 29945 29899
+f 29946 29947 29900
+f 29899 29946 29900
+f 29947 29948 29901
+f 29900 29947 29901
+f 29948 29949 29902
+f 29901 29948 29902
+f 29949 29950 29903
+f 29902 29949 29903
+f 29951 29904 29903
+f 29950 29951 29903
+f 29951 29952 29905
+f 29904 29951 29905
+f 29952 29953 29906
+f 29905 29952 29906
+f 29953 29954 29907
+f 29906 29953 29907
+f 29954 29955 29908
+f 29907 29954 29908
+f 29955 29956 29909
+f 29908 29955 29909
+f 29956 29957 29910
+f 29909 29956 29910
+f 29957 29958 29911
+f 29910 29957 29911
+f 29958 29959 29912
+f 29911 29958 29912
+f 29960 29913 29912
+f 29959 29960 29912
+f 29961 29914 29913
+f 29960 29961 29913
+f 29962 29915 29914
+f 29961 29962 29914
+f 29962 29963 29916
+f 29915 29962 29916
+f 29963 29964 29917
+f 29916 29963 29917
+f 29964 29965 29918
+f 29917 29964 29918
+f 29966 29919 29918
+f 29965 29966 29918
+f 29967 29920 29919
+f 29966 29967 29919
+f 29968 29921 29920
+f 29967 29968 29920
+f 29968 29969 29922
+f 29921 29968 29922
+f 29969 29970 29923
+f 29922 29969 29923
+f 29970 29971 27543
+f 29923 29970 27543
+f 25039 14424 23380
+f 29971 18934 27543
+f 29456 29498 22714
+f 17589 28934 19019
+f 29498 29538 17327
+f 29538 17328 17327
+f 17328 29538 23202
+f 29538 29584 23202
+f 29584 28934 23202
+f 28934 17588 23202
+f 17588 28934 17589
+f 29064 23929 27086
+f 28006 25044 17531
+f 28609 29925 29926
+f 21069 2519 2343
+f 5401 28556 25792
+f 22018 27521 25169
+f 27526 22372 22371
+f 3228 3425 3226
+f 15774 24124 24072
+f 28300 28366 29095
+f 20954 4966 6940
+f 22045 23429 8500
+f 28924 29488 10451
+f 2502 15594 17797
+f 4637 2350 8502
+f 25025 14690 25026
+f 27902 27659 27448
+f 23929 29064 29929
+f 29928 23929 29929
+f 28428 23203 17400
+f 22942 22248 22439
+f 28363 22824 28364
+f 25375 25430 25432
+f 28060 29839 28058
+f 29159 25192 25191
+f 29880 29881 29837
+f 29931 29972 29752
+f 28493 29882 29932
+f 28488 28493 29932
+f 29973 29114 10297
+f 16444 29973 10297
+f 28264 26326 28881
+f 26328 28794 28882
+f 28931 29337 28465
+f 29382 29413 28445
+f 24857 4394 29934
+f 11388 17065 11389
+f 29974 28304 10812
+f 29935 29974 10812
+f 6357 14280 15153
+f 2327 5541 6749
+f 14398 13872 13871
+f 12063 12062 15014
+f 27239 23346 7442
+f 27654 29975 14691
+f 5246 6093 5247
+f 25974 25976 25858
+f 29888 29936 28726
+f 29976 28737 28727
+f 25748 23032 24548
+f 23323 25973 22875
+f 16961 29977 29937
+f 26553 16961 29937
+f 29977 29978 29938
+f 29937 29977 29938
+f 29978 29979 29939
+f 29938 29978 29939
+f 29979 29980 29940
+f 29939 29979 29940
+f 29980 29981 29941
+f 29940 29980 29941
+f 29981 29982 29942
+f 29941 29981 29942
+f 29982 29983 29943
+f 29942 29982 29943
+f 29983 29984 29944
+f 29943 29983 29944
+f 29984 29985 29945
+f 29944 29984 29945
+f 29985 29986 29946
+f 29945 29985 29946
+f 29986 29987 29947
+f 29946 29986 29947
+f 29987 29988 29948
+f 29947 29987 29948
+f 29988 29989 29949
+f 29948 29988 29949
+f 29990 29950 29949
+f 29989 29990 29949
+f 29991 29951 29950
+f 29990 29991 29950
+f 29991 29992 29952
+f 29951 29991 29952
+f 29992 29993 29953
+f 29952 29992 29953
+f 29993 29994 29954
+f 29953 29993 29954
+f 29994 29995 29955
+f 29954 29994 29955
+f 29995 29996 29956
+f 29955 29995 29956
+f 29996 29997 29957
+f 29956 29996 29957
+f 29998 29958 29957
+f 29997 29998 29957
+f 29998 29999 29959
+f 29958 29998 29959
+f 30000 29960 29959
+f 29999 30000 29959
+f 30001 29961 29960
+f 30000 30001 29960
+f 30002 29962 29961
+f 30001 30002 29961
+f 30002 30003 29963
+f 29962 30002 29963
+f 30003 30004 29964
+f 29963 30003 29964
+f 30004 30005 29965
+f 29964 30004 29965
+f 30006 29966 29965
+f 30005 30006 29965
+f 30007 29967 29966
+f 30006 30007 29966
+f 30008 29968 29967
+f 30007 30008 29967
+f 30008 30009 29969
+f 29968 30008 29969
+f 30009 30010 29970
+f 29969 30009 29970
+f 30010 30011 29971
+f 29970 30010 29971
+f 27843 18934 29971
+f 30011 27843 29971
+f 27217 27219 28504
+f 25874 27033 24479
+f 30012 29581 29700
+f 26167 27763 26161
+f 30013 30012 29701
+f 29581 29398 29700
+f 30014 30013 29745
+f 30012 29700 29701
+f 30015 30014 17695
+f 30013 29701 29745
+f 29876 30015 17695
+f 17697 29876 17695
+f 16021 29119 5532
+f 30014 29745 17695
+f 4967 27525 22371
+f 9384 17494 26864
+f 27410 15187 27618
+f 27619 27608 25031
+f 28975 29487 28924
+f 29889 17333 17292
+f 3017 3016 9154
+f 29488 29450 10451
+f 17404 22655 17405
+f 1742 26359 29631
+f 30016 29928 15072
+f 29419 30016 15072
+f 6253 23929 29928
+f 30016 6253 29928
+f 7008 8505 11479
+f 3410 2481 2816
+f 3411 3410 3607
+f 27545 22875 25973
+f 28030 4396 4395
+f 21936 29261 22041
+f 29837 29931 29752
+f 30017 29622 29752
+f 28837 29933 30018
+f 29797 28837 30018
+f 28480 28319 28321
+f 29704 28637 28320
+f 26326 28882 28881
+f 29257 22533 22513
+f 28930 29290 28931
+f 29337 29382 28465
+f 29424 26843 26998
+f 4394 14959 29934
+f 30019 28322 28304
+f 29974 30019 28304
+f 28593 29069 23180
+f 22716 11099 11098
+f 1743 30020 22040
+f 1468 12704 5062
+f 26712 22949 29044
+f 26712 29044 28627
+f 4814 28797 4815
+f 22234 10452 22235
+f 29936 29976 28727
+f 30021 28738 28737
+f 7565 2426 2425
+f 14946 4336 4338
+f 30022 30023 29977
+f 16961 30022 29977
+f 30023 30024 29978
+f 29977 30023 29978
+f 30024 30025 29979
+f 29978 30024 29979
+f 30025 30026 29980
+f 29979 30025 29980
+f 30026 30027 29981
+f 29980 30026 29981
+f 30027 30028 29982
+f 29981 30027 29982
+f 30028 30029 29983
+f 29982 30028 29983
+f 30029 30030 29984
+f 29983 30029 29984
+f 30030 30031 29985
+f 29984 30030 29985
+f 30031 30032 29986
+f 29985 30031 29986
+f 30032 30033 29987
+f 29986 30032 29987
+f 30033 30034 29988
+f 29987 30033 29988
+f 30034 30035 29989
+f 29988 30034 29989
+f 30035 30036 29990
+f 29989 30035 29990
+f 30036 30037 29991
+f 29990 30036 29991
+f 30037 30038 29992
+f 29991 30037 29992
+f 30038 30039 29993
+f 29992 30038 29993
+f 30039 30040 29994
+f 29993 30039 29994
+f 30040 30041 29995
+f 29994 30040 29995
+f 30042 29996 29995
+f 30041 30042 29995
+f 30042 30043 29997
+f 29996 30042 29997
+f 30043 30044 29998
+f 29997 30043 29998
+f 30044 30045 29999
+f 29998 30044 29999
+f 30046 30000 29999
+f 30045 30046 29999
+f 30046 30047 30001
+f 30000 30046 30001
+f 30048 30002 30001
+f 30047 30048 30001
+f 30048 30049 30003
+f 30002 30048 30003
+f 30049 30050 30004
+f 30003 30049 30004
+f 30050 30051 30005
+f 30004 30050 30005
+f 30052 30006 30005
+f 30051 30052 30005
+f 30053 30007 30006
+f 30052 30053 30006
+f 30054 30008 30007
+f 30053 30054 30007
+f 30054 30055 30009
+f 30008 30054 30009
+f 30055 30056 30010
+f 30009 30055 30010
+f 30056 29344 30011
+f 30010 30056 30011
+f 13479 27843 30011
+f 29344 13479 30011
+f 25753 25365 25367
+f 24711 18935 18934
+f 3986 20215 20808
+f 3988 20215 3986
+f 29585 29746 29535
+f 29536 29534 29531
+f 29539 29794 29746
+f 29534 29585 29535
+f 29500 29792 29794
+f 29585 29539 29746
+f 29458 29791 29792
+f 29539 29500 29794
+f 29406 29793 29791
+f 29500 29458 29792
+f 16632 27505 16312
+f 2845 10842 220
+f 3545 14324 14323
+f 1540 27302 1541
+f 26885 26884 27622
+f 22165 25091 27505
+f 15824 15823 20813
+f 27671 23176 29506
+f 23102 28162 29439
+f 6535 27505 15132
+f 30057 30016 29419
+f 29418 30057 29419
+f 30058 6253 30016
+f 30057 30058 30016
+f 3410 2816 3607
+f 30058 6254 6253
+f 26469 28222 28224
+f 30059 28205 2587
+f 23877 22254 24064
+f 28597 29443 29709
+f 29972 30017 29752
+f 30060 29542 29622
+f 29797 30018 30061
+f 29082 29797 30061
+f 30062 28959 29114
+f 29973 30062 29114
+f 23981 21684 19956
+f 26700 25817 25035
+f 28970 29292 28930
+f 29290 29337 28931
+f 23924 15700 27536
+f 4395 4394 24857
+f 30063 28325 28322
+f 30019 30063 28322
+f 21619 22825 21620
+f 28579 1880 22648
+f 29419 15072 9272
+f 17634 2593 9933
+f 21744 21347 28324
+f 22048 2845 23099
+f 29976 30021 28737
+f 30064 28739 28738
+f 30021 30064 28738
+f 30065 28740 28739
+f 17791 30066 30022
+f 22464 13009 4325
+f 30066 30067 30023
+f 30022 30066 30023
+f 30067 30068 30024
+f 30023 30067 30024
+f 30068 30069 30025
+f 30024 30068 30025
+f 30070 30026 30025
+f 30069 30070 30025
+f 30071 30027 30026
+f 30070 30071 30026
+f 30071 30072 30028
+f 30027 30071 30028
+f 30072 30073 30029
+f 30028 30072 30029
+f 30073 30074 30030
+f 30029 30073 30030
+f 30074 30075 30031
+f 30030 30074 30031
+f 30075 30076 30032
+f 30031 30075 30032
+f 30076 30077 30033
+f 30032 30076 30033
+f 30077 30078 30034
+f 30033 30077 30034
+f 30078 30079 30035
+f 30034 30078 30035
+f 30079 30080 30036
+f 30035 30079 30036
+f 30080 30081 30037
+f 30036 30080 30037
+f 30081 30082 30038
+f 30037 30081 30038
+f 30082 30083 30039
+f 30038 30082 30039
+f 30083 30084 30040
+f 30039 30083 30040
+f 30084 30085 30041
+f 30040 30084 30041
+f 30086 30042 30041
+f 30085 30086 30041
+f 30087 30043 30042
+f 30086 30087 30042
+f 30087 30088 30044
+f 30043 30087 30044
+f 30088 30089 30045
+f 30044 30088 30045
+f 30089 30090 30046
+f 30045 30089 30046
+f 30090 30091 30047
+f 30046 30090 30047
+f 30091 30092 30048
+f 30047 30091 30048
+f 30092 30093 30049
+f 30048 30092 30049
+f 30094 30050 30049
+f 30093 30094 30049
+f 30095 30051 30050
+f 30094 30095 30050
+f 30096 30052 30051
+f 30095 30096 30051
+f 30097 30053 30052
+f 30096 30097 30052
+f 30098 30054 30053
+f 30097 30098 30053
+f 30099 30055 30054
+f 30098 30099 30054
+f 30099 30100 30056
+f 30055 30099 30056
+f 30100 22782 29344
+f 30056 30100 29344
+f 8555 23262 3314
+f 28185 25972 25971
+f 23372 22598 23373
+f 30101 3576 17317
+f 29326 29488 29487
+f 29327 29326 29487
+f 29324 29327 29487
+f 29486 29324 29487
+f 29324 29486 29529
+f 29321 29324 29529
+f 29321 29529 29580
+f 29318 29321 29580
+f 29318 29580 29619
+f 29316 29318 29619
+f 29703 29215 29658
+f 29273 29316 29619
+f 17329 6262 6261
+f 29658 29273 29619
+f 23346 27240 6241
+f 17365 29428 16833
+f 6525 7361 6526
+f 29579 17890 6958
+f 7361 6525 28282
+f 27445 24342 27582
+f 17359 17361 2832
+f 25091 15132 27505
+f 30102 30057 29418
+f 29417 30102 29418
+f 30103 30058 30057
+f 30102 30103 30057
+f 24063 6254 30058
+f 30103 24063 30058
+f 21289 27676 21290
+f 16861 28721 16854
+f 27719 27701 28284
+f 29444 29443 28597
+f 30017 30060 29622
+f 30104 29543 29542
+f 29076 29080 30105
+f 29082 30061 30106
+f 30107 22010 28959
+f 30062 30107 28959
+f 30108 29140 30109
+f 29201 27900 19958
+f 29292 28970 28973
+f 29245 29292 28973
+f 17671 29553 17062
+f 28230 23389 23388
+f 30110 28306 28325
+f 30063 30110 28325
+f 28885 28975 24556
+f 22027 27420 23313
+f 2007 28417 2008
+f 14046 2317 11015
+f 29266 29138 29137
+f 13479 22781 14819
+f 30064 30065 28739
+f 30111 28770 28740
+f 30065 30111 28740
+f 17792 30112 30066
+f 17791 17792 30066
+f 30112 30113 30067
+f 30066 30112 30067
+f 30113 30114 30068
+f 30067 30113 30068
+f 30114 30115 30069
+f 30068 30114 30069
+f 30115 30116 30070
+f 30069 30115 30070
+f 30116 30117 30071
+f 30070 30116 30071
+f 30117 30118 30072
+f 30071 30117 30072
+f 30118 30119 30073
+f 30072 30118 30073
+f 30119 30120 30074
+f 30073 30119 30074
+f 30120 30121 30075
+f 30074 30120 30075
+f 30121 30122 30076
+f 30075 30121 30076
+f 30122 30123 30077
+f 30076 30122 30077
+f 30123 30124 30078
+f 30077 30123 30078
+f 30124 30125 30079
+f 30078 30124 30079
+f 30125 30126 30080
+f 30079 30125 30080
+f 30127 30081 30080
+f 30126 30127 30080
+f 30127 30128 30082
+f 30081 30127 30082
+f 30128 30129 30083
+f 30082 30128 30083
+f 30129 30130 30084
+f 30083 30129 30084
+f 30130 30131 30085
+f 30084 30130 30085
+f 30132 30086 30085
+f 30131 30132 30085
+f 30133 30087 30086
+f 30132 30133 30086
+f 30133 30134 30088
+f 30087 30133 30088
+f 30134 30135 30089
+f 30088 30134 30089
+f 30135 30136 30090
+f 30089 30135 30090
+f 30136 30137 30091
+f 30090 30136 30091
+f 30137 30138 30092
+f 30091 30137 30092
+f 30138 30139 30093
+f 30092 30138 30093
+f 30140 30094 30093
+f 30139 30140 30093
+f 30141 30095 30094
+f 30140 30141 30094
+f 30142 30096 30095
+f 30141 30142 30095
+f 30143 30097 30096
+f 30142 30143 30096
+f 30144 30098 30097
+f 30143 30144 30097
+f 30145 30099 30098
+f 30144 30145 30098
+f 30145 30146 30100
+f 30099 30145 30100
+f 30146 25408 22782
+f 30100 30146 22782
+f 16651 17366 22345
+f 26763 15021 18795
+f 2501 23380 15594
+f 2502 2501 15594
+f 13336 3033 9276
+f 7937 23341 7331
+f 22237 24968 27467
+f 30147 22206 22208
+f 15033 15032 22207
+f 22397 6794 6796
+f 6795 5116 21880
+f 15425 14867 6388
+f 29671 5968 20953
+f 16145 16151 29190
+f 21673 29257 29485
+f 29120 20336 20212
+f 28537 29097 28538
+f 29142 29066 28979
+f 24346 20921 6235
+f 22656 23945 24064
+f 15655 7361 28282
+f 29930 30148 22846
+f 30148 30149 29416
+f 28108 30148 29416
+f 30150 29417 29416
+f 30149 30150 29416
+f 30151 30102 29417
+f 30150 30151 29417
+f 30152 30103 30102
+f 30151 30152 30102
+f 22654 24063 30103
+f 30152 22654 30103
+f 25154 8929 11080
+f 15171 27924 15172
+f 28110 21912 19196
+f 15171 25193 27924
+f 30060 30104 29542
+f 8474 9154 3016
+f 29080 29082 30106
+f 30153 29460 29543
+f 30108 22011 22010
+f 29076 30105 30153
+f 30109 29201 19958
+f 30107 30108 22010
+f 28671 29245 28672
+f 29140 29201 30109
+f 28570 28620 27218
+f 29292 29290 28930
+f 30154 28307 28306
+f 28715 5806 29671
+f 29188 22783 21415
+f 30110 30154 28306
+f 14024 14026 28334
+f 26373 26281 21013
+f 21661 28629 21662
+f 21416 14024 28334
+f 30155 28785 28770
+f 28231 28599 29281
+f 30111 30155 28770
+f 16939 30156 17792
+f 30156 30157 30112
+f 17792 30156 30112
+f 30157 30158 30113
+f 30112 30157 30113
+f 30158 30159 30114
+f 30113 30158 30114
+f 30159 30160 30115
+f 30114 30159 30115
+f 30161 30116 30115
+f 30160 30161 30115
+f 30162 30117 30116
+f 30161 30162 30116
+f 30162 30163 30118
+f 30117 30162 30118
+f 30163 30164 30119
+f 30118 30163 30119
+f 30164 30165 30120
+f 30119 30164 30120
+f 30165 30166 30121
+f 30120 30165 30121
+f 30166 30167 30122
+f 30121 30166 30122
+f 30167 30168 30123
+f 30122 30167 30123
+f 30168 30169 30124
+f 30123 30168 30124
+f 30169 30170 30125
+f 30124 30169 30125
+f 30170 30171 30126
+f 30125 30170 30126
+f 30172 30127 30126
+f 30171 30172 30126
+f 30172 30173 30128
+f 30127 30172 30128
+f 30173 30174 30129
+f 30128 30173 30129
+f 30174 30175 30130
+f 30129 30174 30130
+f 30175 30176 30131
+f 30130 30175 30131
+f 30177 30132 30131
+f 30176 30177 30131
+f 30177 30178 30133
+f 30132 30177 30133
+f 30178 30179 30134
+f 30133 30178 30134
+f 30179 30180 30135
+f 30134 30179 30135
+f 30180 30181 30136
+f 30135 30180 30136
+f 30181 30182 30137
+f 30136 30181 30137
+f 30182 30183 30138
+f 30137 30182 30138
+f 30183 30184 30139
+f 30138 30183 30139
+f 30185 30140 30139
+f 30184 30185 30139
+f 30186 30141 30140
+f 30185 30186 30140
+f 30187 30142 30141
+f 30186 30187 30141
+f 30188 30143 30142
+f 30187 30188 30142
+f 30189 30144 30143
+f 30188 30189 30143
+f 30190 30145 30144
+f 30189 30190 30144
+f 30190 30191 30146
+f 30145 30190 30146
+f 30191 4492 25408
+f 30146 30191 25408
+f 22781 22782 25408
+f 22280 22279 25305
+f 29212 29211 30015
+f 30192 30013 30014
+f 29876 29219 30015
+f 29211 30014 30015
+f 29593 28059 29876
+f 29219 29212 30015
+f 16048 26780 27349
+f 28059 29219 29876
+f 29281 28769 28234
+f 28057 28059 29593
+f 29706 28289 29707
+f 4964 29661 5387
+f 21561 17109 22952
+f 28289 28312 29707
+f 15110 21389 2293
+f 2292 15110 2293
+f 23177 27648 23178
+f 2336 12538 21562
+f 14687 21287 14688
+f 5029 29930 2126
+f 29930 30193 30149
+f 30148 29930 30149
+f 30194 30150 30149
+f 30193 30194 30149
+f 30195 30151 30150
+f 30194 30195 30150
+f 30196 30152 30151
+f 30195 30196 30151
+f 25605 22654 30152
+f 30196 25605 30152
+f 17405 22655 22654
+f 25605 17405 22654
+f 27597 11387 29802
+f 7433 3367 11185
+f 17716 23203 29027
+f 29188 22867 22783
+f 30104 30153 29543
+f 30105 29410 29460
+f 29077 29076 30153
+f 29080 30106 30105
+f 30108 30109 20977
+f 17675 27776 17673
+f 29096 29095 30062
+f 29140 30108 30107
+f 27776 17675 28368
+f 25991 25993 25989
+f 24335 24334 28796
+f 26812 27816 27842
+f 30197 28327 28307
+f 30154 30197 28307
+f 28228 9614 22800
+f 16159 23382 16160
+f 30198 16539 14780
+f 5065 7544 15507
+f 4810 28577 29143
+f 30199 29063 29113
+f 30155 30200 28788
+f 28785 30155 28788
+f 17889 30156 16939
+f 17889 30201 30157
+f 30156 17889 30157
+f 30201 30202 30158
+f 30157 30201 30158
+f 30202 30203 30159
+f 30158 30202 30159
+f 30203 30204 30160
+f 30159 30203 30160
+f 30204 30205 30161
+f 30160 30204 30161
+f 30205 30206 30162
+f 30161 30205 30162
+f 30206 30207 30163
+f 30162 30206 30163
+f 30207 30208 30164
+f 30163 30207 30164
+f 30208 30209 30165
+f 30164 30208 30165
+f 30209 30210 30166
+f 30165 30209 30166
+f 30210 30211 30167
+f 30166 30210 30167
+f 30211 30212 30168
+f 30167 30211 30168
+f 30212 30213 30169
+f 30168 30212 30169
+f 30213 30214 30170
+f 30169 30213 30170
+f 30214 30215 30171
+f 30170 30214 30171
+f 30215 30216 30172
+f 30171 30215 30172
+f 30216 30217 30173
+f 30172 30216 30173
+f 30217 30218 30174
+f 30173 30217 30174
+f 30218 30219 30175
+f 30174 30218 30175
+f 30219 30220 30176
+f 30175 30219 30176
+f 30221 30177 30176
+f 30220 30221 30176
+f 30221 30222 30178
+f 30177 30221 30178
+f 30222 30223 30179
+f 30178 30222 30179
+f 30223 30224 30180
+f 30179 30223 30180
+f 30224 30225 30181
+f 30180 30224 30181
+f 30225 30226 30182
+f 30181 30225 30182
+f 30226 30227 30183
+f 30182 30226 30183
+f 30227 30228 30184
+f 30183 30227 30184
+f 30229 30185 30184
+f 30228 30229 30184
+f 30230 30186 30185
+f 30229 30230 30185
+f 30230 30231 30187
+f 30186 30230 30187
+f 30232 30188 30187
+f 30231 30232 30187
+f 30233 30189 30188
+f 30232 30233 30188
+f 30234 30190 30189
+f 30233 30234 30189
+f 30234 30235 30191
+f 30190 30234 30191
+f 30235 14830 4492
+f 30191 30235 4492
+f 11221 14414 6746
+f 4490 14041 4491
+f 22041 29011 29875
+f 1133 16178 21685
+f 29227 30012 30013
+f 30192 29227 30013
+f 29227 29226 30012
+f 29226 29581 30012
+f 29226 29221 29581
+f 29221 29532 29581
+f 29221 29218 29532
+f 29218 29533 29532
+f 29218 29224 29533
+f 29224 29530 29533
+f 29224 29223 29530
+f 29223 29491 29530
+f 29223 29230 29491
+f 29230 29493 29491
+f 16718 27498 22906
+f 29232 29494 29493
+f 30236 30237 28136
+f 22846 30148 28108
+f 30238 30193 29930
+f 5029 30238 29930
+f 30239 30194 30193
+f 30238 30239 30193
+f 30240 30195 30194
+f 30239 30240 30194
+f 30241 30196 30195
+f 30240 30241 30195
+f 30241 30242 25605
+f 30196 30241 25605
+f 30242 25604 25605
+f 17406 25604 24511
+f 21086 21085 25479
+f 27695 27325 27640
+f 25792 16656 5401
+f 29204 14520 29135
+f 30153 30105 29460
+f 29932 29236 29235
+f 11019 21015 29972
+f 29118 30060 30017
+f 22011 30108 20977
+f 30109 19958 19957
+f 29095 30107 30062
+f 29095 29140 30107
+f 26809 23787 23206
+f 18558 18557 18559
+f 30243 30244 30245
+f 30245 18226 27570
+f 30246 28328 28327
+f 30197 30246 28327
+f 28514 28228 30247
+f 27213 27218 26888
+f 28558 21661 21663
+f 28629 10429 21662
+f 8707 807 844
+f 2006 2008 28452
+f 30200 30248 28814
+f 28788 30200 28814
+f 16168 30249 30201
+f 17889 16168 30201
+f 30249 30250 30202
+f 30201 30249 30202
+f 30251 30203 30202
+f 30250 30251 30202
+f 30251 30252 30204
+f 30203 30251 30204
+f 30252 30253 30205
+f 30204 30252 30205
+f 30253 30254 30206
+f 30205 30253 30206
+f 30254 30255 30207
+f 30206 30254 30207
+f 30255 30256 30208
+f 30207 30255 30208
+f 30256 30257 30209
+f 30208 30256 30209
+f 30257 30258 30210
+f 30209 30257 30210
+f 30259 30211 30210
+f 30258 30259 30210
+f 30260 30212 30211
+f 30259 30260 30211
+f 30261 30213 30212
+f 30260 30261 30212
+f 30262 30214 30213
+f 30261 30262 30213
+f 30263 30215 30214
+f 30262 30263 30214
+f 30263 30264 30216
+f 30215 30263 30216
+f 30264 30265 30217
+f 30216 30264 30217
+f 30265 30266 30218
+f 30217 30265 30218
+f 30266 30267 30219
+f 30218 30266 30219
+f 30267 30268 30220
+f 30219 30267 30220
+f 30269 30221 30220
+f 30268 30269 30220
+f 30269 30270 30222
+f 30221 30269 30222
+f 30270 30271 30223
+f 30222 30270 30223
+f 30271 30272 30224
+f 30223 30271 30224
+f 30272 30273 30225
+f 30224 30272 30225
+f 30273 30274 30226
+f 30225 30273 30226
+f 30274 30275 30227
+f 30226 30274 30227
+f 30276 30228 30227
+f 30275 30276 30227
+f 30277 30229 30228
+f 30276 30277 30228
+f 30278 30230 30229
+f 30277 30278 30229
+f 30279 30231 30230
+f 30278 30279 30230
+f 30279 30280 30232
+f 30231 30279 30232
+f 30281 30233 30232
+f 30280 30281 30232
+f 30282 30234 30233
+f 30281 30282 30233
+f 30282 30283 30235
+f 30234 30282 30235
+f 30283 30284 14830
+f 30235 30283 14830
+f 2658 25788 29661
+f 30284 29024 14830
+f 6384 27841 27892
+f 29024 15923 14830
+f 21162 14705 27795
+f 4965 13818 6941
+f 29142 28980 28982
+f 13815 28586 28883
+f 21674 21673 29485
+f 28297 24556 24558
+f 21436 28923 21266
+f 6088 21744 20953
+f 28632 28367 28259
+f 30285 30286 30287
+f 22010 22012 28960
+f 29275 29210 29212
+f 28028 22373 27611
+f 1462 2826 14408
+f 29279 28087 28089
+f 6718 30288 22749
+f 29975 27619 25031
+f 27670 23175 23174
+f 23205 30238 5029
+f 5028 23205 5029
+f 28109 30239 30238
+f 23205 28109 30238
+f 28109 30289 30240
+f 30239 28109 30240
+f 30289 30290 30241
+f 30240 30289 30241
+f 30290 26930 30242
+f 30241 30290 30242
+f 23924 29064 27086
+f 9703 15823 15825
+f 4451 4450 27694
+f 24548 23032 25745
+f 5672 5673 14025
+f 29138 28260 28247
+f 29933 29235 29331
+f 30018 29933 29331
+f 21015 29118 30017
+f 29800 30104 30060
+f 20977 30109 19957
+f 15410 15412 23447
+f 29887 30291 16444
+f 29096 30062 29973
+f 27775 27773 27772
+f 26505 23026 12386
+f 29059 30244 30243
+f 30292 29059 30243
+f 30293 28350 28328
+f 30294 30295 28394
+f 28514 30247 30296
+f 28515 28514 30296
+f 29265 28231 29136
+f 29128 28879 10428
+f 29699 30236 28160
+f 4491 22781 25408
+f 30248 30297 28825
+f 28814 30248 28825
+f 16167 30298 30249
+f 16168 16167 30249
+f 30298 30299 30250
+f 30249 30298 30250
+f 30300 30251 30250
+f 30299 30300 30250
+f 30300 30301 30252
+f 30251 30300 30252
+f 30301 30302 30253
+f 30252 30301 30253
+f 30302 30303 30254
+f 30253 30302 30254
+f 30303 30304 30255
+f 30254 30303 30255
+f 30304 30305 30256
+f 30255 30304 30256
+f 30305 30306 30257
+f 30256 30305 30257
+f 30306 30307 30258
+f 30257 30306 30258
+f 30307 30308 30259
+f 30258 30307 30259
+f 30309 30260 30259
+f 30308 30309 30259
+f 30310 30261 30260
+f 30309 30310 30260
+f 30310 30311 30262
+f 30261 30310 30262
+f 30311 30312 30263
+f 30262 30311 30263
+f 30312 30313 30264
+f 30263 30312 30264
+f 30313 30314 30265
+f 30264 30313 30265
+f 30314 30315 30266
+f 30265 30314 30266
+f 30315 30316 30267
+f 30266 30315 30267
+f 30316 30317 30268
+f 30267 30316 30268
+f 30318 30269 30268
+f 30317 30318 30268
+f 30318 30319 30270
+f 30269 30318 30270
+f 30319 30320 30271
+f 30270 30319 30271
+f 30320 30321 30272
+f 30271 30320 30272
+f 30321 30322 30273
+f 30272 30321 30273
+f 30322 30323 30274
+f 30273 30322 30274
+f 30323 30324 30275
+f 30274 30323 30275
+f 30325 30276 30275
+f 30324 30325 30275
+f 30326 30277 30276
+f 30325 30326 30276
+f 30327 30278 30277
+f 30326 30327 30277
+f 30328 30279 30278
+f 30327 30328 30278
+f 30328 30329 30280
+f 30279 30328 30280
+f 30329 30330 30281
+f 30280 30329 30281
+f 30331 30282 30281
+f 30330 30331 30281
+f 30332 30283 30282
+f 30331 30332 30282
+f 30332 30333 30284
+f 30283 30332 30284
+f 30334 29024 30284
+f 30333 30334 30284
+f 22944 27048 29024
+f 30334 22944 29024
+f 25839 30335 30336
+f 13816 25863 14623
+f 4962 4964 2323
+f 23323 25971 25973
+f 5542 28324 5543
+f 29975 25031 14691
+f 29875 29011 13813
+f 25761 28590 22602
+f 30337 29699 28204
+f 23663 14017 28758
+f 30338 30337 24859
+f 14921 15129 15319
+f 11988 8113 4412
+f 22168 22169 6543
+f 16757 4449 24349
+f 1869 18266 1870
+f 18936 18935 17823
+f 23786 28109 23787
+f 27787 26811 15112
+f 10122 10208 10207
+f 30339 30340 15078
+f 23788 23841 23786
+f 23840 30289 28109
+f 3155 17014 17013
+f 23840 30341 30290
+f 30289 23840 30290
+f 30341 30342 26930
+f 30290 30341 26930
+f 27614 26931 26930
+f 30342 27614 26930
+f 17217 17705 17703
+f 20920 20921 24346
+f 18940 28393 27670
+f 18040 16242 14235
+f 30018 29331 29375
+f 30061 30018 29375
+f 29118 29800 30060
+f 29077 30153 30104
+f 21978 18956 16741
+f 25762 22550 28560
+f 23661 29887 16443
+f 30291 29096 29973
+f 23496 23479 16132
+f 28444 29463 28388
+f 23127 29059 30292
+f 30244 18226 30245
+f 30246 30293 28328
+f 28370 30294 28394
+f 28515 30296 30343
+f 28228 22800 30247
+f 30344 30338 24858
+f 30244 15040 18226
+f 27671 29506 26137
+f 15412 15411 23462
+f 30297 30345 28826
+f 28825 30297 28826
+f 16166 30346 16167
+f 30346 30347 30298
+f 16167 30346 30298
+f 30347 30348 30299
+f 30298 30347 30299
+f 30349 30300 30299
+f 30348 30349 30299
+f 30349 30350 30301
+f 30300 30349 30301
+f 30350 30351 30302
+f 30301 30350 30302
+f 30351 30352 30303
+f 30302 30351 30303
+f 30352 30353 30304
+f 30303 30352 30304
+f 30353 30354 30305
+f 30304 30353 30305
+f 30354 30355 30306
+f 30305 30354 30306
+f 30355 30356 30307
+f 30306 30355 30307
+f 30356 30357 30308
+f 30307 30356 30308
+f 30357 30358 30309
+f 30308 30357 30309
+f 30358 30359 30310
+f 30309 30358 30310
+f 30359 30360 30311
+f 30310 30359 30311
+f 30360 30361 30312
+f 30311 30360 30312
+f 30361 30362 30313
+f 30312 30361 30313
+f 30362 30363 30314
+f 30313 30362 30314
+f 30363 30364 30315
+f 30314 30363 30315
+f 30364 30365 30316
+f 30315 30364 30316
+f 30365 30366 30317
+f 30316 30365 30317
+f 30367 30318 30317
+f 30366 30367 30317
+f 30367 30368 30319
+f 30318 30367 30319
+f 30368 30369 30320
+f 30319 30368 30320
+f 30369 30370 30321
+f 30320 30369 30321
+f 30370 30371 30322
+f 30321 30370 30322
+f 30371 30372 30323
+f 30322 30371 30323
+f 30372 30373 30324
+f 30323 30372 30324
+f 30373 30374 30325
+f 30324 30373 30325
+f 30375 30326 30325
+f 30374 30375 30325
+f 30376 30327 30326
+f 30375 30376 30326
+f 30377 30328 30327
+f 30376 30377 30327
+f 30377 30378 30329
+f 30328 30377 30329
+f 30378 30379 30330
+f 30329 30378 30330
+f 30380 30331 30330
+f 30379 30380 30330
+f 30381 30332 30331
+f 30380 30381 30331
+f 30381 30382 30333
+f 30332 30381 30333
+f 30383 30334 30333
+f 30382 30383 30333
+f 27791 22944 30334
+f 30383 27791 30334
+f 27791 16987 22944
+f 27570 18226 18227
+f 22208 22207 29320
+f 4451 14738 4449
+f 28962 28693 29499
+f 15032 29328 29323
+f 28962 29457 29404
+f 28963 28962 29404
+f 28963 29404 29371
+f 29152 28963 29371
+f 15034 29152 29371
+f 29325 15034 29371
+f 22207 15032 29323
+f 15032 15034 29325
+f 16727 7557 8120
+f 29328 15032 29325
+f 5028 14738 28055
+f 27694 28430 25366
+f 22139 22280 25304
+f 5813 24968 23302
+f 26757 11222 28294
+f 29203 23098 22023
+f 27761 22874 25149
+f 2324 5386 28290
+f 30384 30341 23840
+f 23841 30384 23840
+f 30385 30342 30341
+f 30384 30385 30341
+f 17530 27614 30342
+f 30385 17530 30342
+f 29158 29159 29620
+f 26931 17532 24512
+f 5964 5966 27701
+f 28108 27716 26991
+f 30106 29374 29410
+f 30105 30106 29410
+f 29931 10951 29972
+f 29800 29077 30104
+f 25907 23567 25785
+f 12388 29133 26505
+f 1960 1959 16327
+f 30291 29973 16444
+f 3922 22161 4614
+f 28445 29413 28444
+f 23127 30386 30387
+f 30386 23127 30292
+f 30293 30294 28370
+f 28350 30293 28370
+f 28750 30343 30388
+f 28750 28515 30343
+f 25763 22940 22942
+f 28599 28769 29281
+f 12768 17456 23391
+f 22040 30020 22034
+f 30345 30389 28864
+f 28826 30345 28864
+f 16226 30390 30346
+f 16166 16226 30346
+f 30390 30391 30347
+f 30346 30390 30347
+f 30391 30392 30348
+f 30347 30391 30348
+f 30393 30349 30348
+f 30392 30393 30348
+f 30393 30394 30350
+f 30349 30393 30350
+f 30394 30395 30351
+f 30350 30394 30351
+f 30395 30396 30352
+f 30351 30395 30352
+f 30396 30397 30353
+f 30352 30396 30353
+f 30397 30398 30354
+f 30353 30397 30354
+f 30398 30399 30355
+f 30354 30398 30355
+f 30399 30400 30356
+f 30355 30399 30356
+f 30400 30401 30357
+f 30356 30400 30357
+f 30401 30402 30358
+f 30357 30401 30358
+f 30402 30403 30359
+f 30358 30402 30359
+f 30403 30404 30360
+f 30359 30403 30360
+f 30404 30405 30361
+f 30360 30404 30361
+f 30405 30406 30362
+f 30361 30405 30362
+f 30406 30407 30363
+f 30362 30406 30363
+f 30407 30408 30364
+f 30363 30407 30364
+f 30408 30409 30365
+f 30364 30408 30365
+f 30409 30410 30366
+f 30365 30409 30366
+f 30411 30367 30366
+f 30410 30411 30366
+f 30412 30368 30367
+f 30411 30412 30367
+f 30412 30413 30369
+f 30368 30412 30369
+f 30413 30414 30370
+f 30369 30413 30370
+f 30414 30415 30371
+f 30370 30414 30371
+f 30415 30416 30372
+f 30371 30415 30372
+f 30416 30417 30373
+f 30372 30416 30373
+f 30417 30418 30374
+f 30373 30417 30374
+f 30419 30375 30374
+f 30418 30419 30374
+f 30420 30376 30375
+f 30419 30420 30375
+f 30420 30421 30377
+f 30376 30420 30377
+f 30421 30422 30378
+f 30377 30421 30378
+f 30423 30379 30378
+f 30422 30423 30378
+f 30424 30380 30379
+f 30423 30424 30379
+f 30425 30381 30380
+f 30424 30425 30380
+f 30425 30426 30382
+f 30381 30425 30382
+f 30427 30383 30382
+f 30426 30427 30382
+f 3818 27791 30383
+f 30427 3818 30383
+f 807 842 844
+f 24269 24271 25972
+f 29286 11930 11162
+f 29287 29286 11162
+f 29714 29759 29276
+f 25683 11284 11429
+f 14169 16188 14170
+f 25193 25192 29158
+f 22983 30198 14780
+f 15187 19825 15188
+f 27715 16540 16539
+f 27714 16542 16540
+f 10585 11162 5470
+f 30198 27715 16539
+f 28504 27332 27660
+f 13908 1461 1460
+f 28994 27543 27043
+f 25043 25044 23094
+f 30338 24859 24858
+f 12419 12423 12322
+f 5115 5114 23841
+f 22308 29628 2510
+f 26794 25314 27090
+f 28710 28669 28241
+f 5114 30384 23841
+f 11883 14510 21608
+f 5114 30428 30385
+f 30384 5114 30385
+f 28006 17530 30385
+f 30428 28006 30385
+f 17530 28006 17531
+f 8989 16891 25042
+f 27709 4813 4815
+f 30429 22827 30430
+f 30061 29375 29374
+f 30106 30061 29374
+f 29881 12833 29931
+f 21015 30017 29972
+f 28264 28881 29133
+f 12388 28264 29133
+f 16933 5076 16934
+f 29887 16444 16443
+f 29712 25616 28662
+f 29463 29503 28388
+f 23128 30387 30431
+f 23128 23127 30387
+f 30295 30432 28396
+f 28394 30295 28396
+f 28712 28714 30388
+f 28714 28750 30388
+f 28535 28797 4814
+f 23787 23207 23206
+f 4451 26809 28055
+f 11162 8819 29287
+f 30389 30433 28911
+f 28864 30389 28911
+f 16225 30434 30390
+f 16226 16225 30390
+f 30434 30435 30391
+f 30390 30434 30391
+f 30435 30436 30392
+f 30391 30435 30392
+f 30437 30393 30392
+f 30436 30437 30392
+f 30438 30394 30393
+f 30437 30438 30393
+f 30438 30439 30395
+f 30394 30438 30395
+f 30440 30396 30395
+f 30439 30440 30395
+f 30440 30441 30397
+f 30396 30440 30397
+f 30441 30442 30398
+f 30397 30441 30398
+f 30442 30443 30399
+f 30398 30442 30399
+f 30443 30444 30400
+f 30399 30443 30400
+f 30445 30401 30400
+f 30444 30445 30400
+f 30445 30446 30402
+f 30401 30445 30402
+f 30446 30447 30403
+f 30402 30446 30403
+f 30447 30448 30404
+f 30403 30447 30404
+f 30448 30449 30405
+f 30404 30448 30405
+f 30449 30450 30406
+f 30405 30449 30406
+f 30450 30451 30407
+f 30406 30450 30407
+f 30451 30452 30408
+f 30407 30451 30408
+f 30452 30453 30409
+f 30408 30452 30409
+f 30453 30454 30410
+f 30409 30453 30410
+f 30455 30411 30410
+f 30454 30455 30410
+f 30456 30412 30411
+f 30455 30456 30411
+f 30456 30457 30413
+f 30412 30456 30413
+f 30457 30458 30414
+f 30413 30457 30414
+f 30458 30459 30415
+f 30414 30458 30415
+f 30459 30460 30416
+f 30415 30459 30416
+f 30460 30461 30417
+f 30416 30460 30417
+f 30461 30462 30418
+f 30417 30461 30418
+f 30462 30463 30419
+f 30418 30462 30419
+f 30464 30420 30419
+f 30463 30464 30419
+f 30464 30465 30421
+f 30420 30464 30421
+f 30465 30466 30422
+f 30421 30465 30422
+f 30467 30423 30422
+f 30466 30467 30422
+f 30468 30424 30423
+f 30467 30468 30423
+f 30469 30425 30424
+f 30468 30469 30424
+f 30470 30426 30425
+f 30469 30470 30425
+f 25418 30427 30426
+f 30470 25418 30426
+f 3819 3818 30427
+f 25418 3819 30427
+f 29624 29625 29174
+f 30471 30472 30473
+f 29625 29544 29172
+f 29544 29171 29172
+f 29171 29544 29168
+f 29544 29545 29168
+f 29379 29334 28838
+f 29545 29461 29162
+f 29378 29379 28842
+f 29165 29378 28842
+f 29411 29378 29165
+f 29163 29411 29165
+f 29168 29545 29162
+f 29461 29411 29163
+f 14257 15320 7362
+f 29162 29461 29163
+f 28429 4450 22277
+f 23928 28429 22277
+f 27757 27756 30474
+f 30474 28663 27757
+f 5387 29661 25120
+f 6388 14869 6389
+f 28882 28794 2181
+f 29232 29234 29494
+f 24881 27734 16222
+f 21656 21655 26271
+f 27288 30428 5114
+f 5113 27288 5114
+f 16047 28006 30428
+f 27288 16047 30428
+f 26607 26525 26522
+f 16047 27152 25044
+f 1743 1742 29631
+f 14440 10919 15915
+f 29933 29932 29235
+f 29882 29237 29236
+f 29838 13073 29881
+f 10951 11019 29972
+f 25264 25262 25263
+f 16541 17114 27736
+f 23206 5028 28055
+f 16443 11791 16327
+f 28646 29712 28647
+f 28647 29712 28662
+f 29107 29100 30431
+f 29100 23128 30431
+f 30475 28425 28396
+f 30432 30475 28396
+f 28712 30476 30477
+f 30476 28712 30388
+f 28626 26712 28627
+f 28797 24334 4815
+f 2401 3221 2399
+f 3817 3819 25654
+f 30433 28424 28912
+f 28911 30433 28912
+f 30478 30434 16225
+f 16320 30478 16225
+f 30478 30479 30435
+f 30434 30478 30435
+f 30479 30480 30436
+f 30435 30479 30436
+f 30481 30437 30436
+f 30480 30481 30436
+f 30482 30438 30437
+f 30481 30482 30437
+f 30482 30483 30439
+f 30438 30482 30439
+f 30483 30484 30440
+f 30439 30483 30440
+f 30484 30485 30441
+f 30440 30484 30441
+f 30485 30486 30442
+f 30441 30485 30442
+f 30486 30487 30443
+f 30442 30486 30443
+f 30487 30488 30444
+f 30443 30487 30444
+f 30489 30445 30444
+f 30488 30489 30444
+f 30489 30490 30446
+f 30445 30489 30446
+f 30491 30447 30446
+f 30490 30491 30446
+f 30492 30448 30447
+f 30491 30492 30447
+f 30492 30493 30449
+f 30448 30492 30449
+f 30493 30494 30450
+f 30449 30493 30450
+f 30494 30495 30451
+f 30450 30494 30451
+f 30495 30496 30452
+f 30451 30495 30452
+f 30496 30497 30453
+f 30452 30496 30453
+f 30497 30498 30454
+f 30453 30497 30454
+f 30499 30455 30454
+f 30498 30499 30454
+f 30500 30456 30455
+f 30499 30500 30455
+f 30500 30501 30457
+f 30456 30500 30457
+f 30501 30502 30458
+f 30457 30501 30458
+f 30502 30503 30459
+f 30458 30502 30459
+f 30503 30504 30460
+f 30459 30503 30460
+f 30504 30505 30461
+f 30460 30504 30461
+f 30505 30506 30462
+f 30461 30505 30462
+f 30507 30463 30462
+f 30506 30507 30462
+f 30507 30508 30464
+f 30463 30507 30464
+f 30508 30509 30465
+f 30464 30508 30465
+f 30509 30510 30466
+f 30465 30509 30466
+f 30510 30511 30467
+f 30466 30510 30467
+f 30512 30468 30467
+f 30511 30512 30467
+f 30513 30469 30468
+f 30512 30513 30468
+f 27896 30470 30469
+f 30513 27896 30469
+f 27895 25418 30470
+f 27896 27895 30470
+f 11199 22721 14886
+f 4887 4886 22209
+f 22718 16145 21282
+f 5106 5105 27733
+f 5386 5388 28272
+f 11222 2324 28294
+f 6255 22254 25756
+f 27761 22710 22874
+f 20979 29332 29285
+f 22012 20979 29285
+f 20979 20978 29332
+f 20978 29376 29332
+f 29376 20978 29408
+f 20978 21005 29408
+f 29408 21005 23204
+f 23203 17716 16348
+f 4399 29343 4397
+f 24975 25226 22574
+f 15022 28429 23928
+f 15023 15022 23928
+f 30514 28430 28429
+f 15022 30514 28429
+f 17405 25604 17406
+f 30514 6248 28430
+f 29230 29232 29493
+f 29234 29536 29494
+f 24271 24270 17723
+f 22148 15678 22372
+f 5775 5777 21302
+f 21249 29359 21250
+f 30515 28007 18122
+f 30516 30517 30518
+f 23094 27152 27349
+f 16047 16046 27152
+f 29620 29159 29551
+f 26877 10981 26991
+f 29932 29882 29236
+f 28430 6248 25366
+f 13073 12833 29881
+f 12833 10951 29931
+f 25491 29798 11919
+f 6097 25491 11919
+f 7739 14781 17594
+f 14781 27736 17594
+f 28644 28468 28646
+f 28902 28643 28900
+f 29108 29107 30519
+f 30520 29107 30431
+f 30475 30521 28448
+f 28425 30475 28448
+f 28713 30477 30522
+f 28713 28712 30477
+f 25417 27895 23548
+f 22949 28575 29044
+f 20291 28648 3461
+f 21473 21382 17615
+f 18002 18001 28912
+f 28424 18002 28912
+f 16325 30523 30478
+f 16320 16325 30478
+f 30523 30524 30479
+f 30478 30523 30479
+f 30524 30525 30480
+f 30479 30524 30480
+f 30525 30526 30481
+f 30480 30525 30481
+f 30527 30482 30481
+f 30526 30527 30481
+f 30527 30528 30483
+f 30482 30527 30483
+f 30528 30529 30484
+f 30483 30528 30484
+f 30529 30530 30485
+f 30484 30529 30485
+f 30530 30531 30486
+f 30485 30530 30486
+f 30531 30532 30487
+f 30486 30531 30487
+f 30532 30533 30488
+f 30487 30532 30488
+f 30533 30534 30489
+f 30488 30533 30489
+f 30534 30535 30490
+f 30489 30534 30490
+f 30535 30536 30491
+f 30490 30535 30491
+f 30536 30537 30492
+f 30491 30536 30492
+f 30537 30538 30493
+f 30492 30537 30493
+f 30538 30539 30494
+f 30493 30538 30494
+f 30539 30540 30495
+f 30494 30539 30495
+f 30540 30541 30496
+f 30495 30540 30496
+f 30542 30497 30496
+f 30541 30542 30496
+f 30543 30498 30497
+f 30542 30543 30497
+f 30544 30499 30498
+f 30543 30544 30498
+f 30545 30500 30499
+f 30544 30545 30499
+f 30545 30546 30501
+f 30500 30545 30501
+f 30546 30547 30502
+f 30501 30546 30502
+f 30547 30548 30503
+f 30502 30547 30503
+f 30548 30549 30504
+f 30503 30548 30504
+f 30549 30550 30505
+f 30504 30549 30505
+f 30550 30551 30506
+f 30505 30550 30506
+f 30551 30552 30507
+f 30506 30551 30507
+f 30552 30553 30508
+f 30507 30552 30508
+f 30553 30554 30509
+f 30508 30553 30509
+f 30554 30555 30510
+f 30509 30554 30510
+f 30555 30556 30511
+f 30510 30555 30511
+f 30557 30512 30511
+f 30556 30557 30511
+f 30558 30513 30512
+f 30557 30558 30512
+f 22873 27896 30513
+f 30558 22873 30513
+f 21613 22963 6652
+f 21250 26790 21248
+f 16914 27740 16943
+f 30242 26930 25604
+f 29335 29075 29093
+f 29380 29335 29093
+f 29504 27143 21014
+f 29414 29885 21066
+f 29380 29093 29885
+f 27143 29414 21066
+f 29291 29078 29075
+f 29414 29380 29885
+f 29189 29288 29796
+f 29335 29291 29075
+f 29242 29189 29079
+f 29288 28836 29796
+f 29291 29242 29078
+f 29189 29796 29079
+f 28835 28834 29835
+f 29242 29079 29078
+f 29835 24777 4341
+f 25430 25374 25429
+f 26763 30514 15022
+f 1513 1506 17301
+f 6246 6248 30514
+f 26763 6246 30514
+f 28664 27773 27775
+f 21805 21804 15111
+f 28630 22148 22372
+f 27980 23927 21631
+f 29586 29455 29402
+f 30559 29586 29402
+f 23464 28284 4649
+f 21287 14687 5106
+f 27719 28284 23464
+f 16612 16606 16608
+f 27477 2767 23909
+f 25227 29550 25288
+f 858 13073 29838
+f 14958 28181 25765
+f 29711 29667 13053
+f 29795 858 29838
+f 16914 16943 22927
+f 29798 29757 856
+f 1959 23661 16327
+f 25973 27544 27545
+f 29108 30519 27666
+f 28468 28489 28646
+f 30560 30561 28490
+f 23173 29108 27666
+f 30521 30560 28467
+f 28448 30521 28467
+f 28540 28752 30562
+f 28752 28713 30522
+f 28395 12560 12559
+f 17303 16096 16095
+f 29801 28680 20291
+f 28648 3462 3461
+f 25753 5113 5115
+f 27896 22873 23549
+f 16509 30563 30523
+f 16325 16509 30523
+f 30563 30564 30524
+f 30523 30563 30524
+f 30564 30565 30525
+f 30524 30564 30525
+f 30565 30566 30526
+f 30525 30565 30526
+f 30567 30527 30526
+f 30566 30567 30526
+f 30567 30568 30528
+f 30527 30567 30528
+f 30568 30569 30529
+f 30528 30568 30529
+f 30569 30570 30530
+f 30529 30569 30530
+f 30570 30571 30531
+f 30530 30570 30531
+f 30571 30572 30532
+f 30531 30571 30532
+f 30572 30573 30533
+f 30532 30572 30533
+f 30573 30574 30534
+f 30533 30573 30534
+f 30574 30575 30535
+f 30534 30574 30535
+f 30575 30576 30536
+f 30535 30575 30536
+f 30576 30577 30537
+f 30536 30576 30537
+f 30577 30578 30538
+f 30537 30577 30538
+f 30578 30579 30539
+f 30538 30578 30539
+f 30579 30580 30540
+f 30539 30579 30540
+f 30580 30581 30541
+f 30540 30580 30541
+f 30581 30582 30542
+f 30541 30581 30542
+f 30582 30583 30543
+f 30542 30582 30543
+f 30583 30584 30544
+f 30543 30583 30544
+f 30585 30545 30544
+f 30584 30585 30544
+f 30585 30586 30546
+f 30545 30585 30546
+f 30586 30587 30547
+f 30546 30586 30547
+f 30587 30588 30548
+f 30547 30587 30548
+f 30588 30589 30549
+f 30548 30588 30549
+f 30589 30590 30550
+f 30549 30589 30550
+f 30590 30591 30551
+f 30550 30590 30551
+f 30591 30592 30552
+f 30551 30591 30552
+f 30592 30593 30553
+f 30552 30592 30553
+f 30593 30594 30554
+f 30553 30593 30554
+f 30594 30595 30555
+f 30554 30594 30555
+f 30595 30596 30556
+f 30555 30595 30556
+f 30597 30557 30556
+f 30596 30597 30556
+f 30598 30558 30557
+f 30597 30598 30557
+f 22871 22873 30558
+f 30598 22871 30558
+f 14738 25148 24349
+f 22872 23549 22873
+f 30599 30600 28606
+f 5677 176 175
+f 29347 29296 29348
+f 30601 30602 30199
+f 29346 29348 30603
+f 28576 30601 28577
+f 30602 30603 30199
+f 30601 30199 28577
+f 30600 29349 29057
+f 30602 29346 30603
+f 29307 29297 29296
+f 29347 29307 29296
+f 29308 28605 29297
+f 30599 28606 28605
+f 29308 30599 28605
+f 29349 28558 29057
+f 29709 22309 23103
+f 30600 29057 28606
+f 26148 27251 18795
+f 27776 27775 27743
+f 27444 1506 2446
+f 17301 1506 27444
+f 22796 6246 26763
+f 27252 22796 26763
+f 18799 17817 22393
+f 28717 22229 22797
+f 29071 28363 5117
+f 30604 30605 30606
+f 30559 29402 5471
+f 11930 30559 5471
+f 28841 28843 29214
+f 29315 28841 29214
+f 29541 29459 28156
+f 28480 28321 22911
+f 16461 22714 22716
+f 22714 17327 22715
+f 11920 858 29795
+f 22825 21935 21620
+f 11919 29798 856
+f 857 29711 13053
+f 10813 28623 28523
+f 27252 26763 18795
+f 28489 28491 29712
+f 3507 2465 27666
+f 23182 23917 23916
+f 29107 30520 30519
+f 28467 30560 28490
+f 30561 30607 28494
+f 28545 28541 30608
+f 28540 30562 30609
+f 28752 30522 30562
+f 28541 28540 30609
+f 22911 28610 22235
+f 28245 28395 2023
+f 29760 28682 29801
+f 28680 28648 20291
+f 2018 14706 2019
+f 22306 28597 30610
+f 17344 30611 30563
+f 16509 17344 30563
+f 30611 30612 30564
+f 30563 30611 30564
+f 30612 30613 30565
+f 30564 30612 30565
+f 30613 30614 30566
+f 30565 30613 30566
+f 30615 30567 30566
+f 30614 30615 30566
+f 30615 30616 30568
+f 30567 30615 30568
+f 30616 30617 30569
+f 30568 30616 30569
+f 30617 30618 30570
+f 30569 30617 30570
+f 30618 30619 30571
+f 30570 30618 30571
+f 30619 30620 30572
+f 30571 30619 30572
+f 30620 30621 30573
+f 30572 30620 30573
+f 30621 30622 30574
+f 30573 30621 30574
+f 30622 30623 30575
+f 30574 30622 30575
+f 30623 30624 30576
+f 30575 30623 30576
+f 30624 30625 30577
+f 30576 30624 30577
+f 30625 30626 30578
+f 30577 30625 30578
+f 30626 30627 30579
+f 30578 30626 30579
+f 30627 30628 30580
+f 30579 30627 30580
+f 30628 30629 30581
+f 30580 30628 30581
+f 30630 30582 30581
+f 30629 30630 30581
+f 30631 30583 30582
+f 30630 30631 30582
+f 30631 30632 30584
+f 30583 30631 30584
+f 30632 30633 30585
+f 30584 30632 30585
+f 30633 30634 30586
+f 30585 30633 30586
+f 30634 30635 30587
+f 30586 30634 30587
+f 30635 30636 30588
+f 30587 30635 30588
+f 30636 30637 30589
+f 30588 30636 30589
+f 30637 30638 30590
+f 30589 30637 30590
+f 30638 30639 30591
+f 30590 30638 30591
+f 30639 30640 30592
+f 30591 30639 30592
+f 30640 30641 30593
+f 30592 30640 30593
+f 30641 30642 30594
+f 30593 30641 30594
+f 30642 30643 30595
+f 30594 30642 30595
+f 30643 30644 30596
+f 30595 30643 30596
+f 30645 30597 30596
+f 30644 30645 30596
+f 30646 30598 30597
+f 30645 30646 30597
+f 30647 22871 30598
+f 30646 30647 30598
+f 27548 24161 23126
+f 30647 14247 22871
+f 12713 23916 12714
+f 20377 20416 20450
+f 22478 25046 22186
+f 1752 28285 29338
+f 30245 27570 28365
+f 28299 30245 28365
+f 30386 30292 28595
+f 30243 28362 28582
+f 30243 30245 28299
+f 30292 30243 28582
+f 21067 26332 21068
+f 28362 30243 28299
+f 24857 29934 28466
+f 26332 23389 28230
+f 28229 26332 28230
+f 27218 27217 28570
+f 30610 29709 23103
+f 4841 6800 4842
+f 24338 24342 27445
+f 16784 1751 1753
+f 25786 5677 5678
+f 27042 30648 27251
+f 30649 22796 27252
+f 29264 30649 27252
+f 28221 25177 12638
+f 30649 28717 22796
+f 20712 9950 9877
+f 28717 22797 22796
+f 5470 5469 10585
+f 15172 24880 15170
+f 28843 28840 29271
+f 29214 28843 29271
+f 29587 29409 29541
+f 29459 27693 28156
+f 29840 29180 29237
+f 29755 29207 29180
+f 17702 17497 28783
+f 29270 11920 29795
+f 29757 29711 857
+f 856 29757 857
+f 2170 2293 16231
+f 22550 15232 15234
+f 17661 13290 13289
+f 12474 12475 14625
+f 29548 29589 28391
+f 13662 18148 2999
+f 28490 30561 28494
+f 30650 28495 28494
+f 28547 28545 23179
+f 28541 30609 30608
+f 28940 28756 28706
+f 22948 23236 22949
+f 22948 23234 23236
+f 28326 22947 26712
+f 29715 28681 29760
+f 28682 28680 29801
+f 21668 2662 2512
+f 28608 21668 2512
+f 16635 30651 30611
+f 17344 16635 30611
+f 30651 30652 30612
+f 30611 30651 30612
+f 30652 30653 30613
+f 30612 30652 30613
+f 30653 30654 30614
+f 30613 30653 30614
+f 30654 30655 30615
+f 30614 30654 30615
+f 30655 30656 30616
+f 30615 30655 30616
+f 30656 30657 30617
+f 30616 30656 30617
+f 30657 30658 30618
+f 30617 30657 30618
+f 30658 30659 30619
+f 30618 30658 30619
+f 30660 30620 30619
+f 30659 30660 30619
+f 30661 30621 30620
+f 30660 30661 30620
+f 30661 30662 30622
+f 30621 30661 30622
+f 30662 30663 30623
+f 30622 30662 30623
+f 30663 30664 30624
+f 30623 30663 30624
+f 30664 30665 30625
+f 30624 30664 30625
+f 30665 30666 30626
+f 30625 30665 30626
+f 30666 30667 30627
+f 30626 30666 30627
+f 30667 30668 30628
+f 30627 30667 30628
+f 30668 30669 30629
+f 30628 30668 30629
+f 30669 30670 30630
+f 30629 30669 30630
+f 30671 30631 30630
+f 30670 30671 30630
+f 30671 30672 30632
+f 30631 30671 30632
+f 30672 30673 30633
+f 30632 30672 30633
+f 30673 30674 30634
+f 30633 30673 30634
+f 30674 30675 30635
+f 30634 30674 30635
+f 30675 30676 30636
+f 30635 30675 30636
+f 30676 30677 30637
+f 30636 30676 30637
+f 30677 30678 30638
+f 30637 30677 30638
+f 30678 30679 30639
+f 30638 30678 30639
+f 30679 30680 30640
+f 30639 30679 30640
+f 30680 30681 30641
+f 30640 30680 30641
+f 30681 30682 30642
+f 30641 30681 30642
+f 30682 30683 30643
+f 30642 30682 30643
+f 30683 30684 30644
+f 30643 30683 30644
+f 30685 30645 30644
+f 30684 30685 30644
+f 30686 30646 30645
+f 30685 30686 30645
+f 30687 30647 30646
+f 30686 30687 30646
+f 14248 14247 30647
+f 30687 14248 30647
+f 24270 6953 17768
+f 23345 23373 22031
+f 21613 12104 17880
+f 28598 28594 15684
+f 28369 28664 27776
+f 28368 28369 27776
+f 22787 25932 15109
+f 23175 28393 28664
+f 22042 22041 29875
+f 21389 5064 2651
+f 23464 17675 17674
+f 23464 17674 27720
+f 3309 8968 2771
+f 15284 15283 28161
+f 23661 1959 2771
+f 1723 1725 15681
+f 15681 1725 15679
+f 8968 23661 2771
+f 23588 21085 21087
+f 19826 16771 3378
+f 186 9447 187
+f 30688 29264 27251
+f 30689 30649 29264
+f 30688 30689 29264
+f 29927 28717 30649
+f 30689 29927 30649
+f 29927 22228 28717
+f 22785 7342 22786
+f 11930 5471 5470
+f 14303 25991 28555
+f 28840 28845 29272
+f 29271 28840 29272
+f 29377 29409 29586
+f 29409 29459 29541
+f 29882 29840 29237
+f 29840 29755 29180
+f 6096 6098 24880
+f 11542 11541 20421
+f 29667 29626 10949
+f 13053 29667 10949
+f 2293 21389 16232
+f 5064 2652 2651
+f 30387 30386 8967
+f 30292 28582 28595
+f 29503 29548 28390
+f 28390 29548 28391
+f 30607 30650 28494
+f 30690 30691 28801
+f 25911 25120 25788
+f 2829 21957 21876
+f 28229 22178 2340
+f 28707 28760 28708
+f 28661 28681 29715
+f 29669 28661 29715
+f 2662 21668 2507
+f 28681 28682 29760
+f 21668 21617 2507
+f 16634 30692 30651
+f 16635 16634 30651
+f 30692 30693 30652
+f 30651 30692 30652
+f 30693 30694 30653
+f 30652 30693 30653
+f 30694 30695 30654
+f 30653 30694 30654
+f 30695 30696 30655
+f 30654 30695 30655
+f 30696 30697 30656
+f 30655 30696 30656
+f 30697 30698 30657
+f 30656 30697 30657
+f 30698 30699 30658
+f 30657 30698 30658
+f 30699 30700 30659
+f 30658 30699 30659
+f 30700 30701 30660
+f 30659 30700 30660
+f 30701 30702 30661
+f 30660 30701 30661
+f 30702 30703 30662
+f 30661 30702 30662
+f 30703 30704 30663
+f 30662 30703 30663
+f 30704 30705 30664
+f 30663 30704 30664
+f 30705 30706 30665
+f 30664 30705 30665
+f 30706 30707 30666
+f 30665 30706 30666
+f 30707 30708 30667
+f 30666 30707 30667
+f 30708 30709 30668
+f 30667 30708 30668
+f 30709 30710 30669
+f 30668 30709 30669
+f 30710 30711 30670
+f 30669 30710 30670
+f 30712 30671 30670
+f 30711 30712 30670
+f 30712 30713 30672
+f 30671 30712 30672
+f 30713 30714 30673
+f 30672 30713 30673
+f 30714 30715 30674
+f 30673 30714 30674
+f 30715 30716 30675
+f 30674 30715 30675
+f 30716 30717 30676
+f 30675 30716 30676
+f 30717 30718 30677
+f 30676 30717 30677
+f 30718 30719 30678
+f 30677 30718 30678
+f 30719 30720 30679
+f 30678 30719 30679
+f 30720 30721 30680
+f 30679 30720 30680
+f 30721 30722 30681
+f 30680 30721 30681
+f 30722 30723 30682
+f 30681 30722 30682
+f 30723 30724 30683
+f 30682 30723 30683
+f 30724 30725 30684
+f 30683 30724 30684
+f 30726 30685 30684
+f 30725 30726 30684
+f 30727 30686 30685
+f 30726 30727 30685
+f 30728 30687 30686
+f 30727 30728 30686
+f 30729 14248 30687
+f 30728 30729 30687
+f 13590 16423 14567
+f 30729 18933 14248
+f 28855 26137 29506
+f 5819 27281 5813
+f 28369 23175 28664
+f 20922 28155 12637
+f 10847 1769 1768
+f 29623 29228 30192
+f 28542 30730 28796
+f 25317 15680 15679
+f 30731 30730 28542
+f 28509 30731 28542
+f 28594 28600 25046
+f 30730 27605 28796
+f 29228 29227 30192
+f 29210 29623 29211
+f 17879 22141 23971
+f 22230 27532 24968
+f 21225 28111 30648
+f 27042 21225 30648
+f 30732 30688 30648
+f 28111 30732 30648
+f 30733 30689 30688
+f 30732 30733 30688
+f 30733 29003 29927
+f 30689 30733 29927
+f 17278 22228 17279
+f 26330 6245 26327
+f 29883 18269 18247
+f 21325 15424 21161
+f 28847 29317 29272
+f 28845 28847 29272
+f 29333 29377 30559
+f 29409 29587 29586
+f 29756 29176 29207
+f 29755 29756 29207
+f 6249 6096 24879
+f 24879 6096 24880
+f 29626 29590 10950
+f 10949 29626 10950
+f 14135 8128 18009
+f 19958 27900 19956
+f 30519 10500 3507
+f 27666 30519 3507
+f 28644 28646 28645
+f 28388 29503 28390
+f 30734 30690 28800
+f 28799 30734 28800
+f 27626 28748 23178
+f 29157 27626 23178
+f 28319 29704 28320
+f 28718 2006 28452
+f 29592 28660 29630
+f 28659 28661 29669
+f 21777 22512 23967
+f 29350 21661 28558
+f 16723 30735 30692
+f 16634 16723 30692
+f 30735 30736 30693
+f 30692 30735 30693
+f 30736 30737 30694
+f 30693 30736 30694
+f 30737 30738 30695
+f 30694 30737 30695
+f 30739 30696 30695
+f 30738 30739 30695
+f 30739 30740 30697
+f 30696 30739 30697
+f 30740 30741 30698
+f 30697 30740 30698
+f 30741 30742 30699
+f 30698 30741 30699
+f 30742 30743 30700
+f 30699 30742 30700
+f 30743 30744 30701
+f 30700 30743 30701
+f 30744 30745 30702
+f 30701 30744 30702
+f 30745 30746 30703
+f 30702 30745 30703
+f 30746 30747 30704
+f 30703 30746 30704
+f 30747 30748 30705
+f 30704 30747 30705
+f 30748 30749 30706
+f 30705 30748 30706
+f 30749 30750 30707
+f 30706 30749 30707
+f 30750 30751 30708
+f 30707 30750 30708
+f 30751 30752 30709
+f 30708 30751 30709
+f 30752 30753 30710
+f 30709 30752 30710
+f 30753 30754 30711
+f 30710 30753 30711
+f 30755 30712 30711
+f 30754 30755 30711
+f 30755 30756 30713
+f 30712 30755 30713
+f 30756 30757 30714
+f 30713 30756 30714
+f 30757 30758 30715
+f 30714 30757 30715
+f 30758 30759 30716
+f 30715 30758 30716
+f 30759 30760 30717
+f 30716 30759 30717
+f 30760 30761 30718
+f 30717 30760 30718
+f 30761 30762 30719
+f 30718 30761 30719
+f 30762 30763 30720
+f 30719 30762 30720
+f 30763 30764 30721
+f 30720 30763 30721
+f 30764 30765 30722
+f 30721 30764 30722
+f 30766 30723 30722
+f 30765 30766 30722
+f 30766 30767 30724
+f 30723 30766 30724
+f 30767 30768 30725
+f 30724 30767 30725
+f 30769 30726 30725
+f 30768 30769 30725
+f 30770 30727 30726
+f 30769 30770 30726
+f 30771 30728 30727
+f 30770 30771 30727
+f 22719 30729 30728
+f 30771 22719 30728
+f 25428 18933 30729
+f 22719 25428 30729
+f 28485 28484 28506
+f 23430 23429 22045
+f 29443 22307 29709
+f 28486 28488 28837
+f 28801 30691 28508
+f 30772 30731 28509
+f 28803 27581 27605
+f 30730 28803 27605
+f 30691 28806 30772
+f 22896 16254 25988
+f 30690 28767 30691
+f 28805 28804 30731
+f 28809 28766 30773
+f 28806 28805 30772
+f 28111 28110 30732
+f 30774 28809 30773
+f 19491 24252 16205
+f 25858 13816 6100
+f 26129 15072 29928
+f 28994 20754 20756
+f 30775 30733 30732
+f 28698 30775 30732
+f 30775 30776 29003
+f 30733 30775 29003
+f 27657 22779 18654
+f 30776 23313 29003
+f 18039 6260 18040
+f 28183 6379 6249
+f 30777 29322 29317
+f 29322 30777 29320
+f 29333 30559 11930
+f 29286 29333 11930
+f 29710 29205 29176
+f 29756 29710 29176
+f 28114 23375 28089
+f 29620 6249 24879
+f 29590 29546 23050
+f 23050 29546 21014
+f 22310 15442 22311
+f 21389 2651 16232
+f 30519 30520 29803
+f 10500 30519 29803
+f 12561 28643 28904
+f 23173 27666 19995
+f 28511 30774 28798
+f 30773 30734 28799
+f 28748 28547 23179
+f 23178 28748 23179
+f 29704 27525 28670
+f 29266 29265 29138
+f 29549 28699 29592
+f 29630 28659 29669
+f 25373 25282 25427
+f 28296 22579 22533
+f 16760 28802 30735
+f 16723 16760 30735
+f 28802 29426 30736
+f 30735 28802 30736
+f 29426 30778 30737
+f 30736 29426 30737
+f 30778 30779 30738
+f 30737 30778 30738
+f 30780 30739 30738
+f 30779 30780 30738
+f 30780 30781 30740
+f 30739 30780 30740
+f 30781 30782 30741
+f 30740 30781 30741
+f 30782 30783 30742
+f 30741 30782 30742
+f 30783 30784 30743
+f 30742 30783 30743
+f 30784 30785 30744
+f 30743 30784 30744
+f 30785 30786 30745
+f 30744 30785 30745
+f 30786 30787 30746
+f 30745 30786 30746
+f 30787 30788 30747
+f 30746 30787 30747
+f 30788 30789 30748
+f 30747 30788 30748
+f 30789 30790 30749
+f 30748 30789 30749
+f 30791 30750 30749
+f 30790 30791 30749
+f 30792 30751 30750
+f 30791 30792 30750
+f 30792 30793 30752
+f 30751 30792 30752
+f 30793 30794 30753
+f 30752 30793 30753
+f 30794 30795 30754
+f 30753 30794 30754
+f 30796 30755 30754
+f 30795 30796 30754
+f 30796 30797 30756
+f 30755 30796 30756
+f 30797 30798 30757
+f 30756 30797 30757
+f 30798 30799 30758
+f 30757 30798 30758
+f 30799 30800 30759
+f 30758 30799 30759
+f 30800 30801 30760
+f 30759 30800 30760
+f 30801 30802 30761
+f 30760 30801 30761
+f 30802 30803 30762
+f 30761 30802 30762
+f 30803 30804 30763
+f 30762 30803 30763
+f 30804 30805 30764
+f 30763 30804 30764
+f 30805 30806 30765
+f 30764 30805 30765
+f 30807 30766 30765
+f 30806 30807 30765
+f 30807 30808 30767
+f 30766 30807 30767
+f 30809 30768 30767
+f 30808 30809 30767
+f 30810 30769 30768
+f 30809 30810 30768
+f 30811 30770 30769
+f 30810 30811 30769
+f 30812 30771 30770
+f 30811 30812 30770
+f 22720 22719 30771
+f 30812 22720 30771
+f 25428 5263 25373
+f 9642 9534 12563
+f 29796 28836 29797
+f 28324 21346 2841
+f 30609 21289 21288
+f 30608 30609 21288
+f 30691 30772 28508
+f 28508 30772 28509
+f 28804 28803 30730
+f 27245 24479 5932
+f 28722 868 28764
+f 25149 21656 27761
+f 11098 6894 8308
+f 25948 6370 6369
+f 15321 22160 8554
+f 29267 29266 29137
+f 28767 28806 30691
+f 21332 27240 23261
+f 29472 29471 30813
+f 29161 25216 29132
+f 28225 19196 19198
+f 27615 26752 23173
+f 30814 30775 28698
+f 28225 30814 28698
+f 30814 30815 30776
+f 30775 30814 30776
+f 22028 23313 30776
+f 30815 22028 30776
+f 4763 4765 17867
+f 16096 17143 16094
+f 28847 30777 29317
+f 22207 29323 29320
+f 21158 29714 29277
+f 29377 29586 30559
+f 29624 29174 29205
+f 29710 29624 29205
+f 22012 29285 29239
+f 23172 27615 23173
+f 10950 29590 23050
+f 27143 21066 21014
+f 10814 10813 28523
+f 28708 28760 28762
+f 30520 30431 22694
+f 30386 28595 8967
+f 28900 28644 28645
+f 27477 25759 25249
+f 30774 28511 28495
+f 28798 30773 28799
+f 29707 3584 29924
+f 28545 30608 23179
+f 28231 29281 29136
+f 17361 15585 30816
+f 28700 28699 29505
+f 28660 28659 29630
+f 28604 28765 5253
+f 35 30817 32
+f 24039 23984 23921
+f 16760 16854 28802
+f 29420 29421 30817
+f 25565 25837 25839
+f 29427 30818 30778
+f 29426 29427 30778
+f 30818 30819 30779
+f 30778 30818 30779
+f 30819 30820 30780
+f 30779 30819 30780
+f 30820 30821 30781
+f 30780 30820 30781
+f 30821 30822 30782
+f 30781 30821 30782
+f 30822 30823 30783
+f 30782 30822 30783
+f 30823 30824 30784
+f 30783 30823 30784
+f 30825 30785 30784
+f 30824 30825 30784
+f 30825 30826 30786
+f 30785 30825 30786
+f 30826 30827 30787
+f 30786 30826 30787
+f 30827 30828 30788
+f 30787 30827 30788
+f 30828 30829 30789
+f 30788 30828 30789
+f 30829 30830 30790
+f 30789 30829 30790
+f 30830 30831 30791
+f 30790 30830 30791
+f 30832 30792 30791
+f 30831 30832 30791
+f 30833 30793 30792
+f 30832 30833 30792
+f 30833 30834 30794
+f 30793 30833 30794
+f 30834 30835 30795
+f 30794 30834 30795
+f 30836 30796 30795
+f 30835 30836 30795
+f 30836 30837 30797
+f 30796 30836 30797
+f 30837 30838 30798
+f 30797 30837 30798
+f 30838 30839 30799
+f 30798 30838 30799
+f 30839 30840 30800
+f 30799 30839 30800
+f 30840 30841 30801
+f 30800 30840 30801
+f 30841 30842 30802
+f 30801 30841 30802
+f 30842 30843 30803
+f 30802 30842 30803
+f 30843 30844 30804
+f 30803 30843 30804
+f 30844 30845 30805
+f 30804 30844 30805
+f 30845 30846 30806
+f 30805 30845 30806
+f 30847 30807 30806
+f 30846 30847 30806
+f 30847 30848 30808
+f 30807 30847 30808
+f 30848 30849 30809
+f 30808 30848 30809
+f 30850 30810 30809
+f 30849 30850 30809
+f 30851 30811 30810
+f 30850 30851 30810
+f 30852 30812 30811
+f 30851 30852 30811
+f 15107 22720 30812
+f 30852 15107 30812
+f 22282 20812 11201
+f 18905 25988 18903
+f 28836 28837 29797
+f 19197 22895 19198
+f 30562 28848 21289
+f 30609 30562 21289
+f 28573 30607 30561
+f 28571 28573 30561
+f 30772 28805 30731
+f 30731 28804 30730
+f 21415 14024 21416
+f 29265 29136 29138
+f 28665 28700 29464
+f 28699 29549 29505
+f 28697 28696 29384
+f 28665 29464 29415
+f 28577 30199 29113
+f 28696 28665 29415
+f 30734 28724 30690
+f 28602 28580 28603
+f 21211 19198 22895
+f 29002 17279 22228
+f 19198 30853 30814
+f 28225 19198 30814
+f 30854 30815 30814
+f 30853 30854 30814
+f 30854 27756 22028
+f 30815 30854 22028
+f 22439 25763 22942
+f 17489 22956 22955
+f 29281 28234 28274
+f 30777 22208 29320
+f 29185 30855 28846
+f 29714 29276 29277
+f 25683 21343 11284
+f 29625 29172 29174
+f 29187 28481 28492
+f 28960 29239 28138
+f 28979 29066 28978
+f 29546 29504 21014
+f 29065 29258 28976
+f 28676 28675 21805
+f 29803 30520 22694
+f 30387 8967 22694
+f 29552 3309 3308
+f 28643 28644 28900
+f 30650 30774 28495
+f 30774 30773 28798
+f 29664 22459 22176
+f 29926 29706 29708
+f 868 28722 869
+f 5971 2238 2240
+f 28696 29415 29384
+f 28699 28660 29592
+f 28831 21669 28608
+f 22394 13051 13050
+f 5802 5801 17345
+f 22080 24017 22081
+f 27684 27709 4815
+f 27684 24334 24333
+f 28720 30856 30818
+f 29427 28720 30818
+f 30856 30857 30819
+f 30818 30856 30819
+f 30858 30820 30819
+f 30857 30858 30819
+f 30859 30821 30820
+f 30858 30859 30820
+f 30860 30822 30821
+f 30859 30860 30821
+f 30861 30823 30822
+f 30860 30861 30822
+f 30862 30824 30823
+f 30861 30862 30823
+f 30862 30863 30825
+f 30824 30862 30825
+f 30863 30864 30826
+f 30825 30863 30826
+f 30864 30865 30827
+f 30826 30864 30827
+f 30865 30866 30828
+f 30827 30865 30828
+f 30866 30867 30829
+f 30828 30866 30829
+f 30867 30868 30830
+f 30829 30867 30830
+f 30868 30869 30831
+f 30830 30868 30831
+f 30869 30870 30832
+f 30831 30869 30832
+f 30871 30833 30832
+f 30870 30871 30832
+f 30872 30834 30833
+f 30871 30872 30833
+f 30872 30873 30835
+f 30834 30872 30835
+f 30874 30836 30835
+f 30873 30874 30835
+f 30874 30875 30837
+f 30836 30874 30837
+f 30875 30876 30838
+f 30837 30875 30838
+f 30876 30877 30839
+f 30838 30876 30839
+f 30877 30878 30840
+f 30839 30877 30840
+f 30878 30879 30841
+f 30840 30878 30841
+f 30879 30880 30842
+f 30841 30879 30842
+f 30880 30881 30843
+f 30842 30880 30843
+f 30881 30882 30844
+f 30843 30881 30844
+f 30882 30883 30845
+f 30844 30882 30845
+f 30884 30846 30845
+f 30883 30884 30845
+f 30885 30847 30846
+f 30884 30885 30846
+f 30885 30886 30848
+f 30847 30885 30848
+f 30886 30887 30849
+f 30848 30886 30849
+f 1704 30850 30849
+f 30887 1704 30849
+f 28989 30851 30850
+f 1704 28989 30850
+f 30888 30852 30851
+f 28989 30888 30851
+f 15108 15107 30852
+f 30888 15108 30852
+f 24017 21888 21890
+f 21211 21213 19198
+f 30562 30522 28848
+f 22294 30610 22301
+f 28572 28571 30561
+f 30522 28807 28848
+f 2325 29671 2326
+f 30560 28572 30561
+f 22160 21332 23261
+f 17063 29466 17832
+f 28697 29384 29339
+f 25565 9795 16882
+f 29057 28558 28559
+f 28692 28697 29339
+f 28831 28608 21569
+f 28604 28346 29294
+f 28700 29505 29464
+f 28692 29339 29295
+f 5621 5623 28357
+f 28437 28621 25989
+f 16053 16052 17789
+f 28724 28767 30690
+f 21213 30853 19198
+f 27757 8928 22029
+f 21213 30889 30854
+f 30853 21213 30854
+f 30889 30474 27756
+f 30854 30889 27756
+f 10499 3299 3135
+f 24335 28796 27605
+f 2322 4962 2323
+f 6795 23181 5116
+f 29186 28846 28844
+f 29186 29185 28846
+f 29184 29238 182
+f 28137 28960 28138
+f 29068 28492 28487
+f 29068 29187 28492
+f 22237 5394 6899
+f 28323 28626 28624
+f 28886 15130 28887
+f 26998 26843 26844
+f 14781 16541 27736
+f 30431 30387 22694
+f 22316 2239 26503
+f 3308 1961 6531
+f 28809 30774 30650
+f 28800 30690 28801
+f 29159 25191 29665
+f 20213 25454 22474
+f 28741 28743 29248
+f 868 29631 28764
+f 14923 5340 14446
+f 28742 29295 29249
+f 20421 11541 6801
+f 24682 22603 25995
+f 1704 1703 28989
+f 24334 27684 4815
+f 28721 16861 26990
+f 28462 30890 30856
+f 28720 28462 30856
+f 30890 30891 30857
+f 30856 30890 30857
+f 30892 30858 30857
+f 30891 30892 30857
+f 30892 30893 30859
+f 30858 30892 30859
+f 30894 30860 30859
+f 30893 30894 30859
+f 30895 30861 30860
+f 30894 30895 30860
+f 30896 30862 30861
+f 30895 30896 30861
+f 30897 30863 30862
+f 30896 30897 30862
+f 30897 30898 30864
+f 30863 30897 30864
+f 30898 30899 30865
+f 30864 30898 30865
+f 30899 30900 30866
+f 30865 30899 30866
+f 30900 30901 30867
+f 30866 30900 30867
+f 30901 30902 30868
+f 30867 30901 30868
+f 30902 30903 30869
+f 30868 30902 30869
+f 30903 30904 30870
+f 30869 30903 30870
+f 30904 30905 30871
+f 30870 30904 30871
+f 30905 30906 30872
+f 30871 30905 30872
+f 30906 30907 30873
+f 30872 30906 30873
+f 30908 30874 30873
+f 30907 30908 30873
+f 30908 30909 30875
+f 30874 30908 30875
+f 30909 30910 30876
+f 30875 30909 30876
+f 30910 30911 30877
+f 30876 30910 30877
+f 30911 30912 30878
+f 30877 30911 30878
+f 30913 30879 30878
+f 30912 30913 30878
+f 30913 30914 30880
+f 30879 30913 30880
+f 30914 30915 30881
+f 30880 30914 30881
+f 30915 30916 30882
+f 30881 30915 30882
+f 30916 30917 30883
+f 30882 30916 30883
+f 30917 30918 30884
+f 30883 30917 30884
+f 30918 30919 30885
+f 30884 30918 30885
+f 30919 30920 30886
+f 30885 30919 30886
+f 30920 30921 30887
+f 30886 30920 30887
+f 28138 10847 10298
+f 30887 30921 1704
+f 21979 16743 25303
+f 30888 28989 25708
+f 14690 14689 25026
+f 25198 25136 17072
+f 22788 15108 30888
+f 22576 22780 22779
+f 27696 23984 24038
+f 25366 6248 25367
+f 30477 28808 28807
+f 22362 13815 22377
+f 28746 30521 30475
+f 28747 28746 30475
+f 6168 14442 2836
+f 6802 6801 17885
+f 28772 28741 29248
+f 29256 28772 29248
+f 28723 28604 29294
+f 28743 29249 29248
+f 28723 29294 25342
+f 22788 30888 25708
+f 30603 29348 29010
+f 28742 28692 29295
+f 29193 28771 29256
+f 27332 28504 27219
+f 29385 28744 28621
+f 16804 17490 16805
+f 28766 28724 30734
+f 16318 16779 16319
+f 27820 24711 13478
+f 21212 30922 30889
+f 21213 21212 30889
+f 30922 28663 30474
+f 30889 30922 30474
+f 28437 25989 25994
+f 8929 8928 27757
+f 29138 29136 28260
+f 12637 28178 12638
+f 29241 28844 28839
+f 29241 29186 28844
+f 29015 16277 16273
+f 21342 10022 15560
+f 29303 28487 28486
+f 29303 29068 28487
+f 28305 28323 28624
+f 28323 28326 28626
+f 21659 24857 28466
+f 29934 15130 28886
+f 29157 23178 27648
+f 7347 29552 3308
+f 29623 30192 29211
+f 11118 7554 6479
+f 28768 30650 30607
+f 28768 28809 30650
+f 15282 23389 15280
+f 8820 8385 8295
+f 29192 28875 29193
+f 28743 28742 29249
+f 29348 28958 29010
+f 14026 22442 14968
+f 21610 24936 21611
+f 19189 2337 5808
+f 29628 29261 21936
+f 5388 25120 28551
+f 30337 28204 24859
+f 2338 28288 29925
+f 11153 29551 29665
+f 30923 24997 24934
+f 22041 29260 29011
+f 19190 19189 5808
+f 4495 6086 28753
+f 2339 2338 29925
+f 6380 24991 25280
+f 2475 20292 20294
+f 29551 28183 29620
+f 22872 14247 16865
+f 4495 28753 28539
+f 26990 28462 28720
+f 28972 19599 11088
+f 28461 30924 30890
+f 28462 28461 30890
+f 30924 30925 30891
+f 30890 30924 30891
+f 30926 30892 30891
+f 30925 30926 30891
+f 30926 30927 30893
+f 30892 30926 30893
+f 30928 30894 30893
+f 30927 30928 30893
+f 30929 30895 30894
+f 30928 30929 30894
+f 30929 30930 30896
+f 30895 30929 30896
+f 30930 30931 30897
+f 30896 30930 30897
+f 30931 30932 30898
+f 30897 30931 30898
+f 30932 30933 30899
+f 30898 30932 30899
+f 30933 30934 30900
+f 30899 30933 30900
+f 30934 30935 30901
+f 30900 30934 30901
+f 30935 30936 30902
+f 30901 30935 30902
+f 30936 30937 30903
+f 30902 30936 30903
+f 30937 30938 30904
+f 30903 30937 30904
+f 30938 30939 30905
+f 30904 30938 30905
+f 30939 30940 30906
+f 30905 30939 30906
+f 30940 30941 30907
+f 30906 30940 30907
+f 30941 30942 30908
+f 30907 30941 30908
+f 30942 30943 30909
+f 30908 30942 30909
+f 30943 30944 30910
+f 30909 30943 30910
+f 30944 30945 30911
+f 30910 30944 30911
+f 30945 30946 30912
+f 30911 30945 30912
+f 30946 30947 30913
+f 30912 30946 30913
+f 30947 30948 30914
+f 30913 30947 30914
+f 30948 30949 30915
+f 30914 30948 30915
+f 30949 30950 30916
+f 30915 30949 30916
+f 30951 30917 30916
+f 30950 30951 30916
+f 30951 30952 30918
+f 30917 30951 30918
+f 30952 30953 30919
+f 30918 30952 30919
+f 30953 30954 30920
+f 30919 30953 30920
+f 30954 30955 30921
+f 30920 30954 30921
+f 28057 25266 25265
+f 24168 24120 24119
+f 28410 28964 28701
+f 15774 24072 24069
+f 29035 28387 29037
+f 28389 28392 29039
+f 22656 24063 22654
+f 9739 5118 22458
+f 23945 22656 22655
+f 2926 2928 17783
+f 30477 30476 28808
+f 20212 20214 9157
+f 28747 30475 30432
+f 28810 28747 30432
+f 16991 16783 22863
+f 16783 16991 28933
+f 29150 28876 29192
+f 28875 28771 29193
+f 4803 4495 28539
+f 28851 28853 29465
+f 6086 28751 28753
+f 28853 28855 29506
+f 28827 28876 29150
+f 29111 28827 29150
+f 21902 6241 27240
+f 21332 21902 27240
+f 22896 25988 18905
+f 30773 28766 30734
+f 18905 21212 22896
+f 29041 27868 27841
+f 18905 11081 30922
+f 21212 18905 30922
+f 2462 22901 2463
+f 30922 11081 28663
+f 22080 22082 24074
+f 22723 17237 26943
+f 29759 29282 29283
+f 25765 28463 28887
+f 28842 29379 28838
+f 29240 29241 28839
+f 29238 29015 16273
+f 28960 22012 29239
+f 29304 28486 28836
+f 29304 29303 28486
+f 28301 28300 29096
+f 28326 26712 28626
+f 28466 29934 28886
+f 27628 29157 27647
+f 18269 17158 18247
+f 16543 200 17114
+f 19767 27504 18685
+f 25734 11029 24613
+f 28746 28572 30560
+f 28573 28768 30607
+f 20537 21311 20536
+f 5806 5968 29671
+f 28787 28827 29111
+f 28771 28772 29256
+f 27186 24108 26779
+f 28855 28857 26137
+f 28857 29802 26137
+f 28857 23233 29802
+f 24997 30923 25068
+f 30237 28116 28136
+f 28116 30237 27641
+f 29665 25191 11153
+f 641 29551 11153
+f 24934 21610 30923
+f 25987 30344 24858
+f 21152 21086 25479
+f 28160 30236 28136
+f 3538 18721 11096
+f 4080 12887 6594
+f 526 27370 16828
+f 25987 24990 30956
+f 25068 30923 642
+f 17053 21269 26552
+f 21216 7157 7156
+f 16215 24969 16216
+f 30921 30955 28067
+f 30957 22360 22361
+f 26050 19705 26148
+f 23233 27597 29802
+f 8554 23261 8555
+f 16861 16643 24589
+f 18614 27228 11030
+f 14904 30958 30924
+f 28461 14904 30924
+f 30958 30959 30925
+f 30924 30958 30925
+f 30959 30960 30926
+f 30925 30959 30926
+f 30960 30961 30927
+f 30926 30960 30927
+f 30961 30962 30928
+f 30927 30961 30928
+f 30962 30963 30929
+f 30928 30962 30929
+f 30963 30964 30930
+f 30929 30963 30930
+f 30965 30931 30930
+f 30964 30965 30930
+f 30966 30932 30931
+f 30965 30966 30931
+f 30967 30933 30932
+f 30966 30967 30932
+f 30968 30934 30933
+f 30967 30968 30933
+f 30968 30969 30935
+f 30934 30968 30935
+f 30969 30970 30936
+f 30935 30969 30936
+f 30970 30971 30937
+f 30936 30970 30937
+f 30971 30972 30938
+f 30937 30971 30938
+f 30972 30973 30939
+f 30938 30972 30939
+f 30973 30974 30940
+f 30939 30973 30940
+f 30974 30975 30941
+f 30940 30974 30941
+f 30975 30976 30942
+f 30941 30975 30942
+f 30976 30977 30943
+f 30942 30976 30943
+f 30977 30978 30944
+f 30943 30977 30944
+f 30978 30979 30945
+f 30944 30978 30945
+f 30979 30980 30946
+f 30945 30979 30946
+f 30980 30981 30947
+f 30946 30980 30947
+f 30981 30982 30948
+f 30947 30981 30948
+f 30982 30983 30949
+f 30948 30982 30949
+f 30983 30984 30950
+f 30949 30983 30950
+f 30985 30951 30950
+f 30984 30985 30950
+f 30985 30986 30952
+f 30951 30985 30952
+f 30986 30987 30953
+f 30952 30986 30953
+f 30987 30988 30954
+f 30953 30987 30954
+f 30988 30989 30955
+f 30954 30988 30955
+f 30989 2410 28067
+f 30955 30989 28067
+f 22153 17578 2565
+f 16310 16309 15460
+f 29037 28389 29039
+f 28392 27868 29041
+f 8501 1339 8696
+f 29184 182 16542
+f 21673 28884 29257
+f 28884 24556 28297
+f 30388 28850 28849
+f 29485 29257 22513
+f 28812 28793 30295
+f 30294 28812 30295
+f 5667 5796 15655
+f 28933 5667 15655
+f 28954 28863 29008
+f 28786 28787 29061
+f 23405 23429 23408
+f 26340 23641 18002
+f 29747 29121 20336
+f 27930 18903 28179
+f 28876 28875 29192
+f 28953 28865 28954
+f 12644 27582 24342
+f 18710 12644 24342
+f 6262 28677 6387
+f 30293 28832 30294
+f 15394 26051 11542
+f 22901 2462 8857
+f 25267 5682 2500
+f 18905 18904 11081
+f 8686 16287 8687
+f 23368 3430 19194
+f 17358 30990 14909
+f 24224 23425 23424
+f 22442 5259 14969
+f 29759 29283 29276
+f 29240 28839 28838
+f 29334 29240 28838
+f 6905 2997 5780
+f 2584 2586 16277
+f 29288 29304 28836
+f 29141 28484 28481
+f 29075 29078 29076
+f 28301 29096 30291
+f 25968 25857 27898
+f 28783 17703 17702
+f 23243 28513 28641
+f 9384 25709 17494
+f 30608 21288 28679
+f 23179 30608 28679
+f 28810 30432 30295
+f 30521 28746 30560
+f 11026 16991 22863
+f 16991 5667 28933
+f 28952 28910 28953
+f 29061 28787 29111
+f 27240 23346 27239
+f 22027 23259 27420
+f 29014 29747 29120
+f 10566 29884 22658
+f 30991 18119 643
+f 22863 16411 22713
+f 24336 29155 24394
+f 30992 6805 6804
+f 181 9916 185
+f 16960 16962 17791
+f 26636 24896 16732
+f 4369 21226 3007
+f 17699 17698 24592
+f 30993 29238 29184
+f 15620 15634 15636
+f 13400 17619 17620
+f 8295 8385 6698
+f 1486 3282 21292
+f 24214 17996 1486
+f 21292 24214 1486
+f 18794 15023 23855
+f 11224 11223 17922
+f 11389 24346 3812
+f 13534 14950 18267
+f 15111 21804 15112
+f 29120 29747 20336
+f 28155 28177 28178
+f 18009 15190 3005
+f 20288 20289 21150
+f 27657 22576 22779
+f 14903 30994 14904
+f 14902 14904 28461
+f 30994 30995 30958
+f 14904 30994 30958
+f 30995 30996 30959
+f 30958 30995 30959
+f 30997 30960 30959
+f 30996 30997 30959
+f 30997 30998 30961
+f 30960 30997 30961
+f 30999 30962 30961
+f 30998 30999 30961
+f 31000 30963 30962
+f 30999 31000 30962
+f 31000 31001 30964
+f 30963 31000 30964
+f 31001 31002 30965
+f 30964 31001 30965
+f 31002 31003 30966
+f 30965 31002 30966
+f 31004 30967 30966
+f 31003 31004 30966
+f 31005 30968 30967
+f 31004 31005 30967
+f 31006 30969 30968
+f 31005 31006 30968
+f 31006 31007 30970
+f 30969 31006 30970
+f 31007 31008 30971
+f 30970 31007 30971
+f 31008 31009 30972
+f 30971 31008 30972
+f 31009 31010 30973
+f 30972 31009 30973
+f 31010 31011 30974
+f 30973 31010 30974
+f 31011 31012 30975
+f 30974 31011 30975
+f 31012 31013 30976
+f 30975 31012 30976
+f 31013 31014 30977
+f 30976 31013 30977
+f 31014 31015 30978
+f 30977 31014 30978
+f 31015 31016 30979
+f 30978 31015 30979
+f 31016 31017 30980
+f 30979 31016 30980
+f 31017 31018 30981
+f 30980 31017 30981
+f 31018 31019 30982
+f 30981 31018 30982
+f 31019 31020 30983
+f 30982 31019 30983
+f 31021 30984 30983
+f 31020 31021 30983
+f 31021 31022 30985
+f 30984 31021 30985
+f 31022 31023 30986
+f 30985 31022 30986
+f 31023 31024 30987
+f 30986 31023 30987
+f 31024 31025 30988
+f 30987 31024 30988
+f 31025 31026 30989
+f 30988 31025 30989
+f 31026 31027 2410
+f 30989 31026 2410
+f 22161 3922 15085
+f 31027 2408 2410
+f 29039 28392 29041
+f 26864 27261 15367
+f 31028 14511 26131
+f 4113 4115 21718
+f 28893 28891 29588
+f 29547 28893 29588
+f 30388 30343 28850
+f 29496 27548 23126
+f 28922 28880 30154
+f 28833 30246 30197
+f 5253 22954 5254
+f 5248 5247 2318
+f 28951 28993 28952
+f 29008 28786 29061
+f 21626 21625 22146
+f 22145 28513 23243
+f 27448 27660 27332
+f 15280 26332 23169
+f 28863 28786 29008
+f 29047 28993 28951
+f 8128 15190 18009
+f 21653 6805 17410
+f 28677 6388 6387
+f 28832 28812 30294
+f 6212 5655 5654
+f 15848 15604 15606
+f 27982 26041 13949
+f 13949 17566 27982
+f 1217 9062 9341
+f 7361 15655 7359
+f 15677 21631 23927
+f 29457 28962 29499
+f 30855 30147 22208
+f 12461 9800 22163
+f 29185 29309 30147
+f 30855 29185 30147
+f 3814 16131 28159
+f 14653 8611 15167
+f 29187 29141 28481
+f 29094 28505 28484
+f 29114 28137 10298
+f 29078 29080 29076
+f 22595 15399 22596
+f 16156 22234 22236
+f 28889 15111 15113
+f 7361 23773 28061
+f 30522 30477 28807
+f 30476 28849 28808
+f 28832 30293 30246
+f 28793 28810 30295
+f 17292 16127 16128
+f 5666 28346 5252
+f 29005 29047 29099
+f 28865 28863 28954
+f 28677 15425 6388
+f 28597 29709 30610
+f 14767 560 27565
+f 11026 22863 11027
+f 2862 17589 19668
+f 11025 11027 25343
+f 25343 25342 11025
+f 27902 27897 28066
+f 29754 6804 26960
+f 27394 2587 2589
+f 2587 28206 2588
+f 4173 3229 19760
+f 28206 14846 2588
+f 15873 15619 4389
+f 4173 19760 15013
+f 16115 9048 14536
+f 15172 25193 29158
+f 31029 21292 4174
+f 15013 31029 4174
+f 31030 24214 21292
+f 31029 31030 21292
+f 27565 560 22292
+f 31030 21153 24214
+f 29672 30020 1743
+f 22292 560 559
+f 17661 27569 17723
+f 26752 27595 14949
+f 29802 11387 26135
+f 16752 16751 13807
+f 13333 18215 18100
+f 21719 14903 24703
+f 21719 22200 14903
+f 31031 31032 31033
+f 22200 31034 30994
+f 14903 22200 30994
+f 31034 31035 30995
+f 30994 31034 30995
+f 31035 31036 30996
+f 30995 31035 30996
+f 31037 30997 30996
+f 31036 31037 30996
+f 31037 31038 30998
+f 30997 31037 30998
+f 31038 31039 30999
+f 30998 31038 30999
+f 31039 31040 31000
+f 30999 31039 31000
+f 31040 31041 31001
+f 31000 31040 31001
+f 31041 31042 31002
+f 31001 31041 31002
+f 31042 31043 31003
+f 31002 31042 31003
+f 31044 31004 31003
+f 31043 31044 31003
+f 31045 31005 31004
+f 31044 31045 31004
+f 31046 31006 31005
+f 31045 31046 31005
+f 31046 31047 31007
+f 31006 31046 31007
+f 31047 31048 31008
+f 31007 31047 31008
+f 31048 31049 31009
+f 31008 31048 31009
+f 31049 31050 31010
+f 31009 31049 31010
+f 31050 31051 31011
+f 31010 31050 31011
+f 31051 31052 31012
+f 31011 31051 31012
+f 31052 31053 31013
+f 31012 31052 31013
+f 31053 31054 31014
+f 31013 31053 31014
+f 31054 31055 31015
+f 31014 31054 31015
+f 31055 31056 31016
+f 31015 31055 31016
+f 31056 31057 31017
+f 31016 31056 31017
+f 31057 31058 31018
+f 31017 31057 31018
+f 31058 31059 31019
+f 31018 31058 31019
+f 31059 31060 31020
+f 31019 31059 31020
+f 31061 31021 31020
+f 31060 31061 31020
+f 31061 31062 31022
+f 31021 31061 31022
+f 31062 31063 31023
+f 31022 31062 31023
+f 31063 31064 31024
+f 31023 31063 31024
+f 31064 31065 31025
+f 31024 31064 31025
+f 31066 31026 31025
+f 31065 31066 31025
+f 31066 31067 31027
+f 31026 31066 31027
+f 31067 27653 2408
+f 31027 31067 2408
+f 23511 23496 23531
+f 19604 31068 31069
+f 23010 2831 5340
+f 22596 15399 25734
+f 28891 28890 29627
+f 29588 28891 29627
+f 30247 28856 28854
+f 30296 30247 28854
+f 28859 28922 30110
+f 28880 28833 30197
+f 2318 28715 2325
+f 5255 5109 28576
+f 29006 29005 29045
+f 28910 28865 28953
+f 22353 29875 22358
+f 22006 29259 28598
+f 28881 2333 22020
+f 28941 29007 28991
+f 26505 29133 22315
+f 29099 29047 28951
+f 28993 28910 28952
+f 15215 15682 15216
+f 5255 28576 15220
+f 28110 21225 21912
+f 11099 6261 18509
+f 27336 27410 27337
+f 20289 24328 7860
+f 19473 23007 23075
+f 27410 27618 27337
+f 28846 30855 28847
+f 3539 3541 23028
+f 6386 6385 27566
+f 30855 30777 28847
+f 6386 27566 23238
+f 29089 6386 23238
+f 29309 29310 22206
+f 30147 29309 22206
+f 5388 28551 28270
+f 23182 21924 22964
+f 29141 29094 28484
+f 29094 29042 28348
+f 28694 29072 28695
+f 23368 4337 22778
+f 29132 24108 11556
+f 28491 25617 25616
+f 28890 28889 29666
+f 29666 28889 15113
+f 30476 30388 28849
+f 30343 28852 28850
+f 28860 28859 30063
+f 28833 28832 30246
+f 15219 5255 15220
+f 5109 30601 28576
+f 29004 29007 28908
+f 29045 29005 29099
+f 2024 12559 19839
+f 12559 12561 28904
+f 3033 13336 13147
+f 15680 25317 22292
+f 31070 25343 11027
+f 31071 31070 22713
+f 11027 22713 31070
+f 22713 11027 22863
+f 16642 29754 26960
+f 31072 31073 27328
+f 16910 1346 14846
+f 28206 16910 14846
+f 17452 17167 21160
+f 14534 7017 9406
+f 31074 19760 14534
+f 9406 31074 14534
+f 31075 15013 19760
+f 31074 31075 19760
+f 31076 31029 15013
+f 31075 31076 15013
+f 31077 31030 31029
+f 31076 31077 31029
+f 31078 21153 31030
+f 31077 31078 31030
+f 18210 21259 17836
+f 31078 21086 21153
+f 29106 28031 29496
+f 29338 15285 1752
+f 23025 1882 29307
+f 21141 21140 28927
+f 16639 25228 16640
+f 18933 25427 25529
+f 26990 24590 28462
+f 17127 2897 22199
+f 17127 22199 16978
+f 21873 17500 31034
+f 22200 21873 31034
+f 17500 27352 31035
+f 31034 17500 31035
+f 27352 31079 31036
+f 31035 27352 31036
+f 31079 31080 31037
+f 31036 31079 31037
+f 31080 31081 31038
+f 31037 31080 31038
+f 31081 31082 31039
+f 31038 31081 31039
+f 31083 31040 31039
+f 31082 31083 31039
+f 31084 31041 31040
+f 31083 31084 31040
+f 31084 31085 31042
+f 31041 31084 31042
+f 31085 31086 31043
+f 31042 31085 31043
+f 31086 31087 31044
+f 31043 31086 31044
+f 31087 31088 31045
+f 31044 31087 31045
+f 31088 31089 31046
+f 31045 31088 31046
+f 31089 31090 31047
+f 31046 31089 31047
+f 31090 31091 31048
+f 31047 31090 31048
+f 31091 31092 31049
+f 31048 31091 31049
+f 31093 31050 31049
+f 31092 31093 31049
+f 31094 31051 31050
+f 31093 31094 31050
+f 31094 31095 31052
+f 31051 31094 31052
+f 31095 31096 31053
+f 31052 31095 31053
+f 31096 31097 31054
+f 31053 31096 31054
+f 31097 31098 31055
+f 31054 31097 31055
+f 31098 31099 31056
+f 31055 31098 31056
+f 31099 31100 31057
+f 31056 31099 31057
+f 31100 31101 31058
+f 31057 31100 31058
+f 31101 31102 31059
+f 31058 31101 31059
+f 31102 31103 31060
+f 31059 31102 31060
+f 31104 31061 31060
+f 31103 31104 31060
+f 31104 31105 31062
+f 31061 31104 31062
+f 31105 31106 31063
+f 31062 31105 31063
+f 31106 31107 31064
+f 31063 31106 31064
+f 31107 31108 31065
+f 31064 31107 31065
+f 31109 31066 31065
+f 31108 31109 31065
+f 31110 31067 31066
+f 31109 31110 31066
+f 31110 27654 27653
+f 31067 31110 27653
+f 23026 6371 26504
+f 26087 22846 28108
+f 26813 29666 26811
+f 26962 28888 12466
+f 29462 28894 29502
+f 24558 24557 16155
+f 22800 28906 28856
+f 30247 22800 28856
+f 28860 30063 30019
+f 28880 30197 30154
+f 5795 30602 30601
+f 5109 5795 30601
+f 28909 29056 28908
+f 28991 29006 29045
+f 24590 14902 28461
+f 29589 28227 28226
+f 25749 27620 26946
+f 20371 31111 20372
+f 29060 29056 28909
+f 28862 29060 28909
+f 5800 29346 30602
+f 5795 5800 30602
+f 27572 15187 27410
+f 15684 22135 22134
+f 4490 14042 14041
+f 23546 14735 11030
+f 5946 5948 27618
+f 28906 22800 11198
+f 29540 28695 23027
+f 21496 26255 22748
+f 26826 17980 20253
+f 2339 29925 28609
+f 5531 5533 20018
+f 23103 2509 22317
+f 14520 10814 6528
+f 29350 29126 21661
+f 23663 28757 29134
+f 29278 29128 10427
+f 5259 19243 14969
+f 14025 5673 22442
+f 28505 29094 28348
+f 28348 29042 28410
+f 8311 2147 7105
+f 21343 21342 15560
+f 25176 22751 22750
+f 17221 25479 21085
+f 28892 28893 29547
+f 29627 28890 29666
+f 30296 28854 28852
+f 30343 30296 28852
+f 28858 28860 30019
+f 28922 30154 30110
+f 5799 29347 29346
+f 5800 5799 29346
+f 29110 29060 28862
+f 29007 29006 28991
+f 12257 5390 14959
+f 26946 27620 27754
+f 21514 21513 1274
+f 1273 21514 1274
+f 30020 29672 22034
+f 31112 28763 31113
+f 17485 17144 24762
+f 31114 31115 31116
+f 31117 31118 29115
+f 16642 26960 24589
+f 16643 16642 24589
+f 31119 27350 31120
+f 43 42 1346
+f 4554 9406 2418
+f 4343 8305 8307
+f 31121 31074 9406
+f 4554 31121 9406
+f 31122 31075 31074
+f 31121 31122 31074
+f 31123 31076 31075
+f 31122 31123 31075
+f 31124 31077 31076
+f 31123 31124 31076
+f 31125 31078 31077
+f 31124 31125 31077
+f 31126 21086 31078
+f 31125 31126 31078
+f 23100 23102 18938
+f 31126 21087 21086
+f 23928 22277 16756
+f 17501 17500 21873
+f 28877 29109 28878
+f 29007 28941 28908
+f 8446 20542 18888
+f 4394 12257 14959
+f 16830 16832 18838
+f 17127 16978 16977
+f 27550 28031 27574
+f 23429 21884 8500
+f 430 18838 16832
+f 431 430 16832
+f 3982 31127 31079
+f 27352 3982 31079
+f 31128 31080 31079
+f 31127 31128 31079
+f 31128 31129 31081
+f 31080 31128 31081
+f 31129 31130 31082
+f 31081 31129 31082
+f 31131 31083 31082
+f 31130 31131 31082
+f 31132 31084 31083
+f 31131 31132 31083
+f 31133 31085 31084
+f 31132 31133 31084
+f 31134 31086 31085
+f 31133 31134 31085
+f 31135 31087 31086
+f 31134 31135 31086
+f 31135 31136 31088
+f 31087 31135 31088
+f 31136 31137 31089
+f 31088 31136 31089
+f 31137 31138 31090
+f 31089 31137 31090
+f 31139 31091 31090
+f 31138 31139 31090
+f 31140 31092 31091
+f 31139 31140 31091
+f 31141 31093 31092
+f 31140 31141 31092
+f 31142 31094 31093
+f 31141 31142 31093
+f 31143 31095 31094
+f 31142 31143 31094
+f 31144 31096 31095
+f 31143 31144 31095
+f 31144 31145 31097
+f 31096 31144 31097
+f 31145 31146 31098
+f 31097 31145 31098
+f 31146 31147 31099
+f 31098 31146 31099
+f 31147 31148 31100
+f 31099 31147 31100
+f 31148 31149 31101
+f 31100 31148 31101
+f 31149 31150 31102
+f 31101 31149 31102
+f 31150 31151 31103
+f 31102 31150 31103
+f 31152 31104 31103
+f 31151 31152 31103
+f 31152 31153 31105
+f 31104 31152 31105
+f 31153 31154 31106
+f 31105 31153 31106
+f 31155 31107 31106
+f 31154 31155 31106
+f 31156 31108 31107
+f 31155 31156 31107
+f 31157 31109 31108
+f 31156 31157 31108
+f 31158 31110 31109
+f 31157 31158 31109
+f 29975 27654 31110
+f 31158 29975 31110
+f 27654 14691 14690
+f 28201 29313 29268
+f 8555 3314 3794
+f 23810 5029 2126
+f 5623 29188 21415
+f 28894 28892 29502
+f 28942 28907 29935
+f 27218 22628 26888
+f 2174 29126 29350
+f 28858 30019 29974
+f 29148 29145 28861
+f 23025 29307 29347
+f 5660 2416 2418
+f 29145 29109 28877
+f 8885 4219 5206
+f 21889 23966 23967
+f 27571 17583 19823
+f 29056 29004 28908
+f 29149 29148 28830
+f 1882 22007 29308
+f 22007 30599 29308
+f 29885 29800 29118
+f 21066 29885 29118
+f 4451 28055 14738
+f 22778 3430 23368
+f 27982 17566 17706
+f 27571 15187 27572
+f 28695 3539 23027
+f 21837 18709 18711
+f 29097 29142 28982
+f 28586 28593 28883
+f 22332 22042 22353
+f 29875 13813 22358
+f 29125 1052 29134
+f 27668 27671 26136
+f 28983 15443 15442
+f 22310 28983 15442
+f 28984 28983 22310
+f 24514 28984 22310
+f 29042 28964 28410
+f 28964 28965 28701
+f 28464 28447 29028
+f 6384 29041 27841
+f 28646 28489 29712
+f 17144 17143 24762
+f 29336 28897 29381
+f 29502 28892 29547
+f 24338 27446 24336
+f 5110 22160 15321
+f 29046 28992 29841
+f 28859 30110 30063
+f 5799 23025 29347
+f 1882 29308 29307
+f 29194 29149 28829
+f 28878 29110 28862
+f 5970 29842 6950
+f 5971 5970 6950
+f 22316 2240 2239
+f 869 31159 31160
+f 15717 27957 15718
+f 17119 17121 31161
+f 22945 14907 29116
+f 31115 31162 31116
+f 31114 31116 10557
+f 10556 31114 10557
+f 16910 43 1346
+f 41 15826 42
+f 31163 31164 31165
+f 1747 1746 7651
+f 31166 4554 2417
+f 4969 31166 2417
+f 31167 31121 4554
+f 31166 31167 4554
+f 31168 31122 31121
+f 31167 31168 31121
+f 31169 31123 31122
+f 31168 31169 31122
+f 31170 31124 31123
+f 31169 31170 31123
+f 31171 31125 31124
+f 31170 31171 31124
+f 31172 31126 31125
+f 31171 31172 31125
+f 23589 21087 31126
+f 31172 23589 31126
+f 20921 25049 6236
+f 23588 23587 25372
+f 29109 29110 28878
+f 17833 3367 3366
+f 5974 29888 29842
+f 5970 5974 29842
+f 6238 29936 29888
+f 18099 18215 18161
+f 3983 9795 3981
+f 17306 17265 17267
+f 6525 28088 28283
+f 24479 27245 25874
+f 23765 31173 31127
+f 3982 23765 31127
+f 31174 31128 31127
+f 31173 31174 31127
+f 31175 31129 31128
+f 31174 31175 31128
+f 31175 31176 31130
+f 31129 31175 31130
+f 31177 31131 31130
+f 31176 31177 31130
+f 31178 31132 31131
+f 31177 31178 31131
+f 31179 31133 31132
+f 31178 31179 31132
+f 31180 31134 31133
+f 31179 31180 31133
+f 31181 31135 31134
+f 31180 31181 31134
+f 31182 31136 31135
+f 31181 31182 31135
+f 31183 31137 31136
+f 31182 31183 31136
+f 31184 31138 31137
+f 31183 31184 31137
+f 31185 31139 31138
+f 31184 31185 31138
+f 31186 31140 31139
+f 31185 31186 31139
+f 31187 31141 31140
+f 31186 31187 31140
+f 31188 31142 31141
+f 31187 31188 31141
+f 31189 31143 31142
+f 31188 31189 31142
+f 31190 31144 31143
+f 31189 31190 31143
+f 31190 31191 31145
+f 31144 31190 31145
+f 31191 31192 31146
+f 31145 31191 31146
+f 31192 31193 31147
+f 31146 31192 31147
+f 31194 31148 31147
+f 31193 31194 31147
+f 31194 31195 31149
+f 31148 31194 31149
+f 31195 31196 31150
+f 31149 31195 31150
+f 31197 31151 31150
+f 31196 31197 31150
+f 31198 31152 31151
+f 31197 31198 31151
+f 31198 31199 31153
+f 31152 31198 31153
+f 31199 31200 31154
+f 31153 31199 31154
+f 31201 31155 31154
+f 31200 31201 31154
+f 31202 31156 31155
+f 31201 31202 31155
+f 31203 31157 31156
+f 31202 31203 31156
+f 31203 31204 31158
+f 31157 31203 31158
+f 31205 29975 31158
+f 31204 31205 31158
+f 26791 28201 23322
+f 31205 27619 29975
+f 24429 2668 3051
+f 22217 26340 28424
+f 25629 1741 1740
+f 28603 5798 5794
+f 28992 28942 29886
+f 28907 28858 29974
+f 19056 15185 30600
+f 19103 2174 29350
+f 29194 28829 28828
+f 28921 29145 28877
+f 5974 6238 29888
+f 4500 29976 29936
+f 6238 4500 29936
+f 4499 30021 29976
+f 29145 28921 28861
+f 29250 28828 28811
+f 19056 30600 30599
+f 22007 19056 30599
+f 25505 26132 19823
+f 28942 29935 29886
+f 31159 869 31206
+f 9635 27730 24829
+f 14981 24328 20289
+f 20289 7860 21150
+f 28693 28695 29540
+f 1274 22034 29672
+f 1868 1867 22724
+f 28762 28761 22312
+f 29092 29091 3540
+f 29072 29092 3540
+f 29203 9548 23098
+f 22252 5531 20018
+f 28760 28929 28761
+f 28985 28984 24514
+f 28977 28967 23106
+f 23105 28977 23106
+f 28974 28971 29016
+f 28977 28974 29033
+f 29293 28937 25748
+f 29033 28974 29016
+f 29289 28899 29336
+f 28158 25372 23587
+f 29059 29058 30244
+f 28897 28896 29381
+f 11090 17600 28972
+f 8690 28419 28420
+f 28956 29046 29799
+f 28992 29886 29841
+f 15185 29349 30600
+f 2664 29278 29048
+f 29255 28811 28813
+f 29148 28861 28830
+f 4500 4499 29976
+f 17883 30064 30021
+f 22034 1274 21513
+f 31207 31208 31209
+f 867 869 31160
+f 31210 31211 31212
+f 31210 31212 31213
+f 14756 16170 15826
+f 14756 17547 16170
+f 41 14756 15826
+f 17547 16976 16170
+f 868 867 1274
+f 8672 5523 8673
+f 6644 15828 6645
+f 18170 12554 10819
+f 31214 31166 4969
+f 13209 31214 4969
+f 31215 31167 31166
+f 31214 31215 31166
+f 31216 31168 31167
+f 31215 31216 31167
+f 31217 31169 31168
+f 31216 31217 31168
+f 31218 31170 31169
+f 31217 31218 31169
+f 31219 31171 31170
+f 31218 31219 31170
+f 31220 31172 31171
+f 31219 31220 31171
+f 27954 23589 31172
+f 31220 27954 31172
+f 6797 17304 17267
+f 22596 25614 10979
+f 27504 19767 25372
+f 13815 28883 22377
+f 29302 29254 28790
+f 29149 28830 28829
+f 4499 17883 30021
+f 16228 30065 30064
+f 23765 3981 23298
+f 17883 16228 30064
+f 23298 31221 23765
+f 24405 14585 14584
+f 31221 31222 31173
+f 23765 31221 31173
+f 31222 31223 31174
+f 31173 31222 31174
+f 31224 31175 31174
+f 31223 31224 31174
+f 31224 31225 31176
+f 31175 31224 31176
+f 31226 31177 31176
+f 31225 31226 31176
+f 31227 31178 31177
+f 31226 31227 31177
+f 31228 31179 31178
+f 31227 31228 31178
+f 31229 31180 31179
+f 31228 31229 31179
+f 31230 31181 31180
+f 31229 31230 31180
+f 31231 31182 31181
+f 31230 31231 31181
+f 31232 31183 31182
+f 31231 31232 31182
+f 31233 31184 31183
+f 31232 31233 31183
+f 31234 31185 31184
+f 31233 31234 31184
+f 31235 31186 31185
+f 31234 31235 31185
+f 31236 31187 31186
+f 31235 31236 31186
+f 31237 31188 31187
+f 31236 31237 31187
+f 31238 31189 31188
+f 31237 31238 31188
+f 31239 31190 31189
+f 31238 31239 31189
+f 31240 31191 31190
+f 31239 31240 31190
+f 31241 31192 31191
+f 31240 31241 31191
+f 31242 31193 31192
+f 31241 31242 31192
+f 31242 31243 31194
+f 31193 31242 31194
+f 31243 31244 31195
+f 31194 31243 31195
+f 31245 31196 31195
+f 31244 31245 31195
+f 31246 31197 31196
+f 31245 31246 31196
+f 31247 31198 31197
+f 31246 31247 31197
+f 31248 31199 31198
+f 31247 31248 31198
+f 31248 31249 31200
+f 31199 31248 31200
+f 31250 31201 31200
+f 31249 31250 31200
+f 31251 31202 31201
+f 31250 31251 31201
+f 31251 31252 31203
+f 31202 31251 31203
+f 31252 31253 31204
+f 31203 31252 31204
+f 31253 31254 31205
+f 31204 31253 31205
+f 31254 31255 27619
+f 31205 31254 27619
+f 17497 24976 28783
+f 31255 27620 27619
+f 22630 26880 26888
+f 19824 26132 11885
+f 28957 28956 29758
+f 28907 29974 29935
+f 19103 29350 29349
+f 15185 19103 29349
+f 29340 29302 28789
+f 29250 29194 28828
+f 14945 30111 30065
+f 16228 14945 30065
+f 5547 30155 30111
+f 14945 5547 30111
+f 29255 29250 28811
+f 29386 29340 28745
+f 2513 29048 29126
+f 2174 2513 29126
+f 28591 28584 22708
+f 28956 29799 29758
+f 19983 19985 15282
+f 26866 24213 27058
+f 27081 27930 28179
+f 21890 22081 24017
+f 29499 28693 29540
+f 24882 13201 27137
+f 29135 28399 28398
+f 29283 29135 28398
+f 29123 29092 29072
+f 28694 29123 29072
+f 2509 2511 22331
+f 28551 28550 28256
+f 28929 28985 28761
+f 21702 26135 11387
+f 28967 28977 29033
+f 28932 28464 29022
+f 29246 29153 28938
+f 23393 23252 13168
+f 28898 28899 29289
+f 3261 29293 25748
+f 16988 16987 27791
+f 29244 28898 29289
+f 29672 1743 29631
+f 29058 15040 30244
+f 29348 29296 28958
+f 23587 27954 27956
+f 28957 29758 29713
+f 29144 29591 22860
+f 29664 2055 29202
+f 2513 2664 29048
+f 29386 28745 28744
+f 29254 29255 28813
+f 5547 5404 30200
+f 30155 5547 30200
+f 31256 31257 23163
+f 23163 31258 31256
+f 31259 31260 28007
+f 2498 14356 31261
+f 17437 2895 17127
+f 18150 15720 15796
+f 26961 6806 4113
+f 21653 4110 4114
+f 11467 17378 3548
+f 4114 4929 4115
+f 31262 8672 8671
+f 20295 31262 8671
+f 31263 13209 8672
+f 31262 31263 8672
+f 31264 31214 13209
+f 31263 31264 13209
+f 31265 31215 31214
+f 31264 31265 31214
+f 31266 31216 31215
+f 31265 31266 31215
+f 31267 31217 31216
+f 31266 31267 31216
+f 31268 31218 31217
+f 31267 31268 31217
+f 31269 31219 31218
+f 31268 31269 31218
+f 31270 31220 31219
+f 31269 31270 31219
+f 31270 27955 27954
+f 31220 31270 27954
+f 6652 22963 6656
+f 23373 22597 22031
+f 26133 26131 26132
+f 13169 19194 5122
+f 29306 28673 28976
+f 6387 6389 21509
+f 5404 5260 30248
+f 30200 5404 30248
+f 3362 14990 28815
+f 25589 31271 23298
+f 309 3051 307
+f 31271 31272 31221
+f 23298 31271 31221
+f 31272 31273 31222
+f 31221 31272 31222
+f 31273 31274 31223
+f 31222 31273 31223
+f 31275 31224 31223
+f 31274 31275 31223
+f 31275 31276 31225
+f 31224 31275 31225
+f 31277 31226 31225
+f 31276 31277 31225
+f 31278 31227 31226
+f 31277 31278 31226
+f 31279 31228 31227
+f 31278 31279 31227
+f 31280 31229 31228
+f 31279 31280 31228
+f 31281 31230 31229
+f 31280 31281 31229
+f 31282 31231 31230
+f 31281 31282 31230
+f 31283 31232 31231
+f 31282 31283 31231
+f 31284 31233 31232
+f 31283 31284 31232
+f 31285 31234 31233
+f 31284 31285 31233
+f 31286 31235 31234
+f 31285 31286 31234
+f 31287 31236 31235
+f 31286 31287 31235
+f 31288 31237 31236
+f 31287 31288 31236
+f 31289 31238 31237
+f 31288 31289 31237
+f 31290 31239 31238
+f 31289 31290 31238
+f 31291 31240 31239
+f 31290 31291 31239
+f 31292 31241 31240
+f 31291 31292 31240
+f 31293 31242 31241
+f 31292 31293 31241
+f 31294 31243 31242
+f 31293 31294 31242
+f 31295 31244 31243
+f 31294 31295 31243
+f 31295 31296 31245
+f 31244 31295 31245
+f 31296 31297 31246
+f 31245 31296 31246
+f 31298 31247 31246
+f 31297 31298 31246
+f 31299 31248 31247
+f 31298 31299 31247
+f 31299 31300 31249
+f 31248 31299 31249
+f 31301 31250 31249
+f 31300 31301 31249
+f 31302 31251 31250
+f 31301 31302 31250
+f 31302 31303 31252
+f 31251 31302 31252
+f 31303 31304 31253
+f 31252 31303 31253
+f 31304 31305 31254
+f 31253 31304 31254
+f 31305 27754 31255
+f 31254 31305 31255
+f 25031 27608 25032
+f 31255 27754 27620
+f 28606 28990 28607
+f 29154 25231 25233
+f 29062 29009 29668
+f 29046 29841 29799
+f 29751 2506 29664
+f 2663 29127 29278
+f 21068 28229 2340
+f 29254 28813 28790
+f 5260 5262 30297
+f 30248 5260 30297
+f 5262 5396 30345
+f 30297 5262 30345
+f 5396 5398 30389
+f 29302 28790 28789
+f 29385 29386 28744
+f 2506 29751 29127
+f 2664 2663 29278
+f 22604 28297 22627
+f 29009 28957 29713
+f 27586 31306 26700
+f 27952 21631 21630
+f 31307 31308 31309
+f 3811 6949 21108
+f 27058 29197 27059
+f 23545 26770 10155
+f 24557 10450 16155
+f 19922 9156 9158
+f 29081 28961 29836
+f 29074 29081 29836
+f 2511 22042 22332
+f 26962 15049 28888
+f 15034 23029 29152
+f 29670 19190 5807
+f 29017 28969 29020
+f 29020 28932 29022
+f 29246 28938 28937
+f 29293 29246 28937
+f 29345 28905 29243
+f 28899 28897 29336
+f 29297 28605 29098
+f 30603 29010 29063
+f 8967 28595 8968
+f 29301 28603 5794
+f 1947 31310 1948
+f 29190 29191 22115
+f 2057 2164 29202
+f 2164 3254 9548
+f 15424 21325 15425
+f 2164 29203 29202
+f 30345 5396 30389
+f 28978 29065 28976
+f 5398 5546 30433
+f 30389 5398 30433
+f 7472 7474 19192
+f 17260 17649 22318
+f 15519 16017 6517
+f 17120 31311 17121
+f 6806 21653 4114
+f 21653 17410 4111
+f 26961 4113 21717
+f 24702 26961 21717
+f 16291 14462 18176
+f 31312 16174 31313
+f 31314 31262 20295
+f 15672 31314 20295
+f 31315 31263 31262
+f 31314 31315 31262
+f 31316 31264 31263
+f 31315 31316 31263
+f 31317 31265 31264
+f 31316 31317 31264
+f 31318 31266 31265
+f 31317 31318 31265
+f 31319 31267 31266
+f 31318 31319 31266
+f 31320 31268 31267
+f 31319 31320 31267
+f 31321 31269 31268
+f 31320 31321 31268
+f 22962 31270 31269
+f 31321 22962 31269
+f 24975 22574 27657
+f 31270 22962 27955
+f 16304 9413 9412
+f 22006 22005 17696
+f 2506 2055 29664
+f 23302 27532 27712
+f 28583 28301 30291
+f 28437 29385 28621
+f 26182 24317 15219
+f 30433 5546 28424
+f 17685 17684 21684
+f 23368 19194 23251
+f 30336 30335 31271
+f 25589 30336 31271
+f 30335 31322 31272
+f 31271 30335 31272
+f 31322 31323 31273
+f 31272 31322 31273
+f 31323 31324 31274
+f 31273 31323 31274
+f 31325 31275 31274
+f 31324 31325 31274
+f 31326 31276 31275
+f 31325 31326 31275
+f 31327 31277 31276
+f 31326 31327 31276
+f 31328 31278 31277
+f 31327 31328 31277
+f 31329 31279 31278
+f 31328 31329 31278
+f 31330 31280 31279
+f 31329 31330 31279
+f 31331 31281 31280
+f 31330 31331 31280
+f 31332 31282 31281
+f 31331 31332 31281
+f 31333 31283 31282
+f 31332 31333 31282
+f 31334 31284 31283
+f 31333 31334 31283
+f 31335 31285 31284
+f 31334 31335 31284
+f 31336 31286 31285
+f 31335 31336 31285
+f 31337 31287 31286
+f 31336 31337 31286
+f 31338 31288 31287
+f 31337 31338 31287
+f 31339 31289 31288
+f 31338 31339 31288
+f 31340 31290 31289
+f 31339 31340 31289
+f 31341 31291 31290
+f 31340 31341 31290
+f 31342 31292 31291
+f 31341 31342 31291
+f 31343 31293 31292
+f 31342 31343 31292
+f 31343 31344 31294
+f 31293 31343 31294
+f 31344 31345 31295
+f 31294 31344 31295
+f 31345 31346 31296
+f 31295 31345 31296
+f 31346 31347 31297
+f 31296 31346 31297
+f 31347 31348 31298
+f 31297 31347 31298
+f 31348 31349 31299
+f 31298 31348 31299
+f 31349 31350 31300
+f 31299 31349 31300
+f 31350 31351 31301
+f 31300 31350 31301
+f 31351 31352 31302
+f 31301 31351 31302
+f 31352 31353 31303
+f 31302 31352 31303
+f 31353 31354 31304
+f 31303 31353 31304
+f 31354 31355 31305
+f 31304 31354 31305
+f 31355 26945 27754
+f 31305 31355 27754
+f 27532 17884 27468
+f 15238 22285 22351
+f 29112 29062 29629
+f 21326 21161 21162
+f 9549 1863 28923
+f 29009 29713 29668
+f 15424 17588 17590
+f 2055 2057 29202
+f 17062 17061 17671
+f 28583 30291 29887
+f 15219 15221 26182
+f 27956 27955 24696
+f 28721 29427 28802
+f 23234 28329 23235
+f 28329 28344 23235
+f 28923 1865 21215
+f 29340 28789 28745
+f 17400 17486 28428
+f 2663 2506 29127
+f 2563 3968 2564
+f 17484 17144 17485
+f 31306 31028 26131
+f 22869 22775 22870
+f 23280 841 16617
+f 25856 22229 17278
+f 16017 3811 21108
+f 26263 13534 18267
+f 16145 31310 21282
+f 25964 7360 7359
+f 29123 28694 28961
+f 29090 29089 23238
+f 2499 31261 31356
+f 29081 29123 28961
+f 31310 16145 29190
+f 25747 3262 3261
+f 28971 28969 29017
+f 15684 22478 22166
+f 22960 22962 27346
+f 29153 28939 28938
+f 28901 28898 29244
+f 29243 28901 29244
+f 14969 2322 11222
+f 23127 23126 29059
+f 28601 28603 29301
+f 22860 17653 31357
+f 21282 31310 13879
+f 31310 29190 1948
+f 28395 2024 2023
+f 28635 21667 28237
+f 5658 2995 2675
+f 28245 2023 28246
+f 14706 5658 28516
+f 10948 2018 2020
+f 22319 31358 22196
+f 27540 27790 27541
+f 31358 22319 22318
+f 2497 31359 2498
+f 16482 16481 31360
+f 16975 29883 29884
+f 4110 21653 4111
+f 31361 75 74
+f 26456 26543 26269
+f 9716 14643 693
+f 15672 4692 6831
+f 31362 31314 15672
+f 6831 31362 15672
+f 31363 31315 31314
+f 31362 31363 31314
+f 31364 31316 31315
+f 31363 31364 31315
+f 31365 31317 31316
+f 31364 31365 31316
+f 31366 31318 31317
+f 31365 31366 31317
+f 31367 31319 31318
+f 31366 31367 31318
+f 31368 31320 31319
+f 31367 31368 31319
+f 27346 31321 31320
+f 31368 27346 31320
+f 22321 9599 4757
+f 31321 27346 22962
+f 22301 23103 22317
+f 26059 25948 6369
+f 29670 5807 12537
+f 29671 20953 2326
+f 26264 25584 25431
+f 29203 2164 9548
+f 14706 28516 2019
+f 15423 15425 28677
+f 21082 5384 2163
+f 21288 27674 28679
+f 16224 5401 16657
+f 25839 31369 30335
+f 29929 29043 26127
+f 31369 31370 31322
+f 30335 31369 31322
+f 31370 31371 31323
+f 31322 31370 31323
+f 31371 31372 31324
+f 31323 31371 31324
+f 31373 31325 31324
+f 31372 31373 31324
+f 31374 31326 31325
+f 31373 31374 31325
+f 31375 31327 31326
+f 31374 31375 31326
+f 31376 31328 31327
+f 31375 31376 31327
+f 31377 31329 31328
+f 31376 31377 31328
+f 31378 31330 31329
+f 31377 31378 31329
+f 31379 31331 31330
+f 31378 31379 31330
+f 31380 31332 31331
+f 31379 31380 31331
+f 31381 31333 31332
+f 31380 31381 31332
+f 31382 31334 31333
+f 31381 31382 31333
+f 31383 31335 31334
+f 31382 31383 31334
+f 31384 31336 31335
+f 31383 31384 31335
+f 31385 31337 31336
+f 31384 31385 31336
+f 31386 31338 31337
+f 31385 31386 31337
+f 31387 31339 31338
+f 31386 31387 31338
+f 31388 31340 31339
+f 31387 31388 31339
+f 31389 31341 31340
+f 31388 31389 31340
+f 31390 31342 31341
+f 31389 31390 31341
+f 31391 31343 31342
+f 31390 31391 31342
+f 31392 31344 31343
+f 31391 31392 31343
+f 31393 31345 31344
+f 31392 31393 31344
+f 31394 31346 31345
+f 31393 31394 31345
+f 31394 31395 31347
+f 31346 31394 31347
+f 31395 31396 31348
+f 31347 31395 31348
+f 31396 31397 31349
+f 31348 31396 31349
+f 31397 31398 31350
+f 31349 31397 31350
+f 31398 31399 31351
+f 31350 31398 31351
+f 31400 31352 31351
+f 31399 31400 31351
+f 31400 31401 31353
+f 31352 31400 31353
+f 31401 31402 31354
+f 31353 31401 31354
+f 31402 31403 31355
+f 31354 31402 31355
+f 31403 27734 26945
+f 31355 31403 26945
+f 13436 24484 24405
+f 3968 2563 2911
+f 29062 29668 29629
+f 29485 22513 22511
+f 3254 1863 9549
+f 1865 13976 21215
+f 27563 26264 22249
+f 4497 28599 28231
+f 2056 21082 2163
+f 2163 5384 3252
+f 5384 5389 3252
+f 17594 27736 25833
+f 22942 27563 22248
+f 26264 25431 22249
+f 23079 23081 27586
+f 13976 21277 13888
+f 7361 28061 6526
+f 5814 23302 5818
+f 25025 27653 14690
+f 25295 25296 25294
+f 26131 14511 11885
+f 31306 26131 26700
+f 31028 31404 14510
+f 14511 31028 14510
+f 31404 25263 21608
+f 14510 31404 21608
+f 15682 15684 22134
+f 25746 3261 24547
+f 29091 29090 23237
+f 23237 29090 23238
+f 28888 15048 5622
+f 28290 5386 28272
+f 28926 28929 28760
+f 28761 28985 24514
+f 29016 28971 29017
+f 28969 28932 29020
+f 8500 21884 8501
+f 23566 19242 19305
+f 28896 28895 29412
+f 29381 28896 29412
+f 21068 2340 2519
+f 28765 22231 22954
+f 29112 29629 29591
+f 29144 29112 29591
+f 21215 13976 13888
+f 21282 13879 13888
+f 17236 26943 17237
+f 28329 28244 28344
+f 27736 21793 25833
+f 28523 28623 6529
+f 23163 23231 6620
+f 22318 15858 7472
+f 31405 6516 24433
+f 31406 31407 31408
+f 17410 16363 10566
+f 4111 17410 10566
+f 16363 16365 29884
+f 10566 16363 29884
+f 3318 31409 24684
+f 31410 31411 31412
+f 31413 6831 6830
+f 15471 31413 6830
+f 31414 31362 6831
+f 31413 31414 6831
+f 31415 31363 31362
+f 31414 31415 31362
+f 31416 31364 31363
+f 31415 31416 31363
+f 31417 31365 31364
+f 31416 31417 31364
+f 31418 31366 31365
+f 31417 31418 31365
+f 31419 31367 31366
+f 31418 31419 31366
+f 31420 31368 31367
+f 31419 31420 31367
+f 27347 27346 31368
+f 31420 27347 31368
+f 17730 27445 17731
+f 25431 25584 25430
+f 27476 6595 2814
+f 22331 2511 22332
+f 1948 29190 22115
+f 12536 29670 12537
+f 31405 15518 6516
+f 25749 26946 25750
+f 25046 28600 25048
+f 3541 23237 15676
+f 14145 8446 18888
+f 5263 25428 22719
+f 25838 31421 31369
+f 25839 25838 31369
+f 31421 31422 31370
+f 31369 31421 31370
+f 31422 31423 31371
+f 31370 31422 31371
+f 31423 31424 31372
+f 31371 31423 31372
+f 31425 31373 31372
+f 31424 31425 31372
+f 31426 31374 31373
+f 31425 31426 31373
+f 31426 31427 31375
+f 31374 31426 31375
+f 31428 31376 31375
+f 31427 31428 31375
+f 31429 31377 31376
+f 31428 31429 31376
+f 31430 31378 31377
+f 31429 31430 31377
+f 31431 31379 31378
+f 31430 31431 31378
+f 31432 31380 31379
+f 31431 31432 31379
+f 31433 31381 31380
+f 31432 31433 31380
+f 31434 31382 31381
+f 31433 31434 31381
+f 31435 31383 31382
+f 31434 31435 31382
+f 31436 31384 31383
+f 31435 31436 31383
+f 31437 31385 31384
+f 31436 31437 31384
+f 31438 31386 31385
+f 31437 31438 31385
+f 31439 31387 31386
+f 31438 31439 31386
+f 31440 31388 31387
+f 31439 31440 31387
+f 31441 31389 31388
+f 31440 31441 31388
+f 31442 31390 31389
+f 31441 31442 31389
+f 31443 31391 31390
+f 31442 31443 31390
+f 31444 31392 31391
+f 31443 31444 31391
+f 31445 31393 31392
+f 31444 31445 31392
+f 31446 31394 31393
+f 31445 31446 31393
+f 31447 31395 31394
+f 31446 31447 31394
+f 31448 31396 31395
+f 31447 31448 31395
+f 31449 31397 31396
+f 31448 31449 31396
+f 31450 31398 31397
+f 31449 31450 31397
+f 31451 31399 31398
+f 31450 31451 31398
+f 31451 31452 31400
+f 31399 31451 31400
+f 31452 31453 31401
+f 31400 31452 31401
+f 31453 31454 31402
+f 31401 31453 31402
+f 31454 31455 31403
+f 31402 31454 31403
+f 31455 22019 27734
+f 31403 31455 27734
+f 24581 24583 24504
+f 25120 25911 25793
+f 31456 4657 4655
+f 20213 22474 20214
+f 9548 3254 9549
+f 1863 1865 28923
+f 27336 27338 27930
+f 5813 27281 27467
+f 28623 28625 6529
+f 28582 28583 28596
+f 25335 15171 28060
+f 28417 2007 2321
+f 28578 28791 28579
+f 22913 28522 22270
+f 5264 22720 15107
+f 5809 28609 17108
+f 26883 23081 23080
+f 1131 1130 3381
+f 31457 31306 27586
+f 23081 31457 27586
+f 31458 31028 31306
+f 31457 31458 31306
+f 25264 31404 31028
+f 31458 25264 31028
+f 19689 6930 12511
+f 31404 25264 25263
+f 28923 21215 21266
+f 17292 17333 17293
+f 29074 29836 29151
+f 3540 29091 23237
+f 22867 5672 22783
+f 28272 5388 28270
+f 28925 28926 28707
+f 28707 28926 28760
+f 29022 28464 29028
+f 28447 28446 29029
+f 12973 26969 12974
+f 21884 1339 8501
+f 28895 28894 29462
+f 29412 28895 29462
+f 29106 29496 23126
+f 29338 28087 29280
+f 28089 28115 29279
+f 29279 29280 28087
+f 21277 21282 13888
+f 31310 1947 13879
+f 28472 26149 6369
+f 27563 22249 22248
+f 28512 28795 28635
+f 22279 650 25305
+f 15858 22318 17649
+f 31358 22318 7472
+f 16050 20540 16051
+f 24267 31459 6519
+f 17615 18269 29883
+f 16365 16975 29884
+f 2917 75 2918
+f 9 13003 10
+f 9374 14886 15320
+f 31460 31410 31412
+f 31461 31413 15471
+f 13058 31461 15471
+f 31462 31414 31413
+f 31461 31462 31413
+f 31463 31415 31414
+f 31462 31463 31414
+f 31464 31416 31415
+f 31463 31464 31415
+f 31465 31417 31416
+f 31464 31465 31416
+f 31466 31418 31417
+f 31465 31466 31417
+f 31467 31419 31418
+f 31466 31467 31418
+f 31468 31420 31419
+f 31467 31468 31419
+f 31468 13202 27347
+f 31420 31468 27347
+f 7472 23163 31257
+f 31469 33 49
+f 28610 22695 22236
+f 30610 23103 22301
+f 29191 29670 12536
+f 22115 29191 12536
+f 30777 30855 22208
+f 22390 23566 19305
+f 21669 21618 21617
+f 21568 28831 21569
+f 25837 31470 25838
+f 2668 24585 2669
+f 31470 31471 31421
+f 25838 31470 31421
+f 31471 31472 31422
+f 31421 31471 31422
+f 31472 31473 31423
+f 31422 31472 31423
+f 31473 31474 31424
+f 31423 31473 31424
+f 31475 31425 31424
+f 31474 31475 31424
+f 31476 31426 31425
+f 31475 31476 31425
+f 31477 31427 31426
+f 31476 31477 31426
+f 31478 31428 31427
+f 31477 31478 31427
+f 31479 31429 31428
+f 31478 31479 31428
+f 31480 31430 31429
+f 31479 31480 31429
+f 31481 31431 31430
+f 31480 31481 31430
+f 31482 31432 31431
+f 31481 31482 31431
+f 31483 31433 31432
+f 31482 31483 31432
+f 31484 31434 31433
+f 31483 31484 31433
+f 31485 31435 31434
+f 31484 31485 31434
+f 31486 31436 31435
+f 31485 31486 31435
+f 31487 31437 31436
+f 31486 31487 31436
+f 31488 31438 31437
+f 31487 31488 31437
+f 31489 31439 31438
+f 31488 31489 31438
+f 31490 31440 31439
+f 31489 31490 31439
+f 31491 31441 31440
+f 31490 31491 31440
+f 31492 31442 31441
+f 31491 31492 31441
+f 31493 31443 31442
+f 31492 31493 31442
+f 31494 31444 31443
+f 31493 31494 31443
+f 31495 31445 31444
+f 31494 31495 31444
+f 31496 31446 31445
+f 31495 31496 31445
+f 31497 31447 31446
+f 31496 31497 31446
+f 31498 31448 31447
+f 31497 31498 31447
+f 31499 31449 31448
+f 31498 31499 31448
+f 31500 31450 31449
+f 31499 31500 31449
+f 31501 31451 31450
+f 31500 31501 31450
+f 31501 31502 31452
+f 31451 31501 31452
+f 31502 31503 31453
+f 31452 31502 31453
+f 31503 31504 31454
+f 31453 31503 31454
+f 31504 31505 31455
+f 31454 31504 31455
+f 31505 22017 22019
+f 31455 31505 22019
+f 24584 20334 24585
+f 5937 5518 5655
+f 27187 10155 26770
+f 22306 30610 22294
+f 5807 5809 17107
+f 12537 5807 17107
+f 18955 18957 28587
+f 11920 15170 6098
+f 28592 29069 28593
+f 21669 21668 28608
+f 2323 5387 5386
+f 15923 27048 15924
+f 16639 28718 14763
+f 1054 23663 29134
+f 29661 25788 25120
+f 29708 29924 2487
+f 21745 21747 23422
+f 24613 6799 1507
+f 31506 31457 23081
+f 26883 31506 23081
+f 6194 31458 31457
+f 31506 6194 31457
+f 6193 25264 31458
+f 6194 6193 31458
+f 28719 12975 12511
+f 12511 12975 19689
+f 28117 27536 26843
+f 1779 23420 1555
+f 29139 29073 29151
+f 29073 29074 29151
+f 21099 21098 28522
+f 22912 29154 28522
+f 28966 28925 28756
+f 28756 28925 28707
+f 29028 28447 29029
+f 28446 28387 29035
+f 22046 8500 2350
+f 35 29420 30817
+f 28903 28905 29345
+f 29305 28903 29345
+f 29465 23176 28367
+f 28632 29465 28367
+f 15283 15285 29280
+f 28795 21624 21667
+f 17107 5809 17108
+f 28609 29926 2306
+f 28267 22791 21276
+f 28791 2331 28579
+f 28288 28289 29706
+f 29803 22694 29552
+f 31358 7472 31257
+f 23163 19192 23231
+f 10571 28330 28331
+f 31507 31508 31509
+f 21382 9639 18269
+f 16975 17615 29883
+f 13004 16016 10
+f 10711 15045 10712
+f 8833 8832 3032
+f 1276 13058 15471
+f 31510 31461 13058
+f 13059 31510 13058
+f 31511 31462 31461
+f 31510 31511 31461
+f 31512 31463 31462
+f 31511 31512 31462
+f 31513 31464 31463
+f 31512 31513 31463
+f 31514 31465 31464
+f 31513 31514 31464
+f 31515 31466 31465
+f 31514 31515 31465
+f 31516 31467 31466
+f 31515 31516 31466
+f 31516 31517 31468
+f 31467 31516 31468
+f 31517 13203 13202
+f 31468 31517 13202
+f 25659 18523 28005
+f 28428 29105 28426
+f 28758 28759 4652
+f 22601 25041 25760
+f 17328 23202 17855
+f 17108 28609 2306
+f 28312 3585 3584
+f 13975 28253 15209
+f 29925 28288 29706
+f 18930 25853 31470
+f 25837 18930 31470
+f 25853 31518 31471
+f 31470 25853 31471
+f 31518 31519 31472
+f 31471 31518 31472
+f 31519 31520 31473
+f 31472 31519 31473
+f 31520 31521 31474
+f 31473 31520 31474
+f 31522 31475 31474
+f 31521 31522 31474
+f 31523 31476 31475
+f 31522 31523 31475
+f 31523 31524 31477
+f 31476 31523 31477
+f 31525 31478 31477
+f 31524 31525 31477
+f 31526 31479 31478
+f 31525 31526 31478
+f 31527 31480 31479
+f 31526 31527 31479
+f 31528 31481 31480
+f 31527 31528 31480
+f 31529 31482 31481
+f 31528 31529 31481
+f 28200 31483 31482
+f 31529 28200 31482
+f 24225 31484 31483
+f 28200 24225 31483
+f 24119 31485 31484
+f 24225 24119 31484
+f 24121 31486 31485
+f 24119 24121 31485
+f 15773 31487 31486
+f 24121 15773 31486
+f 15772 31488 31487
+f 15773 15772 31487
+f 31530 31489 31488
+f 15772 31530 31488
+f 31531 31490 31489
+f 31530 31531 31489
+f 31532 31491 31490
+f 31531 31532 31490
+f 31533 31492 31491
+f 31532 31533 31491
+f 31534 31493 31492
+f 31533 31534 31492
+f 31535 31494 31493
+f 31534 31535 31493
+f 31536 31495 31494
+f 31535 31536 31494
+f 31537 31496 31495
+f 31536 31537 31495
+f 31538 31497 31496
+f 31537 31538 31496
+f 31539 31498 31497
+f 31538 31539 31497
+f 31540 31499 31498
+f 31539 31540 31498
+f 31541 31500 31499
+f 31540 31541 31499
+f 31542 31501 31500
+f 31541 31542 31500
+f 31542 31543 31502
+f 31501 31542 31502
+f 31543 31544 31503
+f 31502 31543 31503
+f 31544 31545 31504
+f 31503 31544 31504
+f 31545 31546 31505
+f 31504 31545 31505
+f 31546 27522 22017
+f 31505 31546 22017
+f 18795 24598 26148
+f 1272 17937 1270
+f 15285 29338 29280
+f 22868 2316 5672
+f 29926 29708 2307
+f 2306 29926 2307
+f 28253 28267 15209
+f 25229 16639 14763
+f 28544 4654 28539
+f 29707 28312 3584
+f 28543 22959 28544
+f 4654 4803 28539
+f 23030 22959 28546
+f 17768 6952 17560
+f 2507 21617 2056
+f 22005 15683 15682
+f 16798 29124 16799
+f 11139 7670 15900
+f 15900 14640 11139
+f 27637 31547 31506
+f 26883 27637 31506
+f 31547 6192 6194
+f 31506 31547 6194
+f 12606 14365 13246
+f 13954 9281 13246
+f 1133 21685 1134
+f 11030 27228 25220
+f 29048 29278 10427
+f 28463 25765 28202
+f 29183 29139 23029
+f 23029 29139 29151
+f 28758 14017 28759
+f 28294 2324 28290
+f 28965 28966 28702
+f 28702 28966 28756
+f 29029 28446 29035
+f 28387 28389 29037
+f 28062 25745 23032
+f 14865 31548 14866
+f 23241 28903 29305
+f 28905 28901 29243
+f 30732 28110 28698
+f 29465 29506 23176
+f 25202 25166 16828
+f 17980 26826 23382
+f 2307 29708 2487
+f 29924 29124 16798
+f 28253 13975 1864
+f 21617 21082 2056
+f 22959 4654 28544
+f 28749 22004 28546
+f 19192 23163 7472
+f 31118 22945 29116
+f 22152 20815 10327
+f 17615 21382 18269
+f 22946 17195 18011
+f 7318 9640 9639
+f 21382 7318 9639
+f 4115 14516 24378
+f 17895 25619 17721
+f 31549 13059 4925
+f 4925 13059 4923
+f 31550 31510 13059
+f 31549 31550 13059
+f 31551 31511 31510
+f 31550 31551 31510
+f 31552 31512 31511
+f 31551 31552 31511
+f 31553 31513 31512
+f 31552 31553 31512
+f 31554 31514 31513
+f 31553 31554 31513
+f 31555 31515 31514
+f 31554 31555 31514
+f 31556 31516 31515
+f 31555 31556 31515
+f 31556 31557 31517
+f 31516 31556 31517
+f 31557 25063 13203
+f 31517 31557 13203
+f 31558 28352 31559
+f 29154 25294 25297
+f 28757 28758 22958
+f 28309 22176 22175
+f 5389 22050 3253
+f 15423 23202 15424
+f 22959 28543 28546
+f 18939 18938 27603
+f 11224 2824 2823
+f 31560 31561 18403
+f 22575 31562 31518
+f 25853 22575 31518
+f 31562 31563 31519
+f 31518 31562 31519
+f 31563 31564 31520
+f 31519 31563 31520
+f 31564 31565 31521
+f 31520 31564 31521
+f 31565 31566 31522
+f 31521 31565 31522
+f 31566 31567 31523
+f 31522 31566 31523
+f 31567 31568 31524
+f 31523 31567 31524
+f 31568 31569 31525
+f 31524 31568 31525
+f 31570 31526 31525
+f 31569 31570 31525
+f 31571 31527 31526
+f 31570 31571 31526
+f 23342 31528 31527
+f 31571 23342 31527
+f 23662 31529 31528
+f 23342 23662 31528
+f 23425 28200 31529
+f 23662 23425 31529
+f 25297 25296 25299
+f 24124 24121 24120
+f 25233 25294 29154
+f 28340 29516 27271
+f 21097 25280 13342
+f 24069 24076 15772
+f 214 17073 212
+f 17576 17578 22153
+f 11631 20961 11632
+f 28057 29593 25266
+f 24076 31530 15772
+f 22018 22017 27522
+f 22082 31531 31530
+f 24076 22082 31530
+f 22081 31532 31531
+f 22082 22081 31531
+f 31572 31533 31532
+f 22081 31572 31532
+f 31573 31534 31533
+f 31572 31573 31533
+f 31574 31535 31534
+f 31573 31574 31534
+f 31575 31536 31535
+f 31574 31575 31535
+f 31576 31537 31536
+f 31575 31576 31536
+f 31577 31538 31537
+f 31576 31577 31537
+f 31578 31539 31538
+f 31577 31578 31538
+f 31579 31540 31539
+f 31578 31579 31539
+f 31580 31541 31540
+f 31579 31580 31540
+f 31581 31542 31541
+f 31580 31581 31541
+f 31582 31543 31542
+f 31581 31582 31542
+f 31582 31583 31544
+f 31543 31582 31544
+f 31583 31584 31545
+f 31544 31583 31545
+f 31584 31585 31546
+f 31545 31584 31546
+f 31585 27640 27522
+f 31546 31585 27522
+f 27955 24697 24696
+f 7669 25050 24980
+f 30199 30603 29063
+f 6088 12455 21347
+f 2487 29924 16798
+f 29124 29125 16799
+f 3252 5389 3253
+f 28250 28253 1864
+f 22179 22004 28749
+f 22715 17329 6261
+f 16800 22179 27625
+f 29211 30192 30014
+f 13050 13052 15184
+f 28412 13050 15184
+f 29125 29134 22002
+f 12382 16933 12383
+f 29889 17055 26553
+f 24959 6258 29428
+f 7634 3319 3318
+f 24684 7634 3318
+f 16313 31586 31547
+f 27637 16313 31547
+f 31586 13288 6192
+f 31547 31586 6192
+f 8700 6305 6307
+f 13246 14513 13954
+f 26943 17236 26963
+f 17612 16537 17465
+f 29751 22176 28309
+f 29924 3584 29124
+f 29310 29183 15033
+f 15033 29183 23029
+f 28610 28591 22695
+f 25231 28521 16638
+f 28981 6381 23104
+f 28701 28965 28702
+f 25818 27572 25819
+f 6382 23105 6383
+f 31587 27353 27355
+f 26618 20536 21311
+f 17210 23241 17211
+f 23242 23241 29305
+f 26618 21311 26617
+f 29927 29003 29002
+f 21158 29277 21159
+f 26522 16890 16889
+f 28757 22003 22002
+f 29134 28757 22002
+f 28412 15184 19055
+f 28250 1864 3253
+f 28321 28591 28610
+f 30336 25565 25839
+f 19821 22152 10327
+f 25584 25587 25513
+f 9567 9566 22361
+f 75 31361 2918
+f 7318 7317 9640
+f 7317 14820 9640
+f 31309 31588 31589
+f 31590 16482 31591
+f 4928 24896 26636
+f 17551 10711 17552
+f 22657 31549 10092
+f 4925 10092 31549
+f 31592 31550 31549
+f 22657 31592 31549
+f 31593 31551 31550
+f 31592 31593 31550
+f 31594 31552 31551
+f 31593 31594 31551
+f 31595 31553 31552
+f 31594 31595 31552
+f 31596 31554 31553
+f 31595 31596 31553
+f 31597 31555 31554
+f 31596 31597 31554
+f 31598 31556 31555
+f 31597 31598 31555
+f 31598 31599 31557
+f 31556 31598 31557
+f 31599 21364 25063
+f 31557 31599 25063
+f 27678 23177 28679
+f 24763 22960 21670
+f 16639 16638 28718
+f 22003 28757 22958
+f 21723 16207 20378
+f 2331 1881 1880
+f 27625 22179 28749
+f 21400 18403 31561
+f 9948 6690 14256
+f 22574 25226 31562
+f 22575 22574 31562
+f 25226 25225 31563
+f 31562 25226 31563
+f 25225 28784 31564
+f 31563 25225 31564
+f 28784 31600 31565
+f 31564 28784 31565
+f 31601 31566 31565
+f 31600 31601 31565
+f 31602 31567 31566
+f 31601 31602 31566
+f 31602 31603 31568
+f 31567 31602 31568
+f 31603 31604 31569
+f 31568 31603 31569
+f 31605 31570 31569
+f 31604 31605 31569
+f 28455 31571 31570
+f 31605 28455 31570
+f 14586 23342 31571
+f 28455 14586 31571
+f 23662 23342 22346
+f 25288 29550 25303
+f 27086 23929 6255
+f 25307 26962 25301
+f 24225 28200 24224
+f 24888 21611 24936
+f 25046 25048 22222
+f 16448 16801 12931
+f 22135 15684 22166
+f 29155 27446 24396
+f 23236 23235 28574
+f 24018 22080 24074
+f 21563 9548 9550
+f 22778 4336 27476
+f 21151 10426 2644
+f 28675 28535 4814
+f 25335 28057 25265
+f 22150 22192 25249
+f 24822 18872 18873
+f 19826 3378 16142
+f 21890 31572 22081
+f 30990 17988 31606
+f 21887 31573 31572
+f 21890 21887 31572
+f 31607 31574 31573
+f 21887 31607 31573
+f 31608 31575 31574
+f 31607 31608 31574
+f 31609 31576 31575
+f 31608 31609 31575
+f 31610 31577 31576
+f 31609 31610 31576
+f 31610 31611 31578
+f 31577 31610 31578
+f 31612 31579 31578
+f 31611 31612 31578
+f 31613 31580 31579
+f 31612 31613 31579
+f 31614 31581 31580
+f 31613 31614 31580
+f 31615 31582 31581
+f 31614 31615 31581
+f 31615 31616 31583
+f 31582 31615 31583
+f 31616 31617 31584
+f 31583 31616 31584
+f 31617 31618 31585
+f 31584 31617 31585
+f 31618 27695 27640
+f 31585 31618 27640
+f 23239 2233 5616
+f 27521 27325 25169
+f 24793 24483 24730
+f 6914 60 27929
+f 8819 21144 29287
+f 22958 28758 4652
+f 22004 23030 28546
+f 16638 2006 28718
+f 25589 23298 9795
+f 25063 25062 24992
+f 29122 28507 20337
+f 1361 1368 10149
+f 28521 2007 2006
+f 15911 31619 31620
+f 16799 29125 22002
+f 20756 25142 25213
+f 29550 25227 25229
+f 16312 15387 16313
+f 7634 24684 14923
+f 15387 15196 31586
+f 16313 15387 31586
+f 15196 14766 13288
+f 31586 15196 13288
+f 14766 14767 13287
+f 13288 14766 13287
+f 26842 21078 21079
+f 27270 22830 25059
+f 23028 3541 22148
+f 3586 1052 29125
+f 22206 15033 22207
+f 22206 29310 15033
+f 6794 23180 6795
+f 10814 28523 6528
+f 15443 28981 15143
+f 15143 28981 23104
+f 15240 6100 6099
+f 23531 23496 5508
+f 23032 23031 28062
+f 21259 21152 17836
+f 15338 18994 15339
+f 18995 17212 18996
+f 28513 28510 28641
+f 16627 1624 16091
+f 28595 28596 8968
+f 29296 28955 28958
+f 28759 18944 4653
+f 4652 28759 4653
+f 25761 28561 28590
+f 2332 28412 19055
+f 29105 28428 17486
+f 21672 28885 21673
+f 11885 11884 19824
+f 18797 1361 10149
+f 28330 10556 10558
+f 17 65 15721
+f 17726 6260 18039
+f 17727 18039 14820
+f 16050 17895 20540
+f 22497 22499 31111
+f 3899 3898 2818
+f 20292 23183 20293
+f 23125 16216 11390
+f 2349 28159 15411
+f 2836 31592 22657
+f 2837 2836 22657
+f 14442 31593 31592
+f 2836 14442 31592
+f 12321 31594 31593
+f 14442 12321 31593
+f 21809 31595 31594
+f 12321 21809 31594
+f 21872 31596 31595
+f 21809 21872 31595
+f 3037 31597 31596
+f 21872 3037 31596
+f 3037 21535 31598
+f 31597 3037 31598
+f 21535 21362 31599
+f 31598 21535 31599
+f 21363 25061 25062
+f 31599 21362 21364
+f 6827 4493 4802
+f 16797 16796 21063
+f 28561 28587 28590
+f 28579 2331 1880
+f 29836 28963 29152
+f 28764 29631 26359
+f 28201 29268 23322
+f 25963 7359 5254
+f 25864 25866 17838
+f 24974 28784 25225
+f 25491 25280 21097
+f 6374 24973 5819
+f 6536 6256 15711
+f 14745 3444 17713
+f 6374 6375 31600
+f 28784 6374 31600
+f 22266 31601 31600
+f 6375 22266 31600
+f 14350 31602 31601
+f 22266 14350 31601
+f 14350 6199 31603
+f 31602 14350 31603
+f 6199 6201 31604
+f 31603 6199 31604
+f 6201 15186 31605
+f 31604 6201 31605
+f 13535 28455 31605
+f 15186 13535 31605
+f 24429 16887 24376
+f 22292 25317 25316
+f 14990 3362 14971
+f 13535 24405 14584
+f 31621 31311 20382
+f 6698 8386 6699
+f 22778 27476 2813
+f 1911 1913 14405
+f 2651 2653 14044
+f 16232 2651 14044
+f 5064 2412 2414
+f 2652 5659 2653
+f 6095 8120 4956
+f 21717 4113 21718
+f 17028 17029 15798
+f 17548 16726 16976
+f 3430 22778 2813
+f 26340 18002 28424
+f 30648 30688 27251
+f 27446 29155 24336
+f 3039 4404 5378
+f 28246 2023 28343
+f 21889 22512 21887
+f 29496 28031 27549
+f 24168 24225 24171
+f 20451 21506 16882
+f 22512 31607 21887
+f 10327 19826 19821
+f 21738 31608 31607
+f 22512 21738 31607
+f 5511 31609 31608
+f 21738 5511 31608
+f 5510 31610 31609
+f 5511 5510 31609
+f 12105 31611 31610
+f 5510 12105 31610
+f 6654 31612 31611
+f 12105 6654 31611
+f 6653 31613 31612
+f 6654 6653 31612
+f 21432 31614 31613
+f 6653 21432 31613
+f 21923 31615 31614
+f 21432 21923 31614
+f 21923 19626 31616
+f 31615 21923 31616
+f 19626 12715 31617
+f 31616 19626 31617
+f 12715 15612 31618
+f 31617 12715 31618
+f 15612 23922 27695
+f 31618 15612 27695
+f 23922 23983 27696
+f 27695 23922 27696
+f 24731 24483 23607
+f 29058 23126 24161
+f 28561 18955 28587
+f 28580 28579 22648
+f 24556 28975 24557
+f 28297 24558 22627
+f 24752 21411 15365
+f 26127 26129 29929
+f 29157 27624 27626
+f 19072 22724 6085
+f 16638 28521 2006
+f 15094 16233 16099
+f 29550 25229 14763
+f 6535 6539 16312
+f 27505 6535 16312
+f 6539 561 15387
+f 16312 6539 15387
+f 561 563 15196
+f 29441 16014 17171
+f 16969 3576 31622
+f 31623 31624 31625
+f 31626 31627 31628
+f 31624 31626 31628
+f 31629 31630 31627
+f 31626 31629 31627
+f 31631 31632 31630
+f 31629 31631 31630
+f 31633 31634 31632
+f 31631 31633 31632
+f 31635 31636 31634
+f 31633 31635 31634
+f 31637 31638 31636
+f 31635 31637 31636
+f 31639 31640 31638
+f 31637 31639 31638
+f 31641 31642 31640
+f 31639 31641 31640
+f 31643 31644 31642
+f 31641 31643 31642
+f 31645 31646 31644
+f 31643 31645 31644
+f 31645 14779 14778
+f 31646 31645 14778
+f 31647 31648 31649
+f 27402 26963 22193
+f 31650 23093 31651
+f 31652 31647 31649
+f 125 22498 22497
+f 31653 17738 31654
+f 31655 31656 31657
+f 14722 31658 31659
+f 31660 31647 31652
+f 31661 31662 24266
+f 31663 31661 24266
+f 15115 15114 15150
+f 10710 10712 31664
+f 31665 31666 31667
+f 27328 31031 31668
+f 31669 11227 31670
+f 15625 16281 31671
+f 4349 21305 4348
+f 31672 31673 31674
+f 17552 31675 31676
+f 31677 31660 143
+f 31678 31679 31680
+f 31408 31681 31459
+f 31682 31683 31684
+f 31685 10572 19779
+f 31686 31687 31688
+f 142 31677 143
+f 31689 31655 31690
+f 31656 31688 31657
+f 31653 31654 139
+f 27758 27760 31691
+f 22273 31692 17116
+f 31683 31693 31694
+f 31683 31694 31684
+f 16389 31695 3318
+f 31696 31677 142
+f 31116 31697 31698
+f 4557 4559 4555
+f 31699 31700 31701
+f 21027 31702 31703
+f 31704 2497 27030
+f 31032 23879 31033
+f 31705 31663 22026
+f 4758 31706 17622
+f 31707 31708 31709
+f 31623 31625 31710
+f 31711 31712 31713
+f 31714 31715 31716
+f 31717 31707 31709
+f 31718 31719 15149
+f 10557 31116 31698
+f 31720 31721 31722
+f 31723 31682 13
+f 24593 24595 31680
+f 31679 31678 31724
+f 19826 10327 16771
+f 31702 31679 31724
+f 31725 31726 31727
+f 31700 31725 31727
+f 31725 31718 31726
+f 31718 31728 31726
+f 31729 31730 31731
+f 31732 26851 31733
+f 31734 31735 31736
+f 25547 31737 25548
+f 31735 31738 31739
+f 31738 31740 31739
+f 15796 31741 31742
+f 21749 31210 31213
+f 31743 31744 31745
+f 14357 31746 31747
+f 31728 31718 15149
+f 3018 6443 5040
+f 16176 16175 7000
+f 5054 4560 4559
+f 22210 21985 22132
+f 24632 15571 15570
+f 31706 31705 17622
+f 31748 31749 31750
+f 31751 31752 31753
+f 9599 31754 4758
+f 31749 31755 31756
+f 31757 31679 31702
+f 26852 31758 25960
+f 31759 31760 31761
+f 31261 31762 31763
+f 31764 31765 31766
+f 31767 31768 31706
+f 31661 31663 31705
+f 157 31769 156
+f 28525 31770 31691
+f 31771 31710 31772
+f 8307 31773 31774
+f 31765 31775 31766
+f 29088 15716 31776
+f 31777 31778 31779
+f 16176 7000 4558
+f 22273 22272 31692
+f 1461 3412 2825
+f 31780 16176 4558
+f 31781 25187 31780
+f 38 23768 39
+f 23860 22320 22321
+f 31782 31783 31784
+f 4502 4501 21027
+f 31785 31786 15468
+f 31787 31788 31789
+f 31786 18149 15468
+f 31116 31162 31697
+f 31790 4389 27075
+f 22801 31791 31695
+f 16389 22801 31695
+f 31792 31689 31791
+f 22801 31792 31791
+f 31793 31655 31689
+f 31794 31795 15884
+f 12665 31794 15884
+f 31162 31796 20370
+f 31797 31798 31795
+f 31799 31651 31800
+f 22515 31801 31802
+f 31803 28473 16162
+f 20817 22202 16188
+f 31804 31805 31806
+f 15718 17120 17119
+f 31807 31808 31809
+f 31810 31811 31812
+f 31813 4505 27588
+f 21980 21982 31814
+f 17296 2562 20650
+f 23592 5507 22473
+f 22587 31815 31816
+f 31815 22587 14913
+f 31675 31664 31817
+f 31664 22587 31816
+f 31208 27713 31818
+f 31819 15059 31820
+f 31821 31822 31672
+f 27760 28525 31691
+f 31162 20370 31697
+f 126 22497 20371
+f 31794 31797 31795
+f 31651 23092 31800
+f 31823 31824 31798
+f 31797 31823 31798
+f 31825 31826 31824
+f 31823 31825 31824
+f 31827 31828 31826
+f 31825 31827 31826
+f 31827 31829 31830
+f 31831 31832 31833
+f 31832 31651 31834
+f 31831 31833 31835
+f 31651 31799 31834
+f 31836 31831 31835
+f 31832 31834 31833
+f 29421 31776 31837
+f 31838 31839 31840
+f 28835 29835 31841
+f 4341 4343 31774
+f 31842 66 18150
+f 31843 31844 19
+f 31619 15446 25473
+f 31751 31753 31845
+f 58 57 31846
+f 31847 31838 31840
+f 30817 29421 31837
+f 31848 31849 31850
+f 31851 31852 31853
+f 31854 31855 31856
+f 31857 31858 31859
+f 31860 31857 31859
+f 31828 31827 31830
+f 31829 31861 31769
+f 31830 31829 31769
+f 22241 12837 22285
+f 836 5507 837
+f 6753 927 4692
+f 4558 4560 10306
+f 31861 31862 31696
+f 31769 31861 31696
+f 31862 31863 31677
+f 31696 31862 31677
+f 31863 31864 31660
+f 31677 31863 31660
+f 31865 29879 31866
+f 31867 31860 31866
+f 31868 29877 31865
+f 31860 31859 31866
+f 31869 29877 31868
+f 29879 31867 31866
+f 31870 31869 31868
+f 29877 29879 31865
+f 31755 31871 31756
+f 31872 31873 31874
+f 6426 7105 8223
+f 31619 31720 31693
+f 21747 24285 31875
+f 31876 124 126
+f 31877 31878 31879
+f 31880 31881 31755
+f 31836 31835 31858
+f 31857 31836 31858
+f 31864 31882 31647
+f 31883 27354 31870
+f 31660 31864 31647
+f 3412 1461 13910
+f 23092 8122 5230
+f 13382 13381 7369
+f 1087 1089 31884
+f 14437 23573 22473
+f 24632 23078 31885
+f 31261 14356 31762
+f 31886 31648 31647
+f 31882 31886 31647
+f 31887 31888 31648
+f 31886 31887 31648
+f 31889 31771 31888
+f 31887 31889 31888
+f 31890 31623 31771
+f 31889 31890 31771
+f 31891 31624 31623
+f 27354 31883 31892
+f 27354 31869 31870
+f 17740 31893 31894
+f 27355 27354 31892
+f 27355 31892 31895
+f 31893 27355 31895
+f 22272 31896 31692
+f 31620 31619 31693
+f 31897 31847 31898
+f 31740 31899 31900
+f 31901 31902 31903
+f 31877 31904 31878
+f 139 31654 155
+f 17740 31894 31905
+f 31890 31891 31623
+f 31906 31626 31624
+f 31891 31906 31624
+f 31907 31629 31626
+f 31906 31907 31626
+f 7245 7367 10905
+f 17272 22472 13055
+f 18005 12383 16135
+f 17796 22876 4230
+f 16481 31908 31909
+f 31910 28007 30515
+f 31911 31631 31629
+f 31907 31911 31629
+f 31912 31633 31631
+f 31911 31912 31631
+f 31913 31635 31633
+f 31912 31913 31633
+f 31914 31637 31635
+f 31913 31914 31635
+f 31915 31639 31637
+f 31914 31915 31637
+f 23857 146 145
+f 31654 31905 155
+f 25633 23858 31916
+f 31917 23857 145
+f 23858 23857 31917
+f 31918 23858 31917
+f 31796 20371 20370
+f 31115 31876 31162
+f 31654 17740 31905
+f 31893 31895 31894
+f 31919 31641 31639
+f 23858 31918 31916
+f 31915 31919 31639
+f 8215 18320 18708
+f 4691 2289 8697
+f 12763 3031 18682
+f 8302 16955 3970
+f 16301 17725 17727
+f 14039 17866 31920
+f 25305 650 652
+f 9567 22360 31921
+f 14779 10145 12377
+f 31922 31405 24433
+f 31923 31924 30993
+f 31902 31923 30993
+f 31925 31643 31641
+f 31919 31925 31641
+f 22342 31645 31643
+f 31925 22342 31643
+f 6466 8393 6467
+f 31645 22342 14779
+f 31926 31830 157
+f 11202 3318 3317
+f 31792 31793 31689
+f 31927 31656 31655
+f 31695 31791 31928
+f 7948 31920 7949
+f 31695 31928 31409
+f 31920 31929 7949
+f 3318 31695 31409
+f 31791 31930 31928
+f 16132 6906 4284
+f 14039 31920 7948
+f 31793 31927 31655
+f 31931 72 31932
+f 31933 31686 31656
+f 2305 10149 1368
+f 31456 31934 4977
+f 6236 6394 6237
+f 18097 20651 18098
+f 23545 23626 26770
+f 18375 21959 7364
+f 24214 21259 17996
+f 10912 12054 20183
+f 15258 14551 24914
+f 26554 26555 28935
+f 31935 31936 5680
+f 16032 16604 19879
+f 14780 16539 14781
+f 25633 31916 31929
+f 31920 25633 31929
+f 143 31660 31652
+f 31830 31769 157
+f 31662 31937 24266
+f 31937 24267 24266
+f 18151 31742 31938
+f 15469 18151 31938
+f 15625 31671 31939
+f 31666 31669 31670
+f 31940 31786 31785
+f 15626 15625 31939
+f 31682 31684 13
+f 8143 8142 31941
+f 31826 31828 17896
+f 31032 31685 23879
+f 31681 31672 31674
+f 31927 31933 31656
+f 31828 31830 31926
+f 31942 31943 31686
+f 31933 31942 31686
+f 16162 21258 16163
+f 2649 18097 17580
+f 18098 9998 17579
+f 31944 26758 18097
+f 2649 31944 18097
+f 31944 28134 26262
+f 26758 31944 26262
+f 13250 18800 28473
+f 28473 31803 31945
+f 28719 14321 12975
+f 19013 12512 6931
+f 3455 3263 3057
+f 1444 2586 1317
+f 12062 12061 15647
+f 15882 15799 15883
+f 8142 27329 31941
+f 31946 31947 31948
+f 31798 16973 14040
+f 31949 31950 31943
+f 31707 31767 31754
+f 156 31696 142
+f 6521 6520 31951
+f 31708 31707 31754
+f 14636 31952 31953
+f 6520 14636 31953
+f 2918 31361 31954
+f 31665 31667 31758
+f 15469 31938 31955
+f 26852 31665 31758
+f 18 16 31843
+f 15470 15469 31955
+f 31795 14040 14052
+f 2650 2649 17580
+f 16914 22925 16912
+f 21790 31944 2649
+f 2648 2650 17827
+f 31956 28134 31944
+f 21790 31956 31944
+f 31956 31957 16161
+f 28134 31956 16161
+f 31957 31945 31803
+f 16161 31957 31803
+f 27328 31668 27329
+f 13250 28473 31945
+f 17720 16274 16276
+f 24768 17243 21611
+f 31754 31767 31706
+f 31958 16480 16482
+f 31942 31949 31943
+f 15884 31795 14052
+f 31959 31960 31950
+f 31949 31959 31950
+f 31961 31794 12665
+f 1739 31961 12665
+f 31962 31797 31794
+f 31961 31962 31794
+f 31963 31823 31797
+f 31962 31963 31797
+f 31964 31825 31823
+f 31963 31964 31823
+f 31965 31827 31825
+f 31964 31965 31825
+f 31966 31829 31827
+f 31965 31966 31827
+f 31966 31967 31861
+f 31829 31966 31861
+f 31967 31968 31862
+f 10557 31698 31969
+f 31861 31967 31862
+f 24596 18800 13250
+f 9052 11590 11592
+f 2472 9052 18038
+f 20326 31956 21790
+f 2053 2853 17315
+f 31970 31957 31956
+f 20326 31970 31956
+f 31970 3707 31945
+f 31957 31970 31945
+f 1337 15085 1338
+f 31945 3707 13250
+f 18338 18387 18385
+f 31800 31971 31972
+f 31968 31973 31863
+f 31862 31968 31863
+f 31973 31974 31864
+f 31863 31973 31864
+f 31975 31882 31864
+f 31974 31975 31864
+f 31976 31886 31882
+f 31975 31976 31882
+f 31977 31887 31886
+f 31976 31977 31886
+f 31978 31889 31887
+f 31977 31978 31887
+f 31979 31890 31889
+f 31978 31979 31889
+f 31801 31980 31981
+f 31982 31891 31890
+f 31983 31984 31777
+f 31985 31986 31987
+f 17738 17740 31654
+f 31988 31869 27354
+f 25473 31989 31721
+f 12 31723 13
+f 31693 31722 31694
+f 31407 31681 31408
+f 22498 31990 31991
+f 28331 10558 31992
+f 31979 31982 31890
+f 6612 4808 4807
+f 31993 31906 31891
+f 17726 1871 6260
+f 2703 2702 21790
+f 17727 17726 18039
+f 2890 31970 20326
+f 5197 16161 16163
+f 20326 21635 2890
+f 31970 2890 3707
+f 19779 31992 31994
+f 21791 5956 5955
+f 10145 14779 14147
+f 31982 31993 31891
+f 31995 31907 31906
+f 31993 31995 31906
+f 31996 31911 31907
+f 31995 31996 31907
+f 31997 31912 31911
+f 31996 31997 31911
+f 31998 31913 31912
+f 31997 31998 31912
+f 31999 31914 31913
+f 32000 32001 31760
+f 31998 31999 31913
+f 32002 32003 32004
+f 32005 32006 32007
+f 10558 10557 31969
+f 32008 32009 32010
+f 31729 32011 32012
+f 32013 31729 32012
+f 32014 31915 31914
+f 31360 31909 4763
+f 31999 32014 31914
+f 32015 31919 31915
+f 32014 32015 31915
+f 32016 31925 31919
+f 32015 32016 31919
+f 34 32017 35
+f 32016 14148 22342
+f 31925 32016 22342
+f 3108 11540 3109
+f 5671 17634 9933
+f 32018 31717 32019
+f 31769 31696 156
+f 15618 32020 16807
+f 31833 31834 32021
+f 32022 8141 9194
+f 32022 32023 8141
+f 19879 32022 9194
+f 32023 31072 8141
+f 32024 31073 31072
+f 32023 32024 31072
+f 32025 32026 31073
+f 32024 32025 31073
+f 31833 32021 32027
+f 31835 31833 32027
+f 32028 21283 31960
+f 31959 32028 31960
+f 3891 3893 13588
+f 7949 14087 10985
+f 4809 5670 5669
+f 31972 31971 13588
+f 32029 32030 32031
+f 17110 29441 17171
+f 22680 19782 8292
+f 21718 4115 24378
+f 32032 28438 21283
+f 32028 32032 21283
+f 31866 31859 4
+f 30516 32033 30517
+f 31738 31983 31740
+f 25305 652 25306
+f 26851 25960 31733
+f 31670 11227 32034
+f 29 31732 79
+f 31759 32000 31760
+f 32035 32036 32037
+f 31984 31778 31777
+f 32035 32037 32026
+f 32025 32035 32026
+f 32038 10571 10570
+f 32036 10570 32037
+f 122 31876 31115
+f 32036 32038 10570
+f 5962 16011 15515
+f 32039 122 31115
+f 31770 16974 17471
+f 31117 29115 32040
+f 31776 15716 31811
+f 15124 16235 15123
+f 31980 30518 31981
+f 16364 32041 17471
+f 32042 31799 31972
+f 31744 32043 27758
+f 31787 31789 31896
+f 31799 32042 32044
+f 32045 31701 31843
+f 31408 31459 24267
+f 15470 31955 32046
+f 27226 15470 32046
+f 31865 31866 4
+f 15626 31939 21
+f 32047 32048 32049
+f 32050 31865 4
+f 31955 32051 32052
+f 32053 32054 31407
+f 32046 32052 32055
+f 32056 32046 32055
+f 32057 32058 32059
+f 32060 32061 32062
+f 31834 32044 32021
+f 32058 32060 32062
+f 16281 31676 31671
+f 32063 31868 32050
+f 31672 31822 31673
+f 12192 22680 648
+f 25659 28005 14425
+f 23380 14424 14426
+f 22680 649 648
+f 3703 5905 10504
+f 14653 15167 11014
+f 28439 11014 15167
+f 32064 31940 31785
+f 31826 17896 17865
+f 32065 31828 31926
+f 31858 32066 32067
+f 22139 25304 14865
+f 32068 32069 28330
+f 31859 31858 32067
+f 32068 28330 10571
+f 32038 32068 10571
+f 32070 31114 10556
+f 32069 10556 28330
+f 32039 31115 31114
+f 32069 32070 10556
+f 31939 31671 22
+f 32070 32039 31114
+f 31664 31816 31817
+f 31676 32071 32072
+f 21 31939 22
+f 31671 32072 22
+f 32073 64 32074
+f 32075 64 63
+f 32076 154 32077
+f 31741 32073 32078
+f 122 124 31876
+f 32079 32018 32077
+f 154 32076 127
+f 154 32080 32077
+f 32080 32079 32077
+f 32081 32082 32018
+f 32079 32081 32018
+f 32083 32049 32082
+f 31834 31799 32044
+f 32081 32083 32082
+f 31859 32067 4
+f 31799 31800 31972
+f 32032 11014 28438
+f 31870 31868 32063
+f 2891 3707 2889
+f 3920 8976 18791
+f 31883 31870 32084
+f 32085 31259 31910
+f 32086 31821 32087
+f 32088 31883 32084
+f 32054 32086 32087
+f 32089 32090 31821
+f 32091 69 32092
+f 32093 69 68
+f 32060 32094 32095
+f 32061 32060 32095
+f 31895 31892 32096
+f 31883 32088 32097
+f 21359 21113 21353
+f 21871 6888 9661
+f 14171 14170 20382
+f 1799 1798 17575
+f 31667 31670 32098
+f 31892 32097 32096
+f 31648 31888 31649
+f 31835 32027 32066
+f 31868 31865 32050
+f 32099 31406 32095
+f 31858 31835 32066
+f 31952 32100 32101
+f 32094 32099 32095
+f 31953 31952 32101
+f 32056 32055 32100
+f 6751 29579 6849
+f 31676 31675 32071
+f 23769 32102 14755
+f 31671 31676 32072
+f 4559 7000 4555
+f 31675 31817 32071
+f 14972 14912 14911
+f 32103 17535 32104
+f 31812 17119 31161
+f 17536 32105 32106
+f 32105 31410 31460
+f 32107 32103 32104
+f 64 32075 32074
+f 17537 17536 32106
+f 31741 32078 32108
+f 31742 31741 32108
+f 31742 32108 32109
+f 32073 32074 32078
+f 31938 32109 32051
+f 31938 31742 32109
+f 32046 31955 32052
+f 31955 31938 32051
+f 32048 32047 32059
+f 31952 32056 32100
+f 32083 32047 32049
+f 32058 32062 32059
+f 32084 31870 32063
+f 32047 32057 32059
+f 32110 15116 15045
+f 31894 31895 32111
+f 31701 31727 31844
+f 31822 32112 31673
+f 31894 32111 32113
+f 22906 29179 976
+f 31905 31894 32113
+f 31895 32096 32111
+f 32114 32115 15
+f 77 32116 15
+f 32086 32089 31821
+f 32091 32092 32090
+f 31892 31883 32097
+f 32089 32091 32090
+f 14994 1050 18906
+f 155 31905 137
+f 17623 6521 32117
+f 6520 31953 31951
+f 32118 4759 32117
+f 22401 31780 10306
+f 31726 32119 32120
+f 31917 145 148
+f 31905 32113 137
+f 32053 31407 31406
+f 32099 32053 31406
+f 32121 31700 31699
+f 32054 32087 31407
+f 32122 32121 31699
+f 32123 31725 31700
+f 31745 31744 32041
+f 32124 32118 32125
+f 15307 13953 13952
+f 31068 15617 31069
+f 32126 32127 11070
+f 22400 15571 24632
+f 23380 14426 15595
+f 8999 8478 1955
+f 14995 22391 1799
+f 32128 15608 15607
+f 9105 32129 32130
+f 30022 16961 16960
+f 1409 14757 8981
+f 32131 16682 32132
+f 12831 21070 12832
+f 32133 29441 17110
+f 4946 32134 22897
+f 16941 32133 17110
+f 32135 16012 29441
+f 6591 32136 22349
+f 32133 32135 29441
+f 32137 21386 16012
+f 32135 32137 16012
+f 32137 32138 32139
+f 31953 32101 32140
+f 31951 31953 32140
+f 32116 32114 15
+f 32122 31699 32115
+f 31918 31917 148
+f 32141 31918 148
+f 31918 32141 32142
+f 31916 31918 32142
+f 6521 31951 32117
+f 31929 31916 32143
+f 31888 31772 31649
+f 31701 31844 31843
+f 7949 31929 14087
+f 31980 30516 30518
+f 31929 32143 14087
+f 31916 32142 32143
+f 31931 31932 31947
+f 31651 23093 23092
+f 69 32093 32092
+f 4502 21027 31703
+f 127 32076 32144
+f 32145 127 32144
+f 31706 31768 31705
+f 32082 31707 31717
+f 32018 32082 31717
+f 7547 31961 1739
+f 19473 23008 9738
+f 32146 31962 31961
+f 72 32147 31932
+f 24266 20366 22026
+f 31946 31931 31947
+f 32148 32149 32150
+f 31903 29184 27714
+f 15540 22391 14994
+f 32151 31718 31725
+f 32121 32123 31700
+f 22515 31802 22516
+f 4502 32152 32153
+f 17152 22549 17153
+f 1739 12665 6629
+f 15043 17798 6393
+f 7227 12777 7228
+f 32154 17994 32155
+f 17994 32156 32155
+f 16618 23281 23280
+f 20326 21790 2702
+f 23280 1165 15577
+f 9566 19761 22361
+f 12548 9722 9642
+f 7001 6585 6896
+f 16806 1494 1630
+f 32157 3412 28666
+f 29358 17698 16806
+f 31936 5976 5684
+f 9489 8478 4331
+f 16188 32158 20817
+f 17698 32159 24592
+f 3715 6308 1746
+f 21386 32137 32139
+f 32138 32160 32161
+f 32118 32117 32125
+f 31951 32140 32162
+f 32114 32122 32115
+f 32123 32151 31725
+f 32163 32164 32165
+f 32166 31589 17725
+f 7547 32146 31961
+f 32167 31963 31962
+f 32146 32167 31962
+f 32168 31964 31963
+f 32167 32168 31963
+f 32169 31965 31964
+f 32168 32169 31964
+f 32170 31966 31965
+f 32169 32170 31965
+f 32171 31967 31966
+f 32170 32171 31966
+f 32172 31968 31967
+f 32147 72 71
+f 32171 32172 31967
+f 6896 6585 6584
+f 20078 20367 944
+f 32173 31973 31968
+f 32172 32173 31968
+f 32174 31974 31973
+f 32173 32174 31973
+f 32175 31975 31974
+f 32174 32175 31974
+f 32176 31976 31975
+f 32175 32176 31975
+f 32177 31977 31976
+f 32176 32177 31976
+f 32178 31978 31977
+f 32177 32178 31977
+f 32179 31979 31978
+f 32178 32179 31978
+f 32180 31982 31979
+f 32179 32180 31979
+f 32181 31993 31982
+f 32180 32181 31982
+f 31693 31720 31722
+f 18060 32182 6583
+f 32085 32183 31259
+f 12097 4099 1207
+f 14446 7109 14274
+f 9195 8143 16886
+f 15539 15541 16618
+f 31812 31161 23769
+f 11845 11753 11754
+f 4349 4167 4169
+f 25549 12830 12832
+f 17102 17101 32184
+f 19067 32185 23281
+f 16618 19067 23281
+f 32185 32186 1166
+f 23281 32185 1166
+f 32186 32187 1164
+f 1166 32186 1164
+f 32187 32188 29358
+f 1164 32187 29358
+f 32188 32159 17698
+f 29358 32188 17698
+f 18098 17579 17580
+f 32159 22645 24592
+f 2586 1444 16278
+f 15151 15150 15192
+f 32139 32138 32161
+f 30517 32150 32189
+f 32117 31951 32162
+f 32160 32190 32191
+f 4946 17019 32192
+f 32193 32124 32125
+f 133 21925 131
+f 31718 32151 31719
+f 32194 31995 31993
+f 32195 32085 31910
+f 32181 32194 31993
+f 32196 31996 31995
+f 32194 32196 31995
+f 32197 31997 31996
+f 32196 32197 31996
+f 32198 31764 32199
+f 31983 31777 31740
+f 32200 31998 31997
+f 32197 32200 31997
+f 32201 31999 31998
+f 32200 32201 31998
+f 32202 32014 31999
+f 32201 32202 31999
+f 32203 32015 32014
+f 32202 32203 32014
+f 27673 32016 32015
+f 32203 27673 32015
+f 25040 25659 14424
+f 32016 27673 14148
+f 18206 18205 16947
+f 31622 3576 32204
+f 31768 32205 31705
+f 32077 32018 32019
+f 31832 31650 31651
+f 9048 16115 7832
+f 32206 32207 31836
+f 32207 31650 31831
+f 31762 17516 21473
+f 3707 2891 388
+f 22238 47 46
+f 31591 31360 18266
+f 32208 32209 12706
+f 32210 32211 31839
+f 6234 12636 6082
+f 15335 25473 15446
+f 19067 15588 32185
+f 15588 19067 206
+f 15083 32212 32186
+f 32185 15083 32186
+f 32212 32213 32187
+f 32186 32212 32187
+f 32213 32214 32188
+f 32187 32213 32188
+f 32214 32215 32159
+f 32188 32214 32159
+f 18337 22645 32215
+f 32159 32215 22645
+f 11013 14653 11014
+f 3711 11688 3895
+f 32150 32216 32189
+f 32149 32217 32216
+f 32161 32160 32191
+f 32218 32219 32191
+f 32220 32124 32193
+f 32117 32162 32125
+f 32221 31620 31683
+f 16388 5772 16389
+f 32222 31734 32223
+f 31715 31761 31716
+f 32224 6169 14832
+f 31763 21473 17614
+f 132 32225 25230
+f 31728 32226 32119
+f 31727 32120 31844
+f 27226 32046 32056
+f 18982 27226 32056
+f 32000 32198 32001
+f 32227 32198 32000
+f 65 64 32073
+f 32227 32228 32198
+f 20 15626 21
+f 32064 31785 32112
+f 31822 32064 32112
+f 31824 31826 17865
+f 31828 32065 17896
+f 31824 17865 16973
+f 31798 31824 16973
+f 21748 21750 32229
+f 31795 31798 14040
+f 31791 31689 31930
+f 31735 31739 31736
+f 32087 31672 31681
+f 141 31653 139
+f 31888 31771 31772
+f 31876 31796 31162
+f 31717 31709 32230
+f 32019 31717 32230
+f 32009 32002 32004
+f 4 32067 5
+f 22239 5959 32231
+f 17894 23860 32232
+f 23860 22321 32220
+f 31312 31313 32233
+f 32234 17894 32232
+f 28439 15167 22349
+f 31727 31726 32120
+f 18375 22199 21959
+f 32136 28439 22349
+f 32235 32063 32236
+f 32050 4 76
+f 15588 15083 32185
+f 32237 31879 31873
+f 16278 16277 2586
+f 31031 31033 31668
+f 6307 2152 8846
+f 22898 32238 26073
+f 15082 32239 32212
+f 15083 15082 32212
+f 32239 32240 32213
+f 32212 32239 32213
+f 32240 32241 32214
+f 32213 32240 32214
+f 32241 32242 32215
+f 32214 32241 32215
+f 12832 5978 5977
+f 32242 22898 18337
+f 21763 21765 21759
+f 26073 18575 18335
+f 18575 18336 18335
+f 5774 5773 13659
+f 32190 32218 32191
+f 32243 22514 32219
+f 32244 32232 32245
+f 32245 32220 32193
+f 22625 32221 31682
+f 31620 31693 31683
+f 32246 24593 32247
+f 31842 18150 18149
+f 32041 31691 17471
+f 31909 4764 4763
+f 68 67 32248
+f 32228 31764 32198
+f 28352 21197 4513
+f 3711 11613 11688
+f 9738 1783 1816
+f 6594 12887 6595
+f 32249 32146 7547
+f 7548 32249 7547
+f 32088 32084 32250
+f 32251 32167 32146
+f 32252 31765 31764
+f 32253 32088 32250
+f 32249 32251 32146
+f 32254 32097 32253
+f 32255 32168 32167
+f 32251 32255 32167
+f 32256 32169 32168
+f 32255 32256 32168
+f 32257 32170 32169
+f 32256 32257 32169
+f 32258 32171 32170
+f 32257 32258 32170
+f 32096 32097 32259
+f 32260 32172 32171
+f 32096 32259 32261
+f 32097 32088 32253
+f 32111 32096 32261
+f 32097 32254 32259
+f 31731 31730 32005
+f 32198 32199 32001
+f 31950 32262 32263
+f 31764 31766 32199
+f 27350 25110 31120
+f 32006 32264 32007
+f 32042 31972 14391
+f 11445 11366 11368
+f 32258 32260 32171
+f 32265 32173 32172
+f 32260 32265 32172
+f 32266 32174 32173
+f 32265 32266 32173
+f 32066 32027 32267
+f 32268 32175 32174
+f 32266 32268 32174
+f 32269 32176 32175
+f 32268 32269 32175
+f 32270 32177 32176
+f 32269 32270 32176
+f 32271 32178 32177
+f 32270 32271 32177
+f 137 32113 138
+f 32272 32179 32178
+f 32271 32272 32178
+f 32111 32261 32273
+f 32274 32180 32179
+f 32272 32274 32179
+f 32275 32181 32180
+f 32274 32275 32180
+f 32276 32194 32181
+f 32275 32276 32181
+f 32236 32050 76
+f 32277 32141 147
+f 14923 24686 23010
+f 24686 19796 23010
+f 2471 2470 18282
+f 25187 16176 31780
+f 21198 32278 13309
+f 23281 1166 1165
+f 15082 29179 32239
+f 29179 25627 976
+f 27498 27500 32240
+f 32239 27498 32240
+f 27500 32279 32241
+f 32240 27500 32241
+f 32279 32280 32242
+f 32241 32279 32242
+f 32280 32238 22898
+f 32242 32280 22898
+f 32281 16178 16177
+f 32238 32282 26073
+f 11589 11517 11518
+f 14029 32282 14027
+f 16465 14028 14027
+f 4974 5125 5270
+f 11846 11845 11754
+f 31459 31674 14635
+f 32283 32234 32244
+f 32232 32220 32245
+f 29421 29088 31776
+f 31838 32210 31839
+f 4506 15717 15716
+f 32284 32285 31851
+f 32020 30059 16879
+f 27957 18720 17120
+f 32286 32227 32000
+f 32020 32287 30059
+f 32063 32050 32236
+f 32231 5959 5960
+f 32288 32196 32194
+f 32084 32063 32235
+f 32276 32288 32194
+f 32289 32197 32196
+f 32288 32289 32196
+f 32290 32200 32197
+f 32141 148 147
+f 32289 32290 32197
+f 32143 32142 32291
+f 32141 32277 32292
+f 32293 32201 32200
+f 32290 32293 32200
+f 32294 32202 32201
+f 14087 32143 15380
+f 32293 32294 32201
+f 32182 32136 6583
+f 32142 32292 32291
+f 32182 18060 27350
+f 32143 32291 15380
+f 32295 32203 32202
+f 21284 32182 27350
+f 32294 32295 32202
+f 27520 27673 32203
+f 32295 27520 32203
+f 25565 30336 25589
+f 21284 27350 31119
+f 21285 21284 31119
+f 31786 31842 18149
+f 32296 23290 32297
+f 31587 27355 31893
+f 32298 32299 31924
+f 31746 32166 31747
+f 15058 29490 32300
+f 32301 32042 14391
+f 12590 18120 11585
+f 32021 32044 32302
+f 32042 32301 32303
+f 32027 32021 32304
+f 32044 32042 32303
+f 32021 32302 32304
+f 32044 32303 32302
+f 32066 32267 5
+f 32067 32066 5
+f 32113 32111 32273
+f 32027 32304 32267
+f 25663 25587 26264
+f 32077 32019 32144
+f 17135 16979 16980
+f 13659 5773 18385
+f 32263 32262 27789
+f 31624 31628 31625
+f 32113 32273 138
+f 32009 32004 32010
+f 10558 31969 31992
+f 32305 32306 32307
+f 13660 31792 22801
+f 23930 20651 23988
+f 32308 32309 32310
+f 32311 31793 31792
+f 26845 17359 19796
+f 8143 31941 16886
+f 29179 27498 32239
+f 32312 32070 32069
+f 24433 27387 24434
+f 4816 4976 4974
+f 17714 11336 23051
+f 27982 26144 26041
+f 23628 23613 14438
+f 17222 25834 20152
+f 27499 32313 32279
+f 27500 27499 32279
+f 32313 32314 32280
+f 32279 32313 32280
+f 32314 32315 32238
+f 32280 32314 32238
+f 32315 32316 32282
+f 32238 32315 32282
+f 32316 32317 14027
+f 32282 32316 14027
+f 32317 14761 3625
+f 14027 32317 3625
+f 17715 23051 11933
+f 17075 3624 14760
+f 21358 15600 32318
+f 21077 15081 106
+f 32319 32320 32283
+f 32234 32232 32244
+f 32321 32322 32319
+f 32320 32234 32283
+f 32323 27587 27588
+f 32322 32320 32319
+f 31804 31806 31853
+f 31808 31814 31809
+f 32324 31807 32325
+f 31811 15718 17119
+f 32250 32084 32235
+f 32326 32327 32328
+f 31734 31736 32223
+f 31765 32329 31775
+f 13660 32311 31792
+f 6171 22238 22239
+f 32330 14722 32331
+f 31728 15149 32110
+f 32142 32141 32292
+f 32332 32333 16326
+f 31726 31728 32119
+f 32329 32334 31775
+f 18982 32056 31952
+f 14636 18982 31952
+f 18151 15796 31742
+f 15721 65 32073
+f 32332 32013 32333
+f 32248 31842 31786
+f 31940 32248 31786
+f 31730 32006 32005
+f 32248 67 31842
+f 67 66 31842
+f 11227 31669 3473
+f 16 32045 31843
+f 32335 31927 31793
+f 31937 31408 24267
+f 32011 31729 31731
+f 32311 32335 31793
+f 31720 25473 31721
+f 15335 15446 15360
+f 26845 31845 17359
+f 31753 27241 17360
+f 17537 32106 32336
+f 32337 17537 32336
+f 27499 16718 16720
+f 32327 32338 32328
+f 31872 32237 31873
+f 31897 31898 32338
+f 31881 32339 31714
+f 31904 32165 31878
+f 31736 31739 32340
+f 31739 31740 31900
+f 23290 28835 32297
+f 32339 31715 31714
+f 12 11 31723
+f 32297 28835 31841
+f 15720 66 17
+f 31720 31619 25473
+f 32262 21285 30604
+f 18 31843 19
+f 32341 31933 31927
+f 31989 25473 13952
+f 32335 32341 31927
+f 32342 31942 31933
+f 32341 32342 31933
+f 31714 31716 31871
+f 31260 32343 22983
+f 31673 32112 18981
+f 31796 126 20371
+f 31845 17360 17359
+f 16281 17552 31676
+f 32344 14507 17989
+f 15059 32300 31820
+f 32345 32233 32003
+f 31591 18266 1869
+f 32346 31307 31746
+f 32347 32312 32069
+f 31360 4763 18266
+f 128 32348 32080
+f 31588 31590 32349
+f 5125 4976 32350
+f 9446 21243 21648
+f 21153 21152 21259
+f 5230 8122 8796
+f 16720 19074 32313
+f 27499 16720 32313
+f 19074 32351 32314
+f 32313 19074 32314
+f 32351 32352 32315
+f 32314 32351 32315
+f 32352 32353 32316
+f 32315 32352 32316
+f 32353 32354 32317
+f 32316 32353 32317
+f 32354 14762 14761
+f 32317 32354 14761
+f 17645 26144 24559
+f 26144 17645 17682
+f 20383 14170 16189
+f 17018 32355 17019
+f 20261 32356 4434
+f 18404 17414 18402
+f 32357 5339 5341
+f 4946 4945 17019
+f 22285 12837 22351
+f 13005 12926 32358
+f 32359 32322 32321
+f 22876 32360 9234
+f 32336 32106 32361
+f 32362 32359 32321
+f 24686 26845 19796
+f 31758 32363 25961
+f 32364 32365 32366
+f 11 22626 31723
+f 31855 14733 31856
+f 31762 14358 17516
+f 32002 32345 32003
+f 32367 32246 32247
+f 32349 31591 1869
+f 28438 28439 32182
+f 31763 31762 21473
+f 32368 31763 17614
+f 32369 32370 32371
+f 32372 31949 31942
+f 32342 32372 31942
+f 32373 31959 31949
+f 17121 19759 19758
+f 32372 32373 31949
+f 32374 32028 31959
+f 31161 19758 32102
+f 16162 18802 24316
+f 18003 26152 18001
+f 32303 32375 32376
+f 32377 32249 7548
+f 32378 32023 32022
+f 31813 27588 27958
+f 31845 31753 17360
+f 13589 32378 32022
+f 32379 32107 32380
+f 13589 32022 19879
+f 32381 32382 32362
+f 32106 31460 32361
+f 32383 32384 32381
+f 32382 32359 32362
+f 32385 32386 32383
+f 32384 32382 32381
+f 32387 32388 32385
+f 32386 32384 32383
+f 32389 32390 32387
+f 32388 32386 32385
+f 32391 31412 32389
+f 32390 32388 32387
+f 31460 31412 32391
+f 32361 31460 32391
+f 32107 32104 32380
+f 31412 32390 32389
+f 32392 32024 32023
+f 32393 32107 32379
+f 20382 2895 17437
+f 32378 32392 32023
+f 32262 30604 27789
+f 21285 31119 30604
+f 32263 27789 27540
+f 21026 31757 31702
+f 31796 31876 126
+f 31687 32263 27540
+f 32394 32395 32035
+f 32396 32038 32036
+f 32397 32398 29199
+f 32399 32347 32068
+f 29031 32377 7548
+f 32302 32376 32400
+f 32401 32251 32249
+f 32377 32401 32249
+f 32304 32400 32402
+f 32403 32255 32251
+f 32404 32081 32079
+f 32267 32304 32402
+f 32405 32054 32053
+f 32406 32405 32053
+f 19074 16720 16719
+f 15081 15080 104
+f 4656 31456 4655
+f 26556 14409 22036
+f 19075 32407 32351
+f 19074 19075 32351
+f 32407 32408 32352
+f 32351 32407 32352
+f 32408 32409 32353
+f 32352 32408 32353
+f 32409 32410 32354
+f 32353 32409 32354
+f 32410 32411 14762
+f 32354 32410 14762
+f 32411 32412 15686
+f 14762 32411 15686
+f 32412 32355 17018
+f 15686 32412 17018
+f 1208 1207 4099
+f 32355 32192 17019
+f 32192 32134 4946
+f 12834 12748 6957
+f 25344 32413 31206
+f 6955 6957 12748
+f 15048 28888 15049
+f 18335 22898 26073
+f 32218 32243 32219
+f 5678 175 4948
+f 32325 32414 32415
+f 31667 32098 32363
+f 123 32039 32070
+f 32405 32416 32054
+f 32417 32236 3
+f 32267 32402 6
+f 32401 32403 32251
+f 32418 32256 32255
+f 32403 32418 32255
+f 32419 32257 32256
+f 32420 32235 32417
+f 32236 76 3
+f 32418 32419 32256
+f 32421 32258 32257
+f 32419 32421 32257
+f 32422 32260 32258
+f 32421 32422 32258
+f 32423 32265 32260
+f 32424 32250 32420
+f 32422 32423 32260
+f 32425 2585 2584
+f 23769 31161 32102
+f 32426 32266 32265
+f 32423 32426 32265
+f 32427 32268 32266
+f 32426 32427 32266
+f 32428 32269 32268
+f 32427 32428 32268
+f 32429 32270 32269
+f 32428 32429 32269
+f 32302 32303 32376
+f 32430 32271 32270
+f 32312 123 32070
+f 32301 32431 32375
+f 31708 31754 9599
+f 123 122 32039
+f 32104 17537 32337
+f 32432 31313 31781
+f 32433 32434 22515
+f 32380 32104 32337
+f 32433 22515 22514
+f 32435 31980 31801
+f 32243 32433 22514
+f 32434 31801 22515
+f 32434 32435 31801
+f 32436 30516 31980
+f 32435 32436 31980
+f 32437 32033 30516
+f 32438 32148 32033
+f 32436 32437 30516
+f 32439 32440 32148
+f 32437 32438 32033
+f 32441 32442 31880
+f 32438 32439 32148
+f 32439 32442 32441
+f 32440 32439 32441
+f 32443 32393 32379
+f 32442 32444 31880
+f 32445 32394 32025
+f 32446 32447 32448
+f 32445 32025 32024
+f 32395 32036 32035
+f 32392 32445 32024
+f 32394 32035 32025
+f 32395 32396 32036
+f 32399 32068 32038
+f 32396 32399 32038
+f 32347 32069 32068
+f 128 32080 154
+f 17121 31311 19759
+f 32304 32302 32400
+f 32348 32079 32080
+f 32429 32430 32270
+f 32250 32235 32420
+f 32449 32272 32271
+f 32430 32449 32271
+f 32450 32254 32451
+f 32452 32274 32272
+f 32416 32086 32054
+f 32253 32250 32424
+f 16807 32020 16879
+f 32453 70 32091
+f 4558 7000 4559
+f 1960 5663 3709
+f 19075 24481 32407
+f 22060 22061 22754
+f 32454 32455 32408
+f 32407 32454 32408
+f 32455 32456 32409
+f 32408 32455 32409
+f 32456 32457 32410
+f 32409 32456 32410
+f 32457 32458 32411
+f 32410 32457 32411
+f 32458 32459 32412
+f 32411 32458 32412
+f 32459 32460 32355
+f 32412 32459 32355
+f 32460 32461 32192
+f 32355 32460 32192
+f 32461 32462 32134
+f 32192 32461 32134
+f 32463 22994 32134
+f 32462 32463 32134
+f 13525 1471 13526
+f 32463 22995 22994
+f 15116 15086 15046
+f 12924 21762 12925
+f 32464 32465 32466
+f 32467 32222 32309
+f 32468 32089 32086
+f 32305 32307 32365
+f 5 32267 6
+f 32416 32468 32086
+f 32449 32452 32272
+f 32259 32254 32469
+f 32470 32275 32274
+f 32452 32470 32274
+f 32471 32276 32275
+f 138 32273 136
+f 32261 32472 32473
+f 32470 32471 32275
+f 32474 32288 32276
+f 32471 32474 32276
+f 32475 32289 32288
+f 32474 32475 32288
+f 32476 32290 32289
+f 32475 32476 32289
+f 32277 147 32477
+f 32478 32293 32290
+f 32348 32404 32079
+f 32235 32236 32417
+f 15636 24741 32479
+f 39 23769 14755
+f 12926 12924 12834
+f 27075 15620 28534
+f 28534 15636 32479
+f 24741 24670 32480
+f 4386 10627 6301
+f 24442 17123 25045
+f 32303 32301 32375
+f 32301 14391 32481
+f 32060 32482 32094
+f 32431 32301 32481
+f 31758 31667 32363
+f 32483 32099 32094
+f 32484 32485 31881
+f 22320 31708 9599
+f 32484 31881 31880
+f 32444 32484 31880
+f 21387 32486 32487
+f 32485 32339 31881
+f 30518 30517 32488
+f 32489 21387 32487
+f 30518 32488 32490
+f 31981 30518 32490
+f 31981 32490 32491
+f 30517 32189 32488
+f 31802 32491 32492
+f 31802 31981 32491
+f 32493 22516 32494
+f 22516 31802 32492
+f 32495 32493 32496
+f 22516 32492 32494
+f 32487 32486 32496
+f 32493 32494 32496
+f 16013 21385 32497
+f 21385 21387 32489
+f 32498 32499 32339
+f 16014 16013 32500
+f 32447 32393 32443
+f 32485 32498 32339
+f 32501 32446 32502
+f 32503 32447 32443
+f 32504 32501 32505
+f 32447 32503 32448
+f 17027 32504 17712
+f 32446 32448 32502
+f 32504 32505 17712
+f 32501 32502 32505
+f 15716 15718 31811
+f 32306 32506 32507
+f 32483 32406 32099
+f 32508 13951 32151
+f 32292 32277 32477
+f 32509 32292 32477
+f 32476 32478 32290
+f 32510 32294 32293
+f 32478 32510 32293
+f 32511 32295 32294
+f 32451 32253 32424
+f 32291 32292 32512
+f 32231 5960 28205
+f 32513 32116 77
+f 4346 4510 4509
+f 11103 14555 11101
+f 25045 32514 32454
+f 24481 32454 32407
+f 32514 32515 32455
+f 32454 32514 32455
+f 32515 32516 32456
+f 32455 32515 32456
+f 32516 32517 32457
+f 32456 32516 32457
+f 32517 32518 32458
+f 32457 32517 32458
+f 32518 32519 32459
+f 32458 32518 32459
+f 32519 32520 32460
+f 32459 32519 32460
+f 32520 32521 32461
+f 32460 32520 32461
+f 32521 32522 32462
+f 32461 32521 32462
+f 32523 32463 32462
+f 32522 32523 32462
+f 23568 22995 32463
+f 32523 23568 32463
+f 13479 13478 27843
+f 21400 18404 18403
+f 32524 32467 32309
+f 14158 12218 12220
+f 24285 31874 31875
+f 32525 31734 32222
+f 32453 32091 32089
+f 19603 31068 19604
+f 32254 32253 32451
+f 32468 32453 32089
+f 32510 32511 32294
+f 32259 32469 32472
+f 32526 27520 32295
+f 32511 32526 32295
+f 15380 32291 32527
+f 32292 32509 32512
+f 557 18158 555
+f 27520 32526 18120
+f 31666 31670 31667
+f 17796 4229 32357
+f 32373 32374 31959
+f 31732 31733 79
+f 15380 32527 6465
+f 32528 32032 32028
+f 70 69 32091
+f 32273 32473 136
+f 32529 32083 32081
+f 32404 32529 32081
+f 32529 32530 32083
+f 32530 32047 32083
+f 32047 32530 32057
+f 32530 32531 32057
+f 32531 32532 32057
+f 32532 32058 32057
+f 32532 32482 32058
+f 32482 32060 32058
+f 32533 32483 32094
+f 32482 32533 32094
+f 31733 25960 25962
+f 32406 32053 32099
+f 4929 4928 26636
+f 32284 31851 27759
+f 31311 31621 19759
+f 32393 32534 32107
+f 27759 31851 32535
+f 32536 21385 32489
+f 2832 30816 2833
+f 32486 32495 32496
+f 32537 32538 32007
+f 32264 32537 32007
+f 32539 32540 32541
+f 32542 32543 32538
+f 32537 32542 32538
+f 32544 32539 32541
+f 32544 32541 32543
+f 32542 32544 32543
+f 32545 32546 32540
+f 32539 32545 32540
+f 32547 32548 32546
+f 32545 32547 32546
+f 32547 32549 32548
+f 32549 31112 32548
+f 32549 32550 31112
+f 32550 28763 31112
+f 21385 32536 32497
+f 32551 20836 28763
+f 32552 32553 32286
+f 16014 32500 17613
+f 32552 32286 32499
+f 32554 32228 32227
+f 32498 32552 32499
+f 32553 32227 32286
+f 32553 32554 32227
+f 32555 32252 32228
+f 32554 32555 32228
+f 32556 32557 32252
+f 32558 31704 27030
+f 32555 32556 32252
+f 32123 32508 32151
+f 31311 17120 14171
+f 147 149 32477
+f 4167 4348 4511
+f 32374 32528 32028
+f 31757 32367 31679
+f 11012 11014 32032
+f 32528 11012 32032
+f 32246 32559 24593
+f 28439 32136 32182
+f 14 32513 77
+f 32560 32561 31902
+f 22696 26268 22763
+f 32136 6591 6583
+f 17125 32562 32514
+f 25045 17125 32514
+f 32562 32563 32515
+f 32514 32562 32515
+f 32563 32564 32516
+f 32515 32563 32516
+f 32564 32565 32517
+f 32516 32564 32517
+f 32565 32566 32518
+f 32517 32565 32518
+f 32566 32567 32519
+f 32518 32566 32519
+f 32567 32568 32520
+f 32519 32567 32520
+f 32568 32569 32521
+f 32520 32568 32521
+f 32569 32570 32522
+f 32521 32569 32522
+f 32571 32523 32522
+f 32570 32571 32522
+f 9265 23568 32523
+f 32571 9265 32523
+f 4326 8199 4327
+f 32572 458 19028
+f 32572 14704 32573
+f 6425 13349 6292
+f 32467 32525 32222
+f 32574 32575 32576
+f 32577 32364 32366
+f 32578 31735 31734
+f 32579 32114 32116
+f 32580 32581 15614
+f 32261 32259 32472
+f 32513 32579 32116
+f 32273 32261 32473
+f 32254 32450 32469
+f 19759 31621 17437
+f 31688 27539 31782
+f 14722 31659 32331
+f 32226 31728 32110
+f 21957 21956 22061
+f 4757 4759 32118
+f 32124 4757 32118
+f 31690 31657 31752
+f 15721 32073 31741
+f 32508 32123 32121
+f 32291 32512 32527
+f 32010 32004 32582
+f 32583 32508 32121
+f 31313 25187 31781
+f 21981 26947 26948
+f 31313 32432 30339
+f 32233 31313 30339
+f 32003 32233 27441
+f 32584 31751 31845
+f 4501 21025 21027
+f 29471 32585 30813
+f 31788 31987 31789
+f 32586 32587 32588
+f 25960 31758 25961
+f 32219 32493 32495
+f 32589 32590 32591
+f 32191 32219 32495
+f 2499 2498 31261
+f 16002 5678 16003
+f 32592 31743 29753
+f 32593 32592 29753
+f 16855 32594 16862
+f 32593 29753 16641
+f 13376 16732 13377
+f 32594 32593 16641
+f 22471 22210 22209
+f 3624 3626 14760
+f 32543 32541 32595
+f 32540 23421 32596
+f 32538 32543 32597
+f 32541 32540 32596
+f 32598 32007 32597
+f 32541 32596 32595
+f 32599 32005 32598
+f 32543 32595 32597
+f 32600 31731 32599
+f 32007 32538 32597
+f 31731 32005 32599
+f 32005 32007 32598
+f 32011 31731 32600
+f 28755 32011 32600
+f 32550 32551 28763
+f 31851 31853 32535
+f 17171 16014 17613
+f 32601 32602 20836
+f 32582 27440 32603
+f 16013 32497 32500
+f 32604 32582 32605
+f 27441 15078 15077
+f 32582 32603 32605
+f 27440 15077 32603
+f 32606 32607 32608
+f 31361 74 32609
+f 32610 31984 31983
+f 21785 32611 21786
+f 3891 13588 31971
+f 32612 32610 31983
+f 3542 9233 8564
+f 32219 22514 32493
+f 31688 31687 27539
+f 31784 32613 27241
+f 15796 15721 31741
+f 32120 32119 15624
+f 32382 32614 32359
+f 32232 23860 32220
+f 31880 31755 31749
+f 31687 27540 27539
+f 32615 32008 32616
+f 3473 14360 3474
+f 31784 31783 32613
+f 32617 32130 32562
+f 17125 32617 32562
+f 32130 32618 32563
+f 32562 32130 32563
+f 32618 32619 32564
+f 32563 32618 32564
+f 32619 32620 32565
+f 32564 32619 32565
+f 32620 32621 32566
+f 32565 32620 32566
+f 32621 32622 32567
+f 32566 32621 32567
+f 32622 32623 32568
+f 32567 32622 32568
+f 32623 32624 32569
+f 32568 32623 32569
+f 32624 32625 32570
+f 32569 32624 32570
+f 32626 32571 32570
+f 32625 32626 32570
+f 32627 9265 32571
+f 32626 32627 32571
+f 14704 32572 19028
+f 32627 9266 9265
+f 15395 9525 21838
+f 18123 10882 16308
+f 32628 32629 32630
+f 14509 32631 31854
+f 32525 32578 31734
+f 32632 32633 32634
+f 32580 19602 32581
+f 32635 31738 31735
+f 32583 32121 32122
+f 32636 15614 15613
+f 32637 32122 32114
+f 32637 32583 32122
+f 31657 31688 31782
+f 32579 32637 32114
+f 31740 31777 31899
+f 20836 32602 20837
+f 18906 12603 15540
+f 10710 31664 31675
+f 32638 1955 8479
+f 7672 21492 21491
+f 32639 32634 32398
+f 31459 14635 6519
+f 32640 31848 29489
+f 32641 31117 32040
+f 32609 73 31931
+f 31658 14721 153
+f 26713 26714 2265
+f 32642 25546 32557
+f 32556 32642 32557
+f 12832 21070 6104
+f 32643 25547 25546
+f 32642 32643 25546
+f 14848 14768 14974
+f 32643 32644 25547
+f 32644 32645 25547
+f 32644 32589 32645
+f 32589 32591 32645
+f 32524 32309 32308
+f 32590 32308 32591
+f 32646 32647 32648
+f 32590 32524 32308
+f 21477 32210 31838
+f 26881 32432 22047
+f 32145 32144 31990
+f 32183 32649 31259
+f 22136 22291 21881
+f 31307 31309 31746
+f 7550 19689 7551
+f 7551 19689 15697
+f 704 14321 28719
+f 22202 20817 21300
+f 9447 12746 188
+f 32134 22994 22897
+f 11518 11446 32650
+f 4389 31790 4390
+f 31782 27539 31783
+f 17358 21016 30990
+f 32534 32103 32107
+f 32651 32652 32653
+f 12068 17721 12069
+f 32104 17535 17537
+f 14832 6169 15514
+f 451 14721 14720
+f 32594 16641 16862
+f 31686 31943 31687
+f 32654 32368 31770
+f 32592 32043 31744
+f 32655 32326 31507
+f 31165 31164 32656
+f 32551 32601 20836
+f 32657 32655 31507
+f 32657 31507 32602
+f 32601 32657 32602
+f 32658 32327 32326
+f 32655 32658 32326
+f 32659 31897 32327
+f 32658 32659 32327
+f 32660 32661 32164
+f 31606 31847 31897
+f 28 27 31984
+f 32662 32415 32663
+f 22514 22516 32493
+f 32610 28 31984
+f 31753 31784 27241
+f 32664 32665 32587
+f 32008 32010 32616
+f 31783 32615 32613
+f 32145 31990 22498
+f 31657 31782 31752
+f 32397 32639 32398
+f 4503 4502 32153
+f 32613 32615 32666
+f 32603 15077 23183
+f 12975 12977 15697
+f 7550 2119 2118
+f 32130 32617 9105
+f 32156 17994 9266
+f 32129 32667 32618
+f 32130 32129 32618
+f 32667 32668 32619
+f 32618 32667 32619
+f 32668 32669 32620
+f 32619 32668 32620
+f 32669 32670 32621
+f 32620 32669 32621
+f 32670 32671 32622
+f 32621 32670 32622
+f 32671 32672 32623
+f 32622 32671 32623
+f 32672 32673 32624
+f 32623 32672 32624
+f 32673 32674 32625
+f 32624 32673 32625
+f 32675 32626 32625
+f 32674 32675 32625
+f 32676 32627 32626
+f 32675 32676 32626
+f 32156 9266 32627
+f 32676 32156 32627
+f 21235 15448 15447
+f 32154 22409 17994
+f 32677 14731 31855
+f 16980 16769 16870
+f 32575 32678 32576
+f 32631 32677 31855
+f 32578 32635 31735
+f 10 16016 11
+f 26947 32636 15613
+f 32612 31983 31738
+f 31816 32679 32680
+f 31817 31816 32680
+f 27541 32008 32615
+f 31923 32298 31924
+f 28007 31260 18270
+f 32195 31910 31908
+f 125 32145 22498
+f 28438 32182 21284
+f 31658 32681 31659
+f 31960 21283 21285
+f 21283 28438 21284
+f 31658 153 121
+f 32681 31658 121
+f 25548 31737 32682
+f 32309 32683 32310
+f 15794 32684 32654
+f 32685 32346 14357
+f 31815 14913 32686
+f 32208 12705 32687
+f 32688 14577 32689
+f 32690 32688 31666
+f 17897 32691 146
+f 3537 9473 17718
+f 14641 19765 7645
+f 23573 21729 22473
+f 74 73 32609
+f 23879 19778 23880
+f 31698 32692 32693
+f 19689 7550 4851
+f 32629 32646 32648
+f 32694 19765 32695
+f 17990 21477 31838
+f 16016 22626 11
+f 5960 44 16910
+f 14509 31854 32210
+f 25731 25733 32696
+f 31943 32263 31687
+f 19689 4851 6930
+f 32697 32464 32466
+f 23124 16947 18205
+f 23124 23249 23248
+f 2476 19634 26031
+f 17620 2476 26031
+f 12511 702 704
+f 26448 26446 24943
+f 1218 16071 1216
+f 1218 18332 16071
+f 18332 1218 19909
+f 24820 32698 9107
+f 32699 31819 16484
+f 32700 15059 31819
+f 32701 16484 29749
+f 32701 32699 16484
+f 32702 29749 32703
+f 32702 32701 29749
+f 31806 15792 28524
+f 32704 32702 32703
+f 32535 28524 27760
+f 32704 32703 32705
+f 32011 28755 28754
+f 17173 17175 16761
+f 32012 28754 22083
+f 32012 32011 28754
+f 32333 22083 16510
+f 32333 32012 22083
+f 10712 22587 31664
+f 16326 32333 16510
+f 32346 31746 14357
+f 25230 32369 32371
+f 32677 32706 14731
+f 21982 32707 32708
+f 32325 31809 32414
+f 32709 22154 21605
+f 32710 31732 29
+f 32029 23422 32030
+f 31788 31985 31987
+f 26 32710 29
+f 22625 31682 31723
+f 31709 31708 22320
+f 17440 19759 17437
+f 22626 22625 31723
+f 31928 31930 32584
+f 32343 30198 22983
+f 31690 31752 31751
+f 31930 31690 31751
+f 21791 22013 5956
+f 10756 7645 7644
+f 32698 32711 32129
+f 9107 32698 9105
+f 32711 32712 32667
+f 32129 32711 32667
+f 32712 32713 32668
+f 32667 32712 32668
+f 32713 32714 32669
+f 32668 32713 32669
+f 32714 32715 32670
+f 32669 32714 32670
+f 32715 32716 32671
+f 32670 32715 32671
+f 32716 32717 32672
+f 32671 32716 32672
+f 32717 32718 32673
+f 32672 32717 32673
+f 32718 32719 32674
+f 32673 32718 32674
+f 32719 32720 32675
+f 32674 32719 32675
+f 32721 32676 32675
+f 32720 32721 32675
+f 32155 32156 32676
+f 32721 32155 32676
+f 17994 17993 22553
+f 2833 30816 32722
+f 22966 22965 19431
+f 10017 3710 9388
+f 32706 21605 14731
+f 6948 27929 30429
+f 32604 32605 2474
+f 32723 32604 2474
+f 32635 32612 31738
+f 10571 28331 10572
+f 32072 32071 32724
+f 31817 32680 32725
+f 31854 31856 32211
+f 4505 31813 15717
+f 32013 32012 32333
+f 25548 32682 32334
+f 26755 14825 11365
+f 32205 31661 31705
+f 32019 32230 32726
+f 1162 1161 18543
+f 32033 32150 30517
+f 32727 29031 15589
+f 27588 32158 27958
+f 32654 31356 32368
+f 15262 32727 15589
+f 29088 4506 15716
+f 32309 32222 32683
+f 31815 32686 32679
+f 32210 31854 32211
+f 31669 32688 32689
+f 12920 14913 7643
+f 16761 17175 16855
+f 32728 32729 32730
+f 14503 14063 14483
+f 1500 1501 3795
+f 3795 11364 1500
+f 26755 11364 3795
+f 5663 16327 11791
+f 6931 12511 6930
+f 17990 31838 31847
+f 32659 31606 31897
+f 21477 14509 32210
+f 31606 17990 31847
+f 29754 30992 6804
+f 32631 31855 31854
+f 32726 32731 32732
+f 31908 30515 31909
+f 49 48 6170
+f 32733 14910 32465
+f 32734 32735 31805
+f 32736 32734 31805
+f 23200 22302 23249
+f 9805 2532 10021
+f 5536 5535 9275
+f 2178 32737 4348
+f 8210 2431 1138
+f 8125 8210 1138
+f 14624 15015 703
+f 702 14624 703
+f 22291 22142 21881
+f 15015 12062 703
+f 132 25230 129
+f 22745 3538 11095
+f 30604 31119 30605
+f 32722 5775 21301
+f 32357 32722 21301
+f 15586 5776 5775
+f 32722 15586 5775
+f 29470 5961 29471
+f 32738 32704 32705
+f 31119 31120 30605
+f 32581 19604 32739
+f 32740 32741 32558
+f 32705 31359 2497
+f 31068 14831 15617
+f 6170 22238 6171
+f 14833 16654 15618
+f 32742 32743 28435
+f 28434 32742 28435
+f 32744 32745 32746
+f 32747 32744 32746
+f 31903 30993 29184
+f 50 32748 31
+f 32706 32709 21605
+f 31809 31814 32749
+f 21747 31875 32750
+f 32751 32752 22154
+f 32753 26851 31732
+f 31211 32754 32755
+f 23859 31709 22320
+f 32710 32753 31732
+f 66 15720 18150
+f 32233 30339 27441
+f 31844 32120 15719
+f 31118 29116 29115
+f 18721 3538 17718
+f 15560 10022 10024
+f 11345 19951 9565
+f 5634 15319 5632
+f 24820 32756 32711
+f 32698 24820 32711
+f 32756 32757 32712
+f 32711 32756 32712
+f 32757 32758 32713
+f 32712 32757 32713
+f 32758 32759 32714
+f 32713 32758 32714
+f 32760 32715 32714
+f 32759 32760 32714
+f 32761 32716 32715
+f 32760 32761 32715
+f 32761 32762 32717
+f 32716 32761 32717
+f 32762 32763 32718
+f 32717 32762 32718
+f 32763 32764 32719
+f 32718 32763 32719
+f 32764 32765 32720
+f 32719 32764 32720
+f 32766 32721 32720
+f 32765 32766 32720
+f 32767 32155 32721
+f 32766 32767 32721
+f 25627 23729 976
+f 32767 32768 32155
+f 23092 5230 31971
+f 15390 8723 8722
+f 6949 6948 32769
+f 27929 22827 30429
+f 15912 15911 31620
+f 16009 15912 32221
+f 14906 18011 32367
+f 14907 14906 31757
+f 22 32072 23
+f 32071 31817 32725
+f 27957 27958 14169
+f 31852 32770 31853
+f 32546 21745 23421
+f 32548 21746 21745
+f 32771 32377 29031
+f 32727 32771 29031
+f 32772 32401 32377
+f 32771 32772 32377
+f 32773 32403 32401
+f 32772 32773 32401
+f 32774 14508 14507
+f 17616 17617 32775
+f 17652 22999 17644
+f 31356 31261 31763
+f 31816 31815 32679
+f 32776 32777 17408
+f 11591 15969 20183
+f 14913 12920 32686
+f 14768 8194 14974
+f 3413 16376 14825
+f 18011 2919 32246
+f 17408 32593 32594
+f 25304 25306 31548
+f 4331 1500 11364
+f 22957 11429 18773
+f 26755 11365 11364
+f 18602 11096 9107
+f 22194 21921 21920
+f 32026 32037 31032
+f 16879 27394 2598
+f 31674 15001 14635
+f 32778 29086 29420
+f 17317 3578 25251
+f 14907 31757 21026
+f 31819 31820 16485
+f 14721 31658 14722
+f 21605 22155 14732
+f 32440 31748 32149
+f 32779 32780 31852
+f 32285 32779 31852
+f 14357 31747 14358
+f 29440 24432 17719
+f 26144 17682 26041
+f 25322 25321 25251
+f 25321 32781 14624
+f 26755 16672 14825
+f 32781 15166 15015
+f 14624 32781 15015
+f 15084 25627 15082
+f 2179 2178 21305
+f 32415 32414 32183
+f 9473 18281 17718
+f 32414 32782 32183
+f 32749 31207 32782
+f 32415 32183 32085
+f 32663 32415 32085
+f 32663 32085 32195
+f 31849 32663 32195
+f 31778 58 31846
+f 31069 1088 1087
+f 32738 32705 31704
+f 31733 25962 59
+f 32734 32740 32735
+f 32741 32738 31704
+f 32740 32558 32735
+f 32741 31704 32558
+f 32783 32779 32285
+f 32776 32783 32285
+f 32784 17174 17173
+f 32785 32784 17173
+f 31663 24266 22026
+f 16636 32785 16724
+f 2498 32685 14356
+f 32786 14832 14831
+f 32709 32751 22154
+f 26948 32787 32707
+f 31211 32755 31212
+f 24434 32577 32752
+f 32788 26852 26851
+f 31941 27329 32789
+f 9933 32790 5669
+f 32753 32788 26851
+f 32003 27441 27440
+f 31752 31784 31753
+f 11284 15560 11285
+f 32004 32003 27440
+f 32791 24820 18721
+f 32768 32792 32154
+f 32791 32793 32756
+f 24820 32791 32756
+f 32793 32794 32757
+f 32756 32793 32757
+f 32794 32795 32758
+f 32757 32794 32758
+f 32795 32796 32759
+f 32758 32795 32759
+f 32797 32760 32759
+f 32796 32797 32759
+f 32798 32761 32760
+f 32797 32798 32760
+f 32799 32762 32761
+f 32798 32799 32761
+f 32800 32763 32762
+f 32799 32800 32762
+f 32801 32764 32763
+f 32800 32801 32763
+f 32801 32802 32765
+f 32764 32801 32765
+f 32802 32803 32766
+f 32765 32802 32766
+f 32803 32804 32767
+f 32766 32803 32767
+f 32804 32805 32768
+f 32767 32804 32768
+f 22000 22409 32154
+f 15046 14973 15044
+f 32154 32792 22000
+f 3413 32157 16376
+f 32723 2474 17619
+f 32806 32723 17619
+f 32807 32808 32809
+f 32810 32811 32812
+f 32071 32725 32724
+f 32037 31685 31032
+f 32813 32324 32662
+f 32072 32724 23
+f 31669 32689 3473
+f 15718 27957 17120
+f 32814 32418 32403
+f 15078 15882 15079
+f 32773 32814 32403
+f 32815 32419 32418
+f 27759 32535 27760
+f 32814 32815 32418
+f 32816 32421 32419
+f 32815 32816 32419
+f 32602 31509 20837
+f 32817 32818 32819
+f 32078 32074 32820
+f 15793 32684 15794
+f 32075 32821 32822
+f 32074 32075 32822
+f 31697 32823 32692
+f 32040 29115 4501
+f 11386 11465 7834
+f 22906 976 975
+f 27929 56 22827
+f 56 80 22827
+f 16725 15319 16549
+f 11188 3455 3265
+f 32824 11188 3265
+f 16376 9489 11365
+f 11253 8934 2645
+f 4974 5123 4975
+f 16542 179 16543
+f 6103 32825 651
+f 4637 8502 12557
+f 650 6103 651
+f 22957 18773 32825
+f 21960 27587 32745
+f 32736 31805 31804
+f 32826 32736 31804
+f 32780 32827 32770
+f 31852 32780 32770
+f 32826 31804 32770
+f 32827 32826 32770
+f 32791 17718 18281
+f 32061 31662 31661
+f 1162 18543 3712
+f 26458 32828 32829
+f 25322 22426 32781
+f 25321 25322 32781
+f 22426 22546 15166
+f 32781 22426 15166
+f 17517 16403 22593
+f 1341 1956 3201
+f 31820 32830 31308
+f 24632 22823 22400
+f 32831 16486 32346
+f 16485 31308 31307
+f 16485 31820 31308
+f 16486 16485 31307
+f 32300 31958 32830
+f 31820 32300 32830
+f 32739 31069 1087
+f 29490 16480 31958
+f 20540 29156 20541
+f 32739 1087 32832
+f 26411 32833 15585
+f 29440 31922 24432
+f 22498 31991 22499
+f 18964 16051 18965
+f 32783 32776 17174
+f 32784 32783 17174
+f 30340 26881 15797
+f 26881 22047 16548
+f 32743 32783 32784
+f 27799 32785 16636
+f 30340 15797 15882
+f 28435 32743 32784
+f 31814 32708 32749
+f 15078 30340 15882
+f 32751 24434 32752
+f 31814 21982 32708
+f 31668 31033 32834
+f 27387 32364 32577
+f 32835 32690 31665
+f 32836 32837 32630
+f 32835 31665 26852
+f 32688 31669 31666
+f 32788 32835 26852
+f 32690 31666 31665
+f 13910 13964 3412
+f 22994 22996 22897
+f 32838 32793 32791
+f 18281 32838 32791
+f 32838 32839 32794
+f 32793 32838 32794
+f 32839 32840 32795
+f 32794 32839 32795
+f 32840 32841 32796
+f 32795 32840 32796
+f 32841 32842 32797
+f 32796 32841 32797
+f 32843 32798 32797
+f 32842 32843 32797
+f 32844 32799 32798
+f 32843 32844 32798
+f 32844 32845 32800
+f 32799 32844 32800
+f 32846 32801 32800
+f 32845 32846 32800
+f 32847 32802 32801
+f 32846 32847 32801
+f 32847 32848 32803
+f 32802 32847 32803
+f 32848 32849 32804
+f 32803 32848 32804
+f 32849 32850 32805
+f 32804 32849 32805
+f 32850 23247 22078
+f 32805 32850 22078
+f 25834 178 177
+f 22391 14995 14994
+f 31033 23879 23878
+f 32851 31033 23878
+f 17133 17057 17056
+f 16016 16010 22626
+f 32040 4501 32852
+f 15618 16654 32020
+f 63 78 32821
+f 32075 63 32821
+f 15685 17287 17075
+f 31807 31809 32325
+f 17409 31745 16364
+f 16276 6718 22749
+f 32853 32422 32421
+f 32816 32853 32421
+f 32854 32423 32422
+f 6805 30992 17409
+f 32853 32854 32422
+f 14358 7316 17516
+f 32540 32546 23421
+f 32855 32426 32423
+f 32854 32855 32423
+f 30993 31924 29238
+f 31837 31776 31810
+f 32299 32425 2584
+f 32326 32328 31508
+f 31743 30992 29754
+f 32108 32078 32856
+f 32074 32822 32820
+f 14408 22035 14409
+f 31698 31697 32692
+f 17018 14872 15686
+f 16090 26758 26262
+f 21982 26948 32707
+f 16135 32748 50
+f 20651 20650 18098
+f 32204 30101 32857
+f 32157 32858 9490
+f 16376 32157 9490
+f 32858 32859 8479
+f 9490 32858 8479
+f 32859 32860 32638
+f 8479 32859 32638
+f 32860 32861 14703
+f 32638 32860 14703
+f 30101 32204 3576
+f 20988 19951 11345
+f 32791 18721 17718
+f 14704 6601 9179
+f 25322 3578 3577
+f 32824 11282 11188
+f 32062 32061 31661
+f 25322 3577 22426
+f 32862 32863 29087
+f 29489 31848 31850
+f 26826 20253 20578
+f 16792 22897 22996
+f 4765 16303 16302
+f 15124 12063 15014
+f 22425 22547 22546
+f 22426 22425 22546
+f 13471 9211 9323
+f 27294 17068 26325
+f 6104 21070 6264
+f 32864 17899 22545
+f 14703 1956 32638
+f 16234 15458 18067
+f 18009 3005 21037
+f 32865 16969 31622
+f 15686 14760 14762
+f 17893 23859 17894
+f 32300 29490 31958
+f 3710 7053 9388
+f 32866 32739 32832
+f 31850 32867 16480
+f 15615 32868 32561
+f 32787 15615 32561
+f 32743 32742 32869
+f 14703 32861 14704
+f 32605 32603 20292
+f 32785 17173 16724
+f 17238 27799 16636
+f 28435 32784 32785
+f 26948 15613 32787
+f 30286 32870 32871
+f 32862 29087 29086
+f 32606 32608 32872
+f 32733 14908 14910
+f 23422 21747 32750
+f 21926 32641 32873
+f 23010 19796 2831
+f 24434 27387 32577
+f 32700 15057 15059
+f 32818 32874 32819
+f 6518 32305 32364
+f 22822 2520 2345
+f 32875 32807 32809
+f 21927 32873 32225
+f 32678 32837 32836
+f 19298 19477 6723
+f 23861 20651 23930
+f 25119 32838 18281
+f 10817 11590 9052
+f 25119 32876 32839
+f 32838 25119 32839
+f 32876 32877 32840
+f 32839 32876 32840
+f 32877 32878 32841
+f 32840 32877 32841
+f 32878 32879 32842
+f 32841 32878 32842
+f 32879 32880 32843
+f 32842 32879 32843
+f 32881 32844 32843
+f 32880 32881 32843
+f 32882 32845 32844
+f 32881 32882 32844
+f 32883 32846 32845
+f 32882 32883 32845
+f 32884 32847 32846
+f 32883 32884 32846
+f 32884 32885 32848
+f 32847 32884 32848
+f 32885 32886 32849
+f 32848 32885 32849
+f 32886 32887 32850
+f 32849 32886 32850
+f 32887 23246 23247
+f 32850 32887 23247
+f 7771 7672 21491
+f 22403 22402 22369
+f 21108 6949 32506
+f 6949 32769 32506
+f 5962 15515 5963
+f 6948 30429 32769
+f 18720 14169 14171
+f 3624 17808 3625
+f 32078 32820 32856
+f 32043 32284 27759
+f 32602 31507 31509
+f 27789 30604 30606
+f 31884 1089 32425
+f 31747 16301 7316
+f 32888 32427 32426
+f 32855 32888 32426
+f 32889 32428 32427
+f 32888 32889 32427
+f 32287 28205 30059
+f 1089 16808 32425
+f 16808 16879 2598
+f 30059 2587 27394
+f 32890 32429 32428
+f 32889 32890 32428
+f 5340 2831 5341
+f 32041 27758 31691
+f 126 125 22497
+f 32891 32892 32661
+f 32223 31736 32893
+f 30992 31745 17409
+f 26554 28936 26637
+f 17075 14760 15685
+f 14410 1462 14408
+f 17326 32358 12926
+f 6955 12546 22163
+f 13964 14311 19595
+f 26881 17028 15797
+f 15613 15615 32787
+f 32526 13159 12218
+f 20896 22548 20894
+f 9232 9234 32360
+f 32894 32895 456
+f 32829 32896 32859
+f 32858 32829 32859
+f 32896 32897 32860
+f 32859 32896 32860
+f 32897 32573 32861
+f 32860 32897 32861
+f 15085 2127 22161
+f 20542 21526 20458
+f 32572 32894 458
+f 20542 20458 18888
+f 458 32894 456
+f 32895 30101 456
+f 8125 1138 7945
+f 2347 20464 2345
+f 32866 32832 32868
+f 7834 3316 11386
+f 3577 16969 22425
+f 15615 32866 32868
+f 16969 32898 22425
+f 21586 28352 31558
+f 32898 32899 22547
+f 22425 32898 22547
+f 32900 22545 22547
+f 32899 32900 22547
+f 17899 32864 15458
+f 32900 32864 22545
+f 32864 15459 15458
+f 21987 32901 22247
+f 13859 13943 14035
+f 14035 5942 13859
+f 14976 18877 14977
+f 13859 5942 13764
+f 14760 3626 14761
+f 17742 23201 120
+f 29490 31850 16480
+f 31849 32195 32867
+f 32787 32561 32560
+f 32707 32787 32560
+f 15717 31813 27958
+f 4388 4390 30288
+f 2474 32605 2475
+f 32603 23183 20292
+f 27799 28435 32785
+f 32743 32869 32779
+f 22084 28434 27799
+f 32778 32862 29086
+f 5078 25731 32607
+f 16934 5078 32607
+f 10585 10375 8820
+f 16343 25732 25731
+f 17622 31705 22026
+f 15512 7228 21242
+f 27 58 31778
+f 10711 32110 15045
+f 21108 32506 32306
+f 27713 31903 27714
+f 27387 6518 32364
+f 21109 21108 32306
+f 21109 32306 32305
+f 6518 21109 32305
+f 23124 23123 23249
+f 22142 23246 4515
+f 16946 25119 18206
+f 21873 21719 9796
+f 16946 32902 32876
+f 25119 16946 32876
+f 32902 32903 32877
+f 32876 32902 32877
+f 32903 32904 32878
+f 32877 32903 32878
+f 32904 32905 32879
+f 32878 32904 32879
+f 32906 32880 32879
+f 32905 32906 32879
+f 32907 32881 32880
+f 32906 32907 32880
+f 32908 32882 32881
+f 32907 32908 32881
+f 32909 32883 32882
+f 32908 32909 32882
+f 32909 32910 32884
+f 32883 32909 32884
+f 32910 32911 32885
+f 32884 32910 32885
+f 32911 32912 32886
+f 32885 32911 32886
+f 32912 31559 32887
+f 32886 32912 32887
+f 31559 4515 23246
+f 32887 31559 23246
+f 4581 6511 3110
+f 13309 12232 5353
+f 31069 15617 1088
+f 15614 32866 15615
+f 32561 31923 31902
+f 1088 15618 16807
+f 32742 30285 32869
+f 27241 32913 26411
+f 32109 32108 32914
+f 32777 32284 32043
+f 16481 31909 31360
+f 32499 31759 31715
+f 16654 16552 32287
+f 12069 17721 32915
+f 32916 32430 32429
+f 32890 32916 32429
+f 32917 32449 32430
+f 32916 32917 32430
+f 32918 32452 32449
+f 32917 32918 32449
+f 14755 32102 14756
+f 31704 32705 2497
+f 32919 32470 32452
+f 16552 32231 32287
+f 32918 32919 32452
+f 31884 32425 32299
+f 8613 15577 1165
+f 104 17742 120
+f 23288 23290 32296
+f 32237 31877 31879
+f 28936 32920 14410
+f 26637 28936 14410
+f 32920 1460 1462
+f 14410 32920 1462
+f 13159 32526 17087
+f 16389 5774 22801
+f 7549 2119 7550
+f 13212 11332 2770
+f 21468 2895 20382
+f 32684 2499 31356
+f 26458 26457 32828
+f 1956 14703 3201
+f 32828 32921 32896
+f 32829 32828 32896
+f 32921 32922 32897
+f 32896 32921 32897
+f 32922 32923 32573
+f 32897 32922 32573
+f 32923 32924 32572
+f 32573 32923 32572
+f 32924 32925 32894
+f 32572 32924 32894
+f 32925 32926 32895
+f 32894 32925 32895
+f 32926 32857 30101
+f 32895 32926 30101
+f 22546 15124 15166
+f 22076 22078 22291
+f 9340 9628 3653
+f 12455 6370 21347
+f 32865 32927 32898
+f 16969 32865 32898
+f 32927 32928 32899
+f 32898 32927 32899
+f 32929 32900 32899
+f 32928 32929 32899
+f 32930 32864 32900
+f 32929 32930 32900
+f 32930 32931 15459
+f 32864 32930 15459
+f 32931 23904 14976
+f 15459 32931 14976
+f 5257 2315 5258
+f 14976 23904 18877
+f 23157 26452 23158
+f 6810 6896 6584
+f 31850 31849 32867
+f 28524 28525 27760
+f 32707 32560 32932
+f 32708 32707 32932
+f 31207 32932 31208
+f 36 31837 37
+f 32613 32666 32913
+f 32605 20292 2475
+f 32783 32743 32779
+f 32869 30287 32780
+f 30471 30473 32611
+f 32728 32697 32729
+f 5078 16343 25731
+f 15512 21242 25732
+f 32363 32098 12382
+f 32034 11281 27511
+f 25962 25961 18004
+f 32363 12382 12381
+f 31846 57 26162
+f 25962 18004 55
+f 31779 31846 3810
+f 57 30 26162
+f 31899 31779 3809
+f 31846 26162 3810
+f 31900 31899 15519
+f 31779 3810 3809
+f 31622 32204 32865
+f 31971 31800 23092
+f 23248 16945 16947
+f 16947 16946 18206
+f 16945 32933 32902
+f 16946 16945 32902
+f 32934 32903 32902
+f 32933 32934 32902
+f 32935 32904 32903
+f 32934 32935 32903
+f 32936 32905 32904
+f 32935 32936 32904
+f 32937 32906 32905
+f 32936 32937 32905
+f 32937 32938 32907
+f 32906 32937 32907
+f 32939 32908 32907
+f 32938 32939 32907
+f 32940 32909 32908
+f 32939 32940 32908
+f 32940 32941 32910
+f 32909 32940 32910
+f 32941 32942 32911
+f 32910 32941 32911
+f 32942 31558 32912
+f 32911 32942 32912
+f 28443 27902 28066
+f 32912 31558 31559
+f 8199 2972 15828
+f 14972 15044 14973
+f 16135 16134 32748
+f 26470 28224 26555
+f 53 16135 50
+f 16134 32606 32748
+f 16654 32287 32020
+f 32148 32440 32149
+f 6170 48 22238
+f 31589 32349 23250
+f 32108 32856 32914
+f 32592 32777 32043
+f 32286 32000 31759
+f 32110 10711 17551
+f 32481 32278 32943
+f 19603 32944 31068
+f 32945 32471 32470
+f 32919 32945 32470
+f 22472 32474 32471
+f 32945 22472 32471
+f 17272 32475 32474
+f 22472 17272 32474
+f 32375 32431 32946
+f 17135 32476 32475
+f 17272 17135 32475
+f 16980 32478 32476
+f 32376 32375 32947
+f 32431 32943 32946
+f 5340 5339 4720
+f 11418 1141 20287
+f 28935 32948 32920
+f 28936 28935 32920
+f 32948 13908 1460
+f 32920 32948 1460
+f 18010 18009 21037
+f 18098 20650 2562
+f 8129 22505 21507
+f 26458 28666 19595
+f 22363 32949 22402
+f 2315 19306 19305
+f 26457 32950 32828
+f 14311 26458 19595
+f 32950 32951 32921
+f 32828 32950 32921
+f 32951 32952 32922
+f 32921 32951 32922
+f 32952 32953 32923
+f 32922 32952 32923
+f 32953 32954 32924
+f 32923 32953 32924
+f 32954 32955 32925
+f 32924 32954 32925
+f 32955 32956 32926
+f 32925 32955 32926
+f 32956 32957 32857
+f 32926 32956 32857
+f 32958 32204 32857
+f 32957 32958 32857
+f 32958 32959 32865
+f 32204 32958 32865
+f 32959 32960 32927
+f 32865 32959 32927
+f 32960 32961 32928
+f 32927 32960 32928
+f 32962 32929 32928
+f 32961 32962 32928
+f 32963 32930 32929
+f 32962 32963 32929
+f 32963 32964 32931
+f 32930 32963 32931
+f 32964 32965 23904
+f 32931 32964 23904
+f 2315 19305 5258
+f 32965 22777 23904
+f 13590 6612 6611
+f 22775 22727 22776
+f 32645 32966 31737
+f 23201 102 120
+f 32708 32932 31207
+f 32749 32708 31207
+f 13400 17620 13401
+f 17502 7431 11185
+f 32786 32224 14832
+f 32585 32967 32968
+f 32779 32869 32780
+f 30287 32871 32827
+f 32817 32819 32808
+f 27441 30339 15078
+f 16343 15512 25732
+f 31589 23250 17725
+f 25961 32363 12381
+f 32098 27511 12382
+f 32432 26881 30340
+f 2833 32722 32357
+f 32969 29198 29200
+f 31747 32166 16301
+f 31904 32163 32165
+f 16484 31819 16485
+f 32970 32971 32633
+f 32639 32632 32634
+f 27182 25732 21241
+f 32607 25731 32696
+f 15969 11591 11590
+f 11589 14238 11667
+f 32972 16945 23248
+f 14758 32973 14757
+f 32974 32933 16945
+f 32972 32974 16945
+f 32974 32975 32934
+f 32933 32974 32934
+f 32976 32935 32934
+f 32975 32976 32934
+f 32977 32936 32935
+f 32976 32977 32935
+f 32978 32937 32936
+f 32977 32978 32936
+f 32979 32938 32937
+f 32978 32979 32937
+f 32980 32939 32938
+f 32979 32980 32938
+f 32981 32940 32939
+f 32980 32981 32939
+f 32981 32982 32941
+f 32940 32981 32941
+f 32982 32983 32942
+f 32941 32982 32942
+f 32983 32984 31558
+f 32942 32983 31558
+f 4513 4515 28352
+f 32984 21586 31558
+f 14446 14274 14923
+f 11613 3711 3512
+f 16934 32607 32606
+f 16134 16934 32606
+f 32098 32034 27511
+f 3472 21731 11281
+f 12501 29472 9933
+f 32034 3472 11281
+f 31837 31810 37
+f 11590 10817 13585
+f 32109 32914 32985
+f 32777 32592 32593
+f 31739 31900 32340
+f 32986 26873 32987
+f 32400 32376 32988
+f 32431 32481 32943
+f 17135 16980 32476
+f 16870 32510 32478
+f 16980 16870 32478
+f 32376 32947 32988
+f 32989 32511 32510
+f 16870 32989 32510
+f 28223 26555 28224
+f 32511 32989 32526
+f 32870 32651 32653
+f 32990 5679 5409
+f 32402 32400 32991
+f 26555 32992 28935
+f 21178 32126 11070
+f 32992 32993 32948
+f 28935 32992 32948
+f 32993 13909 13908
+f 32948 32993 13908
+f 6229 11418 13469
+f 13469 11418 20287
+f 5229 3891 31971
+f 13965 32994 14311
+f 32994 32995 26457
+f 26073 32282 14029
+f 32995 32996 32950
+f 26457 32995 32950
+f 32996 32997 32951
+f 32950 32996 32951
+f 32997 32998 32952
+f 32951 32997 32952
+f 32998 32999 32953
+f 32952 32998 32953
+f 32999 33000 32954
+f 32953 32999 32954
+f 33000 33001 32955
+f 32954 33000 32955
+f 33001 33002 32956
+f 32955 33001 32956
+f 33002 33003 32957
+f 32956 33002 32957
+f 33003 33004 32958
+f 32957 33003 32958
+f 33004 33005 32959
+f 32958 33004 32959
+f 33005 33006 32960
+f 32959 33005 32960
+f 33006 33007 32961
+f 32960 33006 32961
+f 33008 32962 32961
+f 33007 33008 32961
+f 33009 32963 32962
+f 33008 33009 32962
+f 33009 33010 32964
+f 32963 33009 32964
+f 33010 33011 32965
+f 32964 33010 32965
+f 33012 22777 32965
+f 33011 33012 32965
+f 22775 22802 22727
+f 33012 22870 22777
+f 423 4644 899
+f 22198 22197 33013
+f 32414 32749 32782
+f 17653 22860 29591
+f 32581 32739 32866
+f 32867 32195 31908
+f 32969 29200 33014
+f 32703 32831 31359
+f 32780 30287 32827
+f 32653 32826 32827
+f 32037 10570 31685
+f 31165 32656 33015
+f 21544 27587 21960
+f 31755 31714 31871
+f 59 25962 55
+f 25961 12381 18004
+f 33016 21748 32229
+f 21749 31213 21750
+f 32055 33017 22271
+f 32100 32055 22271
+f 32101 33018 33019
+f 32140 32101 33019
+f 32140 33019 31163
+f 32162 32140 31163
+f 32193 32125 20379
+f 32162 31163 33020
+f 31712 32694 33021
+f 32125 32162 33020
+f 22303 32972 23248
+f 22401 10306 22348
+f 33022 32974 32972
+f 22753 33022 32972
+f 33022 33023 32975
+f 32974 33022 32975
+f 33024 32976 32975
+f 33023 33024 32975
+f 33025 32977 32976
+f 33024 33025 32976
+f 33026 32978 32977
+f 33025 33026 32977
+f 33027 32979 32978
+f 33026 33027 32978
+f 33028 32980 32979
+f 33027 33028 32979
+f 33029 32981 32980
+f 33028 33029 32980
+f 33029 33030 32982
+f 32981 33029 32982
+f 33031 32983 32982
+f 33030 33031 32982
+f 33032 32984 32983
+f 33031 33032 32983
+f 21565 21586 32984
+f 33032 21565 32984
+f 15149 31719 15150
+f 1783 9738 23008
+f 33033 32893 31922
+f 32340 15518 31405
+f 31900 15519 15518
+f 32893 32340 31405
+f 22438 62 61
+f 31969 31698 32693
+f 14411 14413 17617
+f 32694 32695 33021
+f 32052 32051 33034
+f 32051 32109 32985
+f 32559 31954 24594
+f 32120 15624 15719
+f 32400 32988 32991
+f 32375 32946 32947
+f 32184 9802 12458
+f 31650 31646 23093
+f 8678 3893 8679
+f 32082 32049 31767
+f 31707 32082 31767
+f 6 32402 7
+f 31767 32049 31768
+f 32049 32048 31768
+f 16979 17056 14348
+f 2564 9998 2562
+f 13054 17134 17133
+f 637 1364 5730
+f 28223 33035 32992
+f 26555 28223 32992
+f 33035 33036 32993
+f 32992 33035 32993
+f 33036 33037 13909
+f 32993 33036 13909
+f 33037 33038 13965
+f 13909 33037 13965
+f 33038 33039 32994
+f 13965 33038 32994
+f 33039 33040 32995
+f 32994 33039 32995
+f 33040 33041 32996
+f 32995 33040 32996
+f 33041 33042 32997
+f 32996 33041 32997
+f 33042 33043 32998
+f 32997 33042 32998
+f 33043 33044 32999
+f 32998 33043 32999
+f 33044 33045 33000
+f 32999 33044 33000
+f 33045 33046 33001
+f 33000 33045 33001
+f 33046 33047 33002
+f 33001 33046 33002
+f 33047 33048 33003
+f 33002 33047 33003
+f 33048 33049 33004
+f 33003 33048 33004
+f 33049 33050 33005
+f 33004 33049 33005
+f 33050 33051 33006
+f 33005 33050 33006
+f 33051 33052 33007
+f 33006 33051 33007
+f 33053 33008 33007
+f 33052 33053 33007
+f 33054 33009 33008
+f 33053 33054 33008
+f 33055 33010 33009
+f 33054 33055 33009
+f 33056 33011 33010
+f 33055 33056 33010
+f 33057 33012 33011
+f 33056 33057 33011
+f 33058 22870 33012
+f 33057 33058 33012
+f 14051 3218 6336
+f 33058 19429 22870
+f 15647 703 12062
+f 18942 27771 27773
+f 23880 19778 19780
+f 13399 13401 5776
+f 32811 32875 33059
+f 22154 33060 22155
+f 32871 32653 32827
+f 32031 32736 32826
+f 32144 32019 32726
+f 15793 27030 32684
+f 32705 32703 31359
+f 21026 31702 21027
+f 32340 31900 15518
+f 31899 3809 15519
+f 24285 31872 31874
+f 32703 29749 32831
+f 32100 22271 33018
+f 32101 32100 33018
+f 27790 30606 32009
+f 30605 32345 32002
+f 6611 33061 32378
+f 30606 30605 32002
+f 33061 33062 32392
+f 33062 32445 32392
+f 32125 33020 20379
+f 33063 32394 32445
+f 3237 21698 16178
+f 6242 21902 21901
+f 33064 33022 22753
+f 18683 33064 22753
+f 33064 33065 33023
+f 33022 33064 33023
+f 33066 33024 33023
+f 33065 33066 33023
+f 33067 33025 33024
+f 33066 33067 33024
+f 33068 33026 33025
+f 33067 33068 33025
+f 33069 33027 33026
+f 33068 33069 33026
+f 33070 33028 33027
+f 33069 33070 33027
+f 33071 33029 33028
+f 33070 33071 33028
+f 33071 33072 33030
+f 33029 33071 33030
+f 33073 33031 33030
+f 33072 33073 33030
+f 33074 33032 33031
+f 33073 33074 33031
+f 23078 21565 33032
+f 33074 23078 33032
+f 15238 32949 15239
+f 7564 14414 11221
+f 32893 31405 31922
+f 19028 6601 14704
+f 31711 31713 15517
+f 31712 33021 31713
+f 2919 32559 32246
+f 32875 32809 33059
+f 32052 33034 33017
+f 32055 32052 33017
+f 27541 27790 32008
+f 32051 32985 33034
+f 32417 3 2
+f 31783 27541 32615
+f 31646 31650 32207
+f 33075 32417 2
+f 31681 31674 31459
+f 31771 31623 31710
+f 32561 32868 31923
+f 32112 31785 17618
+f 4759 17623 32117
+f 32220 22321 32124
+f 8678 14391 31972
+f 33076 32614 32382
+f 26543 26460 25507
+f 21960 32745 22013
+f 28222 33077 28223
+f 25507 26269 26543
+f 33077 33078 33035
+f 28223 33077 33035
+f 33078 33079 33036
+f 33035 33078 33036
+f 33079 33080 33037
+f 33036 33079 33037
+f 33080 33081 33038
+f 33037 33080 33038
+f 33081 33082 33039
+f 33038 33081 33039
+f 33082 33083 33040
+f 33039 33082 33040
+f 33083 33084 33041
+f 33040 33083 33041
+f 33084 33085 33042
+f 33041 33084 33042
+f 33085 33086 33043
+f 33042 33085 33043
+f 33086 33087 33044
+f 33043 33086 33044
+f 33087 33088 33045
+f 33044 33087 33045
+f 33088 33089 33046
+f 33045 33088 33046
+f 33089 33090 33047
+f 33046 33089 33047
+f 33090 33091 33048
+f 33047 33090 33048
+f 33091 33092 33049
+f 33048 33091 33049
+f 33092 33093 33050
+f 33049 33092 33050
+f 33093 33094 33051
+f 33050 33093 33051
+f 33094 33095 33052
+f 33051 33094 33052
+f 33096 33053 33052
+f 33095 33096 33052
+f 33097 33054 33053
+f 33096 33097 33053
+f 33098 33055 33054
+f 33097 33098 33054
+f 33099 33056 33055
+f 33098 33099 33055
+f 33100 33057 33056
+f 33099 33100 33056
+f 33101 33058 33057
+f 33100 33101 33057
+f 33102 19429 33058
+f 33101 33102 33058
+f 18940 18942 28393
+f 33102 19430 19429
+f 3623 11336 17714
+f 28423 28443 28066
+f 32464 32733 32465
+f 6718 4388 30288
+f 32653 32031 32826
+f 32030 32734 32736
+f 10570 10572 31685
+f 31072 27328 8142
+f 17360 26411 17361
+f 15057 33103 15058
+f 33033 31922 29440
+f 33104 33033 29440
+f 30472 32969 33014
+f 22047 31781 22401
+f 32245 32193 20379
+f 8306 32245 20379
+f 31120 31312 32345
+f 6611 32378 13589
+f 32420 32417 33075
+f 33105 32420 33075
+f 32451 32424 33106
+f 32424 32420 33105
+f 33062 33063 32445
+f 33107 32424 33105
+f 23382 17601 16160
+f 33108 32395 32394
+f 18682 33064 18683
+f 9571 9568 9569
+f 18682 22799 33065
+f 33064 18682 33065
+f 33109 33066 33065
+f 22799 33109 33065
+f 33110 33067 33066
+f 33109 33110 33066
+f 33111 33068 33067
+f 33110 33111 33067
+f 33112 33069 33068
+f 33111 33112 33068
+f 33113 33070 33069
+f 33112 33113 33069
+f 33114 33071 33070
+f 33113 33114 33070
+f 33114 33115 33072
+f 33071 33114 33072
+f 33115 33116 33073
+f 33072 33115 33073
+f 33117 33074 33073
+f 33116 33117 33073
+f 33117 31885 23078
+f 33074 33117 23078
+f 2413 14016 10718
+f 5816 5817 12293
+f 10142 33118 14504
+f 7466 8915 5467
+f 20370 20372 32823
+f 11666 11667 11754
+f 32283 32244 8305
+f 4342 32283 8305
+f 8305 32244 8306
+f 32244 32245 8306
+f 32609 31931 31946
+f 30606 32002 32009
+f 32424 33107 33106
+f 32402 32991 7
+f 18011 32246 32367
+f 37 31810 23768
+f 32384 33076 32382
+f 33119 32450 33106
+f 31644 32207 32206
+f 31778 31846 31779
+f 33120 32206 31857
+f 32867 31908 16481
+f 31642 31644 32206
+f 17867 4765 16302
+f 14311 32994 26457
+f 17468 33121 28222
+f 17466 17468 28222
+f 33121 33122 33077
+f 28222 33121 33077
+f 33122 33123 33078
+f 33077 33122 33078
+f 33123 33124 33079
+f 33078 33123 33079
+f 33124 33125 33080
+f 33079 33124 33080
+f 33125 33126 33081
+f 33080 33125 33081
+f 33126 33127 33082
+f 33081 33126 33082
+f 33127 33128 33083
+f 33082 33127 33083
+f 33128 33129 33084
+f 33083 33128 33084
+f 33129 33130 33085
+f 33084 33129 33085
+f 33130 33131 33086
+f 33085 33130 33086
+f 33131 33132 33087
+f 33086 33131 33087
+f 33132 33133 33088
+f 33087 33132 33088
+f 33133 33134 33089
+f 33088 33133 33089
+f 33134 33135 33090
+f 33089 33134 33090
+f 33135 33136 33091
+f 33090 33135 33091
+f 33136 33137 33092
+f 33091 33136 33092
+f 33137 33138 33093
+f 33092 33137 33093
+f 33138 33139 33094
+f 33093 33138 33094
+f 33139 33140 33095
+f 33094 33139 33095
+f 33141 33096 33095
+f 33140 33141 33095
+f 33142 33097 33096
+f 33141 33142 33096
+f 33143 33098 33097
+f 33142 33143 33097
+f 33144 33099 33098
+f 33143 33144 33098
+f 33145 33100 33099
+f 33144 33145 33099
+f 33146 33101 33100
+f 33145 33146 33100
+f 17728 33102 33101
+f 33146 17728 33101
+f 13809 19430 33102
+f 17728 13809 33102
+f 32901 21458 33147
+f 3031 2834 3029
+f 32748 32872 31
+f 21017 32344 17989
+f 32031 32030 32736
+f 32750 32740 32734
+f 32944 14831 31068
+f 33103 29489 15058
+f 21387 32139 32486
+f 32139 32161 32486
+f 33104 29440 14412
+f 21523 33104 14412
+f 31780 4558 10306
+f 31697 20370 32823
+f 27425 32362 28834
+f 32321 32319 24777
+f 33061 32392 32378
+f 33063 33108 32394
+f 32469 32450 33148
+f 32450 32451 33106
+f 31650 31832 31831
+f 31407 32087 31681
+f 32450 33119 33148
+f 31642 32206 33120
+f 32469 33148 33149
+f 32472 32469 33149
+f 23250 1871 17726
+f 15152 15151 15192
+f 22400 22823 20464
+f 20464 22823 22822
+f 33150 33109 22799
+f 22798 33150 22799
+f 33151 33110 33109
+f 33150 33151 33109
+f 33152 33111 33110
+f 33151 33152 33110
+f 33153 33112 33111
+f 33152 33153 33111
+f 33154 33113 33112
+f 33153 33154 33112
+f 33155 33114 33113
+f 33154 33155 33113
+f 33155 33156 33115
+f 33114 33155 33115
+f 33157 33116 33115
+f 33156 33157 33115
+f 33157 33158 33117
+f 33116 33157 33117
+f 33158 33159 31885
+f 33117 33158 31885
+f 22823 24632 31885
+f 33159 22823 31885
+f 1785 18638 1783
+f 5155 2423 6365
+f 14922 15258 22647
+f 5040 6443 5595
+f 28834 32321 24777
+f 32319 32283 4342
+f 33160 32331 32396
+f 31659 32347 32399
+f 136 32473 134
+f 27790 32009 32008
+f 32115 32045 16
+f 32472 33149 33161
+f 32093 68 32248
+f 31640 31642 33120
+f 31699 31701 32045
+f 33162 33120 31860
+f 32473 33161 134
+f 15 32115 16
+f 11443 11444 11518
+f 32868 32832 32298
+f 26373 33163 17468
+f 15414 15910 15444
+f 33163 33164 33121
+f 17468 33163 33121
+f 33164 33165 33122
+f 33121 33164 33122
+f 33165 33166 33123
+f 33122 33165 33123
+f 33166 33167 33124
+f 33123 33166 33124
+f 33167 33168 33125
+f 33124 33167 33125
+f 33168 33169 33126
+f 33125 33168 33126
+f 33169 33170 33127
+f 33126 33169 33127
+f 33170 33171 33128
+f 33127 33170 33128
+f 33171 33172 33129
+f 33128 33171 33129
+f 33172 33173 33130
+f 33129 33172 33130
+f 33173 33174 33131
+f 33130 33173 33131
+f 33174 33175 33132
+f 33131 33174 33132
+f 33175 33176 33133
+f 33132 33175 33133
+f 33176 33177 33134
+f 33133 33176 33134
+f 33177 33178 33135
+f 33134 33177 33135
+f 33178 33179 33136
+f 33135 33178 33136
+f 33179 33180 33137
+f 33136 33179 33137
+f 33180 33181 33138
+f 33137 33180 33138
+f 33181 33182 33139
+f 33138 33181 33139
+f 33182 33183 33140
+f 33139 33182 33140
+f 33183 33184 33141
+f 33140 33183 33141
+f 33185 33142 33141
+f 33184 33185 33141
+f 33186 33143 33142
+f 33185 33186 33142
+f 33187 33144 33143
+f 33186 33187 33143
+f 33188 33145 33144
+f 33187 33188 33144
+f 33189 33146 33145
+f 33188 33189 33145
+f 4886 17728 33146
+f 33189 4886 33146
+f 28064 28066 27897
+f 3625 17808 16465
+f 16715 16716 6366
+f 15335 15307 13952
+f 51 33 31469
+f 31806 28524 32535
+f 32030 32750 32734
+f 31875 32741 32740
+f 21241 32744 32747
+f 27182 21241 32747
+f 32662 32325 32415
+f 32163 32660 32164
+f 21523 14412 14411
+f 21524 21523 14411
+f 29116 21026 21025
+f 29116 14907 21026
+f 23289 32381 27425
+f 32362 32321 28834
+f 33160 32396 32395
+f 32681 32312 32347
+f 33190 32509 151
+f 32477 149 151
+f 31357 17653 17655
+f 22798 3244 14744
+f 33191 32311 13660
+f 13659 33191 13660
+f 31638 31640 33162
+f 22351 12837 12836
+f 3748 3749 6743
+f 14135 27369 22505
+f 24943 24945 26448
+f 33192 33150 22798
+f 14744 33192 22798
+f 33193 33151 33150
+f 33192 33193 33150
+f 33194 33152 33151
+f 33193 33194 33151
+f 33195 33153 33152
+f 33194 33195 33152
+f 33196 33154 33153
+f 33195 33196 33153
+f 33197 33155 33154
+f 33196 33197 33154
+f 33198 33156 33155
+f 33197 33198 33155
+f 33199 33157 33156
+f 33198 33199 33156
+f 33199 33200 33158
+f 33157 33199 33158
+f 33200 33201 33159
+f 33158 33200 33159
+f 33201 22821 22823
+f 33159 33201 22823
+f 2423 12841 14459
+f 6365 2423 14459
+f 21347 21346 28324
+f 22507 22424 22368
+f 32383 32381 23289
+f 24777 32319 4342
+f 33108 33160 32395
+f 32331 31659 32399
+f 32509 32477 151
+f 32473 32472 33161
+f 33202 32335 32311
+f 33191 33202 32311
+f 1273 33203 21514
+f 32151 13951 15277
+f 33203 21512 21514
+f 11282 11368 11367
+f 33204 32341 32335
+f 33202 33204 32335
+f 15261 32727 15262
+f 33205 32771 32727
+f 22000 32792 22078
+f 21013 33206 26373
+f 22925 22847 26268
+f 33206 33207 33163
+f 26373 33206 33163
+f 33207 33208 33164
+f 33163 33207 33164
+f 33208 33209 33165
+f 33164 33208 33165
+f 33209 33210 33166
+f 33165 33209 33166
+f 33210 33211 33167
+f 33166 33210 33167
+f 33211 33212 33168
+f 33167 33211 33168
+f 33212 33213 33169
+f 33168 33212 33169
+f 33213 33214 33170
+f 33169 33213 33170
+f 33214 33215 33171
+f 33170 33214 33171
+f 33215 33216 33172
+f 33171 33215 33172
+f 33216 33217 33173
+f 33172 33216 33173
+f 33217 33218 33174
+f 33173 33217 33174
+f 33218 33219 33175
+f 33174 33218 33175
+f 33220 33176 33175
+f 33219 33220 33175
+f 33220 33221 33177
+f 33176 33220 33177
+f 33221 33222 33178
+f 33177 33221 33178
+f 33222 33223 33179
+f 33178 33222 33179
+f 33223 33224 33180
+f 33179 33223 33180
+f 33224 33225 33181
+f 33180 33224 33181
+f 33225 33226 33182
+f 33181 33225 33182
+f 33226 33227 33183
+f 33182 33226 33183
+f 33227 33228 33184
+f 33183 33227 33184
+f 33229 33185 33184
+f 33228 33229 33184
+f 33230 33186 33185
+f 33229 33230 33185
+f 33231 33187 33186
+f 33230 33231 33186
+f 33232 33188 33187
+f 33231 33232 33187
+f 22470 33189 33188
+f 33232 22470 33188
+f 22209 4886 33189
+f 22470 22209 33189
+f 7640 9146 20078
+f 8699 9500 6305
+f 17408 32777 32593
+f 26551 26552 21269
+f 31875 31874 32741
+f 31922 24433 24432
+f 32750 31875 32740
+f 31874 32738 32741
+f 15116 32110 15149
+f 317 14577 315
+f 32697 32466 32729
+f 32017 29420 35
+f 32682 33233 32774
+f 32334 32682 32774
+f 20380 31165 33015
+f 4503 32153 32370
+f 26872 32383 23289
+f 32381 32362 27425
+f 31659 32681 32347
+f 121 123 32312
+f 32527 32512 33234
+f 32509 33190 33235
+f 15261 33205 32727
+f 33236 32772 32771
+f 33205 33236 32771
+f 33237 32773 32772
+f 33236 33237 32772
+f 33238 32814 32773
+f 6483 21474 14210
+f 489 8722 14521
+f 14745 33192 14744
+f 20464 22822 2345
+f 33239 33193 33192
+f 14745 33239 33192
+f 33240 33194 33193
+f 33239 33240 33193
+f 33241 33195 33194
+f 33240 33241 33194
+f 33242 33196 33195
+f 33241 33242 33195
+f 33243 33197 33196
+f 33242 33243 33196
+f 33244 33198 33197
+f 33243 33244 33197
+f 33245 33199 33198
+f 33244 33245 33198
+f 33245 33246 33200
+f 33199 33245 33200
+f 33246 33247 33201
+f 33200 33246 33201
+f 33247 2727 22821
+f 33201 33247 22821
+f 12639 6955 12748
+f 22821 2727 22822
+f 24668 32387 24669
+f 22368 33248 22539
+f 32371 32370 32404
+f 32385 32383 26872
+f 32527 33234 7857
+f 32331 32399 32396
+f 33237 33238 32773
+f 6465 32527 7857
+f 33249 32815 32814
+f 22350 33250 32949
+f 32413 33251 31160
+f 31159 32413 31160
+f 33251 33252 867
+f 31160 33251 867
+f 33252 33253 1273
+f 867 33252 1273
+f 33253 33254 33203
+f 1273 33253 33203
+f 33254 22169 21512
+f 33203 33254 21512
+f 32949 15238 22350
+f 21689 20753 7465
+f 22198 22195 22196
+f 33238 33249 32814
+f 33255 32816 32815
+f 33249 33255 32815
+f 11139 16871 7670
+f 4887 22132 16279
+f 5823 33256 33206
+f 21013 5823 33206
+f 33256 33257 33207
+f 33206 33256 33207
+f 33257 33258 33208
+f 33207 33257 33208
+f 33258 33259 33209
+f 33208 33258 33209
+f 33259 33260 33210
+f 33209 33259 33210
+f 33260 33261 33211
+f 33210 33260 33211
+f 33261 33262 33212
+f 33211 33261 33212
+f 33262 33263 33213
+f 33212 33262 33213
+f 33263 33264 33214
+f 33213 33263 33214
+f 33264 33265 33215
+f 33214 33264 33215
+f 33265 33266 33216
+f 33215 33265 33216
+f 33266 33267 33217
+f 33216 33266 33217
+f 33267 33268 33218
+f 33217 33267 33218
+f 33268 33269 33219
+f 33218 33268 33219
+f 33270 33220 33219
+f 33269 33270 33219
+f 33270 33271 33221
+f 33220 33270 33221
+f 33271 33272 33222
+f 33221 33271 33222
+f 33272 33273 33223
+f 33222 33272 33223
+f 33273 33274 33224
+f 33223 33273 33224
+f 33274 33275 33225
+f 33224 33274 33225
+f 33275 33276 33226
+f 33225 33275 33226
+f 33276 33277 33227
+f 33226 33276 33227
+f 33277 33278 33228
+f 33227 33277 33228
+f 33279 33229 33228
+f 33278 33279 33228
+f 33280 33230 33229
+f 33279 33280 33229
+f 33281 33231 33230
+f 33280 33281 33230
+f 33282 33232 33231
+f 33281 33282 33231
+f 22471 22470 33232
+f 33282 22471 33232
+f 32858 32157 32829
+f 32829 28666 26458
+f 26715 26640 2265
+f 26470 26469 28224
+f 17133 17135 17272
+f 15389 15388 15414
+f 31873 32704 32738
+f 31874 31873 32738
+f 25733 32863 32862
+f 32696 25733 32862
+f 25733 27182 32863
+f 27182 32747 32863
+f 32818 33283 32874
+f 16049 16051 18964
+f 33284 17616 33233
+f 32682 33284 33233
+f 31988 29878 29877
+f 20541 32135 32133
+f 16275 32380 6719
+f 32337 32336 15873
+f 32681 121 32312
+f 6719 32337 15873
+f 32512 32509 33235
+f 130 32348 128
+f 33285 32853 32816
+f 31930 31751 32584
+f 33255 33285 32816
+f 33286 32854 32853
+f 33285 33286 32853
+f 24267 6519 20366
+f 31409 31928 24685
+f 15446 15388 15360
+f 24596 13250 387
+f 33287 33239 14745
+f 17713 33287 14745
+f 33288 33240 33239
+f 33287 33288 33239
+f 33289 33241 33240
+f 33288 33289 33240
+f 33290 33242 33241
+f 33289 33290 33241
+f 33291 33243 33242
+f 33290 33291 33242
+f 33292 33244 33243
+f 33291 33292 33243
+f 33293 33245 33244
+f 33292 33293 33244
+f 33293 33294 33246
+f 33245 33293 33246
+f 33294 33295 33247
+f 33246 33294 33247
+f 33295 3264 2728
+f 33247 33295 2727
+f 15969 11590 10917
+f 23421 23422 32029
+f 32387 32385 24669
+f 24669 32385 26872
+f 130 32371 32348
+f 32153 32530 32529
+f 11139 14640 11140
+f 32512 33235 33234
+f 33296 32855 32854
+f 33286 33296 32854
+f 32949 22363 15239
+f 25344 33297 32413
+f 5977 5821 5820
+f 33297 33298 33251
+f 32413 33297 33251
+f 33298 33299 33252
+f 33251 33298 33252
+f 33299 33300 33253
+f 33252 33299 33253
+f 33300 33301 33254
+f 33253 33300 33254
+f 33301 33302 22169
+f 33254 33301 22169
+f 33302 12836 6543
+f 22169 33302 6543
+f 12745 9446 21648
+f 6543 12836 6541
+f 20379 33020 20380
+f 5355 15910 21198
+f 33303 32888 32855
+f 33296 33303 32855
+f 33304 32889 32888
+f 33303 33304 32888
+f 33305 32890 32889
+f 33304 33305 32889
+f 5822 4812 4811
+f 20753 21689 17778
+f 5822 33306 33256
+f 5823 5822 33256
+f 33306 33307 33257
+f 33256 33306 33257
+f 33307 33308 33258
+f 33257 33307 33258
+f 33308 33309 33259
+f 33258 33308 33259
+f 33309 33310 33260
+f 33259 33309 33260
+f 33310 33311 33261
+f 33260 33310 33261
+f 33311 33312 33262
+f 33261 33311 33262
+f 33312 33313 33263
+f 33262 33312 33263
+f 33313 33314 33264
+f 33263 33313 33264
+f 33314 33315 33265
+f 33264 33314 33265
+f 33315 33316 33266
+f 33265 33315 33266
+f 33316 33317 33267
+f 33266 33316 33267
+f 33317 33318 33268
+f 33267 33317 33268
+f 33318 33319 33269
+f 33268 33318 33269
+f 33319 33320 33270
+f 33269 33319 33270
+f 33320 33321 33271
+f 33270 33320 33271
+f 33321 33322 33272
+f 33271 33321 33272
+f 33322 33323 33273
+f 33272 33322 33273
+f 33323 33324 33274
+f 33273 33323 33274
+f 33324 33325 33275
+f 33274 33324 33275
+f 33325 33326 33276
+f 33275 33325 33276
+f 33326 33327 33277
+f 33276 33326 33277
+f 33327 33328 33278
+f 33277 33327 33278
+f 33329 33279 33278
+f 33328 33329 33278
+f 33330 33280 33279
+f 33329 33330 33279
+f 33331 33281 33280
+f 33330 33331 33280
+f 33332 33282 33281
+f 33331 33332 33281
+f 21457 22471 33282
+f 33332 21457 33282
+f 33233 32775 14508
+f 32745 32744 5956
+f 17715 17714 23051
+f 32863 32747 4504
+f 31879 32702 32704
+f 31873 31879 32704
+f 32608 32778 32017
+f 32872 32608 32017
+f 32608 32696 32778
+f 32696 32862 32778
+f 32871 32870 32653
+f 32652 32031 32653
+f 17185 33333 17184
+f 32017 32778 29420
+f 21524 14411 17616
+f 33284 21524 17616
+f 32247 24593 31680
+f 24594 31946 31948
+f 32336 32361 15619
+f 15873 32336 15619
+f 24595 32406 32483
+f 31680 24595 32483
+f 32371 32404 32348
+f 32370 32153 32529
+f 27958 32158 14169
+f 451 16011 159
+f 33334 32916 32890
+f 33305 33334 32890
+f 33335 32917 32916
+f 33334 33335 32916
+f 15238 15237 22285
+f 15586 13399 5776
+f 25342 25344 31206
+f 16389 5772 5774
+f 33336 33287 17713
+f 17715 33336 17713
+f 33337 33288 33287
+f 33336 33337 33287
+f 33338 33289 33288
+f 33337 33338 33288
+f 33339 33290 33289
+f 33338 33339 33289
+f 33340 33291 33290
+f 33339 33340 33290
+f 33341 33292 33291
+f 33340 33341 33291
+f 33342 33293 33292
+f 33341 33342 33292
+f 33342 33343 33294
+f 33293 33342 33294
+f 33343 3264 33295
+f 33294 33343 33295
+f 12054 14062 20183
+f 24481 25045 32454
+f 32389 32387 24668
+f 21735 15609 16848
+f 31703 32532 32531
+f 15635 32389 24668
+f 12501 29470 29472
+f 32370 32529 32404
+f 33344 32918 32917
+f 32777 32776 32284
+f 33335 33344 32917
+f 28067 1704 30921
+f 33345 25344 25343
+f 31070 33345 25343
+f 33346 33297 25344
+f 33345 33346 25344
+f 33347 33298 33297
+f 33346 33347 33297
+f 33348 33299 33298
+f 33347 33348 33298
+f 33349 33300 33299
+f 33348 33349 33299
+f 33350 33301 33300
+f 33349 33350 33300
+f 33351 33302 33301
+f 33350 33351 33301
+f 33351 33352 12836
+f 33302 33351 12836
+f 22247 20369 22246
+f 22246 20369 22085
+f 13809 13808 19430
+f 20818 20817 32158
+f 16189 22202 20942
+f 2895 21468 2896
+f 33353 32919 32918
+f 22941 25663 27563
+f 33344 33353 32918
+f 33354 32945 32919
+f 14409 26556 26637
+f 33353 33354 32919
+f 22861 33355 5822
+f 31655 31657 31690
+f 33355 33356 33306
+f 5822 33355 33306
+f 33356 33357 33307
+f 33306 33356 33307
+f 33357 33358 33308
+f 33307 33357 33308
+f 33358 33359 33309
+f 33308 33358 33309
+f 33359 33360 33310
+f 33309 33359 33310
+f 33360 33361 33311
+f 33310 33360 33311
+f 33361 33362 33312
+f 33311 33361 33312
+f 33362 33363 33313
+f 33312 33362 33313
+f 33363 33364 33314
+f 33313 33363 33314
+f 33364 33365 33315
+f 33314 33364 33315
+f 33365 33366 33316
+f 33315 33365 33316
+f 33366 33367 33317
+f 33316 33366 33317
+f 33367 33368 33318
+f 33317 33367 33318
+f 33368 33369 33319
+f 33318 33368 33319
+f 33369 33370 33320
+f 33319 33369 33320
+f 33370 33371 33321
+f 33320 33370 33321
+f 33371 33372 33322
+f 33321 33371 33322
+f 33372 33373 33323
+f 33322 33372 33323
+f 33373 33374 33324
+f 33323 33373 33324
+f 33374 33375 33325
+f 33324 33374 33325
+f 33375 33376 33326
+f 33325 33375 33326
+f 33376 33377 33327
+f 33326 33376 33327
+f 33377 33378 33328
+f 33327 33377 33328
+f 33379 33329 33328
+f 33378 33379 33328
+f 33380 33330 33329
+f 33379 33380 33329
+f 33381 33331 33330
+f 33380 33381 33330
+f 33147 33332 33331
+f 33381 33147 33331
+f 21458 21457 33332
+f 33147 21458 33332
+f 28666 32829 32157
+f 7206 7205 6510
+f 32869 30285 30287
+f 32747 32746 4504
+f 31878 32701 32702
+f 31879 31878 32702
+f 32872 32017 34
+f 31 32872 34
+f 21785 30471 32611
+f 30472 33014 30473
+f 15059 15058 32300
+f 29489 31850 29490
+f 31775 32344 21017
+f 31766 31775 21017
+f 31775 32334 32344
+f 32334 32774 32344
+f 19778 31685 19779
+f 17866 25633 31920
+f 32361 32391 15634
+f 15634 32391 15635
+f 31724 31678 32482
+f 31680 32483 32533
+f 31958 16482 31590
+f 79 31733 59
+f 32440 32441 31748
+f 32144 32726 31990
+f 9252 22472 32945
+f 33354 9252 32945
+f 16104 6655 6390
+f 11089 21901 11090
+f 17715 11933 11935
+f 31972 13588 8678
+f 11932 11846 11935
+f 11935 33336 17715
+f 20896 23161 22548
+f 33382 33337 33336
+f 11935 33382 33336
+f 33383 33338 33337
+f 33382 33383 33337
+f 32650 33339 33338
+f 33383 32650 33338
+f 11446 33340 33339
+f 32650 11446 33339
+f 11445 33341 33340
+f 11446 11445 33340
+f 33384 33342 33341
+f 11445 33384 33341
+f 33385 33343 33342
+f 33384 33385 33342
+f 33385 3265 3264
+f 33343 33385 3264
+f 17052 17054 22748
+f 2850 3265 3057
+f 32380 32337 6719
+f 5500 21574 26635
+f 32152 32531 32530
+f 32152 31703 32531
+f 31164 17115 17117
+f 33103 32640 29489
+f 13659 18385 18387
+f 14707 16722 13963
+f 25068 642 25124
+f 1704 28067 1702
+f 33386 33345 31070
+f 31071 33386 31070
+f 33387 33346 33345
+f 33386 33387 33345
+f 33388 33347 33346
+f 33387 33388 33346
+f 33389 33348 33347
+f 33388 33389 33347
+f 33390 33349 33348
+f 33389 33390 33348
+f 33391 33350 33349
+f 33390 33391 33349
+f 33392 33351 33350
+f 33391 33392 33350
+f 33392 33393 33352
+f 33351 33392 33352
+f 33393 28678 22351
+f 33352 33393 22351
+f 12847 2533 2532
+f 13487 934 2951
+f 3510 842 807
+f 9105 32617 17124
+f 10962 10961 16769
+f 33394 13659 18387
+f 17087 32989 10961
+f 22861 22860 31357
+f 11869 16769 16869
+f 28393 18942 27773
+f 31357 33395 33355
+f 22861 31357 33355
+f 33395 33396 33356
+f 33355 33395 33356
+f 33396 33397 33357
+f 33356 33396 33357
+f 33397 33398 33358
+f 33357 33397 33358
+f 33398 33399 33359
+f 33358 33398 33359
+f 33399 33400 33360
+f 33359 33399 33360
+f 33400 33401 33361
+f 33360 33400 33361
+f 33401 33402 33362
+f 33361 33401 33362
+f 33402 33403 33363
+f 33362 33402 33363
+f 33403 33404 33364
+f 33363 33403 33364
+f 33404 33405 33365
+f 33364 33404 33365
+f 33405 33406 33366
+f 33365 33405 33366
+f 33406 33407 33367
+f 33366 33406 33367
+f 33407 33408 33368
+f 33367 33407 33368
+f 33408 33409 33369
+f 33368 33408 33369
+f 33409 33410 33370
+f 33369 33409 33370
+f 33410 33411 33371
+f 33370 33410 33371
+f 33411 33412 33372
+f 33371 33411 33372
+f 33412 33413 33373
+f 33372 33412 33373
+f 33413 33414 33374
+f 33373 33413 33374
+f 33414 33415 33375
+f 33374 33414 33375
+f 33415 33416 33376
+f 33375 33415 33376
+f 33416 33417 33377
+f 33376 33416 33377
+f 33417 33418 33378
+f 33377 33417 33378
+f 33419 33379 33378
+f 33418 33419 33378
+f 33420 33380 33379
+f 33419 33420 33379
+f 33421 33381 33380
+f 33420 33421 33380
+f 33422 33147 33381
+f 33421 33422 33381
+f 33422 32901 33147
+f 21458 32901 21987
+f 9566 9565 19951
+f 5633 5632 22348
+f 19604 31069 32739
+f 12706 33423 12707
+f 32165 32699 32701
+f 31878 32165 32701
+f 54 51 32754
+f 22828 54 32754
+f 33424 33425 32892
+f 32891 33424 32892
+f 32199 21016 17358
+f 32001 32199 17358
+f 32199 31766 21016
+f 31766 21017 21016
+f 18965 20541 32133
+f 29156 32137 32135
+f 18965 32133 16941
+f 16940 18965 16941
+f 15619 32361 15634
+f 32391 32389 15635
+f 31724 32482 32532
+f 31678 31680 32533
+f 31928 32584 24685
+f 32285 31852 31851
+f 6542 6541 22241
+f 31636 31638 33426
+f 5272 5123 5270
+f 31634 31636 33427
+f 31640 33120 33162
+f 31164 17117 32656
+f 32095 31406 31937
+f 16011 152 159
+f 32641 32040 32873
+f 11846 33382 11935
+f 14391 13309 32481
+f 11755 33383 33382
+f 11846 11755 33382
+f 14238 32650 33383
+f 11755 14238 33383
+f 14238 11518 32650
+f 11446 11518 11444
+f 11366 11445 11444
+f 22291 23247 22142
+f 11368 33384 11445
+f 25743 12377 8123
+f 32824 33385 33384
+f 11368 32824 33384
+f 1955 32638 1956
+f 33385 32824 3265
+f 2832 17361 30816
+f 32745 5956 22013
+f 31947 32416 32405
+f 16274 32379 16275
+f 16009 32221 22625
+f 32153 32152 32530
+f 33428 32342 32341
+f 32640 33429 31848
+f 31638 33162 33426
+f 30956 30344 25987
+f 33430 31071 22713
+f 22709 33430 22713
+f 33431 33386 31071
+f 33430 33431 31071
+f 33432 33387 33386
+f 33431 33432 33386
+f 33433 33388 33387
+f 33432 33433 33387
+f 33434 33389 33388
+f 33433 33434 33388
+f 33435 33390 33389
+f 33434 33435 33389
+f 33436 33391 33390
+f 33435 33436 33390
+f 33437 33392 33391
+f 33436 33437 33391
+f 33438 33393 33392
+f 33437 33438 33392
+f 33439 28678 33393
+f 33438 33439 33393
+f 33250 22350 28678
+f 33439 33250 28678
+f 23479 23462 28159
+f 16870 10961 32989
+f 33204 33428 32341
+f 17654 28385 17550
+f 33440 32372 32342
+f 31632 31634 29878
+f 15277 15241 15192
+f 11336 3623 3808
+f 17655 33441 33395
+f 31357 17655 33395
+f 33441 33442 33396
+f 33395 33441 33396
+f 33442 33443 33397
+f 33396 33442 33397
+f 33443 33444 33398
+f 33397 33443 33398
+f 33444 33445 33399
+f 33398 33444 33399
+f 33445 33446 33400
+f 33399 33445 33400
+f 33446 33447 33401
+f 33400 33446 33401
+f 33447 33448 33402
+f 33401 33447 33402
+f 33448 33449 33403
+f 33402 33448 33403
+f 33449 33450 33404
+f 33403 33449 33404
+f 33450 33451 33405
+f 33404 33450 33405
+f 33451 33452 33406
+f 33405 33451 33406
+f 33452 33453 33407
+f 33406 33452 33407
+f 33453 33454 33408
+f 33407 33453 33408
+f 33454 33455 33409
+f 33408 33454 33409
+f 33455 33456 33410
+f 33409 33455 33410
+f 33456 33457 33411
+f 33410 33456 33411
+f 33457 33458 33412
+f 33411 33457 33412
+f 33458 33459 33413
+f 33412 33458 33413
+f 33459 33460 33414
+f 33413 33459 33414
+f 33460 33461 33415
+f 33414 33460 33415
+f 33461 33462 33416
+f 33415 33461 33416
+f 33462 33463 33417
+f 33416 33462 33417
+f 33464 33418 33417
+f 33463 33464 33417
+f 33464 33465 33419
+f 33418 33464 33419
+f 33466 33420 33419
+f 33465 33466 33419
+f 33467 33421 33420
+f 33466 33467 33420
+f 33468 33422 33421
+f 33467 33468 33421
+f 8207 9204 529
+f 33468 33469 33422
+f 26282 26281 17467
+f 2834 3031 12763
+f 21926 32873 21927
+f 21458 21987 21459
+f 32164 32700 32699
+f 32165 32164 32699
+f 22828 32754 31211
+f 30430 22828 31211
+f 33016 32229 33470
+f 33471 33016 33470
+f 32001 17358 14908
+f 31760 32001 14908
+f 32137 29156 32138
+f 12067 12069 32160
+f 20541 29156 32135
+f 29156 12067 32138
+f 32503 32443 17895
+f 32379 16274 25619
+f 32443 32379 25619
+f 32379 32380 16275
+f 31703 31724 32532
+f 31678 32533 32482
+f 31161 17121 19758
+f 33429 33472 31848
+f 33428 33440 32342
+f 31644 31646 32207
+f 31646 14778 23093
+f 32112 17618 18981
+f 31881 31714 31755
+f 4343 8307 31774
+f 20380 33015 31773
+f 32388 33473 32386
+f 22321 4757 32124
+f 31737 33284 32682
+f 32649 31209 32343
+f 1870 16883 6259
+f 32222 32223 32683
+f 18123 16308 16303
+f 11755 11667 14238
+f 6722 15848 19298
+f 11844 11845 11932
+f 32215 32242 18337
+f 26554 26637 26471
+f 26281 26373 17467
+f 9489 16376 9490
+f 6103 22957 32825
+f 31947 31932 32416
+f 5026 5025 8289
+f 24703 21717 21719
+f 32147 32453 32468
+f 21572 17053 26552
+f 31932 32468 32416
+f 31932 32147 32468
+f 32329 25548 32334
+f 31948 31947 32405
+f 31855 14731 14733
+f 31984 27 31778
+f 33474 33076 32384
+f 30991 30956 24990
+f 18119 30991 24990
+f 33475 33430 22709
+f 27642 33475 22709
+f 33476 33431 33430
+f 33475 33476 33430
+f 33477 33432 33431
+f 33476 33477 33431
+f 33478 33433 33432
+f 33477 33478 33432
+f 33479 33434 33433
+f 33478 33479 33433
+f 33480 33435 33434
+f 33479 33480 33434
+f 33481 33436 33435
+f 33480 33481 33435
+f 33482 33437 33436
+f 33481 33482 33436
+f 33483 33438 33437
+f 33482 33483 33437
+f 33484 33439 33438
+f 33483 33484 33438
+f 22465 33250 33439
+f 33484 22465 33439
+f 33250 22465 22402
+f 31258 27739 31256
+f 11282 32824 11368
+f 5684 5976 5820
+f 31632 29878 31988
+f 31808 21980 31814
+f 33485 32373 32372
+f 17654 17054 17655
+f 456 30101 17317
+f 17054 33486 33441
+f 17655 17054 33441
+f 33486 33487 33442
+f 33441 33486 33442
+f 33487 33488 33443
+f 33442 33487 33443
+f 33488 33489 33444
+f 33443 33488 33444
+f 33489 33490 33445
+f 33444 33489 33445
+f 33490 33491 33446
+f 33445 33490 33446
+f 33491 33492 33447
+f 33446 33491 33447
+f 33492 33493 33448
+f 33447 33492 33448
+f 33493 33494 33449
+f 33448 33493 33449
+f 33494 33495 33450
+f 33449 33494 33450
+f 33495 33496 33451
+f 33450 33495 33451
+f 33496 33497 33452
+f 33451 33496 33452
+f 33498 33453 33452
+f 33497 33498 33452
+f 33499 33454 33453
+f 33498 33499 33453
+f 33499 33500 33455
+f 33454 33499 33455
+f 33500 33501 33456
+f 33455 33500 33456
+f 33501 33502 33457
+f 33456 33501 33457
+f 33502 33503 33458
+f 33457 33502 33458
+f 33503 33504 33459
+f 33458 33503 33459
+f 33504 33505 33460
+f 33459 33504 33460
+f 33505 33506 33461
+f 33460 33505 33461
+f 33506 33507 33462
+f 33461 33506 33462
+f 33507 33508 33463
+f 33462 33507 33463
+f 33508 33509 33464
+f 33463 33508 33464
+f 33510 33465 33464
+f 33509 33510 33464
+f 33511 33466 33465
+f 33510 33511 33465
+f 33512 33467 33466
+f 33511 33512 33466
+f 33513 33468 33467
+f 33512 33513 33467
+f 33514 33469 33468
+f 33513 33514 33468
+f 33515 22247 33469
+f 33514 33515 33469
+f 26182 15221 26281
+f 33515 20369 22247
+f 15129 22646 16549
+f 31971 5230 5229
+f 30430 31211 31210
+f 33516 30430 31210
+f 32632 32970 32633
+f 33471 33470 32971
+f 31760 14908 32733
+f 31761 31760 32733
+f 32138 12067 32160
+f 12069 32915 32190
+f 32502 32448 16049
+f 32503 17895 16050
+f 32443 25619 17895
+f 32448 32503 16050
+f 71 70 32453
+f 32147 71 32453
+f 31948 32405 32406
+f 24595 31948 32406
+f 31409 24685 24684
+f 2179 21306 6484
+f 13585 10917 11590
+f 32349 1869 23250
+f 31630 31632 31988
+f 33440 33485 32372
+f 33118 32374 32373
+f 33485 33118 32373
+f 14700 32528 32374
+f 33118 14700 32374
+f 32102 17547 14756
+f 16227 32332 16326
+f 21359 15598 21360
+f 17335 29579 6751
+f 17102 32184 12458
+f 17412 17414 21146
+f 32546 32548 21745
+f 25732 21242 21241
+f 32932 31901 31208
+f 31743 32592 31744
+f 31909 30515 4764
+f 21016 17988 30990
+f 32166 17725 16301
+f 32043 27759 27758
+f 31818 27715 30198
+f 32343 31818 30198
+f 5960 16910 28206
+f 31745 32041 16364
+f 16879 30059 27394
+f 28205 5960 28206
+f 33517 32575 33518
+f 32479 24741 32480
+f 33283 32728 32730
+f 33519 27642 27641
+f 30237 33519 27641
+f 33520 33475 27642
+f 33519 33520 27642
+f 33521 33476 33475
+f 33520 33521 33475
+f 33522 33477 33476
+f 33521 33522 33476
+f 33523 33478 33477
+f 33522 33523 33477
+f 33524 33479 33478
+f 33523 33524 33478
+f 33525 33480 33479
+f 33524 33525 33479
+f 33526 33481 33480
+f 33525 33526 33480
+f 33527 33482 33481
+f 33526 33527 33481
+f 33528 33483 33482
+f 33527 33528 33482
+f 33529 33484 33483
+f 33528 33529 33483
+f 33530 22465 33484
+f 33529 33530 33484
+f 33530 33531 22370
+f 22465 33530 22370
+f 9264 22553 23208
+f 33531 22368 22370
+f 31670 32034 32098
+f 29115 21025 4501
+f 33532 33205 15261
+f 14991 33532 15261
+f 33533 22198 33013
+f 15116 15114 15086
+f 17053 21572 33486
+f 17054 17053 33486
+f 21572 33534 33487
+f 33486 21572 33487
+f 33534 33535 33488
+f 33487 33534 33488
+f 33535 33536 33489
+f 33488 33535 33489
+f 33536 33537 33490
+f 33489 33536 33490
+f 33537 33538 33491
+f 33490 33537 33491
+f 33538 33539 33492
+f 33491 33538 33492
+f 33539 33540 33493
+f 33492 33539 33493
+f 33540 33541 33494
+f 33493 33540 33494
+f 33541 33542 33495
+f 33494 33541 33495
+f 33542 33543 33496
+f 33495 33542 33496
+f 33543 33544 33497
+f 33496 33543 33497
+f 33544 33545 33498
+f 33497 33544 33498
+f 33546 33499 33498
+f 33545 33546 33498
+f 33547 33500 33499
+f 33546 33547 33499
+f 33547 33548 33501
+f 33500 33547 33501
+f 33548 33549 33502
+f 33501 33548 33502
+f 33549 33550 33503
+f 33502 33549 33503
+f 33550 33551 33504
+f 33503 33550 33504
+f 33551 33552 33505
+f 33504 33551 33505
+f 33552 33553 33506
+f 33505 33552 33506
+f 33553 33554 33507
+f 33506 33553 33507
+f 33554 33555 33508
+f 33507 33554 33508
+f 33555 33556 33509
+f 33508 33555 33509
+f 33556 33557 33510
+f 33509 33556 33510
+f 33558 33511 33510
+f 33557 33558 33510
+f 33559 33512 33511
+f 33558 33559 33511
+f 33559 33560 33513
+f 33512 33559 33513
+f 33560 33561 33514
+f 33513 33560 33514
+f 33561 33562 33515
+f 33514 33561 33515
+f 33562 20368 20369
+f 33515 33562 20369
+f 11081 11080 28663
+f 17827 2650 4796
+f 20818 32158 27588
+f 28133 6940 6941
+f 29753 31743 29754
+f 32970 33471 32971
+f 31761 32733 32464
+f 31716 31761 32464
+f 32160 12069 32190
+f 22749 32218 32190
+f 32505 32502 22999
+f 32448 16050 16049
+f 31694 31722 32579
+f 31721 32583 32637
+f 31684 32513 14
+f 13 31684 14
+f 32752 33563 33060
+f 31810 31812 23768
+f 31821 32090 31822
+f 32735 15793 15792
+f 17602 550 19599
+f 37 23768 38
+f 32225 32852 32369
+f 32852 4501 4503
+f 33564 33236 33205
+f 33532 33564 33205
+f 33565 33237 33236
+f 33564 33565 33236
+f 31112 31113 21746
+f 33566 32278 21198
+f 33567 33238 33237
+f 32278 33566 33568
+f 33565 33567 33237
+f 33569 33249 33238
+f 33567 33569 33238
+f 33570 33255 33249
+f 33569 33570 33249
+f 33571 33285 33255
+f 33570 33571 33255
+f 33572 33286 33285
+f 33571 33572 33285
+f 33573 33296 33286
+f 33572 33573 33286
+f 33574 33303 33296
+f 33573 33574 33296
+f 33575 33304 33303
+f 33574 33575 33303
+f 30236 33576 30237
+f 33577 33519 30237
+f 33576 33577 30237
+f 33578 33520 33519
+f 33577 33578 33519
+f 33579 33521 33520
+f 33578 33579 33520
+f 33580 33522 33521
+f 33579 33580 33521
+f 33581 33523 33522
+f 33580 33581 33522
+f 33582 33524 33523
+f 33581 33582 33523
+f 33583 33525 33524
+f 33582 33583 33524
+f 33584 33526 33525
+f 33583 33584 33525
+f 33585 33527 33526
+f 33584 33585 33526
+f 33586 33528 33527
+f 33585 33586 33527
+f 33587 33529 33528
+f 33586 33587 33528
+f 33588 33530 33529
+f 33587 33588 33529
+f 33589 33531 33530
+f 33588 33589 33530
+f 33589 33248 22368
+f 33531 33589 22368
+f 21919 21920 21763
+f 26552 26634 21573
+f 33590 33305 33304
+f 33575 33590 33304
+f 16403 17517 16404
+f 21572 21574 33534
+f 2264 26716 26715
+f 26711 21574 5500
+f 29179 22906 27498
+f 26715 2265 2264
+f 26711 33591 33535
+f 33534 26711 33535
+f 33591 33592 33536
+f 33535 33591 33536
+f 33592 33593 33537
+f 33536 33592 33537
+f 33593 33594 33538
+f 33537 33593 33538
+f 33594 33595 33539
+f 33538 33594 33539
+f 33595 33596 33540
+f 33539 33595 33540
+f 33596 33597 33541
+f 33540 33596 33541
+f 33597 33598 33542
+f 33541 33597 33542
+f 33598 33599 33543
+f 33542 33598 33543
+f 33599 33600 33544
+f 33543 33599 33544
+f 33600 33601 33545
+f 33544 33600 33545
+f 33601 33602 33546
+f 33545 33601 33546
+f 33602 33603 33547
+f 33546 33602 33547
+f 33603 33604 33548
+f 33547 33603 33548
+f 33604 33605 33549
+f 33548 33604 33549
+f 33605 33606 33550
+f 33549 33605 33550
+f 33606 33607 33551
+f 33550 33606 33551
+f 33607 33608 33552
+f 33551 33607 33552
+f 33608 33609 33553
+f 33552 33608 33553
+f 33609 33610 33554
+f 33553 33609 33554
+f 33610 33611 33555
+f 33554 33610 33555
+f 33611 33612 33556
+f 33555 33611 33556
+f 33613 33557 33556
+f 33612 33613 33556
+f 33613 33614 33558
+f 33557 33613 33558
+f 33614 33615 33559
+f 33558 33614 33559
+f 33616 33560 33559
+f 33615 33616 33559
+f 33616 33617 33561
+f 33560 33616 33561
+f 33617 33618 33562
+f 33561 33617 33562
+f 33618 33619 20368
+f 33562 33618 20368
+f 9688 21728 20368
+f 33619 9688 20368
+f 25581 11080 11082
+f 21401 33620 33621
+f 31621 20382 17437
+f 15607 15609 21502
+f 31716 32464 32697
+f 31871 31716 32697
+f 32915 22749 32190
+f 22749 30288 32243
+f 17712 32505 17652
+f 32502 16049 22999
+f 31722 31721 32637
+f 31989 32508 32583
+f 32943 33568 33622
+f 32946 32943 33622
+f 32946 33622 33623
+f 32947 32946 33623
+f 33624 33334 33305
+f 33590 33624 33305
+f 33625 33335 33334
+f 33624 33625 33334
+f 32947 33623 33626
+f 32988 32947 33626
+f 33627 33344 33335
+f 33625 33627 33335
+f 33628 33353 33344
+f 33627 33628 33344
+f 7 32991 8
+f 32988 33626 8
+f 32943 32278 33568
+f 27637 16314 16313
+f 24914 33354 33353
+f 33629 33075 33630
+f 33628 24914 33353
+f 33631 33576 30236
+f 29699 33631 30236
+f 33632 33577 33576
+f 33631 33632 33576
+f 33633 33578 33577
+f 33632 33633 33577
+f 33634 33579 33578
+f 33633 33634 33578
+f 33635 33580 33579
+f 33634 33635 33579
+f 33636 33581 33580
+f 33635 33636 33580
+f 33637 33582 33581
+f 33636 33637 33581
+f 33638 33583 33582
+f 33637 33638 33582
+f 33639 33584 33583
+f 33638 33639 33583
+f 33640 33585 33584
+f 33639 33640 33584
+f 33641 33586 33585
+f 33640 33641 33585
+f 33642 33587 33586
+f 33641 33642 33586
+f 33643 33588 33587
+f 33642 33643 33587
+f 33644 33589 33588
+f 33643 33644 33588
+f 33644 22636 33248
+f 33589 33644 33248
+f 33248 22636 22539
+f 2354 9781 5311
+f 9253 9252 33354
+f 39 14755 40
+f 24914 9253 33354
+f 4435 5500 4433
+f 32299 2584 29015
+f 31924 32299 29015
+f 32155 32768 32154
+f 15277 15150 31719
+f 12543 32356 33591
+f 26711 12543 33591
+f 32356 33645 33592
+f 33591 32356 33592
+f 33645 33646 33593
+f 33592 33645 33593
+f 33646 33647 33594
+f 33593 33646 33594
+f 33647 33648 33595
+f 33594 33647 33595
+f 33648 33649 33596
+f 33595 33648 33596
+f 33650 33597 33596
+f 33649 33650 33596
+f 33651 33598 33597
+f 33650 33651 33597
+f 33651 33652 33599
+f 33598 33651 33599
+f 33652 33653 33600
+f 33599 33652 33600
+f 33653 33654 33601
+f 33600 33653 33601
+f 33654 33655 33602
+f 33601 33654 33602
+f 33656 33603 33602
+f 33655 33656 33602
+f 33657 33604 33603
+f 33656 33657 33603
+f 33657 33658 33605
+f 33604 33657 33605
+f 33658 33659 33606
+f 33605 33658 33606
+f 33659 33660 33607
+f 33606 33659 33607
+f 33660 33661 33608
+f 33607 33660 33608
+f 33661 33662 33609
+f 33608 33661 33609
+f 33662 33663 33610
+f 33609 33662 33610
+f 33663 33664 33611
+f 33610 33663 33611
+f 33664 33665 33612
+f 33611 33664 33612
+f 33665 33666 33613
+f 33612 33665 33613
+f 33666 33667 33614
+f 33613 33666 33614
+f 33667 33668 33615
+f 33614 33667 33615
+f 33668 33669 33616
+f 33615 33668 33616
+f 33669 33670 33617
+f 33616 33669 33617
+f 33670 33671 33618
+f 33617 33670 33618
+f 33671 33672 33619
+f 33618 33671 33619
+f 33672 9686 9688
+f 33619 33672 9688
+f 32687 21401 33621
+f 21401 32687 12705
+f 13953 15241 15277
+f 32689 14577 317
+f 31871 32697 32728
+f 31756 31871 32728
+f 32218 22749 32243
+f 4390 32433 32243
+f 32004 27440 32582
+f 32505 22999 17652
+f 31721 31989 32583
+f 31120 25110 31312
+f 33106 33107 33673
+f 33107 33105 33674
+f 22539 22585 22540
+f 32752 32577 33563
+f 32364 32305 32365
+f 32048 32059 32205
+f 31768 32048 32205
+f 31627 27353 31587
+f 33107 33675 33673
+f 33120 31857 31860
+f 32207 31831 31836
+f 31700 31727 31701
+f 33119 33106 33676
+f 32115 31699 32045
+f 31694 32579 32513
+f 32991 32988 8
+f 31722 32637 32579
+f 31684 31694 32513
+f 33105 33075 33629
+f 33630 2 1
+f 32093 32248 31940
+f 32092 32093 31940
+f 23857 17897 146
+f 32206 31836 31857
+f 33426 33162 31867
+f 31628 31587 17739
+f 33677 33631 29699
+f 30337 33677 29699
+f 33678 33632 33631
+f 33677 33678 33631
+f 33679 33633 33632
+f 33678 33679 33632
+f 33680 33634 33633
+f 33679 33680 33633
+f 33681 33635 33634
+f 33680 33681 33634
+f 33682 33636 33635
+f 33681 33682 33635
+f 33683 33637 33636
+f 33682 33683 33636
+f 33684 33638 33637
+f 33683 33684 33637
+f 33685 33639 33638
+f 33684 33685 33638
+f 33686 33640 33639
+f 33685 33686 33639
+f 33687 33641 33640
+f 33686 33687 33640
+f 33688 33642 33641
+f 33687 33688 33641
+f 33689 33643 33642
+f 33688 33689 33642
+f 33690 33644 33643
+f 33689 33690 33643
+f 8584 22636 33644
+f 33690 8584 33644
+f 20578 20253 20579
+f 17890 6946 6945
+f 33106 33673 33676
+f 32356 12543 4434
+f 33394 33191 13659
+f 31811 17119 31812
+f 32102 19758 17547
+f 31636 33426 33427
+f 9473 3537 3536
+f 9105 32698 32129
+f 33469 32901 33422
+f 16828 27370 25202
+f 20261 33691 33645
+f 32356 20261 33645
+f 33691 33692 33646
+f 33645 33691 33646
+f 33692 33693 33647
+f 33646 33692 33647
+f 33693 33694 33648
+f 33647 33693 33648
+f 33694 33695 33649
+f 33648 33694 33649
+f 33695 33696 33650
+f 33649 33695 33650
+f 33696 33697 33651
+f 33650 33696 33651
+f 33697 33698 33652
+f 33651 33697 33652
+f 33699 33653 33652
+f 33698 33699 33652
+f 33700 33654 33653
+f 33699 33700 33653
+f 33701 33655 33654
+f 33700 33701 33654
+f 33702 33656 33655
+f 33701 33702 33655
+f 33703 33657 33656
+f 33702 33703 33656
+f 33703 33704 33658
+f 33657 33703 33658
+f 33704 33705 33659
+f 33658 33704 33659
+f 33705 33706 33660
+f 33659 33705 33660
+f 33706 33707 33661
+f 33660 33706 33661
+f 33707 33708 33662
+f 33661 33707 33662
+f 33708 33709 33663
+f 33662 33708 33663
+f 33709 33710 33664
+f 33663 33709 33664
+f 33711 33665 33664
+f 33710 33711 33664
+f 33711 33712 33666
+f 33665 33711 33666
+f 33712 33713 33667
+f 33666 33712 33667
+f 33713 33714 33668
+f 33667 33713 33668
+f 33714 33715 33669
+f 33668 33714 33669
+f 33715 33716 33670
+f 33669 33715 33670
+f 33716 33717 33671
+f 33670 33716 33671
+f 33717 33718 33672
+f 33671 33717 33672
+f 33718 33719 9686
+f 33672 33718 9686
+f 33719 2180 9687
+f 9686 33719 9687
+f 21513 22107 22033
+f 17213 17215 16264
+f 31750 31756 33283
+f 27584 17602 17601
+f 30288 4390 32243
+f 31790 32434 32433
+f 32010 32582 32604
+f 32616 32010 32604
+f 25110 25109 16175
+f 32119 16280 15624
+f 33149 33148 33720
+f 33119 33676 33721
+f 30992 31743 31745
+f 31744 27758 32041
+f 32770 31804 31853
+f 31805 15792 31806
+f 33722 33723 32322
+f 32359 33722 32322
+f 31411 33724 32390
+f 32386 33474 32384
+f 32 30817 36
+f 33161 33725 135
+f 134 33161 135
+f 31901 31903 27713
+f 31989 13952 13951
+f 32508 31989 13951
+f 31954 31946 24594
+f 33674 33105 33629
+f 33075 2 33630
+f 33190 151 150
+f 33675 33107 33674
+f 16641 29753 16642
+f 33726 33190 150
+f 31710 31625 17738
+f 30338 33727 30337
+f 33728 33677 30337
+f 33727 33728 30337
+f 33729 33678 33677
+f 33728 33729 33677
+f 33730 33679 33678
+f 33729 33730 33678
+f 33731 33680 33679
+f 33730 33731 33679
+f 33732 33681 33680
+f 33731 33732 33680
+f 33733 33682 33681
+f 33732 33733 33681
+f 33734 33683 33682
+f 33733 33734 33682
+f 33735 33684 33683
+f 33734 33735 33683
+f 33736 33685 33684
+f 33735 33736 33684
+f 33737 33686 33685
+f 33736 33737 33685
+f 33738 33687 33686
+f 33737 33738 33686
+f 33739 33688 33687
+f 33738 33739 33687
+f 33740 33689 33688
+f 33739 33740 33688
+f 33741 33690 33689
+f 33740 33741 33689
+f 8582 8584 33690
+f 33741 8582 33690
+f 19844 20026 16264
+f 16264 17215 19844
+f 21787 23161 20896
+f 18338 18282 18387
+f 31634 33427 29878
+f 14507 14509 21477
+f 33742 33202 33191
+f 33394 33742 33191
+f 32831 32346 32685
+f 32932 32560 31901
+f 22748 17054 17654
+f 2180 32737 2178
+f 20261 8979 33691
+f 22776 22660 22726
+f 32973 33743 33692
+f 33691 32973 33692
+f 33743 33744 33693
+f 33692 33743 33693
+f 33744 33745 33694
+f 33693 33744 33694
+f 33745 33746 33695
+f 33694 33745 33695
+f 33746 33747 33696
+f 33695 33746 33696
+f 33748 33697 33696
+f 33747 33748 33696
+f 33749 33698 33697
+f 33748 33749 33697
+f 33750 33699 33698
+f 33749 33750 33698
+f 33750 33751 33700
+f 33699 33750 33700
+f 33752 33701 33700
+f 33751 33752 33700
+f 33753 33702 33701
+f 33752 33753 33701
+f 33754 33703 33702
+f 33753 33754 33702
+f 33755 33704 33703
+f 33754 33755 33703
+f 33755 33756 33705
+f 33704 33755 33705
+f 33757 33706 33705
+f 33756 33757 33705
+f 33758 33707 33706
+f 33757 33758 33706
+f 33758 33759 33708
+f 33707 33758 33708
+f 33759 33760 33709
+f 33708 33759 33709
+f 33760 33761 33710
+f 33709 33760 33710
+f 33761 33762 33711
+f 33710 33761 33711
+f 33762 33763 33712
+f 33711 33762 33712
+f 33763 33764 33713
+f 33712 33763 33713
+f 33764 33765 33714
+f 33713 33764 33714
+f 33765 33766 33715
+f 33714 33765 33715
+f 33766 33767 33716
+f 33715 33766 33716
+f 33767 33768 33717
+f 33716 33767 33717
+f 33768 33769 33718
+f 33717 33768 33718
+f 33769 33770 33719
+f 33718 33769 33719
+f 33770 32737 2180
+f 33719 33770 2180
+f 33771 31935 5680
+f 22368 22539 22507
+f 5978 5821 5977
+f 26162 30 6914
+f 4390 31790 32433
+f 31790 27075 32434
+f 32666 32616 32723
+f 31752 31782 31784
+f 16174 25110 16175
+f 32221 31683 31682
+f 33149 33720 33725
+f 33148 33119 33721
+f 33772 33204 33202
+f 33742 33772 33202
+f 33773 33428 33204
+f 33772 33773 33204
+f 20182 33440 33428
+f 33773 20182 33428
+f 14061 33485 33440
+f 20182 14061 33440
+f 14504 33118 33485
+f 33235 33774 33775
+f 33234 33235 33775
+f 17174 32776 17408
+f 4506 4505 15717
+f 28723 25342 31206
+f 30605 31120 32345
+f 33234 33775 33776
+f 25110 16174 31312
+f 14061 14504 33485
+f 7857 33234 33776
+f 9571 9569 9578
+f 33777 33727 30338
+f 30344 33777 30338
+f 33778 33728 33727
+f 33777 33778 33727
+f 33779 33729 33728
+f 33778 33779 33728
+f 33780 33730 33729
+f 33779 33780 33729
+f 33781 33731 33730
+f 33780 33781 33730
+f 33782 33732 33731
+f 33781 33782 33731
+f 33783 33733 33732
+f 33782 33783 33732
+f 33784 33734 33733
+f 33783 33784 33733
+f 33785 33735 33734
+f 33784 33785 33734
+f 33786 33736 33735
+f 33785 33786 33735
+f 33787 33737 33736
+f 33786 33787 33736
+f 33788 33738 33737
+f 33787 33788 33737
+f 33789 33739 33738
+f 33788 33789 33738
+f 33790 33740 33739
+f 33789 33790 33739
+f 33791 33741 33740
+f 33790 33791 33740
+f 33792 8582 33741
+f 33791 33792 33741
+f 26268 8583 8582
+f 33792 26268 8582
+f 3413 3412 32157
+f 28723 31206 869
+f 14181 11012 32528
+f 33793 32128 15607
+f 4720 14446 5340
+f 31749 31756 31750
+f 8979 32973 33691
+f 32149 31748 32217
+f 14508 32631 14509
+f 4947 4946 22897
+f 16719 24480 19075
+f 22107 21512 22168
+f 14758 32131 33743
+f 32973 14758 33743
+f 32131 33794 33744
+f 33743 32131 33744
+f 33795 33745 33744
+f 33794 33795 33744
+f 33796 33746 33745
+f 33795 33796 33745
+f 33796 33797 33747
+f 33746 33796 33747
+f 33797 33798 33748
+f 33747 33797 33748
+f 33798 33799 33749
+f 33748 33798 33749
+f 33800 33750 33749
+f 33799 33800 33749
+f 33801 33751 33750
+f 33800 33801 33750
+f 33802 33752 33751
+f 33801 33802 33751
+f 33803 33753 33752
+f 33802 33803 33752
+f 33804 33754 33753
+f 33803 33804 33753
+f 33805 33755 33754
+f 33804 33805 33754
+f 33805 33806 33756
+f 33755 33805 33756
+f 33806 33807 33757
+f 33756 33806 33757
+f 33807 33808 33758
+f 33757 33807 33758
+f 33808 33809 33759
+f 33758 33808 33759
+f 33810 33760 33759
+f 33809 33810 33759
+f 33811 33761 33760
+f 33810 33811 33760
+f 33811 33812 33762
+f 33761 33811 33762
+f 33812 33813 33763
+f 33762 33812 33763
+f 33813 33814 33764
+f 33763 33813 33764
+f 33814 33815 33765
+f 33764 33814 33765
+f 33815 33816 33766
+f 33765 33815 33766
+f 33816 33817 33767
+f 33766 33816 33767
+f 33817 33818 33768
+f 33767 33817 33768
+f 33818 33819 33769
+f 33768 33818 33769
+f 33819 33820 33770
+f 33769 33819 33770
+f 33820 6083 32737
+f 33770 33820 32737
+f 6083 4511 4348
+f 32737 6083 4348
+f 26714 26755 3795
+f 4811 29143 22862
+f 27075 32435 32434
+f 31308 31588 31309
+f 5963 32967 32585
+f 32225 32369 25230
+f 73 72 31931
+f 32559 24594 24593
+f 33161 33149 33725
+f 33148 33721 33720
+f 33190 33726 33774
+f 33235 33190 33774
+f 31781 31780 22401
+f 32901 33469 22247
+f 33821 33532 14991
+f 9232 33821 14991
+f 33822 33564 33532
+f 33821 33822 33532
+f 33823 33565 33564
+f 33822 33823 33564
+f 32557 32329 31765
+f 32090 32064 31822
+f 5669 32790 33824
+f 4505 32323 27588
+f 32790 33825 33824
+f 32287 32231 28205
+f 33826 33567 33565
+f 14356 14358 31762
+f 33823 33826 33565
+f 6497 6737 6739
+f 33827 33777 30344
+f 30956 33827 30344
+f 33828 33778 33777
+f 33827 33828 33777
+f 33829 33779 33778
+f 33828 33829 33778
+f 33830 33780 33779
+f 33829 33830 33779
+f 33831 33781 33780
+f 33830 33831 33780
+f 33832 33782 33781
+f 33831 33832 33781
+f 33833 33783 33782
+f 33832 33833 33782
+f 33834 33784 33783
+f 33833 33834 33783
+f 33835 33785 33784
+f 33834 33835 33784
+f 33836 33786 33785
+f 33835 33836 33785
+f 33837 33787 33786
+f 33836 33837 33786
+f 33838 33788 33787
+f 33837 33838 33787
+f 33839 33789 33788
+f 33838 33839 33788
+f 33840 33790 33789
+f 33839 33840 33789
+f 33841 33791 33790
+f 33840 33841 33790
+f 26076 33792 33791
+f 33841 26076 33791
+f 20025 25848 16266
+f 33792 26076 26268
+f 22696 8583 26268
+f 16682 32131 14758
+f 33842 33569 33567
+f 33826 33842 33567
+f 33843 33570 33569
+f 33842 33843 33569
+f 32832 1087 31884
+f 32832 31884 32298
+f 15797 17028 15798
+f 20499 32132 16682
+f 3235 33844 21146
+f 29294 11025 25342
+f 32132 33845 33794
+f 32131 32132 33794
+f 33845 33846 33795
+f 33794 33845 33795
+f 33846 33847 33796
+f 33795 33846 33796
+f 33847 33848 33797
+f 33796 33847 33797
+f 33849 33798 33797
+f 33848 33849 33797
+f 33850 33799 33798
+f 33849 33850 33798
+f 33851 33800 33799
+f 33850 33851 33799
+f 33852 33801 33800
+f 33851 33852 33800
+f 33853 33802 33801
+f 33852 33853 33801
+f 33854 33803 33802
+f 33853 33854 33802
+f 33855 33804 33803
+f 33854 33855 33803
+f 33856 33805 33804
+f 33855 33856 33804
+f 33857 33806 33805
+f 33856 33857 33805
+f 33858 33807 33806
+f 33857 33858 33806
+f 33858 33859 33808
+f 33807 33858 33808
+f 33860 33809 33808
+f 33859 33860 33808
+f 33861 33810 33809
+f 33860 33861 33809
+f 33861 33862 33811
+f 33810 33861 33811
+f 33862 33863 33812
+f 33811 33862 33812
+f 33863 33864 33813
+f 33812 33863 33813
+f 33864 33865 33814
+f 33813 33864 33814
+f 33865 33866 33815
+f 33814 33865 33815
+f 33866 33867 33816
+f 33815 33866 33816
+f 33867 33868 33817
+f 33816 33867 33817
+f 33868 33869 33818
+f 33817 33868 33818
+f 33869 33870 33819
+f 33818 33869 33819
+f 33870 4656 33820
+f 33819 33870 33820
+f 4167 4511 4346
+f 33820 4656 6083
+f 32596 23421 32029
+f 13171 13159 17087
+f 23768 31812 23769
+f 14778 12377 25743
+f 28534 32436 32435
+f 27075 28534 32435
+f 32726 32230 17893
+f 32616 32604 32723
+f 22847 22763 26268
+f 32183 32782 32649
+f 31073 32026 31031
+f 31924 29015 29238
+f 31746 31309 32166
+f 31209 31208 31818
+f 32790 30813 33825
+f 7857 33776 2595
+f 33871 33571 33570
+f 33843 33871 33570
+f 33872 33572 33571
+f 33871 33872 33571
+f 33873 33573 33572
+f 33872 33873 33572
+f 30813 32585 33874
+f 30813 33874 33825
+f 33875 33574 33573
+f 32967 32330 32968
+f 33873 33875 33573
+f 33876 33575 33574
+f 33875 33876 33574
+f 30991 33877 30956
+f 6497 6739 6498
+f 33878 33827 30956
+f 33877 33878 30956
+f 33879 33828 33827
+f 33878 33879 33827
+f 33880 33829 33828
+f 33879 33880 33828
+f 33881 33830 33829
+f 33880 33881 33829
+f 33882 33831 33830
+f 33881 33882 33830
+f 33883 33832 33831
+f 33882 33883 33831
+f 33884 33833 33832
+f 33883 33884 33832
+f 33885 33834 33833
+f 33884 33885 33833
+f 33886 33835 33834
+f 33885 33886 33834
+f 33887 33836 33835
+f 33886 33887 33835
+f 33888 33837 33836
+f 33887 33888 33836
+f 33889 33838 33837
+f 33888 33889 33837
+f 33890 33839 33838
+f 33889 33890 33838
+f 33891 33840 33839
+f 33890 33891 33839
+f 33892 33841 33840
+f 33891 33892 33840
+f 33893 26076 33841
+f 33892 33893 33841
+f 16266 16265 20025
+f 33893 16912 26076
+f 4515 31559 28352
+f 22763 22697 22696
+f 15277 31719 32151
+f 17602 19599 28972
+f 33894 33590 33575
+f 33876 33894 33575
+f 33895 33624 33590
+f 33894 33895 33590
+f 33896 33625 33624
+f 28525 32654 31770
+f 31356 31763 32368
+f 6301 3639 4386
+f 20383 21468 20382
+f 20499 33897 33845
+f 32132 20499 33845
+f 33897 33898 33846
+f 33845 33897 33846
+f 33898 33899 33847
+f 33846 33898 33847
+f 33900 33848 33847
+f 33899 33900 33847
+f 33901 33849 33848
+f 33900 33901 33848
+f 33902 33850 33849
+f 33901 33902 33849
+f 32209 33851 33850
+f 33902 32209 33850
+f 32208 33852 33851
+f 32209 32208 33851
+f 33903 33853 33852
+f 32208 33903 33852
+f 33904 33854 33853
+f 33903 33904 33853
+f 33905 33855 33854
+f 33904 33905 33854
+f 33906 33856 33855
+f 33905 33906 33855
+f 33907 33857 33856
+f 33906 33907 33856
+f 33908 33858 33857
+f 33907 33908 33857
+f 33909 33859 33858
+f 33908 33909 33858
+f 33910 33860 33859
+f 33909 33910 33859
+f 33911 33861 33860
+f 33910 33911 33860
+f 33912 33862 33861
+f 33911 33912 33861
+f 33912 33913 33863
+f 33862 33912 33863
+f 33913 33914 33864
+f 33863 33913 33864
+f 33914 33915 33865
+f 33864 33914 33865
+f 33915 33916 33866
+f 33865 33915 33866
+f 33916 33917 33867
+f 33866 33916 33867
+f 33917 33918 33868
+f 33867 33917 33868
+f 33918 33919 33869
+f 33868 33918 33869
+f 33919 31456 33870
+f 33869 33919 33870
+f 18523 21762 21761
+f 33870 31456 4656
+f 33516 31210 21749
+f 6422 6425 6292
+f 31406 31408 31937
+f 27030 2499 32684
+f 31750 33283 32818
+f 31756 32728 33283
+f 28534 32479 32437
+f 32436 28534 32437
+f 32731 32726 17893
+f 9933 29472 32790
+f 31985 33920 31986
+f 17438 17439 26317
+f 2918 31954 32559
+f 16012 21386 16013
+f 32158 16188 14169
+f 32776 32285 32284
+f 31674 31673 15001
+f 5669 33824 4807
+f 33895 33896 33624
+f 33921 33627 33625
+f 33896 33921 33625
+f 33922 33628 33627
+f 33921 33922 33627
+f 22647 24914 33628
+f 33922 22647 33628
+f 27563 25663 26264
+f 22647 15258 24914
+f 33923 33877 30991
+f 643 33923 30991
+f 33924 33878 33877
+f 33923 33924 33877
+f 33925 33879 33878
+f 33924 33925 33878
+f 33926 33880 33879
+f 33925 33926 33879
+f 33927 33881 33880
+f 33926 33927 33880
+f 33928 33882 33881
+f 33927 33928 33881
+f 33929 33883 33882
+f 33928 33929 33882
+f 33930 33884 33883
+f 33929 33930 33883
+f 33931 33885 33884
+f 33930 33931 33884
+f 33932 33886 33885
+f 33931 33932 33885
+f 33933 33887 33886
+f 33932 33933 33886
+f 33934 33888 33887
+f 33933 33934 33887
+f 33935 33889 33888
+f 33934 33935 33888
+f 33936 33890 33889
+f 33935 33936 33889
+f 33937 33891 33890
+f 33936 33937 33890
+f 33938 33892 33891
+f 33937 33938 33891
+f 33939 33893 33892
+f 33938 33939 33892
+f 16913 16912 33893
+f 33939 16913 33893
+f 22753 22061 18683
+f 27740 16914 16913
+f 15050 22244 22868
+f 15050 22867 15048
+f 31628 31627 31587
+f 29087 4504 4506
+f 33940 33900 33899
+f 33941 33901 33900
+f 33940 33941 33900
+f 33423 33902 33901
+f 33941 33423 33901
+f 552 19599 550
+f 550 17602 27584
+f 14424 25659 14425
+f 6941 28107 28133
+f 32687 33903 32208
+f 6940 28133 23096
+f 33942 33904 33903
+f 32687 33942 33903
+f 33943 33905 33904
+f 33942 33943 33904
+f 33944 33906 33905
+f 33943 33944 33905
+f 33945 33907 33906
+f 33944 33945 33906
+f 33946 33908 33907
+f 33945 33946 33907
+f 33947 33909 33908
+f 33946 33947 33908
+f 33948 33910 33909
+f 33947 33948 33909
+f 33949 33911 33910
+f 33948 33949 33910
+f 33950 33912 33911
+f 33949 33950 33911
+f 33950 33951 33913
+f 33912 33950 33913
+f 33951 33952 33914
+f 33913 33951 33914
+f 33952 33953 33915
+f 33914 33952 33915
+f 33953 33954 33916
+f 33915 33953 33916
+f 33954 33955 33917
+f 33916 33954 33917
+f 33955 33956 33918
+f 33917 33955 33918
+f 33956 31934 33919
+f 33918 33956 33919
+f 22832 21898 21235
+f 33919 31934 31456
+f 32661 15057 32700
+f 19067 15541 206
+f 33957 21749 21748
+f 33957 33516 21749
+f 15515 14720 32967
+f 16482 31360 31591
+f 32189 32216 32807
+f 32217 31750 32818
+f 32479 32480 32438
+f 32437 32479 32438
+f 32438 32480 32439
+f 32480 32986 32439
+f 32439 32986 32442
+f 32986 32987 32442
+f 2152 1578 8846
+f 21386 21385 16013
+f 33429 32813 33472
+f 18720 27957 14169
+f 21522 32310 21523
+f 32441 31749 31748
+f 6896 4556 4555
+f 32629 32648 32630
+f 31710 17738 31653
+f 32735 32558 15793
+f 605 19439 19165
+f 25629 20330 1741
+f 387 389 24596
+f 24703 24590 24589
+f 24590 24703 14902
+f 16848 17102 12370
+f 17242 20054 21612
+f 24481 24480 24442
+f 22354 21921 22201
+f 16618 23280 16617
+f 642 33958 643
+f 33959 33923 643
+f 33958 33959 643
+f 33960 33924 33923
+f 33959 33960 33923
+f 33961 33925 33924
+f 33960 33961 33924
+f 33962 33926 33925
+f 33961 33962 33925
+f 33963 33927 33926
+f 33962 33963 33926
+f 33964 33928 33927
+f 33963 33964 33927
+f 33965 33929 33928
+f 33964 33965 33928
+f 33966 33930 33929
+f 33965 33966 33929
+f 33967 33931 33930
+f 33966 33967 33930
+f 33968 33932 33931
+f 33967 33968 33931
+f 33969 33933 33932
+f 33968 33969 33932
+f 33970 33934 33933
+f 33969 33970 33933
+f 33971 33935 33934
+f 33970 33971 33934
+f 33972 33936 33935
+f 33971 33972 33935
+f 33973 33937 33936
+f 33972 33973 33936
+f 33974 33938 33937
+f 33973 33974 33937
+f 33975 33939 33938
+f 33974 33975 33938
+f 33976 16913 33939
+f 33975 33976 33939
+f 33977 27740 16913
+f 33976 33977 16913
+f 33977 33978 27739
+f 27740 33977 27739
+f 11345 9565 11346
+f 33978 31256 27739
+f 31256 33979 31257
+f 33979 22197 31358
+f 31257 33979 31358
+f 22196 31358 22197
+f 3700 2868 13559
+f 21762 12924 14339
+f 22195 22198 22354
+f 8612 3838 3837
+f 1590 21883 1591
+f 22870 22775 22777
+f 21921 22194 22201
+f 21883 1590 1909
+f 22899 16792 22996
+f 30339 32432 30340
+f 6236 6392 6394
+f 32095 31937 31662
+f 22342 14148 14147
+f 27739 31258 16943
+f 19757 22430 16928
+f 22039 16928 22430
+f 17575 14995 1799
+f 33621 33942 32687
+f 16928 22429 16929
+f 33980 33943 33942
+f 33621 33980 33942
+f 33981 33944 33943
+f 33980 33981 33943
+f 33982 33945 33944
+f 33981 33982 33944
+f 33983 33946 33945
+f 33982 33983 33945
+f 33984 33947 33946
+f 33983 33984 33946
+f 33985 33948 33947
+f 33984 33985 33947
+f 33986 33949 33948
+f 33985 33986 33948
+f 33987 33950 33949
+f 33986 33987 33949
+f 33987 33988 33951
+f 33950 33987 33951
+f 33988 33989 33952
+f 33951 33988 33952
+f 33989 33990 33953
+f 33952 33989 33953
+f 33990 33991 33954
+f 33953 33990 33954
+f 33991 33992 33955
+f 33954 33991 33955
+f 33992 33993 33956
+f 33955 33992 33956
+f 33993 32350 31934
+f 33956 33993 31934
+f 32350 4977 31934
+f 29143 4811 4810
+f 32164 32661 32700
+f 32344 32774 14507
+f 32507 21748 33016
+f 32507 33957 21748
+f 31941 32789 16885
+f 31033 32851 32834
+f 32217 32818 32817
+f 32216 32217 32817
+f 32488 32189 32875
+f 32216 32817 32807
+f 32490 32488 32811
+f 32189 32807 32875
+f 32987 32296 32444
+f 32442 32987 32444
+f 22867 15050 22868
+f 31361 32609 31954
+f 32813 32662 33472
+f 32324 32325 32662
+f 32087 31821 31672
+f 32298 31884 32299
+f 33994 6170 6169
+f 33426 31867 29879
+f 17730 33995 24396
+f 33995 33996 24397
+f 24396 33995 24397
+f 33996 33997 22549
+f 24397 33996 22549
+f 33997 33998 20054
+f 22549 33997 20054
+f 33998 33999 21612
+f 20054 33998 21612
+f 33999 34000 21610
+f 21612 33999 21610
+f 34000 34001 30923
+f 21610 34000 30923
+f 34001 34002 642
+f 30923 34001 642
+f 34003 33958 642
+f 34002 34003 642
+f 34004 33959 33958
+f 34003 34004 33958
+f 34005 33960 33959
+f 34004 34005 33959
+f 34006 33961 33960
+f 34005 34006 33960
+f 34007 33962 33961
+f 34006 34007 33961
+f 34008 33963 33962
+f 34007 34008 33962
+f 34009 33964 33963
+f 34008 34009 33963
+f 34010 33965 33964
+f 34009 34010 33964
+f 34011 33966 33965
+f 34010 34011 33965
+f 34012 33967 33966
+f 34011 34012 33966
+f 34013 33968 33967
+f 34012 34013 33967
+f 34014 33969 33968
+f 34013 34014 33968
+f 34015 33970 33969
+f 34014 34015 33969
+f 34016 33971 33970
+f 34015 34016 33970
+f 34017 33972 33971
+f 34016 34017 33971
+f 34018 33973 33972
+f 34017 34018 33972
+f 34019 33974 33973
+f 34018 34019 33973
+f 34020 33975 33974
+f 34019 34020 33974
+f 34021 33976 33975
+f 34020 34021 33975
+f 34022 33977 33976
+f 34021 34022 33976
+f 34022 34023 33978
+f 33977 34022 33978
+f 34023 34024 31256
+f 33978 34023 31256
+f 34024 34025 33979
+f 31256 34024 33979
+f 34025 33013 22197
+f 33979 34025 22197
+f 3856 3700 13561
+f 3700 3856 8379
+f 33533 34026 22354
+f 3700 13559 13561
+f 34026 34027 21921
+f 22354 34026 21921
+f 34027 34028 21922
+f 21921 34027 21922
+f 34028 21764 22571
+f 21922 34028 22571
+f 20295 2287 4693
+f 21764 34029 21765
+f 22571 21764 21763
+f 1164 29358 1630
+f 32062 31661 32205
+f 31772 31653 141
+f 32090 32092 32064
+f 31805 32735 15792
+f 31625 31628 17739
+f 33233 17616 32775
+f 31561 33620 21400
+f 2472 18038 2470
+f 22429 16928 22039
+f 4977 32350 4976
+f 31561 33980 33621
+f 33620 31561 33621
+f 31560 33981 33980
+f 31561 31560 33980
+f 34030 33982 33981
+f 31560 34030 33981
+f 34031 33983 33982
+f 34030 34031 33982
+f 34032 33984 33983
+f 34031 34032 33983
+f 34033 33985 33984
+f 34032 34033 33984
+f 34034 33986 33985
+f 34033 34034 33985
+f 34034 34035 33987
+f 33986 34034 33987
+f 34035 34036 33988
+f 33987 34035 33988
+f 34036 34037 33989
+f 33988 34036 33989
+f 34037 34038 33990
+f 33989 34037 33990
+f 34038 34039 33991
+f 33990 34038 33991
+f 34039 34040 33992
+f 33991 34039 33992
+f 34040 34041 33993
+f 33992 34040 33993
+f 34041 5125 32350
+f 33993 34041 32350
+f 6615 1208 6616
+f 22926 22927 16943
+f 32892 33103 15057
+f 32661 32892 15057
+f 32307 33016 33471
+f 32307 32507 33016
+f 27789 30606 27790
+f 32852 4503 32369
+f 32769 33516 33957
+f 31992 31969 31994
+f 32491 32490 32810
+f 29749 16486 32831
+f 32484 32297 32485
+f 32488 32875 32811
+f 32577 32366 33563
+f 32296 32297 32484
+f 32683 32223 33033
+f 5341 2833 32357
+f 32441 31880 31749
+f 22999 16049 18964
+f 32390 33724 32388
+f 32152 4502 31703
+f 30817 31837 36
+f 32320 17892 32234
+f 17732 34042 17730
+f 34043 33995 17730
+f 34042 34043 17730
+f 34043 34044 33996
+f 33995 34043 33996
+f 34045 33997 33996
+f 34044 34045 33996
+f 34046 33998 33997
+f 34045 34046 33997
+f 34047 33999 33998
+f 34046 34047 33998
+f 34048 34000 33999
+f 34047 34048 33999
+f 34049 34001 34000
+f 34048 34049 34000
+f 34050 34002 34001
+f 34049 34050 34001
+f 34051 34003 34002
+f 34050 34051 34002
+f 34052 34004 34003
+f 34051 34052 34003
+f 34053 34005 34004
+f 34052 34053 34004
+f 34054 34006 34005
+f 34053 34054 34005
+f 34055 34007 34006
+f 34054 34055 34006
+f 34056 34008 34007
+f 34055 34056 34007
+f 34057 34009 34008
+f 34056 34057 34008
+f 34058 34010 34009
+f 34057 34058 34009
+f 34059 34011 34010
+f 34058 34059 34010
+f 34060 34012 34011
+f 34059 34060 34011
+f 34061 34013 34012
+f 34060 34061 34012
+f 34062 34014 34013
+f 34061 34062 34013
+f 34063 34015 34014
+f 34062 34063 34014
+f 34064 34016 34015
+f 34063 34064 34015
+f 34065 34017 34016
+f 34064 34065 34016
+f 34066 34018 34017
+f 34065 34066 34017
+f 34067 34019 34018
+f 34066 34067 34018
+f 34068 34020 34019
+f 34067 34068 34019
+f 34069 34021 34020
+f 34068 34069 34020
+f 34070 34022 34021
+f 34069 34070 34021
+f 34071 34023 34022
+f 34070 34071 34022
+f 34071 34072 34024
+f 34023 34071 34024
+f 34073 34025 34024
+f 34072 34073 34024
+f 34074 33013 34025
+f 34073 34074 34025
+f 34075 33533 33013
+f 34074 34075 33013
+f 34076 34026 33533
+f 34075 34076 33533
+f 34077 34027 34026
+f 34076 34077 34026
+f 34078 34028 34027
+f 34077 34078 34027
+f 34078 34079 21764
+f 34028 34078 21764
+f 34079 34080 34029
+f 21764 34079 34029
+f 34080 22360 30957
+f 34029 34080 30957
+f 23200 23249 23123
+f 8386 7466 6699
+f 32092 31940 32064
+f 14444 3473 32689
+f 32614 33722 32359
+f 32033 32148 32150
+f 33723 17892 32320
+f 31259 32649 31260
+f 16944 31258 23163
+f 31776 31811 31810
+f 2562 9998 18098
+f 31258 16944 16943
+f 18403 18402 17413
+f 22861 5822 4811
+f 34081 34030 31560
+f 18403 34081 31560
+f 34082 34031 34030
+f 34081 34082 34030
+f 34083 34032 34031
+f 34082 34083 34031
+f 34084 34033 34032
+f 34083 34084 34032
+f 34085 34034 34033
+f 34084 34085 34033
+f 34085 34086 34035
+f 34034 34085 34035
+f 34086 34087 34036
+f 34035 34086 34036
+f 34087 34088 34037
+f 34036 34087 34037
+f 34088 34089 34038
+f 34037 34088 34038
+f 34089 34090 34039
+f 34038 34089 34039
+f 34090 34091 34040
+f 34039 34090 34040
+f 34091 34092 34041
+f 34040 34091 34041
+f 34092 5270 5125
+f 34041 34092 5125
+f 16161 31803 16162
+f 17899 15458 16234
+f 33425 32640 33103
+f 32892 33425 33103
+f 33563 32366 32632
+f 32365 32307 33471
+f 32574 31729 32013
+f 32365 33471 32970
+f 32491 32810 32646
+f 31311 14171 20382
+f 32494 32492 32629
+f 32492 32491 32646
+f 32444 32296 32484
+f 31841 34093 32498
+f 22154 32752 33060
+f 33333 34094 17184
+f 15077 15079 23183
+f 31990 32732 31991
+f 32308 32310 21522
+f 32683 33033 33104
+f 32322 33723 32320
+f 34095 32534 32393
+f 17892 17894 32234
+f 34096 34042 17732
+f 17975 34096 17732
+f 34097 34043 34042
+f 34096 34097 34042
+f 34098 34044 34043
+f 34097 34098 34043
+f 34099 34045 34044
+f 34098 34099 34044
+f 34100 34046 34045
+f 34099 34100 34045
+f 34101 34047 34046
+f 34100 34101 34046
+f 34102 34048 34047
+f 34101 34102 34047
+f 34103 34049 34048
+f 34102 34103 34048
+f 34104 34050 34049
+f 34103 34104 34049
+f 34105 34051 34050
+f 34104 34105 34050
+f 34106 34052 34051
+f 34105 34106 34051
+f 34107 34053 34052
+f 34106 34107 34052
+f 34108 34054 34053
+f 34107 34108 34053
+f 34109 34055 34054
+f 34108 34109 34054
+f 34110 34056 34055
+f 34109 34110 34055
+f 34111 34057 34056
+f 34110 34111 34056
+f 34112 34058 34057
+f 34111 34112 34057
+f 34113 34059 34058
+f 34112 34113 34058
+f 34114 34060 34059
+f 34113 34114 34059
+f 34115 34061 34060
+f 34114 34115 34060
+f 34116 34062 34061
+f 34115 34116 34061
+f 34117 34063 34062
+f 34116 34117 34062
+f 34118 34064 34063
+f 34117 34118 34063
+f 34119 34065 34064
+f 34118 34119 34064
+f 34120 34066 34065
+f 34119 34120 34065
+f 34121 34067 34066
+f 34120 34121 34066
+f 34122 34068 34067
+f 34121 34122 34067
+f 34123 34069 34068
+f 34122 34123 34068
+f 34124 34070 34069
+f 34123 34124 34069
+f 34125 34071 34070
+f 34124 34125 34070
+f 34126 34072 34071
+f 34125 34126 34071
+f 34127 34073 34072
+f 34126 34127 34072
+f 34128 34074 34073
+f 34127 34128 34073
+f 34129 34075 34074
+f 34128 34129 34074
+f 34130 34076 34075
+f 34129 34130 34075
+f 34131 34077 34076
+f 34130 34131 34076
+f 34132 34078 34077
+f 34131 34132 34077
+f 34133 34079 34078
+f 34132 34133 34078
+f 34133 34134 34080
+f 34079 34133 34080
+f 34134 31921 22360
+f 34080 34134 22360
+f 6646 9905 3835
+f 16538 8687 16287
+f 6584 6583 6591
+f 16538 16287 16286
+f 25546 25548 32329
+f 23051 11336 11335
+f 24685 32584 26845
+f 31737 32966 33284
+f 32447 34095 32393
+f 17721 17720 32915
+f 32368 17614 16974
+f 32774 33233 14508
+f 13349 6132 6292
+f 31770 32368 16974
+f 17413 34081 18403
+f 22847 16914 22927
+f 34135 34082 34081
+f 17413 34135 34081
+f 34136 34083 34082
+f 34135 34136 34082
+f 34137 34084 34083
+f 34136 34137 34083
+f 34137 34138 34085
+f 34084 34137 34085
+f 34139 34086 34085
+f 34138 34139 34085
+f 34139 34140 34087
+f 34086 34139 34087
+f 34140 34141 34088
+f 34087 34140 34088
+f 34141 34142 34089
+f 34088 34141 34089
+f 34142 34143 34090
+f 34089 34142 34090
+f 34143 34144 34091
+f 34090 34143 34091
+f 34144 32990 34092
+f 34091 34144 34092
+f 22788 25708 25939
+f 34092 32990 5270
+f 32357 21301 17796
+f 19431 19430 13808
+f 33563 32632 32639
+f 21786 33429 32640
+f 32576 32836 32006
+f 33060 33563 32639
+f 32494 32629 32628
+f 33518 32574 32013
+f 31773 33015 32553
+f 32496 32494 32628
+f 32656 32555 32554
+f 33015 32656 32554
+f 32506 32769 33957
+f 32297 31841 32485
+f 32782 31207 31209
+f 22827 22828 30430
+f 31908 31910 30515
+f 31507 32326 31508
+f 32591 32308 21522
+f 34093 4341 31774
+f 31652 31649 141
+f 31847 31840 31898
+f 34145 34096 17975
+f 17976 34145 17975
+f 34146 34097 34096
+f 34145 34146 34096
+f 34147 34098 34097
+f 34146 34147 34097
+f 34148 34099 34098
+f 34147 34148 34098
+f 34149 34100 34099
+f 34148 34149 34099
+f 34150 34101 34100
+f 34149 34150 34100
+f 34151 34102 34101
+f 34150 34151 34101
+f 34152 34103 34102
+f 34151 34152 34102
+f 34153 34104 34103
+f 34152 34153 34103
+f 34154 34105 34104
+f 34153 34154 34104
+f 34155 34106 34105
+f 34154 34155 34105
+f 34156 34107 34106
+f 34155 34156 34106
+f 34157 34108 34107
+f 34156 34157 34107
+f 34158 34109 34108
+f 34157 34158 34108
+f 34159 34110 34109
+f 34158 34159 34109
+f 34160 34111 34110
+f 34159 34160 34110
+f 34161 34112 34111
+f 34160 34161 34111
+f 34162 34113 34112
+f 34161 34162 34112
+f 34163 34114 34113
+f 34162 34163 34113
+f 34164 34115 34114
+f 34163 34164 34114
+f 34165 34116 34115
+f 34164 34165 34115
+f 34166 34117 34116
+f 34165 34166 34116
+f 34167 34118 34117
+f 34166 34167 34117
+f 34168 34119 34118
+f 34167 34168 34118
+f 34169 34120 34119
+f 34168 34169 34119
+f 34170 34121 34120
+f 34169 34170 34120
+f 34171 34122 34121
+f 34170 34171 34121
+f 34172 34123 34122
+f 34171 34172 34122
+f 34173 34124 34123
+f 34172 34173 34123
+f 34174 34125 34124
+f 34173 34174 34124
+f 34175 34126 34125
+f 34174 34175 34125
+f 34176 34127 34126
+f 34175 34176 34126
+f 34177 34128 34127
+f 34176 34177 34127
+f 34178 34129 34128
+f 34177 34178 34128
+f 34179 34130 34129
+f 34178 34179 34129
+f 34180 34131 34130
+f 34179 34180 34130
+f 34181 34132 34131
+f 34180 34181 34131
+f 34182 34133 34132
+f 34181 34182 34132
+f 34183 34134 34133
+f 34182 34183 34133
+f 34183 34184 31921
+f 34134 34183 31921
+f 34184 34185 9567
+f 31921 34184 9567
+f 34185 23160 9565
+f 9567 34185 9565
+f 5355 21198 5353
+f 4504 32746 32323
+f 11227 3472 32034
+f 22167 22168 6542
+f 143 31652 140
+f 31715 31759 31761
+f 140 31652 141
+f 7833 7834 11465
+f 31691 31770 17471
+f 20371 22497 31111
+f 33844 17412 21146
+f 5270 32990 5409
+f 34186 34135 17413
+f 17412 34186 17413
+f 34187 34136 34135
+f 34186 34187 34135
+f 34188 34137 34136
+f 34187 34188 34136
+f 34189 34138 34137
+f 34188 34189 34137
+f 34189 34190 34139
+f 34138 34189 34139
+f 34190 34191 34140
+f 34139 34190 34140
+f 34191 34192 34141
+f 34140 34191 34141
+f 34192 34193 34142
+f 34141 34192 34142
+f 34193 34194 34143
+f 34142 34193 34143
+f 34194 17091 34144
+f 34143 34194 34144
+f 17091 5679 32990
+f 34144 17091 32990
+f 17124 32617 17125
+f 29087 4506 29088
+f 32611 30473 32813
+f 30473 33014 32324
+f 14732 22155 29198
+f 32366 32970 32632
+f 32574 32576 31730
+f 31730 32576 32006
+f 32678 32489 32837
+f 32492 32646 32629
+f 31774 31773 32552
+f 17117 32556 32555
+f 32769 30429 33516
+f 32636 32580 15614
+f 32987 23288 32296
+f 30429 30430 33516
+f 31736 32340 32893
+f 32226 17551 16280
+f 28763 20838 31113
+f 32310 32683 33104
+f 33427 33426 29879
+f 32966 21524 33284
+f 17898 17897 23858
+f 22984 34195 17976
+f 34196 34145 17976
+f 34195 34196 17976
+f 34197 34146 34145
+f 34196 34197 34145
+f 34198 34147 34146
+f 34197 34198 34146
+f 34199 34148 34147
+f 34198 34199 34147
+f 34200 34149 34148
+f 34199 34200 34148
+f 34201 34150 34149
+f 34200 34201 34149
+f 34202 34151 34150
+f 34201 34202 34150
+f 34203 34152 34151
+f 34202 34203 34151
+f 34204 34153 34152
+f 34203 34204 34152
+f 34205 34154 34153
+f 34204 34205 34153
+f 34206 34155 34154
+f 34205 34206 34154
+f 34207 34156 34155
+f 34206 34207 34155
+f 34208 34157 34156
+f 34207 34208 34156
+f 34209 34158 34157
+f 34208 34209 34157
+f 34210 34159 34158
+f 34209 34210 34158
+f 34211 34160 34159
+f 34210 34211 34159
+f 34212 34161 34160
+f 34211 34212 34160
+f 34213 34162 34161
+f 34212 34213 34161
+f 34214 34163 34162
+f 34213 34214 34162
+f 34215 34164 34163
+f 34214 34215 34163
+f 34216 34165 34164
+f 34215 34216 34164
+f 34217 34166 34165
+f 34216 34217 34165
+f 34218 34167 34166
+f 34217 34218 34166
+f 34219 34168 34167
+f 34218 34219 34167
+f 34220 34169 34168
+f 34219 34220 34168
+f 34221 34170 34169
+f 34220 34221 34169
+f 34222 34171 34170
+f 34221 34222 34170
+f 34223 34172 34171
+f 34222 34223 34171
+f 34224 34173 34172
+f 34223 34224 34172
+f 34225 34174 34173
+f 34224 34225 34173
+f 34226 34175 34174
+f 34225 34226 34174
+f 34227 34176 34175
+f 34226 34227 34175
+f 34228 34177 34176
+f 34227 34228 34176
+f 34229 34178 34177
+f 34228 34229 34177
+f 34230 34179 34178
+f 34229 34230 34178
+f 34231 34180 34179
+f 34230 34231 34179
+f 34232 34181 34180
+f 34231 34232 34180
+f 34233 34182 34181
+f 34232 34233 34181
+f 34234 34183 34182
+f 34233 34234 34182
+f 34235 34184 34183
+f 34234 34235 34183
+f 34236 34185 34184
+f 34235 34236 34184
+f 34236 34237 23160
+f 34185 34236 23160
+f 4656 4508 6083
+f 34237 23161 23160
+f 16510 22083 17183
+f 8981 14757 8979
+f 32548 31112 21746
+f 32506 33957 32507
+f 32691 144 146
+f 31869 31988 29877
+f 31679 32247 31680
+f 26711 33534 21574
+f 3235 34238 33844
+f 32768 32805 32792
+f 34239 34186 17412
+f 33844 34239 17412
+f 34240 34187 34186
+f 34239 34240 34186
+f 34241 34188 34187
+f 34240 34241 34187
+f 34242 34189 34188
+f 34241 34242 34188
+f 34242 34243 34190
+f 34189 34242 34190
+f 34243 34244 34191
+f 34190 34243 34191
+f 34244 34245 34192
+f 34191 34244 34192
+f 34245 34246 34193
+f 34192 34245 34193
+f 34246 33771 34194
+f 34193 34246 34194
+f 33793 21359 34247
+f 34194 33771 17091
+f 16979 15294 16869
+f 20183 15969 10912
+f 6171 22239 16552
+f 14062 14058 14063
+f 21786 32611 33429
+f 33014 31807 32324
+f 33060 32639 32397
+f 22155 33060 32397
+f 33518 32013 32332
+f 31729 32574 31730
+f 32487 32496 32628
+f 32837 32487 32628
+f 34093 31774 32498
+f 33015 32554 32553
+f 19602 19604 32581
+f 32306 32507 32307
+f 32339 32499 31715
+f 32499 32286 31759
+f 22391 15540 15539
+f 16051 20541 18965
+f 17866 17898 25633
+f 32915 17720 22749
+f 13809 4888 13810
+f 32065 31926 144
+f 32691 32065 144
+f 31630 31988 27353
+f 34248 34195 22984
+f 18063 34248 22984
+f 34249 34196 34195
+f 34248 34249 34195
+f 34250 34197 34196
+f 34249 34250 34196
+f 34251 34198 34197
+f 34250 34251 34197
+f 34252 34199 34198
+f 34251 34252 34198
+f 34253 34200 34199
+f 34252 34253 34199
+f 34254 34201 34200
+f 34253 34254 34200
+f 34255 34202 34201
+f 34254 34255 34201
+f 34256 34203 34202
+f 34255 34256 34202
+f 34257 34204 34203
+f 34256 34257 34203
+f 34258 34205 34204
+f 34257 34258 34204
+f 34259 34206 34205
+f 34258 34259 34205
+f 34260 34207 34206
+f 34259 34260 34206
+f 34261 34208 34207
+f 34260 34261 34207
+f 34262 34209 34208
+f 34261 34262 34208
+f 34263 34210 34209
+f 34262 34263 34209
+f 34264 34211 34210
+f 34263 34264 34210
+f 34265 34212 34211
+f 34264 34265 34211
+f 34266 34213 34212
+f 34265 34266 34212
+f 34267 34214 34213
+f 34266 34267 34213
+f 34268 34215 34214
+f 34267 34268 34214
+f 34269 34216 34215
+f 34268 34269 34215
+f 34270 34217 34216
+f 34269 34270 34216
+f 34271 34218 34217
+f 34270 34271 34217
+f 82 34219 34218
+f 34271 82 34218
+f 84 34220 34219
+f 82 84 34219
+f 86 34221 34220
+f 84 86 34220
+f 34272 34222 34221
+f 86 34272 34221
+f 34273 34223 34222
+f 34272 34273 34222
+f 34274 34224 34223
+f 34273 34274 34223
+f 34275 34225 34224
+f 34274 34275 34224
+f 34276 34226 34225
+f 34275 34276 34225
+f 34277 34227 34226
+f 34276 34277 34226
+f 34278 34228 34227
+f 34277 34278 34227
+f 34279 34229 34228
+f 34278 34279 34228
+f 34280 34230 34229
+f 34279 34280 34229
+f 34281 34231 34230
+f 34280 34281 34230
+f 34282 34232 34231
+f 34281 34282 34231
+f 34283 34233 34232
+f 34282 34283 34232
+f 34284 34234 34233
+f 34283 34284 34233
+f 34285 34235 34234
+f 34284 34285 34234
+f 34286 34236 34235
+f 34285 34286 34235
+f 34287 34237 34236
+f 34286 34287 34236
+f 34287 34288 23161
+f 34237 34287 23161
+f 4888 17728 4886
+f 34288 22548 23161
+f 17552 10710 31675
+f 16178 34238 3235
+f 31627 31630 27353
+f 31260 22983 18270
+f 17896 32065 17897
+f 32684 31356 32654
+f 32281 34238 16178
+f 22402 32949 33250
+f 32281 34239 33844
+f 34238 32281 33844
+f 34289 34240 34239
+f 32281 34289 34239
+f 34290 34241 34240
+f 34289 34290 34240
+f 34291 34242 34241
+f 34290 34291 34241
+f 34291 34292 34243
+f 34242 34291 34243
+f 34292 34293 34244
+f 34243 34292 34244
+f 34293 34294 34245
+f 34244 34293 34245
+f 34294 34295 34246
+f 34245 34294 34246
+f 34295 31935 33771
+f 34246 34295 33771
+f 17091 33771 5680
+f 31936 5684 5680
+f 21576 21898 22832
+f 17087 10963 13171
+f 15614 32581 32866
+f 23053 11469 22267
+f 33425 21786 32640
+f 30473 32324 32813
+f 22155 32397 29198
+f 32366 32365 32970
+f 34094 32332 16227
+f 34094 33518 32332
+f 32489 32487 32837
+f 32490 32811 32810
+f 32485 31841 32498
+f 31773 32553 32552
+f 14720 14722 32330
+f 33994 49 6170
+f 32310 33104 21523
+f 26873 23288 32987
+f 30515 18122 4764
+f 32699 32700 31819
+f 31625 17739 17738
+f 29878 33427 29879
+f 2470 33742 33394
+f 22754 22303 22188
+f 18038 33772 33742
+f 2470 18038 33742
+f 34296 34248 18063
+f 26997 34296 18063
+f 34297 34249 34248
+f 34296 34297 34248
+f 34298 34250 34249
+f 34297 34298 34249
+f 34299 34251 34250
+f 34298 34299 34250
+f 34300 34252 34251
+f 34299 34300 34251
+f 34301 34253 34252
+f 34300 34301 34252
+f 34302 34254 34253
+f 34301 34302 34253
+f 34303 34255 34254
+f 34302 34303 34254
+f 34304 34256 34255
+f 34303 34304 34255
+f 34305 34257 34256
+f 34304 34305 34256
+f 34306 34258 34257
+f 34305 34306 34257
+f 34307 34259 34258
+f 34306 34307 34258
+f 34308 34260 34259
+f 34307 34308 34259
+f 34309 34261 34260
+f 34308 34309 34260
+f 34310 34262 34261
+f 34309 34310 34261
+f 34311 34263 34262
+f 34310 34311 34262
+f 34312 34264 34263
+f 34311 34312 34263
+f 34313 34265 34264
+f 34312 34313 34264
+f 34314 34266 34265
+f 34313 34314 34265
+f 34315 34267 34266
+f 34314 34315 34266
+f 34316 34268 34267
+f 34315 34316 34267
+f 34317 34269 34268
+f 34316 34317 34268
+f 34318 34270 34269
+f 34317 34318 34269
+f 83 34271 34270
+f 34318 83 34270
+f 83 82 34271
+f 85 34272 86
+f 85 34319 34273
+f 34272 85 34273
+f 34320 34274 34273
+f 34319 34320 34273
+f 34321 34275 34274
+f 34320 34321 34274
+f 34322 34276 34275
+f 34321 34322 34275
+f 34323 34277 34276
+f 34322 34323 34276
+f 34324 34278 34277
+f 34323 34324 34277
+f 34325 34279 34278
+f 34324 34325 34278
+f 34326 34280 34279
+f 34325 34326 34279
+f 34327 34281 34280
+f 34326 34327 34280
+f 34328 34282 34281
+f 34327 34328 34281
+f 34329 34283 34282
+f 34328 34329 34282
+f 34330 34284 34283
+f 34329 34330 34283
+f 34331 34285 34284
+f 34330 34331 34284
+f 34332 34286 34285
+f 34331 34332 34285
+f 34333 34287 34286
+f 34332 34333 34286
+f 34333 34334 34288
+f 34287 34333 34288
+f 32318 22548 34288
+f 34334 32318 34288
+f 32573 14704 32861
+f 22776 22727 22660
+f 14358 31747 7316
+f 31818 27713 27715
+f 11592 33773 33772
+f 18038 11592 33772
+f 12832 5977 25549
+f 32360 33821 9232
+f 20818 27587 21544
+f 33620 21401 21400
+f 16177 6081 22001
+f 28385 17653 29253
+f 34335 34290 34289
+f 16177 34335 34289
+f 34336 34291 34290
+f 34335 34336 34290
+f 34336 34337 34292
+f 34291 34336 34292
+f 34337 34338 34293
+f 34292 34337 34293
+f 34338 34339 34294
+f 34293 34338 34294
+f 34339 34340 34295
+f 34294 34339 34295
+f 34340 34341 31935
+f 34295 34340 31935
+f 34341 5976 31936
+f 31935 34341 31936
+f 26280 21269 21270
+f 1816 1783 18638
+f 17175 32594 16855
+f 22078 23247 22291
+f 14732 29198 32969
+f 32611 32813 33429
+f 32630 32648 32264
+f 14733 14732 32969
+f 32497 32536 33517
+f 17184 34094 16227
+f 31692 32643 32642
+f 32536 32489 32678
+f 32486 32161 32495
+f 31774 32552 32498
+f 25109 6585 7001
+f 16808 2598 2585
+f 46 45 5959
+f 32223 32893 33033
+f 15599 20894 15600
+f 40 14755 41
+f 34342 33822 33821
+f 32360 34342 33821
+f 34343 33823 33822
+f 34342 34343 33822
+f 34344 33826 33823
+f 34343 34344 33823
+f 34345 34296 26997
+f 27981 34345 26997
+f 34346 34297 34296
+f 34345 34346 34296
+f 34347 34298 34297
+f 34346 34347 34297
+f 34348 34299 34298
+f 34347 34348 34298
+f 34349 34300 34299
+f 34348 34349 34299
+f 34350 34301 34300
+f 34349 34350 34300
+f 34351 34302 34301
+f 34350 34351 34301
+f 34352 34303 34302
+f 34351 34352 34302
+f 34353 34304 34303
+f 34352 34353 34303
+f 34354 34305 34304
+f 34353 34354 34304
+f 34355 34306 34305
+f 34354 34355 34305
+f 34356 34307 34306
+f 34355 34356 34306
+f 34357 34308 34307
+f 34356 34357 34307
+f 34358 34309 34308
+f 34357 34358 34308
+f 34359 34310 34309
+f 34358 34359 34309
+f 34360 34311 34310
+f 34359 34360 34310
+f 34361 34312 34311
+f 34360 34361 34311
+f 34362 34313 34312
+f 34361 34362 34312
+f 34363 34314 34313
+f 34362 34363 34313
+f 34364 34315 34314
+f 34363 34364 34314
+f 34365 34316 34315
+f 34364 34365 34315
+f 34366 34317 34316
+f 34365 34366 34316
+f 34367 34318 34317
+f 34366 34367 34317
+f 81 83 34318
+f 34367 81 34318
+f 88 34319 85
+f 34368 34320 34319
+f 88 34368 34319
+f 34369 34321 34320
+f 34368 34369 34320
+f 34370 34322 34321
+f 34369 34370 34321
+f 34371 34323 34322
+f 34370 34371 34322
+f 34372 34324 34323
+f 34371 34372 34323
+f 34373 34325 34324
+f 34372 34373 34324
+f 34374 34326 34325
+f 34373 34374 34325
+f 34375 34327 34326
+f 34374 34375 34326
+f 34376 34328 34327
+f 34375 34376 34327
+f 34377 34329 34328
+f 34376 34377 34328
+f 34378 34330 34329
+f 34377 34378 34329
+f 34379 34331 34330
+f 34378 34379 34330
+f 34380 34332 34331
+f 34379 34380 34331
+f 34381 34333 34332
+f 34380 34381 34332
+f 34382 34334 34333
+f 34381 34382 34333
+f 21358 32318 34334
+f 34382 21358 34334
+f 14978 14977 22659
+f 20287 1141 20252
+f 31309 31589 32166
+f 16552 22239 32231
+f 34383 33842 33826
+f 32615 32616 32666
+f 34344 34383 33826
+f 34384 33843 33842
+f 21386 32139 21387
+f 34383 34384 33842
+f 22707 22635 22585
+f 32664 26316 32665
+f 22001 34335 16177
+f 12705 32208 12706
+f 22001 34385 34336
+f 34335 22001 34336
+f 34385 34386 34337
+f 34336 34385 34337
+f 34386 34387 34338
+f 34337 34386 34338
+f 34387 34388 34339
+f 34338 34387 34339
+f 34388 34389 34340
+f 34339 34388 34340
+f 34389 34390 34341
+f 34340 34389 34341
+f 34390 25549 5976
+f 34341 34390 5976
+f 11469 23053 22995
+f 11934 11933 11335
+f 32689 317 14444
+f 18802 16162 28473
+f 31856 14733 30472
+f 32944 32786 14831
+f 32836 32630 32264
+f 32647 32542 32537
+f 32500 32497 33333
+f 32575 32536 32678
+f 32656 17117 32555
+f 17116 31692 32642
+f 26316 26317 32665
+f 32425 16808 2585
+f 32226 32110 17551
+f 16175 25109 7001
+f 6082 12636 22001
+f 19758 17548 17547
+f 34391 33871 33843
+f 34384 34391 33843
+f 34392 33872 33871
+f 34391 34392 33871
+f 34393 33873 33872
+f 32119 32226 16280
+f 34392 34393 33872
+f 34394 33875 33873
+f 34395 34345 27981
+f 24808 34395 27981
+f 34396 34346 34345
+f 34395 34396 34345
+f 34397 34347 34346
+f 34396 34397 34346
+f 34398 34348 34347
+f 34397 34398 34347
+f 34399 34349 34348
+f 34398 34399 34348
+f 34400 34350 34349
+f 34399 34400 34349
+f 34401 34351 34350
+f 34400 34401 34350
+f 34402 34352 34351
+f 34401 34402 34351
+f 34403 34353 34352
+f 34402 34403 34352
+f 34404 34354 34353
+f 34403 34404 34353
+f 34405 34355 34354
+f 34404 34405 34354
+f 34406 34356 34355
+f 34405 34406 34355
+f 34407 34357 34356
+f 34406 34407 34356
+f 161 34358 34357
+f 34407 161 34357
+f 34408 34359 34358
+f 161 34408 34358
+f 34409 34360 34359
+f 34408 34409 34359
+f 34410 34361 34360
+f 34409 34410 34360
+f 34411 34362 34361
+f 34410 34411 34361
+f 34412 34363 34362
+f 34411 34412 34362
+f 34413 34364 34363
+f 34412 34413 34363
+f 34414 34365 34364
+f 34413 34414 34364
+f 34415 34366 34365
+f 34414 34415 34365
+f 117 34367 34366
+f 34415 117 34366
+f 117 81 34367
+f 87 34368 88
+f 87 34416 34369
+f 34368 87 34369
+f 34417 34370 34369
+f 34416 34417 34369
+f 34418 34371 34370
+f 34417 34418 34370
+f 34419 34372 34371
+f 34418 34419 34371
+f 34420 34373 34372
+f 34419 34420 34372
+f 34421 34374 34373
+f 34420 34421 34373
+f 34422 34375 34374
+f 34421 34422 34374
+f 34423 34376 34375
+f 34422 34423 34375
+f 34424 34377 34376
+f 34423 34424 34376
+f 34425 34378 34377
+f 34424 34425 34377
+f 34426 34379 34378
+f 34425 34426 34378
+f 34427 34380 34379
+f 34426 34427 34379
+f 34428 34381 34380
+f 34427 34428 34380
+f 34429 34382 34381
+f 34428 34429 34381
+f 34429 34247 21358
+f 34382 34429 21358
+f 7226 21731 7227
+f 2470 33394 18387
+f 32076 32077 32144
+f 9525 15395 7344
+f 34393 34394 33873
+f 34430 33876 33875
+f 34394 34430 33875
+f 34431 33894 33876
+f 34430 34431 33876
+f 34432 33895 33894
+f 32369 4503 32370
+f 32413 31159 31206
+f 21113 21359 33793
+f 1340 1956 1341
+f 12636 34433 34385
+f 22001 12636 34385
+f 34433 34434 34386
+f 34385 34433 34386
+f 34434 34435 34387
+f 34386 34434 34387
+f 34435 34436 34388
+f 34387 34435 34388
+f 34436 34437 34389
+f 34388 34436 34389
+f 34437 34438 34390
+f 34389 34437 34390
+f 34438 12830 25549
+f 34390 34438 25549
+f 33902 12706 32209
+f 12706 33902 33423
+f 8678 8680 10804
+f 16163 5195 5197
+f 32211 31856 30471
+f 5961 5963 29471
+f 32006 32836 32264
+f 32648 32537 32264
+f 17613 32500 17185
+f 32536 32575 33517
+f 17116 32642 32556
+f 17117 17116 32556
+f 17893 32230 23859
+f 28552 15507 7544
+f 32367 32247 31679
+f 31954 32609 31946
+f 15914 33566 15910
+f 31673 18981 15001
+f 34431 34432 33894
+f 34439 33896 33895
+f 34432 34439 33895
+f 34440 33921 33896
+f 34439 34440 33896
+f 34441 33922 33921
+f 34440 34441 33921
+f 22646 22647 33922
+f 34442 34395 24808
+f 18182 34442 24808
+f 34443 34396 34395
+f 34442 34443 34395
+f 34444 34397 34396
+f 34443 34444 34396
+f 34445 34398 34397
+f 34444 34445 34397
+f 34446 34399 34398
+f 34445 34446 34398
+f 34447 34400 34399
+f 34446 34447 34399
+f 34448 34401 34400
+f 34447 34448 34400
+f 34449 34402 34401
+f 34448 34449 34401
+f 34450 34403 34402
+f 34449 34450 34402
+f 34451 34404 34403
+f 34450 34451 34403
+f 34452 34405 34404
+f 34451 34452 34404
+f 34453 34406 34405
+f 34452 34453 34405
+f 34454 34407 34406
+f 34453 34454 34406
+f 162 161 34407
+f 34454 162 34407
+f 160 34408 161
+f 34455 34409 34408
+f 160 34455 34408
+f 34456 34410 34409
+f 34455 34456 34409
+f 34457 34411 34410
+f 34456 34457 34410
+f 34458 34412 34411
+f 34457 34458 34411
+f 34459 34413 34412
+f 34458 34459 34412
+f 34460 34414 34413
+f 34459 34460 34413
+f 34460 34461 34415
+f 34414 34460 34415
+f 34461 118 117
+f 34415 34461 117
+f 89 34416 87
+f 34462 34417 34416
+f 89 34462 34416
+f 34463 34418 34417
+f 34462 34463 34417
+f 34464 34419 34418
+f 34463 34464 34418
+f 34465 34420 34419
+f 34464 34465 34419
+f 34466 34421 34420
+f 34465 34466 34420
+f 34467 34422 34421
+f 34466 34467 34421
+f 34468 34423 34422
+f 34467 34468 34422
+f 34469 34424 34423
+f 34468 34469 34423
+f 34470 34425 34424
+f 34469 34470 34424
+f 34471 34426 34425
+f 34470 34471 34425
+f 34472 34427 34426
+f 34471 34472 34426
+f 34473 34428 34427
+f 34472 34473 34427
+f 34474 34429 34428
+f 34473 34474 34428
+f 34475 34247 34429
+f 34474 34475 34429
+f 34247 21359 21358
+f 34475 33793 34247
+f 12707 21401 12705
+f 15258 13811 14549
+f 34441 22646 33922
+f 15688 17699 16789
+f 16160 17601 17600
+f 31308 32830 31588
+f 26469 26375 26374
+f 127 32145 125
+f 33568 33566 16008
+f 3020 16380 2826
+f 12832 6104 5978
+f 11070 32127 34434
+f 21113 15607 21110
+f 34433 11070 34434
+f 15607 21113 33793
+f 32127 34476 34435
+f 34434 32127 34435
+f 34476 34477 34436
+f 34435 34476 34436
+f 34477 34478 34437
+f 34436 34477 34437
+f 34478 34479 34438
+f 34437 34478 34438
+f 34479 12831 12830
+f 34438 34479 12830
+f 22348 10306 5633
+f 21070 6390 6264
+f 13309 32278 32481
+f 15598 15600 21360
+f 31839 32211 21785
+f 14733 32969 30472
+f 32648 32647 32537
+f 32812 32544 32542
+f 32833 32806 13400
+f 32497 33517 33333
+f 31896 32644 32643
+f 31692 31896 32643
+f 5963 15515 32967
+f 32161 32191 32495
+f 14865 25304 31548
+f 32660 32891 32661
+f 33622 33568 16015
+f 17019 4945 14870
+f 31772 31710 31653
+f 29835 4341 34093
+f 11591 20182 33773
+f 17865 17896 17898
+f 11592 11591 33773
+f 13570 3095 15005
+f 31943 31950 32263
+f 34480 34442 18182
+f 18181 34480 18182
+f 34481 34443 34442
+f 34480 34481 34442
+f 34482 34444 34443
+f 34481 34482 34443
+f 34483 34445 34444
+f 34482 34483 34444
+f 34484 34446 34445
+f 34483 34484 34445
+f 34485 34447 34446
+f 34484 34485 34446
+f 34486 34448 34447
+f 34485 34486 34447
+f 34487 34449 34448
+f 34486 34487 34448
+f 34488 34450 34449
+f 34487 34488 34449
+f 34489 34451 34450
+f 34488 34489 34450
+f 34490 34452 34451
+f 34489 34490 34451
+f 34491 34453 34452
+f 34490 34491 34452
+f 34492 34454 34453
+f 34491 34492 34453
+f 34493 162 34454
+f 34492 34493 34454
+f 34493 163 162
+f 199 34455 160
+f 34494 34456 34455
+f 199 34494 34455
+f 34495 34457 34456
+f 34494 34495 34456
+f 34496 34458 34457
+f 34495 34496 34457
+f 34497 34459 34458
+f 34496 34497 34458
+f 34498 34460 34459
+f 34497 34498 34459
+f 34498 34499 34461
+f 34460 34498 34461
+f 34499 115 118
+f 34461 34499 118
+f 91 34462 89
+f 34500 34463 34462
+f 91 34500 34462
+f 34501 34464 34463
+f 34500 34501 34463
+f 34502 34465 34464
+f 34501 34502 34464
+f 34503 34466 34465
+f 34502 34503 34465
+f 34504 34467 34466
+f 34503 34504 34466
+f 34505 34468 34467
+f 34504 34505 34467
+f 34506 34469 34468
+f 34505 34506 34468
+f 34507 34470 34469
+f 34506 34507 34469
+f 34508 34471 34470
+f 34507 34508 34470
+f 34509 34472 34471
+f 34508 34509 34471
+f 34510 34473 34472
+f 34509 34510 34472
+f 34511 34474 34473
+f 34510 34511 34473
+f 34512 34475 34474
+f 34511 34512 34474
+f 32128 33793 34475
+f 34512 32128 34475
+f 16177 34289 32281
+f 22995 23053 22985
+f 3094 15005 3095
+f 32649 32343 31260
+f 31649 31772 141
+f 31412 31411 32390
+f 33566 21198 15910
+f 33623 33622 13004
+f 33295 2728 2727
+f 32782 31209 32649
+f 22635 22707 22696
+f 32126 21178 21576
+f 34433 12636 11070
+f 12831 16104 21070
+f 34513 34476 32127
+f 32126 34513 32127
+f 34514 34477 34476
+f 34513 34514 34476
+f 34514 34515 34478
+f 34477 34514 34478
+f 34515 34516 34479
+f 34478 34515 34479
+f 34516 16104 12831
+f 34479 34516 12831
+f 1871 1870 6259
+f 32526 12218 18120
+f 29200 31808 31807
+f 15414 15444 15415
+f 32211 30471 21785
+f 31856 30472 30471
+f 32647 32812 32542
+f 33059 32539 32544
+f 32833 13400 13399
+f 32500 33333 17185
+f 31789 32589 32644
+f 31896 31789 32644
+f 32913 32806 32833
+f 33920 32586 32588
+f 22272 31787 31896
+f 33472 32662 32663
+f 33622 16015 13004
+f 33566 15914 16008
+f 31844 15719 19
+f 2919 2918 32559
+f 33473 33474 32386
+f 8980 8979 4434
+f 5339 32357 4229
+f 34095 32447 32446
+f 21731 7226 15513
+f 18243 34480 18181
+f 34517 34481 34480
+f 18243 34517 34480
+f 34518 34482 34481
+f 34517 34518 34481
+f 34519 34483 34482
+f 34518 34519 34482
+f 34520 34484 34483
+f 34519 34520 34483
+f 34521 34485 34484
+f 34520 34521 34484
+f 34522 34486 34485
+f 34521 34522 34485
+f 34523 34487 34486
+f 34522 34523 34486
+f 34524 34488 34487
+f 34523 34524 34487
+f 34525 34489 34488
+f 34524 34525 34488
+f 34526 34490 34489
+f 34525 34526 34489
+f 34527 34491 34490
+f 34526 34527 34490
+f 34528 34492 34491
+f 34527 34528 34491
+f 34529 34493 34492
+f 34528 34529 34492
+f 164 163 34493
+f 34529 164 34493
+f 34530 34494 199
+f 198 34530 199
+f 34531 34495 34494
+f 34530 34531 34494
+f 34532 34496 34495
+f 34531 34532 34495
+f 34533 34497 34496
+f 34532 34533 34496
+f 34534 34498 34497
+f 34533 34534 34497
+f 34534 34535 34499
+f 34498 34534 34499
+f 34535 116 115
+f 34499 34535 115
+f 34536 34500 91
+f 90 34536 91
+f 34537 34501 34500
+f 34536 34537 34500
+f 34538 34502 34501
+f 34537 34538 34501
+f 34539 34503 34502
+f 34538 34539 34502
+f 34540 34504 34503
+f 34539 34540 34503
+f 34541 34505 34504
+f 34540 34541 34504
+f 34542 34506 34505
+f 34541 34542 34505
+f 34543 34507 34506
+f 34542 34543 34506
+f 34544 34508 34507
+f 34543 34544 34507
+f 34545 34509 34508
+f 34544 34545 34508
+f 34546 34510 34509
+f 34545 34546 34509
+f 34547 34511 34510
+f 34546 34547 34510
+f 34548 34512 34511
+f 34547 34548 34511
+f 15608 32128 34512
+f 34548 15608 34512
+f 23988 18097 26758
+f 22585 22539 22636
+f 8141 31072 8142
+f 33626 33623 13003
+f 34549 34095 32446
+f 25230 32371 130
+f 16174 25187 31313
+f 33568 16008 16015
+f 8 33626 9
+f 4807 33061 6611
+f 33824 33062 33061
+f 32868 32298 31923
+f 32560 31902 31901
+f 22659 14977 18878
+f 3264 2850 2728
+f 22833 34513 32126
+f 21576 22833 32126
+f 34550 34514 34513
+f 22833 34550 34513
+f 34551 34515 34514
+f 34550 34551 34514
+f 34551 16105 34516
+f 34515 34551 34516
+f 14181 32528 14700
+f 34516 16105 16104
+f 31359 32685 2498
+f 14994 1610 1050
+f 31898 31840 33424
+f 33014 29200 31807
+f 32819 32549 32547
+f 31839 21785 21784
+f 27329 31668 34552
+f 32812 33059 32544
+f 32587 32665 32525
+f 16010 16009 22625
+f 5310 8289 5025
+f 31987 32590 32589
+f 32330 32331 33160
+f 5956 32744 21241
+f 1 75 2917
+f 4807 33824 33061
+f 31163 33019 31164
+f 33630 1 2917
+f 31702 31724 31703
+f 14700 33118 10142
+f 22198 33533 22354
+f 21735 21502 15609
+f 32150 32149 32216
+f 24594 31948 24595
+f 31748 31750 32217
+f 34553 34517 18243
+f 18242 34553 18243
+f 34554 34518 34517
+f 34553 34554 34517
+f 34555 34519 34518
+f 34554 34555 34518
+f 34556 34520 34519
+f 34555 34556 34519
+f 34557 34521 34520
+f 34556 34557 34520
+f 34558 34522 34521
+f 34557 34558 34521
+f 34558 34559 34523
+f 34522 34558 34523
+f 34559 34560 34524
+f 34523 34559 34524
+f 34561 34525 34524
+f 34560 34561 34524
+f 34562 34526 34525
+f 34561 34562 34525
+f 34563 34527 34526
+f 34562 34563 34526
+f 34564 34528 34527
+f 34563 34564 34527
+f 34565 34529 34528
+f 34564 34565 34528
+f 34566 164 34529
+f 34565 34566 34529
+f 34566 165 164
+f 197 34530 198
+f 34567 34531 34530
+f 197 34567 34530
+f 34568 34532 34531
+f 34567 34568 34531
+f 34569 34533 34532
+f 34568 34569 34532
+f 34570 34534 34533
+f 34569 34570 34533
+f 34570 34571 34535
+f 34534 34570 34535
+f 34571 113 116
+f 34535 34571 116
+f 93 34536 90
+f 34572 34537 34536
+f 93 34572 34536
+f 34573 34538 34537
+f 34572 34573 34537
+f 34574 34539 34538
+f 34573 34574 34538
+f 34575 34540 34539
+f 34574 34575 34539
+f 34576 34541 34540
+f 34575 34576 34540
+f 34577 34542 34541
+f 34576 34577 34541
+f 34578 34543 34542
+f 34577 34578 34542
+f 34579 34544 34543
+f 34578 34579 34543
+f 34580 34545 34544
+f 34579 34580 34544
+f 34581 34546 34545
+f 34580 34581 34545
+f 34582 34547 34546
+f 34581 34582 34546
+f 34583 34548 34547
+f 34582 34583 34547
+f 16849 15608 34548
+f 34583 16849 34548
+f 15084 15083 15588
+f 15608 16849 15609
+f 33629 33630 17195
+f 21576 22832 22833
+f 32327 31897 32338
+f 31926 157 144
+f 28331 31992 19779
+f 31902 30993 31903
+f 33623 13004 13003
+f 22946 33674 17195
+f 33825 33063 33062
+f 33824 33825 33062
+f 32230 31709 23859
+f 27539 27541 31783
+f 15001 18982 14636
+f 31208 31901 27713
+f 9565 21787 11346
+f 6655 16104 6658
+f 21236 34550 22833
+f 21236 22832 21235
+f 34584 34551 34550
+f 21236 34584 34550
+f 17335 16105 34551
+f 34584 17335 34551
+f 23628 8302 21119
+f 8194 14913 14974
+f 29199 21980 31808
+f 32398 21981 21980
+f 31840 21784 33424
+f 31840 31839 21784
+f 32808 32547 32545
+f 32808 32819 32547
+f 31990 32726 32732
+f 31619 15911 15446
+f 32588 32587 32467
+f 26317 32635 32578
+f 32686 12920 32694
+f 33020 31165 20380
+f 32968 33160 33108
+f 32968 32330 33160
+f 33674 33629 17195
+f 33626 13003 9
+f 19765 34585 32695
+f 10572 28331 19779
+f 31969 32693 31994
+f 32432 31781 22047
+f 22753 32972 22303
+f 33675 33674 14905
+f 15541 207 206
+f 34586 34553 18242
+f 18271 34586 18242
+f 34587 34554 34553
+f 34586 34587 34553
+f 34588 34555 34554
+f 34587 34588 34554
+f 34589 34556 34555
+f 34588 34589 34555
+f 34590 34557 34556
+f 34589 34590 34556
+f 34590 34591 34558
+f 34557 34590 34558
+f 34591 34592 34559
+f 34558 34591 34559
+f 34592 34593 34560
+f 34559 34592 34560
+f 34594 34561 34560
+f 34593 34594 34560
+f 34595 34562 34561
+f 34594 34595 34561
+f 34596 34563 34562
+f 34595 34596 34562
+f 34597 34564 34563
+f 34596 34597 34563
+f 34598 34565 34564
+f 34597 34598 34564
+f 34599 34566 34565
+f 34598 34599 34565
+f 166 165 34566
+f 34599 166 34566
+f 34600 34567 197
+f 196 34600 197
+f 34601 34568 34567
+f 34600 34601 34567
+f 34602 34569 34568
+f 34601 34602 34568
+f 34603 34570 34569
+f 34602 34603 34569
+f 34603 34604 34571
+f 34570 34603 34571
+f 34604 114 113
+f 34571 34604 113
+f 34605 34572 93
+f 92 34605 93
+f 34606 34573 34572
+f 34605 34606 34572
+f 34607 34574 34573
+f 34606 34607 34573
+f 34608 34575 34574
+f 34607 34608 34574
+f 34609 34576 34575
+f 34608 34609 34575
+f 34610 34577 34576
+f 34609 34610 34576
+f 34611 34578 34577
+f 34610 34611 34577
+f 34612 34579 34578
+f 34611 34612 34578
+f 34613 34580 34579
+f 34612 34613 34579
+f 34614 34581 34580
+f 34613 34614 34580
+f 34615 34582 34581
+f 34614 34615 34581
+f 34616 34583 34582
+f 34615 34616 34582
+f 17101 16849 34583
+f 34616 17101 34583
+f 29031 7548 20330
+f 20957 7063 21235
+f 33674 22946 14905
+f 16486 31307 32346
+f 23000 34342 32360
+f 22876 23000 32360
+f 21302 34343 34342
+f 23000 21302 34342
+f 33630 2917 17195
+f 33675 14905 22945
+f 33874 33108 33063
+f 33825 33874 33063
+f 32913 32666 32806
+f 29472 30813 32790
+f 31789 31987 32589
+f 31986 32524 32590
+f 14913 22587 14974
+f 9490 8479 8478
+f 7063 15448 21235
+f 30022 16960 17791
+f 15447 17891 34584
+f 21236 15447 34584
+f 29579 17335 34584
+f 17891 29579 34584
+f 32633 32636 26947
+f 30287 30286 32871
+f 32328 32338 32660
+f 29200 29199 31808
+f 32730 32729 32551
+f 31898 33424 32891
+f 32811 33059 32812
+f 32809 32808 32545
+f 61 28 32610
+f 32810 32812 32647
+f 32686 32694 31712
+f 32665 32578 32525
+f 34552 32834 34549
+f 17152 24395 24394
+f 33721 33676 31117
+f 33874 32968 33108
+f 5777 34344 34343
+f 33673 22945 31118
+f 21302 5777 34343
+f 18497 34383 34344
+f 5777 18497 34344
+f 26032 34384 34383
+f 18497 26032 34383
+f 34617 34586 18271
+f 18653 34617 18271
+f 34618 34587 34586
+f 34617 34618 34586
+f 34619 34588 34587
+f 34618 34619 34587
+f 34620 34589 34588
+f 34619 34620 34588
+f 34620 34621 34590
+f 34589 34620 34590
+f 34621 34622 34591
+f 34590 34621 34591
+f 34622 34623 34592
+f 34591 34622 34592
+f 34624 34593 34592
+f 34623 34624 34592
+f 34625 34594 34593
+f 34624 34625 34593
+f 34626 34595 34594
+f 34625 34626 34594
+f 34627 34596 34595
+f 34626 34627 34595
+f 34628 34597 34596
+f 34627 34628 34596
+f 34629 34598 34597
+f 34628 34629 34597
+f 34630 34599 34598
+f 34629 34630 34598
+f 34631 166 34599
+f 34630 34631 34599
+f 34631 167 166
+f 195 34600 196
+f 34632 34601 34600
+f 195 34632 34600
+f 34633 34602 34601
+f 34632 34633 34601
+f 34634 34603 34602
+f 34633 34634 34602
+f 34635 34604 34603
+f 34634 34635 34603
+f 34635 111 114
+f 34604 34635 114
+f 34636 34605 92
+f 94 34636 92
+f 34637 34606 34605
+f 34636 34637 34605
+f 34638 34607 34606
+f 34637 34638 34606
+f 34639 34608 34607
+f 34638 34639 34607
+f 34640 34609 34608
+f 34639 34640 34608
+f 34641 34610 34609
+f 34640 34641 34609
+f 34642 34611 34610
+f 34641 34642 34610
+f 34643 34612 34611
+f 34642 34643 34611
+f 34644 34613 34612
+f 34643 34644 34612
+f 34645 34614 34613
+f 34644 34645 34613
+f 34646 34615 34614
+f 34645 34646 34614
+f 34647 34616 34615
+f 34646 34647 34615
+f 32184 17101 34616
+f 34647 32184 34616
+f 4657 31456 4977
+f 15447 6946 17891
+f 33676 31118 31117
+f 15792 15794 28524
+f 26031 34391 34384
+f 26032 26031 34384
+f 19634 34392 34391
+f 26031 19634 34391
+f 33673 33675 22945
+f 33721 31117 32641
+f 33920 32588 31986
+f 16885 34648 16165
+f 26411 32913 32833
+f 32666 32723 32806
+f 31987 31986 32590
+f 32588 32467 32524
+f 32685 14357 14356
+f 15585 32833 13399
+f 20651 23861 20649
+f 32645 32591 32966
+f 32526 32989 17087
+f 16947 23124 23248
+f 10980 10979 26167
+f 17891 17890 29579
+f 29199 32398 21980
+f 32634 32633 26947
+f 31508 32328 32163
+f 32338 31898 32891
+f 32730 32551 32550
+f 32466 32657 32601
+f 33333 33517 34094
+f 15794 32654 28525
+f 26317 17439 32635
+f 22438 61 32610
+f 32679 31712 31711
+f 32679 32686 31712
+f 34552 34549 34649
+f 32834 32851 32534
+f 33720 32641 21926
+f 33676 33673 31118
+f 20294 34393 34392
+f 19634 20294 34392
+f 20293 34394 34393
+f 33776 33775 29470
+f 20294 20293 34393
+f 21409 34430 34394
+f 20293 21409 34394
+f 15883 34431 34430
+f 34650 34617 18653
+f 28371 34650 18653
+f 34651 34618 34617
+f 34650 34651 34617
+f 34652 34619 34618
+f 34651 34652 34618
+f 34653 34620 34619
+f 34652 34653 34619
+f 34653 34654 34621
+f 34620 34653 34621
+f 34654 34655 34622
+f 34621 34654 34622
+f 34655 34656 34623
+f 34622 34655 34623
+f 34657 34624 34623
+f 34656 34657 34623
+f 34658 34625 34624
+f 34657 34658 34624
+f 34659 34626 34625
+f 34658 34659 34625
+f 34660 34627 34626
+f 34659 34660 34626
+f 34661 34628 34627
+f 34660 34661 34627
+f 34662 34629 34628
+f 34661 34662 34628
+f 34663 34630 34629
+f 34662 34663 34629
+f 34664 34631 34630
+f 34663 34664 34630
+f 168 167 34631
+f 34664 168 34631
+f 34665 34632 195
+f 194 34665 195
+f 34666 34633 34632
+f 34665 34666 34632
+f 34667 34634 34633
+f 34666 34667 34633
+f 34668 34635 34634
+f 34667 34668 34634
+f 34668 112 111
+f 34635 34668 111
+f 34669 34636 94
+f 119 34669 94
+f 34670 34637 34636
+f 34669 34670 34636
+f 34671 34638 34637
+f 34670 34671 34637
+f 34672 34639 34638
+f 34671 34672 34638
+f 34673 34640 34639
+f 34672 34673 34639
+f 34674 34641 34640
+f 34673 34674 34640
+f 34675 34642 34641
+f 34674 34675 34641
+f 34676 34643 34642
+f 34675 34676 34642
+f 34677 34644 34643
+f 34676 34677 34643
+f 34678 34645 34644
+f 34677 34678 34644
+f 34679 34646 34645
+f 34678 34679 34645
+f 34680 34647 34646
+f 34679 34680 34646
+f 9802 32184 34647
+f 34680 9802 34647
+f 18981 27226 18982
+f 14758 14300 16682
+f 21409 15883 34430
+f 33776 29470 12501
+f 15799 34432 34431
+f 15883 15799 34431
+f 15798 34439 34432
+f 33720 33721 32641
+f 32557 25546 32329
+f 32789 34649 34648
+f 16885 32789 34648
+f 12920 19765 32694
+f 32680 31711 15516
+f 31986 32588 32524
+f 32587 32525 32467
+f 32806 17619 13400
+f 29471 5963 32585
+f 32809 32545 32539
+f 17175 17408 32594
+f 22628 27218 28620
+f 15600 22548 32318
+f 21750 32944 19603
+f 14242 10145 14147
+f 32634 26947 21981
+f 32398 32634 21981
+f 31509 31508 31904
+f 32338 32891 32660
+f 32874 32730 32550
+f 32729 32601 32551
+f 32837 32628 32630
+f 32646 32810 32647
+f 22438 32610 32612
+f 17439 22438 32612
+f 32725 15516 15637
+f 32680 32679 31711
+f 32789 34552 34649
+f 32834 34095 34549
+f 33726 150 16011
+f 33725 33720 21926
+f 15799 15798 34432
+f 17029 34440 34439
+f 33775 33774 5961
+f 15798 17029 34439
+f 2595 33776 12501
+f 33774 5962 5961
+f 16547 34441 34440
+f 17029 16547 34440
+f 16547 16549 22646
+f 34441 16547 22646
+f 34681 34650 28371
+f 18929 34681 28371
+f 34682 34651 34650
+f 34681 34682 34650
+f 34683 34652 34651
+f 34682 34683 34651
+f 34684 34653 34652
+f 34683 34684 34652
+f 34684 34685 34654
+f 34653 34684 34654
+f 34685 34686 34655
+f 34654 34685 34655
+f 34686 34687 34656
+f 34655 34686 34656
+f 34688 34657 34656
+f 34687 34688 34656
+f 34689 34658 34657
+f 34688 34689 34657
+f 34690 34659 34658
+f 34689 34690 34658
+f 34691 34660 34659
+f 34690 34691 34659
+f 34692 34661 34660
+f 34691 34692 34660
+f 34693 34662 34661
+f 34692 34693 34661
+f 34694 34663 34662
+f 34693 34694 34662
+f 34695 34664 34663
+f 34694 34695 34663
+f 34696 168 34664
+f 34695 34696 34664
+f 34696 169 168
+f 193 34665 194
+f 34697 34666 34665
+f 193 34697 34665
+f 34698 34667 34666
+f 34697 34698 34666
+f 34699 34668 34667
+f 34698 34699 34667
+f 34699 34700 112
+f 34668 34699 112
+f 34700 110 112
+f 34701 34669 119
+f 95 34701 119
+f 34702 34670 34669
+f 34701 34702 34669
+f 34703 34671 34670
+f 34702 34703 34670
+f 34704 34672 34671
+f 34703 34704 34671
+f 34705 34673 34672
+f 34704 34705 34672
+f 34706 34674 34673
+f 34705 34706 34673
+f 34707 34675 34674
+f 34706 34707 34674
+f 34708 34676 34675
+f 34707 34708 34675
+f 34709 34677 34676
+f 34708 34709 34676
+f 34710 34678 34677
+f 34709 34710 34677
+f 34711 34679 34678
+f 34710 34711 34678
+f 22164 34680 34679
+f 34711 22164 34679
+f 22164 9800 9802
+f 34680 22164 9802
+f 17153 20053 22293
+f 13811 14922 13384
+f 14922 22646 15129
+f 2138 8706 16682
+f 33724 33473 32388
+f 14906 32367 31757
+f 31841 29835 34093
+f 31754 31706 4758
+f 32228 32252 31764
+f 34095 32834 32534
+f 32851 23878 32103
+f 32725 32680 15516
+f 32820 32664 32586
+f 32665 26317 32578
+f 17439 32612 32635
+f 31668 32834 34552
+f 32607 32696 32608
+f 32874 32550 32549
+f 33059 32809 32539
+f 20838 20837 32237
+f 31509 31904 31877
+f 31213 32786 32944
+f 32229 21750 19603
+f 32971 32580 32636
+f 32633 32971 32636
+f 20837 31509 31877
+f 32328 32660 32163
+f 32729 32466 32601
+f 32465 32655 32657
+f 21784 21786 33425
+f 33517 33518 34094
+f 15517 32710 26
+f 25 15517 26
+f 32822 26316 32664
+f 32724 32725 15637
+f 32534 32851 32103
+f 23878 23880 17535
+f 135 21925 133
+f 33725 21926 21925
+f 33726 16011 5962
+f 135 33725 21925
+f 33774 33726 5962
+f 150 152 16011
+f 33775 5961 29470
+f 32693 32692 31411
+f 17125 25045 17123
+f 31809 32749 32414
+f 32106 32105 31460
+f 32065 32691 17897
+f 34712 34681 18929
+f 18928 34712 18929
+f 34713 34682 34681
+f 34712 34713 34681
+f 34714 34683 34682
+f 34713 34714 34682
+f 34715 34684 34683
+f 34714 34715 34683
+f 34715 34716 34685
+f 34684 34715 34685
+f 34716 34717 34686
+f 34685 34716 34686
+f 34717 34718 34687
+f 34686 34717 34687
+f 34719 34688 34687
+f 34718 34719 34687
+f 34720 34689 34688
+f 34719 34720 34688
+f 34721 34690 34689
+f 34720 34721 34689
+f 34722 34691 34690
+f 34721 34722 34690
+f 34723 34692 34691
+f 34722 34723 34691
+f 34724 34693 34692
+f 34723 34724 34692
+f 34725 34694 34693
+f 34724 34725 34693
+f 34726 34695 34694
+f 34725 34726 34694
+f 34727 34696 34695
+f 34726 34727 34695
+f 170 169 34696
+f 34727 170 34696
+f 34728 34697 193
+f 192 34728 193
+f 34729 34698 34697
+f 34728 34729 34697
+f 34730 34699 34698
+f 34729 34730 34698
+f 34730 34731 34700
+f 34699 34730 34700
+f 108 110 34700
+f 34731 108 34700
+f 34732 34701 95
+f 97 34732 95
+f 34733 34702 34701
+f 34732 34733 34701
+f 34734 34703 34702
+f 34733 34734 34702
+f 34735 34704 34703
+f 34734 34735 34703
+f 34736 34705 34704
+f 34735 34736 34704
+f 34737 34706 34705
+f 34736 34737 34705
+f 34738 34707 34706
+f 34737 34738 34706
+f 34739 34708 34707
+f 34738 34739 34707
+f 34740 34709 34708
+f 34739 34740 34708
+f 34741 34710 34709
+f 34740 34741 34709
+f 34742 34711 34710
+f 34741 34742 34710
+f 22162 22164 34711
+f 34742 22162 34711
+f 14551 15258 14549
+f 2265 3795 2263
+f 4346 4168 4167
+f 12382 27511 16933
+f 32584 31845 26845
+f 15516 31711 15517
+f 17865 17898 17866
+f 32558 27030 15793
+f 16480 32867 16481
+f 32967 14720 32330
+f 22644 24592 22645
+f 31801 31981 31802
+f 31411 32692 33724
+f 20372 33473 33724
+f 32856 32820 32586
+f 32856 32586 33920
+f 31713 32753 32710
+f 15517 31713 32710
+f 32576 32678 32836
+f 32575 32574 33518
+f 32465 14910 32655
+f 32819 32874 32549
+f 32599 32598 32870
+f 30286 32599 32870
+f 4505 4504 32323
+f 21750 31213 32944
+f 33470 19602 32580
+f 32971 33470 32580
+f 31113 20838 31872
+f 31508 32163 31904
+f 32466 32465 32657
+f 14910 32658 32655
+f 33424 21784 33425
+f 32748 32606 32872
+f 33021 32788 32753
+f 33283 32730 32874
+f 32820 32822 32664
+f 31713 33021 32753
+f 32105 31994 31410
+f 32821 17438 26316
+f 17536 19780 32105
+f 31994 32693 31410
+f 32103 23878 17535
+f 23880 19780 17536
+f 17535 23880 17536
+f 19780 31994 32105
+f 31410 32693 31411
+f 32692 32823 33724
+f 8307 20380 31773
+f 24684 24686 14923
+f 32224 33994 6169
+f 32059 32062 32205
+f 34743 34712 18928
+f 28351 34743 18928
+f 34744 34713 34712
+f 34743 34744 34712
+f 34745 34714 34713
+f 34744 34745 34713
+f 34745 34746 34715
+f 34714 34745 34715
+f 34746 34747 34716
+f 34715 34746 34716
+f 34747 34748 34717
+f 34716 34747 34717
+f 34748 34749 34718
+f 34717 34748 34718
+f 34750 34719 34718
+f 34749 34750 34718
+f 34751 34720 34719
+f 34750 34751 34719
+f 34752 34721 34720
+f 34751 34752 34720
+f 34753 34722 34721
+f 34752 34753 34721
+f 34754 34723 34722
+f 34753 34754 34722
+f 34755 34724 34723
+f 34754 34755 34723
+f 34756 34725 34724
+f 34755 34756 34724
+f 34757 34726 34725
+f 34756 34757 34725
+f 34758 34727 34726
+f 34757 34758 34726
+f 171 170 34727
+f 34758 171 34727
+f 34759 34728 192
+f 191 34759 192
+f 34760 34729 34728
+f 34759 34760 34728
+f 34761 34730 34729
+f 34760 34761 34729
+f 34762 34731 34730
+f 34761 34762 34730
+f 109 108 34731
+f 34762 109 34731
+f 96 34763 97
+f 34764 34732 97
+f 34763 34764 97
+f 34765 34733 34732
+f 34764 34765 34732
+f 34766 34734 34733
+f 34765 34766 34733
+f 34767 34735 34734
+f 34766 34767 34734
+f 34768 34736 34735
+f 34767 34768 34735
+f 34769 34737 34736
+f 34768 34769 34736
+f 34770 34738 34737
+f 34769 34770 34737
+f 34771 34739 34738
+f 34770 34771 34738
+f 34772 34740 34739
+f 34771 34772 34739
+f 32358 34741 34740
+f 34772 32358 34740
+f 17326 34742 34741
+f 32358 17326 34741
+f 6956 22162 34742
+f 17326 6956 34742
+f 6956 22163 22162
+f 10144 14180 14181
+f 32061 32095 31662
+f 31359 32831 32685
+f 31960 21285 32262
+f 27353 31988 27354
+f 31785 15468 17618
+f 31950 31960 32262
+f 25109 18060 6585
+f 31777 31779 31899
+f 32823 20372 33724
+f 22499 33076 33474
+f 31111 33474 33473
+f 20372 31111 33473
+f 32914 32856 33920
+f 33034 32985 31788
+f 131 21927 132
+f 3795 2265 26714
+f 32586 32664 32587
+f 22351 12836 33352
+f 17617 14413 32706
+f 14909 32659 32658
+f 32742 28755 30285
+f 32600 32599 30286
+f 32746 32745 32323
+f 32745 27587 32323
+f 32229 19603 19602
+f 33470 32229 19602
+f 31113 31872 24285
+f 20837 31877 32237
+f 14910 14909 32658
+f 30990 31606 32659
+f 17988 17990 31606
+f 14909 30990 32659
+f 32807 32817 32808
+f 2831 2833 5341
+f 32688 14641 14577
+f 31590 31591 32349
+f 32822 32821 26316
+f 14641 32688 32690
+f 78 62 17438
+f 32821 78 17438
+f 32724 15637 24
+f 23 32724 24
+f 22271 33017 22272
+f 33017 33034 31787
+f 31111 22499 33474
+f 32731 17893 17892
+f 32480 24670 32986
+f 24670 26873 32986
+f 34549 32446 32501
+f 32345 31312 32233
+f 34773 34743 28351
+f 28548 34773 28351
+f 34774 34744 34743
+f 34773 34774 34743
+f 34775 34745 34744
+f 34774 34775 34744
+f 34775 34776 34746
+f 34745 34775 34746
+f 34776 34777 34747
+f 34746 34776 34747
+f 34777 34778 34748
+f 34747 34777 34748
+f 34778 34779 34749
+f 34748 34778 34749
+f 34780 34750 34749
+f 34779 34780 34749
+f 34781 34751 34750
+f 34780 34781 34750
+f 34782 34752 34751
+f 34781 34782 34751
+f 34783 34753 34752
+f 34782 34783 34752
+f 34784 34754 34753
+f 34783 34784 34753
+f 34785 34755 34754
+f 34784 34785 34754
+f 34786 34756 34755
+f 34785 34786 34755
+f 34787 34757 34756
+f 34786 34787 34756
+f 34788 34758 34757
+f 34787 34788 34757
+f 34789 171 34758
+f 34788 34789 34758
+f 34789 172 171
+f 190 34759 191
+f 34790 34760 34759
+f 190 34790 34759
+f 34791 34761 34760
+f 34790 34791 34760
+f 34791 34792 34762
+f 34761 34791 34762
+f 34793 109 34762
+f 34792 34793 34762
+f 34793 105 109
+f 34794 34763 96
+f 98 34794 96
+f 34795 34764 34763
+f 34794 34795 34763
+f 34796 34765 34764
+f 34795 34796 34764
+f 34797 34766 34765
+f 34796 34797 34765
+f 34798 34767 34766
+f 34797 34798 34766
+f 34799 34768 34767
+f 34798 34799 34767
+f 34800 34769 34768
+f 34799 34800 34768
+f 34801 34770 34769
+f 34800 34801 34769
+f 34802 34771 34770
+f 34801 34802 34770
+f 34803 34772 34771
+f 34802 34803 34771
+f 13005 32358 34772
+f 34803 13005 34772
+f 1799 22391 16617
+f 25321 19013 25251
+f 6957 6956 17326
+f 6956 6955 22163
+f 25321 14624 12512
+f 20078 944 7640
+f 34649 32501 32504
+f 34649 34549 32501
+f 34648 32504 17027
+f 32830 31590 31588
+f 32252 32557 31765
+f 31991 32614 33076
+f 32585 32968 33874
+f 33018 22273 17115
+f 22499 31991 33076
+f 32914 33920 31985
+f 32985 31985 31788
+f 31689 31690 31930
+f 32985 32914 31985
+f 16886 31941 16885
+f 32873 32852 32225
+f 17719 32751 32709
+f 29198 32397 29199
+f 28755 32600 30285
+f 14413 17719 32709
+f 4510 6083 4508
+f 30285 32600 30286
+f 31910 31259 28007
+f 16389 3318 11202
+f 31212 32224 32786
+f 31213 31212 32786
+f 21746 31113 24285
+f 20838 32237 31872
+f 32598 32597 32651
+f 32596 32029 32652
+f 32775 17617 32677
+f 14413 32709 32706
+f 32775 32677 32631
+f 17617 32706 32677
+f 32754 51 31469
+f 32754 31469 32755
+f 34585 14641 32690
+f 5923 9852 6167
+f 34585 32690 32835
+f 32695 34585 32835
+f 32695 32835 32788
+f 33021 32695 32788
+f 33018 22271 22273
+f 33034 31788 31787
+f 31991 32732 32614
+f 33723 32731 17892
+f 17115 22273 17116
+f 25547 32645 31737
+f 34648 34649 32504
+f 34585 19765 14641
+f 34804 34773 28548
+f 28549 34804 28548
+f 34805 34774 34773
+f 34804 34805 34773
+f 34806 34775 34774
+f 34805 34806 34774
+f 34806 34807 34776
+f 34775 34806 34776
+f 34807 34808 34777
+f 34776 34807 34777
+f 34808 34809 34778
+f 34777 34808 34778
+f 34810 34779 34778
+f 34809 34810 34778
+f 34811 34780 34779
+f 34810 34811 34779
+f 34812 34781 34780
+f 34811 34812 34780
+f 34813 34782 34781
+f 34812 34813 34781
+f 34814 34783 34782
+f 34813 34814 34782
+f 34815 34784 34783
+f 34814 34815 34783
+f 34816 34785 34784
+f 34815 34816 34784
+f 34817 34786 34785
+f 34816 34817 34785
+f 34818 34787 34786
+f 34817 34818 34786
+f 34819 34788 34787
+f 34818 34819 34787
+f 34820 34789 34788
+f 34819 34820 34788
+f 173 172 34789
+f 34820 173 34789
+f 34821 34790 190
+f 189 34821 190
+f 34822 34791 34790
+f 34821 34822 34790
+f 34823 34792 34791
+f 34822 34823 34791
+f 34824 34793 34792
+f 34823 34824 34792
+f 34824 107 105
+f 34793 34824 105
+f 34825 34794 98
+f 100 34825 98
+f 34826 34795 34794
+f 34825 34826 34794
+f 34827 34796 34795
+f 34826 34827 34795
+f 34828 34797 34796
+f 34827 34828 34796
+f 34829 34798 34797
+f 34828 34829 34797
+f 34830 34799 34798
+f 34829 34830 34798
+f 34831 34800 34799
+f 34830 34831 34799
+f 34832 34801 34800
+f 34831 34832 34800
+f 34833 34802 34801
+f 34832 34833 34801
+f 34834 34803 34802
+f 34833 34834 34802
+f 14339 13005 34803
+f 34834 14339 34803
+f 14757 32973 8979
+f 22078 32792 32805
+f 9801 9800 12461
+f 31853 31806 32535
+f 16165 34648 17027
+f 32026 31032 31031
+f 19780 19779 31994
+f 31685 19778 23879
+f 31588 32349 31589
+f 32591 21522 32966
+f 23859 22320 23860
+f 32732 33722 32614
+f 33020 31163 31165
+f 33019 17115 31164
+f 17739 31587 31893
+f 31656 31686 31688
+f 30816 15586 32722
+f 21927 32225 132
+f 24432 24434 32751
+f 27329 34552 32789
+f 28754 28434 22084
+f 17719 24432 32751
+f 22083 28754 22084
+f 28755 32742 28434
+f 31209 31818 32343
+f 32863 4504 29087
+f 9194 8143 9195
+f 32830 31958 31590
+f 32755 33994 32224
+f 31212 32755 32224
+f 32755 31469 33994
+f 31469 49 33994
+f 32870 32598 32651
+f 32595 32652 32651
+f 32595 32596 32652
+f 32597 32595 32651
+f 17989 14507 21477
+f 14508 32775 32631
+f 32652 32029 32031
+f 23422 32750 32030
+f 31848 33472 31849
+f 33472 32663 31849
+f 30816 15585 15586
+f 15912 31620 32221
+f 17739 31893 17740
+f 32873 32040 32852
+f 33019 33018 17115
+f 33017 31787 22272
+f 32732 32731 33723
+f 33722 32732 33723
+f 32966 21522 21524
+f 27241 32613 32913
+f 31073 31031 27328
+f 33162 31860 31867
+f 21507 34804 28549
+f 21508 21507 28549
+f 22505 34805 34804
+f 21507 22505 34804
+f 27369 34806 34805
+f 22505 27369 34805
+f 27369 18010 34807
+f 34806 27369 34807
+f 18010 21037 34808
+f 34807 18010 34808
+f 21037 14866 34809
+f 34808 21037 34809
+f 31548 34810 34809
+f 14866 31548 34809
+f 25306 34811 34810
+f 31548 25306 34810
+f 652 34812 34811
+f 25306 652 34811
+f 651 34813 34812
+f 652 651 34812
+f 32825 34814 34813
+f 651 32825 34813
+f 18773 34815 34814
+f 32825 18773 34814
+f 11286 34816 34815
+f 18773 11286 34815
+f 11285 34817 34816
+f 11286 11285 34816
+f 10024 34818 34817
+f 11285 10024 34817
+f 10023 34819 34818
+f 10024 10023 34818
+f 16003 34820 34819
+f 10023 16003 34819
+f 4948 173 34820
+f 16003 4948 34820
+f 4948 174 173
+f 188 34821 189
+f 12746 34822 34821
+f 188 12746 34821
+f 12745 34823 34822
+f 12746 12745 34822
+f 12745 21648 34824
+f 34823 12745 34824
+f 21648 21076 107
+f 34824 21648 107
+f 21076 106 107
+f 3813 34825 100
+f 99 3813 100
+f 6237 34826 34825
+f 3813 6237 34825
+f 6394 34827 34826
+f 6237 6394 34826
+f 6393 34828 34827
+f 6394 6393 34827
+f 17798 34829 34828
+f 6393 17798 34828
+f 15596 34830 34829
+f 17798 15596 34829
+f 15595 34831 34830
+f 15596 15595 34830
+f 14426 34832 34831
+f 15595 14426 34831
+f 14425 34833 34832
+f 14426 14425 34832
+f 28005 34834 34833
+f 14425 28005 34833
+f 21761 14339 34834
+f 28005 21761 34834
+f 2118 2623 4851
+f 34029 30957 21765
+f 21758 30957 22361
+f 30957 21758 21765
+f 21765 21758 21759
+f 33423 33941 34835
+f 33941 33940 34835
+f 33940 33899 34835
+f 33899 33898 34835
+f 33898 33897 34835
+f 33897 20499 34835
+f 20499 8706 34835
+f 8706 460 34835
+f 460 459 34835
+f 459 4466 34835
+f 4466 4465 34835
+f 4465 19979 34835
+f 19979 16601 34835
+f 16601 16546 34835
+f 16546 16324 34835
+f 16324 16323 34835
+f 16323 16322 34835
+f 16322 20914 34835
+f 20914 20916 34835
+f 20916 22065 34835
+f 22065 12707 34835
+f 12707 33423 34835
diff --git a/data/models/cat.3ds b/data/models/cat.3ds
new file mode 100644
index 0000000..c6cce29
--- /dev/null
+++ b/data/models/cat.3ds
Binary files differ
diff --git a/data/models/cube.3ds b/data/models/cube.3ds
new file mode 100644
index 0000000..35b8300
--- /dev/null
+++ b/data/models/cube.3ds
Binary files differ
diff --git a/data/models/horse.3ds b/data/models/horse.3ds
new file mode 100644
index 0000000..4aa0c3c
--- /dev/null
+++ b/data/models/horse.3ds
Binary files differ
diff --git a/data/models/jellyfish.jobj b/data/models/jellyfish.jobj
new file mode 100644
index 0000000..2ce5e2c
--- /dev/null
+++ b/data/models/jellyfish.jobj
@@ -0,0 +1,24432 @@
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.271150618792 1.56851112843 0.00000000000
+v 0.265946507454 1.56851112843 -0.0528689213097
+v 0.250522226095 1.56851112843 -0.103736661375
+v 0.225470513105 1.56851112843 -0.150617852807
+v 0.191754087806 1.56851112843 -0.191710904241
+v 0.150668665767 1.56851112843 -0.225436612964
+v 0.103793129325 1.56851112843 -0.250498920679
+v 0.0529288947582 1.56851112843 -0.265934675932
+v 0.00000000000 1.56851112843 -0.271150738001
+v 0.525979161263 1.56077754498 0.00000000000
+v 0.515896677971 1.56077754498 -0.102492742240
+v 0.485988527536 1.56077754498 -0.201169818640
+v 0.437404125929 1.56077754498 -0.292116075754
+v 0.372010529041 1.56077754498 -0.371836453676
+v 0.292320758104 1.56077754498 -0.437267392874
+v 0.201397284865 1.56077754498 -0.485894382000
+v 0.102734237909 1.56077754498 -0.515848755836
+v 0.00000000000 1.56077754498 -0.525979340076
+v 0.779304146767 1.53255486488 0.00000000000
+v 0.764382541180 1.53255486488 -0.151770964265
+v 0.720086097717 1.53255486488 -0.297978371382
+v 0.648117184639 1.53255486488 -0.432734668255
+v 0.551241457462 1.53255486488 -0.550861239433
+v 0.433181852102 1.53255486488 -0.647818505764
+v 0.298475265503 1.53255486488 -0.719880402088
+v 0.152298495173 1.53255486488 -0.764277815819
+v 0.00000000000 1.53255486488 -0.779304385185
+v 1.02816593647 1.47749805450 0.00000000000
+v 1.00848352909 1.47749805450 -0.200215876102
+v 0.950045704842 1.47749805450 -0.393114209175
+v 0.855098009109 1.47749805450 -0.570905327797
+v 0.727289497852 1.47749805450 -0.726756870747
+v 0.571531653404 1.47749805450 -0.854679703712
+v 0.393810063601 1.47749805450 -0.949757516384
+v 0.200954675674 1.47749817371 -1.00833678246
+v 0.00000000000 1.47749817371 -1.02816617489
+v 1.26983809471 1.39657485485 0.00000000000
+v 1.24549603462 1.39657485485 -0.247444033623
+v 1.17329025269 1.39657485485 -0.485673725605
+v 1.05599558353 1.39657485485 -0.705239236355
+v 0.898119568825 1.39657485485 -0.897702872753
+v 0.705729365349 1.39657497406 -1.05566823483
+v 0.486218273640 1.39657497406 -1.17306482792
+v 0.248022228479 1.39657497406 -1.24538123608
+v 0.00000000000 1.39657497406 -1.26983833313
+v 1.49952828884 1.28625142574 0.00000000000
+v 1.47073674202 1.28625142574 -0.292435467243
+v 1.38542568684 1.28625142574 -0.573742866516
+v 1.24687337875 1.28625142574 -0.833001852036
+v 1.06040453911 1.28625154495 -1.06024897099
+v 0.833184838295 1.28625154495 -1.24675130844
+v 0.573946356773 1.28625154495 -1.38534164429
+v 0.292651504278 1.28625154495 -1.47069406509
+v 0.00000000000 1.28625154495 -1.49952852726
+v 1.71322810650 1.14743721485 0.00000000000
+v 1.68031167984 1.14743721485 -0.334220170975
+v 1.58282196522 1.14743721485 -0.655610799789
+v 1.42450511456 1.14743721485 -0.951806783676
+v 1.21144545078 1.14743733406 -1.21142530441
+v 0.951830387115 1.14743733406 -1.42448937893
+v 0.655637204647 1.14743733406 -1.58281123638
+v 0.334248304367 1.14743733406 -1.68030643463
+v 0.00000000000 1.14743733406 -1.71322846413
+v 1.90656912327 0.981508374214 0.00000000000
+v 1.86993503571 0.981508374214 -0.371953219175
+v 1.76144027710 0.981508433819 -0.729612529278
+v 1.58525431156 0.981508433819 -1.05923318863
+v 1.34814798832 0.981508433819 -1.34814810753
+v 1.05923295021 0.981508493423 -1.58525466919
+v 0.729612410069 0.981508493423 -1.76144039631
+v 0.371953248978 0.981508493423 -1.86993515491
+v 0.00000000000 0.981508493423 -1.90656936169
+v 2.07388091087 0.789333820343 0.00000000000
+v 2.03403186798 0.789333820343 -0.404594153166
+v 1.91601622105 0.789333879948 -0.793640017509
+v 1.72436892986 0.789333879948 -1.15218663216
+v 1.46645522118 0.789333879948 -1.46645534039
+v 1.15218639374 0.789333939552 -1.72436928749
+v 0.793639838696 0.789333939552 -1.91601634026
+v 0.404594153166 0.789333939552 -2.03403210640
+v 0.00000000000 0.789333939552 -2.07388114929
+v 2.21890187263 0.579685330391 0.00000000000
+v 2.17626643181 0.579685330391 -0.432886332273
+v 2.04999804497 0.579685389996 -0.849137127399
+v 1.84494948387 0.579685389996 -1.23275601864
+v 1.56900048256 0.579685449600 -1.56900072098
+v 1.23275578022 0.579685449600 -1.84494984150
+v 0.849136948586 0.579685449600 -2.04999828339
+v 0.432886362076 0.579685449600 -2.17626643181
+v 0.00000000000 0.579685449600 -2.21890211105
+v 2.34411764145 0.357696920633 0.00000000000
+v 2.29907608032 0.357696950436 -0.457314729691
+v 2.16568231583 0.357696980238 -0.897055089474
+v 1.94906258583 0.357697010040 -1.30232214928
+v 1.65754139423 0.357697010040 -1.65754163265
+v 1.30232191086 0.357697039843 -1.94906294346
+v 0.897054970264 0.357697039843 -2.16568255424
+v 0.457314729691 0.357697069645 -2.29907631874
+v 0.00000000000 0.357697069645 -2.34411787987
+v 2.43018102646 0.118421189487 0.00000000000
+v 2.38348579407 0.118421219289 -0.474104851484
+v 2.24519443512 0.118421241641 -0.929990172386
+v 2.02062153816 0.118421271443 -1.35013639927
+v 1.71839749813 0.118421293795 -1.71839773655
+v 1.35013616085 0.118421308696 -2.02062201500
+v 0.929989993572 0.118421323597 -2.24519467354
+v 0.474104881287 0.118421331048 -2.38348603249
+v 0.00000000000 0.118421331048 -2.43018126488
+v 2.43130278587 -0.134944006801 0.00000000000
+v 2.38458585739 -0.134943976998 -0.474323719740
+v 2.24623084068 -0.134943947196 -0.930419445038
+v 2.02155423164 -0.134943932295 -1.35075962543
+v 1.71919071674 -0.134943902493 -1.71919095516
+v 1.35075938702 -0.134943887591 -2.02155470848
+v 0.930419266224 -0.134943872690 -2.24623107910
+v 0.474323719740 -0.134943857789 -2.38458609581
+v 0.00000000000 -0.134943857789 -2.43130302429
+v 2.30445790291 -0.347892343998 0.00000000000
+v 2.26017832756 -0.347892314196 -0.449577510357
+v 2.12904143333 -0.347892284393 -0.881878018379
+v 1.91608667374 -0.347892254591 -1.28028845787
+v 1.62949764729 -0.347892254591 -1.62949812412
+v 1.28028798103 -0.347892224789 -1.91608703136
+v 0.881877541542 -0.347892224789 -2.12904191017
+v 0.449577242136 -0.347892194986 -2.26017880440
+v 0.00000000000 -0.347892194986 -2.30445814133
+v 2.13941001892 -0.418420016766 0.00000000000
+v 2.09830188751 -0.418419986963 -0.417378246784
+v 1.97655701637 -0.418419957161 -0.818716943264
+v 1.77885437012 -0.418419957161 -1.18859279156
+v 1.51279115677 -0.418419927359 -1.51279163361
+v 1.18859231472 -0.418419897556 -1.77885472775
+v 0.818716526031 -0.418419897556 -1.97655737400
+v 0.417378008366 -0.418419897556 -2.09830212593
+v 0.00000000000 -0.418419897556 -2.13941025734
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.188552573323 0.734181761742 0.00000000000
+v 0.184929594398 0.734181761742 -0.0367847904563
+v 0.174199879169 0.734181761742 -0.0721559599042
+v 0.156775757670 0.734181761742 -0.104754216969
+v 0.133326828480 0.734181761742 -0.133326843381
+v 0.104754231870 0.734181761742 -0.156775772572
+v 0.0721559897065 0.734181761742 -0.174199908972
+v 0.0367848314345 0.734181761742 -0.184929639101
+v 0.00000000000 0.734181761742 -0.188552647829
+v 0.416212409735 0.895024657249 0.00000000000
+v 0.408215016127 0.895024657249 -0.0811990201473
+v 0.384530127048 0.895024657249 -0.159277617931
+v 0.346067994833 0.895024657249 -0.231235265732
+v 0.294306635857 0.895024657249 -0.294306665659
+v 0.231235250831 0.895024657249 -0.346068054438
+v 0.159277647734 0.895024657249 -0.384530246258
+v 0.0811990723014 0.895024657249 -0.408215105534
+v 0.00000000000 0.895024657249 -0.416212528944
+v 0.681565940380 0.981257736683 0.00000000000
+v 0.668469846249 0.981257736683 -0.132966935635
+v 0.629684865475 0.981257736683 -0.260824024677
+v 0.566701412201 0.981257736683 -0.378657847643
+v 0.481939941645 0.981257736683 -0.481940001249
+v 0.378657758236 0.981257796288 -0.566701471806
+v 0.260823994875 0.981257796288 -0.629684925079
+v 0.132966935635 0.981257796288 -0.668469965458
+v 0.00000000000 0.981257796288 -0.681566059589
+v 0.960314631462 1.00112521648 0.00000000000
+v 0.941862463951 1.00112521648 -0.187348112464
+v 0.887215077877 1.00112521648 -0.367496550083
+v 0.798472464085 1.00112521648 -0.533522307873
+v 0.679045021534 1.00112521648 -0.679045081139
+v 0.533522248268 1.00112521648 -0.798472583294
+v 0.367496490479 1.00112521648 -0.887215197086
+v 0.187348127365 1.00112521648 -0.941862583160
+v 0.00000000000 1.00112521648 -0.960314810276
+v 1.23817658424 0.969767212868 0.00000000000
+v 1.21438539028 0.969767212868 -0.241556301713
+v 1.14392602444 0.969767212868 -0.473829776049
+v 1.02950620651 0.969767272472 -0.687894165516
+v 0.875523030758 0.969767272472 -0.875523209572
+v 0.687893986702 0.969767272472 -1.02950632572
+v 0.473829656839 0.969767272472 -1.14392614365
+v 0.241556301713 0.969767272472 -1.21438550949
+v 0.00000000000 0.969767272472 -1.23817670345
+v 1.50508165359 0.886858522892 0.00000000000
+v 1.47616195679 0.886858522892 -0.293626904488
+v 1.39051413536 0.886858582497 -0.575969934464
+v 1.25142967701 0.886858582497 -0.836178779602
+v 1.06425344944 0.886858582497 -1.06425356865
+v 0.836178481579 0.886858582497 -1.25142979622
+v 0.575969815254 0.886858582497 -1.39051425457
+v 0.293626904488 0.886858582497 -1.47616195679
+v 0.00000000000 0.886858642101 -1.50508189201
+v 1.74579274654 0.745474517345 0.00000000000
+v 1.71224784851 0.745474517345 -0.340587288141
+v 1.61290228367 0.745474576950 -0.668086051941
+v 1.45157361031 0.745474576950 -0.969910681248
+v 1.23446190357 0.745474576950 -1.23446202278
+v 0.969910383224 0.745474576950 -1.45157384872
+v 0.668085932732 0.745474636555 -1.61290240288
+v 0.340587317944 0.745474636555 -1.71224796772
+v 0.00000000000 0.745474636555 -1.74579298496
+v 1.93074250221 0.537642598152 0.00000000000
+v 1.89364385605 0.537642598152 -0.376669228077
+v 1.78377354145 0.537642657757 -0.738863289356
+v 1.60535371304 0.537642657757 -1.07266318798
+v 1.36524105072 0.537642657757 -1.36524116993
+v 1.07266294956 0.537642717361 -1.60535407066
+v 0.738863170147 0.537642717361 -1.78377366066
+v 0.376669228077 0.537642717361 -1.89364397526
+v 0.00000000000 0.537642717361 -1.93074274063
+v 1.99614274502 0.269756197929 0.00000000000
+v 1.95778751373 0.269756227732 -0.389428198338
+v 1.84419548512 0.269756257534 -0.763890862465
+v 1.65973198414 0.269756257534 -1.10899758339
+v 1.41148602962 0.269756287336 -1.41148614883
+v 1.10899734497 0.269756287336 -1.65973234177
+v 0.763890743256 0.269756317139 -1.84419560432
+v 0.389428198338 0.269756317139 -1.95778763294
+v 0.00000000000 0.269756317139 -1.99614298344
+v 1.94291639328 -0.00477932812646 0.00000000000
+v 1.90558373928 -0.00477930530906 -0.379044234753
+v 1.79502058029 -0.00477928388864 -0.743522047997
+v 1.61547589302 -0.00477926386520 -1.07942664623
+v 1.37384939194 -0.00477924617007 -1.37384951115
+v 1.07942640781 -0.00477923173457 -1.61547625065
+v 0.743521928787 -0.00477922102436 -1.79502081871
+v 0.379044234753 -0.00477921450511 -1.90558397770
+v 0.00000000000 -0.00477921217680 -1.94291663170
+v 1.99091351032 -0.275719702244 0.00000000000
+v 1.95265865326 -0.275719672441 -0.388408035040
+v 1.83936417103 -0.275719642639 -0.761889755726
+v 1.65538406372 -0.275719642639 -1.10609257221
+v 1.40778827667 -0.275719612837 -1.40778863430
+v 1.10609209538 -0.275719612837 -1.65538442135
+v 0.761889338493 -0.275719583035 -1.83936452866
+v 0.388407796621 -0.275719583035 -1.95265901089
+v 0.00000000000 -0.275719583035 -1.99091374874
+v 2.13941001892 -0.418420016766 0.00000000000
+v 2.09830188751 -0.418419986963 -0.417378246784
+v 1.97655701637 -0.418419957161 -0.818716943264
+v 1.77885437012 -0.418419957161 -1.18859279156
+v 1.51279115677 -0.418419927359 -1.51279163361
+v 1.18859231472 -0.418419897556 -1.77885472775
+v 0.818716526031 -0.418419897556 -1.97655737400
+v 0.417378008366 -0.418419897556 -2.09830212593
+v 0.00000000000 -0.418419897556 -2.13941025734
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56851112843 -0.271150618792
+v -0.0528689324856 1.56851112843 -0.265946507454
+v -0.103736668825 1.56851112843 -0.250522226095
+v -0.150617867708 1.56851112843 -0.225470513105
+v -0.191710919142 1.56851112843 -0.191754072905
+v -0.225436612964 1.56851112843 -0.150668650866
+v -0.250498920679 1.56851112843 -0.103793121874
+v -0.265934675932 1.56851112843 -0.0529288835824
+v -0.271150738001 1.56851112843 0.00000000000
+v 0.00000000000 1.56077754498 -0.525979161263
+v -0.102492764592 1.56077754498 -0.515896677971
+v -0.201169833541 1.56077754498 -0.485988527536
+v -0.292116105556 1.56077754498 -0.437404125929
+v -0.371836483479 1.56077754498 -0.372010499239
+v -0.437267392874 1.56077754498 -0.292320728302
+v -0.485894382000 1.56077754498 -0.201397269964
+v -0.515848755836 1.56077754498 -0.102734215558
+v -0.525979340076 1.56077754498 0.00000000000
+v 0.00000000000 1.53255486488 -0.779304146767
+v -0.151770994067 1.53255486488 -0.764382541180
+v -0.297978401184 1.53255486488 -0.720086097717
+v -0.432734698057 1.53255486488 -0.648117184639
+v -0.550861239433 1.53255486488 -0.551241457462
+v -0.647818505764 1.53255486488 -0.433181822300
+v -0.719880402088 1.53255486488 -0.298475235701
+v -0.764277815819 1.53255486488 -0.152298465371
+v -0.779304385185 1.53255486488 0.00000000000
+v 0.00000000000 1.47749805450 -1.02816593647
+v -0.200215920806 1.47749805450 -1.00848352909
+v -0.393114238977 1.47749805450 -0.950045704842
+v -0.570905387402 1.47749805450 -0.855098009109
+v -0.726756930351 1.47749805450 -0.727289438248
+v -0.854679703712 1.47749805450 -0.571531593800
+v -0.949757516384 1.47749805450 -0.393810033798
+v -1.00833678246 1.47749817371 -0.200954630971
+v -1.02816617489 1.47749817371 0.00000000000
+v 0.00000000000 1.39657485485 -1.26983809471
+v -0.247444093227 1.39657485485 -1.24549603462
+v -0.485673785210 1.39657485485 -1.17329025269
+v -0.705239295959 1.39657485485 -1.05599558353
+v -0.897702932358 1.39657485485 -0.898119509220
+v -1.05566823483 1.39657497406 -0.705729305744
+v -1.17306482792 1.39657497406 -0.486218214035
+v -1.24538123608 1.39657497406 -0.248022168875
+v -1.26983833313 1.39657497406 0.00000000000
+v 0.00000000000 1.28625142574 -1.49952828884
+v -0.292435526848 1.28625142574 -1.47073674202
+v -0.573742926121 1.28625142574 -1.38542568684
+v -0.833001911640 1.28625142574 -1.24687337875
+v -1.06024897099 1.28625154495 -1.06040453911
+v -1.24675130844 1.28625154495 -0.833184778690
+v -1.38534164429 1.28625154495 -0.573946297169
+v -1.47069406509 1.28625154495 -0.292651444674
+v -1.49952852726 1.28625154495 0.00000000000
+v 0.00000000000 1.14743721485 -1.71322810650
+v -0.334220230579 1.14743721485 -1.68031167984
+v -0.655610859394 1.14743721485 -1.58282196522
+v -0.951806843281 1.14743721485 -1.42450511456
+v -1.21142530441 1.14743733406 -1.21144545078
+v -1.42448937893 1.14743733406 -0.951830327511
+v -1.58281123638 1.14743733406 -0.655637145042
+v -1.68030643463 1.14743733406 -0.334248244762
+v -1.71322846413 1.14743733406 0.00000000000
+v 0.00000000000 0.981508374214 -1.90656912327
+v -0.371953308582 0.981508374214 -1.86993503571
+v -0.729612588882 0.981508433819 -1.76144027710
+v -1.05923330784 0.981508433819 -1.58525431156
+v -1.34814810753 0.981508433819 -1.34814798832
+v -1.58525466919 0.981508493423 -1.05923283100
+v -1.76144039631 0.981508493423 -0.729612350464
+v -1.86993515491 0.981508493423 -0.371953159571
+v -1.90656936169 0.981508493423 0.00000000000
+v 0.00000000000 0.789333820343 -2.07388091087
+v -0.404594242573 0.789333820343 -2.03403186798
+v -0.793640077114 0.789333879948 -1.91601622105
+v -1.15218675137 0.789333879948 -1.72436892986
+v -1.46645545959 0.789333879948 -1.46645510197
+v -1.72436928749 0.789333939552 -1.15218627453
+v -1.91601634026 0.789333939552 -0.793639779091
+v -2.03403210640 0.789333939552 -0.404594063759
+v -2.07388114929 0.789333939552 0.00000000000
+v 0.00000000000 0.579685330391 -2.21890187263
+v -0.432886421680 0.579685330391 -2.17626643181
+v -0.849137246609 0.579685389996 -2.04999804497
+v -1.23275613785 0.579685389996 -1.84494948387
+v -1.56900084019 0.579685449600 -1.56900036335
+v -1.84494984150 0.579685449600 -1.23275566101
+v -2.04999828339 0.579685449600 -0.849136829376
+v -2.17626643181 0.579685449600 -0.432886272669
+v -2.21890211105 0.579685449600 0.00000000000
+v 0.00000000000 0.357696920633 -2.34411764145
+v -0.457314819098 0.357696950436 -2.29907608032
+v -0.897055208683 0.357696980238 -2.16568231583
+v -1.30232226849 0.357697010040 -1.94906258583
+v -1.65754175186 0.357697010040 -1.65754127502
+v -1.94906294346 0.357697039843 -1.30232179165
+v -2.16568255424 0.357697039843 -0.897054851055
+v -2.29907631874 0.357697069645 -0.457314640284
+v -2.34411787987 0.357697069645 0.00000000000
+v 0.00000000000 0.118421189487 -2.43018102646
+v -0.474104940891 0.118421219289 -2.38348579407
+v -0.929990291595 0.118421241641 -2.24519443512
+v -1.35013651848 0.118421271443 -2.02062153816
+v -1.71839785576 0.118421293795 -1.71839737892
+v -2.02062201500 0.118421308696 -1.35013604164
+v -2.24519467354 0.118421323597 -0.929989874363
+v -2.38348603249 0.118421331048 -0.474104791880
+v -2.43018126488 0.118421331048 0.00000000000
+v 0.00000000000 -0.134944006801 -2.43130278587
+v -0.474323809147 -0.134943976998 -2.38458585739
+v -0.930419564247 -0.134943947196 -2.24623084068
+v -1.35075974464 -0.134943932295 -2.02155423164
+v -1.71919107437 -0.134943902493 -1.71919059753
+v -2.02155470848 -0.134943887591 -1.35075926781
+v -2.24623107910 -0.134943872690 -0.930419147015
+v -2.38458609581 -0.134943857789 -0.474323630333
+v -2.43130302429 -0.134943857789 0.00000000000
+v 0.00000000000 -0.347892343998 -2.30445790291
+v -0.449577599764 -0.347892314196 -2.26017832756
+v -0.881878137589 -0.347892284393 -2.12904143333
+v -1.28028857708 -0.347892254591 -1.91608667374
+v -1.62949824333 -0.347892254591 -1.62949752808
+v -1.91608703136 -0.347892224789 -1.28028786182
+v -2.12904191017 -0.347892224789 -0.881877422333
+v -2.26017880440 -0.347892194986 -0.449577152729
+v -2.30445814133 -0.347892194986 0.00000000000
+v 0.00000000000 -0.418420016766 -2.13941001892
+v -0.417378336191 -0.418419986963 -2.09830188751
+v -0.818717002869 -0.418419957161 -1.97655701637
+v -1.18859291077 -0.418419957161 -1.77885437012
+v -1.51279175282 -0.418419927359 -1.51279103756
+v -1.77885472775 -0.418419897556 -1.18859219551
+v -1.97655737400 -0.418419897556 -0.818716466427
+v -2.09830212593 -0.418419897556 -0.417377918959
+v -2.13941025734 -0.418419897556 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.734181761742 -0.188552573323
+v -0.0367847979069 0.734181761742 -0.184929594398
+v -0.0721559673548 0.734181761742 -0.174199879169
+v -0.104754224420 0.734181761742 -0.156775757670
+v -0.133326843381 0.734181761742 -0.133326828480
+v -0.156775772572 0.734181761742 -0.104754224420
+v -0.174199908972 0.734181761742 -0.0721559822559
+v -0.184929639101 0.734181761742 -0.0367848239839
+v -0.188552647829 0.734181761742 0.00000000000
+v 0.00000000000 0.895024657249 -0.416212409735
+v -0.0811990350485 0.895024657249 -0.408215016127
+v -0.159277632833 0.895024657249 -0.384530127048
+v -0.231235280633 0.895024657249 -0.346067994833
+v -0.294306665659 0.895024657249 -0.294306635857
+v -0.346068054438 0.895024657249 -0.231235235929
+v -0.384530246258 0.895024657249 -0.159277632833
+v -0.408215105534 0.895024657249 -0.0811990574002
+v -0.416212528944 0.895024657249 0.00000000000
+v 0.00000000000 0.981257736683 -0.681565940380
+v -0.132966965437 0.981257736683 -0.668469846249
+v -0.260824054480 0.981257736683 -0.629684865475
+v -0.378657877445 0.981257736683 -0.566701412201
+v -0.481940031052 0.981257736683 -0.481939911842
+v -0.566701471806 0.981257796288 -0.378657728434
+v -0.629684925079 0.981257796288 -0.260823965073
+v -0.668469965458 0.981257796288 -0.132966905832
+v -0.681566059589 0.981257796288 0.00000000000
+v 0.00000000000 1.00112521648 -0.960314631462
+v -0.187348157167 1.00112521648 -0.941862463951
+v -0.367496579885 1.00112521648 -0.887215077877
+v -0.533522367477 1.00112521648 -0.798472464085
+v -0.679045081139 1.00112521648 -0.679045021534
+v -0.798472583294 1.00112521648 -0.533522188663
+v -0.887215197086 1.00112521648 -0.367496460676
+v -0.941862583160 1.00112521648 -0.187348082662
+v -0.960314810276 1.00112521648 0.00000000000
+v 0.00000000000 0.969767212868 -1.23817658424
+v -0.241556361318 0.969767212868 -1.21438539028
+v -0.473829835653 0.969767212868 -1.14392602444
+v -0.687894225121 0.969767272472 -1.02950620651
+v -0.875523269176 0.969767272472 -0.875522971153
+v -1.02950632572 0.969767272472 -0.687893927097
+v -1.14392614365 0.969767272472 -0.473829597235
+v -1.21438550949 0.969767272472 -0.241556242108
+v -1.23817670345 0.969767272472 0.00000000000
+v 0.00000000000 0.886858522892 -1.50508165359
+v -0.293626964092 0.886858522892 -1.47616195679
+v -0.575969994068 0.886858582497 -1.39051413536
+v -0.836178839207 0.886858582497 -1.25142967701
+v -1.06425356865 0.886858582497 -1.06425344944
+v -1.25142979622 0.886858582497 -0.836178421974
+v -1.39051425457 0.886858582497 -0.575969755650
+v -1.47616195679 0.886858582497 -0.293626844883
+v -1.50508189201 0.886858642101 0.00000000000
+v 0.00000000000 0.745474517345 -1.74579274654
+v -0.340587377548 0.745474517345 -1.71224784851
+v -0.668086111546 0.745474576950 -1.61290228367
+v -0.969910740852 0.745474576950 -1.45157361031
+v -1.23446202278 0.745474576950 -1.23446190357
+v -1.45157384872 0.745474576950 -0.969910323620
+v -1.61290240288 0.745474636555 -0.668085873127
+v -1.71224796772 0.745474636555 -0.340587228537
+v -1.74579298496 0.745474636555 0.00000000000
+v 0.00000000000 0.537642598152 -1.93074250221
+v -0.376669317484 0.537642598152 -1.89364385605
+v -0.738863348961 0.537642657757 -1.78377354145
+v -1.07266330719 0.537642657757 -1.60535371304
+v -1.36524128914 0.537642657757 -1.36524093151
+v -1.60535407066 0.537642717361 -1.07266283035
+v -1.78377366066 0.537642717361 -0.738863110542
+v -1.89364397526 0.537642717361 -0.376669138670
+v -1.93074274063 0.537642717361 0.00000000000
+v 0.00000000000 0.269756197929 -1.99614274502
+v -0.389428287745 0.269756227732 -1.95778751373
+v -0.763890922070 0.269756257534 -1.84419548512
+v -1.10899770260 0.269756257534 -1.65973198414
+v -1.41148626804 0.269756287336 -1.41148591042
+v -1.65973234177 0.269756287336 -1.10899722576
+v -1.84419560432 0.269756317139 -0.763890683651
+v -1.95778763294 0.269756317139 -0.389428108931
+v -1.99614298344 0.269756317139 0.00000000000
+v 0.00000000000 -0.00477932812646 -1.94291639328
+v -0.379044324160 -0.00477930530906 -1.90558373928
+v -0.743522107601 -0.00477928388864 -1.79502058029
+v -1.07942676544 -0.00477926386520 -1.61547589302
+v -1.37384963036 -0.00477924617007 -1.37384927273
+v -1.61547625065 -0.00477923173457 -1.07942628860
+v -1.79502081871 -0.00477922102436 -0.743521869183
+v -1.90558397770 -0.00477921450511 -0.379044145346
+v -1.94291663170 -0.00477921217680 0.00000000000
+v 0.00000000000 -0.275719702244 -1.99091351032
+v -0.388408124447 -0.275719672441 -1.95265865326
+v -0.761889815331 -0.275719642639 -1.83936417103
+v -1.10609269142 -0.275719642639 -1.65538406372
+v -1.40778875351 -0.275719612837 -1.40778815746
+v -1.65538442135 -0.275719612837 -1.10609197617
+v -1.83936452866 -0.275719583035 -0.761889278889
+v -1.95265901089 -0.275719583035 -0.388407707214
+v -1.99091374874 -0.275719583035 0.00000000000
+v 0.00000000000 -0.418420016766 -2.13941001892
+v -0.417378336191 -0.418419986963 -2.09830188751
+v -0.818717002869 -0.418419957161 -1.97655701637
+v -1.18859291077 -0.418419957161 -1.77885437012
+v -1.51279175282 -0.418419927359 -1.51279103756
+v -1.77885472775 -0.418419897556 -1.18859219551
+v -1.97655737400 -0.418419897556 -0.818716466427
+v -2.09830212593 -0.418419897556 -0.417377918959
+v -2.13941025734 -0.418419897556 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v -0.271150618792 1.56851112843 0.00000000000
+v -0.265946507454 1.56851112843 0.0528689436615
+v -0.250522226095 1.56851112843 0.103736683726
+v -0.225470498204 1.56851112843 0.150617867708
+v -0.191754072905 1.56851112843 0.191710919142
+v -0.150668650866 1.56851112843 0.225436627865
+v -0.103793106973 1.56851112843 0.250498920679
+v -0.0529288724065 1.56851112843 0.265934675932
+v 0.00000000000 1.56851112843 0.271150738001
+v -0.525979161263 1.56077754498 0.00000000000
+v -0.515896677971 1.56077754498 0.102492786944
+v -0.485988497734 1.56077754498 0.201169863343
+v -0.437404096127 1.56077754498 0.292116105556
+v -0.372010499239 1.56077754498 0.371836483479
+v -0.292320728302 1.56077754498 0.437267422676
+v -0.201397240162 1.56077754498 0.485894411802
+v -0.102734193206 1.56077754498 0.515848755836
+v 0.00000000000 1.56077754498 0.525979340076
+v -0.779304146767 1.53255486488 0.00000000000
+v -0.764382541180 1.53255486488 0.151771023870
+v -0.720086097717 1.53255486488 0.297978430986
+v -0.648117125034 1.53255486488 0.432734727859
+v -0.551241397858 1.53255486488 0.550861299038
+v -0.433181792498 1.53255486488 0.647818565369
+v -0.298475205898 1.53255486488 0.719880402088
+v -0.152298435569 1.53255486488 0.764277815819
+v 0.00000000000 1.53255486488 0.779304385185
+v -1.02816593647 1.47749805450 0.00000000000
+v -1.00848352909 1.47749805450 0.200215965509
+v -0.950045645237 1.47749805450 0.393114298582
+v -0.855097949505 1.47749805450 0.570905387402
+v -0.727289438248 1.47749805450 0.726756930351
+v -0.571531593800 1.47749805450 0.854679763317
+v -0.393809974194 1.47749805450 0.949757575989
+v -0.200954586267 1.47749817371 1.00833678246
+v 0.00000000000 1.47749817371 1.02816617489
+v -1.26983809471 1.39657485485 0.00000000000
+v -1.24549603462 1.39657485485 0.247444137931
+v -1.17329025269 1.39657485485 0.485673815012
+v -1.05599546432 1.39657485485 0.705239355564
+v -0.898119509220 1.39657485485 0.897702932358
+v -0.705729246140 1.39657497406 1.05566835403
+v -0.486218184233 1.39657497406 1.17306482792
+v -0.248022124171 1.39657497406 1.24538123608
+v 0.00000000000 1.39657497406 1.26983833313
+v -1.49952828884 1.28625142574 0.00000000000
+v -1.47073674202 1.28625142574 0.292435586452
+v -1.38542568684 1.28625142574 0.573742985725
+v -1.24687325954 1.28625142574 0.833001971245
+v -1.06040441990 1.28625154495 1.06024909019
+v -0.833184719086 1.28625154495 1.24675142765
+v -0.573946237564 1.28625154495 1.38534164429
+v -0.292651385069 1.28625154495 1.47069406509
+v 0.00000000000 1.28625154495 1.49952852726
+v -1.71322810650 1.14743721485 0.00000000000
+v -1.68031167984 1.14743721485 0.334220319986
+v -1.58282196522 1.14743721485 0.655610918999
+v -1.42450499535 1.14743721485 0.951806902885
+v -1.21144533157 1.14743733406 1.21142542362
+v -0.951830267906 1.14743733406 1.42448949814
+v -0.655637085438 1.14743733406 1.58281123638
+v -0.334248155355 1.14743733406 1.68030643463
+v 0.00000000000 1.14743733406 1.71322846413
+v -1.90656912327 0.981508374214 0.00000000000
+v -1.86993503571 0.981508374214 0.371953368187
+v -1.76144015789 0.981508433819 0.729612708092
+v -1.58525419235 0.981508433819 1.05923330784
+v -1.34814786911 0.981508433819 1.34814822674
+v -1.05923283100 0.981508493423 1.58525478840
+v -0.729612231255 0.981508493423 1.76144051552
+v -0.371953099966 0.981508493423 1.86993515491
+v 0.00000000000 0.981508493423 1.90656936169
+v -2.07388091087 0.789333820343 0.00000000000
+v -2.03403186798 0.789333820343 0.404594331980
+v -1.91601610184 0.789333879948 0.793640196323
+v -1.72436881065 0.789333879948 1.15218675137
+v -1.46645510197 0.789333879948 1.46645545959
+v -1.15218627453 0.789333939552 1.72436940670
+v -0.793639659882 0.789333939552 1.91601645947
+v -0.404593974352 0.789333939552 2.03403210640
+v 0.00000000000 0.789333939552 2.07388114929
+v -2.21890187263 0.579685330391 0.00000000000
+v -2.17626643181 0.579685330391 0.432886511087
+v -2.04999804497 0.579685389996 0.849137306213
+v -1.84494936466 0.579685389996 1.23275613785
+v -1.56900036335 0.579685449600 1.56900084019
+v -1.23275566101 0.579685449600 1.84494996071
+v -0.849136769772 0.579685449600 2.04999828339
+v -0.432886183262 0.579685449600 2.17626643181
+v 0.00000000000 0.579685449600 2.21890211105
+v -2.34411764145 0.357696920633 0.00000000000
+v -2.29907608032 0.357696950436 0.457314938307
+v -2.16568231583 0.357696980238 0.897055268288
+v -1.94906246662 0.357697010040 1.30232226849
+v -1.65754127502 0.357697010040 1.65754175186
+v -1.30232179165 0.357697039843 1.94906306267
+v -0.897054791451 0.357697039843 2.16568255424
+v -0.457314521074 0.357697069645 2.29907631874
+v 0.00000000000 0.357697069645 2.34411787987
+v -2.43018102646 0.118421189487 0.00000000000
+v -2.38348579407 0.118421219289 0.474105060101
+v -2.24519443512 0.118421241641 0.929990351200
+v -2.02062153816 0.118421271443 1.35013651848
+v -1.71839737892 0.118421293795 1.71839785576
+v -1.35013604164 0.118421308696 2.02062201500
+v -0.929989814758 0.118421323597 2.24519467354
+v -0.474104672670 0.118421331048 2.38348603249
+v 0.00000000000 0.118421331048 2.43018126488
+v -2.43130278587 -0.134944006801 0.00000000000
+v -2.38458585739 -0.134943976998 0.474323928356
+v -2.24623084068 -0.134943947196 0.930419623852
+v -2.02155423164 -0.134943932295 1.35075974464
+v -1.71919059753 -0.134943902493 1.71919107437
+v -1.35075926781 -0.134943887591 2.02155470848
+v -0.930419087410 -0.134943872690 2.24623107910
+v -0.474323511124 -0.134943857789 2.38458609581
+v 0.00000000000 -0.134943857789 2.43130302429
+v -2.30445790291 -0.347892343998 0.00000000000
+v -2.26017832756 -0.347892314196 0.449577718973
+v -2.12904143333 -0.347892284393 0.881878197193
+v -1.91608655453 -0.347892254591 1.28028857708
+v -1.62949752808 -0.347892254591 1.62949824333
+v -1.28028786182 -0.347892224789 1.91608715057
+v -0.881877362728 -0.347892224789 2.12904191017
+v -0.449577033520 -0.347892194986 2.26017880440
+v 0.00000000000 -0.347892194986 2.30445814133
+v -2.13941001892 -0.418420016766 0.00000000000
+v -2.09830188751 -0.418419986963 0.417378425598
+v -1.97655689716 -0.418419957161 0.818717122078
+v -1.77885425091 -0.418419957161 1.18859291077
+v -1.51279103756 -0.418419927359 1.51279175282
+v -1.18859219551 -0.418419897556 1.77885484695
+v -0.818716347218 -0.418419897556 1.97655749321
+v -0.417377829552 -0.418419897556 2.09830212593
+v 0.00000000000 -0.418419897556 2.13941025734
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v -0.188552573323 0.734181761742 0.00000000000
+v -0.184929594398 0.734181761742 0.0367848053575
+v -0.174199879169 0.734181761742 0.0721559748054
+v -0.156775742769 0.734181761742 0.104754231870
+v -0.133326813579 0.734181761742 0.133326858282
+v -0.104754216969 0.734181761742 0.156775787473
+v -0.0721559748054 0.734181761742 0.174199908972
+v -0.0367848165333 0.734181761742 0.184929639101
+v 0.00000000000 0.734181761742 0.188552647829
+v -0.416212409735 0.895024657249 0.00000000000
+v -0.408215016127 0.895024657249 0.0811990574002
+v -0.384530127048 0.895024657249 0.159277647734
+v -0.346067965031 0.895024657249 0.231235295534
+v -0.294306606054 0.895024657249 0.294306695461
+v -0.231235221028 0.895024657249 0.346068084240
+v -0.159277617931 0.895024657249 0.384530246258
+v -0.0811990350485 0.895024657249 0.408215105534
+v 0.00000000000 0.895024657249 0.416212528944
+v -0.681565940380 0.981257736683 0.00000000000
+v -0.668469846249 0.981257736683 0.132966995239
+v -0.629684865475 0.981257736683 0.260824084282
+v -0.566701352596 0.981257736683 0.378657907248
+v -0.481939911842 0.981257736683 0.481940031052
+v -0.378657698631 0.981257796288 0.566701531410
+v -0.260823935270 0.981257796288 0.629684925079
+v -0.132966876030 0.981257796288 0.668469965458
+v 0.00000000000 0.981257796288 0.681566059589
+v -0.960314631462 1.00112521648 0.00000000000
+v -0.941862463951 1.00112521648 0.187348201871
+v -0.887215018272 1.00112521648 0.367496639490
+v -0.798472404480 1.00112521648 0.533522367477
+v -0.679044961929 1.00112521648 0.679045140743
+v -0.533522188663 1.00112521648 0.798472642899
+v -0.367496401072 1.00112521648 0.887215256691
+v -0.187348037958 1.00112521648 0.941862583160
+v 0.00000000000 1.00112521648 0.960314810276
+v -1.23817658424 0.969767212868 0.00000000000
+v -1.21438539028 0.969767212868 0.241556406021
+v -1.14392602444 0.969767212868 0.473829865456
+v -1.02950608730 0.969767272472 0.687894284725
+v -0.875522971153 0.969767272472 0.875523269176
+v -0.687893867493 0.969767272472 1.02950644493
+v -0.473829567432 0.969767272472 1.14392614365
+v -0.241556197405 0.969767272472 1.21438550949
+v 0.00000000000 0.969767272472 1.23817670345
+v -1.50508165359 0.886858522892 0.00000000000
+v -1.47616195679 0.886858522892 0.293627023697
+v -1.39051413536 0.886858582497 0.575970053673
+v -1.25142955780 0.886858582497 0.836178898811
+v -1.06425333023 0.886858582497 1.06425368786
+v -0.836178362370 0.886858582497 1.25142991543
+v -0.575969696045 0.886858582497 1.39051425457
+v -0.293626785278 0.886858582497 1.47616195679
+v 0.00000000000 0.886858642101 1.50508189201
+v -1.74579274654 0.745474517345 0.00000000000
+v -1.71224784851 0.745474517345 0.340587437153
+v -1.61290228367 0.745474576950 0.668086171150
+v -1.45157349110 0.745474576950 0.969910800457
+v -1.23446178436 0.745474576950 1.23446214199
+v -0.969910264015 0.745474576950 1.45157396793
+v -0.668085813522 0.745474636555 1.61290240288
+v -0.340587168932 0.745474636555 1.71224796772
+v 0.00000000000 0.745474636555 1.74579298496
+v -1.93074250221 0.537642598152 0.00000000000
+v -1.89364385605 0.537642598152 0.376669406891
+v -1.78377342224 0.537642657757 0.738863468170
+v -1.60535359383 0.537642657757 1.07266330719
+v -1.36524093151 0.537642657757 1.36524128914
+v -1.07266283035 0.537642717361 1.60535418987
+v -0.738862991333 0.537642717361 1.78377377987
+v -0.376669049263 0.537642717361 1.89364397526
+v 0.00000000000 0.537642717361 1.93074274063
+v -1.99614274502 0.269756197929 0.00000000000
+v -1.95778751373 0.269756227732 0.389428377151
+v -1.84419536591 0.269756257534 0.763891041279
+v -1.65973186493 0.269756257534 1.10899770260
+v -1.41148591042 0.269756287336 1.41148626804
+v -1.10899722576 0.269756287336 1.65973246098
+v -0.763890564442 0.269756317139 1.84419572353
+v -0.389428019524 0.269756317139 1.95778763294
+v 0.00000000000 0.269756317139 1.99614298344
+v -1.94291639328 -0.00477932812646 0.00000000000
+v -1.90558373928 -0.00477930530906 0.379044413567
+v -1.79502046108 -0.00477928388864 0.743522226810
+v -1.61547577381 -0.00477926386520 1.07942676544
+v -1.37384927273 -0.00477924617007 1.37384963036
+v -1.07942628860 -0.00477923173457 1.61547636986
+v -0.743521749973 -0.00477922102436 1.79502093792
+v -0.379044055939 -0.00477921450511 1.90558397770
+v 0.00000000000 -0.00477921217680 1.94291663170
+v -1.99091351032 -0.275719702244 0.00000000000
+v -1.95265865326 -0.275719672441 0.388408213854
+v -1.83936405182 -0.275719642639 0.761889934540
+v -1.65538394451 -0.275719642639 1.10609269142
+v -1.40778815746 -0.275719612837 1.40778875351
+v -1.10609197617 -0.275719612837 1.65538454056
+v -0.761889159679 -0.275719583035 1.83936464787
+v -0.388407617807 -0.275719583035 1.95265901089
+v 0.00000000000 -0.275719583035 1.99091374874
+v -2.13941001892 -0.418420016766 0.00000000000
+v -2.09830188751 -0.418419986963 0.417378425598
+v -1.97655689716 -0.418419957161 0.818717122078
+v -1.77885425091 -0.418419957161 1.18859291077
+v -1.51279103756 -0.418419927359 1.51279175282
+v -1.18859219551 -0.418419897556 1.77885484695
+v -0.818716347218 -0.418419897556 1.97655749321
+v -0.417377829552 -0.418419897556 2.09830212593
+v 0.00000000000 -0.418419897556 2.13941025734
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56283009052 0.00000000000
+v 0.00000000000 1.56851112843 0.271150618792
+v 0.0528689250350 1.56851112843 0.265946507454
+v 0.103736661375 1.56851112843 0.250522226095
+v 0.150617852807 1.56851112843 0.225470513105
+v 0.191710904241 1.56851112843 0.191754087806
+v 0.225436612964 1.56851112843 0.150668665767
+v 0.250498920679 1.56851112843 0.103793129325
+v 0.265934675932 1.56851112843 0.0529288910329
+v 0.271150738001 1.56851112843 0.00000000000
+v 0.00000000000 1.56077754498 0.525979161263
+v 0.102492749691 1.56077754498 0.515896677971
+v 0.201169818640 1.56077754498 0.485988527536
+v 0.292116075754 1.56077754498 0.437404125929
+v 0.371836453676 1.56077754498 0.372010529041
+v 0.437267392874 1.56077754498 0.292320758104
+v 0.485894382000 1.56077754498 0.201397284865
+v 0.515848755836 1.56077754498 0.102734230459
+v 0.525979340076 1.56077754498 0.00000000000
+v 0.00000000000 1.53255486488 0.779304146767
+v 0.151770979166 1.53255486488 0.764382541180
+v 0.297978371382 1.53255486488 0.720086097717
+v 0.432734668255 1.53255486488 0.648117184639
+v 0.550861239433 1.53255486488 0.551241457462
+v 0.647818505764 1.53255486488 0.433181852102
+v 0.719880402088 1.53255486488 0.298475265503
+v 0.764277815819 1.53255486488 0.152298480272
+v 0.779304385185 1.53255486488 0.00000000000
+v 0.00000000000 1.47749805450 1.02816593647
+v 0.200215891004 1.47749805450 1.00848352909
+v 0.393114209175 1.47749805450 0.950045704842
+v 0.570905327797 1.47749805450 0.855098009109
+v 0.726756870747 1.47749805450 0.727289497852
+v 0.854679703712 1.47749805450 0.571531653404
+v 0.949757516384 1.47749805450 0.393810063601
+v 1.00833678246 1.47749817371 0.200954660773
+v 1.02816617489 1.47749817371 0.00000000000
+v 0.00000000000 1.39657485485 1.26983809471
+v 0.247444048524 1.39657485485 1.24549603462
+v 0.485673725605 1.39657485485 1.17329025269
+v 0.705239236355 1.39657485485 1.05599558353
+v 0.897702872753 1.39657485485 0.898119568825
+v 1.05566823483 1.39657497406 0.705729365349
+v 1.17306482792 1.39657497406 0.486218273640
+v 1.24538123608 1.39657497406 0.248022213578
+v 1.26983833313 1.39657497406 0.00000000000
+v 0.00000000000 1.28625142574 1.49952828884
+v 0.292435497046 1.28625142574 1.47073674202
+v 0.573742866516 1.28625142574 1.38542568684
+v 0.833001852036 1.28625142574 1.24687337875
+v 1.06024897099 1.28625154495 1.06040453911
+v 1.24675130844 1.28625154495 0.833184838295
+v 1.38534164429 1.28625154495 0.573946356773
+v 1.47069406509 1.28625154495 0.292651474476
+v 1.49952852726 1.28625154495 0.00000000000
+v 0.00000000000 1.14743721485 1.71322810650
+v 0.334220200777 1.14743721485 1.68031167984
+v 0.655610799789 1.14743721485 1.58282196522
+v 0.951806783676 1.14743721485 1.42450511456
+v 1.21142530441 1.14743733406 1.21144545078
+v 1.42448937893 1.14743733406 0.951830387115
+v 1.58281123638 1.14743733406 0.655637204647
+v 1.68030643463 1.14743733406 0.334248274565
+v 1.71322846413 1.14743733406 0.00000000000
+v 0.00000000000 0.981508374214 1.90656912327
+v 0.371953248978 0.981508374214 1.86993503571
+v 0.729612529278 0.981508433819 1.76144027710
+v 1.05923318863 0.981508433819 1.58525431156
+v 1.34814810753 0.981508433819 1.34814798832
+v 1.58525466919 0.981508493423 1.05923295021
+v 1.76144039631 0.981508493423 0.729612410069
+v 1.86993515491 0.981508493423 0.371953219175
+v 1.90656936169 0.981508493423 0.00000000000
+v 0.00000000000 0.789333820343 2.07388091087
+v 0.404594182968 0.789333820343 2.03403186798
+v 0.793640017509 0.789333879948 1.91601622105
+v 1.15218663216 0.789333879948 1.72436892986
+v 1.46645534039 0.789333879948 1.46645522118
+v 1.72436928749 0.789333939552 1.15218639374
+v 1.91601634026 0.789333939552 0.793639838696
+v 2.03403210640 0.789333939552 0.404594123363
+v 2.07388114929 0.789333939552 0.00000000000
+v 0.00000000000 0.579685330391 2.21890187263
+v 0.432886362076 0.579685330391 2.17626643181
+v 0.849137127399 0.579685389996 2.04999804497
+v 1.23275601864 0.579685389996 1.84494948387
+v 1.56900072098 0.579685449600 1.56900048256
+v 1.84494984150 0.579685449600 1.23275578022
+v 2.04999828339 0.579685449600 0.849136948586
+v 2.17626643181 0.579685449600 0.432886332273
+v 2.21890211105 0.579685449600 0.00000000000
+v 0.00000000000 0.357696920633 2.34411764145
+v 0.457314759493 0.357696950436 2.29907608032
+v 0.897055089474 0.357696980238 2.16568231583
+v 1.30232214928 0.357697010040 1.94906258583
+v 1.65754163265 0.357697010040 1.65754139423
+v 1.94906294346 0.357697039843 1.30232191086
+v 2.16568255424 0.357697039843 0.897054970264
+v 2.29907631874 0.357697069645 0.457314699888
+v 2.34411787987 0.357697069645 0.00000000000
+v 0.00000000000 0.118421189487 2.43018102646
+v 0.474104881287 0.118421219289 2.38348579407
+v 0.929990172386 0.118421241641 2.24519443512
+v 1.35013639927 0.118421271443 2.02062153816
+v 1.71839773655 0.118421293795 1.71839749813
+v 2.02062201500 0.118421308696 1.35013616085
+v 2.24519467354 0.118421323597 0.929989993572
+v 2.38348603249 0.118421331048 0.474104851484
+v 2.43018126488 0.118421331048 0.00000000000
+v 0.00000000000 -0.134944006801 2.43130278587
+v 0.474323749542 -0.134943976998 2.38458585739
+v 0.930419445038 -0.134943947196 2.24623084068
+v 1.35075962543 -0.134943932295 2.02155423164
+v 1.71919095516 -0.134943902493 1.71919071674
+v 2.02155470848 -0.134943887591 1.35075938702
+v 2.24623107910 -0.134943872690 0.930419266224
+v 2.38458609581 -0.134943857789 0.474323689938
+v 2.43130302429 -0.134943857789 0.00000000000
+v 0.00000000000 -0.347892343998 2.30445790291
+v 0.449577540159 -0.347892314196 2.26017832756
+v 0.881878018379 -0.347892284393 2.12904143333
+v 1.28028845787 -0.347892254591 1.91608667374
+v 1.62949812412 -0.347892254591 1.62949764729
+v 1.91608703136 -0.347892224789 1.28028798103
+v 2.12904191017 -0.347892224789 0.881877541542
+v 2.26017880440 -0.347892194986 0.449577212334
+v 2.30445814133 -0.347892194986 0.00000000000
+v 0.00000000000 -0.418420016766 2.13941001892
+v 0.417378276587 -0.418419986963 2.09830188751
+v 0.818716943264 -0.418419957161 1.97655701637
+v 1.18859279156 -0.418419957161 1.77885437012
+v 1.51279163361 -0.418419927359 1.51279115677
+v 1.77885472775 -0.418419897556 1.18859231472
+v 1.97655737400 -0.418419897556 0.818716526031
+v 2.09830212593 -0.418419897556 0.417377978563
+v 2.13941025734 -0.418419897556 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.512883007526 0.00000000000
+v 0.00000000000 0.734181761742 0.188552573323
+v 0.0367847941816 0.734181761742 0.184929594398
+v 0.0721559599042 0.734181761742 0.174199879169
+v 0.104754216969 0.734181761742 0.156775757670
+v 0.133326843381 0.734181761742 0.133326828480
+v 0.156775772572 0.734181761742 0.104754231870
+v 0.174199908972 0.734181761742 0.0721559897065
+v 0.184929639101 0.734181761742 0.0367848277092
+v 0.188552647829 0.734181761742 0.00000000000
+v 0.00000000000 0.895024657249 0.416212409735
+v 0.0811990275979 0.895024657249 0.408215016127
+v 0.159277617931 0.895024657249 0.384530127048
+v 0.231235265732 0.895024657249 0.346067994833
+v 0.294306665659 0.895024657249 0.294306635857
+v 0.346068054438 0.895024657249 0.231235250831
+v 0.384530246258 0.895024657249 0.159277647734
+v 0.408215105534 0.895024657249 0.0811990648508
+v 0.416212528944 0.895024657249 0.00000000000
+v 0.00000000000 0.981257736683 0.681565940380
+v 0.132966950536 0.981257736683 0.668469846249
+v 0.260824024677 0.981257736683 0.629684865475
+v 0.378657847643 0.981257736683 0.566701412201
+v 0.481940001249 0.981257736683 0.481939941645
+v 0.566701471806 0.981257796288 0.378657758236
+v 0.629684925079 0.981257796288 0.260823994875
+v 0.668469965458 0.981257796288 0.132966920733
+v 0.681566059589 0.981257796288 0.00000000000
+v 0.00000000000 1.00112521648 0.960314631462
+v 0.187348127365 1.00112521648 0.941862463951
+v 0.367496550083 1.00112521648 0.887215077877
+v 0.533522307873 1.00112521648 0.798472464085
+v 0.679045081139 1.00112521648 0.679045021534
+v 0.798472583294 1.00112521648 0.533522248268
+v 0.887215197086 1.00112521648 0.367496490479
+v 0.941862583160 1.00112521648 0.187348112464
+v 0.960314810276 1.00112521648 0.00000000000
+v 0.00000000000 0.969767212868 1.23817658424
+v 0.241556316614 0.969767212868 1.21438539028
+v 0.473829776049 0.969767212868 1.14392602444
+v 0.687894165516 0.969767272472 1.02950620651
+v 0.875523209572 0.969767272472 0.875523030758
+v 1.02950632572 0.969767272472 0.687893986702
+v 1.14392614365 0.969767272472 0.473829656839
+v 1.21438550949 0.969767272472 0.241556286812
+v 1.23817670345 0.969767272472 0.00000000000
+v 0.00000000000 0.886858522892 1.50508165359
+v 0.293626934290 0.886858522892 1.47616195679
+v 0.575969934464 0.886858582497 1.39051413536
+v 0.836178779602 0.886858582497 1.25142967701
+v 1.06425356865 0.886858582497 1.06425344944
+v 1.25142979622 0.886858582497 0.836178481579
+v 1.39051425457 0.886858582497 0.575969815254
+v 1.47616195679 0.886858582497 0.293626874685
+v 1.50508189201 0.886858642101 0.00000000000
+v 0.00000000000 0.745474517345 1.74579274654
+v 0.340587317944 0.745474517345 1.71224784851
+v 0.668086051941 0.745474576950 1.61290228367
+v 0.969910681248 0.745474576950 1.45157361031
+v 1.23446202278 0.745474576950 1.23446190357
+v 1.45157384872 0.745474576950 0.969910383224
+v 1.61290240288 0.745474636555 0.668085932732
+v 1.71224796772 0.745474636555 0.340587288141
+v 1.74579298496 0.745474636555 0.00000000000
+v 0.00000000000 0.537642598152 1.93074250221
+v 0.376669257879 0.537642598152 1.89364385605
+v 0.738863289356 0.537642657757 1.78377354145
+v 1.07266318798 0.537642657757 1.60535371304
+v 1.36524116993 0.537642657757 1.36524105072
+v 1.60535407066 0.537642717361 1.07266294956
+v 1.78377366066 0.537642717361 0.738863170147
+v 1.89364397526 0.537642717361 0.376669198275
+v 1.93074274063 0.537642717361 0.00000000000
+v 0.00000000000 0.269756197929 1.99614274502
+v 0.389428228140 0.269756227732 1.95778751373
+v 0.763890862465 0.269756257534 1.84419548512
+v 1.10899758339 0.269756257534 1.65973198414
+v 1.41148614883 0.269756287336 1.41148602962
+v 1.65973234177 0.269756287336 1.10899734497
+v 1.84419560432 0.269756317139 0.763890743256
+v 1.95778763294 0.269756317139 0.389428168535
+v 1.99614298344 0.269756317139 0.00000000000
+v 0.00000000000 -0.00477932812646 1.94291639328
+v 0.379044264555 -0.00477930530906 1.90558373928
+v 0.743522047997 -0.00477928388864 1.79502058029
+v 1.07942664623 -0.00477926386520 1.61547589302
+v 1.37384951115 -0.00477924617007 1.37384939194
+v 1.61547625065 -0.00477923173457 1.07942640781
+v 1.79502081871 -0.00477922102436 0.743521928787
+v 1.90558397770 -0.00477921450511 0.379044204950
+v 1.94291663170 -0.00477921217680 0.00000000000
+v 0.00000000000 -0.275719702244 1.99091351032
+v 0.388408064842 -0.275719672441 1.95265865326
+v 0.761889755726 -0.275719642639 1.83936417103
+v 1.10609257221 -0.275719642639 1.65538406372
+v 1.40778863430 -0.275719612837 1.40778827667
+v 1.65538442135 -0.275719612837 1.10609209538
+v 1.83936452866 -0.275719583035 0.761889338493
+v 1.95265901089 -0.275719583035 0.388407766819
+v 1.99091374874 -0.275719583035 0.00000000000
+v 0.00000000000 -0.418420016766 2.13941001892
+v 0.417378276587 -0.418419986963 2.09830188751
+v 0.818716943264 -0.418419957161 1.97655701637
+v 1.18859279156 -0.418419957161 1.77885437012
+v 1.51279163361 -0.418419927359 1.51279115677
+v 1.77885472775 -0.418419897556 1.18859231472
+v 1.97655737400 -0.418419897556 0.818716526031
+v 2.09830212593 -0.418419897556 0.417377978563
+v 2.13941025734 -0.418419897556 0.00000000000
+v 2.14007830620 -0.418796598911 -0.0368032231927
+v 2.04664254189 -0.828077733517 -0.0341006405652
+v 1.98348164558 -1.24324965477 -0.0319110713899
+v 1.93546414375 -1.66048097610 -0.0299804508686
+v 1.89577078819 -2.07859110832 -0.0281928163022
+v 1.86292469501 -2.49729800224 -0.0265231449157
+v 1.83479392529 -2.91635060310 -0.0249348729849
+v 1.81011140347 -3.33562064171 -0.0234062261879
+v 1.78803622723 -3.75503730774 -0.0219227001071
+v 1.76795697212 -4.17455387115 -0.0204737558961
+v 1.75010693073 -4.59417104721 -0.0190634541214
+v 1.73491787910 -5.01389360428 -0.0176993291825
+v 1.72265613079 -5.43371152878 -0.0163860470057
+v 1.71352374554 -5.85360956192 -0.0151271810755
+v 1.70721590519 -6.27355909348 -0.0139174815267
+v 1.70345759392 -6.69354009628 -0.0127522032708
+v 1.70194685459 -7.11353540421 -0.0116261169314
+v 1.70251107216 -7.53353309631 -0.0105362441391
+v 1.70513868332 -7.95352315903 -0.00948240980506
+v 1.70998597145 -8.37349414825 -0.00846736878157
+v 1.71705317497 -8.79343318939 -0.00749116204679
+v 1.71955072880 -8.91691970825 -0.00721141509712
+v 2.17038989067 -0.410798013210 0.00000000000
+v 2.07692146301 -0.820080518723 0.00000000000
+v 2.01373171806 -1.23525381088 0.00000000000
+v 1.96568799019 -1.65248656273 0.00000000000
+v 1.92596936226 -2.07059836388 0.00000000000
+v 1.89309918880 -2.48930644989 0.00000000000
+v 1.86494493484 -2.90836048126 0.00000000000
+v 1.84023964405 -3.32763195038 0.00000000000
+v 1.81814193726 -3.74705004692 0.00000000000
+v 1.79804039001 -4.16656827927 0.00000000000
+v 1.78016841412 -4.58618688583 0.00000000000
+v 1.76495790482 -5.00591087341 0.00000000000
+v 1.75267505646 -5.42573022842 0.00000000000
+v 1.74352216721 -5.84562969208 0.00000000000
+v 1.73719418049 -6.26558065414 0.00000000000
+v 1.73341608047 -6.68556308746 0.00000000000
+v 1.73188591003 -7.10555982590 0.00000000000
+v 1.73243105412 -7.52555894852 0.00000000000
+v 1.73503994942 -7.94555044174 0.00000000000
+v 1.73986876011 -8.36552238464 0.00000000000
+v 1.74691784382 -8.78546237946 0.00000000000
+v 1.74941003323 -8.90894985199 0.00000000000
+v 2.14007830620 -0.418796598911 0.0368032231927
+v 2.04664254189 -0.828077733517 0.0341006405652
+v 1.98348164558 -1.24324965477 0.0319110713899
+v 1.93546414375 -1.66048097610 0.0299804508686
+v 1.89577078819 -2.07859110832 0.0281928163022
+v 1.86292469501 -2.49729800224 0.0265231449157
+v 1.83479392529 -2.91635060310 0.0249348729849
+v 1.81011140347 -3.33562064171 0.0234062261879
+v 1.78803622723 -3.75503730774 0.0219227001071
+v 1.76795697212 -4.17455387115 0.0204737558961
+v 1.75010693073 -4.59417104721 0.0190634541214
+v 1.73491787910 -5.01389360428 0.0176993291825
+v 1.72265613079 -5.43371152878 0.0163860470057
+v 1.71352374554 -5.85360956192 0.0151271810755
+v 1.70721590519 -6.27355909348 0.0139174815267
+v 1.70345759392 -6.69354009628 0.0127522032708
+v 1.70194685459 -7.11353540421 0.0116261169314
+v 1.70251107216 -7.53353309631 0.0105362441391
+v 1.70513868332 -7.95352315903 0.00948240980506
+v 1.70998597145 -8.37349414825 0.00846736878157
+v 1.71705317497 -8.79343318939 0.00749116204679
+v 1.71955072880 -8.91691970825 0.00721141509712
+v 1.83496057987 -0.418796598911 -1.10191166401
+v 1.75539410114 -0.828077733517 -1.05285334587
+v 1.70178985596 -1.24324965477 -1.01937663555
+v 1.66117084026 -1.66048097610 -0.993695914745
+v 1.62768924236 -2.07859110832 -0.972301065922
+v 1.60007858276 -2.49729800224 -0.954432070255
+v 1.57651078701 -2.91635060310 -0.938991189003
+v 1.55589926243 -3.33562064171 -0.925326108932
+v 1.53752350807 -3.75503730774 -0.913003742695
+v 1.52085876465 -4.17455387115 -0.901709258556
+v 1.50610530376 -4.59417104721 -0.891562879086
+v 1.49363327026 -5.01389360428 -0.882786989212
+v 1.48367094994 -5.43371152878 -0.875518798828
+v 1.47639143467 -5.85360956192 -0.869862377644
+v 1.47153353691 -6.27355909348 -0.865660846233
+v 1.46886134148 -6.69354009628 -0.862772524357
+v 1.46811616421 -7.11353540421 -0.861041963100
+v 1.46914970875 -7.53353309631 -0.860380172729
+v 1.47195219994 -7.95352315903 -0.860781371593
+v 1.47665750980 -8.37349414825 -0.862325966358
+v 1.48326611519 -8.79343318939 -0.865014135838
+v 1.48556888103 -8.91691970825 -0.866020619869
+v 1.87961280346 -0.410798013210 -1.08519494534
+v 1.79866671562 -0.820080518723 -1.03846073151
+v 1.74394273758 -1.23525381088 -1.00686585903
+v 1.70233571529 -1.65248656273 -0.982843995094
+v 1.66793835163 -2.07059836388 -0.962984681129
+v 1.63947200775 -2.48930644989 -0.946549594402
+v 1.61508965492 -2.90836048126 -0.932472467422
+v 1.59369421005 -3.32763195038 -0.920119822025
+v 1.57455706596 -3.74705004692 -0.909070968628
+v 1.55714857578 -4.16656827927 -0.899020195007
+v 1.54167103767 -4.58618688583 -0.890084207058
+v 1.52849841118 -5.00591087341 -0.882478952408
+v 1.51786112785 -5.42573022842 -0.876337528229
+v 1.50993442535 -5.84562969208 -0.871761083603
+v 1.50445425510 -6.26558065414 -0.868597090244
+v 1.50118231773 -6.68556308746 -0.866708040237
+v 1.49985718727 -7.10555982590 -0.865942955017
+v 1.50032925606 -7.52555894852 -0.866215527058
+v 1.50258862972 -7.94555044174 -0.867519974709
+v 1.50677049160 -8.36552238464 -0.869934380054
+v 1.51287519932 -8.78546237946 -0.873458921909
+v 1.51503348351 -8.90894985199 -0.874705016613
+v 1.87176382542 -0.418796598911 -1.03816664219
+v 1.78949463367 -0.828077733517 -0.993789255619
+v 1.73370099068 -1.24324965477 -0.964105010033
+v 1.69115126133 -1.66048097610 -0.941768229008
+v 1.65588200092 -2.07859110832 -0.923469722271
+v 1.62660169601 -2.49729800224 -0.908492624760
+v 1.60144555569 -2.91635060310 -0.895802736282
+v 1.57930552959 -3.33562064171 -0.884785294533
+v 1.55944609642 -3.75503730774 -0.875032484531
+v 1.54133248329 -4.17455387115 -0.866247713566
+v 1.52516877651 -4.59417104721 -0.858544051647
+v 1.51133251190 -5.01389360428 -0.852130889893
+v 1.50005698204 -5.43371152878 -0.847137331963
+v 1.49151861668 -5.85360956192 -0.843661367893
+v 1.48545098305 -6.27355909348 -0.841555058956
+v 1.48161363602 -6.69354009628 -0.840685069561
+v 1.47974216938 -7.11353540421 -0.840904891491
+v 1.47968590260 -7.53353309631 -0.842130899429
+v 1.48143458366 -7.95352315903 -0.844357311726
+v 1.48512494564 -8.37349414825 -0.847660005093
+v 1.49075722694 -8.79343318939 -0.852039039135
+v 1.49278032780 -8.91691970825 -0.853530108929
+v 1.03816652298 -0.418796598911 -1.87176394463
+v 0.993789136410 -0.828077733517 -1.78949475288
+v 0.964104950428 -1.24324965477 -1.73370110989
+v 0.941768169403 -1.66048097610 -1.69115138054
+v 0.923469662666 -2.07859110832 -1.65588212013
+v 0.908492565155 -2.49729800224 -1.62660169601
+v 0.895802676678 -2.91635060310 -1.60144555569
+v 0.884785234928 -3.33562064171 -1.57930564880
+v 0.875032424927 -3.75503730774 -1.55944621563
+v 0.866247653961 -4.17455387115 -1.54133260250
+v 0.858543992043 -4.59417104721 -1.52516889572
+v 0.852130830288 -5.01389360428 -1.51133263111
+v 0.847137272358 -5.43371152878 -1.50005710125
+v 0.843661308289 -5.85360956192 -1.49151873589
+v 0.841554999352 -6.27355909348 -1.48545110226
+v 0.840685009956 -6.69354009628 -1.48161375523
+v 0.840904831886 -7.11353540421 -1.47974228859
+v 0.842130839825 -7.53353309631 -1.47968602180
+v 0.844357252121 -7.95352315903 -1.48143470287
+v 0.847659945488 -8.37349414825 -1.48512506485
+v 0.852038979530 -8.79343318939 -1.49075734615
+v 0.853530049324 -8.91691970825 -1.49278044701
+v 1.08519482613 -0.410798013210 -1.87961292267
+v 1.03846061230 -0.820080518723 -1.79866683483
+v 1.00686573982 -1.23525381088 -1.74394285679
+v 0.982843935490 -1.65248656273 -1.70233583450
+v 0.962984621525 -2.07059836388 -1.66793847084
+v 0.946549534798 -2.48930644989 -1.63947212696
+v 0.932472407818 -2.90836048126 -1.61508977413
+v 0.920119762421 -3.32763195038 -1.59369432926
+v 0.909070909023 -3.74705004692 -1.57455718517
+v 0.899020135403 -4.16656827927 -1.55714869499
+v 0.890084147453 -4.58618688583 -1.54167115688
+v 0.882478892803 -5.00591087341 -1.52849841118
+v 0.876337468624 -5.42573022842 -1.51786124706
+v 0.871761023998 -5.84562969208 -1.50993454456
+v 0.868597030640 -6.26558065414 -1.50445437431
+v 0.866707980633 -6.68556308746 -1.50118243694
+v 0.865942895412 -7.10555982590 -1.49985730648
+v 0.866215467453 -7.52555894852 -1.50032937527
+v 0.867519915104 -7.94555044174 -1.50258874893
+v 0.869934320450 -8.36552238464 -1.50677061081
+v 0.873458862305 -8.78546237946 -1.51287531853
+v 0.874704957008 -8.90894985199 -1.51503360271
+v 1.10191154480 -0.418796598911 -1.83496069908
+v 1.05285322666 -0.828077733517 -1.75539422035
+v 1.01937651634 -1.24324965477 -1.70178997517
+v 0.993695855141 -1.66048097610 -1.66117095947
+v 0.972301006317 -2.07859110832 -1.62768936157
+v 0.954432010651 -2.49729800224 -1.60007858276
+v 0.938991129398 -2.91635060310 -1.57651078701
+v 0.925326049328 -3.33562064171 -1.55589938164
+v 0.913003683090 -3.75503730774 -1.53752362728
+v 0.901709198952 -4.17455387115 -1.52085888386
+v 0.891562819481 -4.59417104721 -1.50610542297
+v 0.882786929607 -5.01389360428 -1.49363338947
+v 0.875518739223 -5.43371152878 -1.48367106915
+v 0.869862318039 -5.85360956192 -1.47639155388
+v 0.865660786629 -6.27355909348 -1.47153365612
+v 0.862772464752 -6.69354009628 -1.46886146069
+v 0.861041903496 -7.11353540421 -1.46811628342
+v 0.860380113125 -7.53353309631 -1.46914982796
+v 0.860781311989 -7.95352315903 -1.47195231915
+v 0.862325906754 -8.37349414825 -1.47665762901
+v 0.865014076233 -8.79343318939 -1.48326623440
+v 0.866020560265 -8.91691970825 -1.48556900024
+v -0.0368033163249 -0.418796598911 -2.14007830620
+v -0.0341007299721 -0.828077733517 -2.04664254189
+v -0.0319111570716 -1.24324965477 -1.98348164558
+v -0.0299805346876 -1.66048097610 -1.93546414375
+v -0.0281928982586 -2.07859110832 -1.89577078819
+v -0.0265232268721 -2.49729800224 -1.86292469501
+v -0.0249349530786 -2.91635060310 -1.83479392529
+v -0.0234063044190 -3.33562064171 -1.81011140347
+v -0.0219227783382 -3.75503730774 -1.78803622723
+v -0.0204738322645 -4.17455387115 -1.76795697212
+v -0.0190635304898 -4.59417104721 -1.75010693073
+v -0.0176994055510 -5.01389360428 -1.73491787910
+v -0.0163861215115 -5.43371152878 -1.72265613079
+v -0.0151272555813 -5.85360956192 -1.71352374554
+v -0.0139175560325 -6.27355909348 -1.70721590519
+v -0.0127522777766 -6.69354009628 -1.70345759392
+v -0.0116261914372 -7.11353540421 -1.70194685459
+v -0.0105363186449 -7.53353309631 -1.70251107216
+v -0.00948248431087 -7.95352315903 -1.70513868332
+v -0.00846744328737 -8.37349414825 -1.70998597145
+v -0.00749123701826 -8.79343318939 -1.71705317497
+v -0.00721149006858 -8.91691970825 -1.71955072880
+v -9.48707565840e-08 -0.410798013210 -2.17038989067
+v -9.07851216425e-08 -0.820080518723 -2.07692146301
+v -8.80230075495e-08 -1.23525381088 -2.01373171806
+v -8.59229487560e-08 -1.65248656273 -1.96568799019
+v -8.41867944246e-08 -2.07059836388 -1.92596936226
+v -8.27499917477e-08 -2.48930644989 -1.89309918880
+v -8.15193317294e-08 -2.90836048126 -1.86494493484
+v -8.04394275633e-08 -3.32763195038 -1.84023964405
+v -7.94735086629e-08 -3.74705004692 -1.81814193726
+v -7.85948444104e-08 -4.16656827927 -1.79804039001
+v -7.78136310942e-08 -4.58618688583 -1.78016841412
+v -7.71487620455e-08 -5.00591087341 -1.76495790482
+v -7.66118617435e-08 -5.42573022842 -1.75267505646
+v -7.62117764452e-08 -5.84562969208 -1.74352216721
+v -7.59351692636e-08 -6.26558065414 -1.73719418049
+v -7.57700249210e-08 -6.68556308746 -1.73341608047
+v -7.57031344278e-08 -7.10555982590 -1.73188591003
+v -7.57269660312e-08 -7.52555894852 -1.73243105412
+v -7.58410081403e-08 -7.94555044174 -1.73503994942
+v -7.60520819654e-08 -8.36552238464 -1.73986876011
+v -7.63602017173e-08 -8.78546237946 -1.74691784382
+v -7.64691421296e-08 -8.90894985199 -1.74941003323
+v 0.0368031300604 -0.418796598911 -2.14007830620
+v 0.0341005511582 -0.828077733517 -2.04664254189
+v 0.0319109857082 -1.24324965477 -1.98348164558
+v 0.0299803670496 -1.66048097610 -1.93546414375
+v 0.0281927343458 -2.07859110832 -1.89577078819
+v 0.0265230629593 -2.49729800224 -1.86292469501
+v 0.0249347928911 -2.91635060310 -1.83479392529
+v 0.0234061479568 -3.33562064171 -1.81011140347
+v 0.0219226218760 -3.75503730774 -1.78803622723
+v 0.0204736795276 -4.17455387115 -1.76795697212
+v 0.0190633777529 -4.59417104721 -1.75010693073
+v 0.0176992528141 -5.01389360428 -1.73491787910
+v 0.0163859724998 -5.43371152878 -1.72265613079
+v 0.0151271065697 -5.85360956192 -1.71352374554
+v 0.0139174070209 -6.27355909348 -1.70721590519
+v 0.0127521287650 -6.69354009628 -1.70345759392
+v 0.0116260424256 -7.11353540421 -1.70194685459
+v 0.0105361696333 -7.53353309631 -1.70251107216
+v 0.00948233529925 -7.95352315903 -1.70513868332
+v 0.00846729427576 -8.37349414825 -1.70998597145
+v 0.00749108707532 -8.79343318939 -1.71705317497
+v 0.00721134012565 -8.91691970825 -1.71955072880
+v -1.10191178322 -0.418796598911 -1.83496057987
+v -1.05285346508 -0.828077733517 -1.75539410114
+v -1.01937675476 -1.24324965477 -1.70178985596
+v -0.993696033955 -1.66048097610 -1.66117084026
+v -0.972301185131 -2.07859110832 -1.62768924236
+v -0.954432189465 -2.49729800224 -1.60007858276
+v -0.938991308212 -2.91635060310 -1.57651078701
+v -0.925326228142 -3.33562064171 -1.55589926243
+v -0.913003861904 -3.75503730774 -1.53752350807
+v -0.901709377766 -4.17455387115 -1.52085876465
+v -0.891562998295 -4.59417104721 -1.50610530376
+v -0.882787108421 -5.01389360428 -1.49363327026
+v -0.875518918037 -5.43371152878 -1.48367094994
+v -0.869862496853 -5.85360956192 -1.47639143467
+v -0.865660965443 -6.27355909348 -1.47153353691
+v -0.862772643566 -6.69354009628 -1.46886134148
+v -0.861042082310 -7.11353540421 -1.46811616421
+v -0.860380291939 -7.53353309631 -1.46914970875
+v -0.860781490803 -7.95352315903 -1.47195219994
+v -0.862326085567 -8.37349414825 -1.47665750980
+v -0.865014255047 -8.79343318939 -1.48326611519
+v -0.866020739079 -8.91691970825 -1.48556888103
+v -1.08519506454 -0.410798013210 -1.87961280346
+v -1.03846085072 -0.820080518723 -1.79866671562
+v -1.00686597824 -1.23525381088 -1.74394273758
+v -0.982844114304 -1.65248656273 -1.70233571529
+v -0.962984800339 -2.07059836388 -1.66793835163
+v -0.946549713612 -2.48930644989 -1.63947200775
+v -0.932472586632 -2.90836048126 -1.61508965492
+v -0.920119941235 -3.32763195038 -1.59369421005
+v -0.909071087837 -3.74705004692 -1.57455706596
+v -0.899020314217 -4.16656827927 -1.55714857578
+v -0.890084326267 -4.58618688583 -1.54167103767
+v -0.882479071617 -5.00591087341 -1.52849841118
+v -0.876337647438 -5.42573022842 -1.51786112785
+v -0.871761202812 -5.84562969208 -1.50993442535
+v -0.868597209454 -6.26558065414 -1.50445425510
+v -0.866708159447 -6.68556308746 -1.50118231773
+v -0.865943074226 -7.10555982590 -1.49985718727
+v -0.866215646267 -7.52555894852 -1.50032925606
+v -0.867520093918 -7.94555044174 -1.50258862972
+v -0.869934499264 -8.36552238464 -1.50677049160
+v -0.873459041119 -8.78546237946 -1.51287519932
+v -0.874705135822 -8.90894985199 -1.51503348351
+v -1.03816676140 -0.418796598911 -1.87176382542
+v -0.993789374828 -0.828077733517 -1.78949463367
+v -0.964105129242 -1.24324965477 -1.73370099068
+v -0.941768348217 -1.66048097610 -1.69115126133
+v -0.923469841480 -2.07859110832 -1.65588200092
+v -0.908492743969 -2.49729800224 -1.62660169601
+v -0.895802855492 -2.91635060310 -1.60144555569
+v -0.884785413742 -3.33562064171 -1.57930552959
+v -0.875032603741 -3.75503730774 -1.55944609642
+v -0.866247832775 -4.17455387115 -1.54133248329
+v -0.858544170856 -4.59417104721 -1.52516877651
+v -0.852131009102 -5.01389360428 -1.51133251190
+v -0.847137451172 -5.43371152878 -1.50005698204
+v -0.843661487103 -5.85360956192 -1.49151861668
+v -0.841555178165 -6.27355909348 -1.48545098305
+v -0.840685188770 -6.69354009628 -1.48161363602
+v -0.840905010700 -7.11353540421 -1.47974216938
+v -0.842131018639 -7.53353309631 -1.47968590260
+v -0.844357430935 -7.95352315903 -1.48143458366
+v -0.847660124302 -8.37349414825 -1.48512494564
+v -0.852039158344 -8.79343318939 -1.49075722694
+v -0.853530228138 -8.91691970825 -1.49278032780
+v -1.87176382542 -0.418796598911 -1.03816676140
+v -1.78949463367 -0.828077733517 -0.993789374828
+v -1.73370099068 -1.24324965477 -0.964105129242
+v -1.69115126133 -1.66048097610 -0.941768348217
+v -1.65588200092 -2.07859110832 -0.923469841480
+v -1.62660169601 -2.49729800224 -0.908492743969
+v -1.60144555569 -2.91635060310 -0.895802855492
+v -1.57930552959 -3.33562064171 -0.884785413742
+v -1.55944609642 -3.75503730774 -0.875032603741
+v -1.54133248329 -4.17455387115 -0.866247832775
+v -1.52516877651 -4.59417104721 -0.858544170856
+v -1.51133251190 -5.01389360428 -0.852131009102
+v -1.50005698204 -5.43371152878 -0.847137451172
+v -1.49151861668 -5.85360956192 -0.843661487103
+v -1.48545098305 -6.27355909348 -0.841555178165
+v -1.48161363602 -6.69354009628 -0.840685188770
+v -1.47974216938 -7.11353540421 -0.840905010700
+v -1.47968590260 -7.53353309631 -0.842131018639
+v -1.48143458366 -7.95352315903 -0.844357430935
+v -1.48512494564 -8.37349414825 -0.847660124302
+v -1.49075722694 -8.79343318939 -0.852039158344
+v -1.49278032780 -8.91691970825 -0.853530228138
+v -1.87961280346 -0.410798013210 -1.08519506454
+v -1.79866671562 -0.820080518723 -1.03846085072
+v -1.74394273758 -1.23525381088 -1.00686597824
+v -1.70233571529 -1.65248656273 -0.982844114304
+v -1.66793835163 -2.07059836388 -0.962984800339
+v -1.63947200775 -2.48930644989 -0.946549713612
+v -1.61508965492 -2.90836048126 -0.932472586632
+v -1.59369421005 -3.32763195038 -0.920119941235
+v -1.57455706596 -3.74705004692 -0.909071087837
+v -1.55714857578 -4.16656827927 -0.899020314217
+v -1.54167103767 -4.58618688583 -0.890084326267
+v -1.52849841118 -5.00591087341 -0.882479071617
+v -1.51786112785 -5.42573022842 -0.876337647438
+v -1.50993442535 -5.84562969208 -0.871761202812
+v -1.50445425510 -6.26558065414 -0.868597209454
+v -1.50118231773 -6.68556308746 -0.866708159447
+v -1.49985718727 -7.10555982590 -0.865943074226
+v -1.50032925606 -7.52555894852 -0.866215646267
+v -1.50258862972 -7.94555044174 -0.867520093918
+v -1.50677049160 -8.36552238464 -0.869934499264
+v -1.51287519932 -8.78546237946 -0.873459041119
+v -1.51503348351 -8.90894985199 -0.874705135822
+v -1.83496057987 -0.418796598911 -1.10191178322
+v -1.75539410114 -0.828077733517 -1.05285346508
+v -1.70178985596 -1.24324965477 -1.01937675476
+v -1.66117084026 -1.66048097610 -0.993696033955
+v -1.62768924236 -2.07859110832 -0.972301185131
+v -1.60007858276 -2.49729800224 -0.954432189465
+v -1.57651078701 -2.91635060310 -0.938991308212
+v -1.55589926243 -3.33562064171 -0.925326228142
+v -1.53752350807 -3.75503730774 -0.913003861904
+v -1.52085876465 -4.17455387115 -0.901709377766
+v -1.50610530376 -4.59417104721 -0.891562998295
+v -1.49363327026 -5.01389360428 -0.882787108421
+v -1.48367094994 -5.43371152878 -0.875518918037
+v -1.47639143467 -5.85360956192 -0.869862496853
+v -1.47153353691 -6.27355909348 -0.865660965443
+v -1.46886134148 -6.69354009628 -0.862772643566
+v -1.46811616421 -7.11353540421 -0.861042082310
+v -1.46914970875 -7.53353309631 -0.860380291939
+v -1.47195219994 -7.95352315903 -0.860781490803
+v -1.47665750980 -8.37349414825 -0.862326085567
+v -1.48326611519 -8.79343318939 -0.865014255047
+v -1.48556888103 -8.91691970825 -0.866020739079
+v -2.14007830620 -0.418796598911 0.0368034094572
+v -2.04664254189 -0.828077733517 0.0341008193791
+v -1.98348164558 -1.24324965477 0.0319112464786
+v -1.93546414375 -1.66048097610 0.0299806203693
+v -1.89577078819 -2.07859110832 0.0281929820776
+v -1.86292469501 -2.49729800224 0.0265233069658
+v -1.83479392529 -2.91635060310 0.0249350331724
+v -1.81011140347 -3.33562064171 0.0234063845128
+v -1.78803622723 -3.75503730774 0.0219228565693
+v -1.76795697212 -4.17455387115 0.0204739104956
+v -1.75010693073 -4.59417104721 0.0190636068583
+v -1.73491787910 -5.01389360428 0.0176994800568
+v -1.72265613079 -5.43371152878 0.0163861978799
+v -1.71352374554 -5.85360956192 0.0151273310184
+v -1.70721590519 -6.27355909348 0.0139176305383
+v -1.70345759392 -6.69354009628 0.0127523522824
+v -1.70194685459 -7.11353540421 0.0116262659431
+v -1.70251107216 -7.53353309631 0.0105363931507
+v -1.70513868332 -7.95352315903 0.00948255881667
+v -1.70998597145 -8.37349414825 0.00846751872450
+v -1.71705317497 -8.79343318939 0.00749131198972
+v -1.71955072880 -8.91691970825 0.00721156550571
+v -2.17038989067 -0.410798013210 1.89741513168e-07
+v -2.07692146301 -0.820080518723 1.81570243285e-07
+v -2.01373171806 -1.23525381088 1.76046015099e-07
+v -1.96568799019 -1.65248656273 1.71845897512e-07
+v -1.92596936226 -2.07059836388 1.68373588849e-07
+v -1.89309918880 -2.48930644989 1.65499983495e-07
+v -1.86494493484 -2.90836048126 1.63038663459e-07
+v -1.84023964405 -3.32763195038 1.60878855127e-07
+v -1.81814193726 -3.74705004692 1.58947017326e-07
+v -1.79804039001 -4.16656827927 1.57189688821e-07
+v -1.78016841412 -4.58618688583 1.55627262188e-07
+v -1.76495790482 -5.00591087341 1.54297524091e-07
+v -1.75267505646 -5.42573022842 1.53223723487e-07
+v -1.74352216721 -5.84562969208 1.52423552890e-07
+v -1.73719418049 -6.26558065414 1.51870338527e-07
+v -1.73341608047 -6.68556308746 1.51540049842e-07
+v -1.73188591003 -7.10555982590 1.51406268856e-07
+v -1.73243105412 -7.52555894852 1.51453932062e-07
+v -1.73503994942 -7.94555044174 1.51682016281e-07
+v -1.73986876011 -8.36552238464 1.52104163931e-07
+v -1.74691784382 -8.78546237946 1.52720403435e-07
+v -1.74941003323 -8.90894985199 1.52938284259e-07
+v -2.14007830620 -0.418796598911 -0.0368030369282
+v -2.04664254189 -0.828077733517 -0.0341004617512
+v -1.98348164558 -1.24324965477 -0.0319108963013
+v -1.93546414375 -1.66048097610 -0.0299802813679
+v -1.89577078819 -2.07859110832 -0.0281926505268
+v -1.86292469501 -2.49729800224 -0.0265229828656
+v -1.83479392529 -2.91635060310 -0.0249347127974
+v -1.81011140347 -3.33562064171 -0.0234060678631
+v -1.78803622723 -3.75503730774 -0.0219225436449
+v -1.76795697212 -4.17455387115 -0.0204736012965
+v -1.75010693073 -4.59417104721 -0.0190633013844
+v -1.73491787910 -5.01389360428 -0.0176991783082
+v -1.72265613079 -5.43371152878 -0.0163858961314
+v -1.71352374554 -5.85360956192 -0.0151270311326
+v -1.70721590519 -6.27355909348 -0.0139173325151
+v -1.70345759392 -6.69354009628 -0.0127520542592
+v -1.70194685459 -7.11353540421 -0.0116259679198
+v -1.70251107216 -7.53353309631 -0.0105360951275
+v -1.70513868332 -7.95352315903 -0.00948226079345
+v -1.70998597145 -8.37349414825 -0.00846721883863
+v -1.71705317497 -8.79343318939 -0.00749101210386
+v -1.71955072880 -8.91691970825 -0.00721126468852
+v -1.83496057987 -0.418796598911 1.10191154480
+v -1.75539410114 -0.828077733517 1.05285322666
+v -1.70178985596 -1.24324965477 1.01937651634
+v -1.66117084026 -1.66048097610 0.993695855141
+v -1.62768924236 -2.07859110832 0.972301006317
+v -1.60007858276 -2.49729800224 0.954432010651
+v -1.57651078701 -2.91635060310 0.938991129398
+v -1.55589926243 -3.33562064171 0.925326049328
+v -1.53752350807 -3.75503730774 0.913003683090
+v -1.52085876465 -4.17455387115 0.901709198952
+v -1.50610530376 -4.59417104721 0.891562819481
+v -1.49363327026 -5.01389360428 0.882786929607
+v -1.48367094994 -5.43371152878 0.875518739223
+v -1.47639143467 -5.85360956192 0.869862318039
+v -1.47153353691 -6.27355909348 0.865660786629
+v -1.46886134148 -6.69354009628 0.862772464752
+v -1.46811616421 -7.11353540421 0.861041903496
+v -1.46914970875 -7.53353309631 0.860380113125
+v -1.47195219994 -7.95352315903 0.860781311989
+v -1.47665750980 -8.37349414825 0.862325906754
+v -1.48326611519 -8.79343318939 0.865014076233
+v -1.48556888103 -8.91691970825 0.866020560265
+v -1.87961280346 -0.410798013210 1.08519482613
+v -1.79866671562 -0.820080518723 1.03846061230
+v -1.74394273758 -1.23525381088 1.00686573982
+v -1.70233571529 -1.65248656273 0.982843935490
+v -1.66793835163 -2.07059836388 0.962984621525
+v -1.63947200775 -2.48930644989 0.946549534798
+v -1.61508965492 -2.90836048126 0.932472407818
+v -1.59369421005 -3.32763195038 0.920119762421
+v -1.57455706596 -3.74705004692 0.909070909023
+v -1.55714857578 -4.16656827927 0.899020135403
+v -1.54167103767 -4.58618688583 0.890084147453
+v -1.52849841118 -5.00591087341 0.882478892803
+v -1.51786112785 -5.42573022842 0.876337468624
+v -1.50993442535 -5.84562969208 0.871761023998
+v -1.50445425510 -6.26558065414 0.868597030640
+v -1.50118231773 -6.68556308746 0.866707980633
+v -1.49985718727 -7.10555982590 0.865942895412
+v -1.50032925606 -7.52555894852 0.866215467453
+v -1.50258862972 -7.94555044174 0.867519915104
+v -1.50677049160 -8.36552238464 0.869934320450
+v -1.51287519932 -8.78546237946 0.873458862305
+v -1.51503348351 -8.90894985199 0.874704957008
+v -1.87176382542 -0.418796598911 1.03816652298
+v -1.78949463367 -0.828077733517 0.993789136410
+v -1.73370099068 -1.24324965477 0.964104950428
+v -1.69115126133 -1.66048097610 0.941768169403
+v -1.65588200092 -2.07859110832 0.923469662666
+v -1.62660169601 -2.49729800224 0.908492565155
+v -1.60144555569 -2.91635060310 0.895802676678
+v -1.57930552959 -3.33562064171 0.884785234928
+v -1.55944609642 -3.75503730774 0.875032424927
+v -1.54133248329 -4.17455387115 0.866247653961
+v -1.52516877651 -4.59417104721 0.858543992043
+v -1.51133251190 -5.01389360428 0.852130830288
+v -1.50005698204 -5.43371152878 0.847137272358
+v -1.49151861668 -5.85360956192 0.843661308289
+v -1.48545098305 -6.27355909348 0.841554999352
+v -1.48161363602 -6.69354009628 0.840685009956
+v -1.47974216938 -7.11353540421 0.840904831886
+v -1.47968590260 -7.53353309631 0.842130839825
+v -1.48143458366 -7.95352315903 0.844357252121
+v -1.48512494564 -8.37349414825 0.847659945488
+v -1.49075722694 -8.79343318939 0.852038979530
+v -1.49278032780 -8.91691970825 0.853530049324
+v -1.03816640377 -0.418796598911 1.87176394463
+v -0.993789017200 -0.828077733517 1.78949475288
+v -0.964104831219 -1.24324965477 1.73370110989
+v -0.941768050194 -1.66048097610 1.69115138054
+v -0.923469543457 -2.07859110832 1.65588212013
+v -0.908492445946 -2.49729800224 1.62660169601
+v -0.895802557468 -2.91635060310 1.60144555569
+v -0.884785115719 -3.33562064171 1.57930564880
+v -0.875032305717 -3.75503730774 1.55944621563
+v -0.866247534752 -4.17455387115 1.54133260250
+v -0.858543872833 -4.59417104721 1.52516889572
+v -0.852130711079 -5.01389360428 1.51133263111
+v -0.847137153149 -5.43371152878 1.50005710125
+v -0.843661189079 -5.85360956192 1.49151873589
+v -0.841554880142 -6.27355909348 1.48545110226
+v -0.840684890747 -6.69354009628 1.48161375523
+v -0.840904712677 -7.11353540421 1.47974228859
+v -0.842130720615 -7.53353309631 1.47968602180
+v -0.844357132912 -7.95352315903 1.48143470287
+v -0.847659826279 -8.37349414825 1.48512506485
+v -0.852038860321 -8.79343318939 1.49075734615
+v -0.853529930115 -8.91691970825 1.49278044701
+v -1.08519470692 -0.410798013210 1.87961292267
+v -1.03846049309 -0.820080518723 1.79866683483
+v -1.00686562061 -1.23525381088 1.74394285679
+v -0.982843816280 -1.65248656273 1.70233583450
+v -0.962984502316 -2.07059836388 1.66793847084
+v -0.946549415588 -2.48930644989 1.63947212696
+v -0.932472288609 -2.90836048126 1.61508977413
+v -0.920119643211 -3.32763195038 1.59369432926
+v -0.909070789814 -3.74705004692 1.57455718517
+v -0.899020016193 -4.16656827927 1.55714869499
+v -0.890084028244 -4.58618688583 1.54167115688
+v -0.882478773594 -5.00591087341 1.52849841118
+v -0.876337349415 -5.42573022842 1.51786124706
+v -0.871760904789 -5.84562969208 1.50993454456
+v -0.868596911430 -6.26558065414 1.50445437431
+v -0.866707861423 -6.68556308746 1.50118243694
+v -0.865942776203 -7.10555982590 1.49985730648
+v -0.866215348244 -7.52555894852 1.50032937527
+v -0.867519795895 -7.94555044174 1.50258874893
+v -0.869934201241 -8.36552238464 1.50677061081
+v -0.873458743095 -8.78546237946 1.51287531853
+v -0.874704837799 -8.90894985199 1.51503360271
+v -1.10191142559 -0.418796598911 1.83496069908
+v -1.05285310745 -0.828077733517 1.75539422035
+v -1.01937639713 -1.24324965477 1.70178997517
+v -0.993695735931 -1.66048097610 1.66117095947
+v -0.972300887108 -2.07859110832 1.62768936157
+v -0.954431891441 -2.49729800224 1.60007858276
+v -0.938991010189 -2.91635060310 1.57651078701
+v -0.925325930119 -3.33562064171 1.55589938164
+v -0.913003563881 -3.75503730774 1.53752362728
+v -0.901709079742 -4.17455387115 1.52085888386
+v -0.891562700272 -4.59417104721 1.50610542297
+v -0.882786810398 -5.01389360428 1.49363338947
+v -0.875518620014 -5.43371152878 1.48367106915
+v -0.869862198830 -5.85360956192 1.47639155388
+v -0.865660667419 -6.27355909348 1.47153365612
+v -0.862772345543 -6.69354009628 1.46886146069
+v -0.861041784286 -7.11353540421 1.46811628342
+v -0.860379993916 -7.53353309631 1.46914982796
+v -0.860781192780 -7.95352315903 1.47195231915
+v -0.862325787544 -8.37349414825 1.47665762901
+v -0.865013957024 -8.79343318939 1.48326623440
+v -0.866020441055 -8.91691970825 1.48556900024
+v 0.0368032492697 -0.418796598911 2.14007830620
+v 0.0341006666422 -0.828077733517 2.04664254189
+v 0.0319110937417 -1.24324965477 1.98348164558
+v 0.0299804732203 -1.66048097610 1.93546414375
+v 0.0281928386539 -2.07859110832 1.89577078819
+v 0.0265231672674 -2.49729800224 1.86292469501
+v 0.0249348953366 -2.91635060310 1.83479392529
+v 0.0234062485397 -3.33562064171 1.81011140347
+v 0.0219227205962 -3.75503730774 1.78803622723
+v 0.0204737763852 -4.17455387115 1.76795697212
+v 0.0190634746104 -4.59417104721 1.75010693073
+v 0.0176993496716 -5.01389360428 1.73491787910
+v 0.0163860674948 -5.43371152878 1.72265613079
+v 0.0151272015646 -5.85360956192 1.71352374554
+v 0.0139175020158 -6.27355909348 1.70721590519
+v 0.0127522237599 -6.69354009628 1.70345759392
+v 0.0116261374205 -7.11353540421 1.70194685459
+v 0.0105362646282 -7.53353309631 1.70251107216
+v 0.00948243029416 -7.95352315903 1.70513868332
+v 0.00846738927066 -8.37349414825 1.70998597145
+v 0.00749118253589 -8.79343318939 1.71705317497
+v 0.00721143558621 -8.91691970825 1.71955072880
+v 2.58816399423e-08 -0.410798013210 2.17038989067
+v 2.47670399744e-08 -0.820080518723 2.07692146301
+v 2.40135111795e-08 -1.23525381088 2.01373171806
+v 2.34405952426e-08 -1.65248656273 1.96568799019
+v 2.29669545604e-08 -2.07059836388 1.92596936226
+v 2.25749818838e-08 -2.48930644989 1.89309918880
+v 2.22392451121e-08 -2.90836048126 1.86494493484
+v 2.19446381067e-08 -3.32763195038 1.84023964405
+v 2.16811262277e-08 -3.74705004692 1.81814193726
+v 2.14414175304e-08 -4.16656827927 1.79804039001
+v 2.12282955658e-08 -4.58618688583 1.78016841412
+v 2.10469117690e-08 -5.00591087341 1.76495790482
+v 2.09004404894e-08 -5.42573022842 1.75267505646
+v 2.07912940198e-08 -5.84562969208 1.74352216721
+v 2.07158326049e-08 -6.26558065414 1.73719418049
+v 2.06707806427e-08 -6.68556308746 1.73341608047
+v 2.06525321289e-08 -7.10555982590 1.73188591003
+v 2.06590335949e-08 -7.52555894852 1.73243105412
+v 2.06901447086e-08 -7.94555044174 1.73503994942
+v 2.07477270919e-08 -8.36552238464 1.73986876011
+v 2.08317860739e-08 -8.78546237946 1.74691784382
+v 2.08615063002e-08 -8.90894985199 1.74941003323
+v -0.0368031971157 -0.418796598911 2.14007830620
+v -0.0341006144881 -0.828077733517 2.04664254189
+v -0.0319110490382 -1.24324965477 1.98348164558
+v -0.0299804285169 -1.66048097610 1.93546414375
+v -0.0281927939504 -2.07859110832 1.89577078819
+v -0.0265231225640 -2.49729800224 1.86292469501
+v -0.0249348506331 -2.91635060310 1.83479392529
+v -0.0234062038362 -3.33562064171 1.81011140347
+v -0.0219226796180 -3.75503730774 1.78803622723
+v -0.0204737354070 -4.17455387115 1.76795697212
+v -0.0190634336323 -4.59417104721 1.75010693073
+v -0.0176993086934 -5.01389360428 1.73491787910
+v -0.0163860265166 -5.43371152878 1.72265613079
+v -0.0151271605864 -5.85360956192 1.71352374554
+v -0.0139174610376 -6.27355909348 1.70721590519
+v -0.0127521827817 -6.69354009628 1.70345759392
+v -0.0116260964423 -7.11353540421 1.70194685459
+v -0.0105362236500 -7.53353309631 1.70251107216
+v -0.00948238931596 -7.95352315903 1.70513868332
+v -0.00846734829247 -8.37349414825 1.70998597145
+v -0.00749114155769 -8.79343318939 1.71705317497
+v -0.00721139460802 -8.91691970825 1.71955072880
+v 1.10191142559 -0.418796598911 1.83496069908
+v 1.05285310745 -0.828077733517 1.75539422035
+v 1.01937639713 -1.24324965477 1.70178997517
+v 0.993695735931 -1.66048097610 1.66117095947
+v 0.972300887108 -2.07859110832 1.62768936157
+v 0.954431891441 -2.49729800224 1.60007858276
+v 0.938991010189 -2.91635060310 1.57651078701
+v 0.925325930119 -3.33562064171 1.55589938164
+v 0.913003563881 -3.75503730774 1.53752362728
+v 0.901709079742 -4.17455387115 1.52085888386
+v 0.891562700272 -4.59417104721 1.50610542297
+v 0.882786810398 -5.01389360428 1.49363338947
+v 0.875518620014 -5.43371152878 1.48367106915
+v 0.869862198830 -5.85360956192 1.47639155388
+v 0.865660667419 -6.27355909348 1.47153365612
+v 0.862772345543 -6.69354009628 1.46886146069
+v 0.861041784286 -7.11353540421 1.46811628342
+v 0.860379993916 -7.53353309631 1.46914982796
+v 0.860781192780 -7.95352315903 1.47195231915
+v 0.862325787544 -8.37349414825 1.47665762901
+v 0.865013957024 -8.79343318939 1.48326623440
+v 0.866020441055 -8.91691970825 1.48556900024
+v 1.08519470692 -0.410798013210 1.87961292267
+v 1.03846049309 -0.820080518723 1.79866683483
+v 1.00686562061 -1.23525381088 1.74394285679
+v 0.982843816280 -1.65248656273 1.70233583450
+v 0.962984502316 -2.07059836388 1.66793847084
+v 0.946549415588 -2.48930644989 1.63947212696
+v 0.932472288609 -2.90836048126 1.61508977413
+v 0.920119643211 -3.32763195038 1.59369432926
+v 0.909070789814 -3.74705004692 1.57455718517
+v 0.899020016193 -4.16656827927 1.55714869499
+v 0.890084028244 -4.58618688583 1.54167115688
+v 0.882478773594 -5.00591087341 1.52849841118
+v 0.876337349415 -5.42573022842 1.51786124706
+v 0.871760904789 -5.84562969208 1.50993454456
+v 0.868596911430 -6.26558065414 1.50445437431
+v 0.866707861423 -6.68556308746 1.50118243694
+v 0.865942776203 -7.10555982590 1.49985730648
+v 0.866215348244 -7.52555894852 1.50032937527
+v 0.867519795895 -7.94555044174 1.50258874893
+v 0.869934201241 -8.36552238464 1.50677061081
+v 0.873458743095 -8.78546237946 1.51287531853
+v 0.874704837799 -8.90894985199 1.51503360271
+v 1.03816640377 -0.418796598911 1.87176394463
+v 0.993789017200 -0.828077733517 1.78949475288
+v 0.964104831219 -1.24324965477 1.73370110989
+v 0.941768050194 -1.66048097610 1.69115138054
+v 0.923469543457 -2.07859110832 1.65588212013
+v 0.908492445946 -2.49729800224 1.62660169601
+v 0.895802557468 -2.91635060310 1.60144555569
+v 0.884785115719 -3.33562064171 1.57930564880
+v 0.875032305717 -3.75503730774 1.55944621563
+v 0.866247534752 -4.17455387115 1.54133260250
+v 0.858543872833 -4.59417104721 1.52516889572
+v 0.852130711079 -5.01389360428 1.51133263111
+v 0.847137153149 -5.43371152878 1.50005710125
+v 0.843661189079 -5.85360956192 1.49151873589
+v 0.841554880142 -6.27355909348 1.48545110226
+v 0.840684890747 -6.69354009628 1.48161375523
+v 0.840904712677 -7.11353540421 1.47974228859
+v 0.842130720615 -7.53353309631 1.47968602180
+v 0.844357132912 -7.95352315903 1.48143470287
+v 0.847659826279 -8.37349414825 1.48512506485
+v 0.852038860321 -8.79343318939 1.49075734615
+v 0.853529930115 -8.91691970825 1.49278044701
+v 1.87176358700 -0.418796598911 1.03816699982
+v 1.78949451447 -0.828077733517 0.993789613247
+v 1.73370087147 -1.24324965477 0.964105367661
+v 1.69115114212 -1.66048097610 0.941768586636
+v 1.65588188171 -2.07859110832 0.923470079899
+v 1.62660157681 -2.49729800224 0.908492982388
+v 1.60144543648 -2.91635060310 0.895803093910
+v 1.57930541039 -3.33562064171 0.884785592556
+v 1.55944609642 -3.75503730774 0.875032782555
+v 1.54133236408 -4.17455387115 0.866248011589
+v 1.52516865730 -4.59417104721 0.858544349670
+v 1.51133239269 -5.01389360428 0.852131187916
+v 1.50005686283 -5.43371152878 0.847137629986
+v 1.49151849747 -5.85360956192 0.843661665916
+v 1.48545098305 -6.27355909348 0.841555356979
+v 1.48161351681 -6.69354009628 0.840685367584
+v 1.47974205017 -7.11353540421 0.840905189514
+v 1.47968578339 -7.53353309631 0.842131197453
+v 1.48143446445 -7.95352315903 0.844357609749
+v 1.48512482643 -8.37349414825 0.847660303116
+v 1.49075710773 -8.79343318939 0.852039337158
+v 1.49278020859 -8.91691970825 0.853530406952
+v 1.87961256504 -0.410798013210 1.08519530296
+v 1.79866659641 -0.820080518723 1.03846108913
+v 1.74394261837 -1.23525381088 1.00686621666
+v 1.70233559608 -1.65248656273 0.982844352722
+v 1.66793823242 -2.07059836388 0.962985038757
+v 1.63947188854 -2.48930644989 0.946549952030
+v 1.61508953571 -2.90836048126 0.932472825050
+v 1.59369409084 -3.32763195038 0.920120179653
+v 1.57455694675 -3.74705004692 0.909071266651
+v 1.55714857578 -4.16656827927 0.899020493031
+v 1.54167091846 -4.58618688583 0.890084505081
+v 1.52849829197 -5.00591087341 0.882479250431
+v 1.51786100864 -5.42573022842 0.876337826252
+v 1.50993430614 -5.84562969208 0.871761381626
+v 1.50445413589 -6.26558065414 0.868597388268
+v 1.50118219852 -6.68556308746 0.866708338261
+v 1.49985706806 -7.10555982590 0.865943253040
+v 1.50032913685 -7.52555894852 0.866215825081
+v 1.50258851051 -7.94555044174 0.867520272732
+v 1.50677037239 -8.36552238464 0.869934678078
+v 1.51287508011 -8.78546237946 0.873459219933
+v 1.51503336430 -8.90894985199 0.874705314636
+v 1.83496034145 -0.418796598911 1.10191202164
+v 1.75539398193 -0.828077733517 1.05285370350
+v 1.70178973675 -1.24324965477 1.01937699318
+v 1.66117072105 -1.66048097610 0.993696272373
+v 1.62768912315 -2.07859110832 0.972301423550
+v 1.60007846355 -2.49729800224 0.954432427883
+v 1.57651066780 -2.91635060310 0.938991546631
+v 1.55589914322 -3.33562064171 0.925326406956
+v 1.53752326965 -3.75503730774 0.913004040718
+v 1.52085864544 -4.17455387115 0.901709556580
+v 1.50610518456 -4.59417104721 0.891563177109
+v 1.49363315105 -5.01389360428 0.882787287235
+v 1.48367083073 -5.43371152878 0.875519096851
+v 1.47639131546 -5.85360956192 0.869862675667
+v 1.47153353691 -6.27355909348 0.865661144257
+v 1.46886122227 -6.69354009628 0.862772822380
+v 1.46811604500 -7.11353540421 0.861042261124
+v 1.46914958954 -7.53353309631 0.860380470753
+v 1.47195208073 -7.95352315903 0.860781669617
+v 1.47665739059 -8.37349414825 0.862326264381
+v 1.48326599598 -8.79343318939 0.865014433861
+v 1.48556876183 -8.91691970825 0.866020917892
+v 1.34025776386 0.224341705441 0.893152236938
+v 0.948108494282 0.697064042091 0.575407683849
+v 0.629241466522 0.745632708073 0.337044954300
+v 0.348916083574 0.627248585224 0.140597522259
+v 0.0352053716779 0.377591788769 -0.0213888939470
+v 0.351581811905 0.635162472725 -0.208860591054
+v 0.636798977852 0.758229315281 -0.399993628263
+v 0.950840592384 0.715482532978 -0.621411204338
+v 1.33508372307 0.257521241903 -0.899675965309
+v 1.28630971909 -0.0666490197182 0.829961478710
+v 0.926218152046 0.370055854321 0.520223796368
+v 0.637903034687 0.416028052568 0.281918168068
+v 0.346148699522 0.304290801287 0.146094620228
+v 0.0731019526720 0.0743406116962 -0.0217581726611
+v 0.357968837023 0.312744766474 -0.195187151432
+v 0.630768597126 0.427057445049 -0.364583671093
+v 0.930698335171 0.388275861740 -0.562738955021
+v 1.28270900249 -0.0350034832954 -0.844231247902
+v 1.23640727997 -0.365398585796 0.767941296101
+v 0.889881432056 0.0378883257508 0.486467361450
+v 0.613934338093 0.0793285667896 0.278625160456
+v 0.354106694460 -0.0229657329619 0.133013218641
+v 0.0718219429255 -0.233621567488 -0.0208880044520
+v 0.372171819210 -0.0138031365350 -0.168519675732
+v 0.627948164940 0.0914766862988 -0.326782882214
+v 0.893903076649 0.0547426007688 -0.530046701431
+v 1.22488427162 -0.337240546942 -0.801718413830
+v 1.19505798817 -0.668307662010 0.703647494316
+v 0.855095922947 -0.299033880234 0.455623894930
+v 0.606642663479 -0.260383635759 0.253515541553
+v 0.370027869940 -0.353987246752 0.105984576046
+v 0.122017599642 -0.547029376030 -0.0210377201438
+v 0.358789622784 -0.347642064095 -0.192820012569
+v 0.613558709621 -0.248514205217 -0.309968143702
+v 0.852122902870 -0.282889872789 -0.508776128292
+v 1.22579002380 -0.639858424664 -0.681404769421
+v 1.08336043358 -0.979578554630 0.723397612572
+v 0.854664444923 -0.639635503292 0.388843506575
+v 0.609979271889 -0.604736268520 0.214778274298
+v 0.375886499882 -0.690936744213 0.0994643121958
+v 0.129926323891 -0.865121424198 -0.0199016705155
+v 0.375591367483 -0.683255732059 -0.163376346231
+v 0.618578433990 -0.593758523464 -0.264184951782
+v 0.850169003010 -0.624104738235 -0.437422573566
+v 1.10134196281 -0.952610015869 -0.743428289890
+v 1.14935696125 -1.29451036453 0.558082640171
+v 0.803838789463 -0.984061539173 0.385840356350
+v 0.572969913483 -0.953997015953 0.240961819887
+v 0.384302437305 -1.03141844273 0.0902752131224
+v 0.181970611215 -1.18897473812 -0.0196616481990
+v 0.376675993204 -1.02434051037 -0.163896486163
+v 0.589265048504 -0.941672027111 -0.279256969690
+v 0.802135825157 -0.968460440636 -0.434271007776
+v 1.18059539795 -1.26515340805 -0.521754503250
+v 0.982017159462 -1.61376023293 0.648066222668
+v 0.815111160278 -1.33434975147 0.311532586813
+v 0.602604985237 -1.30607593060 0.167641863227
+v 0.383985459805 -1.37828421593 0.102121360600
+v 0.174552753568 -1.51930284500 -0.0175641216338
+v 0.398811519146 -1.36971330643 -0.125040903687
+v 0.604309797287 -1.29584300518 -0.219935417175
+v 0.808437943459 -1.31988227367 -0.353922754526
+v 0.989567220211 -1.59146261215 -0.693742394447
+v 1.09752428532 -1.94184899330 0.426895588636
+v 0.735990524292 -1.68858504295 0.355295211077
+v 0.572998523712 -1.66261196136 0.194633916020
+v 0.396710544825 -1.72750020027 0.0846602097154
+v 0.198387265205 -1.85519933701 -0.0159944090992
+v 0.390675663948 -1.71984875202 -0.146523967385
+v 0.552833259106 -1.65355741978 -0.275030970573
+v 0.731123924255 -1.67484593391 -0.406848371029
+v 1.11361610889 -1.91630566120 -0.424654990435
+v 0.897060275078 -2.27331733704 0.575903058052
+v 0.782896995544 -2.04673838615 0.243386641145
+v 0.588324487209 -2.02465367317 0.143859043717
+v 0.409091174603 -2.08318138123 0.0726032704115
+v 0.203580096364 -2.19600677490 -0.0138233313337
+v 0.416239708662 -2.07490324974 -0.104037612677
+v 0.605966389179 -2.01427340508 -0.159499943256
+v 0.795602679253 -2.03379774094 -0.258006751537
+v 0.929091930389 -2.25248265266 -0.598306536674
+v 1.02091801167 -2.61212730408 0.355173647404
+v 0.691302299500 -2.41012716293 0.315055876970
+v 0.550404489040 -2.39015221596 0.189484164119
+v 0.402052581310 -2.44239664078 0.0997400954366
+v 0.235792264342 -2.54131340981 -0.0118754403666
+v 0.408936768770 -2.43367910385 -0.125530570745
+v 0.545897543430 -2.38036751747 -0.239608019590
+v 0.687551498413 -2.39732050896 -0.360030710697
+v 1.03466939926 -2.59154176712 -0.368869602680
+v 0.846544682980 -2.95548081398 0.488743364811
+v 0.755732953548 -2.77681112289 0.189518302679
+v 0.597752094269 -2.75940513611 0.0926153510809
+v 0.433349281549 -2.80647850037 0.0482544265687
+v 0.265654921532 -2.89224982262 -0.00985813513398
+v 0.443652123213 -2.79733729362 -0.0578177943826
+v 0.596182405949 -2.75015139580 -0.129338875413
+v 0.770700275898 -2.76438736916 -0.191518858075
+v 0.887509822845 -2.93660664558 -0.497027903795
+v 0.946059823036 -3.30406403542 0.299595981836
+v 0.654048681259 -3.14956021309 0.284448802471
+v 0.546500205994 -3.13409805298 0.169885158539
+v 0.427139729261 -3.17468976974 0.0813064500690
+v 0.279885679483 -3.24846053123 -0.00703885685652
+v 0.421037793159 -3.16653656960 -0.120458625257
+v 0.543384611607 -3.12447357178 -0.205691248178
+v 0.662065386772 -3.13711929321 -0.305220425129
+v 0.961672723293 -3.28623652458 -0.313315182924
+v 0.824878811836 -3.65978288651 0.392880678177
+v 0.720916748047 -3.52419734001 0.164370417595
+v 0.584228932858 -3.51199221611 0.0936472490430
+v 0.447246521711 -3.54856371880 0.0587842464447
+v 0.305796325207 -3.61128830910 -0.00434590457007
+v 0.447707295418 -3.54036998749 -0.0827043801546
+v 0.577942550182 -3.50375485420 -0.127543807030
+v 0.722279846668 -3.51277923584 -0.170976623893
+v 0.858376622200 -3.64329743385 -0.398682296276
+v 0.889223635197 -4.02129554749 0.256438165903
+v 0.660967767239 -3.90569090843 0.214575916529
+v 0.557058632374 -3.89511179924 0.138854697347
+v 0.450272202492 -3.92562890053 0.0728520676494
+v 0.336228489876 -3.97645616531 -0.00139184540603
+v 0.447169810534 -3.91713571548 -0.0927411168814
+v 0.551218926907 -3.88549137115 -0.163999363780
+v 0.655723989010 -3.89420914650 -0.238620623946
+v 0.903346359730 -4.00617265701 -0.275876104832
+v 0.756510019302 -4.38999366760 0.374437153339
+v 0.692001044750 -4.28882503510 0.153471216559
+v 0.581350505352 -4.28100442886 0.0899336859584
+v 0.466313004494 -4.30863380432 0.0611067749560
+v 0.347106665373 -4.35163688660 0.00217318465002
+v 0.462751030922 -4.30032634735 -0.0769754275680
+v 0.571618199348 -4.27289772034 -0.117462053895
+v 0.684398889542 -4.27872610092 -0.159557431936
+v 0.830688059330 -4.37176561356 -0.320316582918
+v 0.855635941029 -4.76176738739 0.216867938638
+v 0.658083558083 -4.67957067490 0.175537407398
+v 0.559168756008 -4.67260122299 0.134783029556
+v 0.461838752031 -4.69464635849 0.0930508226156
+v 0.371480941772 -4.72722530365 0.00577405327931
+v 0.475073277950 -4.68610763550 -0.0659414455295
+v 0.565557956696 -4.66351270676 -0.123220093548
+v 0.667771875858 -4.66871595383 -0.158197104931
+v 0.870559811592 -4.74656343460 -0.205356210470
+v 0.732425212860 -5.13968086243 0.330772340298
+v 0.647610127926 -5.07255935669 0.174935489893
+v 0.568663716316 -5.06823968887 0.122337311506
+v 0.477074265480 -5.08737993240 0.0868875011802
+v 0.391878604889 -5.11299991608 0.00971189048141
+v 0.488390177488 -5.07775878906 -0.0563410893083
+v 0.580751717091 -5.05760526657 -0.0893457233906
+v 0.657141625881 -5.06211566925 -0.153705671430
+v 0.774797260761 -5.12678909302 -0.307378083467
+v 0.834412276745 -5.52482271194 0.194403469563
+v 0.680178105831 -5.47155380249 0.119324214756
+v 0.589602649212 -5.46836519241 0.0871751010418
+v 0.505468189716 -5.48234176636 0.0581752397120
+v 0.411020219326 -5.49935340881 0.0138326231390
+v 0.507342219353 -5.47324562073 -0.0360760241747
+v 0.589117705822 -5.45860481262 -0.0721827819943
+v 0.670629262924 -5.46100807190 -0.109923057258
+v 0.847322583199 -5.51079559326 -0.152556106448
+v 0.693698585033 -5.91367340088 0.325382858515
+v 0.616905689240 -5.87330055237 0.199512600899
+v 0.568831801414 -5.87189912796 0.146758168936
+v 0.501248478889 -5.88364458084 0.0954632088542
+v 0.419492125511 -5.89652872086 0.0184853803366
+v 0.511017143726 -5.87426280975 -0.0489783473313
+v 0.581425786018 -5.86168956757 -0.0937713384628
+v 0.653666257858 -5.86258268356 -0.133789733052
+v 0.764474451542 -5.90093517303 -0.248104348779
+v 0.832903385162 -6.30964469910 0.160580784082
+v 0.694649696350 -6.28076982498 0.0927494689822
+v 0.614447772503 -6.28093099594 0.0527101904154
+v 0.539588630199 -6.28805494308 0.0506022758782
+v 0.452063024044 -6.29294729233 0.0228255819529
+v 0.538334906101 -6.27845573425 -0.0145919816568
+v 0.608190417290 -6.27035808563 -0.0352961011231
+v 0.683578848839 -6.27043676376 -0.0619169287384
+v 0.826601564884 -6.29780244827 -0.120903402567
+v 0.691076815128 -6.70962333679 0.304186820984
+v 0.618173480034 -6.69062232971 0.205385938287
+v 0.572435438633 -6.69233179092 0.180894434452
+v 0.498956292868 -6.69874858856 0.136896938086
+v 0.424269795418 -6.70190191269 0.0277483258396
+v 0.505485832691 -6.69003725052 -0.0777272954583
+v 0.587288558483 -6.68257379532 -0.101751796901
+v 0.647568285465 -6.68154096603 -0.126952752471
+v 0.740615129471 -6.69943904877 -0.232957080007
+v 0.800016582012 -7.11767005920 0.195976212621
+v 0.699481368065 -7.10679149628 0.100937187672
+v 0.623298227787 -7.10964918137 0.0832938849926
+v 0.567137062550 -7.11151456833 0.0628604441881
+v 0.495850563049 -7.10760498047 0.0321145318449
+v 0.555952966213 -7.10244846344 -0.0208567157388
+v 0.620401263237 -7.09906911850 -0.0347431302071
+v 0.682408571243 -7.09769439697 -0.0619206875563
+v 0.799920320511 -7.10768318176 -0.123668722808
+v 0.752079010010 -7.53022289276 0.247285693884
+v 0.672736942768 -7.52744722366 0.157990217209
+v 0.615890026093 -7.53124189377 0.135409951210
+v 0.560715019703 -7.53230857849 0.103800922632
+v 0.503940165043 -7.52698373795 0.0392017252743
+v 0.555398523808 -7.52236318588 -0.0376427769661
+v 0.615461528301 -7.51974487305 -0.0703365206718
+v 0.672260284424 -7.51732492447 -0.0898495242000
+v 0.757672548294 -7.51933336258 -0.176645576954
+v 0.751103878021 -7.94635438919 0.258906036615
+v 0.676557064056 -7.95092582703 0.171020314097
+v 0.621752738953 -7.95588874817 0.155941352248
+v 0.563398897648 -7.95386648178 0.125113770366
+v 0.510444939137 -7.94447994232 0.0452048443258
+v 0.577192425728 -7.94440937042 -0.0233145486563
+v 0.630401790142 -7.94500970840 -0.0578806102276
+v 0.681682527065 -7.94239902496 -0.0847569033504
+v 0.776324033737 -7.93898296356 -0.143055051565
+v 0.832109689713 -8.37023735046 0.205787286162
+v 0.731009006500 -8.38037967682 0.113932080567
+v 0.666489064693 -8.38644695282 0.0869745090604
+v 0.614323258400 -8.38338756561 0.0822721570730
+v 0.531626462936 -8.37421035767 0.0509941428900
+v 0.584952354431 -8.37360286713 -0.0295189861208
+v 0.651767313480 -8.37387084961 -0.0331925936043
+v 0.710898697376 -8.37060165405 -0.0423592478037
+v 0.816953003407 -8.36337280273 -0.0833568125963
+v 0.670628070831 -8.80066776276 0.347200036049
+v 0.655393660069 -8.81249523163 0.253943711519
+v 0.619546651840 -8.81860351562 0.235167086124
+v 0.557230472565 -8.81437683105 0.183896303177
+v 0.531640529633 -8.80277633667 0.0596839301288
+v 0.604791462421 -8.80482006073 -0.0198457203805
+v 0.653818368912 -8.80719852448 -0.0627519190311
+v 0.699863016605 -8.80360221863 -0.0912581458688
+v 0.744408011436 -8.79422664642 -0.184704810381
+v 0.877493083477 -9.22906303406 0.220052704215
+v 0.755717635155 -9.25110530853 0.153451576829
+v 0.682484567165 -9.26005458832 0.141810506582
+v 0.638456523418 -9.25435066223 0.125166267157
+v 0.567272543907 -9.24394416809 0.0638173446059
+v 0.622983992100 -9.24240303040 -0.0140440762043
+v 0.683337986469 -9.24288940430 -0.0239355992526
+v 0.738825321198 -9.23887538910 -0.0415688417852
+v 0.823288977146 -9.22869014740 -0.0940358191729
+v 0.893152177334 0.224341705441 -1.34025776386
+v 0.575407624245 0.697064042091 -0.948108494282
+v 0.337044924498 0.745632708073 -0.629241466522
+v 0.140597507358 0.627248585224 -0.348916083574
+v -0.0213888958097 0.377591788769 -0.0352053716779
+v -0.208860605955 0.635162472725 -0.351581811905
+v -0.399993658066 0.758229315281 -0.636798977852
+v -0.621411263943 0.715482532978 -0.950840592384
+v -0.899676024914 0.257521241903 -1.33508372307
+v 0.829961419106 -0.0666490197182 -1.28630971909
+v 0.520223736763 0.370055854321 -0.926218152046
+v 0.281918138266 0.416028052568 -0.637903034687
+v 0.146094605327 0.304290801287 -0.346148699522
+v -0.0217581763864 0.0743406116962 -0.0731019526720
+v -0.195187166333 0.312744766474 -0.357968837023
+v -0.364583700895 0.427057445049 -0.630768597126
+v -0.562739014626 0.388275861740 -0.930698335171
+v -0.844231307507 -0.0350034832954 -1.28270900249
+v 0.767941236496 -0.365398585796 -1.23640727997
+v 0.486467331648 0.0378883257508 -0.889881432056
+v 0.278625130653 0.0793285667896 -0.613934338093
+v 0.133013203740 -0.0229657329619 -0.354106694460
+v -0.0208880081773 -0.233621567488 -0.0718219429255
+v -0.168519690633 -0.0138031365350 -0.372171819210
+v -0.326782912016 0.0914766862988 -0.627948164940
+v -0.530046761036 0.0547426007688 -0.893903076649
+v -0.801718473434 -0.337240546942 -1.22488427162
+v 0.703647434711 -0.668307662010 -1.19505798817
+v 0.455623865128 -0.299033880234 -0.855095922947
+v 0.253515511751 -0.260383635759 -0.606642663479
+v 0.105984561145 -0.353987246752 -0.370027869940
+v -0.0210377257317 -0.547029376030 -0.122017599642
+v -0.192820027471 -0.347642064095 -0.358789622784
+v -0.309968173504 -0.248514205217 -0.613558709621
+v -0.508776187897 -0.282889872789 -0.852122902870
+v -0.681404829025 -0.639858424664 -1.22579002380
+v 0.723397552967 -0.979578554630 -1.08336043358
+v 0.388843476772 -0.639635503292 -0.854664444923
+v 0.214778244495 -0.604736268520 -0.609979271889
+v 0.0994642972946 -0.690936744213 -0.375886499882
+v -0.0199016761035 -0.865121424198 -0.129926323891
+v -0.163376361132 -0.683255732059 -0.375591367483
+v -0.264184981585 -0.593758523464 -0.618578433990
+v -0.437422603369 -0.624104738235 -0.850169003010
+v -0.743428349495 -0.952610015869 -1.10134196281
+v 0.558082580566 -1.29451036453 -1.14935696125
+v 0.385840326548 -0.984061539173 -0.803838789463
+v 0.240961790085 -0.953997015953 -0.572969913483
+v 0.0902751982212 -1.03141844273 -0.384302437305
+v -0.0196616556495 -1.18897473812 -0.181970611215
+v -0.163896501064 -1.02434051037 -0.376675993204
+v -0.279256999493 -0.941672027111 -0.589265048504
+v -0.434271037579 -0.968460440636 -0.802135825157
+v -0.521754562855 -1.26515340805 -1.18059539795
+v 0.648066163063 -1.61376023293 -0.982017159462
+v 0.311532557011 -1.33434975147 -0.815111160278
+v 0.167641833425 -1.30607593060 -0.602604985237
+v 0.102121345699 -1.37828421593 -0.383985459805
+v -0.0175641290843 -1.51930284500 -0.174552753568
+v -0.125040918589 -1.36971330643 -0.398811519146
+v -0.219935446978 -1.29584300518 -0.604309797287
+v -0.353922784328 -1.31988227367 -0.808437943459
+v -0.693742454052 -1.59146261215 -0.989567160606
+v 0.426895529032 -1.94184899330 -1.09752428532
+v 0.355295181274 -1.68858504295 -0.735990524292
+v 0.194633886218 -1.66261196136 -0.572998523712
+v 0.0846601948142 -1.72750020027 -0.396710544825
+v -0.0159944184124 -1.85519933701 -0.198387265205
+v -0.146523982286 -1.71984875202 -0.390675663948
+v -0.275031000376 -1.65355741978 -0.552833259106
+v -0.406848400831 -1.67484593391 -0.731123924255
+v -0.424655050039 -1.91630566120 -1.11361610889
+v 0.575902998447 -2.27331733704 -0.897060275078
+v 0.243386611342 -2.04673838615 -0.782896995544
+v 0.143859013915 -2.02465367317 -0.588324487209
+v 0.0726032555103 -2.08318138123 -0.409091174603
+v -0.0138233406469 -2.19600677490 -0.203580096364
+v -0.104037627578 -2.07490324974 -0.416239708662
+v -0.159499973059 -2.01427340508 -0.605966389179
+v -0.258006781340 -2.03379774094 -0.795602679253
+v -0.598306596279 -2.25248265266 -0.929091930389
+v 0.355173617601 -2.61212730408 -1.02091801167
+v 0.315055847168 -2.41012716293 -0.691302299500
+v 0.189484134316 -2.39015221596 -0.550404489040
+v 0.0997400805354 -2.44239664078 -0.402052581310
+v -0.0118754506111 -2.54131340981 -0.235792264342
+v -0.125530585647 -2.43367910385 -0.408936768770
+v -0.239608049393 -2.38036751747 -0.545897543430
+v -0.360030740499 -2.39732050896 -0.687551498413
+v -0.368869662285 -2.59154176712 -1.03466939926
+v 0.488743335009 -2.95548081398 -0.846544682980
+v 0.189518272877 -2.77681112289 -0.755732953548
+v 0.0926153212786 -2.75940513611 -0.597752094269
+v 0.0482544079423 -2.80647850037 -0.433349281549
+v -0.00985814630985 -2.89224982262 -0.265654921532
+v -0.0578178130090 -2.79733729362 -0.443652123213
+v -0.129338905215 -2.75015139580 -0.596182405949
+v -0.191518887877 -2.76438736916 -0.770700275898
+v -0.497027933598 -2.93660664558 -0.887509822845
+v 0.299595952034 -3.30406403542 -0.946059823036
+v 0.284448772669 -3.14956021309 -0.654048681259
+v 0.169885128736 -3.13409805298 -0.546500205994
+v 0.0813064277172 -3.17468976974 -0.427139729261
+v -0.00703886896372 -3.24846053123 -0.279885679483
+v -0.120458640158 -3.16653656960 -0.421037793159
+v -0.205691277981 -3.12447357178 -0.543384611607
+v -0.305220454931 -3.13711929321 -0.662065386772
+v -0.313315212727 -3.28623652458 -0.961672723293
+v 0.392880648375 -3.65978288651 -0.824878811836
+v 0.164370387793 -3.52419734001 -0.720916748047
+v 0.0936472266912 -3.51199221611 -0.584228932858
+v 0.0587842278183 -3.54856371880 -0.447246521711
+v -0.00434591807425 -3.61128830910 -0.305796325207
+v -0.0827044025064 -3.54036998749 -0.447707295418
+v -0.127543836832 -3.50375485420 -0.577942550182
+v -0.170976653695 -3.51277923584 -0.722279846668
+v -0.398682326078 -3.64329743385 -0.858376622200
+v 0.256438136101 -4.02129554749 -0.889223635197
+v 0.214575886726 -3.90569090843 -0.660967767239
+v 0.138854667544 -3.89511179924 -0.557058632374
+v 0.0728520452976 -3.92562890053 -0.450272202492
+v -0.00139186007436 -3.97645616531 -0.336228489876
+v -0.0927411392331 -3.91713571548 -0.447169810534
+v -0.163999393582 -3.88549137115 -0.551218926907
+v -0.238620653749 -3.89420914650 -0.655723989010
+v -0.275876134634 -4.00617265701 -0.903346359730
+v 0.374437123537 -4.38999366760 -0.756510019302
+v 0.153471186757 -4.28882503510 -0.692001044750
+v 0.0899336636066 -4.28100442886 -0.581350505352
+v 0.0611067563295 -4.30863380432 -0.466313004494
+v 0.00217316951603 -4.35163688660 -0.347106665373
+v -0.0769754499197 -4.30032634735 -0.462751030922
+v -0.117462076247 -4.27289772034 -0.571618199348
+v -0.159557461739 -4.27872610092 -0.684398889542
+v -0.320316612720 -4.37176561356 -0.830688059330
+v 0.216867893934 -4.76176738739 -0.855635941029
+v 0.175537377596 -4.67957067490 -0.658083558083
+v 0.134782999754 -4.67260122299 -0.559168756008
+v 0.0930508002639 -4.69464635849 -0.461838752031
+v 0.00577403698117 -4.72722530365 -0.371480941772
+v -0.0659414678812 -4.68610763550 -0.475073277950
+v -0.123220115900 -4.66351270676 -0.565557956696
+v -0.158197134733 -4.66871595383 -0.667771875858
+v -0.205356255174 -4.74656343460 -0.870559811592
+v 0.330772310495 -5.13968086243 -0.732425212860
+v 0.174935460091 -5.07255935669 -0.647610127926
+v 0.122337289155 -5.06823968887 -0.568663716316
+v 0.0868874788284 -5.08737993240 -0.477074265480
+v 0.00971187371761 -5.11299991608 -0.391878604889
+v -0.0563411116600 -5.07775878906 -0.488390177488
+v -0.0893457457423 -5.05760526657 -0.580751717091
+v -0.153705701232 -5.06211566925 -0.657141625881
+v -0.307378113270 -5.12678909302 -0.774797260761
+v 0.194403439760 -5.52482271194 -0.834412276745
+v 0.119324184954 -5.47155380249 -0.680178105831
+v 0.0871750786901 -5.46836519241 -0.589602649212
+v 0.0581752173603 -5.48234176636 -0.505468189716
+v 0.0138326054439 -5.49935340881 -0.411020219326
+v -0.0360760465264 -5.47324562073 -0.507342219353
+v -0.0721828043461 -5.45860481262 -0.589117705822
+v -0.109923087060 -5.46100807190 -0.670629262924
+v -0.152556136250 -5.51079559326 -0.847322583199
+v 0.325382828712 -5.91367340088 -0.693698585033
+v 0.199512571096 -5.87330055237 -0.616905689240
+v 0.146758139133 -5.87189912796 -0.568831801414
+v 0.0954631865025 -5.88364458084 -0.501248478889
+v 0.0184853617102 -5.89652872086 -0.419492125511
+v -0.0489783696830 -5.87426280975 -0.511017143726
+v -0.0937713608146 -5.86168956757 -0.581425786018
+v -0.133789762855 -5.86258268356 -0.653666257858
+v -0.248104378581 -5.90093517303 -0.764474451542
+v 0.160580754280 -6.30964469910 -0.832903385162
+v 0.0927494391799 -6.28076982498 -0.694649696350
+v 0.0527101643384 -6.28093099594 -0.614447772503
+v 0.0506022535264 -6.28805494308 -0.539588630199
+v 0.0228255614638 -6.29294729233 -0.452063024044
+v -0.0145920049399 -6.27845573425 -0.538334906101
+v -0.0352961272001 -6.27035808563 -0.608190417290
+v -0.0619169585407 -6.27043676376 -0.683578848839
+v -0.120903439820 -6.29780244827 -0.826601564884
+v 0.304186791182 -6.70962333679 -0.691076815128
+v 0.205385908484 -6.69062232971 -0.618173480034
+v 0.180894404650 -6.69233179092 -0.572435438633
+v 0.136896923184 -6.69874858856 -0.498956292868
+v 0.0277483072132 -6.70190191269 -0.424269795418
+v -0.0777273178101 -6.69003725052 -0.505485832691
+v -0.101751819253 -6.68257379532 -0.587288558483
+v -0.126952782273 -6.68154096603 -0.647568285465
+v -0.232957109809 -6.69943904877 -0.740615129471
+v 0.195976182818 -7.11767005920 -0.800016582012
+v 0.100937157869 -7.10679149628 -0.699481368065
+v 0.0832938551903 -7.10964918137 -0.623298227787
+v 0.0628604218364 -7.11151456833 -0.567137062550
+v 0.0321145094931 -7.10760498047 -0.495850563049
+v -0.0208567399532 -7.10244846344 -0.555952966213
+v -0.0347431562841 -7.09906911850 -0.620401263237
+v -0.0619207173586 -7.09769439697 -0.682408571243
+v -0.123668760061 -7.10768318176 -0.799920320511
+v 0.247285664082 -7.53022289276 -0.752079010010
+v 0.157990187407 -7.52744722366 -0.672736942768
+v 0.135409921408 -7.53124189377 -0.615890026093
+v 0.103800900280 -7.53230857849 -0.560715019703
+v 0.0392017029226 -7.52698373795 -0.503940165043
+v -0.0376428030431 -7.52236318588 -0.555398523808
+v -0.0703365504742 -7.51974487305 -0.615461528301
+v -0.0898495540023 -7.51732492447 -0.672260284424
+v -0.176645606756 -7.51933336258 -0.757672548294
+v 0.258906006813 -7.94635438919 -0.751103878021
+v 0.171020284295 -7.95092582703 -0.676557064056
+v 0.155941322446 -7.95588874817 -0.621752738953
+v 0.125113740563 -7.95386648178 -0.563398897648
+v 0.0452048219740 -7.94447994232 -0.510444939137
+v -0.0233145747334 -7.94440937042 -0.577192425728
+v -0.0578806363046 -7.94500970840 -0.630401790142
+v -0.0847569331527 -7.94239902496 -0.681682527065
+v -0.143055081367 -7.93898296356 -0.776324033737
+v 0.205787256360 -8.37023735046 -0.832109689713
+v 0.113932050765 -8.38037967682 -0.731009006500
+v 0.0869744792581 -8.38644695282 -0.666489064693
+v 0.0822721272707 -8.38338756561 -0.614323258400
+v 0.0509941205382 -8.37421035767 -0.531626462936
+v -0.0295190121979 -8.37360286713 -0.584952354431
+v -0.0331926234066 -8.37387084961 -0.651767313480
+v -0.0423592776060 -8.37060165405 -0.710898697376
+v -0.0833568498492 -8.36337280273 -0.816953003407
+v 0.347200006247 -8.80066776276 -0.670628070831
+v 0.253943681717 -8.81249523163 -0.655393660069
+v 0.235167056322 -8.81860351562 -0.619546651840
+v 0.183896273375 -8.81437683105 -0.557230472565
+v 0.0596839077771 -8.80277633667 -0.531640529633
+v -0.0198457464576 -8.80482006073 -0.604791462421
+v -0.0627519488335 -8.80719852448 -0.653818368912
+v -0.0912581756711 -8.80360221863 -0.699863016605
+v -0.184704840183 -8.79422664642 -0.744408011436
+v 0.220052659512 -9.22906303406 -0.877493083477
+v 0.153451547027 -9.25110530853 -0.755717635155
+v 0.141810476780 -9.26005458832 -0.682484567165
+v 0.125166237354 -9.25435066223 -0.638456523418
+v 0.0638173222542 -9.24394416809 -0.567272543907
+v -0.0140441032127 -9.24240303040 -0.622983992100
+v -0.0239356290549 -9.24288940430 -0.683337986469
+v -0.0415688753128 -9.23887538910 -0.738825321198
+v -0.0940358564258 -9.22869014740 -0.823288977146
+v -1.34025788307 0.224341705441 -0.893152117729
+v -0.948108553886 0.697064042091 -0.575407624245
+v -0.629241466522 0.745632708073 -0.337044894695
+v -0.348916083574 0.627248585224 -0.140597492456
+v -0.0352053679526 0.377591788769 0.0213888976723
+v -0.351581782103 0.635162472725 0.208860620856
+v -0.636798918247 0.758229315281 0.399993687868
+v -0.950840532780 0.715482532978 0.621411263943
+v -1.33508360386 0.257521241903 0.899676084518
+v -1.28630983829 -0.0666490197182 -0.829961359501
+v -0.926218211651 0.370055854321 -0.520223736763
+v -0.637903034687 0.416028052568 -0.281918108463
+v -0.346148699522 0.304290801287 -0.146094590425
+v -0.0731019526720 0.0743406116962 0.0217581782490
+v -0.357968807220 0.312744766474 0.195187181234
+v -0.630768537521 0.427057445049 0.364583730698
+v -0.930698275566 0.388275861740 0.562739014626
+v -1.28270888329 -0.0350034832954 0.844231367111
+v -1.23640739918 -0.365398585796 -0.767941176891
+v -0.889881491661 0.0378883257508 -0.486467272043
+v -0.613934338093 0.0793285667896 -0.278625100851
+v -0.354106694460 -0.0229657329619 -0.133013188839
+v -0.0718219429255 -0.233621567488 0.0208880100399
+v -0.372171819210 -0.0138031365350 0.168519705534
+v -0.627948164940 0.0914766862988 0.326782941818
+v -0.893903017044 0.0547426007688 0.530046761036
+v -1.22488415241 -0.337240546942 0.801718533039
+v -1.19505810738 -0.668307662010 -0.703647375107
+v -0.855095982552 -0.299033880234 -0.455623805523
+v -0.606642663479 -0.260383635759 -0.253515481949
+v -0.370027869940 -0.353987246752 -0.105984546244
+v -0.122017599642 -0.547029376030 0.0210377313197
+v -0.358789592981 -0.347642064095 0.192820042372
+v -0.613558709621 -0.248514205217 0.309968203306
+v -0.852122843266 -0.282889872789 0.508776187897
+v -1.22579002380 -0.639858424664 0.681404888630
+v -1.08336055279 -0.979578554630 -0.723397493362
+v -0.854664504528 -0.639635503292 -0.388843417168
+v -0.609979271889 -0.604736268520 -0.214778214693
+v -0.375886499882 -0.690936744213 -0.0994642823935
+v -0.129926323891 -0.865121424198 0.0199016816914
+v -0.375591367483 -0.683255732059 0.163376376033
+v -0.618578433990 -0.593758523464 0.264185011387
+v -0.850168943405 -0.624104738235 0.437422633171
+v -1.10134184361 -0.952610015869 0.743428409100
+v -1.14935696125 -1.29451036453 -0.558082520962
+v -0.803838849068 -0.984061539173 -0.385840296745
+v -0.572969913483 -0.953997015953 -0.240961775184
+v -0.384302437305 -1.03141844273 -0.0902751758695
+v -0.181970611215 -1.18897473812 0.0196616649628
+v -0.376675993204 -1.02434051037 0.163896515965
+v -0.589265048504 -0.941672027111 0.279257029295
+v -0.802135765553 -0.968460440636 0.434271067381
+v -1.18059539795 -1.26515340805 0.521754622459
+v -0.982017219067 -1.61376023293 -0.648066163063
+v -0.815111160278 -1.33434975147 -0.311532527208
+v -0.602604985237 -1.30607593060 -0.167641803622
+v -0.383985459805 -1.37828421593 -0.102121323347
+v -0.174552753568 -1.51930284500 0.0175641365349
+v -0.398811519146 -1.36971330643 0.125040933490
+v -0.604309797287 -1.29584300518 0.219935476780
+v -0.808437883854 -1.31988227367 0.353922814131
+v -0.989567160606 -1.59146261215 0.693742454052
+v -1.09752428532 -1.94184899330 -0.426895499229
+v -0.735990583897 -1.68858504295 -0.355295151472
+v -0.572998523712 -1.66261196136 -0.194633871317
+v -0.396710544825 -1.72750020027 -0.0846601724625
+v -0.198387265205 -1.85519933701 0.0159944258630
+v -0.390675663948 -1.71984875202 0.146523997188
+v -0.552833259106 -1.65355741978 0.275031030178
+v -0.731123864651 -1.67484593391 0.406848430634
+v -1.11361610889 -1.91630566120 0.424655079842
+v -0.897060334682 -2.27331733704 -0.575902998447
+v -0.782896995544 -2.04673838615 -0.243386566639
+v -0.588324487209 -2.02465367317 -0.143858999014
+v -0.409091174603 -2.08318138123 -0.0726032331586
+v -0.203580096364 -2.19600677490 0.0138233490288
+v -0.416239708662 -2.07490324974 0.104037649930
+v -0.605966389179 -2.01427340508 0.159500002861
+v -0.795602679253 -2.03379774094 0.258006811142
+v -0.929091870785 -2.25248265266 0.598306596279
+v -1.02091801167 -2.61212730408 -0.355173557997
+v -0.691302299500 -2.41012716293 -0.315055817366
+v -0.550404489040 -2.39015221596 -0.189484119415
+v -0.402052581310 -2.44239664078 -0.0997400581837
+v -0.235792264342 -2.54131340981 0.0118754608557
+v -0.408936768770 -2.43367910385 0.125530600548
+v -0.545897543430 -2.38036751747 0.239608064294
+v -0.687551438808 -2.39732050896 0.360030770302
+v -1.03466939926 -2.59154176712 0.368869692087
+v -0.846544742584 -2.95548081398 -0.488743305206
+v -0.755732953548 -2.77681112289 -0.189518243074
+v -0.597752094269 -2.75940513611 -0.0926152989268
+v -0.433349281549 -2.80647850037 -0.0482543893158
+v -0.265654921532 -2.89224982262 0.00985815841705
+v -0.443652123213 -2.79733729362 0.0578178316355
+v -0.596182405949 -2.75015139580 0.129338920116
+v -0.770700275898 -2.76438736916 0.191518932581
+v -0.887509763241 -2.93660664558 0.497027993202
+v -0.946059823036 -3.30406403542 -0.299595892429
+v -0.654048681259 -3.14956021309 -0.284448742867
+v -0.546500205994 -3.13409805298 -0.169885113835
+v -0.427139729261 -3.17468976974 -0.0813064128160
+v -0.279885679483 -3.24846053123 0.00703888153657
+v -0.421037793159 -3.16653656960 0.120458662510
+v -0.543384611607 -3.12447357178 0.205691292882
+v -0.662065386772 -3.13711929321 0.305220484734
+v -0.961672723293 -3.28623652458 0.313315272331
+v -0.824878871441 -3.65978288651 -0.392880618572
+v -0.720916748047 -3.52419734001 -0.164370357990
+v -0.584228932858 -3.51199221611 -0.0936471968889
+v -0.447246521711 -3.54856371880 -0.0587842091918
+v -0.305796325207 -3.61128830910 0.00434593111277
+v -0.447707295418 -3.54036998749 0.0827044174075
+v -0.577942550182 -3.50375485420 0.127543851733
+v -0.722279846668 -3.51277923584 0.170976683497
+v -0.858376562595 -3.64329743385 0.398682385683
+v -0.889223635197 -4.02129554749 -0.256438076496
+v -0.660967767239 -3.90569090843 -0.214575856924
+v -0.557058632374 -3.89511179924 -0.138854652643
+v -0.450272202492 -3.92562890053 -0.0728520303965
+v -0.336228489876 -3.97645616531 0.00139187474269
+v -0.447169810534 -3.91713571548 0.0927411541343
+v -0.551218926907 -3.88549137115 0.163999408484
+v -0.655723989010 -3.89420914650 0.238620683551
+v -0.903346359730 -4.00617265701 0.275876194239
+v -0.756510078907 -4.38999366760 -0.374437093735
+v -0.692001044750 -4.28882503510 -0.153471156955
+v -0.581350505352 -4.28100442886 -0.0899336338043
+v -0.466313004494 -4.30863380432 -0.0611067339778
+v -0.347106665373 -4.35163688660 -0.00217315438204
+v -0.462751030922 -4.30032634735 0.0769754648209
+v -0.571618199348 -4.27289772034 0.117462106049
+v -0.684398889542 -4.27872610092 0.159557491541
+v -0.830688059330 -4.37176561356 0.320316642523
+v -0.855635941029 -4.76176738739 -0.216867864132
+v -0.658083558083 -4.67957067490 -0.175537347794
+v -0.559168756008 -4.67260122299 -0.134782984853
+v -0.461838752031 -4.69464635849 -0.0930507853627
+v -0.371480941772 -4.72722530365 -0.00577402068302
+v -0.475073277950 -4.68610763550 0.0659414902329
+v -0.565557956696 -4.66351270676 0.123220145702
+v -0.667771875858 -4.66871595383 0.158197164536
+v -0.870559811592 -4.74656343460 0.205356284976
+v -0.732425212860 -5.13968086243 -0.330772280693
+v -0.647610127926 -5.07255935669 -0.174935430288
+v -0.568663716316 -5.06823968887 -0.122337259352
+v -0.477074265480 -5.08737993240 -0.0868874564767
+v -0.391878604889 -5.11299991608 -0.00971185602248
+v -0.488390177488 -5.07775878906 0.0563411302865
+v -0.580751717091 -5.05760526657 0.0893457755446
+v -0.657141625881 -5.06211566925 0.153705731034
+v -0.774797260761 -5.12678909302 0.307378143072
+v -0.834412276745 -5.52482271194 -0.194403395057
+v -0.680178105831 -5.47155380249 -0.119324155152
+v -0.589602649212 -5.46836519241 -0.0871750488877
+v -0.505468189716 -5.48234176636 -0.0581751950085
+v -0.411020219326 -5.49935340881 -0.0138325868174
+v -0.507342219353 -5.47324562073 0.0360760688782
+v -0.589117705822 -5.45860481262 0.0721828341484
+v -0.670629262924 -5.46100807190 0.109923116863
+v -0.847322583199 -5.51079559326 0.152556180954
+v -0.693698585033 -5.91367340088 -0.325382798910
+v -0.616905689240 -5.87330055237 -0.199512541294
+v -0.568831801414 -5.87189912796 -0.146758124232
+v -0.501248478889 -5.88364458084 -0.0954631641507
+v -0.419492125511 -5.89652872086 -0.0184853430837
+v -0.511017143726 -5.87426280975 0.0489783920348
+v -0.581425786018 -5.86168956757 0.0937713906169
+v -0.653666257858 -5.86258268356 0.133789792657
+v -0.764474451542 -5.90093517303 0.248104408383
+v -0.832903385162 -6.30964469910 -0.160580709577
+v -0.694649696350 -6.28076982498 -0.0927494093776
+v -0.614447772503 -6.28093099594 -0.0527101382613
+v -0.539588630199 -6.28805494308 -0.0506022274494
+v -0.452063024044 -6.29294729233 -0.0228255428374
+v -0.538334906101 -6.27845573425 0.0145920291543
+v -0.608190417290 -6.27035808563 0.0352961532772
+v -0.683578848839 -6.27043676376 0.0619169883430
+v -0.826601564884 -6.29780244827 0.120903477073
+v -0.691076815128 -6.70962333679 -0.304186761379
+v -0.618173480034 -6.69062232971 -0.205385878682
+v -0.572435438633 -6.69233179092 -0.180894389749
+v -0.498956292868 -6.69874858856 -0.136896893382
+v -0.424269795418 -6.70190191269 -0.0277482885867
+v -0.505485832691 -6.69003725052 0.0777273401618
+v -0.587288558483 -6.68257379532 0.101751849055
+v -0.647568285465 -6.68154096603 0.126952812076
+v -0.740615129471 -6.69943904877 0.232957139611
+v -0.800016582012 -7.11767005920 -0.195976138115
+v -0.699481368065 -7.10679149628 -0.100937128067
+v -0.623298227787 -7.10964918137 -0.0832938328385
+v -0.567137062550 -7.11151456833 -0.0628603920341
+v -0.495850563049 -7.10760498047 -0.0321144871414
+v -0.555952966213 -7.10244846344 0.0208567641675
+v -0.620401263237 -7.09906911850 0.0347431860864
+v -0.682408571243 -7.09769439697 0.0619207471609
+v -0.799920320511 -7.10768318176 0.123668789864
+v -0.752079010010 -7.53022289276 -0.247285634279
+v -0.672736942768 -7.52744722366 -0.157990157604
+v -0.615890026093 -7.53124189377 -0.135409891605
+v -0.560715019703 -7.53230857849 -0.103800870478
+v -0.503940165043 -7.52698373795 -0.0392016805708
+v -0.555398523808 -7.52236318588 0.0376428253949
+v -0.615461528301 -7.51974487305 0.0703365728259
+v -0.672260284424 -7.51732492447 0.0898495838046
+v -0.757672548294 -7.51933336258 0.176645636559
+v -0.751103878021 -7.94635438919 -0.258905977011
+v -0.676557064056 -7.95092582703 -0.171020254493
+v -0.621752738953 -7.95588874817 -0.155941292644
+v -0.563398897648 -7.95386648178 -0.125113725662
+v -0.510444939137 -7.94447994232 -0.0452047996223
+v -0.577192425728 -7.94440937042 0.0233145989478
+v -0.630401790142 -7.94500970840 0.0578806661069
+v -0.681682527065 -7.94239902496 0.0847569629550
+v -0.776324033737 -7.93898296356 0.143055126071
+v -0.832109689713 -8.37023735046 -0.205787211657
+v -0.731009006500 -8.38037967682 -0.113932013512
+v -0.666489064693 -8.38644695282 -0.0869744494557
+v -0.614323258400 -8.38338756561 -0.0822721049190
+v -0.531626462936 -8.37421035767 -0.0509940981865
+v -0.584952354431 -8.37360286713 0.0295190364122
+v -0.651767313480 -8.37387084961 0.0331926494837
+v -0.710898697376 -8.37060165405 0.0423593111336
+v -0.816953003407 -8.36337280273 0.0833568871021
+v -0.670628130436 -8.80066776276 -0.347199976444
+v -0.655393660069 -8.81249523163 -0.253943651915
+v -0.619546651840 -8.81860351562 -0.235167026520
+v -0.557230472565 -8.81437683105 -0.183896258473
+v -0.531640529633 -8.80277633667 -0.0596838854253
+v -0.604791462421 -8.80482006073 0.0198457725346
+v -0.653818368912 -8.80719852448 0.0627519786358
+v -0.699863016605 -8.80360221863 0.0912582054734
+v -0.744408011436 -8.79422664642 0.184704869986
+v -0.877493083477 -9.22906303406 -0.220052629709
+v -0.755717635155 -9.25110530853 -0.153451517224
+v -0.682484567165 -9.26005458832 -0.141810446978
+v -0.638456523418 -9.25435066223 -0.125166207552
+v -0.567272543907 -9.24394416809 -0.0638172924519
+v -0.622983992100 -9.24240303040 0.0140441302210
+v -0.683337986469 -9.24288940430 0.0239356588572
+v -0.738825321198 -9.23887538910 0.0415689051151
+v -0.823288977146 -9.22869014740 0.0940358936787
+v -0.893152236938 0.224341705441 1.34025776386
+v -0.575407683849 0.697064042091 0.948108494282
+v -0.337044954300 0.745632708073 0.629241466522
+v -0.140597522259 0.627248585224 0.348916083574
+v 0.0213888939470 0.377591788769 0.0352053716779
+v 0.208860591054 0.635162472725 0.351581811905
+v 0.399993628263 0.758229315281 0.636798977852
+v 0.621411204338 0.715482532978 0.950840592384
+v 0.899675965309 0.257521241903 1.33508372307
+v -0.829961478710 -0.0666490197182 1.28630971909
+v -0.520223796368 0.370055854321 0.926218152046
+v -0.281918168068 0.416028052568 0.637903034687
+v -0.146094620228 0.304290801287 0.346148699522
+v 0.0217581726611 0.0743406116962 0.0731019526720
+v 0.195187151432 0.312744766474 0.357968837023
+v 0.364583671093 0.427057445049 0.630768597126
+v 0.562738955021 0.388275861740 0.930698335171
+v 0.844231247902 -0.0350034832954 1.28270900249
+v -0.767941296101 -0.365398585796 1.23640727997
+v -0.486467361450 0.0378883257508 0.889881432056
+v -0.278625160456 0.0793285667896 0.613934338093
+v -0.133013218641 -0.0229657329619 0.354106694460
+v 0.0208880044520 -0.233621567488 0.0718219429255
+v 0.168519675732 -0.0138031365350 0.372171819210
+v 0.326782882214 0.0914766862988 0.627948164940
+v 0.530046701431 0.0547426007688 0.893903076649
+v 0.801718413830 -0.337240546942 1.22488427162
+v -0.703647494316 -0.668307662010 1.19505798817
+v -0.455623894930 -0.299033880234 0.855095922947
+v -0.253515541553 -0.260383635759 0.606642663479
+v -0.105984568596 -0.353987246752 0.370027869940
+v 0.0210377220064 -0.547029376030 0.122017599642
+v 0.192820012569 -0.347642064095 0.358789622784
+v 0.309968143702 -0.248514205217 0.613558709621
+v 0.508776128292 -0.282889872789 0.852122902870
+v 0.681404769421 -0.639858424664 1.22579002380
+v -0.723397612572 -0.979578554630 1.08336043358
+v -0.388843506575 -0.639635503292 0.854664444923
+v -0.214778274298 -0.604736268520 0.609979271889
+v -0.0994643047452 -0.690936744213 0.375886499882
+v 0.0199016723782 -0.865121424198 0.129926323891
+v 0.163376346231 -0.683255732059 0.375591367483
+v 0.264184951782 -0.593758523464 0.618578433990
+v 0.437422573566 -0.624104738235 0.850169003010
+v 0.743428289890 -0.952610015869 1.10134196281
+v -0.558082640171 -1.29451036453 1.14935696125
+v -0.385840356350 -0.984061539173 0.803838789463
+v -0.240961819887 -0.953997015953 0.572969913483
+v -0.0902752056718 -1.03141844273 0.384302437305
+v 0.0196616500616 -1.18897473812 0.181970611215
+v 0.163896486163 -1.02434051037 0.376675993204
+v 0.279256969690 -0.941672027111 0.589265048504
+v 0.434271007776 -0.968460440636 0.802135825157
+v 0.521754503250 -1.26515340805 1.18059539795
+v -0.648066222668 -1.61376023293 0.982017159462
+v -0.311532586813 -1.33434975147 0.815111160278
+v -0.167641863227 -1.30607593060 0.602604985237
+v -0.102121353149 -1.37828421593 0.383985459805
+v 0.0175641234964 -1.51930284500 0.174552753568
+v 0.125040903687 -1.36971330643 0.398811519146
+v 0.219935417175 -1.29584300518 0.604309797287
+v 0.353922754526 -1.31988227367 0.808437943459
+v 0.693742394447 -1.59146261215 0.989567220211
+v -0.426895588636 -1.94184899330 1.09752428532
+v -0.355295211077 -1.68858504295 0.735990524292
+v -0.194633916020 -1.66261196136 0.572998523712
+v -0.0846602022648 -1.72750020027 0.396710544825
+v 0.0159944109619 -1.85519933701 0.198387265205
+v 0.146523967385 -1.71984875202 0.390675663948
+v 0.275030970573 -1.65355741978 0.552833259106
+v 0.406848371029 -1.67484593391 0.731123924255
+v 0.424654990435 -1.91630566120 1.11361610889
+v -0.575903058052 -2.27331733704 0.897060275078
+v -0.243386626244 -2.04673838615 0.782896995544
+v -0.143859043717 -2.02465367317 0.588324487209
+v -0.0726032629609 -2.08318138123 0.409091174603
+v 0.0138233341277 -2.19600677490 0.203580096364
+v 0.104037620127 -2.07490324974 0.416239708662
+v 0.159499943256 -2.01427340508 0.605966389179
+v 0.258006751537 -2.03379774094 0.795602679253
+v 0.598306536674 -2.25248265266 0.929091930389
+v -0.355173647404 -2.61212730408 1.02091801167
+v -0.315055876970 -2.41012716293 0.691302299500
+v -0.189484164119 -2.39015221596 0.550404489040
+v -0.0997400879860 -2.44239664078 0.402052581310
+v 0.0118754431605 -2.54131340981 0.235792264342
+v 0.125530570745 -2.43367910385 0.408936768770
+v 0.239608019590 -2.38036751747 0.545897543430
+v 0.360030710697 -2.39732050896 0.687551498413
+v 0.368869602680 -2.59154176712 1.03466939926
+v -0.488743364811 -2.95548081398 0.846544682980
+v -0.189518287778 -2.77681112289 0.755732953548
+v -0.0926153436303 -2.75940513611 0.597752094269
+v -0.0482544228435 -2.80647850037 0.433349281549
+v 0.00985813792795 -2.89224982262 0.265654921532
+v 0.0578177981079 -2.79733729362 0.443652123213
+v 0.129338875413 -2.75015139580 0.596182405949
+v 0.191518872976 -2.76438736916 0.770700275898
+v 0.497027903795 -2.93660664558 0.887509822845
+v -0.299595981836 -3.30406403542 0.946059823036
+v -0.284448802471 -3.14956021309 0.654048681259
+v -0.169885158539 -3.13409805298 0.546500205994
+v -0.0813064426184 -3.17468976974 0.427139729261
+v 0.00703886011615 -3.24846053123 0.279885679483
+v 0.120458632708 -3.16653656960 0.421037793159
+v 0.205691248178 -3.12447357178 0.543384611607
+v 0.305220425129 -3.13711929321 0.662065386772
+v 0.313315182924 -3.28623652458 0.961672723293
+v -0.392880678177 -3.65978288651 0.824878811836
+v -0.164370402694 -3.52419734001 0.720916748047
+v -0.0936472415924 -3.51199221611 0.584228932858
+v -0.0587842427194 -3.54856371880 0.447246521711
+v 0.00434590829536 -3.61128830910 0.305796325207
+v 0.0827043876052 -3.54036998749 0.447707295418
+v 0.127543807030 -3.50375485420 0.577942550182
+v 0.170976638794 -3.51277923584 0.722279846668
+v 0.398682296276 -3.64329743385 0.858376622200
+v -0.256438165903 -4.02129554749 0.889223635197
+v -0.214575901628 -3.90569090843 0.660967767239
+v -0.138854697347 -3.89511179924 0.557058632374
+v -0.0728520601988 -3.92562890053 0.450272202492
+v 0.00139184936415 -3.97645616531 0.336228489876
+v 0.0927411243320 -3.91713571548 0.447169810534
+v 0.163999363780 -3.88549137115 0.551218926907
+v 0.238620638847 -3.89420914650 0.655723989010
+v 0.275876104832 -4.00617265701 0.903346359730
+v -0.374437153339 -4.38999366760 0.756510019302
+v -0.153471201658 -4.28882503510 0.692001044750
+v -0.0899336785078 -4.28100442886 0.581350505352
+v -0.0611067712307 -4.30863380432 0.466313004494
+v -0.00217318045907 -4.35163688660 0.347106665373
+v 0.0769754350185 -4.30032634735 0.462751030922
+v 0.117462061346 -4.27289772034 0.571618199348
+v 0.159557446837 -4.27872610092 0.684398889542
+v 0.320316582918 -4.37176561356 0.830688059330
+v -0.216867923737 -4.76176738739 0.855635941029
+v -0.175537392497 -4.67957067490 0.658083558083
+v -0.134783029556 -4.67260122299 0.559168756008
+v -0.0930508151650 -4.69464635849 0.461838752031
+v -0.00577404862270 -4.72722530365 0.371480941772
+v 0.0659414529800 -4.68610763550 0.475073277950
+v 0.123220100999 -4.66351270676 0.565557956696
+v 0.158197119832 -4.66871595383 0.667771875858
+v 0.205356225371 -4.74656343460 0.870559811592
+v -0.330772340298 -5.13968086243 0.732425212860
+v -0.174935474992 -5.07255935669 0.647610127926
+v -0.122337304056 -5.06823968887 0.568663716316
+v -0.0868874937296 -5.08737993240 0.477074265480
+v -0.00971188582480 -5.11299991608 0.391878604889
+v 0.0563410967588 -5.07775878906 0.488390177488
+v 0.0893457308412 -5.05760526657 0.580751717091
+v 0.153705686331 -5.06211566925 0.657141625881
+v 0.307378083467 -5.12678909302 0.774797260761
+v -0.194403454661 -5.52482271194 0.834412276745
+v -0.119324207306 -5.47155380249 0.680178105831
+v -0.0871750935912 -5.46836519241 0.589602649212
+v -0.0581752322614 -5.48234176636 0.505468189716
+v -0.0138326184824 -5.49935340881 0.411020219326
+v 0.0360760316253 -5.47324562073 0.507342219353
+v 0.0721827894449 -5.45860481262 0.589117705822
+v 0.109923064709 -5.46100807190 0.670629262924
+v 0.152556121349 -5.51079559326 0.847322583199
+v -0.325382858515 -5.91367340088 0.693698585033
+v -0.199512600899 -5.87330055237 0.616905689240
+v -0.146758168936 -5.87189912796 0.568831801414
+v -0.0954632014036 -5.88364458084 0.501248478889
+v -0.0184853747487 -5.89652872086 0.419492125511
+v 0.0489783547819 -5.87426280975 0.511017143726
+v 0.0937713459134 -5.86168956757 0.581425786018
+v 0.133789747953 -5.86258268356 0.653666257858
+v 0.248104363680 -5.90093517303 0.764474451542
+v -0.160580769181 -6.30964469910 0.832903385162
+v -0.0927494615316 -6.28076982498 0.694649696350
+v -0.0527101829648 -6.28093099594 0.614447772503
+v -0.0506022684276 -6.28805494308 0.539588630199
+v -0.0228255763650 -6.29294729233 0.452063024044
+v 0.0145919881761 -6.27845573425 0.538334906101
+v 0.0352961085737 -6.27035808563 0.608190417290
+v 0.0619169361889 -6.27043676376 0.683578848839
+v 0.120903410017 -6.29780244827 0.826601564884
+v -0.304186820984 -6.70962333679 0.691076815128
+v -0.205385938287 -6.69062232971 0.618173480034
+v -0.180894434452 -6.69233179092 0.572435438633
+v -0.136896938086 -6.69874858856 0.498956292868
+v -0.0277483202517 -6.70190191269 0.424269795418
+v 0.0777273029089 -6.69003725052 0.505485832691
+v 0.101751804352 -6.68257379532 0.587288558483
+v 0.126952767372 -6.68154096603 0.647568285465
+v 0.232957094908 -6.69943904877 0.740615129471
+v -0.195976197720 -7.11767005920 0.800016582012
+v -0.100937180221 -7.10679149628 0.699481368065
+v -0.0832938775420 -7.10964918137 0.623298227787
+v -0.0628604367375 -7.11151456833 0.567137062550
+v -0.0321145243943 -7.10760498047 0.495850563049
+v 0.0208567231894 -7.10244846344 0.555952966213
+v 0.0347431376576 -7.09906911850 0.620401263237
+v 0.0619206950068 -7.09769439697 0.682408571243
+v 0.123668730259 -7.10768318176 0.799920320511
+v -0.247285678983 -7.53022289276 0.752079010010
+v -0.157990202308 -7.52744722366 0.672736942768
+v -0.135409951210 -7.53124189377 0.615890026093
+v -0.103800915182 -7.53230857849 0.560715019703
+v -0.0392017178237 -7.52698373795 0.503940165043
+v 0.0376427844167 -7.52236318588 0.555398523808
+v 0.0703365281224 -7.51974487305 0.615461528301
+v 0.0898495316505 -7.51732492447 0.672260284424
+v 0.176645591855 -7.51933336258 0.757672548294
+v -0.258906036615 -7.94635438919 0.751103878021
+v -0.171020299196 -7.95092582703 0.676557064056
+v -0.155941352248 -7.95588874817 0.621752738953
+v -0.125113770366 -7.95386648178 0.563398897648
+v -0.0452048368752 -7.94447994232 0.510444939137
+v 0.0233145561069 -7.94440937042 0.577192425728
+v 0.0578806176782 -7.94500970840 0.630401790142
+v 0.0847569108009 -7.94239902496 0.681682527065
+v 0.143055066466 -7.93898296356 0.776324033737
+v -0.205787271261 -8.37023735046 0.832109689713
+v -0.113932073116 -8.38037967682 0.731009006500
+v -0.0869745016098 -8.38644695282 0.666489064693
+v -0.0822721496224 -8.38338756561 0.614323258400
+v -0.0509941354394 -8.37421035767 0.531626462936
+v 0.0295189935714 -8.37360286713 0.584952354431
+v 0.0331926010549 -8.37387084961 0.651767313480
+v 0.0423592552543 -8.37060165405 0.710898697376
+v 0.0833568200469 -8.36337280273 0.816953003407
+v -0.347200036049 -8.80066776276 0.670628070831
+v -0.253943711519 -8.81249523163 0.655393660069
+v -0.235167086124 -8.81860351562 0.619546651840
+v -0.183896303177 -8.81437683105 0.557230472565
+v -0.0596839226782 -8.80277633667 0.531640529633
+v 0.0198457278311 -8.80482006073 0.604791462421
+v 0.0627519264817 -8.80719852448 0.653818368912
+v 0.0912581533194 -8.80360221863 0.699863016605
+v 0.184704825282 -8.79422664642 0.744408011436
+v -0.220052689314 -9.22906303406 0.877493083477
+v -0.153451561928 -9.25110530853 0.755717635155
+v -0.141810491681 -9.26005458832 0.682484567165
+v -0.125166252255 -9.25435066223 0.638456523418
+v -0.0638173371553 -9.24394416809 0.567272543907
+v 0.0140440836549 -9.24240303040 0.622983992100
+v 0.0239356067032 -9.24288940430 0.683337986469
+v 0.0415688492358 -9.23887538910 0.738825321198
+v 0.0940358266234 -9.22869014740 0.823288977146
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn 0.00469512119889 0.999988913536 1.20128106573e-06
+vn 0.0129901114851 0.999912261963 -0.00258243945427
+vn 0.00433792127296 0.999988973141 -0.00179674709216
+vn 0.0110137667507 0.999912321568 -0.00735510000959
+vn 0.00332030188292 0.999988973141 -0.00331958360039
+vn 0.00736043090001 0.999912321568 -0.0110112801194
+vn 0.00179719913285 0.999988913536 -0.00433781649917
+vn 0.00258585973643 0.999912321568 -0.0129896244034
+vn 2.68018851557e-07 0.999988913536 -0.00469511654228
+vn 0.0705852955580 0.997505664825 9.83200516202e-06
+vn 0.0692314058542 0.997505724430 -0.0137586798519
+vn 0.0652194842696 0.997505724430 -0.0269947294146
+vn 0.0586986206472 0.997505724430 -0.0392020680010
+vn 0.0499245524406 0.997505724430 -0.0498978123069
+vn 0.0392286740243 0.997505724430 -0.0586798749864
+vn 0.0270291119814 0.997505664825 -0.0652052089572
+vn 0.0137824630365 0.997505724430 -0.0692265778780
+vn 9.47547414398e-06 0.997505724430 -0.0705850943923
+vn 0.163596361876 0.986527383327 2.84709221887e-05
+vn 0.160460308194 0.986527442932 -0.0318760238588
+vn 0.151164829731 0.986527442932 -0.0625534281135
+vn 0.136055633426 0.986527323723 -0.0908440276980
+vn 0.115719832480 0.986527442932 -0.115639790893
+vn 0.0909345522523 0.986527442932 -0.135994687676
+vn 0.0626575127244 0.986527442932 -0.151121675968
+vn 0.0319561585784 0.986527323723 -0.160445287824
+vn 2.83781100734e-05 0.986527442932 -0.163595870137
+vn 0.267129421234 0.963660657406 4.26232436439e-05
+vn 0.262010961771 0.963660657406 -0.0520416162908
+vn 0.246828302741 0.963660717010 -0.102146767080
+vn 0.222164839506 0.963660657406 -0.148327201605
+vn 0.188949823380 0.963660717010 -0.188828051090
+vn 0.148491099477 0.963660717010 -0.222055003047
+vn 0.102305449545 0.963660717010 -0.246762156487
+vn 0.0521872490644 0.963660657406 -0.261982381344
+vn 4.26321057603e-05 0.963660776615 -0.267129242420
+vn 0.375958323479 0.926636636257 4.38095412392e-05
+vn 0.368752717972 0.926633954048 -0.0732871741056
+vn 0.347374558449 0.926636636257 -0.143790006638
+vn 0.312642753124 0.926636695862 -0.208803921938
+vn 0.265906155109 0.926636755466 -0.265778720379
+vn 0.208938255906 0.926636755466 -0.312552660704
+vn 0.143955990672 0.926636815071 -0.347305357456
+vn 0.0734044164419 0.926639318466 -0.368715852499
+vn 4.35723559349e-05 0.926636695862 -0.375957906246
+vn 0.489842385054 0.871811032295 2.06175536732e-05
+vn 0.480436116457 0.871810913086 -0.0955347865820
+vn 0.452572435141 0.871810972691 -0.187413439155
+vn 0.407310634851 0.871811032295 -0.272109657526
+vn 0.346402436495 0.871811091900 -0.346339195967
+vn 0.272173881531 0.871810972691 -0.407267659903
+vn 0.187495619059 0.871810972691 -0.452538490295
+vn 0.0955921187997 0.871810913086 -0.480424553156
+vn 2.06142831303e-05 0.871811032295 -0.489842325449
+vn 0.599311947823 0.800515651703 2.06826689464e-06
+vn 0.587800264359 0.800514101982 -0.116910852492
+vn 0.553693771362 0.800515949726 -0.229340821505
+vn 0.498316437006 0.800515830517 -0.332949042320
+vn 0.423781633377 0.800515890121 -0.423772901297
+vn 0.332970231771 0.800515770912 -0.498302370310
+vn 0.229352191091 0.800515770912 -0.553689539433
+vn 0.116928942502 0.800517559052 -0.587791800499
+vn 2.28145177061e-06 0.800515949726 -0.599311470985
+vn 0.704573988914 0.709630548954 3.34162081117e-07
+vn 0.691035926342 0.709630429745 -0.137455284595
+vn 0.650941908360 0.709630608559 -0.269627481699
+vn 0.585831701756 0.709630668163 -0.391440242529
+vn 0.498210221529 0.709630429745 -0.498208016157
+vn 0.391440749168 0.709630548954 -0.585831642151
+vn 0.269630044699 0.709630489349 -0.650941073895
+vn 0.137455791235 0.709630429745 -0.691035866737
+vn 4.48357525329e-07 0.709630429745 -0.704574048519
+vn 0.789522409439 0.613721609116 -2.35765170942e-07
+vn 0.774352073669 0.613721668720 -0.154028043151
+vn 0.729423761368 0.613721609116 -0.302137225866
+vn 0.656463921070 0.613721728325 -0.438635170460
+vn 0.558276891708 0.613721609116 -0.558276474476
+vn 0.438635259867 0.613721728325 -0.656463801861
+vn 0.302137017250 0.613721787930 -0.729423701763
+vn 0.154028221965 0.613721668720 -0.774352014065
+vn -4.47205422915e-07 0.613721728325 -0.789522469044
+vn 0.847586512566 0.530657291412 -1.95527547930e-07
+vn 0.831300377846 0.530657231808 -0.165355846286
+vn 0.783067643642 0.530657529831 -0.324357211590
+vn 0.704742431641 0.530657470226 -0.470893621445
+vn 0.599334239960 0.530657410622 -0.599334001541
+vn 0.470893710852 0.530657410622 -0.704742372036
+vn 0.324357122183 0.530657410622 -0.783067822456
+vn 0.165356308222 0.530657410622 -0.831300139427
+vn -1.43137398823e-07 0.530657410622 -0.847586393356
+vn 0.909194111824 0.416372656822 -3.17161919838e-07
+vn 0.891724407673 0.416372239590 -0.177374944091
+vn 0.839986026287 0.416372090578 -0.347933501005
+vn 0.755967438221 0.416371971369 -0.505121231079
+vn 0.642897188663 0.416372537613 -0.642897307873
+vn 0.505121231079 0.416372269392 -0.755967259407
+vn 0.347933590412 0.416372269392 -0.839985847473
+vn 0.177374809980 0.416372448206 -0.891724228859
+vn 9.75882699095e-08 0.416372328997 -0.909194171429
+vn 0.984744310379 0.174007967114 -2.63912113496e-07
+vn 0.965822696686 0.174007967114 -0.192114114761
+vn 0.909785151482 0.174007654190 -0.376845359802
+vn 0.818785071373 0.174007892609 -0.547094464302
+vn 0.696319341660 0.174008205533 -0.696319162846
+vn 0.547094404697 0.174007937312 -0.818785071373
+vn 0.376845210791 0.174008056521 -0.909785032272
+vn 0.192113921046 0.174007982016 -0.965822756290
+vn -1.46195901607e-07 0.174008026719 -0.984744191170
+vn 0.964679777622 -0.263425767422 -2.21300837211e-07
+vn 0.946143448353 -0.263426452875 -0.188199654222
+vn 0.891247630119 -0.263426333666 -0.369166851044
+vn 0.802101731300 -0.263426393270 -0.535947203636
+vn 0.682131588459 -0.263426631689 -0.682131111622
+vn 0.535947024822 -0.263426542282 -0.802101731300
+vn 0.369166731834 -0.263426184654 -0.891247749329
+vn 0.188199818134 -0.263426303864 -0.946143507957
+vn -6.40607851210e-08 -0.263426452875 -0.964679479599
+vn 0.658063352108 -0.752962589264 -1.79140599244e-07
+vn 0.645418703556 -0.752962648869 -0.128381952643
+vn 0.607970952988 -0.752962827682 -0.251829832792
+vn 0.547159314156 -0.752962946892 -0.365600228310
+vn 0.465320646763 -0.752963006496 -0.465320795774
+vn 0.365600168705 -0.752962887287 -0.547159314156
+vn 0.251829892397 -0.752962768078 -0.607970952988
+vn 0.128381669521 -0.752962589264 -0.645418763161
+vn -1.90919692500e-07 -0.752962827682 -0.658063173294
+vn 0.959696769714 0.281037539244 -3.12156714699e-07
+vn 0.781838178635 -0.603774249554 -0.155517429113
+vn 0.886644303799 0.281037271023 -0.367260068655
+vn 0.662810444832 -0.603774249554 -0.442875832319
+vn 0.678608000278 0.281037837267 -0.678608059883
+vn 0.442875862122 -0.603774130344 -0.662810504436
+vn 0.367259830236 0.281037539244 -0.886644303799
+vn 0.155517235398 -0.603774487972 -0.781838119030
+vn -3.02087130422e-07 0.281037569046 -0.959696710110
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -0.674308478832 0.738449811935 1.71211596012e-07
+vn -0.630463600159 0.766021370888 0.125407069921
+vn -0.622979700565 0.738449692726 0.258047223091
+vn -0.534481406212 0.766021311283 0.357128888369
+vn -0.476808279753 0.738450169563 0.476807236671
+vn -0.357129007578 0.766021728516 0.534480631351
+vn -0.258046776056 0.738449752331 0.622979819775
+vn -0.125407159328 0.766021370888 0.630463540554
+vn 3.89459330563e-07 0.738449931145 0.674308240414
+vn -0.448026418686 0.894020259380 1.56292117026e-07
+vn -0.439417719841 0.894020378590 0.0874051451683
+vn -0.413922399282 0.894020318985 0.171452537179
+vn -0.372520327568 0.894020199776 0.248910367489
+vn -0.316802561283 0.894020378590 0.316802173853
+vn -0.248910352588 0.894020318985 0.372520208359
+vn -0.171452358365 0.894020259380 0.413922399282
+vn -0.0874055996537 0.894020378590 0.439417541027
+vn 2.06267870340e-07 0.894020378590 0.448026299477
+vn -0.191464751959 0.981499433517 1.64115135703e-07
+vn -0.187785819173 0.981499433517 0.0373527444899
+vn -0.176890373230 0.981499493122 0.0732701644301
+vn -0.159197092056 0.981499433517 0.106372117996
+vn -0.135385885835 0.981499552727 0.135385930538
+vn -0.106372088194 0.981499552727 0.159197151661
+vn -0.0732703953981 0.981499493122 0.176890537143
+vn -0.0373529195786 0.981499433517 0.187785789371
+vn -1.18951220429e-07 0.981499493122 0.191464945674
+vn 0.0206096880138 0.999787628651 -1.46140290980e-08
+vn 0.0202136803418 0.999787628651 -0.00402074959129
+vn 0.0190408397466 0.999787628651 -0.00788707099855
+vn 0.0171362310648 0.999787688255 -0.0114503921941
+vn 0.0145732341334 0.999787628651 -0.0145732220262
+vn 0.0114501547068 0.999787628651 -0.0171361975372
+vn 0.00788700953126 0.999787628651 -0.0190407652408
+vn 0.00402073981240 0.999787628651 -0.0202139317989
+vn -9.16591886835e-08 0.999787628651 -0.0206097252667
+vn 0.205292254686 0.978700757027 -1.29128778781e-07
+vn 0.201347634196 0.978700697422 -0.0400504805148
+vn 0.189665317535 0.978700697422 -0.0785620585084
+vn 0.170694276690 0.978700697422 -0.114054329693
+vn 0.145163610578 0.978700637817 -0.145163536072
+vn 0.114054255188 0.978700697422 -0.170694261789
+vn 0.0785619467497 0.978700697422 -0.189665257931
+vn 0.0400505438447 0.978700757027 -0.201347544789
+vn -2.35800413861e-07 0.978700816631 -0.205292120576
+vn 0.404177725315 0.914680480957 -1.01804673136e-07
+vn 0.396411538124 0.914680421352 -0.0788509994745
+vn 0.373411566019 0.914680480957 -0.154672116041
+vn 0.336061537266 0.914680421352 -0.224549114704
+vn 0.285796761513 0.914680421352 -0.285796731710
+vn 0.224549070001 0.914680600166 -0.336061179638
+vn 0.154672041535 0.914680480957 -0.373411417007
+vn 0.0788513198495 0.914680540562 -0.396411240101
+vn -1.23854533740e-07 0.914680480957 -0.404177516699
+vn 0.634387969971 0.773014843464 -3.49527539356e-07
+vn 0.622198283672 0.773014843464 -0.123762801290
+vn 0.586097836494 0.773015081882 -0.242769479752
+vn 0.527474343777 0.773014724255 -0.352447092533
+vn 0.448580086231 0.773014724255 -0.448580056429
+vn 0.352447032928 0.773014903069 -0.527474105358
+vn 0.242769777775 0.773014843464 -0.586097896099
+vn 0.123763039708 0.773014903069 -0.622198164463
+vn -1.49257701310e-07 0.773014843464 -0.634387850761
+vn 0.885345280170 0.464934170246 -2.25391076469e-07
+vn 0.868333816528 0.464933931828 -0.172722160816
+vn 0.817952454090 0.464933931828 -0.338806957006
+vn 0.736137807369 0.464933633804 -0.491871744394
+vn 0.626033842564 0.464933663607 -0.626033723354
+vn 0.491871684790 0.464934021235 -0.736137688160
+vn 0.338806986809 0.464933902025 -0.817952513695
+vn 0.172722294927 0.464934021235 -0.868333756924
+vn -1.12695538235e-07 0.464933931828 -0.885345399380
+vn 0.999712347984 0.0239820554852 -1.45581026345e-07
+vn 0.980503201485 0.0239825043827 -0.195034116507
+vn 0.923613667488 0.0239821262658 -0.382573544979
+vn 0.831230461597 0.0239823088050 -0.555410504341
+vn 0.706903457642 0.0239825714380 -0.706903398037
+vn 0.555410444736 0.0239824242890 -0.831230401993
+vn 0.382573217154 0.0239823255688 -0.923613846302
+vn 0.195034280419 0.0239824429154 -0.980503201485
+vn 1.72398557652e-08 0.0239824317396 -0.999712407589
+vn 0.999967277050 -0.00808802247047 -3.03573642668e-07
+vn 0.980753123760 -0.00808786693960 -0.195083990693
+vn 0.923849284649 -0.00808799732476 -0.382670938969
+vn 0.831442594528 -0.00808746181428 -0.555551886559
+vn 0.707083821297 -0.00808801501989 -0.707083523273
+vn 0.555552005768 -0.00808793026954 -0.831442475319
+vn 0.382670938969 -0.00808787159622 -0.923849284649
+vn 0.195084348321 -0.00808774679899 -0.980753064156
+vn -2.45523523290e-07 -0.00808791536838 -0.999967277050
+vn 0.882003307343 0.471243262291 -4.63951948859e-07
+vn 0.865055918694 0.471243023872 -0.172070324421
+vn 0.814864933491 0.471242904663 -0.337528049946
+vn 0.733358979225 0.471243202686 -0.490014821291
+vn 0.623670578003 0.471243053675 -0.623670637608
+vn 0.490014642477 0.471243262291 -0.733358979225
+vn 0.337527871132 0.471243202686 -0.814864873886
+vn 0.172070324421 0.471243262291 -0.865055859089
+vn -4.30531628126e-07 0.471243202686 -0.882003247738
+vn 0.959696769714 0.281037539244 -3.12156714699e-07
+vn 0.781838178635 -0.603774249554 -0.155517429113
+vn 0.886644303799 0.281037271023 -0.367260068655
+vn 0.662810444832 -0.603774249554 -0.442875832319
+vn 0.678608000278 0.281037837267 -0.678608059883
+vn 0.442875862122 -0.603774130344 -0.662810504436
+vn 0.367259830236 0.281037539244 -0.886644303799
+vn 0.155517235398 -0.603774487972 -0.781838119030
+vn -3.02087130422e-07 0.281037569046 -0.959696710110
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn 2.68018851557e-07 0.999988913536 -0.00469511654228
+vn -0.00258183083497 0.999912321568 -0.0129901329055
+vn -0.00179628364276 0.999988973141 -0.00433783652261
+vn -0.00735587952659 0.999912321568 -0.0110140237957
+vn -0.00331960362382 0.999988973141 -0.00332047161646
+vn -0.0110107315704 0.999912321568 -0.00736090075225
+vn -0.00433753570542 0.999988973141 -0.00179739668965
+vn -0.0129895620048 0.999912321568 -0.00258522923104
+vn -0.00469512399286 0.999988913536 -1.20209631405e-06
+vn 9.47547414398e-06 0.997505724430 -0.0705850943923
+vn -0.0137586351484 0.997505664825 -0.0692314505577
+vn -0.0269945301116 0.997505664825 -0.0652196705341
+vn -0.0392015017569 0.997505724430 -0.0586993321776
+vn -0.0498981140554 0.997505664825 -0.0499243550003
+vn -0.0586804933846 0.997505784035 -0.0392279699445
+vn -0.0652051344514 0.997505724430 -0.0270292796195
+vn -0.0692266300321 0.997505724430 -0.0137826707214
+vn -0.0705852955580 0.997505724430 -9.83340487437e-06
+vn 2.83781100734e-05 0.986527442932 -0.163595870137
+vn -0.0318761840463 0.986527502537 -0.160460174084
+vn -0.0625536441803 0.986527442932 -0.151164501905
+vn -0.0908439457417 0.986527323723 -0.136055842042
+vn -0.115640319884 0.986527323723 -0.115719877183
+vn -0.135995075107 0.986527383327 -0.0909341126680
+vn -0.151121750474 0.986527442932 -0.0626571029425
+vn -0.160445272923 0.986527323723 -0.0319565050304
+vn -0.163596123457 0.986527442932 -2.84769848804e-05
+vn 4.26321057603e-05 0.963660776615 -0.267129242420
+vn -0.0520419403911 0.963660776615 -0.262010782957
+vn -0.102146603167 0.963660657406 -0.246828407049
+vn -0.148327007890 0.963660776615 -0.222164466977
+vn -0.188828185201 0.963660776615 -0.188949570060
+vn -0.222055003047 0.963660776615 -0.148491069674
+vn -0.246762320399 0.963660776615 -0.102305307984
+vn -0.261981844902 0.963660776615 -0.0521869547665
+vn -0.267129153013 0.963660776615 -4.26495971624e-05
+vn 4.35723559349e-05 0.926636695862 -0.375957906246
+vn -0.0732876881957 0.926634073257 -0.368752300739
+vn -0.143790140748 0.926636517048 -0.347374916077
+vn -0.208803996444 0.926636695862 -0.312642633915
+vn -0.265778899193 0.926636636257 -0.265906035900
+vn -0.312552750111 0.926636755466 -0.208938226104
+vn -0.347305357456 0.926636815071 -0.143956035376
+vn -0.368715852499 0.926639318466 -0.0734041333199
+vn -0.375958114862 0.926636695862 -4.38627685071e-05
+vn 2.06142831303e-05 0.871811032295 -0.489842325449
+vn -0.0955350324512 0.871810793877 -0.480436176062
+vn -0.187413513660 0.871810972691 -0.452572494745
+vn -0.272109746933 0.871810853481 -0.407310873270
+vn -0.346339344978 0.871810972691 -0.346402406693
+vn -0.407267689705 0.871811091900 -0.272173702717
+vn -0.452538251877 0.871811032295 -0.187495693564
+vn -0.480424612761 0.871810853481 -0.0955922156572
+vn -0.489842504263 0.871810972691 -2.06960394280e-05
+vn 2.28145177061e-06 0.800515949726 -0.599311470985
+vn -0.116911172867 0.800513982773 -0.587800383568
+vn -0.229340806603 0.800516009331 -0.553694009781
+vn -0.332949131727 0.800515830517 -0.498316556215
+vn -0.423773258924 0.800515472889 -0.423781961203
+vn -0.498302578926 0.800515651703 -0.332970291376
+vn -0.553689599037 0.800515651703 -0.229352310300
+vn -0.587791860104 0.800517559052 -0.116928882897
+vn -0.599311292171 0.800516009331 -2.07761672755e-06
+vn 4.48357525329e-07 0.709630429745 -0.704574048519
+vn -0.137455835938 0.709630548954 -0.691035807133
+vn -0.269627571106 0.709630608559 -0.650941967964
+vn -0.391440421343 0.709630608559 -0.585831761360
+vn -0.498208224773 0.709630310535 -0.498210191727
+vn -0.585831642151 0.709630727768 -0.391440421343
+vn -0.650941073895 0.709630429745 -0.269630074501
+vn -0.691036045551 0.709630310535 -0.137455791235
+vn -0.704574048519 0.709630429745 -3.67859115613e-07
+vn -4.47205422915e-07 0.613721728325 -0.789522469044
+vn -0.154028385878 0.613721668720 -0.774351894855
+vn -0.302137225866 0.613721609116 -0.729423582554
+vn -0.438635349274 0.613721668720 -0.656463861465
+vn -0.558276712894 0.613721609116 -0.558276772499
+vn -0.656463801861 0.613721787930 -0.438635081053
+vn -0.729423820972 0.613721489906 -0.302137255669
+vn -0.774351894855 0.613721728325 -0.154028221965
+vn -0.789522230625 0.613721966743 3.19967000451e-07
+vn -1.43137398823e-07 0.530657410622 -0.847586393356
+vn -0.165356025100 0.530657410622 -0.831300258636
+vn -0.324357479811 0.530657351017 -0.783067762852
+vn -0.470893681049 0.530657589436 -0.704742252827
+vn -0.599334001541 0.530657470226 -0.599334120750
+vn -0.704742431641 0.530657291412 -0.470893919468
+vn -0.783067882061 0.530657291412 -0.324357211590
+vn -0.831300139427 0.530657649040 -0.165355890989
+vn -0.847586274147 0.530657529831 1.35653081657e-07
+vn 9.75882699095e-08 0.416372328997 -0.909194171429
+vn -0.177375122905 0.416372209787 -0.891724228859
+vn -0.347933650017 0.416372239590 -0.839985847473
+vn -0.505121231079 0.416372328997 -0.755967319012
+vn -0.642897307873 0.416372805834 -0.642897129059
+vn -0.755967319012 0.416372299194 -0.505121231079
+vn -0.839986026287 0.416372001171 -0.347933471203
+vn -0.891724228859 0.416372388601 -0.177375078201
+vn -0.909193992615 0.416372627020 2.34587176351e-07
+vn -1.46195901607e-07 0.174008026719 -0.984744191170
+vn -0.192114427686 0.174007862806 -0.965822577477
+vn -0.376845151186 0.174008041620 -0.909785032272
+vn -0.547094345093 0.174007833004 -0.818785190582
+vn -0.696319401264 0.174008250237 -0.696319103241
+vn -0.818785011768 0.174007758498 -0.547094464302
+vn -0.909784972668 0.174008190632 -0.376845270395
+vn -0.965822577477 0.174008294940 -0.192114114761
+vn -0.984744250774 0.174008145928 2.31635098658e-07
+vn -6.40607851210e-08 -0.263426452875 -0.964679479599
+vn -0.188199669123 -0.263426512480 -0.946143388748
+vn -0.369166851044 -0.263426512480 -0.891247630119
+vn -0.535947322845 -0.263426452875 -0.802101552486
+vn -0.682131409645 -0.263426572084 -0.682131350040
+vn -0.802101790905 -0.263426601887 -0.535947024822
+vn -0.891247749329 -0.263426184654 -0.369166761637
+vn -0.946143627167 -0.263426005840 -0.188199669123
+vn -0.964679539204 -0.263426065445 2.19359648668e-07
+vn -1.90919692500e-07 -0.752962827682 -0.658063173294
+vn -0.128382056952 -0.752962768078 -0.645418584347
+vn -0.251829713583 -0.752962887287 -0.607971012592
+vn -0.365600407124 -0.752962648869 -0.547159612179
+vn -0.465320855379 -0.752962887287 -0.465320676565
+vn -0.547159194946 -0.752963185310 -0.365600019693
+vn -0.607970893383 -0.752962946892 -0.251829773188
+vn -0.645419061184 -0.752962410450 -0.128381744027
+vn -0.658063292503 -0.752962529659 1.65398290619e-07
+vn -3.02087130422e-07 0.281037569046 -0.959696710110
+vn -0.155517607927 -0.603774130344 -0.781838178635
+vn -0.367259860039 0.281037420034 -0.886644244194
+vn -0.442875832319 -0.603774189949 -0.662810444832
+vn -0.678608357906 0.281037628651 -0.678607881069
+vn -0.662810623646 -0.603774011135 -0.442875742912
+vn -0.886644244194 0.281037390232 -0.367260158062
+vn -0.781837940216 -0.603774487972 -0.155517220497
+vn -0.959696769714 0.281037181616 3.14170620186e-07
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn 3.89459330563e-07 0.738449931145 0.674308240414
+vn 0.125407546759 0.766021490097 0.630463302135
+vn 0.258046686649 0.738449931145 0.622979640961
+vn 0.357128679752 0.766021251678 0.534481465816
+vn 0.476808130741 0.738449633121 0.476808309555
+vn 0.534481167793 0.766021370888 0.357128888369
+vn 0.622979700565 0.738449990749 0.258046567440
+vn 0.630463361740 0.766021490097 0.125406876206
+vn 0.674308359623 0.738449871540 -1.58041473242e-07
+vn 2.06267870340e-07 0.894020378590 0.448026299477
+vn 0.0874058082700 0.894020259380 0.439417719841
+vn 0.171452209353 0.894020378590 0.413922488689
+vn 0.248909920454 0.894020259380 0.372520595789
+vn 0.316802531481 0.894020140171 0.316802829504
+vn 0.372520238161 0.894020318985 0.248910412192
+vn 0.413922458887 0.894020378590 0.171452164650
+vn 0.439417779446 0.894020259380 0.0874051526189
+vn 0.448026359081 0.894020318985 -3.79297148356e-07
+vn -1.18951220429e-07 0.981499493122 0.191464945674
+vn 0.0373529121280 0.981499552727 0.187785774469
+vn 0.0732703506947 0.981499433517 0.176890417933
+vn 0.106372065842 0.981499433517 0.159197255969
+vn 0.135386183858 0.981499493122 0.135385721922
+vn 0.159197181463 0.981499433517 0.106372252107
+vn 0.176890373230 0.981499433517 0.0732705071568
+vn 0.187785834074 0.981499493122 0.0373526252806
+vn 0.191464707255 0.981499493122 2.92099162635e-08
+vn -9.16591886835e-08 0.999787628651 -0.0206097252667
+vn -0.00402075564489 0.999787688255 -0.0202137790620
+vn -0.00788694899529 0.999787628651 -0.0190407950431
+vn -0.0114500978962 0.999787628651 -0.0171362236142
+vn -0.0145731791854 0.999787628651 -0.0145732853562
+vn -0.0171363204718 0.999787628651 -0.0114503968507
+vn -0.0190408844501 0.999787628651 -0.00788705796003
+vn -0.0202136654407 0.999787688255 -0.00402074679732
+vn -0.0206096880138 0.999787628651 1.33279929315e-08
+vn -2.35800413861e-07 0.978700816631 -0.205292120576
+vn -0.0400506816804 0.978700816631 -0.201347440481
+vn -0.0785617381334 0.978700757027 -0.189665079117
+vn -0.114054150879 0.978700816631 -0.170694217086
+vn -0.145163387060 0.978700757027 -0.145163252950
+vn -0.170694246888 0.978700757027 -0.114054270089
+vn -0.189665123820 0.978700697422 -0.0785619765520
+vn -0.201347559690 0.978700816631 -0.0400505661964
+vn -0.205292090774 0.978700816631 3.59314867637e-07
+vn -1.23854533740e-07 0.914680480957 -0.404177516699
+vn -0.0788513943553 0.914680361748 -0.396411597729
+vn -0.154671981931 0.914680540562 -0.373411357403
+vn -0.224549144506 0.914680540562 -0.336061269045
+vn -0.285796850920 0.914680540562 -0.285796701908
+vn -0.336061447859 0.914680480957 -0.224548891187
+vn -0.373411357403 0.914680480957 -0.154672116041
+vn -0.396411448717 0.914680421352 -0.0788513943553
+vn -0.404177606106 0.914680540562 1.92819001654e-07
+vn -1.49257701310e-07 0.773014843464 -0.634387850761
+vn -0.123763032258 0.773014783859 -0.622198343277
+vn -0.242769390345 0.773014783859 -0.586098134518
+vn -0.352447211742 0.773014783859 -0.527474224567
+vn -0.448580235243 0.773014605045 -0.448580235243
+vn -0.527474224567 0.773014843464 -0.352447032928
+vn -0.586097717285 0.773014962673 -0.242769762874
+vn -0.622198104858 0.773014962673 -0.123762987554
+vn -0.634387850761 0.773014903069 1.68151089497e-07
+vn -1.12695538235e-07 0.464933931828 -0.885345399380
+vn -0.172722816467 0.464933842421 -0.868333637714
+vn -0.338807106018 0.464933723211 -0.817952513695
+vn -0.491871982813 0.464933693409 -0.736137628555
+vn -0.626033782959 0.464933693409 -0.626033723354
+vn -0.736137688160 0.464933961630 -0.491871625185
+vn -0.817952513695 0.464933902025 -0.338806867599
+vn -0.868333756924 0.464933842421 -0.172722354531
+vn -0.885345399380 0.464933931828 2.08053307915e-07
+vn 1.72398557652e-08 0.0239824317396 -0.999712407589
+vn -0.195034563541 0.0239822957665 -0.980503141880
+vn -0.382573395967 0.0239822193980 -0.923613727093
+vn -0.555410504341 0.0239824503660 -0.831230342388
+vn -0.706903576851 0.0239827502519 -0.706903278828
+vn -0.831230461597 0.0239825174212 -0.555410444736
+vn -0.923613727093 0.0239822268486 -0.382573395967
+vn -0.980503141880 0.0239825509489 -0.195034310222
+vn -0.999712347984 0.0239825863391 1.18763438195e-07
+vn -2.45523523290e-07 -0.00808791536838 -0.999967277050
+vn -0.195084616542 -0.00808811653405 -0.980753064156
+vn -0.382671028376 -0.00808798335493 -0.923849284649
+vn -0.555551886559 -0.00808764062822 -0.831442594528
+vn -0.707083702087 -0.00808779709041 -0.707083523273
+vn -0.831442475319 -0.00808802805841 -0.555551886559
+vn -0.923849344254 -0.00808792840689 -0.382670909166
+vn -0.980753183365 -0.00808801781386 -0.195084095001
+vn -0.999967277050 -0.00808763224632 2.72169472737e-07
+vn -4.30531628126e-07 0.471243202686 -0.882003247738
+vn -0.172070577741 0.471243292093 -0.865055799484
+vn -0.337527811527 0.471243143082 -0.814864933491
+vn -0.490014821291 0.471243172884 -0.733358860016
+vn -0.623670816422 0.471243023872 -0.623670458794
+vn -0.733359038830 0.471243053675 -0.490014761686
+vn -0.814864873886 0.471243232489 -0.337528079748
+vn -0.865055859089 0.471243292093 -0.172070354223
+vn -0.882003307343 0.471243292093 4.04974912271e-07
+vn -3.02087130422e-07 0.281037569046 -0.959696710110
+vn -0.155517607927 -0.603774130344 -0.781838178635
+vn -0.367259860039 0.281037420034 -0.886644244194
+vn -0.442875832319 -0.603774189949 -0.662810444832
+vn -0.678608357906 0.281037628651 -0.678607881069
+vn -0.662810623646 -0.603774011135 -0.442875742912
+vn -0.886644244194 0.281037390232 -0.367260158062
+vn -0.781837940216 -0.603774487972 -0.155517220497
+vn -0.959696769714 0.281037181616 3.14170620186e-07
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -0.00469512399286 0.999988913536 -1.20209631405e-06
+vn -0.0129901124164 0.999912321568 0.00258229183964
+vn -0.00433792360127 0.999988913536 0.00179577118251
+vn -0.0110137602314 0.999912321568 0.00735537521541
+vn -0.00332029536366 0.999988973141 0.00332016358152
+vn -0.00736043648794 0.999912321568 0.0110101830214
+vn -0.00179721030872 0.999988913536 0.00433667702600
+vn -0.00258586253040 0.999912321568 0.0129894306883
+vn -2.68135295300e-07 0.999988913536 0.00469539500773
+vn -0.0705852955580 0.997505724430 -9.83340487437e-06
+vn -0.0692313984036 0.997505724430 0.0137581806630
+vn -0.0652194544673 0.997505724430 0.0269945077598
+vn -0.0586986057460 0.997505664825 0.0392017886043
+vn -0.0499245636165 0.997505664825 0.0498981773853
+vn -0.0392286628485 0.997505724430 0.0586804412305
+vn -0.0270291008055 0.997505724430 0.0652047172189
+vn -0.0137824211270 0.997505724430 0.0692271366715
+vn -9.47663829720e-06 0.997505724430 0.0705851465464
+vn -0.163596123457 0.986527442932 -2.84769848804e-05
+vn -0.160460203886 0.986527502537 0.0318762399256
+vn -0.151164814830 0.986527383327 0.0625538155437
+vn -0.136055618525 0.986527383327 0.0908439382911
+vn -0.115719847381 0.986527442932 0.115640021861
+vn -0.0909345448017 0.986527323723 0.135995030403
+vn -0.0626575425267 0.986527442932 0.151121497154
+vn -0.0319561585784 0.986527264118 0.160445094109
+vn -2.83809076791e-05 0.986527562141 0.163595527411
+vn -0.267129153013 0.963660776615 -4.26495971624e-05
+vn -0.262010991573 0.963660657406 0.0520419627428
+vn -0.246828302741 0.963660657406 0.102146804333
+vn -0.222164943814 0.963660717010 0.148326978087
+vn -0.188949853182 0.963660776615 0.188827991486
+vn -0.148491159081 0.963660776615 0.222054958344
+vn -0.102305367589 0.963660776615 0.246762186289
+vn -0.0521871522069 0.963660776615 0.261981964111
+vn -4.26377046097e-05 0.963660776615 0.267129123211
+vn -0.375958114862 0.926636695862 -4.38627685071e-05
+vn -0.368752598763 0.926633894444 0.0732873827219
+vn -0.347374409437 0.926636636257 0.143789827824
+vn -0.312642782927 0.926636695862 0.208803758025
+vn -0.265906244516 0.926636695862 0.265778630972
+vn -0.208938151598 0.926636695862 0.312552720308
+vn -0.143956005573 0.926636636257 0.347305655479
+vn -0.0734044164419 0.926639318466 0.368715882301
+vn -4.35751608165e-05 0.926636755466 0.375958025455
+vn -0.489842504263 0.871810972691 -2.06960394280e-05
+vn -0.480436295271 0.871810793877 0.0955351144075
+vn -0.452572435141 0.871810972691 0.187413424253
+vn -0.407310366631 0.871811091900 0.272109717131
+vn -0.346402287483 0.871811151505 0.346339106560
+vn -0.272173732519 0.871811032295 0.407267719507
+vn -0.187495648861 0.871810972691 0.452538341284
+vn -0.0955921038985 0.871810972691 0.480424433947
+vn -2.06236290978e-05 0.871811032295 0.489842414856
+vn -0.599311292171 0.800516009331 -2.07761672755e-06
+vn -0.587800204754 0.800514042377 0.116911157966
+vn -0.553694009781 0.800515890121 0.229341089725
+vn -0.498316437006 0.800515770912 0.332949131727
+vn -0.423781901598 0.800515711308 0.423772901297
+vn -0.332970172167 0.800515830517 0.498302459717
+vn -0.229352369905 0.800515890121 0.553689301014
+vn -0.116928964853 0.800517678261 0.587791681290
+vn -2.28893190979e-06 0.800515830517 0.599311530590
+vn -0.704574048519 0.709630429745 -3.67859115613e-07
+vn -0.691035687923 0.709630727768 0.137455627322
+vn -0.650941967964 0.709630548954 0.269627690315
+vn -0.585831999779 0.709630370140 0.391440510750
+vn -0.498210281134 0.709630370140 0.498208165169
+vn -0.391440361738 0.709630608559 0.585831820965
+vn -0.269629955292 0.709630489349 0.650941073895
+vn -0.137455672026 0.709630429745 0.691035926342
+vn -4.61461922896e-07 0.709630429745 0.704574048519
+vn -0.789522230625 0.613721966743 3.19967000451e-07
+vn -0.774352073669 0.613721549511 0.154028445482
+vn -0.729423403740 0.613721907139 0.302137196064
+vn -0.656463861465 0.613721728325 0.438635230064
+vn -0.558276832104 0.613721787930 0.558276474476
+vn -0.438635081053 0.613721728325 0.656463861465
+vn -0.302136838436 0.613721609116 0.729423761368
+vn -0.154028266668 0.613721549511 0.774352133274
+vn 4.34107334968e-07 0.613721787930 0.789522409439
+vn -0.847586274147 0.530657529831 1.35653081657e-07
+vn -0.831300318241 0.530657291412 0.165356069803
+vn -0.783067762852 0.530657410622 0.324357360601
+vn -0.704742193222 0.530657529831 0.470893979073
+vn -0.599334180355 0.530657410622 0.599334001541
+vn -0.470893800259 0.530657470226 0.704742312431
+vn -0.324357092381 0.530657351017 0.783067882061
+vn -0.165356367826 0.530657470226 0.831300199032
+vn 1.24426620118e-07 0.530657410622 0.847586333752
+vn -0.909193992615 0.416372627020 2.34587176351e-07
+vn -0.891724109650 0.416372418404 0.177375167608
+vn -0.839986085892 0.416371852160 0.347933650017
+vn -0.755967319012 0.416372299194 0.505121290684
+vn -0.642897486687 0.416372478008 0.642897069454
+vn -0.505121290684 0.416372209787 0.755967378616
+vn -0.347933471203 0.416372269392 0.839985966682
+vn -0.177374809980 0.416372448206 0.891724228859
+vn -1.14478545754e-07 0.416372328997 0.909194111824
+vn -0.984744250774 0.174008145928 2.31635098658e-07
+vn -0.965822756290 0.174006983638 0.192114412785
+vn -0.909785091877 0.174007773399 0.376845419407
+vn -0.818784952164 0.174007967114 0.547094643116
+vn -0.696319282055 0.174008175731 0.696319341660
+vn -0.547094285488 0.174008026719 0.818785071373
+vn -0.376845210791 0.174008071423 0.909785091877
+vn -0.192113935947 0.174007952213 0.965822696686
+vn 1.34804011509e-07 0.174008041620 0.984744191170
+vn -0.964679539204 -0.263426065445 2.19359648668e-07
+vn -0.946143329144 -0.263426750898 0.188199847937
+vn -0.891247630119 -0.263426393270 0.369166880846
+vn -0.802101612091 -0.263426393270 0.535947263241
+vn -0.682131290436 -0.263426959515 0.682131290436
+vn -0.535947024822 -0.263426482677 0.802101850510
+vn -0.369166672230 -0.263426184654 0.891247749329
+vn -0.188199833035 -0.263426274061 0.946143448353
+vn 5.82370809354e-08 -0.263426423073 0.964679539204
+vn -0.658063292503 -0.752962529659 1.65398290619e-07
+vn -0.645418941975 -0.752962529659 0.128381982446
+vn -0.607971012592 -0.752962768078 0.251829892397
+vn -0.547159552574 -0.752962648869 0.365600436926
+vn -0.465320736170 -0.752962887287 0.465320825577
+vn -0.365600228310 -0.752962708473 0.547159552574
+vn -0.251829802990 -0.752962827682 0.607971012592
+vn -0.128381699324 -0.752962589264 0.645418822765
+vn 1.86011703818e-07 -0.752962708473 0.658063113689
+vn -0.959696769714 0.281037181616 3.14170620186e-07
+vn -0.781838357449 -0.603774130344 0.155517593026
+vn -0.886644303799 0.281037181616 0.367260247469
+vn -0.662810504436 -0.603774249554 0.442875713110
+vn -0.678607940674 0.281037837267 0.678608119488
+vn -0.442875713110 -0.603774130344 0.662810623646
+vn -0.367259651423 0.281037509441 0.886644423008
+vn -0.155517265201 -0.603774130344 0.781838297844
+vn 2.92017546144e-07 0.281037569046 0.959696769714
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn 0.674308359623 0.738449871540 -1.58041473242e-07
+vn 0.630463480949 0.766021311283 -0.125407591462
+vn 0.622979760170 0.738449752331 -0.258047074080
+vn 0.534481108189 0.766021311283 -0.357129037380
+vn 0.476808100939 0.738449692726 -0.476808279753
+vn 0.357129007578 0.766021549702 -0.534480810165
+vn 0.258046805859 0.738449871540 -0.622979700565
+vn 0.125407159328 0.766021430492 -0.630463480949
+vn -3.77229952164e-07 0.738449931145 -0.674308359623
+vn 0.448026359081 0.894020318985 -3.79297148356e-07
+vn 0.439417600632 0.894020318985 -0.0874058529735
+vn 0.413922399282 0.894020378590 -0.171452373266
+vn 0.372520238161 0.894020378590 -0.248910054564
+vn 0.316802442074 0.894020378590 -0.316802442074
+vn 0.248910233378 0.894020318985 -0.372520178556
+vn 0.171452343464 0.894020259380 -0.413922399282
+vn 0.0874055847526 0.894020318985 -0.439417541027
+vn -1.99903027465e-07 0.894020318985 -0.448026418686
+vn 0.191464707255 0.981499493122 2.92099162635e-08
+vn 0.187785774469 0.981499433517 -0.0373528860509
+vn 0.176890328526 0.981499493122 -0.0732703059912
+vn 0.159197106957 0.981499552727 -0.106372036040
+vn 0.135385900736 0.981499552727 -0.135385945439
+vn 0.106372043490 0.981499552727 -0.159197196364
+vn 0.0732703655958 0.981499493122 -0.176890343428
+vn 0.0373529270291 0.981499493122 -0.187785774469
+vn 1.20241637092e-07 0.981499493122 -0.191464900970
+vn -0.0206096880138 0.999787628651 1.33279929315e-08
+vn -0.0202136635780 0.999787688255 0.00402074726298
+vn -0.0190408527851 0.999787628651 0.00788707099855
+vn -0.0171362329274 0.999787628651 0.0114503977820
+vn -0.0145732341334 0.999787628651 0.0145732155070
+vn -0.0114501249045 0.999787688255 0.0171361919492
+vn -0.00788699835539 0.999787628651 0.0190407708287
+vn -0.00402075890452 0.999787688255 0.0202137939632
+vn 9.09577053676e-08 0.999787628651 0.0206097569317
+vn -0.205292090774 0.978700816631 3.59314867637e-07
+vn -0.201347544789 0.978700757027 0.0400506779552
+vn -0.189665332437 0.978700637817 0.0785620436072
+vn -0.170694202185 0.978700757027 0.114054359496
+vn -0.145163431764 0.978700697422 0.145163461566
+vn -0.114054240286 0.978700757027 0.170694261789
+vn -0.0785619467497 0.978700757027 0.189665287733
+vn -0.0400505438447 0.978700816631 0.201347559690
+vn 2.32993244254e-07 0.978700816631 0.205292090774
+vn -0.404177606106 0.914680540562 1.92819001654e-07
+vn -0.396411538124 0.914680421352 0.0788513422012
+vn -0.373411446810 0.914680421352 0.154672086239
+vn -0.336061477661 0.914680421352 0.224549189210
+vn -0.285796761513 0.914680421352 0.285796761513
+vn -0.224549084902 0.914680540562 0.336061358452
+vn -0.154671981931 0.914680540562 0.373411476612
+vn -0.0788513273001 0.914680480957 0.396411478519
+vn 1.18693940010e-07 0.914680540562 0.404177606106
+vn -0.634387850761 0.773014903069 1.68151089497e-07
+vn -0.622198224068 0.773014903069 0.123763158917
+vn -0.586098134518 0.773014724255 0.242769718170
+vn -0.527474343777 0.773014724255 0.352447241545
+vn -0.448580026627 0.773014843464 0.448579937220
+vn -0.352446913719 0.773014962673 0.527474045753
+vn -0.242769628763 0.773014903069 0.586098015308
+vn -0.123763054609 0.773014962673 0.622198224068
+vn 1.37921688292e-07 0.773014903069 0.634387850761
+vn -0.885345399380 0.464933931828 2.08053307915e-07
+vn -0.868333578110 0.464933961630 0.172722652555
+vn -0.817952513695 0.464933753014 0.338807106018
+vn -0.736137688160 0.464933753014 0.491871893406
+vn -0.626033723354 0.464933842421 0.626033782959
+vn -0.491871654987 0.464933872223 0.736137807369
+vn -0.338806837797 0.464933902025 0.817952513695
+vn -0.172722309828 0.464933961630 0.868333756924
+vn 9.82473906674e-08 0.464933872223 0.885345399380
+vn -0.999712347984 0.0239825863391 1.18763438195e-07
+vn -0.980503082275 0.0239822342992 0.195034548640
+vn -0.923613607883 0.0239824168384 0.382573634386
+vn -0.831230401993 0.0239824764431 0.555410504341
+vn -0.706903696060 0.0239827744663 0.706903040409
+vn -0.555410385132 0.0239824466407 0.831230461597
+vn -0.382572948933 0.0239824019372 0.923613965511
+vn -0.195034191012 0.0239824298769 0.980503201485
+vn -2.87330887971e-08 0.0239824298769 0.999712347984
+vn -0.999967277050 -0.00808763224632 2.72169472737e-07
+vn -0.980753123760 -0.00808786507696 0.195084467530
+vn -0.923849225044 -0.00808795541525 0.382671028376
+vn -0.831442356110 -0.00808774307370 0.555552065372
+vn -0.707083642483 -0.00808777753264 0.707083582878
+vn -0.555551886559 -0.00808785390109 0.831442594528
+vn -0.382670730352 -0.00808789953589 0.923849463463
+vn -0.195084109902 -0.00808779709041 0.980753183365
+vn 2.36007124954e-07 -0.00808792654425 0.999967277050
+vn -0.882003307343 0.471243292093 4.04974912271e-07
+vn -0.865055739880 0.471243262291 0.172070741653
+vn -0.814865052700 0.471242845058 0.337528198957
+vn -0.733358860016 0.471243232489 0.490014821291
+vn -0.623670518398 0.471243053675 0.623670697212
+vn -0.490014702082 0.471243143082 0.733358979225
+vn -0.337527841330 0.471243172884 0.814864873886
+vn -0.172070175409 0.471243262291 0.865055859089
+vn 4.22668051669e-07 0.471243143082 0.882003247738
+vn -0.959696769714 0.281037181616 3.14170620186e-07
+vn -0.781838357449 -0.603774130344 0.155517593026
+vn -0.886644303799 0.281037181616 0.367260247469
+vn -0.662810504436 -0.603774249554 0.442875713110
+vn -0.678607940674 0.281037837267 0.678608119488
+vn -0.442875713110 -0.603774130344 0.662810623646
+vn -0.367259651423 0.281037509441 0.886644423008
+vn -0.155517265201 -0.603774130344 0.781838297844
+vn 2.92017546144e-07 0.281037569046 0.959696769714
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -9.89749282532e-10 0.999999940395 1.53847796724e-08
+vn -2.68135295300e-07 0.999988913536 0.00469539500773
+vn 0.00258183013648 0.999912321568 0.0129903201014
+vn 0.00179628038313 0.999988913536 0.00433812197298
+vn 0.00735587347299 0.999912321568 0.0110138310120
+vn 0.00331960013136 0.999988913536 0.00332073331811
+vn 0.0110107343644 0.999912321568 0.00736126489937
+vn 0.00433754781261 0.999988913536 0.00179739971645
+vn 0.0129895685241 0.999912321568 0.00258556660265
+vn 0.00469512119889 0.999988913536 1.20128106573e-06
+vn -9.47663829720e-06 0.997505724430 0.0705851465464
+vn 0.0137586332858 0.997505724430 0.0692311599851
+vn 0.0269945226610 0.997505724430 0.0652196928859
+vn 0.0392014607787 0.997505724430 0.0586987398565
+vn 0.0498981028795 0.997505724430 0.0499246008694
+vn 0.0586804412305 0.997505724430 0.0392282381654
+vn 0.0652051120996 0.997505724430 0.0270292721689
+vn 0.0692266300321 0.997505724430 0.0137828830630
+vn 0.0705852955580 0.997505664825 9.83200516202e-06
+vn -2.83809076791e-05 0.986527562141 0.163595527411
+vn 0.0318761877716 0.986527502537 0.160460203886
+vn 0.0625536367297 0.986527383327 0.151164859533
+vn 0.0908439159393 0.986527383327 0.136055827141
+vn 0.115640372038 0.986527383327 0.115720093250
+vn 0.135995075107 0.986527383327 0.0909341052175
+vn 0.151121750474 0.986527442932 0.0626571029425
+vn 0.160445287824 0.986527264118 0.0319561921060
+vn 0.163596361876 0.986527383327 2.84709221887e-05
+vn -4.26377046097e-05 0.963660776615 0.267129123211
+vn 0.0520419590175 0.963660776615 0.262010842562
+vn 0.102146603167 0.963660657406 0.246828213334
+vn 0.148327007890 0.963660776615 0.222164675593
+vn 0.188828170300 0.963660776615 0.188949704170
+vn 0.222055047750 0.963660717010 0.148491024971
+vn 0.246762305498 0.963660776615 0.102305293083
+vn 0.261981993914 0.963660836220 0.0521863587201
+vn 0.267129421234 0.963660657406 4.26232436439e-05
+vn -4.35751608165e-05 0.926636755466 0.375958025455
+vn 0.0732876881957 0.926633894444 0.368752598763
+vn 0.143790096045 0.926636517048 0.347374618053
+vn 0.208803966641 0.926636636257 0.312642753124
+vn 0.265778720379 0.926636695862 0.265906065702
+vn 0.312552720308 0.926636755466 0.208938181400
+vn 0.347305387259 0.926636815071 0.143956020474
+vn 0.368715912104 0.926639318466 0.0734038054943
+vn 0.375958323479 0.926636636257 4.38095412392e-05
+vn -2.06236290978e-05 0.871811032295 0.489842414856
+vn 0.0955350324512 0.871810793877 0.480436354876
+vn 0.187413513660 0.871810972691 0.452572554350
+vn 0.272109717131 0.871810853481 0.407310903072
+vn 0.346339315176 0.871811091900 0.346402347088
+vn 0.407267689705 0.871811091900 0.272173732519
+vn 0.452538430691 0.871811032295 0.187495723367
+vn 0.480424582958 0.871811032295 0.0955918803811
+vn 0.489842385054 0.871811032295 2.06175536732e-05
+vn -2.28893190979e-06 0.800515830517 0.599311530590
+vn 0.116911187768 0.800514101982 0.587800204754
+vn 0.229340746999 0.800515949726 0.553693830967
+vn 0.332949101925 0.800515890121 0.498316496611
+vn 0.423773080111 0.800515651703 0.423781871796
+vn 0.498302429914 0.800515830517 0.332970261574
+vn 0.553689718246 0.800515592098 0.229352355003
+vn 0.587791860104 0.800517618656 0.116928547621
+vn 0.599311947823 0.800515651703 2.06826689464e-06
+vn -4.61461922896e-07 0.709630429745 0.704574048519
+vn 0.137455821037 0.709630608559 0.691035747528
+vn 0.269627571106 0.709630608559 0.650941967964
+vn 0.391440331936 0.709630608559 0.585831820965
+vn 0.498208194971 0.709630250931 0.498210370541
+vn 0.585831463337 0.709630787373 0.391440391541
+vn 0.650941014290 0.709630548954 0.269629985094
+vn 0.691035628319 0.709630787373 0.137455433607
+vn 0.704573988914 0.709630548954 3.34162081117e-07
+vn 4.34107334968e-07 0.613721787930 0.789522409439
+vn 0.154028385878 0.613721668720 0.774351954460
+vn 0.302137345076 0.613721549511 0.729423701763
+vn 0.438635170460 0.613721728325 0.656463801861
+vn 0.558276653290 0.613721430302 0.558276891708
+vn 0.656463921070 0.613721609116 0.438635230064
+vn 0.729423820972 0.613721489906 0.302137255669
+vn 0.774351954460 0.613721787930 0.154027879238
+vn 0.789522409439 0.613721609116 -2.35765170942e-07
+vn 1.24426620118e-07 0.530657410622 0.847586333752
+vn 0.165356054902 0.530657351017 0.831300258636
+vn 0.324357479811 0.530657291412 0.783067703247
+vn 0.470893681049 0.530657649040 0.704742252827
+vn 0.599333882332 0.530657529831 0.599334180355
+vn 0.704742491245 0.530657172203 0.470893830061
+vn 0.783067762852 0.530657410622 0.324357151985
+vn 0.831300258636 0.530657589436 0.165355578065
+vn 0.847586512566 0.530657291412 -1.95527547930e-07
+vn -1.14478545754e-07 0.416372328997 0.909194111824
+vn 0.177375152707 0.416372179985 0.891724228859
+vn 0.347933769226 0.416372030973 0.839985966682
+vn 0.505121111870 0.416372209787 0.755967378616
+vn 0.642897069454 0.416372835636 0.642897307873
+vn 0.755967259407 0.416372388601 0.505121231079
+vn 0.839985787868 0.416372746229 0.347933381796
+vn 0.891724288464 0.416372448206 0.177374705672
+vn 0.909194111824 0.416372656822 -3.17161919838e-07
+vn 1.34804011509e-07 0.174008041620 0.984744191170
+vn 0.192114427686 0.174007922411 0.965822577477
+vn 0.376845210791 0.174007967114 0.909785151482
+vn 0.547094285488 0.174007922411 0.818785130978
+vn 0.696319222450 0.174008190632 0.696319341660
+vn 0.818785071373 0.174007952213 0.547094464302
+vn 0.909785091877 0.174008235335 0.376845240593
+vn 0.965822815895 0.174007341266 0.192113906145
+vn 0.984744310379 0.174007967114 -2.63912113496e-07
+vn 5.82370809354e-08 -0.263426423073 0.964679539204
+vn 0.188199713826 -0.263426512480 0.946143388748
+vn 0.369166851044 -0.263426452875 0.891247570515
+vn 0.535947263241 -0.263426363468 0.802101612091
+vn 0.682131171227 -0.263426542282 0.682131588459
+vn 0.802101671696 -0.263426572084 0.535947084427
+vn 0.891247808933 -0.263426154852 0.369166731834
+vn 0.946143507957 -0.263426244259 0.188199460506
+vn 0.964679777622 -0.263425767422 -2.21300837211e-07
+vn 1.86011703818e-07 -0.752962708473 0.658063113689
+vn 0.128382056952 -0.752962708473 0.645418643951
+vn 0.251829773188 -0.752962708473 0.607971131802
+vn 0.365600347519 -0.752962589264 0.547159612179
+vn 0.465320914984 -0.752962827682 0.465320855379
+vn 0.547159135342 -0.752963185310 0.365600049496
+vn 0.607970893383 -0.752962946892 0.251829773188
+vn 0.645418882370 -0.752962648869 0.128381624818
+vn 0.658063352108 -0.752962589264 -1.79140599244e-07
+vn 2.92017546144e-07 0.281037569046 0.959696769714
+vn 0.155517607927 -0.603774011135 0.781838417053
+vn 0.367259949446 0.281037509441 0.886644244194
+vn 0.442875772715 -0.603774189949 0.662810385227
+vn 0.678608000278 0.281037926674 0.678607881069
+vn 0.662810385227 -0.603774189949 0.442875742912
+vn 0.886644244194 0.281037390232 0.367260187864
+vn 0.781838119030 -0.603774487972 0.155517131090
+vn 0.959696769714 0.281037539244 -3.12156714699e-07
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -2.01607104344e-08 1.00000000000 -4.21214849666e-08
+vn -3.77229952164e-07 0.738449931145 -0.674308359623
+vn -0.125407546759 0.766021370888 -0.630463540554
+vn -0.258046746254 0.738449871540 -0.622979760170
+vn -0.357128649950 0.766021311283 -0.534481465816
+vn -0.476808071136 0.738449573517 -0.476808488369
+vn -0.534481167793 0.766021370888 -0.357128918171
+vn -0.622979640961 0.738449931145 -0.258046537638
+vn -0.630463540554 0.766021490097 -0.125406533480
+vn -0.674308478832 0.738449811935 1.71211596012e-07
+vn -1.99903027465e-07 0.894020318985 -0.448026418686
+vn -0.0874058380723 0.894020318985 -0.439417660236
+vn -0.171452194452 0.894020318985 -0.413922339678
+vn -0.248909965158 0.894020438194 -0.372520238161
+vn -0.316802501678 0.894020199776 -0.316802859306
+vn -0.372520267963 0.894020318985 -0.248910412192
+vn -0.413922488689 0.894020378590 -0.171452149749
+vn -0.439417779446 0.894020259380 -0.0874050930142
+vn -0.448026418686 0.894020259380 1.56292117026e-07
+vn 1.20241637092e-07 0.981499493122 -0.191464900970
+vn -0.0373529158533 0.981499433517 -0.187785789371
+vn -0.0732703432441 0.981499493122 -0.176890373230
+vn -0.106372036040 0.981499493122 -0.159197062254
+vn -0.135386139154 0.981499493122 -0.135385796428
+vn -0.159197181463 0.981499433517 -0.106372274458
+vn -0.176890328526 0.981499433517 -0.0732704997063
+vn -0.187785848975 0.981499493122 -0.0373525358737
+vn -0.191464751959 0.981499433517 1.64115135703e-07
+vn 9.09577053676e-08 0.999787628651 0.0206097569317
+vn 0.00402075843886 0.999787688255 0.0202139262110
+vn 0.00788694992661 0.999787628651 0.0190408714116
+vn 0.0114500811324 0.999787688255 0.0171362068504
+vn 0.0145731670782 0.999787628651 0.0145732276142
+vn 0.0171363055706 0.999787628651 0.0114503847435
+vn 0.0190408732742 0.999787628651 0.00788705330342
+vn 0.0202136412263 0.999787628651 0.00402074586600
+vn 0.0206096880138 0.999787628651 -1.46140290980e-08
+vn 2.32993244254e-07 0.978700816631 0.205292090774
+vn 0.0400506854057 0.978700697422 0.201347604394
+vn 0.0785617604852 0.978700757027 0.189665198326
+vn 0.114054150879 0.978700816631 0.170694157481
+vn 0.145163431764 0.978700816631 0.145163312554
+vn 0.170694217086 0.978700757027 0.114054329693
+vn 0.189665213227 0.978700697422 0.0785619914532
+vn 0.201347604394 0.978700757027 0.0400504730642
+vn 0.205292254686 0.978700757027 -1.29128778781e-07
+vn 1.18693940010e-07 0.914680540562 0.404177606106
+vn 0.0788514167070 0.914680421352 0.396411716938
+vn 0.154672026634 0.914680540562 0.373411476612
+vn 0.224549219012 0.914680480957 0.336061418056
+vn 0.285796850920 0.914680540562 0.285796761513
+vn 0.336061447859 0.914680480957 0.224548861384
+vn 0.373411417007 0.914680540562 0.154672145844
+vn 0.396411538124 0.914680540562 0.0788510516286
+vn 0.404177725315 0.914680480957 -1.01804673136e-07
+vn 1.37921688292e-07 0.773014903069 0.634387850761
+vn 0.123763047159 0.773014843464 0.622198224068
+vn 0.242769315839 0.773014903069 0.586098074913
+vn 0.352447181940 0.773014783859 0.527474224567
+vn 0.448580116034 0.773014605045 0.448580116034
+vn 0.527474224567 0.773014843464 0.352447092533
+vn 0.586097776890 0.773015022278 0.242769762874
+vn 0.622198104858 0.773015022278 0.123762629926
+vn 0.634387969971 0.773014843464 -3.49527539356e-07
+vn 9.82473906674e-08 0.464933872223 0.885345399380
+vn 0.172722816467 0.464933902025 0.868333578110
+vn 0.338807076216 0.464933812618 0.817952513695
+vn 0.491871923208 0.464933574200 0.736137747765
+vn 0.626033723354 0.464933633804 0.626033842564
+vn 0.736137688160 0.464933872223 0.491871714592
+vn 0.817952573299 0.464933753014 0.338806927204
+vn 0.868333756924 0.464933782816 0.172722071409
+vn 0.885345280170 0.464934170246 -2.25391076469e-07
+vn -2.87330887971e-08 0.0239824298769 0.999712347984
+vn 0.195034563541 0.0239823050797 0.980503082275
+vn 0.382573395967 0.0239822138101 0.923613727093
+vn 0.555410444736 0.0239823330194 0.831230461597
+vn 0.706903278828 0.0239828005433 0.706903517246
+vn 0.831230401993 0.0239824429154 0.555410385132
+vn 0.923613846302 0.0239822026342 0.382573395967
+vn 0.980503201485 0.0239822715521 0.195034012198
+vn 0.999712347984 0.0239820554852 -1.45581026345e-07
+vn 2.36007124954e-07 -0.00808792654425 0.999967277050
+vn 0.195084631443 -0.00808810163289 0.980753064156
+vn 0.382671028376 -0.00808801315725 0.923849225044
+vn 0.555551886559 -0.00808780826628 0.831442594528
+vn 0.707083523273 -0.00808784738183 0.707083761692
+vn 0.831442356110 -0.00808787159622 0.555552065372
+vn 0.923849344254 -0.00808780547231 0.382670938969
+vn 0.980753183365 -0.00808744318783 0.195083782077
+vn 0.999967277050 -0.00808802247047 -3.03573642668e-07
+vn 4.22668051669e-07 0.471243143082 0.882003247738
+vn 0.172070592642 0.471243292093 0.865055799484
+vn 0.337527871132 0.471243143082 0.814864873886
+vn 0.490014731884 0.471243232489 0.733358860016
+vn 0.623670697212 0.471243202686 0.623670458794
+vn 0.733358919621 0.471243202686 0.490014821291
+vn 0.814864814281 0.471243113279 0.337527900934
+vn 0.865055859089 0.471243381500 0.172069996595
+vn 0.882003307343 0.471243262291 -4.63951948859e-07
+vn 2.92017546144e-07 0.281037569046 0.959696769714
+vn 0.155517607927 -0.603774011135 0.781838417053
+vn 0.367259949446 0.281037509441 0.886644244194
+vn 0.442875772715 -0.603774189949 0.662810385227
+vn 0.678608000278 0.281037926674 0.678607881069
+vn 0.662810385227 -0.603774189949 0.442875742912
+vn 0.886644244194 0.281037390232 0.367260187864
+vn 0.781838119030 -0.603774487972 0.155517131090
+vn 0.959696769714 0.281037539244 -3.12156714699e-07
+vn 0.767331600189 -0.177287235856 -0.616255998611
+vn 0.756508588791 -0.147678151727 -0.637091934681
+vn 0.734736502171 -0.100052423775 -0.670933425426
+vn 0.712413907051 -0.0779209434986 -0.697420060635
+vn 0.689794421196 -0.0614006258547 -0.721396982670
+vn 0.666978836060 -0.0514411926270 -0.743298768997
+vn 0.643234848976 -0.0420105420053 -0.764515638351
+vn 0.619229912758 -0.0373408161104 -0.784321427345
+vn 0.593621253967 -0.0312793552876 -0.804136455059
+vn 0.567553758621 -0.0284584984183 -0.822844386101
+vn 0.539623618126 -0.0226897522807 -0.841600537300
+vn 0.511369347572 -0.0194615926594 -0.859140634537
+vn 0.481911450624 -0.0136855924502 -0.876112997532
+vn 0.452550590038 -0.0109421284869 -0.891671657562
+vn 0.422520339489 -0.00639961380512 -0.906330943108
+vn 0.392772585154 -0.00497314799577 -0.919622242451
+vn 0.362427353859 -0.00168254843447 -0.932010591030
+vn 0.332425385714 -0.00114440405741 -0.943128943443
+vn 0.302054315805 0.00146822468378 -0.953289568424
+vn 0.272229820490 0.00158006174024 -0.962231040001
+vn 0.247655078769 0.00345693458803 -0.968842148781
+vn 0.234121307731 0.00253324722871 -0.972204208374
+vn 0.974901139736 -0.222638189793 0.00000000000
+vn 0.981826961040 -0.189777970314 4.83554813968e-08
+vn 0.991181254387 -0.132513239980 -2.01132124289e-08
+vn 0.994284272194 -0.106764525175 4.16094536604e-08
+vn 0.996257841587 -0.0864315629005 -6.45830553481e-08
+vn 0.997193157673 -0.0748720169067 5.57269004275e-08
+vn 0.998017728329 -0.0629319995642 -4.62474503138e-08
+vn 0.998315453529 -0.0580193661153 -1.56272491836e-07
+vn 0.998737215996 -0.0502382628620 1.25365446024e-07
+vn 0.998861372471 -0.0477085560560 5.24970822369e-08
+vn 0.999224066734 -0.0393860898912 2.76017892986e-08
+vn 0.999370336533 -0.0354805402458 -1.45723699774e-08
+vn 0.999674201012 -0.0255220606923 -6.18611437631e-08
+vn 0.999770700932 -0.0214124806225 -4.94171175092e-08
+vn 0.999927580357 -0.0120333172381 -2.11752961832e-07
+vn 0.999953985214 -0.00959443580359 -1.89844513443e-07
+vn 0.999999344349 -0.00117364781909 -4.11533065403e-08
+vn 1.00000000000 4.22244847869e-05 1.12159867172e-07
+vn 0.999960839748 0.00885279569775 -9.87972512689e-08
+vn 0.999951660633 0.00982592441142 2.73859424027e-08
+vn 0.999829351902 0.0184789095074 -1.84561599781e-07
+vn 0.999878704548 0.0155759835616 0.00000000000
+vn 0.767331540585 -0.177287206054 0.616256058216
+vn 0.756508529186 -0.147677958012 0.637091994286
+vn 0.734736442566 -0.100052334368 0.670933485031
+vn 0.712413787842 -0.0779209733009 0.697420179844
+vn 0.689794480801 -0.0614006668329 0.721396982670
+vn 0.666978597641 -0.0514411367476 0.743299007416
+vn 0.643234789371 -0.0420105271041 0.764515697956
+vn 0.619230151176 -0.0373409204185 0.784321188927
+vn 0.593621313572 -0.0312793441117 0.804136455059
+vn 0.567553699017 -0.0284585617483 0.822844386101
+vn 0.539623737335 -0.0226898342371 0.841600477695
+vn 0.511369585991 -0.0194616839290 0.859140455723
+vn 0.481911659241 -0.0136856473982 0.876112997532
+vn 0.452550768852 -0.0109421992674 0.891671538353
+vn 0.422520458698 -0.00639958214015 0.906330764294
+vn 0.392772704363 -0.00497310608625 0.919622242451
+vn 0.362427353859 -0.00168256612960 0.932010591030
+vn 0.332425326109 -0.00114439486060 0.943128943443
+vn 0.302054494619 0.00146825239062 0.953289568424
+vn 0.272229731083 0.00158008735161 0.962231040001
+vn 0.247654974461 0.00345689314418 0.968842148781
+vn 0.234120413661 0.00253308471292 0.972204387188
+vn 0.356402665377 -0.177286729217 -0.917358458042
+vn 0.336611390114 -0.147677868605 -0.929991424084
+vn 0.300832569599 -0.100052669644 -0.948413968086
+vn 0.268255859613 -0.0779211521149 -0.960191190243
+vn 0.236680880189 -0.0614006295800 -0.969645380974
+vn 0.205973461270 -0.0514410547912 -0.977204561234
+vn 0.174800559878 -0.0420106053352 -0.983707308769
+vn 0.144106462598 -0.0373410806060 -0.988857507706
+vn 0.112022392452 -0.0312793590128 -0.993213355541
+vn 0.0800945013762 -0.0284583382308 -0.996380984783
+vn 0.0465265847743 -0.0226898472756 -0.998659253120
+vn 0.0132906027138 -0.0194616578519 -0.999722361565
+vn -0.0207086894661 -0.0136856166646 -0.999691843987
+vn -0.0539184026420 -0.0109420195222 -0.998485386372
+vn -0.0872514322400 -0.00639957748353 -0.996165812016
+vn -0.119659282267 -0.00497306510806 -0.992802619934
+vn -0.152131691575 -0.00168259046040 -0.988358855247
+vn -0.183674603701 -0.00114433723502 -0.982986450195
+vn -0.215056911111 0.00146824959666 -0.976600468159
+vn -0.245356068015 0.00157991808373 -0.969431757927
+vn -0.269945025444 0.00345699186437 -0.962869524956
+vn -0.283344209194 0.00253276829608 -0.959014952183
+vn 0.844288051128 -0.222638905048 -0.487452208996
+vn 0.850287497044 -0.189778044820 -0.490912973881
+vn 0.858388125896 -0.132513463497 -0.495590478182
+vn 0.861075162888 -0.106764890254 -0.497142642736
+vn 0.862784385681 -0.0864318087697 -0.498129040003
+vn 0.863594889641 -0.0748719871044 -0.498596072197
+vn 0.864308953285 -0.0629324018955 -0.499008804560
+vn 0.864566683769 -0.0580194033682 -0.499157518148
+vn 0.864931881428 -0.0502386167645 -0.499368667603
+vn 0.865038871765 -0.0477085113525 -0.499431222677
+vn 0.865353167057 -0.0393865481019 -0.499612659216
+vn 0.865480363369 -0.0354805961251 -0.499684721231
+vn 0.865743339062 -0.0255221687257 -0.499837040901
+vn 0.865827381611 -0.0214125141501 -0.499884307384
+vn 0.865964114666 -0.0120335575193 -0.499961465597
+vn 0.865986049175 -0.00959430262446 -0.499976128340
+vn 0.866025865078 -0.00117404665798 -0.499997824430
+vn 0.866025626659 4.19414645876e-05 -0.499999731779
+vn 0.865991055965 0.00885286554694 -0.499981075525
+vn 0.865983426571 0.00982587877661 -0.499976277351
+vn 0.865877449512 0.0184789299965 -0.499914795160
+vn 0.865921616554 0.0155774336308 -0.499937057495
+vn 0.972656488419 -0.177287399769 0.150028377771
+vn 0.973701119423 -0.147677898407 0.173485830426
+vn 0.971767127514 -0.100052461028 0.213677421212
+vn 0.965678632259 -0.0779206529260 0.247776955366
+vn 0.958077788353 -0.0614007189870 0.279851436615
+vn 0.949269831181 -0.0514404438436 0.310226738453
+vn 0.939315617085 -0.0420105196536 0.340472489595
+vn 0.928429543972 -0.0373408347368 0.369627207518
+vn 0.916159451008 -0.0312793627381 0.399591892958
+vn 0.902938604355 -0.0284583345056 0.428826451302
+vn 0.888127982616 -0.0226899422705 0.459035813808
+vn 0.872427821159 -0.0194615591317 0.488355547190
+vn 0.855403482914 -0.0136856352910 0.517781555653
+vn 0.837755501270 -0.0109420018271 0.545935869217
+vn 0.819078266621 -0.00639953138307 0.573646247387
+vn 0.799962759018 -0.00497296871617 0.600029170513
+vn 0.779875636101 -0.00168253120501 0.625932335854
+vn 0.759452760220 -0.00114435376599 0.650561451912
+vn 0.738232433796 0.00146806659177 0.674544990063
+vn 0.716874718666 0.00157995091286 0.697200179100
+vn 0.698896229267 0.00345724564977 0.715214788914
+vn 0.688853263855 0.00253509893082 0.724896371365
+vn -0.150029435754 -0.177286669612 -0.972656428814
+vn -0.173483714461 -0.147677630186 -0.973701536655
+vn -0.213678047061 -0.100052215159 -0.971767067909
+vn -0.247781723738 -0.0779209434986 -0.965677261353
+vn -0.279853284359 -0.0614006519318 -0.958077251911
+vn -0.310228884220 -0.0514411963522 -0.949269175529
+vn -0.340469807386 -0.0420105941594 -0.939316451550
+vn -0.369624942541 -0.0373407453299 -0.928430497646
+vn -0.399588733912 -0.0312794260681 -0.916160702705
+vn -0.428823828697 -0.0284583494067 -0.902939796448
+vn -0.459035187960 -0.0226899087429 -0.888128280640
+vn -0.488354593515 -0.0194617193192 -0.872428238392
+vn -0.517779648304 -0.0136856706813 -0.855404615402
+vn -0.545937776566 -0.0109419729561 -0.837754309177
+vn -0.573647201061 -0.00639946153387 -0.819077610970
+vn -0.600027143955 -0.00497315637767 -0.799964189529
+vn -0.625930905342 -0.00168259430211 -0.779876828194
+vn -0.650562047958 -0.00114412733819 -0.759452283382
+vn -0.674545824528 0.00146822456736 -0.738231599331
+vn -0.697204351425 0.00157998374198 -0.716870784760
+vn -0.715213477612 0.00345700723119 -0.698897480965
+vn -0.724888801575 0.00253229099326 -0.688861310482
+vn 0.487447768450 -0.222640037537 -0.844290256500
+vn 0.490912973881 -0.189777866006 -0.850287497044
+vn 0.495592415333 -0.132512986660 -0.858387112617
+vn 0.497141242027 -0.106764897704 -0.861076056957
+vn 0.498128831387 -0.0864312872291 -0.862784624100
+vn 0.498596668243 -0.0748720541596 -0.863594591618
+vn 0.499010741711 -0.0629322081804 -0.864307761192
+vn 0.499158829451 -0.0580191798508 -0.864565968513
+vn 0.499369502068 -0.0502384305000 -0.864931285381
+vn 0.499432384968 -0.0477083548903 -0.865038275719
+vn 0.499614119530 -0.0393861606717 -0.865352213383
+vn 0.499684959650 -0.0354805849493 -0.865480244160
+vn 0.499836206436 -0.0255223307759 -0.865743875504
+vn 0.499884545803 -0.0214124545455 -0.865827322006
+vn 0.499964416027 -0.0120334420353 -0.865962266922
+vn 0.499978095293 -0.00959450844675 -0.865984916687
+vn 0.499997645617 -0.00117415050045 -0.866025924683
+vn 0.499999165535 4.25349353463e-05 -0.866025865078
+vn 0.499982029200 0.00885299406946 -0.865990519524
+vn 0.499974995852 0.00982565153390 -0.865984082222
+vn 0.499915391207 0.0184810291976 -0.865876972675
+vn 0.499940037727 0.0155769623816 -0.865919947624
+vn 0.917359113693 -0.177287101746 -0.356400877237
+vn 0.929991722107 -0.147677421570 -0.336610883474
+vn 0.948413610458 -0.100052751601 -0.300833702087
+vn 0.960190296173 -0.0779213979840 -0.268259167671
+vn 0.969645321369 -0.0614006295800 -0.236680999398
+vn 0.977205216885 -0.0514409244061 -0.205970451236
+vn 0.983707487583 -0.0420104712248 -0.174799531698
+vn 0.988857209682 -0.0373408347368 -0.144108667970
+vn 0.993213176727 -0.0312793552876 -0.112023413181
+vn 0.996381044388 -0.0284584276378 -0.0800934210420
+vn 0.998659312725 -0.0226897671819 -0.0465271808207
+vn 0.999722361565 -0.0194615293294 -0.0132883628830
+vn 0.999691903591 -0.0136856632307 0.0207087807357
+vn 0.998485565186 -0.0109419422224 0.0539159588516
+vn 0.996165692806 -0.00639958307147 0.0872527807951
+vn 0.992802500725 -0.00497300364077 0.119660042226
+vn 0.988358557224 -0.00168252538424 0.152133747935
+vn 0.982986330986 -0.00114421767648 0.183675467968
+vn 0.976600527763 0.00146826333366 0.215056762099
+vn 0.969432115555 0.00157997093629 0.245354592800
+vn 0.962869644165 0.00345710199326 0.269944727421
+vn 0.959014296532 0.00253292964771 0.283346682787
+vn -0.616254568100 -0.177287310362 -0.767332792282
+vn -0.637090802193 -0.147677615285 -0.756509542465
+vn -0.670934677124 -0.100052289665 -0.734735310078
+vn -0.697419822216 -0.0779209062457 -0.712414264679
+vn -0.721396625042 -0.0614007115364 -0.689794898033
+vn -0.743299007416 -0.0514411143959 -0.666978597641
+vn -0.764516472816 -0.0420104712248 -0.643233835697
+vn -0.784320473671 -0.0373409315944 -0.619231104851
+vn -0.804136335850 -0.0312793292105 -0.593621492386
+vn -0.822845220566 -0.0284582860768 -0.567552745342
+vn -0.841601252556 -0.0226898286492 -0.539622485638
+vn -0.859140992165 -0.0194617491215 -0.511368870735
+vn -0.876112818718 -0.0136856632307 -0.481911867857
+vn -0.891670763493 -0.0109420595691 -0.452552288771
+vn -0.906330883503 -0.00639959331602 -0.422520279884
+vn -0.919620454311 -0.00497314520180 -0.392776697874
+vn -0.932009994984 -0.00168256880715 -0.362428963184
+vn -0.943128228188 -0.00114425562788 -0.332427352667
+vn -0.953289568424 0.00146822561510 -0.302054643631
+vn -0.962230563164 0.00157998979557 -0.272231370211
+vn -0.968841671944 0.00345696602017 -0.247656822205
+vn -0.972202956676 0.00253281649202 -0.234126314521
+vn 2.50140897151e-06 -0.222639545798 -0.974900841713
+vn 3.86844220657e-07 -0.189777940512 -0.981827080250
+vn -4.02265953880e-08 -0.132513299584 -0.991181194782
+vn 4.16094714240e-08 -0.106764636934 -0.994284272194
+vn 0.00000000000 -0.0864316225052 -0.996257781982
+vn -4.12379336012e-07 -0.0748721361160 -0.997193157673
+vn -3.46856211308e-07 -0.0629320740700 -0.998017847538
+vn 3.84670045150e-07 -0.0580193251371 -0.998315393925
+vn 3.51022606537e-07 -0.0502385459840 -0.998737215996
+vn -2.23113161724e-07 -0.0477084554732 -0.998861312866
+vn -1.10407981424e-07 -0.0393863692880 -0.999224007130
+vn 5.10033885348e-07 -0.0354806929827 -0.999370336533
+vn -6.18610513925e-08 -0.0255221594125 -0.999674201012
+vn 9.88340786989e-08 -0.0214124545455 -0.999770641327
+vn 5.99970007897e-07 -0.0120332697406 -0.999927639961
+vn 3.98672796109e-07 -0.00959445722401 -0.999954044819
+vn 4.11532745659e-08 -0.00117408158258 -0.999999225140
+vn -2.24319450126e-07 4.22275334131e-05 -1.00000000000
+vn -3.45792386724e-07 0.00885282084346 -0.999960780144
+vn -5.47718137511e-08 0.00982581824064 -0.999951720238
+vn 6.15204527321e-08 0.0184799395502 -0.999829173088
+vn -3.75458000690e-07 0.0155761288479 -0.999878704548
+vn 0.616255819798 -0.177287101746 -0.767331779003
+vn 0.637090146542 -0.147677704692 -0.756510138512
+vn 0.670934677124 -0.100052267313 -0.734735369682
+vn 0.697419822216 -0.0779209211469 -0.712414264679
+vn 0.721396148205 -0.0614007264376 -0.689795255661
+vn 0.743298470974 -0.0514411590993 -0.666979134083
+vn 0.764516532421 -0.0420104674995 -0.643233776093
+vn 0.784320950508 -0.0373408794403 -0.619230508804
+vn 0.804136574268 -0.0312793254852 -0.593621134758
+vn 0.822845220566 -0.0284582860768 -0.567552566528
+vn 0.841601490974 -0.0226898323745 -0.539622306824
+vn 0.859141469002 -0.0194617249072 -0.511367976665
+vn 0.876113116741 -0.0136856483296 -0.481911391020
+vn 0.891671001911 -0.0109420446679 -0.452551901340
+vn 0.906331181526 -0.00639958586544 -0.422519654036
+vn 0.919620692730 -0.00497314240783 -0.392776221037
+vn 0.932009935379 -0.00168256985489 -0.362429022789
+vn 0.943128108978 -0.00114425655920 -0.332427680492
+vn 0.953289508820 0.00146822445095 -0.302054733038
+vn 0.962230920792 0.00157999142539 -0.272230386734
+vn 0.968841671944 0.00345696951263 -0.247657060623
+vn 0.972202479839 0.00253282394260 -0.234128132463
+vn -0.917358577251 -0.177287235856 -0.356402039528
+vn -0.929992496967 -0.147676542401 -0.336608946323
+vn -0.948413729668 -0.100052520633 -0.300833553076
+vn -0.960190355778 -0.0779208838940 -0.268258929253
+vn -0.969645261765 -0.0614008158445 -0.236681550741
+vn -0.977205216885 -0.0514411479235 -0.205970555544
+vn -0.983707427979 -0.0420105569065 -0.174799680710
+vn -0.988857150078 -0.0373407378793 -0.144108638167
+vn -0.993213236332 -0.0312793664634 -0.112023599446
+vn -0.996381044388 -0.0284584052861 -0.0800938159227
+vn -0.998659312725 -0.0226899012923 -0.0465270765126
+vn -0.999722361565 -0.0194620639086 -0.0132883610204
+vn -0.999691843987 -0.0136858178303 0.0207088999450
+vn -0.998485565186 -0.0109420549124 0.0539165697992
+vn -0.996165692806 -0.00639955559745 0.0872527584434
+vn -0.992802560329 -0.00497300550342 0.119659818709
+vn -0.988358557224 -0.00168257229961 0.152133435011
+vn -0.982986032963 -0.00114426808432 0.183676779270
+vn -0.976600170135 0.00146822375245 0.215058133006
+vn -0.969430983067 0.00157999945804 0.245359152555
+vn -0.962869703770 0.00345707032830 0.269944608212
+vn -0.959015011787 0.00253327609971 0.283343940973
+vn -0.487451016903 -0.222639575601 -0.844288527966
+vn -0.490913689137 -0.189777657390 -0.850287079811
+vn -0.495589137077 -0.132513523102 -0.858388960361
+vn -0.497141689062 -0.106764554977 -0.861075758934
+vn -0.498128801584 -0.0864317864180 -0.862784564495
+vn -0.498595923185 -0.0748722478747 -0.863594949245
+vn -0.499008506536 -0.0629320368171 -0.864309072495
+vn -0.499156326056 -0.0580193214118 -0.864567339420
+vn -0.499367147684 -0.0502387247980 -0.864932656288
+vn -0.499429583549 -0.0477086082101 -0.865039885044
+vn -0.499611765146 -0.0393861234188 -0.865353584290
+vn -0.499684780836 -0.0354807414114 -0.865480422974
+vn -0.499838232994 -0.0255220606923 -0.865742683411
+vn -0.499887108803 -0.0214125066996 -0.865825831890
+vn -0.499963819981 -0.0120333107188 -0.865962624550
+vn -0.499976187944 -0.00959444977343 -0.865986049175
+vn -0.499999910593 -0.00117428100202 -0.866024613380
+vn -0.500000178814 4.21626900788e-05 -0.866025328636
+vn -0.499979883432 0.00885300152004 -0.865991652012
+vn -0.499975740910 0.00982583034784 -0.865983724594
+vn -0.499912530184 0.0184793658555 -0.865878820419
+vn -0.499939084053 0.0155766597018 -0.865920484066
+vn 0.150027781725 -0.177286878228 -0.972656726837
+vn 0.173485010862 -0.147677317262 -0.973701357841
+vn 0.213676974177 -0.100052133203 -0.971767306328
+vn 0.247775331140 -0.0779205486178 -0.965678989887
+vn 0.279852449894 -0.0614004395902 -0.958077549934
+vn 0.310228794813 -0.0514411516488 -0.949269115925
+vn 0.340473294258 -0.0420106463134 -0.939315259457
+vn 0.369630366564 -0.0373408608139 -0.928428351879
+vn 0.399594217539 -0.0312791801989 -0.916158258915
+vn 0.428829938173 -0.0284583121538 -0.902936935425
+vn 0.459037542343 -0.0226898640394 -0.888127148151
+vn 0.488353699446 -0.0194617323577 -0.872428834438
+vn 0.517778813839 -0.0136856567115 -0.855405151844
+vn 0.545933961868 -0.0109421061352 -0.837756872177
+vn 0.573646366596 -0.00639963475987 -0.819078207016
+vn 0.600033104420 -0.00497316569090 -0.799959778786
+vn 0.625931978226 -0.00168256345205 -0.779875874519
+vn 0.650561511517 -0.00114420009777 -0.759452760220
+vn 0.674544870853 0.00146826205309 -0.738232433796
+vn 0.697199702263 0.00157992332242 -0.716875314713
+vn 0.715213656425 0.00345695554279 -0.698897480965
+vn 0.724884748459 0.00253327074461 -0.688865482807
+vn -0.972656548023 -0.177287489176 0.150028437376
+vn -0.973701238632 -0.147677212954 0.173485606909
+vn -0.971767067909 -0.100052349269 0.213677838445
+vn -0.965678215027 -0.0779207199812 0.247778028250
+vn -0.958077728748 -0.0614006817341 0.279851615429
+vn -0.949269890785 -0.0514407046139 0.310226678848
+vn -0.939315438271 -0.0420106723905 0.340472757816
+vn -0.928429543972 -0.0373406782746 0.369627296925
+vn -0.916159451008 -0.0312791690230 0.399591743946
+vn -0.902938008308 -0.0284583494067 0.428827553988
+vn -0.888127505779 -0.0226899292320 0.459036797285
+vn -0.872427344322 -0.0194614753127 0.488356322050
+vn -0.855403304100 -0.0136856585741 0.517781615257
+vn -0.837755560875 -0.0109420092776 0.545935690403
+vn -0.819078028202 -0.00639942893758 0.573646545410
+vn -0.799963474274 -0.00497286813334 0.600028216839
+vn -0.779876172543 -0.00168248789851 0.625931620598
+vn -0.759454071522 -0.00114426482469 0.650559961796
+vn -0.738232612610 0.00146819825750 0.674544632435
+vn -0.716874778271 0.00158012914471 0.697200119495
+vn -0.698896288872 0.00345720443875 0.715214788914
+vn -0.688852369785 0.00253423722461 0.724897325039
+vn -0.844290435314 -0.222639098763 -0.487447947264
+vn -0.850287914276 -0.189777880907 -0.490912109613
+vn -0.858387470245 -0.132513359189 -0.495591610670
+vn -0.861075580120 -0.106764756143 -0.497142046690
+vn -0.862784862518 -0.0864316225052 -0.498128443956
+vn -0.863594591618 -0.0748721361160 -0.498596578836
+vn -0.864308595657 -0.0629324316978 -0.499009132385
+vn -0.864566564560 -0.0580192878842 -0.499157607555
+vn -0.864931464195 -0.0502384603024 -0.499369293451
+vn -0.865038871765 -0.0477085486054 -0.499431252480
+vn -0.865353286266 -0.0393864922225 -0.499612361193
+vn -0.865480303764 -0.0354806110263 -0.499684929848
+vn -0.865743160248 -0.0255223270506 -0.499837368727
+vn -0.865826964378 -0.0214124545455 -0.499885112047
+vn -0.865964353085 -0.0120334681123 -0.499960809946
+vn -0.865985929966 -0.00959428120404 -0.499976307154
+vn -0.866025745869 -0.00117405469064 -0.499998152256
+vn -0.866025090218 4.21065451519e-05 -0.500000536442
+vn -0.865990757942 0.00885305088013 -0.499981671572
+vn -0.865983188152 0.00982615072280 -0.499976545572
+vn -0.865877449512 0.0184796992689 -0.499914705753
+vn -0.865921080112 0.0155774476007 -0.499938040972
+vn -0.356401950121 -0.177286788821 -0.917358696461
+vn -0.336610823870 -0.147677987814 -0.929991543293
+vn -0.300834774971 -0.100052528083 -0.948413372040
+vn -0.268258213997 -0.0779211148620 -0.960190594196
+vn -0.236680760980 -0.0614006742835 -0.969645380974
+vn -0.205971792340 -0.0514409653842 -0.977204978466
+vn -0.174800440669 -0.0420105978847 -0.983707249165
+vn -0.144107177854 -0.0373411737382 -0.988857388496
+vn -0.112020626664 -0.0312793664634 -0.993213534355
+vn -0.0800935775042 -0.0284583084285 -0.996381044388
+vn -0.0465268790722 -0.0226898379624 -0.998659253120
+vn -0.0132875852287 -0.0194616485387 -0.999722361565
+vn 0.0207097530365 -0.0136856073514 -0.999691903591
+vn 0.0539172478020 -0.0109419543296 -0.998485505581
+vn 0.0872514620423 -0.00639956351370 -0.996165752411
+vn 0.119661830366 -0.00497306464240 -0.992802321911
+vn 0.152134478092 -0.00168257125188 -0.988358378410
+vn 0.183674857020 -0.00114430545364 -0.982986450195
+vn 0.215057119727 0.00146827031858 -0.976600468159
+vn 0.245359569788 0.00157993519679 -0.969430923462
+vn 0.269946515560 0.00345704518259 -0.962869167328
+vn 0.283346354961 0.00253283511847 -0.959014296532
+vn -0.767331480980 -0.177287369967 0.616255998611
+vn -0.756508469582 -0.147678166628 0.637091994286
+vn -0.734736502171 -0.100052341819 0.670933425426
+vn -0.712413907051 -0.0779209285975 0.697420001030
+vn -0.689794421196 -0.0614006593823 0.721397101879
+vn -0.666978776455 -0.0514409691095 0.743298828602
+vn -0.643234789371 -0.0420104600489 0.764515697956
+vn -0.619229853153 -0.0373405814171 0.784321427345
+vn -0.593621253967 -0.0312793366611 0.804136514664
+vn -0.567553639412 -0.0284587442875 0.822844386101
+vn -0.539623558521 -0.0226899255067 0.841600656509
+vn -0.511369347572 -0.0194617249072 0.859140694141
+vn -0.481911391020 -0.0136856427416 0.876113116741
+vn -0.452550470829 -0.0109422607347 0.891671717167
+vn -0.422520190477 -0.00639966921881 0.906330883503
+vn -0.392772495747 -0.00497314799577 0.919622242451
+vn -0.362427264452 -0.00168248475529 0.932010531425
+vn -0.332425326109 -0.00114426435903 0.943128943443
+vn -0.302054286003 0.00146826764103 0.953289568424
+vn -0.272229760885 0.00157999061048 0.962231040001
+vn -0.247654989362 0.00345695437863 0.968842148781
+vn -0.234121218324 0.00253324722871 0.972204208374
+vn -0.974900960922 -0.222638785839 3.73344981597e-08
+vn -0.981827020645 -0.189777985215 -3.86843872491e-08
+vn -0.991181254387 -0.132513150573 4.02264248578e-08
+vn -0.994284272194 -0.106764525175 0.00000000000
+vn -0.996257841587 -0.0864316225052 6.45830553481e-08
+vn -0.997193157673 -0.0748720541596 -2.22907576841e-08
+vn -0.998017728329 -0.0629322230816 1.15618625784e-07
+vn -0.998315453529 -0.0580193437636 1.68293453839e-07
+vn -0.998737215996 -0.0502384230494 -5.01461805413e-08
+vn -0.998861312866 -0.0477084740996 0.00000000000
+vn -0.999224066734 -0.0393859446049 1.38008942940e-07
+vn -0.999370336533 -0.0354805998504 1.60296082186e-07
+vn -0.999674260616 -0.0255220271647 1.85583445500e-07
+vn -0.999770700932 -0.0214124750346 2.80030320710e-07
+vn -0.999927580357 -0.0120329707861 2.11752961832e-07
+vn -0.999953985214 -0.00959464907646 1.89844513443e-07
+vn -0.999999344349 -0.00117404491175 1.23459926726e-07
+vn -1.00000000000 4.24617319368e-05 1.12159867172e-07
+vn -0.999960780144 0.00885293539613 2.46993067776e-07
+vn -0.999951720238 0.00982590578496 -2.73859459554e-08
+vn -0.999829351902 0.0184791404754 1.84561599781e-07
+vn -0.999878704548 0.0155761120841 0.00000000000
+vn -0.767331540585 -0.177287235856 -0.616256058216
+vn -0.756508529186 -0.147677615285 -0.637092053890
+vn -0.734736442566 -0.100052326918 -0.670933485031
+vn -0.712413907051 -0.0779209509492 -0.697420239449
+vn -0.689794540405 -0.0614006519318 -0.721396982670
+vn -0.666978657246 -0.0514410808682 -0.743299007416
+vn -0.643234789371 -0.0420106090605 -0.764515638351
+vn -0.619230151176 -0.0373408570886 -0.784321188927
+vn -0.593621373177 -0.0312793143094 -0.804136395454
+vn -0.567553699017 -0.0284585002810 -0.822844386101
+vn -0.539623796940 -0.0226896684617 -0.841600477695
+vn -0.511369705200 -0.0194617621601 -0.859140455723
+vn -0.481911718845 -0.0136856371537 -0.876112997532
+vn -0.452550828457 -0.0109421666712 -0.891671478748
+vn -0.422520488501 -0.00639963988215 -0.906330764294
+vn -0.392772763968 -0.00497310608625 -0.919622182846
+vn -0.362427413464 -0.00168249721173 -0.932010531425
+vn -0.332425415516 -0.00114425516222 -0.943128943443
+vn -0.302054584026 0.00146820768714 -0.953289568424
+vn -0.272229820490 0.00158006942365 -0.962231040001
+vn -0.247655063868 0.00345690944232 -0.968842148781
+vn -0.234120517969 0.00253300857730 -0.972204387188
+vn -0.356402426958 -0.177286744118 0.917358517647
+vn -0.336611419916 -0.147677987814 0.929991424084
+vn -0.300836265087 -0.100052438676 0.948412835598
+vn -0.268259018660 -0.0779210776091 0.960190296173
+vn -0.236680045724 -0.0614006407559 0.969645619392
+vn -0.205968365073 -0.0514411143959 0.977205693722
+vn -0.174799725413 -0.0420106127858 0.983707368374
+vn -0.144108295441 -0.0373410582542 0.988857150078
+vn -0.112022362649 -0.0312793515623 0.993213295937
+vn -0.0800945609808 -0.0284583382308 0.996380984783
+vn -0.0465275868773 -0.0226898491383 0.998659312725
+vn -0.0132906343788 -0.0194616578519 0.999722361565
+vn 0.0207076333463 -0.0136856175959 0.999691903591
+vn 0.0539141818881 -0.0109420241788 0.998485684395
+vn 0.0872535854578 -0.00639957608655 0.996165573597
+vn 0.119659282267 -0.00497306510806 0.992802619934
+vn 0.152134940028 -0.00168258987833 0.988358318806
+vn 0.183678939939 -0.00114433630370 0.982985675335
+vn 0.215056911111 0.00146825087722 0.976600408554
+vn 0.245358169079 0.00157991761807 0.969431281090
+vn 0.269944995642 0.00345699209720 0.962869644165
+vn 0.283344000578 0.00253276852891 0.959015071392
+vn -0.844290375710 -0.222638905048 0.487448096275
+vn -0.850288033485 -0.189777955413 0.490911930799
+vn -0.858388304710 -0.132513597608 0.495590180159
+vn -0.861075580120 -0.106764756143 0.497141897678
+vn -0.862784385681 -0.0864318311214 0.498129069805
+vn -0.863594710827 -0.0748720616102 0.498596400023
+vn -0.864309370518 -0.0629323199391 0.499007910490
+vn -0.864566206932 -0.0580193325877 0.499158382416
+vn -0.864932000637 -0.0502386800945 0.499368339777
+vn -0.865039288998 -0.0477085150778 0.499430626631
+vn -0.865353345871 -0.0393866151571 0.499612271786
+vn -0.865480363369 -0.0354805961251 0.499684721231
+vn -0.865743339062 -0.0255221687257 0.499837040901
+vn -0.865827083588 -0.0214124713093 0.499884843826
+vn -0.865961611271 -0.0120335556567 0.499965816736
+vn -0.865985333920 -0.00959432031959 0.499977231026
+vn -0.866024136543 -0.00117404700723 0.500000894070
+vn -0.866025209427 4.19442367274e-05 0.500000417233
+vn -0.865992546082 0.00885283760726 0.499978601933
+vn -0.865983426571 0.00982588063926 0.499976068735
+vn -0.865877389908 0.0184789299965 0.499914795160
+vn -0.865921258926 0.0155773786828 0.499937653542
+vn -0.972656488419 -0.177287653089 -0.150028452277
+vn -0.973701238632 -0.147677332163 -0.173485293984
+vn -0.971767127514 -0.100052557886 -0.213677570224
+vn -0.965678632259 -0.0779205113649 -0.247776508331
+vn -0.958077788353 -0.0614007301629 -0.279851436615
+vn -0.949269592762 -0.0514406040311 -0.310227781534
+vn -0.939315497875 -0.0420105643570 -0.340472698212
+vn -0.928430318832 -0.0373406410217 -0.369625240564
+vn -0.916159689426 -0.0312792994082 -0.399591207504
+vn -0.902938961983 -0.0284582804888 -0.428825676441
+vn -0.888127803802 -0.0226899627596 -0.459036231041
+vn -0.872427821159 -0.0194615591317 -0.488355547190
+vn -0.855403780937 -0.0136856241152 -0.517781078815
+vn -0.837755560875 -0.0109419971704 -0.545935928822
+vn -0.819078564644 -0.00639953045174 -0.573645710945
+vn -0.799961924553 -0.00497297989205 -0.600030243397
+vn -0.779876470566 -0.00168253050651 -0.625931322575
+vn -0.759451806545 -0.00114435423166 -0.650562584400
+vn -0.738231360912 0.00146806763951 -0.674546062946
+vn -0.716874718666 0.00157995091286 -0.697200179100
+vn -0.698896765709 0.00345724401996 -0.715214312077
+vn -0.688855290413 0.00253509194590 -0.724894404411
+vn 0.150029435754 -0.177286997437 0.972656369209
+vn 0.173483729362 -0.147677198052 0.973701596260
+vn 0.213678032160 -0.100052572787 0.971767067909
+vn 0.247781723738 -0.0779208391905 0.965677261353
+vn 0.279853284359 -0.0614006519318 0.958077251911
+vn 0.310228884220 -0.0514407493174 0.949269175529
+vn 0.340469866991 -0.0420103706419 0.939316570759
+vn 0.369624942541 -0.0373407453299 0.928430497646
+vn 0.399588733912 -0.0312794856727 0.916160702705
+vn 0.428823828697 -0.0284583494067 0.902939796448
+vn 0.459035187960 -0.0226899087429 0.888128280640
+vn 0.488354593515 -0.0194618459791 0.872428238392
+vn 0.517779648304 -0.0136857023463 0.855404615402
+vn 0.545937776566 -0.0109421052039 0.837754309177
+vn 0.573647201061 -0.00639949413016 0.819077610970
+vn 0.600027143955 -0.00497302040458 0.799964189529
+vn 0.625930905342 -0.00168259383645 0.779876828194
+vn 0.650562047958 -0.00114426715299 0.759452283382
+vn 0.674545824528 0.00146826868877 0.738231599331
+vn 0.697204351425 0.00157991272863 0.716870784760
+vn 0.715213477612 0.00345675111748 0.698897480965
+vn 0.724888801575 0.00253229099326 0.688861310482
+vn -0.487447917461 -0.222640037537 0.844290137291
+vn -0.490913033485 -0.189777940512 0.850287497044
+vn -0.495592474937 -0.132513538003 0.858387112617
+vn -0.497141242027 -0.106764785945 0.861076056957
+vn -0.498128831387 -0.0864315181971 0.862784624100
+vn -0.498596668243 -0.0748719274998 0.863594591618
+vn -0.499010741711 -0.0629322975874 0.864307761192
+vn -0.499158829451 -0.0580191314220 0.864565968513
+vn -0.499369502068 -0.0502385310829 0.864931285381
+vn -0.499432384968 -0.0477084070444 0.865038275719
+vn -0.499614119530 -0.0393862761557 0.865352213383
+vn -0.499684959650 -0.0354806147516 0.865480244160
+vn -0.499836206436 -0.0255218558013 0.865743875504
+vn -0.499884545803 -0.0214124713093 0.865827322006
+vn -0.499964475632 -0.0120330443606 0.865962326527
+vn -0.499978095293 -0.00959446746856 0.865984916687
+vn -0.499997645617 -0.00117395375855 0.866025924683
+vn -0.499999165535 4.24973550253e-05 0.866025865078
+vn -0.499982029200 0.00885314028710 0.865990519524
+vn -0.499974995852 0.00982581544667 0.865984082222
+vn -0.499915450811 0.0184791162610 0.865877091885
+vn -0.499940037727 0.0155746592209 0.865919947624
+vn -0.917359113693 -0.177287146449 0.356400877237
+vn -0.929991722107 -0.147677212954 0.336610853672
+vn -0.948413670063 -0.100052155554 0.300833731890
+vn -0.960190355778 -0.0779209807515 0.268259167671
+vn -0.969645321369 -0.0614006817341 0.236680999398
+vn -0.977205216885 -0.0514408126473 0.205970451236
+vn -0.983707487583 -0.0420104153454 0.174799531698
+vn -0.988857209682 -0.0373405963182 0.144108667970
+vn -0.993213176727 -0.0312792956829 0.112023413181
+vn -0.996381044388 -0.0284585505724 0.0800934210420
+vn -0.998659312725 -0.0226899236441 0.0465271808207
+vn -0.999722361565 -0.0194617211819 0.0132883628830
+vn -0.999691903591 -0.0136855645105 -0.0207087807357
+vn -0.998485565186 -0.0109422067180 -0.0539159588516
+vn -0.996165692806 -0.00639953929931 -0.0872527807951
+vn -0.992802500725 -0.00497311819345 -0.119660042226
+vn -0.988358557224 -0.00168252666481 -0.152133747935
+vn -0.982986330986 -0.00114424386993 -0.183675467968
+vn -0.976600527763 0.00146830815356 -0.215056762099
+vn -0.969432115555 0.00158000655938 -0.245354592800
+vn -0.962869644165 0.00345679209568 -0.269944727421
+vn -0.959014296532 0.00253280764446 -0.283346682787
+vn 0.616254568100 -0.177287310362 0.767332792282
+vn 0.637090802193 -0.147677600384 0.756509542465
+vn 0.670934677124 -0.100052282214 0.734735369682
+vn 0.697419941425 -0.0779209136963 0.712414026260
+vn 0.721396446228 -0.0614007078111 0.689794957638
+vn 0.743299245834 -0.0514411330223 0.666978359222
+vn 0.764516472816 -0.0420104824007 0.643233895302
+vn 0.784320473671 -0.0373409315944 0.619231104851
+vn 0.804136335850 -0.0312793292105 0.593621432781
+vn 0.822845220566 -0.0284582804888 0.567552745342
+vn 0.841601192951 -0.0226898267865 0.539622604847
+vn 0.859140992165 -0.0194617453963 0.511368870735
+vn 0.876112699509 -0.0136856660247 0.481911927462
+vn 0.891670525074 -0.0109420614317 0.452552735806
+vn 0.906330823898 -0.00639959098771 0.422520577908
+vn 0.919620454311 -0.00497314520180 0.392776697874
+vn 0.932009935379 -0.00168256973848 0.362428963184
+vn 0.943128228188 -0.00114425667562 0.332427352667
+vn 0.953289449215 0.00146822480019 0.302054822445
+vn 0.962230801582 0.00157999095973 0.272230595350
+vn 0.968841791153 0.00345696648583 0.247656539083
+vn 0.972202956676 0.00253281649202 0.234126314521
+vn -2.42674013862e-06 -0.222639515996 0.974900841713
+vn -5.41581925972e-07 -0.189777940512 0.981827080250
+vn -2.01132991151e-07 -0.132513314486 0.991181254387
+vn 4.16094714240e-08 -0.106764651835 0.994284391403
+vn -1.72221604089e-07 -0.0864316150546 0.996257781982
+vn 3.78943155965e-07 -0.0748721361160 0.997193157673
+vn 3.93103562146e-07 -0.0629320293665 0.998017787933
+vn -3.36586339245e-07 -0.0580193474889 0.998315453529
+vn -1.00292169236e-07 -0.0502385459840 0.998737275600
+vn 1.31243034218e-08 -0.0477084517479 0.998861312866
+vn -2.76019900269e-08 -0.0393863581121 0.999224066734
+vn -3.78882248242e-07 -0.0354806743562 0.999370336533
+vn -3.71166095192e-07 -0.0255221463740 0.999674260616
+vn -3.95336030579e-07 -0.0214124396443 0.999770700932
+vn -4.58800769820e-07 -0.0120332716033 0.999927580357
+vn -1.70859863147e-07 -0.00959446281195 0.999953985214
+vn -1.23459827250e-07 -0.00117408158258 0.999999225140
+vn 4.48638708406e-08 4.22266166424e-05 1.00000000000
+vn 0.00000000000 0.00885282363743 0.999960899353
+vn 2.73859104283e-08 0.00982582010329 0.999951720238
+vn -1.84561272931e-07 0.0184799320996 0.999829173088
+vn 5.00610838117e-07 0.0155761344358 0.999878644943
+vn -0.616255819798 -0.177287057042 0.767331779003
+vn -0.637090206146 -0.147677719593 0.756510078907
+vn -0.670934796333 -0.100052289665 0.734735369682
+vn -0.697419703007 -0.0779209211469 0.712414383888
+vn -0.721396327019 -0.0614007413387 0.689795255661
+vn -0.743298530579 -0.0514411665499 0.666979074478
+vn -0.764516472816 -0.0420104674995 0.643233835697
+vn -0.784320950508 -0.0373408868909 0.619230508804
+vn -0.804136455059 -0.0312793254852 0.593621313572
+vn -0.822845220566 -0.0284582935274 0.567552566528
+vn -0.841601431370 -0.0226898305118 0.539622247219
+vn -0.859141409397 -0.0194617249072 0.511368095875
+vn -0.876113116741 -0.0136856492609 0.481911242008
+vn -0.891671001911 -0.0109420465305 0.452551901340
+vn -0.906331062317 -0.00639958446845 0.422519832850
+vn -0.919620692730 -0.00497314240783 0.392776221037
+vn -0.932009935379 -0.00168256962206 0.362429022789
+vn -0.943128108978 -0.00114425783977 0.332427680492
+vn -0.953289508820 0.00146822491661 0.302054464817
+vn -0.962230861187 0.00157998979557 0.272230625153
+vn -0.968841612339 0.00345696834847 0.247657179832
+vn -0.972202479839 0.00253282301128 0.234128132463
+vn 0.917359054089 -0.177287355065 0.356400907040
+vn 0.929991662502 -0.147677227855 0.336611002684
+vn 0.948413550854 -0.100052095950 0.300834059715
+vn 0.960190057755 -0.0779213160276 0.268259763718
+vn 0.969645261765 -0.0614008419216 0.236681163311
+vn 0.977205216885 -0.0514407008886 0.205970570445
+vn 0.983707427979 -0.0420104414225 0.174799650908
+vn 0.988857150078 -0.0373407304287 0.144108623266
+vn 0.993213236332 -0.0312794223428 0.112023375928
+vn 0.996381044388 -0.0284587852657 0.0800934880972
+vn 0.998659312725 -0.0226899478585 0.0465270765126
+vn 0.999722361565 -0.0194618478417 0.0132883051410
+vn 0.999691843987 -0.0136856744066 -0.0207087807357
+vn 0.998485505581 -0.0109423557296 -0.0539161004126
+vn 0.996165692806 -0.00639960728586 -0.0872526466846
+vn 0.992802500725 -0.00497313961387 -0.119659803808
+vn 0.988358497620 -0.00168257451151 -0.152133673429
+vn 0.982986330986 -0.00114425772335 -0.183675169945
+vn 0.976600468159 0.00146825669799 -0.215057119727
+vn 0.969432115555 0.00157997163478 -0.245354801416
+vn 0.962869524956 0.00345689756796 -0.269945114851
+vn 0.959014534950 0.00253329286352 -0.283345818520
+vn 0.487447917461 -0.222640037537 0.844290137291
+vn 0.490912348032 -0.189777910709 0.850287854671
+vn 0.495591759682 -0.132513687015 0.858387470245
+vn 0.497141361237 -0.106764845550 0.861075878143
+vn 0.498129516840 -0.0864315256476 0.862784206867
+vn 0.498596310616 -0.0748720318079 0.863594710827
+vn 0.499008387327 -0.0629324764013 0.864308953285
+vn 0.499157935381 -0.0580192469060 0.864566504955
+vn 0.499368786812 -0.0502385795116 0.864931702614
+vn 0.499432623386 -0.0477084852755 0.865038037300
+vn 0.499614626169 -0.0393862016499 0.865351974964
+vn 0.499685466290 -0.0354806035757 0.865479886532
+vn 0.499836653471 -0.0255219507962 0.865743517876
+vn 0.499884545803 -0.0214126165956 0.865827322006
+vn 0.499963849783 -0.0120330899954 0.865962624550
+vn 0.499977946281 -0.00959454476833 0.865985035896
+vn 0.499997794628 -0.00117412861437 0.866025924683
+vn 0.499999046326 4.23503588536e-05 0.866025984287
+vn 0.499981701374 0.00885287020355 0.865990757942
+vn 0.499975323677 0.00982566922903 0.865983963013
+vn 0.499915987253 0.0184788983315 0.865876734257
+vn 0.499940067530 0.0155754517764 0.865920007229
+vn -0.150030672550 -0.177286788821 0.972656309605
+vn -0.173484951258 -0.147676765919 0.973701477051
+vn -0.213678732514 -0.100052513182 0.971766889095
+vn -0.247781664133 -0.0779208168387 0.965677261353
+vn -0.279852479696 -0.0614007115364 0.958077549934
+vn -0.310228824615 -0.0514409318566 0.949269235134
+vn -0.340471655130 -0.0420103892684 0.939315795898
+vn -0.369623869658 -0.0373407304287 0.928430855274
+vn -0.399589449167 -0.0312794484198 0.916160404682
+vn -0.428823530674 -0.0284583456814 0.902939975262
+vn -0.459034383297 -0.0226899180561 0.888128697872
+vn -0.488353699446 -0.0194617882371 0.872428774834
+vn -0.517778813839 -0.0136856650934 0.855405151844
+vn -0.545936942101 -0.0109420828521 0.837754845619
+vn -0.573647797108 -0.00639949552715 0.819077134132
+vn -0.600027501583 -0.00497304135934 0.799964010715
+vn -0.625930607319 -0.00168266857509 0.779876947403
+vn -0.650561571121 -0.00114432000555 0.759452760220
+vn -0.674546122551 0.00146825343836 0.738231241703
+vn -0.697204351425 0.00157993112225 0.716870725155
+vn -0.715213656425 0.00345677370206 0.698897480965
+vn -0.724888443947 0.00253264582716 0.688861608505
+vn 0.972656488419 -0.177287489176 -0.150028675795
+vn 0.973701238632 -0.147677093744 -0.173485875130
+vn 0.971767067909 -0.100052461028 -0.213677808642
+vn 0.965678393841 -0.0779210254550 -0.247777611017
+vn 0.958077847958 -0.0614005215466 -0.279851406813
+vn 0.949269831181 -0.0514413602650 -0.310226619244
+vn 0.939315617085 -0.0420107059181 -0.340472102165
+vn 0.928430080414 -0.0373407751322 -0.369625985622
+vn 0.916159987450 -0.0312792062759 -0.399590522051
+vn 0.902937650681 -0.0284584499896 -0.428828388453
+vn 0.888127088547 -0.0226901043206 -0.459037512541
+vn 0.872427344322 -0.0194617304951 -0.488356322050
+vn 0.855403661728 -0.0136855300516 -0.517781078815
+vn 0.837755680084 -0.0109420018271 -0.545935630798
+vn 0.819079279900 -0.00639957981184 -0.573644638062
+vn 0.799961924553 -0.00497315824032 -0.600030243397
+vn 0.779876708984 -0.00168263365049 -0.625931084156
+vn 0.759451270103 -0.00114398729056 -0.650563240051
+vn 0.738230705261 0.00146848720033 -0.674546778202
+vn 0.716874778271 0.00158012902830 -0.697200119495
+vn 0.698896348476 0.00345661933534 -0.715214729309
+vn 0.688852727413 0.00253032799810 -0.724896967411
+vn 0.844290494919 -0.222638726234 0.487447857857
+vn 0.850288033485 -0.189777776599 0.490912199020
+vn 0.858387410641 -0.132513850927 0.495591640472
+vn 0.861075282097 -0.106764860451 0.497142553329
+vn 0.862784385681 -0.0864317640662 0.498129099607
+vn 0.863594710827 -0.0748720318079 0.498596280813
+vn 0.864308953285 -0.0629320591688 0.499008625746
+vn 0.864566266537 -0.0580192767084 0.499158203602
+vn 0.864931046963 -0.0502385161817 0.499370068312
+vn 0.865039288998 -0.0477087125182 0.499430656433
+vn 0.865353226662 -0.0393865555525 0.499612390995
+vn 0.865480542183 -0.0354808308184 0.499684542418
+vn 0.865744113922 -0.0255223307759 0.499835610390
+vn 0.865826904774 -0.0214124675840 0.499885320663
+vn 0.865961015224 -0.0120332064107 0.499966889620
+vn 0.865984976292 -0.00959448423237 0.499977856874
+vn 0.866023898125 -0.00117411150131 0.500001132488
+vn 0.866025269032 4.25050202466e-05 0.500000178814
+vn 0.865992784500 0.00885278824717 0.499978184700
+vn 0.865983545780 0.00982597190887 0.499976009130
+vn 0.865877330303 0.0184804629534 0.499914765358
+vn 0.865920960903 0.0155739746988 0.499938309193
+vn 0.356400489807 -0.177286833525 0.917359292507
+vn 0.336610853672 -0.147677436471 0.929991662502
+vn 0.300834685564 -0.100052364171 0.948413372040
+vn 0.268258184195 -0.0779206901789 0.960190534592
+vn 0.236681550741 -0.0614007487893 0.969645202160
+vn 0.205973491073 -0.0514410547912 0.977204561234
+vn 0.174799472094 -0.0420106239617 0.983707427979
+vn 0.144107162952 -0.0373408161104 0.988857328892
+vn 0.112022116780 -0.0312793031335 0.993213295937
+vn 0.0800933390856 -0.0284582842141 0.996381044388
+vn 0.0465267971158 -0.0226899478585 0.998659253120
+vn 0.0132875852287 -0.0194617751986 0.999722361565
+vn -0.0207077302039 -0.0136856706813 0.999691843987
+vn -0.0539151653647 -0.0109419934452 0.998485624790
+vn -0.0872538089752 -0.00639955513179 0.996165513992
+vn -0.119659669697 -0.00497306464240 0.992802619934
+vn -0.152135610580 -0.00168257323094 0.988358259201
+vn -0.183679163456 -0.00114423083141 0.982985615730
+vn -0.215057164431 0.00146824994590 0.976600408554
+vn -0.245359569788 0.00157998944633 0.969430923462
+vn -0.269945472479 0.00345669803210 0.962869405746
+vn -0.283346354961 0.00253234663978 0.959014296532
+vn 0.678996086121 0.0558843128383 -0.732011795044
+vn 0.644464015961 0.0850922688842 -0.759885251522
+vn 0.553883612156 0.0958956256509 -0.827053129673
+vn 0.525949597359 -0.0189798474312 -0.850303888321
+vn 0.997015833855 0.0771490335464 -0.00272549968213
+vn 0.511859059334 0.0465186871588 0.857809007168
+vn 0.545941770077 0.0791255310178 0.834078311920
+vn 0.619526624680 0.101438589394 0.778393924236
+vn 0.650599539280 0.0616454817355 0.756914794445
+vn 0.676973700523 0.0368419475853 -0.735084593296
+vn 0.646110057831 0.0466747060418 -0.761815786362
+vn 0.525266468525 0.0625062137842 -0.848639011383
+vn 0.474311649799 0.0318321213126 -0.879781305790
+vn 0.998326361179 0.0577691346407 0.00267354189418
+vn 0.488705933094 0.0641476884484 0.870087087154
+vn 0.528004765511 0.0857260227203 0.844903588295
+vn 0.608886301517 0.0508919544518 0.791623234749
+vn 0.632263720036 0.0106245521456 0.774680435658
+vn 0.647638142109 0.0320448391140 -0.761273801327
+vn 0.619236767292 0.00999107770622 -0.785140693188
+vn 0.546302616596 0.0255463644862 -0.837198197842
+vn 0.451545774937 0.0703845247626 -0.889467477798
+vn 0.996682882309 0.0792019590735 -0.0187166091055
+vn 0.482218593359 0.00464273616672 0.876038610935
+vn 0.548051655293 0.0270831752568 0.836005926132
+vn 0.616759955883 -0.00885642971843 0.787101566792
+vn 0.627863347530 0.0663627460599 0.775489211082
+vn 0.539486050606 -0.0670673847198 -0.839319169521
+vn 0.638468086720 0.0344433784485 -0.768877208233
+vn 0.572472929955 0.0726887732744 -0.816695213318
+vn 0.451976865530 0.0584128648043 -0.890115082264
+vn 0.993348360062 0.0891158431768 -0.0729206800461
+vn 0.469269156456 0.0367832072079 0.882288813591
+vn 0.523576140404 0.0697502791882 0.849118947983
+vn 0.611480951309 0.0478387549520 0.789811611176
+vn 0.432084858418 0.0162451472133 0.901686608791
+vn 0.725751042366 0.0601241029799 -0.685325026512
+vn 0.713347315788 0.0168958753347 -0.700607120991
+vn 0.545757770538 0.0111744469032 -0.837868511677
+vn 0.426020383835 0.0299144051969 -0.904218852520
+vn 0.994556486607 0.0898369401693 -0.0527888834476
+vn 0.422086715698 0.0500904098153 0.905170619488
+vn 0.509943902493 0.0325761958957 0.859590649605
+vn 0.695009589195 0.0260060280561 0.718529999256
+vn 0.635862946510 0.0882048159838 0.766745209694
+vn 0.487917840481 0.0598818734288 -0.870833098888
+vn 0.632084965706 0.0416522137821 -0.773778855801
+vn 0.574342906475 0.0471926294267 -0.817253410816
+vn 0.477901518345 0.0188099406660 -0.878211915493
+vn 0.995788514614 0.0637718290091 -0.0658665150404
+vn 0.464229196310 0.0531505569816 0.884118914604
+vn 0.528756618500 0.0407504886389 0.847794711590
+vn 0.605133533478 0.0494612529874 0.794586062431
+vn 0.296222060919 0.0977078899741 0.950108230114
+vn 0.692387700081 0.0331968925893 -0.720761537552
+vn 0.733851850033 -0.0441599749029 -0.677872776985
+vn 0.512248098850 0.0260561574250 -0.858442127705
+vn 0.388093739748 0.0141800511628 -0.921510875225
+vn 0.999217569828 0.0355870686471 -0.0172568988055
+vn 0.412354022264 0.0312420502305 0.910487830639
+vn 0.526606261730 -0.00815998762846 0.850070178509
+vn 0.718459606171 -0.0491339825094 0.693831205368
+vn 0.623314023018 0.0336316041648 0.781248092651
+vn 0.285026490688 0.138744547963 -0.948424935341
+vn 0.647428750992 0.0401113368571 -0.761069774628
+vn 0.617735981941 0.0124596506357 -0.786286950111
+vn 0.426145136356 0.0337701402605 -0.904024362564
+vn 0.997337698936 0.0422654673457 -0.0594245456159
+vn 0.475148975849 0.0405672304332 0.878969728947
+vn 0.600792706013 0.0632947534323 0.796895205975
+vn 0.594974994659 0.0866550579667 0.799059152603
+vn 0.166049987078 0.191702231765 0.967304348946
+vn 0.685758352280 0.0360955931246 -0.726933717728
+vn 0.743474364281 -0.0195984970778 -0.668477118015
+vn 0.514822363853 -0.00509035773575 -0.857281863689
+vn 0.384606093168 -0.0163278244436 -0.922936439514
+vn 0.999013304710 0.0428509563208 -0.0116728991270
+vn 0.321824699640 0.0356753356755 0.946126937866
+vn 0.498762398958 0.0333558954298 0.866096615791
+vn 0.731668353081 -0.0190447941422 0.681394636631
+vn 0.616785049438 0.0365872345865 0.786280870438
+vn 0.217327073216 0.163509145379 -0.962306439877
+vn 0.632550597191 0.0554836541414 -0.772529125214
+vn 0.587917685509 0.0590886846185 -0.806759834290
+vn 0.424071043730 0.0465338937938 -0.904432654381
+vn 0.996014297009 0.0888703688979 0.00757880136371
+vn 0.451264739037 0.0544503182173 0.890727400780
+vn 0.641621589661 0.0210073869675 0.766733646393
+vn 0.574202239513 0.0535238310695 0.816962063313
+vn 0.124863803387 0.178745746613 0.975940048695
+vn 0.651829898357 0.0257484335452 -0.757927954197
+vn 0.781316876411 -0.0268940944225 -0.623554885387
+vn 0.513296246529 0.0212372336537 -0.857948720455
+vn 0.281809747219 0.0332438014448 -0.958894193172
+vn 0.997653484344 0.0664023086429 -0.0166782159358
+vn 0.339672029018 0.0117608914152 0.940470397472
+vn 0.507885694504 0.0335067063570 0.860772550106
+vn 0.693847656250 0.00530383037403 0.720102369785
+vn 0.595408737659 0.0384130515158 0.802504122257
+vn 0.135900065303 0.161013334990 -0.977550923824
+vn 0.621468365192 0.0260053705424 -0.783007562160
+vn 0.665714681149 -0.0131523367018 -0.746090531349
+vn 0.437387496233 -0.00133382144850 -0.899272143841
+vn 0.996432244778 0.0548988580704 -0.0641012936831
+vn 0.494419872761 -0.00732906628400 0.869192242622
+vn 0.608475387096 -0.0132980830967 0.793461322784
+vn 0.525029957294 0.0220762100071 0.850797355175
+vn 0.102979212999 0.153558149934 0.982758939266
+vn 0.618459463120 0.0630817264318 -0.783280670643
+vn 0.731647491455 0.0588666722178 -0.679136753082
+vn 0.486582934856 0.0449284389615 -0.872478365898
+vn 0.321606278419 0.0206467434764 -0.946648359299
+vn 0.995635390282 0.0791907459497 -0.0493883341551
+vn 0.390139013529 0.0473949499428 0.919535338879
+vn 0.450172930956 0.0560110397637 0.891183018684
+vn 0.620029866695 0.0518754497170 0.782861292362
+vn 0.548123717308 0.0483020320535 0.835001468658
+vn 0.199973255396 0.0403376445174 -0.978970646858
+vn 0.589808821678 -0.00221280404367 -0.807539939880
+vn 0.557610273361 0.00141536502633 -0.830101668835
+vn 0.436580806971 0.00882039964199 -0.899621844292
+vn 0.997122049332 0.0553025081754 -0.0518588647246
+vn 0.513905704021 0.0194100961089 0.857627093792
+vn 0.572665691376 0.00515187950805 0.819772779942
+vn 0.491273701191 0.0204437114298 0.870765268803
+vn 0.194005876780 0.104503110051 0.975418329239
+vn 0.700078964233 0.0454755201936 -0.712615907192
+vn 0.787723362446 0.0269643869251 -0.615438580513
+vn 0.426052302122 0.00837490055710 -0.904659807682
+vn 0.349868714809 -0.0190906655043 -0.936604261398
+vn 0.999026834965 0.0408961884677 -0.0165212526917
+vn 0.446840554476 0.0473698116839 0.893358528614
+vn 0.423653870821 0.0641460865736 0.903550088406
+vn 0.573794424534 0.0922283604741 0.813789844513
+vn 0.516985416412 0.0873600915074 0.851524710655
+vn 0.233557939529 0.0738290399313 -0.969535946846
+vn 0.550873696804 -0.0246426034719 -0.834224820137
+vn 0.390067040920 -0.0443031452596 -0.919720113277
+vn 0.499873012304 -0.0148821901530 -0.865970849991
+vn 0.994759857655 0.0593918524683 0.0832194760442
+vn 0.496045053005 0.0386153012514 0.867437660694
+vn 0.429347991943 0.0369929187000 0.902381241322
+vn 0.472119718790 0.00470737367868 0.881521761417
+vn 0.231268957257 0.0131295500323 0.972801268101
+vn 0.665668666363 0.0582577437162 -0.743969976902
+vn 0.744585096836 0.0662598609924 -0.664230823517
+vn 0.405180513859 0.0682398080826 -0.911686420441
+vn 0.512100398540 0.0661249160767 -0.856376528740
+vn 0.995331704617 0.0783620998263 0.0563417226076
+vn 0.441968530416 0.0520116239786 0.895521342754
+vn 0.455341994762 0.0601960197091 0.888279259205
+vn 0.727919578552 0.0435968600214 0.684275090694
+vn 0.560082495213 0.0546936802566 0.826629459858
+vn 0.438679039478 0.00357305933721 -0.898636698723
+vn 0.594414889812 -0.0318729840219 -0.803526699543
+vn 0.331690460443 -0.0276674944907 -0.942982554436
+vn 0.483373194933 -0.000643678533379 -0.875414133072
+vn 0.999234020710 0.0351815447211 -0.0171397682279
+vn 0.467841416597 0.0167629215866 0.883653342724
+vn 0.412331342697 -0.00451736245304 0.911022782326
+vn 0.517396450043 0.0239238142967 0.855411410332
+vn 0.253709256649 0.0745846629143 0.964400768280
+vn 0.676647722721 0.0330982431769 -0.735562622547
+vn 0.801747739315 0.0258804112673 -0.597101926804
+vn 0.492150038481 0.0378543175757 -0.869686961174
+vn 0.642319619656 0.0338913239539 -0.765687167645
+vn 0.998006939888 0.0566876307130 0.0277218259871
+vn 0.558649241924 0.0432637743652 0.828274846077
+vn 0.434808820486 0.0498104542494 0.899144172668
+vn 0.612037897110 0.0540320239961 0.788980424404
+vn 0.535643756390 0.0447993576527 0.843254923820
+vn 0.445415556431 0.0306468252093 -0.894799292088
+vn 0.604228496552 -0.00605557952076 -0.796788036823
+vn 0.244463279843 -0.0368076972663 -0.968959748745
+vn 0.433315634727 -0.0304121300578 -0.900729000568
+vn 0.998732388020 0.00593701004982 -0.0499833934009
+vn 0.454290777445 -0.0120483944193 0.890771985054
+vn 0.309010326862 -0.00628085294738 0.951038002968
+vn 0.484044790268 0.00232011382468 0.875040233135
+vn 0.382946789265 0.0103605715558 0.923712253571
+vn 0.690666258335 -0.0224884096533 -0.722823917866
+vn 0.654208719730 -0.00799604877830 -0.756271719933
+vn 0.383734583855 -0.0158001258969 -0.923308312893
+vn 0.685342967510 0.0110720377415 -0.728136241436
+vn 0.999007105827 0.0396036393940 -0.0204015355557
+vn 0.564336895943 0.00544703612104 0.825526595116
+vn 0.321980655193 0.000859862368088 0.946745872498
+vn 0.583606064320 -0.00254001747817 0.812032997608
+vn 0.596423268318 -0.00835636164993 0.802626669407
+vn 0.689261376858 0.0955396220088 -0.718185782433
+vn 0.548291563988 0.0813451707363 -0.832321763039
+vn 0.281565189362 0.0649967789650 -0.957338213921
+vn 0.516084134579 0.0620697885752 -0.854285955429
+vn 0.983351767063 0.0938191711903 -0.155618727207
+vn 0.533085107803 0.0678322613239 0.843338131905
+vn 0.305721223354 0.0458007454872 0.951018869877
+vn 0.498923599720 0.0551496185362 0.864889562130
+vn 0.468596309423 0.0678290575743 0.880804598331
+vn 0.731612920761 -0.0847541987896 -0.676431298256
+vn 0.573461890221 -0.0831703990698 -0.814999461174
+vn 0.382799595594 -0.0791279971600 -0.920436501503
+vn 0.630774676800 -0.0599679388106 -0.773645401001
+vn 0.999186277390 -0.00386317749508 -0.0401482991874
+vn 0.673433959484 0.0147010739893 0.739101171494
+vn 0.406598180532 -0.0144026810303 0.913493514061
+vn 0.533201158047 -0.0235802903771 0.845659732819
+vn 0.606908321381 -0.0273393467069 0.794301450253
+vn 0.756078124046 0.101299531758 -0.646594345570
+vn 0.539679169655 0.0840072780848 -0.837668955326
+vn 0.365688860416 0.0723952725530 -0.927917361259
+vn 0.564110398293 0.0478517636657 -0.824311614037
+vn 0.994989275932 0.0335866995156 0.0941711440682
+vn 0.613699913025 0.0383468084037 0.788607716560
+vn 0.503276467323 0.0588023476303 0.862122476101
+vn 0.443567872047 0.0814440250397 0.892532646656
+vn 0.516670823097 0.129410475492 0.846347630024
+vn 0.805353224277 -0.0847905278206 -0.586699962616
+vn 0.540671169758 -0.0868508294225 -0.836738705635
+vn 0.355022072792 -0.0772871524096 -0.931657731533
+vn 0.218086823821 -0.0642571672797 -0.973811686039
+vn 0.999804794788 0.00421729218215 -0.0193008463830
+vn 0.496935874224 0.0193760059774 0.867570936680
+vn 0.336707264185 0.00641398457810 0.941587507725
+vn 0.258412957191 -0.00129659299273 0.966033697128
+vn 0.564170777798 -0.0193973649293 0.825430274010
+vn 0.984472453594 0.0525561086833 -0.167486831546
+vn 0.622862160206 -0.0189978852868 -0.782100856304
+vn 0.554241418839 -0.0416756570339 -0.831311941147
+vn 0.647701442242 -0.0124261723831 -0.761792957783
+vn 0.962451636791 0.0428218282759 0.268054008484
+vn 0.613955378532 0.0368671268225 0.788479328156
+vn 0.593953549862 0.0297200679779 0.803950250149
+vn 0.551460981369 0.0146274315193 0.834072411060
+vn 0.902568161488 0.00291660381481 0.430537104607
+vn 0.698008596897 0.419377356768 -0.580436646938
+vn 0.273388713598 0.273802429438 -0.922112226486
+vn 0.391181647778 0.236710920930 -0.889350771904
+vn 0.519635856152 0.206597283483 -0.829033195972
+vn 0.986614882946 0.124664098024 0.105118565261
+vn 0.527243852615 0.0331775024533 0.849066019058
+vn 0.416976153851 0.0962260141969 0.903809309006
+vn 0.403472930193 0.139349550009 0.904318094254
+vn 0.715100228786 0.203261643648 0.668817222118
+vn -0.732012033463 0.0558844655752 -0.678995728493
+vn -0.759885430336 0.0850924104452 -0.644463777542
+vn -0.827053129673 0.0958955809474 -0.553883612156
+vn -0.850303947926 -0.0189799070358 -0.525949537754
+vn -0.00272546848282 0.0771490260959 -0.997015893459
+vn 0.857809007168 0.0465187318623 -0.511858940125
+vn 0.834078311920 0.0791255459189 -0.545941829681
+vn 0.778393864632 0.101439006627 -0.619526505470
+vn 0.756914734840 0.0616457238793 -0.650599777699
+vn -0.735084652901 0.0368419475853 -0.676973640919
+vn -0.761815905571 0.0466746985912 -0.646109998226
+vn -0.848639070988 0.0625062510371 -0.525266349316
+vn -0.879781365395 0.0318321138620 -0.474311709404
+vn 0.00267354166135 0.0577691644430 -0.998326361179
+vn 0.870087146759 0.0641476958990 -0.488705962896
+vn 0.844903528690 0.0857259631157 -0.528004765511
+vn 0.791623234749 0.0508920475841 -0.608886361122
+vn 0.774680078030 0.0106242271140 -0.632264018059
+vn -0.761273860931 0.0320447422564 -0.647638201714
+vn -0.785140633583 0.00999096687883 -0.619236826897
+vn -0.837198197842 0.0255463887006 -0.546302556992
+vn -0.889467477798 0.0703845173120 -0.451545774937
+vn -0.0187166258693 0.0792019888759 -0.996682882309
+vn 0.876038610935 0.00464269286022 -0.482218652964
+vn 0.836005926132 0.0270831789821 -0.548051655293
+vn 0.787101566792 -0.00885630771518 -0.616759955883
+vn 0.775489211082 0.0663627982140 -0.627863466740
+vn -0.839319288731 -0.0670671463013 -0.539485991001
+vn -0.768877267838 0.0344434380531 -0.638467967510
+vn -0.816695213318 0.0726887062192 -0.572472870350
+vn -0.890115141869 0.0584128648043 -0.451976716518
+vn -0.0729207322001 0.0891158431768 -0.993348419666
+vn 0.882288753986 0.0367831997573 -0.469269216061
+vn 0.849118947983 0.0697502791882 -0.523576200008
+vn 0.789811611176 0.0478387549520 -0.611480951309
+vn 0.901686549187 0.0162452291697 -0.432085037231
+vn -0.685325086117 0.0601241104305 -0.725751042366
+vn -0.700607061386 0.0168959498405 -0.713347315788
+vn -0.837868511677 0.0111744636670 -0.545757770538
+vn -0.904218912125 0.0299144145101 -0.426020383835
+vn -0.0527888610959 0.0898369401693 -0.994556546211
+vn 0.905170559883 0.0500904545188 -0.422086626291
+vn 0.859590768814 0.0325761996210 -0.509943842888
+vn 0.718530058861 0.0260060355067 -0.695009469986
+vn 0.766745090485 0.0882048606873 -0.635863006115
+vn -0.870833277702 0.0598816424608 -0.487917542458
+vn -0.773778796196 0.0416521802545 -0.632084965706
+vn -0.817253351212 0.0471926033497 -0.574342906475
+vn -0.878211975098 0.0188099574298 -0.477901488543
+vn -0.0658666864038 0.0637717321515 -0.995788514614
+vn 0.884118855000 0.0531505495310 -0.464229226112
+vn 0.847794651985 0.0407504998147 -0.528756678104
+vn 0.794586002827 0.0494612716138 -0.605133593082
+vn 0.950108170509 0.0977079421282 -0.296222299337
+vn -0.720761656761 0.0331969074905 -0.692387640476
+vn -0.677872717381 -0.0441599003971 -0.733851730824
+vn -0.858442187309 0.0260562039912 -0.512248039246
+vn -0.921510934830 0.0141800623387 -0.388093501329
+vn -0.0172570087016 0.0355870686471 -0.999217569828
+vn 0.910487890244 0.0312420632690 -0.412353843451
+vn 0.850070238113 -0.00815997645259 -0.526606261730
+vn 0.693831205368 -0.0491340011358 -0.718459546566
+vn 0.781247973442 0.0336315296590 -0.623314082623
+vn -0.948424935341 0.138744711876 -0.285026431084
+vn -0.761069715023 0.0401113033295 -0.647428691387
+vn -0.786286890507 0.0124594774097 -0.617735922337
+vn -0.904024422169 0.0337701216340 -0.426144987345
+vn -0.0594245120883 0.0422655269504 -0.997337698936
+vn 0.878969609737 0.0405672825873 -0.475149035454
+vn 0.796895146370 0.0632948949933 -0.600792646408
+vn 0.799059331417 0.0866549685597 -0.594974935055
+vn 0.967304289341 0.191702216864 -0.166050016880
+vn -0.726933538914 0.0360956229270 -0.685758531094
+vn -0.668476879597 -0.0195985045284 -0.743474721909
+vn -0.857281804085 -0.00509040290490 -0.514822423458
+vn -0.922936379910 -0.0163278598338 -0.384606182575
+vn -0.0116731440648 0.0428509078920 -0.999013245106
+vn 0.946126759052 0.0356753654778 -0.321824878454
+vn 0.866096615791 0.0333559215069 -0.498762577772
+vn 0.681394875050 -0.0190449282527 -0.731668114662
+vn 0.786280989647 0.0365869142115 -0.616784930229
+vn -0.962306320667 0.163509175181 -0.217327713966
+vn -0.772529006004 0.0554836280644 -0.632550835609
+vn -0.806760132313 0.0590888075531 -0.587917208672
+vn -0.904432654381 0.0465339273214 -0.424071073532
+vn 0.00757855596021 0.0888703837991 -0.996014297009
+vn 0.890727460384 0.0544502772391 -0.451264619827
+vn 0.766733467579 0.0210072025657 -0.641621768475
+vn 0.816961944103 0.0535238124430 -0.574202358723
+vn 0.975940048695 0.178745493293 -0.124864153564
+vn -0.757927954197 0.0257483087480 -0.651829898357
+vn -0.623555123806 -0.0268942452967 -0.781316697598
+vn -0.857948780060 0.0212372802198 -0.513296067715
+vn -0.958894193172 0.0332439169288 -0.281809687614
+vn -0.0166782457381 0.0664025321603 -0.997653543949
+vn 0.940470397472 0.0117609677836 -0.339671969414
+vn 0.860772490501 0.0335067808628 -0.507885694504
+vn 0.720102369785 0.00530379405245 -0.693847537041
+vn 0.802504241467 0.0384131334722 -0.595408678055
+vn -0.977551043034 0.161013349891 -0.135900005698
+vn -0.783007681370 0.0260053556412 -0.621468126774
+vn -0.746090412140 -0.0131524484605 -0.665714740753
+vn -0.899272143841 -0.00133385160007 -0.437387406826
+vn -0.0641013160348 0.0548989176750 -0.996432125568
+vn 0.869192242622 -0.00732901785523 -0.494419991970
+vn 0.793461441994 -0.0132978688926 -0.608475208282
+vn 0.850797533989 0.0220762118697 -0.525029838085
+vn 0.982758939266 0.153558343649 -0.102979384363
+vn -0.783280551434 0.0630817413330 -0.618459582329
+vn -0.679136812687 0.0588668473065 -0.731647312641
+vn -0.872478246689 0.0449284128845 -0.486583054066
+vn -0.946648240089 0.0206466931850 -0.321606487036
+vn -0.0493882037699 0.0791907012463 -0.995635330677
+vn 0.919535219669 0.0473949089646 -0.390139311552
+vn 0.891182959080 0.0560110211372 -0.450173020363
+vn 0.782861053944 0.0518753938377 -0.620030164719
+vn 0.835001170635 0.0483020208776 -0.548124015331
+vn -0.978970527649 0.0403376482427 -0.199973732233
+vn -0.807539701462 -0.00221269694157 -0.589809119701
+vn -0.830101907253 0.00141532381531 -0.557610034943
+vn -0.899621963501 0.00882037729025 -0.436580568552
+vn -0.0518587455153 0.0553025566041 -0.997121989727
+vn 0.857627034187 0.0194100830704 -0.513905823231
+vn 0.819772958755 0.00515191722661 -0.572665452957
+vn 0.870765209198 0.0204437356442 -0.491273939610
+vn 0.975418210030 0.104503080249 -0.194006130099
+vn -0.712616205215 0.0454756580293 -0.700078606606
+vn -0.615438520908 0.0269645769149 -0.787723481655
+vn -0.904659807682 0.00837489683181 -0.426052391529
+vn -0.936604022980 -0.0190907418728 -0.349869161844
+vn -0.0165215898305 0.0408960916102 -0.999026834965
+vn 0.893358528614 0.0473698750138 -0.446840852499
+vn 0.903549849987 0.0641461163759 -0.423654198647
+vn 0.813789844513 0.0922283008695 -0.573794484138
+vn 0.851524949074 0.0873599871993 -0.516985058784
+vn -0.969536066055 0.0738288983703 -0.233557492495
+vn -0.834225118160 -0.0246425960213 -0.550873160362
+vn -0.919720113277 -0.0443032048643 -0.390067040920
+vn -0.865970671177 -0.0148822460324 -0.499873399734
+vn 0.0832187309861 0.0593918971717 -0.994759917259
+vn 0.867437481880 0.0386153347790 -0.496045351028
+vn 0.902381300926 0.0369929298759 -0.429347813129
+vn 0.881521940231 0.00470735831186 -0.472119569778
+vn 0.972801148891 0.0131294857711 -0.231269314885
+vn -0.743970632553 0.0582577027380 -0.665667891502
+vn -0.664231181145 0.0662596523762 -0.744584918022
+vn -0.911686539650 0.0682397112250 -0.405180305243
+vn -0.856376409531 0.0661247596145 -0.512100398540
+vn 0.0563419312239 0.0783620923758 -0.995331585407
+vn 0.895521342754 0.0520115755498 -0.441968590021
+vn 0.888279318810 0.0601960085332 -0.455341875553
+vn 0.684275090694 0.0435969494283 -0.727919459343
+vn 0.826629281044 0.0546935573220 -0.560082674026
+vn -0.898637175560 0.00357314175926 -0.438678115606
+vn -0.803527176380 -0.0318730622530 -0.594414234161
+vn -0.942982614040 -0.0276676006615 -0.331690162420
+vn -0.875414252281 -0.000643759150989 -0.483372896910
+vn -0.0171396229416 0.0351815409958 -0.999233961105
+vn 0.883653223515 0.0167628992349 -0.467841804028
+vn 0.911023080349 -0.00451727490872 -0.412330746651
+vn 0.855411529541 0.0239237714559 -0.517396211624
+vn 0.964400470257 0.0745841190219 -0.253710210323
+vn -0.735562920570 0.0330980010331 -0.676647365093
+vn -0.597102880478 0.0258806906641 -0.801747083664
+vn -0.869687020779 0.0378543250263 -0.492149978876
+vn -0.765687346458 0.0338914506137 -0.642319560051
+vn 0.0277213398367 0.0566876046360 -0.998007118702
+vn 0.828274607658 0.0432636737823 -0.558649599552
+vn 0.899144291878 0.0498104877770 -0.434808403254
+vn 0.788980662823 0.0540319830179 -0.612037658691
+vn 0.843254804611 0.0447992086411 -0.535643935204
+vn -0.894799411297 0.0306459721178 -0.445415198803
+vn -0.796787679195 -0.00605546496809 -0.604229092598
+vn -0.968959450722 -0.0368078090250 -0.244463920593
+vn -0.900729119778 -0.0304121524096 -0.433315217495
+vn -0.0499841533601 0.00593699095771 -0.998732388020
+vn 0.890771985054 -0.0120485918596 -0.454290747643
+vn 0.951038002968 -0.00628095446154 -0.309010237455
+vn 0.875039994717 0.00232008262537 -0.484045118093
+vn 0.923712253571 0.0103603349999 -0.382946729660
+vn -0.722823560238 -0.0224883724004 -0.690666675568
+vn -0.756270945072 -0.00799544062465 -0.654209673405
+vn -0.923308312893 -0.0158000327647 -0.383734583855
+vn -0.728135824203 0.0110718123615 -0.685343444347
+vn -0.0204012822360 0.0396036431193 -0.999007165432
+vn 0.825526356697 0.00544678885490 -0.564337313175
+vn 0.946745812893 0.000859745079651 -0.321980923414
+vn 0.812032699585 -0.00254024611786 -0.583606481552
+vn 0.802626788616 -0.00835650414228 -0.596422910690
+vn -0.718186676502 0.0955394133925 -0.689260661602
+vn -0.832321822643 0.0813452154398 -0.548291206360
+vn -0.957338333130 0.0649969577789 -0.281564623117
+vn -0.854285478592 0.0620698556304 -0.516084849834
+vn -0.155619710684 0.0938192158937 -0.983351647854
+vn 0.843338310719 0.0678321719170 -0.533084750175
+vn 0.951019048691 0.0458009280264 -0.305720955133
+vn 0.864889264107 0.0551496073604 -0.498923927546
+vn 0.880804955959 0.0678292438388 -0.468595415354
+vn -0.676431655884 -0.0847542434931 -0.731612503529
+vn -0.814999222755 -0.0831703245640 -0.573462307453
+vn -0.920436382294 -0.0791279822588 -0.382799655199
+vn -0.773645043373 -0.0599679611623 -0.630775153637
+vn -0.0401482097805 -0.00386319006793 -0.999186217785
+vn 0.739101111889 0.0147010181099 -0.673434019089
+vn 0.913493394852 -0.0144026121125 -0.406598627567
+vn 0.845659017563 -0.0235803145915 -0.533202409744
+vn 0.794301152229 -0.0273393075913 -0.606908738613
+vn -0.646594345570 0.101299814880 -0.756078004837
+vn -0.837668538094 0.0840072929859 -0.539679706097
+vn -0.927917838097 0.0723952576518 -0.365687578917
+vn -0.824311614037 0.0478518456221 -0.564110517502
+vn 0.0941733494401 0.0335867963731 -0.994989097118
+vn 0.788607597351 0.0383468084037 -0.613700032234
+vn 0.862122833729 0.0588023215532 -0.503275752068
+vn 0.892532527447 0.0814440175891 -0.443567931652
+vn 0.846348106861 0.129410192370 -0.516670107841
+vn -0.586699068546 -0.0847906246781 -0.805353760719
+vn -0.836737096310 -0.0868509709835 -0.540673613548
+vn -0.931657552719 -0.0772872865200 -0.355022400618
+vn -0.973811745644 -0.0642567351460 -0.218086481094
+vn -0.0193012394011 0.00421735038981 -0.999804794788
+vn 0.867570459843 0.0193760413677 -0.496936827898
+vn 0.941587746143 0.00641397433355 -0.336706846952
+vn 0.966033518314 -0.00129650055896 -0.258413374424
+vn 0.825430572033 -0.0193976983428 -0.564170420170
+vn -0.167491003871 0.0525531768799 -0.984471917152
+vn -0.782101988792 -0.0189985297620 -0.622860848904
+vn -0.831313133240 -0.0416754819453 -0.554239749908
+vn -0.761793434620 -0.0124262347817 -0.647700846195
+vn 0.268054425716 0.0428219251335 -0.962451577187
+vn 0.788479328156 0.0368671379983 -0.613955438137
+vn 0.803950250149 0.0297200214118 -0.593953490257
+vn 0.834072649479 0.0146272787824 -0.551460564137
+vn 0.430538266897 0.00291608925909 -0.902567565441
+vn -0.580441474915 0.419375270605 -0.698005855083
+vn -0.922112345695 0.273802369833 -0.273388057947
+vn -0.889351546764 0.236710742116 -0.391180127859
+vn -0.829033911228 0.206596523523 -0.519635200500
+vn 0.105119146407 0.124664217234 -0.986614823341
+vn 0.849065542221 0.0331773832440 -0.527244746685
+vn 0.903809487820 0.0962260439992 -0.416975915432
+vn 0.904318094254 0.139349743724 -0.403473049402
+vn 0.668817162514 0.203261524439 -0.715100169182
+vn -0.678995728493 0.0558844804764 0.732012033463
+vn -0.644463777542 0.0850924104452 0.759885370731
+vn -0.553883552551 0.0958955585957 0.827053248882
+vn -0.525949597359 -0.0189798511565 0.850303947926
+vn -0.997015893459 0.0771490335464 0.00272556138225
+vn -0.511859059334 0.0465187542140 -0.857809007168
+vn -0.545941770077 0.0791255235672 -0.834078311920
+vn -0.619526624680 0.101438693702 -0.778393745422
+vn -0.650600016117 0.0616452917457 -0.756914377213
+vn -0.676973521709 0.0368419438601 0.735084712505
+vn -0.646109819412 0.0466747470200 0.761815905571
+vn -0.525266349316 0.0625061541796 0.848639070988
+vn -0.474311619997 0.0318321213126 0.879781305790
+vn -0.998326361179 0.0577691309154 -0.00267342338338
+vn -0.488706082106 0.0641477257013 -0.870087027550
+vn -0.528004765511 0.0857260152698 -0.844903528690
+vn -0.608886420727 0.0508919954300 -0.791623234749
+vn -0.632263839245 0.0106243593618 -0.774680316448
+vn -0.647638082504 0.0320448838174 0.761273980141
+vn -0.619236648083 0.00999113544822 0.785140812397
+vn -0.546302556992 0.0255463663489 0.837198257446
+vn -0.451545774937 0.0703845247626 0.889467597008
+vn -0.996682941914 0.0792019739747 0.0187167208642
+vn -0.482218682766 0.00464274734259 -0.876038551331
+vn -0.548051655293 0.0270832143724 -0.836005866528
+vn -0.616760075092 -0.00885626487434 -0.787101387978
+vn -0.627863466740 0.0663629546762 -0.775489091873
+vn -0.539485991001 -0.0670672655106 0.839319348335
+vn -0.638467907906 0.0344433598220 0.768877387047
+vn -0.572472810745 0.0726887062192 0.816695272923
+vn -0.451976686716 0.0584128573537 0.890115141869
+vn -0.993348419666 0.0891158133745 0.0729207992554
+vn -0.469269216061 0.0367832109332 -0.882288753986
+vn -0.523576200008 0.0697502195835 -0.849118947983
+vn -0.611481130123 0.0478387847543 -0.789811551571
+vn -0.432084828615 0.0162451975048 -0.901686549187
+vn -0.725751101971 0.0601240247488 0.685325026512
+vn -0.713347077370 0.0168960094452 0.700607299805
+vn -0.545757591724 0.0111744571477 0.837868630886
+vn -0.426020294428 0.0299144107848 0.904218912125
+vn -0.994556546211 0.0898369476199 0.0527889057994
+vn -0.422086715698 0.0500904396176 -0.905170559883
+vn -0.509944021702 0.0325761921704 -0.859590649605
+vn -0.695009768009 0.0260060168803 -0.718529820442
+vn -0.635862886906 0.0882048383355 -0.766745328903
+vn -0.487917602062 0.0598814412951 0.870833218098
+vn -0.632084846497 0.0416521877050 0.773779034615
+vn -0.574342787266 0.0471926219761 0.817253470421
+vn -0.477901458740 0.0188099239022 0.878212034702
+vn -0.995788514614 0.0637717992067 0.0658665597439
+vn -0.464229255915 0.0531505495310 -0.884118855000
+vn -0.528756678104 0.0407504364848 -0.847794651985
+vn -0.605133593082 0.0494612529874 -0.794586002827
+vn -0.296222060919 0.0977079644799 -0.950108230114
+vn -0.692387580872 0.0331968739629 0.720761716366
+vn -0.733851671219 -0.0441598929465 0.677872776985
+vn -0.512247979641 0.0260561816394 0.858442187309
+vn -0.388093680143 0.0141800194979 0.921510875225
+vn -0.999217569828 0.0355870649219 0.0172569602728
+vn -0.412354111671 0.0312420502305 -0.910487711430
+vn -0.526606321335 -0.00816001463681 -0.850070178509
+vn -0.718459606171 -0.0491339974105 -0.693831205368
+vn -0.623313963413 0.0336314551532 -0.781248092651
+vn -0.285026311874 0.138744637370 0.948424875736
+vn -0.647428631783 0.0401112772524 0.761069834232
+vn -0.617735743523 0.0124595370144 0.786287069321
+vn -0.426145076752 0.0337701588869 0.904024362564
+vn -0.997337698936 0.0422655120492 0.0594245456159
+vn -0.475149095058 0.0405672267079 -0.878969728947
+vn -0.600792646408 0.0632947757840 -0.796895146370
+vn -0.594974875450 0.0866549387574 -0.799059331417
+vn -0.166049361229 0.191702172160 -0.967304468155
+vn -0.685758233070 0.0360955782235 0.726933777332
+vn -0.743474304676 -0.0195984635502 0.668477237225
+vn -0.514822185040 -0.00509039172903 0.857281804085
+vn -0.384606033564 -0.0163278486580 0.922936439514
+vn -0.999013245106 0.0428509190679 0.0116730136797
+vn -0.321824818850 0.0356753356755 -0.946126759052
+vn -0.498762458563 0.0333559140563 -0.866096675396
+vn -0.731668293476 -0.0190449040383 -0.681394755840
+vn -0.616784870625 0.0365870893002 -0.786280989647
+vn -0.217327103019 0.163509026170 0.962306439877
+vn -0.632550597191 0.0554837547243 0.772529125214
+vn -0.587917685509 0.0590886212885 0.806759834290
+vn -0.424070984125 0.0465338975191 0.904432654381
+vn -0.996014297009 0.0888703241944 -0.00757871801034
+vn -0.451264768839 0.0544503033161 -0.890727400780
+vn -0.641621768475 0.0210073180497 -0.766733527184
+vn -0.574202299118 0.0535238645971 -0.816962063313
+vn -0.124863825738 0.178745463490 -0.975940108299
+vn -0.651829600334 0.0257484521717 0.757928252220
+vn -0.781316637993 -0.0268940273672 0.623555123806
+vn -0.513296246529 0.0212372448295 0.857948720455
+vn -0.281809717417 0.0332438312471 0.958894193172
+vn -0.997653484344 0.0664023458958 0.0166782364249
+vn -0.339672058821 0.0117608951405 -0.940470337868
+vn -0.507885873318 0.0335067622364 -0.860772490501
+vn -0.693847656250 0.00530383922160 -0.720102250576
+vn -0.595408916473 0.0384129174054 -0.802504003048
+vn -0.135899811983 0.161013260484 0.977550983429
+vn -0.621468186378 0.0260053370148 0.783007681370
+vn -0.665714621544 -0.0131523450837 0.746090531349
+vn -0.437387436628 -0.00133382237982 0.899272203445
+vn -0.996432244778 0.0548989027739 0.0641013756394
+vn -0.494419902563 -0.00732907420024 -0.869192242622
+vn -0.608475506306 -0.0132980197668 -0.793461263180
+vn -0.525030076504 0.0220761038363 -0.850797295570
+vn -0.102979250252 0.153558075428 -0.982758939266
+vn -0.618459105492 0.0630816370249 0.783280849457
+vn -0.731647193432 0.0588667653501 0.679136931896
+vn -0.486582905054 0.0449283868074 0.872478365898
+vn -0.321606218815 0.0206467248499 0.946648359299
+vn -0.995635330677 0.0791907608509 0.0493884198368
+vn -0.390139013529 0.0473949462175 -0.919535338879
+vn -0.450172960758 0.0560109950602 -0.891182959080
+vn -0.620029866695 0.0518754310906 -0.782861471176
+vn -0.548123657703 0.0483019910753 -0.835001349449
+vn -0.199973136187 0.0403374843299 0.978970646858
+vn -0.589808702469 -0.00221289438196 0.807539999485
+vn -0.557610213757 0.00141525606159 0.830101788044
+vn -0.436580747366 0.00882036704570 0.899621844292
+vn -0.997122049332 0.0553024783731 0.0518589504063
+vn -0.513905704021 0.0194100849330 -0.857627093792
+vn -0.572665810585 0.00515177147463 -0.819772839546
+vn -0.491273850203 0.0204437244684 -0.870765268803
+vn -0.194006174803 0.104503035545 -0.975418210030
+vn -0.700078725815 0.0454755499959 0.712616145611
+vn -0.787723302841 0.0269645210356 0.615438759327
+vn -0.426052272320 0.00837490800768 0.904659867287
+vn -0.349868625402 -0.0190906822681 0.936604321003
+vn -0.999026834965 0.0408961027861 0.0165213197470
+vn -0.446840584278 0.0473698377609 -0.893358528614
+vn -0.423653930426 0.0641460716724 -0.903550088406
+vn -0.573794364929 0.0922283977270 -0.813789844513
+vn -0.516985476017 0.0873600766063 -0.851524710655
+vn -0.233557999134 0.0738289058208 0.969536006451
+vn -0.550873577595 -0.0246425662190 0.834224820137
+vn -0.390066921711 -0.0443031489849 0.919720172882
+vn -0.499872952700 -0.0148821957409 0.865970849991
+vn -0.994759857655 0.0593918375671 -0.0832194313407
+vn -0.496045082808 0.0386153161526 -0.867437601089
+vn -0.429348051548 0.0369930006564 -0.902381241322
+vn -0.472119718790 0.00470739416778 -0.881521880627
+vn -0.231268882751 0.0131295965984 -0.972801268101
+vn -0.665668785572 0.0582577288151 0.743969976902
+vn -0.744585096836 0.0662598460913 0.664230823517
+vn -0.405180484056 0.0682397931814 0.911686420441
+vn -0.512100338936 0.0661248490214 0.856376528740
+vn -0.995331704617 0.0783621668816 -0.0563416965306
+vn -0.441968619823 0.0520116426051 -0.895521402359
+vn -0.455342054367 0.0601960457861 -0.888279259205
+vn -0.727919578552 0.0435968078673 -0.684275031090
+vn -0.560082495213 0.0546937063336 -0.826629459858
+vn -0.438678920269 0.00357282953337 0.898636698723
+vn -0.594414770603 -0.0318730697036 0.803526759148
+vn -0.331690430641 -0.0276674386114 0.942982554436
+vn -0.483373194933 -0.000643683248200 0.875414133072
+vn -0.999233961105 0.0351815856993 0.0171397682279
+vn -0.467841506004 0.0167629104108 -0.883653342724
+vn -0.412331283092 -0.00451735081151 -0.911022782326
+vn -0.517396390438 0.0239238422364 -0.855411291122
+vn -0.253709524870 0.0745846927166 -0.964400708675
+vn -0.676647603512 0.0330981500447 0.735562622547
+vn -0.801747679710 0.0258803796023 0.597102046013
+vn -0.492149949074 0.0378543362021 0.869686961174
+vn -0.642319738865 0.0338912419975 0.765687108040
+vn -0.998006939888 0.0566875562072 -0.0277217440307
+vn -0.558649301529 0.0432637743652 -0.828274786472
+vn -0.434808850288 0.0498104281723 -0.899144113064
+vn -0.612037956715 0.0540320575237 -0.788980424404
+vn -0.535643696785 0.0447993911803 -0.843254983425
+vn -0.445415616035 0.0306466948241 0.894799292088
+vn -0.604228556156 -0.00605555204675 0.796788096428
+vn -0.244463041425 -0.0368075817823 0.968959689140
+vn -0.433315485716 -0.0304121393710 0.900729060173
+vn -0.998732388020 0.00593693554401 0.0499836504459
+vn -0.454290837049 -0.0120484326035 -0.890771985054
+vn -0.309010446072 -0.00628090929240 -0.951037943363
+vn -0.484044790268 0.00232011009939 -0.875040233135
+vn -0.382946670055 0.0103605398908 -0.923712372780
+vn -0.690666198730 -0.0224884916097 0.722823977470
+vn -0.654208660126 -0.00799591280520 0.756271779537
+vn -0.383734464645 -0.0158000271767 0.923308312893
+vn -0.685342907906 0.0110719669610 0.728136241436
+vn -0.999007165432 0.0396036095917 0.0204016342759
+vn -0.564336895943 0.00544700818136 -0.825526595116
+vn -0.321980684996 0.000859830121044 -0.946745872498
+vn -0.583606064320 -0.00254006381147 -0.812032938004
+vn -0.596423268318 -0.00835637841374 -0.802626609802
+vn -0.689261257648 0.0955394804478 0.718185901642
+vn -0.548291504383 0.0813451409340 0.832321763039
+vn -0.281565129757 0.0649968385696 0.957338213921
+vn -0.516084074974 0.0620697773993 0.854285955429
+vn -0.983351767063 0.0938191264868 0.155618846416
+vn -0.533085107803 0.0678321793675 -0.843338012695
+vn -0.305721282959 0.0458007901907 -0.951018869877
+vn -0.498923599720 0.0551496073604 -0.864889562130
+vn -0.468596339226 0.0678290724754 -0.880804598331
+vn -0.731612861156 -0.0847542583942 0.676431357861
+vn -0.573461830616 -0.0831703990698 0.814999461174
+vn -0.382799535990 -0.0791279599071 0.920436441898
+vn -0.630774617195 -0.0599679499865 0.773645460606
+vn -0.999186277390 -0.00386322615668 0.0401484146714
+vn -0.673434019089 0.0147010479122 -0.739101171494
+vn -0.406598210335 -0.0144026605412 -0.913493514061
+vn -0.533201277256 -0.0235803127289 -0.845659673214
+vn -0.606908440590 -0.0273393485695 -0.794301390648
+vn -0.756078243256 0.101299479604 0.646594107151
+vn -0.539679229259 0.0840072557330 0.837668895721
+vn -0.365688860416 0.0723952725530 0.927917361259
+vn -0.564110279083 0.0478518083692 0.824311733246
+vn -0.994989335537 0.0335866436362 -0.0941710919142
+vn -0.613699913025 0.0383468382061 -0.788607716560
+vn -0.503276407719 0.0588024295866 -0.862122416496
+vn -0.443568021059 0.0814440324903 -0.892532527447
+vn -0.516670882702 0.129410371184 -0.846347510815
+vn -0.805352926254 -0.0847905650735 0.586700201035
+vn -0.540671169758 -0.0868507921696 0.836738646030
+vn -0.355022042990 -0.0772870853543 0.931657671928
+vn -0.218086794019 -0.0642571225762 0.973811686039
+vn -0.999804794788 0.00421727029607 0.0193009525537
+vn -0.496935933828 0.0193759817630 -0.867570877075
+vn -0.336707383394 0.00641402695328 -0.941587567329
+vn -0.258413076401 -0.00129661918618 -0.966033637524
+vn -0.564170777798 -0.0193973891437 -0.825430274010
+vn -0.984472274780 0.0525562614202 0.167487859726
+vn -0.622862160206 -0.0189978200942 0.782100915909
+vn -0.554241418839 -0.0416757166386 0.831311941147
+vn -0.647701323032 -0.0124261798337 0.761793017387
+vn -0.962451815605 0.0428219102323 -0.268054008484
+vn -0.613955438137 0.0368670523167 -0.788479328156
+vn -0.593953549862 0.0297200735658 -0.803950190544
+vn -0.551460981369 0.0146274827421 -0.834072411060
+vn -0.902568161488 0.00291675003245 -0.430537015200
+vn -0.698008656502 0.419377267361 0.580436587334
+vn -0.273388564587 0.273802369833 0.922112286091
+vn -0.391181647778 0.236710876226 0.889350771904
+vn -0.519635975361 0.206597194076 0.829033195972
+vn -0.986614882946 0.124664075673 -0.105118528008
+vn -0.527243912220 0.0331774093211 -0.849066019058
+vn -0.416976213455 0.0962259992957 -0.903809309006
+vn -0.403472870588 0.139349520206 -0.904318153858
+vn -0.715100109577 0.203261807561 -0.668817222118
+vn 0.732012033463 0.0558844953775 0.678995788097
+vn 0.759885370731 0.0850922539830 0.644463777542
+vn 0.827053129673 0.0958956032991 0.553883671761
+vn 0.850303888321 -0.0189799070358 0.525949597359
+vn 0.00272540654987 0.0771490037441 0.997015893459
+vn -0.857809126377 0.0465187393129 0.511858880520
+vn -0.834078371525 0.0791254863143 0.545941770077
+vn -0.778393864632 0.101438842714 0.619526505470
+vn -0.756914734840 0.0616455599666 0.650599777699
+vn 0.735084652901 0.0368420332670 0.676973640919
+vn 0.761815845966 0.0466747432947 0.646110057831
+vn 0.848639070988 0.0625062286854 0.525266408920
+vn 0.879781246185 0.0318321138620 0.474311679602
+vn -0.00267354166135 0.0577691495419 0.998326361179
+vn -0.870087146759 0.0641476958990 0.488705962896
+vn -0.844903528690 0.0857259631157 0.528004765511
+vn -0.791623234749 0.0508919581771 0.608886361122
+vn -0.774680078030 0.0106243612245 0.632264018059
+vn 0.761273801327 0.0320447012782 0.647638261318
+vn 0.785140633583 0.00999099947512 0.619236886501
+vn 0.837198197842 0.0255463644862 0.546302556992
+vn 0.889467477798 0.0703845247626 0.451545804739
+vn 0.0187166091055 0.0792019814253 0.996682763100
+vn -0.876038610935 0.00464267982170 0.482218593359
+vn -0.836005926132 0.0270831566304 0.548051476479
+vn -0.787101566792 -0.00885634217411 0.616759955883
+vn -0.775489211082 0.0663628131151 0.627863466740
+vn 0.839319288731 -0.0670671015978 0.539485991001
+vn 0.768877267838 0.0344433821738 0.638467967510
+vn 0.816695272923 0.0726887583733 0.572472989559
+vn 0.890115082264 0.0584128759801 0.451976746321
+vn 0.0729206129909 0.0891158282757 0.993348360062
+vn -0.882288813591 0.0367832034826 0.469269186258
+vn -0.849118947983 0.0697502419353 0.523576080799
+vn -0.789811611176 0.0478387922049 0.611480951309
+vn -0.901686549187 0.0162451658398 0.432085037231
+vn 0.685325086117 0.0601241253316 0.725751101971
+vn 0.700607061386 0.0168959889561 0.713347315788
+vn 0.837868452072 0.0111744832247 0.545757770538
+vn 0.904218912125 0.0299144368619 0.426020413637
+vn 0.0527888610959 0.0898369178176 0.994556486607
+vn -0.905170559883 0.0500904321671 0.422086626291
+vn -0.859590768814 0.0325761958957 0.509943842888
+vn -0.718530118465 0.0260060187429 0.695009410381
+vn -0.766745209694 0.0882048383355 0.635862946510
+vn 0.870833218098 0.0598814785480 0.487917840481
+vn 0.773778796196 0.0416522175074 0.632085025311
+vn 0.817253351212 0.0471925847232 0.574342966080
+vn 0.878211915493 0.0188099369407 0.477901577950
+vn 0.0658666715026 0.0637717247009 0.995788514614
+vn -0.884118914604 0.0531505607069 0.464229166508
+vn -0.847794651985 0.0407504141331 0.528756618500
+vn -0.794586122036 0.0494612529874 0.605133533478
+vn -0.950108110905 0.0977079942822 0.296222180128
+vn 0.720761597157 0.0331968665123 0.692387640476
+vn 0.677872717381 -0.0441598817706 0.733851790428
+vn 0.858442187309 0.0260562077165 0.512248098850
+vn 0.921510934830 0.0141800623387 0.388093680143
+vn 0.0172569639981 0.0355870872736 0.999217569828
+vn -0.910487890244 0.0312420874834 0.412353813648
+vn -0.850070238113 -0.00815997272730 0.526606261730
+vn -0.693831264973 -0.0491339787841 0.718459546566
+vn -0.781247973442 0.0336315818131 0.623314082623
+vn 0.948424935341 0.138744741678 0.285026401281
+vn 0.761069715023 0.0401113107800 0.647428750992
+vn 0.786286890507 0.0124594923109 0.617735922337
+vn 0.904024362564 0.0337701179087 0.426145076752
+vn 0.0594246983528 0.0422655418515 0.997337579727
+vn -0.878969728947 0.0405672788620 0.475149035454
+vn -0.796895205975 0.0632949024439 0.600792586803
+vn -0.799059271812 0.0866549685597 0.594975054264
+vn -0.967304289341 0.191702246666 0.166050150990
+vn 0.726933658123 0.0360955595970 0.685758531094
+vn 0.668476879597 -0.0195985473692 0.743474721909
+vn 0.857281804085 -0.00509038660675 0.514822423458
+vn 0.922936379910 -0.0163278598338 0.384606212378
+vn 0.0116730155423 0.0428509451449 0.999013245106
+vn -0.946126937866 0.0356753505766 0.321824669838
+vn -0.866096615791 0.0333558917046 0.498762577772
+vn -0.681395053864 -0.0190450306982 0.731667935848
+vn -0.786281168461 0.0365868732333 0.616784811020
+vn 0.962306320667 0.163508981466 0.217327713966
+vn 0.772529065609 0.0554835945368 0.632550716400
+vn 0.806759953499 0.0590887703001 0.587917387486
+vn 0.904432654381 0.0465339384973 0.424071103334
+vn -0.00757880927995 0.0888704136014 0.996014297009
+vn -0.890727460384 0.0544502809644 0.451264679432
+vn -0.766733527184 0.0210071951151 0.641621768475
+vn -0.816962063313 0.0535236969590 0.574202179909
+vn -0.975940108299 0.178745418787 0.124864071608
+vn 0.757928013802 0.0257482789457 0.651829898357
+vn 0.623555123806 -0.0268940627575 0.781316697598
+vn 0.857948899269 0.0212372746319 0.513295948505
+vn 0.958894193172 0.0332438834012 0.281809777021
+vn 0.0166781879961 0.0664024800062 0.997653484344
+vn -0.940470397472 0.0117609566078 0.339672029018
+vn -0.860772609711 0.0335066951811 0.507885575294
+vn -0.720102310181 0.00530366040766 0.693847715855
+vn -0.802504181862 0.0384129211307 0.595408737659
+vn 0.977550983429 0.161013394594 0.135900020599
+vn 0.783007681370 0.0260053537786 0.621468126774
+vn 0.746090650558 -0.0131526216865 0.665714561939
+vn 0.899272203445 -0.00133388582617 0.437387317419
+vn 0.0641013160348 0.0548989102244 0.996432125568
+vn -0.869192242622 -0.00732905510813 0.494419872761
+vn -0.793461501598 -0.0132979452610 0.608475148678
+vn -0.850797355175 0.0220762360841 0.525029957294
+vn -0.982758939266 0.153558403254 0.102979384363
+vn 0.783280551434 0.0630817636847 0.618459582329
+vn 0.679136872292 0.0588668882847 0.731647312641
+vn 0.872478246689 0.0449283942580 0.486583113670
+vn 0.946648359299 0.0206466931850 0.321606248617
+vn 0.0493881516159 0.0791907235980 0.995635390282
+vn -0.919535279274 0.0473949164152 0.390139162540
+vn -0.891182839870 0.0560110025108 0.450173169374
+vn -0.782861053944 0.0518754422665 0.620030343533
+vn -0.835001230240 0.0483021438122 0.548123896122
+vn 0.978970527649 0.0403375513852 0.199973747134
+vn 0.807539701462 -0.00221269903705 0.589809119701
+vn 0.830101907253 0.00141530495603 0.557610034943
+vn 0.899621903896 0.00882037077099 0.436580657959
+vn 0.0518584996462 0.0553025230765 0.997122049332
+vn -0.857627093792 0.0194100812078 0.513905763626
+vn -0.819772958755 0.00515192467719 0.572665452957
+vn -0.870765268803 0.0204437412322 0.491273939610
+vn -0.975418269634 0.104503042996 0.194005832076
+vn 0.712616205215 0.0454756394029 0.700078606606
+vn 0.615438520908 0.0269646104425 0.787723481655
+vn 0.904659807682 0.00837490987033 0.426052361727
+vn 0.936604142189 -0.0190907511860 0.349868923426
+vn 0.0165219847113 0.0408960916102 0.999026834965
+vn -0.893358528614 0.0473698787391 0.446840852499
+vn -0.903549849987 0.0641461238265 0.423654198647
+vn -0.813789725304 0.0922282785177 0.573794603348
+vn -0.851524949074 0.0873600244522 0.516985058784
+vn 0.969536066055 0.0738288983703 0.233557507396
+vn 0.834224998951 -0.0246426034719 0.550873279572
+vn 0.919720172882 -0.0443031974137 0.390066921711
+vn 0.865970730782 -0.0148822478950 0.499873310328
+vn -0.0832187458873 0.0593918897212 0.994759917259
+vn -0.867437481880 0.0386153422296 0.496045380831
+vn -0.902381300926 0.0369929410517 0.429347813129
+vn -0.881521940231 0.00470736529678 0.472119659185
+vn -0.972801268101 0.0131295649335 0.231269150972
+vn 0.743970632553 0.0582577809691 0.665667951107
+vn 0.664231240749 0.0662596970797 0.744584798813
+vn 0.911686658859 0.0682397186756 0.405180126429
+vn 0.856376588345 0.0661248043180 0.512100219727
+vn -0.0563421249390 0.0783621370792 0.995331585407
+vn -0.895521342754 0.0520115792751 0.441968590021
+vn -0.888279378414 0.0601960197091 0.455341875553
+vn -0.684274971485 0.0435969606042 0.727919578552
+vn -0.826629400253 0.0546935983002 0.560082554817
+vn 0.898637175560 0.00357314175926 0.438678115606
+vn 0.803526997566 -0.0318729691207 0.594414353371
+vn 0.942982614040 -0.0276676341891 0.331690132618
+vn 0.875414371490 -0.000643751583993 0.483372837305
+vn 0.0171396695077 0.0351814925671 0.999234020710
+vn -0.883653223515 0.0167628917843 0.467841684818
+vn -0.911023139954 -0.00451727770269 0.412330567837
+vn -0.855411589146 0.0239237882197 0.517396152020
+vn -0.964400529861 0.0745841413736 0.253709822893
+vn 0.735562741756 0.0330981090665 0.676647543907
+vn 0.597102344036 0.0258807186037 0.801747322083
+vn 0.869686782360 0.0378543138504 0.492150247097
+vn 0.765686750412 0.0338914059103 0.642320275307
+vn -0.0277216173708 0.0566875487566 0.998007059097
+vn -0.828274428844 0.0432636141777 0.558649778366
+vn -0.899144172668 0.0498104318976 0.434808820486
+vn -0.788980185986 0.0540319159627 0.612038254738
+vn -0.843254685402 0.0447991900146 0.535644114017
+vn 0.894799888134 0.0306462459266 0.445414513350
+vn 0.796787679195 -0.00605551805347 0.604228973389
+vn 0.968959569931 -0.0368078723550 0.244463726878
+vn 0.900729179382 -0.0304121728987 0.433315128088
+vn 0.0499842949212 0.00593698397279 0.998732268810
+vn -0.890771865845 -0.0120486328378 0.454291075468
+vn -0.951038241386 -0.00628098193556 0.309009671211
+vn -0.875040113926 0.00231996993534 0.484044909477
+vn -0.923712491989 0.0103601785377 0.382946342230
+vn 0.722823858261 -0.0224884618074 0.690666437149
+vn 0.756271421909 -0.00799544062465 0.654209136963
+vn 0.923308312893 -0.0158000774682 0.383734554052
+vn 0.728136420250 0.0110720191151 0.685342788696
+vn 0.0204012673348 0.0396036803722 0.999007105827
+vn -0.825526356697 0.00544668082148 0.564337134361
+vn -0.946745872498 0.000859727850184 0.321980416775
+vn -0.812033116817 -0.00254020025022 0.583605885506
+vn -0.802626490593 -0.00835657585412 0.596423268318
+vn 0.718184947968 0.0955394357443 0.689262270927
+vn 0.832321763039 0.0813452377915 0.548291444778
+vn 0.957338094711 0.0649968832731 0.281565696001
+vn 0.854285657406 0.0620698854327 0.516084790230
+vn 0.155619978905 0.0938192531466 0.983351588249
+vn -0.843337893486 0.0678321570158 0.533085346222
+vn -0.951018989086 0.0458009094000 0.305720746517
+vn -0.864889383316 0.0551496185362 0.498923718929
+vn -0.880804598331 0.0678290724754 0.468596279621
+vn 0.676431417465 -0.0847541913390 0.731612801552
+vn 0.814999461174 -0.0831703692675 0.573462009430
+vn 0.920436441898 -0.0791279971600 0.382799714804
+vn 0.773645102978 -0.0599679872394 0.630775094032
+vn 0.0401481986046 -0.00386315537617 0.999186217785
+vn -0.739101111889 0.0147011009976 0.673434078693
+vn -0.913493335247 -0.0144026111811 0.406598597765
+vn -0.845659017563 -0.0235802996904 0.533202409744
+vn -0.794301152229 -0.0273393169045 0.606908738613
+vn 0.646594405174 0.101299725473 0.756078124046
+vn 0.837668657303 0.0840073153377 0.539679586887
+vn 0.927917838097 0.0723952874541 0.365687578917
+vn 0.824311614037 0.0478518716991 0.564110457897
+vn -0.0941727235913 0.0335866734385 0.994989156723
+vn -0.788607478142 0.0383467972279 0.613700091839
+vn -0.862122595310 0.0588023029268 0.503276169300
+vn -0.892532467842 0.0814439877868 0.443568021059
+vn -0.846347749233 0.129410073161 0.516670525074
+vn 0.586699903011 -0.0847905799747 0.805353164673
+vn 0.836737692356 -0.0868511125445 0.540672659874
+vn 0.931657314301 -0.0772872269154 0.355022698641
+vn 0.973811626434 -0.0642566010356 0.218087211251
+vn 0.0193010419607 0.00421741884202 0.999804794788
+vn -0.867570400238 0.0193760059774 0.496936827898
+vn -0.941587746143 0.00641397200525 0.336706846952
+vn -0.966033518314 -0.00129649101291 0.258413285017
+vn -0.825430512428 -0.0193978752941 0.564170300961
+vn 0.167490839958 0.0525538399816 0.984471857548
+vn 0.782102048397 -0.0189984757453 0.622860729694
+vn 0.831312894821 -0.0416752025485 0.554239988327
+vn 0.761792898178 -0.0124260177836 0.647701382637
+vn -0.268054872751 0.0428218245506 0.962451517582
+vn -0.788479328156 0.0368671081960 0.613955318928
+vn -0.803950250149 0.0297200195491 0.593953490257
+vn -0.834072649479 0.0146271353588 0.551460564137
+vn -0.430538207293 0.00291552022099 0.902567625046
+vn 0.580440878868 0.419375240803 0.698006391525
+vn 0.922112107277 0.273802399635 0.273388862610
+vn 0.889351367950 0.236710742116 0.391180515289
+vn 0.829034268856 0.206596672535 0.519634544849
+vn -0.105118237436 0.124664410949 0.986614882946
+vn -0.849065542221 0.0331773795187 0.527244746685
+vn -0.903809487820 0.0962260589004 0.416975915432
+vn -0.904318034649 0.139349743724 0.403473049402
+vn -0.668816804886 0.203261315823 0.715100646019
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.0231357347220 0.0675957724452 8.47497085488e-06
+vc 0.0226928405464 0.0675957724452 -0.00450524687767
+vc 0.0213778764009 0.0675957724452 -0.00884583406150
+vc 0.0192413683981 0.0675957724452 -0.0128464801237
+vc 0.0163654293865 0.0675957724452 -0.0163534432650
+vc 0.0128605738282 0.0675957724452 -0.0192319564521
+vc 0.00886149238795 0.0675957724452 -0.0213713925332
+vc 0.00452184723690 0.0675954222679 -0.0226894188672
+vc 8.47701903695e-06 0.0675954222679 -0.0231356173754
+vc 0.131333187222 0.297297626734 3.04866534862e-05
+vc 0.128815606236 0.297297626734 -0.0255919359624
+vc 0.121347717941 0.297297626734 -0.0502308756113
+vc 0.109216496348 0.297297626734 -0.0729394704103
+vc 0.0928881466389 0.297297626734 -0.0928450524807
+vc 0.0729900747538 0.297297298908 -0.109182514250
+vc 0.0502871386707 0.297297298908 -0.121324263513
+vc 0.0256517045200 0.297297298908 -0.128803580999
+vc 3.04923778458e-05 0.297297298908 -0.131333068013
+vc 0.320522040129 0.576694130898 2.35480656556e-05
+vc 0.314367890358 0.576694130898 -0.0625076666474
+vc 0.296132773161 0.576694130898 -0.122636720538
+vc 0.266517400742 0.576694130898 -0.178052961826
+vc 0.226659834385 0.576693892479 -0.226626574993
+vc 0.178091973066 0.576693892479 -0.266491174698
+vc 0.122680149972 0.576693892479 -0.296114623547
+vc 0.0625538080931 0.576693892479 -0.314358592033
+vc 2.35610532400e-05 0.576693892479 -0.320521891117
+vc 0.604020476341 0.872910022736 5.05827301822e-06
+vc 0.592415392399 0.872910022736 -0.117833591998
+vc 0.558044135571 0.872910022736 -0.231143966317
+vc 0.502227485180 0.872910022736 -0.335571646690
+vc 0.427110433578 0.872909784317 -0.427103340626
+vc 0.335579872131 0.872909784317 -0.502221763134
+vc 0.231153205037 0.872909784317 -0.558040142059
+vc 0.117843471467 0.872909784317 -0.592413306236
+vc 5.08594030180e-06 0.872909784317 -0.604020416737
+vc 0.988540112972 1.14608085155 -1.84205229127e-15
+vc 0.969545662403 1.14608085155 -0.192854627967
+vc 0.913291931152 1.14608085155 -0.378297954798
+vc 0.821941018105 1.14608085155 -0.549203455448
+vc 0.699003338814 1.14608085155 -0.699003398418
+vc 0.549203276634 1.14608073235 -0.821941077709
+vc 0.378297835588 1.14608073235 -0.913291871548
+vc 0.192854598165 1.14608073235 -0.969545483589
+vc 7.46326804801e-08 1.14608073235 -0.988539993763
+vc 1.47383701801 1.35235083103 0.00000000000
+vc 1.44551765919 1.35235083103 -0.287531375885
+vc 1.36164784431 1.35235095024 -0.564013063908
+vc 1.22545063496 1.35235095024 -0.818819999695
+vc 1.04216003418 1.35235095024 -1.04216015339
+vc 0.818819761276 1.35235083103 -1.22545075417
+vc 0.564012885094 1.35235083103 -1.36164772511
+vc 0.287531346083 1.35235083103 -1.44551753998
+vc 1.11271589276e-07 1.35235083103 -1.47383689880
+vc 2.04208803177 1.44259011745 0.00000000000
+vc 2.00284981728 1.44259011745 -0.398391634226
+vc 1.88664317131 1.44259011745 -0.781473278999
+vc 1.69793391228 1.44259011745 -1.13452339172
+vc 1.44397401810 1.44258999825 -1.44397413731
+vc 1.13452303410 1.44258999825 -1.69793415070
+vc 0.781473100185 1.44258999825 -1.88664329052
+vc 0.398391604424 1.44258999825 -2.00284957886
+vc 1.54173335432e-07 1.44258999825 -2.04208779335
+vc 2.67769289017 1.38483130932 -2.02913794064e-15
+vc 2.62624144554 1.38483130932 -0.522391974926
+vc 2.47386527061 1.38483130932 -1.02470874786
+vc 2.22641992569 1.38483130932 -1.48764646053
+vc 1.89341449738 1.38483130932 -1.89341473579
+vc 1.48764622211 1.38483142853 -2.22642040253
+vc 1.02470862865 1.38483142853 -2.47386574745
+vc 0.522391974926 1.38483154774 -2.62624168396
+vc 2.02160165941e-07 1.38483154774 -2.67769289017
+vc 3.35748648643 1.14598357677 -6.13544238998e-16
+vc 3.29297351837 1.14598369598 -0.655013203621
+vc 3.10191297531 1.14598369598 -1.28485465050
+vc 2.79164767265 1.14598369598 -1.86531972885
+vc 2.37410140038 1.14598369598 -2.37410163879
+vc 1.86531937122 1.14598369598 -2.79164838791
+vc 1.28485429287 1.14598381519 -3.10191321373
+vc 0.655013203621 1.14598381519 -3.29297351837
+vc 2.53483165125e-07 1.14598381519 -3.35748672485
+vc 3.97504377365 0.693362772465 0.00000000000
+vc 3.89866423607 0.693362772465 -0.775492727757
+vc 3.67246150970 0.693362951279 -1.52118360996
+vc 3.30512785912 0.693362951279 -2.20841622353
+vc 2.81078052521 0.693363010883 -2.81078076363
+vc 2.20841574669 0.693363010883 -3.30512833595
+vc 1.52118325233 0.693363010883 -3.67246174812
+vc 0.775492668152 0.693363010883 -3.89866423607
+vc 3.00107444673e-07 0.693363010883 -3.97504401207
+vc 4.25838994980 0.154062956572 6.56503219571e-15
+vc 4.17656612396 0.154063045979 -0.830770790577
+vc 3.93423914909 0.154063135386 -1.62961554527
+vc 3.54072189331 0.154063224792 -2.36583518982
+vc 3.01113605499 0.154063224792 -3.01113700867
+vc 2.36583423615 0.154063314199 -3.54072237015
+vc 1.62961471081 0.154063314199 -3.93424010277
+vc 0.830770254135 0.154063388705 -4.17656660080
+vc -1.86140127312e-07 0.154063388705 -4.25838994980
+vc 4.10428714752 -0.0565397106111 0.00000000000
+vc 4.02542400360 -0.0565396137536 -0.800706744194
+vc 3.79186654091 -0.0565395243466 -1.57064294815
+vc 3.41258978844 -0.0565395243466 -2.28022003174
+vc 2.90216875076 -0.0565394312143 -2.90216970444
+vc 2.28021907806 -0.0565393380821 -3.41259026527
+vc 1.57064199448 -0.0565393380821 -3.79186677933
+vc 0.800706267357 -0.0565393380821 -4.02542448044
+vc -1.79404068490e-07 -0.0565393380821 -4.10428714752
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.0231357347220 0.0675957724452 8.47497085488e-06
+vc 0.0226928405464 0.0675957724452 -0.00450524687767
+vc 0.0213778764009 0.0675957724452 -0.00884583406150
+vc 0.0192413683981 0.0675957724452 -0.0128464801237
+vc 0.0163654293865 0.0675957724452 -0.0163534432650
+vc 0.0128605738282 0.0675957724452 -0.0192319564521
+vc 0.00886149238795 0.0675957724452 -0.0213713925332
+vc 0.00452184723690 0.0675954222679 -0.0226894188672
+vc 8.47701903695e-06 0.0675954222679 -0.0231356173754
+vc 0.320522040129 0.576694130898 2.35480656556e-05
+vc 0.314367890358 0.576694130898 -0.0625076666474
+vc 0.296132773161 0.576694130898 -0.122636720538
+vc 0.266517400742 0.576694130898 -0.178052961826
+vc 0.226659834385 0.576693892479 -0.226626574993
+vc 0.178091973066 0.576693892479 -0.266491174698
+vc 0.122680149972 0.576693892479 -0.296114623547
+vc 0.0625538080931 0.576693892479 -0.314358592033
+vc 2.35610532400e-05 0.576693892479 -0.320521891117
+vc 0.604020476341 0.872910022736 5.05827301822e-06
+vc 0.592415392399 0.872910022736 -0.117833591998
+vc 0.558044135571 0.872910022736 -0.231143966317
+vc 0.502227485180 0.872910022736 -0.335571646690
+vc 0.427110433578 0.872909784317 -0.427103340626
+vc 0.335579872131 0.872909784317 -0.502221763134
+vc 0.231153205037 0.872909784317 -0.558040142059
+vc 0.117843471467 0.872909784317 -0.592413306236
+vc 5.08594030180e-06 0.872909784317 -0.604020416737
+vc 0.988540112972 1.14608085155 -1.84205229127e-15
+vc 0.969545662403 1.14608085155 -0.192854627967
+vc 0.913291931152 1.14608085155 -0.378297954798
+vc 0.821941018105 1.14608085155 -0.549203455448
+vc 0.699003338814 1.14608085155 -0.699003398418
+vc 0.549203276634 1.14608073235 -0.821941077709
+vc 0.378297835588 1.14608073235 -0.913291871548
+vc 0.192854598165 1.14608073235 -0.969545483589
+vc 7.46326804801e-08 1.14608073235 -0.988539993763
+vc 1.47383701801 1.35235083103 0.00000000000
+vc 1.44551765919 1.35235083103 -0.287531375885
+vc 1.36164784431 1.35235095024 -0.564013063908
+vc 1.22545063496 1.35235095024 -0.818819999695
+vc 1.04216003418 1.35235095024 -1.04216015339
+vc 0.818819761276 1.35235083103 -1.22545075417
+vc 0.564012885094 1.35235083103 -1.36164772511
+vc 0.287531346083 1.35235083103 -1.44551753998
+vc 1.11271589276e-07 1.35235083103 -1.47383689880
+vc 2.67769289017 1.38483130932 -2.02913794064e-15
+vc 2.62624144554 1.38483130932 -0.522391974926
+vc 2.47386527061 1.38483130932 -1.02470874786
+vc 2.22641992569 1.38483130932 -1.48764646053
+vc 1.89341449738 1.38483130932 -1.89341473579
+vc 1.48764622211 1.38483142853 -2.22642040253
+vc 1.02470862865 1.38483142853 -2.47386574745
+vc 0.522391974926 1.38483154774 -2.62624168396
+vc 2.02160165941e-07 1.38483154774 -2.67769289017
+vc 4.10428714752 -0.0565397106111 0.00000000000
+vc 4.02542400360 -0.0565396137536 -0.800706744194
+vc 3.79186654091 -0.0565395243466 -1.57064294815
+vc 3.41258978844 -0.0565395243466 -2.28022003174
+vc 2.90216875076 -0.0565394312143 -2.90216970444
+vc 2.28021907806 -0.0565393380821 -3.41259026527
+vc 1.57064199448 -0.0565393380821 -3.79186677933
+vc 0.800706267357 -0.0565393380821 -4.02542448044
+vc -1.79404068490e-07 -0.0565393380821 -4.10428714752
+vc 4.10428714752 -0.0565397106111 0.00000000000
+vc 4.02542400360 -0.0565396137536 -0.800706744194
+vc 3.79186654091 -0.0565395243466 -1.57064294815
+vc 3.41258978844 -0.0565395243466 -2.28022003174
+vc 2.90216875076 -0.0565394312143 -2.90216970444
+vc 2.28021907806 -0.0565393380821 -3.41259026527
+vc 1.57064199448 -0.0565393380821 -3.79186677933
+vc 0.800706267357 -0.0565393380821 -4.02542448044
+vc -1.79404068490e-07 -0.0565393380821 -4.10428714752
+vc 4.10428714752 -0.0565397106111 0.00000000000
+vc 4.02542400360 -0.0565396137536 -0.800706744194
+vc 3.79186654091 -0.0565395243466 -1.57064294815
+vc 3.41258978844 -0.0565395243466 -2.28022003174
+vc 2.90216875076 -0.0565394312143 -2.90216970444
+vc 2.28021907806 -0.0565393380821 -3.41259026527
+vc 1.57064199448 -0.0565393380821 -3.79186677933
+vc 0.800706267357 -0.0565393380821 -4.02542448044
+vc -1.79404068490e-07 -0.0565393380821 -4.10428714752
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 8.47395949677e-06 0.0675957724452 -0.0231357347220
+vc -0.00450524780899 0.0675957724452 -0.0226928405464
+vc -0.00884583499283 0.0675957724452 -0.0213778764009
+vc -0.0128464810550 0.0675957724452 -0.0192413683981
+vc -0.0163534432650 0.0675957724452 -0.0163654293865
+vc -0.0192319564521 0.0675957724452 -0.0128605728969
+vc -0.0213713925332 0.0675957724452 -0.00886149145663
+vc -0.0226894188672 0.0675954222679 -0.00452184630558
+vc -0.0231356173754 0.0675954222679 -8.47600767884e-06
+vc 3.04809127556e-05 0.297297626734 -0.131333187222
+vc -0.0255919415504 0.297297626734 -0.128815606236
+vc -0.0502308793366 0.297297626734 -0.121347717941
+vc -0.0729394778609 0.297297626734 -0.109216496348
+vc -0.0928450599313 0.297297626734 -0.0928881391883
+vc -0.109182514250 0.297297298908 -0.0729900673032
+vc -0.121324263513 0.297297298908 -0.0502871349454
+vc -0.128803580999 0.297297298908 -0.0256516989321
+vc -0.131333068013 0.297297298908 -3.04866371152e-05
+vc 2.35340557992e-05 0.576694130898 -0.320522040129
+vc -0.0625076815486 0.576694130898 -0.314367890358
+vc -0.122636735439 0.576694130898 -0.296132773161
+vc -0.178052976727 0.576694130898 -0.266517400742
+vc -0.226626589894 0.576693892479 -0.226659819484
+vc -0.266491174698 0.576693892479 -0.178091958165
+vc -0.296114623547 0.576693892479 -0.122680135071
+vc -0.314358592033 0.576693892479 -0.0625537931919
+vc -0.320521891117 0.576693892479 -2.35470433836e-05
+vc 5.03187038703e-06 0.872910022736 -0.604020476341
+vc -0.117833614349 0.872910022736 -0.592415392399
+vc -0.231143996119 0.872910022736 -0.558044135571
+vc -0.335571676493 0.872910022736 -0.502227485180
+vc -0.427103370428 0.872909784317 -0.427110403776
+vc -0.502221763134 0.872909784317 -0.335579842329
+vc -0.558040142059 0.872909784317 -0.231153175235
+vc -0.592413306236 0.872909784317 -0.117843449116
+vc -0.604020416737 0.872909784317 -5.05953767060e-06
+vc -4.32104627635e-08 1.14608085155 -0.988540112972
+vc -0.192854672670 1.14608085155 -0.969545662403
+vc -0.378297984600 1.14608085155 -0.913291931152
+vc -0.549203515053 1.14608085155 -0.821941018105
+vc -0.699003458023 1.14608085155 -0.699003279209
+vc -0.821941077709 1.14608073235 -0.549203217030
+vc -0.913291871548 1.14608073235 -0.378297805786
+vc -0.969545483589 1.14608073235 -0.192854553461
+vc -0.988539993763 1.14608073235 -3.14222248221e-08
+vc -6.44234603442e-08 1.35235083103 -1.47383701801
+vc -0.287531435490 1.35235083103 -1.44551765919
+vc -0.564013123512 1.35235095024 -1.36164784431
+vc -0.818820059299 1.35235095024 -1.22545063496
+vc -1.04216015339 1.35235095024 -1.04216003418
+vc -1.22545075417 1.35235083103 -0.818819701672
+vc -1.36164772511 1.35235083103 -0.564012825489
+vc -1.44551753998 1.35235083103 -0.287531286478
+vc -1.47383689880 1.35235083103 -4.68481289317e-08
+vc -8.92624996141e-08 1.44259011745 -2.04208803177
+vc -0.398391723633 1.44259011745 -2.00284981728
+vc -0.781473338604 1.44259011745 -1.88664317131
+vc -1.13452351093 1.44259011745 -1.69793391228
+vc -1.44397425652 1.44258999825 -1.44397389889
+vc -1.69793415070 1.44258999825 -1.13452291489
+vc -1.88664329052 1.44258999825 -0.781473040581
+vc -2.00284957886 1.44258999825 -0.398391515017
+vc -2.04208779335 1.44258999825 -6.49108429229e-08
+vc -1.17045672710e-07 1.38483130932 -2.67769289017
+vc -0.522392094135 1.38483130932 -2.62624144554
+vc -1.02470886707 1.38483130932 -2.47386527061
+vc -1.48764657974 1.38483130932 -2.22641992569
+vc -1.89341485500 1.38483130932 -1.89341437817
+vc -2.22642040253 1.38483142853 -1.48764610291
+vc -2.47386574745 1.38483142853 -1.02470850945
+vc -2.62624168396 1.38483154774 -0.522391855717
+vc -2.67769289017 1.38483154774 -8.51144932312e-08
+vc -1.46760399389e-07 1.14598357677 -3.35748648643
+vc -0.655013322830 1.14598369598 -3.29297351837
+vc -1.28485476971 1.14598369598 -3.10191297531
+vc -1.86531984806 1.14598369598 -2.79164767265
+vc -2.37410163879 1.14598369598 -2.37410140038
+vc -2.79164838791 1.14598369598 -1.86531925201
+vc -3.10191321373 1.14598381519 -1.28485417366
+vc -3.29297351837 1.14598381519 -0.655013084412
+vc -3.35748672485 1.14598381519 -1.06722765736e-07
+vc -1.73754685306e-07 0.693362772465 -3.97504377365
+vc -0.775492906570 0.693362772465 -3.89866423607
+vc -1.52118372917 0.693362951279 -3.67246150970
+vc -2.20841646194 0.693362951279 -3.30512785912
+vc -2.81078100204 0.693363010883 -2.81078028679
+vc -3.30512833595 0.693363010883 -2.20841550827
+vc -3.67246174812 0.693363010883 -1.52118313313
+vc -3.89866423607 0.693363010883 -0.775492489338
+vc -3.97504401207 0.693363010883 -1.26352759366e-07
+vc -1.86140141523e-07 0.154062956572 -4.25838994980
+vc -0.830770969391 0.154063045979 -4.17656612396
+vc -1.62961566448 0.154063135386 -3.93423914909
+vc -2.36583542824 0.154063224792 -3.54072189331
+vc -3.01113724709 0.154063224792 -3.01113581657
+vc -3.54072237015 0.154063314199 -2.36583399773
+vc -3.93424010277 0.154063314199 -1.62961459160
+vc -4.17656660080 0.154063388705 -0.830770075321
+vc -4.25838994980 0.154063388705 3.72280283045e-07
+vc -1.79404082701e-07 -0.0565397106111 -4.10428714752
+vc -0.800706923008 -0.0565396137536 -4.02542400360
+vc -1.57064306736 -0.0565395243466 -3.79186654091
+vc -2.28022027016 -0.0565395243466 -3.41258978844
+vc -2.90216994286 -0.0565394312143 -2.90216851234
+vc -3.41259026527 -0.0565393380821 -2.28021883965
+vc -3.79186677933 -0.0565393380821 -1.57064187527
+vc -4.02542448044 -0.0565393380821 -0.800706088543
+vc -4.10428714752 -0.0565393380821 3.58808165402e-07
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 8.47395949677e-06 0.0675957724452 -0.0231357347220
+vc -0.00450524780899 0.0675957724452 -0.0226928405464
+vc -0.00884583499283 0.0675957724452 -0.0213778764009
+vc -0.0128464810550 0.0675957724452 -0.0192413683981
+vc -0.0163534432650 0.0675957724452 -0.0163654293865
+vc -0.0192319564521 0.0675957724452 -0.0128605728969
+vc -0.0213713925332 0.0675957724452 -0.00886149145663
+vc -0.0226894188672 0.0675954222679 -0.00452184630558
+vc -0.0231356173754 0.0675954222679 -8.47600767884e-06
+vc 2.35340557992e-05 0.576694130898 -0.320522040129
+vc -0.0625076815486 0.576694130898 -0.314367890358
+vc -0.122636735439 0.576694130898 -0.296132773161
+vc -0.178052976727 0.576694130898 -0.266517400742
+vc -0.226626589894 0.576693892479 -0.226659819484
+vc -0.266491174698 0.576693892479 -0.178091958165
+vc -0.296114623547 0.576693892479 -0.122680135071
+vc -0.314358592033 0.576693892479 -0.0625537931919
+vc -0.320521891117 0.576693892479 -2.35470433836e-05
+vc 5.03187038703e-06 0.872910022736 -0.604020476341
+vc -0.117833614349 0.872910022736 -0.592415392399
+vc -0.231143996119 0.872910022736 -0.558044135571
+vc -0.335571676493 0.872910022736 -0.502227485180
+vc -0.427103370428 0.872909784317 -0.427110403776
+vc -0.502221763134 0.872909784317 -0.335579842329
+vc -0.558040142059 0.872909784317 -0.231153175235
+vc -0.592413306236 0.872909784317 -0.117843449116
+vc -0.604020416737 0.872909784317 -5.05953767060e-06
+vc -4.32104627635e-08 1.14608085155 -0.988540112972
+vc -0.192854672670 1.14608085155 -0.969545662403
+vc -0.378297984600 1.14608085155 -0.913291931152
+vc -0.549203515053 1.14608085155 -0.821941018105
+vc -0.699003458023 1.14608085155 -0.699003279209
+vc -0.821941077709 1.14608073235 -0.549203217030
+vc -0.913291871548 1.14608073235 -0.378297805786
+vc -0.969545483589 1.14608073235 -0.192854553461
+vc -0.988539993763 1.14608073235 -3.14222248221e-08
+vc -6.44234603442e-08 1.35235083103 -1.47383701801
+vc -0.287531435490 1.35235083103 -1.44551765919
+vc -0.564013123512 1.35235095024 -1.36164784431
+vc -0.818820059299 1.35235095024 -1.22545063496
+vc -1.04216015339 1.35235095024 -1.04216003418
+vc -1.22545075417 1.35235083103 -0.818819701672
+vc -1.36164772511 1.35235083103 -0.564012825489
+vc -1.44551753998 1.35235083103 -0.287531286478
+vc -1.47383689880 1.35235083103 -4.68481289317e-08
+vc -1.17045672710e-07 1.38483130932 -2.67769289017
+vc -0.522392094135 1.38483130932 -2.62624144554
+vc -1.02470886707 1.38483130932 -2.47386527061
+vc -1.48764657974 1.38483130932 -2.22641992569
+vc -1.89341485500 1.38483130932 -1.89341437817
+vc -2.22642040253 1.38483142853 -1.48764610291
+vc -2.47386574745 1.38483142853 -1.02470850945
+vc -2.62624168396 1.38483154774 -0.522391855717
+vc -2.67769289017 1.38483154774 -8.51144932312e-08
+vc -1.79404082701e-07 -0.0565397106111 -4.10428714752
+vc -0.800706923008 -0.0565396137536 -4.02542400360
+vc -1.57064306736 -0.0565395243466 -3.79186654091
+vc -2.28022027016 -0.0565395243466 -3.41258978844
+vc -2.90216994286 -0.0565394312143 -2.90216851234
+vc -3.41259026527 -0.0565393380821 -2.28021883965
+vc -3.79186677933 -0.0565393380821 -1.57064187527
+vc -4.02542448044 -0.0565393380821 -0.800706088543
+vc -4.10428714752 -0.0565393380821 3.58808165402e-07
+vc -1.79404082701e-07 -0.0565397106111 -4.10428714752
+vc -0.800706923008 -0.0565396137536 -4.02542400360
+vc -1.57064306736 -0.0565395243466 -3.79186654091
+vc -2.28022027016 -0.0565395243466 -3.41258978844
+vc -2.90216994286 -0.0565394312143 -2.90216851234
+vc -3.41259026527 -0.0565393380821 -2.28021883965
+vc -3.79186677933 -0.0565393380821 -1.57064187527
+vc -4.02542448044 -0.0565393380821 -0.800706088543
+vc -4.10428714752 -0.0565393380821 3.58808165402e-07
+vc -1.79404082701e-07 -0.0565397106111 -4.10428714752
+vc -0.800706923008 -0.0565396137536 -4.02542400360
+vc -1.57064306736 -0.0565395243466 -3.79186654091
+vc -2.28022027016 -0.0565395243466 -3.41258978844
+vc -2.90216994286 -0.0565394312143 -2.90216851234
+vc -3.41259026527 -0.0565393380821 -2.28021883965
+vc -3.79186677933 -0.0565393380821 -1.57064187527
+vc -4.02542448044 -0.0565393380821 -0.800706088543
+vc -4.10428714752 -0.0565393380821 3.58808165402e-07
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc -0.0231357347220 0.0675957724452 -8.47294813866e-06
+vc -0.0226928405464 0.0675957724452 0.00450524874032
+vc -0.0213778764009 0.0675957724452 0.00884583592415
+vc -0.0192413665354 0.0675957724452 0.0128464819863
+vc -0.0163654275239 0.0675957724452 0.0163534451276
+vc -0.0128605719656 0.0675957724452 0.0192319583148
+vc -0.00886149052531 0.0675957724452 0.0213713925332
+vc -0.00452184537426 0.0675954222679 0.0226894188672
+vc -8.47499632073e-06 0.0675954222679 0.0231356173754
+vc -0.131333187222 0.297297626734 -3.04751720250e-05
+vc -0.128815606236 0.297297626734 0.0255919471383
+vc -0.121347710490 0.297297626734 0.0502308867872
+vc -0.109216488898 0.297297626734 0.0729394778609
+vc -0.0928881391883 0.297297626734 0.0928450599313
+vc -0.0729900673032 0.297297298908 0.109182521701
+vc -0.0502871274948 0.297297298908 0.121324270964
+vc -0.0256516933441 0.297297298908 0.128803580999
+vc -3.04808963847e-05 0.297297298908 0.131333068013
+vc -0.320522040129 0.576694130898 -2.35200441239e-05
+vc -0.314367890358 0.576694130898 0.0625076964498
+vc -0.296132773161 0.576694130898 0.122636742890
+vc -0.266517370939 0.576694130898 0.178052991629
+vc -0.226659819484 0.576693892479 0.226626589894
+vc -0.178091943264 0.576693892479 0.266491204500
+vc -0.122680127621 0.576693892479 0.296114623547
+vc -0.0625537782907 0.576693892479 0.314358592033
+vc -2.35330317082e-05 0.576693892479 0.320521891117
+vc -0.604020476341 0.872910022736 -5.00546775584e-06
+vc -0.592415392399 0.872910022736 0.117833644152
+vc -0.558044135571 0.872910022736 0.231144011021
+vc -0.502227485180 0.872910022736 0.335571676493
+vc -0.427110403776 0.872909784317 0.427103370428
+vc -0.335579842329 0.872909784317 0.502221763134
+vc -0.231153160334 0.872909784317 0.558040142059
+vc -0.117843419313 0.872909784317 0.592413306236
+vc -5.03313503941e-06 0.872909784317 0.604020416737
+vc -0.988540112972 1.14608085155 8.64209184215e-08
+vc -0.969545662403 1.14608085155 0.192854717374
+vc -0.913291871548 1.14608085155 0.378298044205
+vc -0.821940958500 1.14608085155 0.549203515053
+vc -0.699003279209 1.14608085155 0.699003458023
+vc -0.549203217030 1.14608073235 0.821941137314
+vc -0.378297746181 1.14608073235 0.913291931152
+vc -0.192854508758 1.14608073235 0.969545483589
+vc 1.17882308359e-08 1.14608073235 0.988539993763
+vc -1.47383701801 1.35235083103 1.28846920688e-07
+vc -1.44551765919 1.35235083103 0.287531495094
+vc -1.36164784431 1.35235095024 0.564013183117
+vc -1.22545051575 1.35235095024 0.818820118904
+vc -1.04215991497 1.35235095024 1.04216027260
+vc -0.818819642067 1.35235083103 1.22545087337
+vc -0.564012765884 1.35235083103 1.36164772511
+vc -0.287531226873 1.35235083103 1.44551753998
+vc 1.75753314124e-08 1.35235083103 1.47383689880
+vc -2.04208803177 1.44259011745 1.78524999228e-07
+vc -2.00284981728 1.44259011745 0.398391813040
+vc -1.88664305210 1.44259011745 0.781473457813
+vc -1.69793379307 1.44259011745 1.13452351093
+vc -1.44397389889 1.44258999825 1.44397425652
+vc -1.13452291489 1.44258999825 1.69793426991
+vc -0.781472921371 1.44258999825 1.88664340973
+vc -0.398391425610 1.44258999825 2.00284957886
+vc 2.43516495857e-08 1.44258999825 2.04208779335
+vc -2.67769289017 1.38483130932 2.34091345419e-07
+vc -2.62624144554 1.38483130932 0.522392213345
+vc -2.47386527061 1.38483130932 1.02470898628
+vc -2.22641968727 1.38483130932 1.48764669895
+vc -1.89341437817 1.38483130932 1.89341485500
+vc -1.48764598370 1.38483142853 2.22642064095
+vc -1.02470839024 1.38483142853 2.47386574745
+vc -0.522391736507 1.38483154774 2.62624168396
+vc 3.19311794783e-08 1.38483154774 2.67769289017
+vc -3.35748648643 1.14598357677 2.93520798778e-07
+vc -3.29297351837 1.14598369598 0.655013501644
+vc -3.10191297531 1.14598369598 1.28485488892
+vc -2.79164743423 1.14598369598 1.86531996727
+vc -2.37410116196 1.14598369598 2.37410187721
+vc -1.86531913280 1.14598369598 2.79164862633
+vc -1.28485405445 1.14598381519 3.10191321373
+vc -0.655012905598 1.14598381519 3.29297351837
+vc 4.00376336529e-08 1.14598381519 3.35748672485
+vc -3.97504377365 0.693362772465 3.47509370613e-07
+vc -3.89866423607 0.693362772465 0.775493085384
+vc -3.67246127129 0.693362951279 1.52118396759
+vc -3.30512762070 0.693362951279 2.20841646194
+vc -2.81078028679 0.693363010883 2.81078100204
+vc -2.20841550827 0.693363010883 3.30512857437
+vc -1.52118289471 0.693363010883 3.67246198654
+vc -0.775492310524 0.693363010883 3.89866423607
+vc 4.74019259400e-08 0.693363010883 3.97504401207
+vc -4.25838994980 0.154062956572 3.72280283045e-07
+vc -4.17656612396 0.154063045979 0.830771148205
+vc -3.93423891068 0.154063135386 1.62961590290
+vc -3.54072165489 0.154063224792 2.36583542824
+vc -3.01113581657 0.154063224792 3.01113724709
+vc -2.36583399773 0.154063314199 3.54072260857
+vc -1.62961435318 0.154063314199 3.93424034119
+vc -0.830769896507 0.154063388705 4.17656660080
+vc 5.58420424568e-07 0.154063388705 4.25838994980
+vc -4.10428714752 -0.0565397106111 3.58808165402e-07
+vc -4.02542400360 -0.0565396137536 0.800707101822
+vc -3.79186630249 -0.0565395243466 1.57064330578
+vc -3.41258955002 -0.0565395243466 2.28022027016
+vc -2.90216851234 -0.0565394312143 2.90216994286
+vc -2.28021883965 -0.0565393380821 3.41259050369
+vc -1.57064163685 -0.0565393380821 3.79186701775
+vc -0.800705909729 -0.0565393380821 4.02542448044
+vc 5.38212248102e-07 -0.0565393380821 4.10428714752
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc -0.0231357347220 0.0675957724452 -8.47294813866e-06
+vc -0.0226928405464 0.0675957724452 0.00450524874032
+vc -0.0213778764009 0.0675957724452 0.00884583592415
+vc -0.0192413665354 0.0675957724452 0.0128464819863
+vc -0.0163654275239 0.0675957724452 0.0163534451276
+vc -0.0128605719656 0.0675957724452 0.0192319583148
+vc -0.00886149052531 0.0675957724452 0.0213713925332
+vc -0.00452184537426 0.0675954222679 0.0226894188672
+vc -8.47499632073e-06 0.0675954222679 0.0231356173754
+vc -0.320522040129 0.576694130898 -2.35200441239e-05
+vc -0.314367890358 0.576694130898 0.0625076964498
+vc -0.296132773161 0.576694130898 0.122636742890
+vc -0.266517370939 0.576694130898 0.178052991629
+vc -0.226659819484 0.576693892479 0.226626589894
+vc -0.178091943264 0.576693892479 0.266491204500
+vc -0.122680127621 0.576693892479 0.296114623547
+vc -0.0625537782907 0.576693892479 0.314358592033
+vc -2.35330317082e-05 0.576693892479 0.320521891117
+vc -0.604020476341 0.872910022736 -5.00546775584e-06
+vc -0.592415392399 0.872910022736 0.117833644152
+vc -0.558044135571 0.872910022736 0.231144011021
+vc -0.502227485180 0.872910022736 0.335571676493
+vc -0.427110403776 0.872909784317 0.427103370428
+vc -0.335579842329 0.872909784317 0.502221763134
+vc -0.231153160334 0.872909784317 0.558040142059
+vc -0.117843419313 0.872909784317 0.592413306236
+vc -5.03313503941e-06 0.872909784317 0.604020416737
+vc -0.988540112972 1.14608085155 8.64209184215e-08
+vc -0.969545662403 1.14608085155 0.192854717374
+vc -0.913291871548 1.14608085155 0.378298044205
+vc -0.821940958500 1.14608085155 0.549203515053
+vc -0.699003279209 1.14608085155 0.699003458023
+vc -0.549203217030 1.14608073235 0.821941137314
+vc -0.378297746181 1.14608073235 0.913291931152
+vc -0.192854508758 1.14608073235 0.969545483589
+vc 1.17882308359e-08 1.14608073235 0.988539993763
+vc -1.47383701801 1.35235083103 1.28846920688e-07
+vc -1.44551765919 1.35235083103 0.287531495094
+vc -1.36164784431 1.35235095024 0.564013183117
+vc -1.22545051575 1.35235095024 0.818820118904
+vc -1.04215991497 1.35235095024 1.04216027260
+vc -0.818819642067 1.35235083103 1.22545087337
+vc -0.564012765884 1.35235083103 1.36164772511
+vc -0.287531226873 1.35235083103 1.44551753998
+vc 1.75753314124e-08 1.35235083103 1.47383689880
+vc -2.67769289017 1.38483130932 2.34091345419e-07
+vc -2.62624144554 1.38483130932 0.522392213345
+vc -2.47386527061 1.38483130932 1.02470898628
+vc -2.22641968727 1.38483130932 1.48764669895
+vc -1.89341437817 1.38483130932 1.89341485500
+vc -1.48764598370 1.38483142853 2.22642064095
+vc -1.02470839024 1.38483142853 2.47386574745
+vc -0.522391736507 1.38483154774 2.62624168396
+vc 3.19311794783e-08 1.38483154774 2.67769289017
+vc -4.10428714752 -0.0565397106111 3.58808165402e-07
+vc -4.02542400360 -0.0565396137536 0.800707101822
+vc -3.79186630249 -0.0565395243466 1.57064330578
+vc -3.41258955002 -0.0565395243466 2.28022027016
+vc -2.90216851234 -0.0565394312143 2.90216994286
+vc -2.28021883965 -0.0565393380821 3.41259050369
+vc -1.57064163685 -0.0565393380821 3.79186701775
+vc -0.800705909729 -0.0565393380821 4.02542448044
+vc 5.38212248102e-07 -0.0565393380821 4.10428714752
+vc -4.10428714752 -0.0565397106111 3.58808165402e-07
+vc -4.02542400360 -0.0565396137536 0.800707101822
+vc -3.79186630249 -0.0565395243466 1.57064330578
+vc -3.41258955002 -0.0565395243466 2.28022027016
+vc -2.90216851234 -0.0565394312143 2.90216994286
+vc -2.28021883965 -0.0565393380821 3.41259050369
+vc -1.57064163685 -0.0565393380821 3.79186701775
+vc -0.800705909729 -0.0565393380821 4.02542448044
+vc 5.38212248102e-07 -0.0565393380821 4.10428714752
+vc -4.10428714752 -0.0565397106111 3.58808165402e-07
+vc -4.02542400360 -0.0565396137536 0.800707101822
+vc -3.79186630249 -0.0565395243466 1.57064330578
+vc -3.41258955002 -0.0565395243466 2.28022027016
+vc -2.90216851234 -0.0565394312143 2.90216994286
+vc -2.28021883965 -0.0565393380821 3.41259050369
+vc -1.57064163685 -0.0565393380821 3.79186701775
+vc -0.800705909729 -0.0565393380821 4.02542448044
+vc 5.38212248102e-07 -0.0565393380821 4.10428714752
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc -8.47469527798e-06 0.0675957724452 0.0231357347220
+vc 0.00450524734333 0.0675957724452 0.0226928405464
+vc 0.00884583406150 0.0675957724452 0.0213778764009
+vc 0.0128464801237 0.0675957724452 0.0192413683981
+vc 0.0163534432650 0.0675957724452 0.0163654293865
+vc 0.0192319564521 0.0675957724452 0.0128605738282
+vc 0.0213713925332 0.0675957724452 0.00886149238795
+vc 0.0226894188672 0.0675954222679 0.00452184677124
+vc 0.0231356173754 0.0675954222679 8.47674346005e-06
+vc -3.04850873363e-05 0.297297626734 0.131333187222
+vc 0.0255919378251 0.297297626734 0.128815606236
+vc 0.0502308756113 0.297297626734 0.121347717941
+vc 0.0729394704103 0.297297626734 0.109216496348
+vc 0.0928450524807 0.297297626734 0.0928881466389
+vc 0.109182514250 0.297297298908 0.0729900747538
+vc 0.121324263513 0.297297298908 0.0502871386707
+vc 0.128803580999 0.297297298908 0.0256517026573
+vc 0.131333068013 0.297297298908 3.04908116959e-05
+vc -2.35442439589e-05 0.576694130898 0.320522040129
+vc 0.0625076740980 0.576694130898 0.314367890358
+vc 0.122636720538 0.576694130898 0.296132773161
+vc 0.178052961826 0.576694130898 0.266517400742
+vc 0.226626574993 0.576693892479 0.226659834385
+vc 0.266491174698 0.576693892479 0.178091973066
+vc 0.296114623547 0.576693892479 0.122680149972
+vc 0.314358592033 0.576693892479 0.0625538006425
+vc 0.320521891117 0.576693892479 2.35572315432e-05
+vc -5.05107027493e-06 0.872910022736 0.604020476341
+vc 0.117833599448 0.872910022736 0.592415392399
+vc 0.231143966317 0.872910022736 0.558044135571
+vc 0.335571646690 0.872910022736 0.502227485180
+vc 0.427103340626 0.872909784317 0.427110433578
+vc 0.502221763134 0.872909784317 0.335579872131
+vc 0.558040142059 0.872909784317 0.231153205037
+vc 0.592413306236 0.872909784317 0.117843464017
+vc 0.604020416737 0.872909784317 5.07873755851e-06
+vc 1.17882246187e-08 1.14608085155 0.988540112972
+vc 0.192854642868 1.14608085155 0.969545662403
+vc 0.378297954798 1.14608085155 0.913291931152
+vc 0.549203455448 1.14608085155 0.821941018105
+vc 0.699003398418 1.14608085155 0.699003338814
+vc 0.821941077709 1.14608073235 0.549203276634
+vc 0.913291871548 1.14608073235 0.378297835588
+vc 0.969545483589 1.14608073235 0.192854583263
+vc 0.988539993763 1.14608073235 6.28444567496e-08
+vc 1.75753296361e-08 1.35235083103 1.47383701801
+vc 0.287531405687 1.35235083103 1.44551765919
+vc 0.564013063908 1.35235095024 1.36164784431
+vc 0.818819999695 1.35235095024 1.22545063496
+vc 1.04216015339 1.35235095024 1.04216003418
+vc 1.22545075417 1.35235083103 0.818819761276
+vc 1.36164772511 1.35235083103 0.564012885094
+vc 1.44551753998 1.35235083103 0.287531316280
+vc 1.47383689880 1.35235083103 9.36962578635e-08
+vc 2.43516566911e-08 1.44259011745 2.04208803177
+vc 0.398391664028 1.44259011745 2.00284981728
+vc 0.781473278999 1.44259011745 1.88664317131
+vc 1.13452339172 1.44259011745 1.69793391228
+vc 1.44397413731 1.44258999825 1.44397401810
+vc 1.69793415070 1.44258999825 1.13452303410
+vc 1.88664329052 1.44258999825 0.781473100185
+vc 2.00284957886 1.44258999825 0.398391574621
+vc 2.04208779335 1.44258999825 1.29821685846e-07
+vc 3.19311723729e-08 1.38483130932 2.67769289017
+vc 0.522392034531 1.38483130932 2.62624144554
+vc 1.02470874786 1.38483130932 2.47386527061
+vc 1.48764646053 1.38483130932 2.22641992569
+vc 1.89341473579 1.38483130932 1.89341449738
+vc 2.22642040253 1.38483142853 1.48764622211
+vc 2.47386574745 1.38483142853 1.02470862865
+vc 2.62624168396 1.38483154774 0.522391915321
+vc 2.67769289017 1.38483154774 1.70229000673e-07
+vc 4.00376265475e-08 1.14598357677 3.35748648643
+vc 0.655013263226 1.14598369598 3.29297351837
+vc 1.28485465050 1.14598369598 3.10191297531
+vc 1.86531972885 1.14598369598 2.79164767265
+vc 2.37410163879 1.14598369598 2.37410140038
+vc 2.79164838791 1.14598369598 1.86531937122
+vc 3.10191321373 1.14598381519 1.28485429287
+vc 3.29297351837 1.14598381519 0.655013144016
+vc 3.35748672485 1.14598381519 2.13445531472e-07
+vc 4.74019223873e-08 0.693362772465 3.97504377365
+vc 0.775492787361 0.693362772465 3.89866423607
+vc 1.52118360996 0.693362951279 3.67246150970
+vc 2.20841622353 0.693362951279 3.30512785912
+vc 2.81078076363 0.693363010883 2.81078052521
+vc 3.30512833595 0.693363010883 2.20841574669
+vc 3.67246174812 0.693363010883 1.52118325233
+vc 3.89866423607 0.693363010883 0.775492608547
+vc 3.97504401207 0.693363010883 2.52705518733e-07
+vc 5.07807840222e-08 0.154062956572 4.25838994980
+vc 0.830770850182 0.154063045979 4.17656612396
+vc 1.62961554527 0.154063135386 3.93423914909
+vc 2.36583518982 0.154063224792 3.54072189331
+vc 3.01113700867 0.154063224792 3.01113605499
+vc 3.54072237015 0.154063314199 2.36583423615
+vc 3.93424010277 0.154063314199 1.62961471081
+vc 4.17656660080 0.154063388705 0.830770194530
+vc 4.25838994980 0.154063388705 -2.36920925545e-07
+vc 4.89431357664e-08 -0.0565397106111 4.10428714752
+vc 0.800706803799 -0.0565396137536 4.02542400360
+vc 1.57064294815 -0.0565395243466 3.79186654091
+vc 2.28022003174 -0.0565395243466 3.41258978844
+vc 2.90216970444 -0.0565394312143 2.90216875076
+vc 3.41259026527 -0.0565393380821 2.28021907806
+vc 3.79186677933 -0.0565393380821 1.57064199448
+vc 4.02542448044 -0.0565393380821 0.800706207752
+vc 4.10428714752 -0.0565393380821 -2.28347204256e-07
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc -8.47469527798e-06 0.0675957724452 0.0231357347220
+vc 0.00450524734333 0.0675957724452 0.0226928405464
+vc 0.00884583406150 0.0675957724452 0.0213778764009
+vc 0.0128464801237 0.0675957724452 0.0192413683981
+vc 0.0163534432650 0.0675957724452 0.0163654293865
+vc 0.0192319564521 0.0675957724452 0.0128605738282
+vc 0.0213713925332 0.0675957724452 0.00886149238795
+vc 0.0226894188672 0.0675954222679 0.00452184677124
+vc 0.0231356173754 0.0675954222679 8.47674346005e-06
+vc -2.35442439589e-05 0.576694130898 0.320522040129
+vc 0.0625076740980 0.576694130898 0.314367890358
+vc 0.122636720538 0.576694130898 0.296132773161
+vc 0.178052961826 0.576694130898 0.266517400742
+vc 0.226626574993 0.576693892479 0.226659834385
+vc 0.266491174698 0.576693892479 0.178091973066
+vc 0.296114623547 0.576693892479 0.122680149972
+vc 0.314358592033 0.576693892479 0.0625538006425
+vc 0.320521891117 0.576693892479 2.35572315432e-05
+vc -5.05107027493e-06 0.872910022736 0.604020476341
+vc 0.117833599448 0.872910022736 0.592415392399
+vc 0.231143966317 0.872910022736 0.558044135571
+vc 0.335571646690 0.872910022736 0.502227485180
+vc 0.427103340626 0.872909784317 0.427110433578
+vc 0.502221763134 0.872909784317 0.335579872131
+vc 0.558040142059 0.872909784317 0.231153205037
+vc 0.592413306236 0.872909784317 0.117843464017
+vc 0.604020416737 0.872909784317 5.07873755851e-06
+vc 1.17882246187e-08 1.14608085155 0.988540112972
+vc 0.192854642868 1.14608085155 0.969545662403
+vc 0.378297954798 1.14608085155 0.913291931152
+vc 0.549203455448 1.14608085155 0.821941018105
+vc 0.699003398418 1.14608085155 0.699003338814
+vc 0.821941077709 1.14608073235 0.549203276634
+vc 0.913291871548 1.14608073235 0.378297835588
+vc 0.969545483589 1.14608073235 0.192854583263
+vc 0.988539993763 1.14608073235 6.28444567496e-08
+vc 1.75753296361e-08 1.35235083103 1.47383701801
+vc 0.287531405687 1.35235083103 1.44551765919
+vc 0.564013063908 1.35235095024 1.36164784431
+vc 0.818819999695 1.35235095024 1.22545063496
+vc 1.04216015339 1.35235095024 1.04216003418
+vc 1.22545075417 1.35235083103 0.818819761276
+vc 1.36164772511 1.35235083103 0.564012885094
+vc 1.44551753998 1.35235083103 0.287531316280
+vc 1.47383689880 1.35235083103 9.36962578635e-08
+vc 3.19311723729e-08 1.38483130932 2.67769289017
+vc 0.522392034531 1.38483130932 2.62624144554
+vc 1.02470874786 1.38483130932 2.47386527061
+vc 1.48764646053 1.38483130932 2.22641992569
+vc 1.89341473579 1.38483130932 1.89341449738
+vc 2.22642040253 1.38483142853 1.48764622211
+vc 2.47386574745 1.38483142853 1.02470862865
+vc 2.62624168396 1.38483154774 0.522391915321
+vc 2.67769289017 1.38483154774 1.70229000673e-07
+vc 4.89431357664e-08 -0.0565397106111 4.10428714752
+vc 0.800706803799 -0.0565396137536 4.02542400360
+vc 1.57064294815 -0.0565395243466 3.79186654091
+vc 2.28022003174 -0.0565395243466 3.41258978844
+vc 2.90216970444 -0.0565394312143 2.90216875076
+vc 3.41259026527 -0.0565393380821 2.28021907806
+vc 3.79186677933 -0.0565393380821 1.57064199448
+vc 4.02542448044 -0.0565393380821 0.800706207752
+vc 4.10428714752 -0.0565393380821 -2.28347204256e-07
+vc 4.89431357664e-08 -0.0565397106111 4.10428714752
+vc 0.800706803799 -0.0565396137536 4.02542400360
+vc 1.57064294815 -0.0565395243466 3.79186654091
+vc 2.28022003174 -0.0565395243466 3.41258978844
+vc 2.90216970444 -0.0565394312143 2.90216875076
+vc 3.41259026527 -0.0565393380821 2.28021907806
+vc 3.79186677933 -0.0565393380821 1.57064199448
+vc 4.02542448044 -0.0565393380821 0.800706207752
+vc 4.10428714752 -0.0565393380821 -2.28347204256e-07
+vc 4.89431357664e-08 -0.0565397106111 4.10428714752
+vc 0.800706803799 -0.0565396137536 4.02542400360
+vc 1.57064294815 -0.0565395243466 3.79186654091
+vc 2.28022003174 -0.0565395243466 3.41258978844
+vc 2.90216970444 -0.0565394312143 2.90216875076
+vc 3.41259026527 -0.0565393380821 2.28021907806
+vc 3.79186677933 -0.0565393380821 1.57064199448
+vc 4.02542448044 -0.0565393380821 0.800706207752
+vc 4.10428714752 -0.0565393380821 -2.28347204256e-07
+vc 4.11531972885 0.156813323498 -0.281369030476
+vc 4.12518215179 0.0738224312663 -0.301320075989
+vc 4.09934043884 -0.0409938506782 -0.165720313787
+vc 4.10428714752 -0.0565397106111 0.00000000000
+vc 4.10428714752 -0.0565397106111 0.00000000000
+vc 4.11574554443 -0.0565155819058 -0.000439705239842
+vc 4.30464649200 -0.0546659342945 -0.00991629716009
+vc 4.38447713852 -0.0490531846881 -0.0243181977421
+vc 4.04046821594 -0.0386698320508 -0.0348165184259
+vc 3.26701450348 -0.0297298487276 -0.0356816798449
+vc 2.46035099030 -0.0226897522807 -0.0267999563366
+vc 1.73491787910 -0.0194615926594 -0.0176993291825
+vc 1.72265613079 -0.0136855924502 -0.0163860470057
+vc 1.71352374554 -0.0109421284869 -0.0151271810755
+vc 1.70721590519 -0.00639961380512 -0.0139174815267
+vc 1.70345759392 -0.00497314799577 -0.0127522032708
+vc 1.70194685459 -0.00168254843447 -0.0116261169314
+vc 1.70251107216 -0.00114440405741 -0.0105362441391
+vc 1.70513868332 0.00146822468378 -0.00948240980506
+vc 1.70998597145 0.00158006174024 -0.00846736878157
+vc 1.71705317497 0.00345693458803 -0.00749116204679
+vc 1.71955072880 0.00253324722871 -0.00721141509712
+vc 4.11542224884 0.164881870151 -0.264504671097
+vc 4.12610435486 0.0827928856015 -0.281253993511
+vc 4.10943126678 -0.0318338721991 -0.131319016218
+vc 4.10428714752 -0.0565397106111 0.00000000000
+vc 4.10428714752 -0.0565397106111 0.00000000000
+vc 4.11356544495 -0.0566066280007 0.00000000000
+vc 4.30940628052 -0.0573288910091 0.00000000000
+vc 4.41483068466 -0.0571045428514 0.00000000000
+vc 4.09861946106 -0.0521330311894 0.00000000000
+vc 3.33652591705 -0.0481452606618 0.00000000000
+vc 2.51682543755 -0.0393860898912 0.00000000000
+vc 1.76495790482 -0.0354805402458 0.00000000000
+vc 1.75267505646 -0.0255220606923 0.00000000000
+vc 1.74352216721 -0.0214124806225 0.00000000000
+vc 1.73719418049 -0.0120333172381 0.00000000000
+vc 1.73341608047 -0.00959443580359 0.00000000000
+vc 1.73188591003 -0.00117364781909 0.00000000000
+vc 1.73243105412 4.22244847869e-05 0.00000000000
+vc 1.73503994942 0.00885279569775 0.00000000000
+vc 1.73986876011 0.00982592441142 0.00000000000
+vc 1.74691784382 0.0184789095074 0.00000000000
+vc 1.74941003323 0.0155759835616 0.00000000000
+vc 4.11605215073 0.162553936243 -0.252731055021
+vc 4.12732410431 0.0761898234487 -0.264677196741
+vc 4.10905027390 -0.0389517359436 -0.0823076665401
+vc 4.10428714752 -0.0565397106111 0.00000000000
+vc 4.10428714752 -0.0565397106111 0.00000000000
+vc 4.11574554443 -0.0565155819058 0.000439705239842
+vc 4.30464649200 -0.0546659305692 0.00991629716009
+vc 4.38447713852 -0.0490532256663 0.0243181977421
+vc 4.04046821594 -0.0386698246002 0.0348165184259
+vc 3.26701450348 -0.0297299101949 0.0356816798449
+vc 2.46035099030 -0.0226898342371 0.0267999563366
+vc 1.73491787910 -0.0194616839290 0.0176993291825
+vc 1.72265613079 -0.0136856473982 0.0163860470057
+vc 1.71352374554 -0.0109421992674 0.0151271810755
+vc 1.70721590519 -0.00639958214015 0.0139174815267
+vc 1.70345759392 -0.00497310608625 0.0127522032708
+vc 1.70194685459 -0.00168256612960 0.0116261169314
+vc 1.70251107216 -0.00114439486060 0.0105362441391
+vc 1.70513868332 0.00146825239062 0.00948240980506
+vc 1.70998597145 0.00158008735161 0.00846736878157
+vc 1.71705317497 0.00345689314418 0.00749116204679
+vc 1.71955072880 0.00253308471292 0.00721141509712
+vc 3.42328667641 0.156813323498 -2.30133271217
+vc 3.42185235023 0.0738224312663 -2.32354187965
+vc 3.46727275848 -0.0409938506782 -2.19318819046
+vc 3.55441689491 -0.0565397106111 -2.05214357376
+vc 3.55441689491 -0.0565397106111 -2.05214357376
+vc 3.56412029266 -0.0565155819058 -2.05825352669
+vc 3.72297501564 -0.0546659342945 -2.16091108322
+vc 3.78490948677 -0.0490531846881 -2.21329879761
+vc 3.48173975945 -0.0386698320508 -2.05038619041
+vc 2.81147670746 -0.0297298487276 -1.66440844536
+vc 2.11732625961 -0.0226897522807 -1.25338494778
+vc 1.49363327026 -0.0194615926594 -0.882786989212
+vc 1.48367094994 -0.0136855924502 -0.875518798828
+vc 1.47639143467 -0.0109421284869 -0.869862377644
+vc 1.47153353691 -0.00639961380512 -0.865660846233
+vc 1.46886134148 -0.00497314799577 -0.862772524357
+vc 1.46811616421 -0.00168254843447 -0.861041963100
+vc 1.46914970875 -0.00114440405741 -0.860380172729
+vc 1.47195219994 0.00146822468378 -0.860781371593
+vc 1.47665750980 0.00158006174024 -0.862325966358
+vc 1.48326611519 0.00345693458803 -0.865014135838
+vc 1.48556888103 0.00253324722871 -0.866020619869
+vc 3.43180799484 0.164881870151 -2.28677892685
+vc 3.43268418312 0.0827928856015 -2.30662536621
+vc 3.49321222305 -0.0318338721991 -2.16844129562
+vc 3.55441689491 -0.0565397106111 -2.05214357376
+vc 3.55441689491 -0.0565397106111 -2.05214357376
+vc 3.56245207787 -0.0566066280007 -2.05678272247
+vc 3.73205518723 -0.0573288910091 -2.15470314026
+vc 3.82335543633 -0.0571045428514 -2.20741534233
+vc 3.54950857162 -0.0521330311894 -2.04930973053
+vc 2.88951611519 -0.0481452606618 -1.66826295853
+vc 2.17963480949 -0.0393860898912 -1.25841271877
+vc 1.52849841118 -0.0354805402458 -0.882478952408
+vc 1.51786112785 -0.0255220606923 -0.876337528229
+vc 1.50993442535 -0.0214124806225 -0.871761083603
+vc 1.50445425510 -0.0120333172381 -0.868597090244
+vc 1.50118231773 -0.00959443580359 -0.866708040237
+vc 1.49985718727 -0.00117364781909 -0.865942955017
+vc 1.50032925606 4.22244847869e-05 -0.866215527058
+vc 1.50258862972 0.00885279569775 -0.867519974709
+vc 1.50677049160 0.00982592441142 -0.869934380054
+vc 1.51287519932 0.0184789095074 -0.873458921909
+vc 1.51503348351 0.0155759835616 -0.874705016613
+vc 3.43824028969 0.162553936243 -2.27689766884
+vc 3.44202899933 0.0761898234487 -2.29287934303
+vc 3.51738786697 -0.0389517359436 -2.12580561638
+vc 3.55441689491 -0.0565397106111 -2.05214357376
+vc 3.55441689491 -0.0565397106111 -2.05214357376
+vc 3.56455993652 -0.0565155819058 -2.05749201775
+vc 3.73289132118 -0.0546659305692 -2.14373540878
+vc 3.80922770500 -0.0490532256663 -2.17117834091
+vc 3.51655650139 -0.0386698246002 -1.99008214474
+vc 2.84715843201 -0.0297299101949 -1.60260605812
+vc 2.14412641525 -0.0226898342371 -1.20696604252
+vc 1.51133251190 -0.0194616839290 -0.852130889893
+vc 1.50005698204 -0.0136856473982 -0.847137331963
+vc 1.49151861668 -0.0109421992674 -0.843661367893
+vc 1.48545098305 -0.00639958214015 -0.841555058956
+vc 1.48161363602 -0.00497310608625 -0.840685069561
+vc 1.47974216938 -0.00168256612960 -0.840904891491
+vc 1.47968590260 -0.00114439486060 -0.842130899429
+vc 1.48143458366 0.00146825239062 -0.844357311726
+vc 1.48512494564 0.00158008735161 -0.847660005093
+vc 1.49075722694 0.00345689314418 -0.852039039135
+vc 1.49278032780 0.00253308471292 -0.853530108929
+vc 1.81398689747 0.156813323498 -3.70465612411
+vc 1.80164003372 0.0738224312663 -3.72317266464
+vc 1.90615200996 -0.0409938506782 -3.63299345970
+vc 2.05214333534 -0.0565397106111 -3.55441713333
+vc 2.05214333534 -0.0565397106111 -3.55441713333
+vc 2.05749177933 -0.0565155819058 -3.56456017494
+vc 2.14373517036 -0.0546659342945 -3.73289155960
+vc 2.17117810249 -0.0490531846881 -3.80922794342
+vc 1.99008190632 -0.0386698320508 -3.51655673981
+vc 1.60260593891 -0.0297298487276 -2.84715867043
+vc 1.20696592331 -0.0226897522807 -2.14412665367
+vc 0.852130830288 -0.0194615926594 -1.51133263111
+vc 0.847137272358 -0.0136855924502 -1.50005710125
+vc 0.843661308289 -0.0109421284869 -1.49151873589
+vc 0.841554999352 -0.00639961380512 -1.48545110226
+vc 0.840685009956 -0.00497314799577 -1.48161375523
+vc 0.840904831886 -0.00168254843447 -1.47974228859
+vc 0.842130839825 -0.00114440405741 -1.47968602180
+vc 0.844357252121 0.00146822468378 -1.48143470287
+vc 0.847659945488 0.00158006174024 -1.48512506485
+vc 0.852038979530 0.00345693458803 -1.49075734615
+vc 0.853530049324 0.00253324722871 -1.49278044701
+vc 1.82864308357 0.164881870151 -3.69631266594
+vc 1.81947886944 0.0827928856015 -3.71393823624
+vc 1.94098973274 -0.0318338721991 -3.62453150749
+vc 2.05214333534 -0.0565397106111 -3.55441713333
+vc 2.05214333534 -0.0565397106111 -3.55441713333
+vc 2.05678248405 -0.0566066280007 -3.56245231628
+vc 2.15470290184 -0.0573288910091 -3.73205542564
+vc 2.20741510391 -0.0571045428514 -3.82335567474
+vc 2.04930949211 -0.0521330311894 -3.54950881004
+vc 1.66826283932 -0.0481452606618 -2.88951635361
+vc 1.25841259956 -0.0393860898912 -2.17963480949
+vc 0.882478892803 -0.0354805402458 -1.52849841118
+vc 0.876337468624 -0.0255220606923 -1.51786124706
+vc 0.871761023998 -0.0214124806225 -1.50993454456
+vc 0.868597030640 -0.0120333172381 -1.50445437431
+vc 0.866707980633 -0.00959443580359 -1.50118243694
+vc 0.865942895412 -0.00117364781909 -1.49985730648
+vc 0.866215467453 4.22244847869e-05 -1.50032937527
+vc 0.867519915104 0.00885279569775 -1.50258874893
+vc 0.869934320450 0.00982592441142 -1.50677061081
+vc 0.873458862305 0.0184789095074 -1.51287531853
+vc 0.874704957008 0.0155759835616 -1.51503360271
+vc 1.83915436268 0.162553936243 -3.69097137451
+vc 1.83444464207 0.0761898234487 -3.70670628548
+vc 1.98324441910 -0.0389517359436 -3.59969592094
+vc 2.05214333534 -0.0565397106111 -3.55441713333
+vc 2.05214333534 -0.0565397106111 -3.55441713333
+vc 2.05825328827 -0.0565155819058 -3.56412053108
+vc 2.16091084480 -0.0546659305692 -3.72297525406
+vc 2.21329855919 -0.0490532256663 -3.78490972519
+vc 2.05038595200 -0.0386698246002 -3.48173999786
+vc 1.66440832615 -0.0297299101949 -2.81147694588
+vc 1.25338482857 -0.0226898342371 -2.11732649803
+vc 0.882786929607 -0.0194616839290 -1.49363338947
+vc 0.875518739223 -0.0136856473982 -1.48367106915
+vc 0.869862318039 -0.0109421992674 -1.47639155388
+vc 0.865660786629 -0.00639958214015 -1.47153365612
+vc 0.862772464752 -0.00497310608625 -1.46886146069
+vc 0.861041903496 -0.00168256612960 -1.46811628342
+vc 0.860380113125 -0.00114439486060 -1.46914982796
+vc 0.860781311989 0.00146825239062 -1.47195231915
+vc 0.862325906754 0.00158008735161 -1.47665762901
+vc 0.865014076233 0.00345689314418 -1.48326623440
+vc 0.866020560265 0.00253308471292 -1.48556900024
+vc -0.281369209290 0.156813323498 -4.11531972885
+vc -0.301320254803 0.0738224312663 -4.12518215179
+vc -0.165720492601 -0.0409938506782 -4.09934043884
+vc -1.79404082701e-07 -0.0565397106111 -4.10428714752
+vc -1.79404082701e-07 -0.0565397106111 -4.10428714752
+vc -0.000439885130618 -0.0565155819058 -4.11574554443
+vc -0.00991648528725 -0.0546659342945 -4.30464649200
+vc -0.0243183895946 -0.0490531846881 -4.38447713852
+vc -0.0348166935146 -0.0386698320508 -4.04046821594
+vc -0.0356818214059 -0.0297298487276 -3.26701450348
+vc -0.0268000643700 -0.0226897522807 -2.46035099030
+vc -0.0176994055510 -0.0194615926594 -1.73491787910
+vc -0.0163861215115 -0.0136855924502 -1.72265613079
+vc -0.0151272555813 -0.0109421284869 -1.71352374554
+vc -0.0139175560325 -0.00639961380512 -1.70721590519
+vc -0.0127522777766 -0.00497314799577 -1.70345759392
+vc -0.0116261914372 -0.00168254843447 -1.70194685459
+vc -0.0105363186449 -0.00114440405741 -1.70251107216
+vc -0.00948248431087 0.00146822468378 -1.70513868332
+vc -0.00846744328737 0.00158006174024 -1.70998597145
+vc -0.00749123701826 0.00345693458803 -1.71705317497
+vc -0.00721149006858 0.00253324722871 -1.71955072880
+vc -0.264504849911 0.164881870151 -4.11542224884
+vc -0.281254172325 0.0827928856015 -4.12610435486
+vc -0.131319195032 -0.0318338721991 -4.10943126678
+vc -1.79404082701e-07 -0.0565397106111 -4.10428714752
+vc -1.79404082701e-07 -0.0565397106111 -4.10428714752
+vc -1.79809660494e-07 -0.0566066280007 -4.11356544495
+vc -1.88370137266e-07 -0.0573288910091 -4.30940628052
+vc -1.92978376390e-07 -0.0571045428514 -4.41483068466
+vc -1.79156344871e-07 -0.0521330311894 -4.09861946106
+vc -1.45844182953e-07 -0.0481452606618 -3.33652591705
+vc -1.10013935739e-07 -0.0393860898912 -2.51682543755
+vc -7.71487620455e-08 -0.0354805402458 -1.76495790482
+vc -7.66118617435e-08 -0.0255220606923 -1.75267505646
+vc -7.62117764452e-08 -0.0214124806225 -1.74352216721
+vc -7.59351692636e-08 -0.0120333172381 -1.73719418049
+vc -7.57700249210e-08 -0.00959443580359 -1.73341608047
+vc -7.57031344278e-08 -0.00117364781909 -1.73188591003
+vc -7.57269660312e-08 4.22244847869e-05 -1.73243105412
+vc -7.58410081403e-08 0.00885279569775 -1.73503994942
+vc -7.60520819654e-08 0.00982592441142 -1.73986876011
+vc -7.63602017173e-08 0.0184789095074 -1.74691784382
+vc -7.64691421296e-08 0.0155759835616 -1.74941003323
+vc -0.252731233835 0.162553936243 -4.11605215073
+vc -0.264677375555 0.0761898234487 -4.12732410431
+vc -0.0823078453541 -0.0389517359436 -4.10905027390
+vc -1.79404082701e-07 -0.0565397106111 -4.10428714752
+vc -1.79404082701e-07 -0.0565397106111 -4.10428714752
+vc 0.000439525349066 -0.0565155819058 -4.11574554443
+vc 0.00991610903293 -0.0546659305692 -4.30464649200
+vc 0.0243180058897 -0.0490532256663 -4.38447713852
+vc 0.0348163433373 -0.0386698246002 -4.04046821594
+vc 0.0356815382838 -0.0297299101949 -3.26701450348
+vc 0.0267998483032 -0.0226898342371 -2.46035099030
+vc 0.0176992528141 -0.0194616839290 -1.73491787910
+vc 0.0163859724998 -0.0136856473982 -1.72265613079
+vc 0.0151271065697 -0.0109421992674 -1.71352374554
+vc 0.0139174070209 -0.00639958214015 -1.70721590519
+vc 0.0127521287650 -0.00497310608625 -1.70345759392
+vc 0.0116260424256 -0.00168256612960 -1.70194685459
+vc 0.0105361696333 -0.00114439486060 -1.70251107216
+vc 0.00948233529925 0.00146825239062 -1.70513868332
+vc 0.00846729427576 0.00158008735161 -1.70998597145
+vc 0.00749108707532 0.00345689314418 -1.71705317497
+vc 0.00721134012565 0.00253308471292 -1.71955072880
+vc -2.30133295059 0.156813323498 -3.42328643799
+vc -2.32354211807 0.0738224312663 -3.42185211182
+vc -2.19318842888 -0.0409938506782 -3.46727252007
+vc -2.05214381218 -0.0565397106111 -3.55441665649
+vc -2.05214381218 -0.0565397106111 -3.55441665649
+vc -2.05825376511 -0.0565155819058 -3.56412005424
+vc -2.16091132164 -0.0546659342945 -3.72297477722
+vc -2.21329903603 -0.0490531846881 -3.78490924835
+vc -2.05038642883 -0.0386698320508 -3.48173952103
+vc -1.66440868378 -0.0297298487276 -2.81147646904
+vc -1.25338506699 -0.0226897522807 -2.11732625961
+vc -0.882787108421 -0.0194615926594 -1.49363315105
+vc -0.875518918037 -0.0136855924502 -1.48367083073
+vc -0.869862496853 -0.0109421284869 -1.47639131546
+vc -0.865660965443 -0.00639961380512 -1.47153353691
+vc -0.862772643566 -0.00497314799577 -1.46886122227
+vc -0.861042082310 -0.00168254843447 -1.46811604500
+vc -0.860380291939 -0.00114440405741 -1.46914958954
+vc -0.860781490803 0.00146822468378 -1.47195208073
+vc -0.862326085567 0.00158006174024 -1.47665739059
+vc -0.865014255047 0.00345693458803 -1.48326599598
+vc -0.866020739079 0.00253324722871 -1.48556876183
+vc -2.28677916527 0.164881870151 -3.43180751801
+vc -2.30662560463 0.0827928856015 -3.43268394470
+vc -2.16844153404 -0.0318338721991 -3.49321198463
+vc -2.05214381218 -0.0565397106111 -3.55441665649
+vc -2.05214381218 -0.0565397106111 -3.55441665649
+vc -2.05678296089 -0.0566066280007 -3.56245183945
+vc -2.15470337868 -0.0573288910091 -3.73205494881
+vc -2.20741558075 -0.0571045428514 -3.82335519791
+vc -2.04930996895 -0.0521330311894 -3.54950833321
+vc -1.66826319695 -0.0481452606618 -2.88951587677
+vc -1.25841283798 -0.0393860898912 -2.17963457108
+vc -0.882479071617 -0.0354805402458 -1.52849829197
+vc -0.876337647438 -0.0255220606923 -1.51786100864
+vc -0.871761202812 -0.0214124806225 -1.50993430614
+vc -0.868597209454 -0.0120333172381 -1.50445413589
+vc -0.866708159447 -0.00959443580359 -1.50118219852
+vc -0.865943074226 -0.00117364781909 -1.49985706806
+vc -0.866215646267 4.22244847869e-05 -1.50032913685
+vc -0.867520093918 0.00885279569775 -1.50258851051
+vc -0.869934499264 0.00982592441142 -1.50677037239
+vc -0.873459041119 0.0184789095074 -1.51287508011
+vc -0.874705135822 0.0155759835616 -1.51503336430
+vc -2.27689790726 0.162553936243 -3.43824005127
+vc -2.29287958145 0.0761898234487 -3.44202876091
+vc -2.12580585480 -0.0389517359436 -3.51738762856
+vc -2.05214381218 -0.0565397106111 -3.55441665649
+vc -2.05214381218 -0.0565397106111 -3.55441665649
+vc -2.05749225616 -0.0565155819058 -3.56455969810
+vc -2.14373564720 -0.0546659305692 -3.73289108276
+vc -2.17117857933 -0.0490532256663 -3.80922746658
+vc -1.99008238316 -0.0386698246002 -3.51655626297
+vc -1.60260629654 -0.0297299101949 -2.84715819359
+vc -1.20696616173 -0.0226898342371 -2.14412641525
+vc -0.852131009102 -0.0194616839290 -1.51133239269
+vc -0.847137451172 -0.0136856473982 -1.50005686283
+vc -0.843661487103 -0.0109421992674 -1.49151849747
+vc -0.841555178165 -0.00639958214015 -1.48545098305
+vc -0.840685188770 -0.00497310608625 -1.48161351681
+vc -0.840905010700 -0.00168256612960 -1.47974205017
+vc -0.842131018639 -0.00114439486060 -1.47968578339
+vc -0.844357430935 0.00146825239062 -1.48143446445
+vc -0.847660124302 0.00158008735161 -1.48512482643
+vc -0.852039158344 0.00345689314418 -1.49075710773
+vc -0.853530228138 0.00253308471292 -1.49278020859
+vc -3.70465564728 0.156813323498 -1.81398737431
+vc -3.72317218781 0.0738224312663 -1.80164051056
+vc -3.63299298286 -0.0409938506782 -1.90615248680
+vc -3.55441665649 -0.0565397106111 -2.05214381218
+vc -3.55441665649 -0.0565397106111 -2.05214381218
+vc -3.56455969810 -0.0565155819058 -2.05749225616
+vc -3.73289108276 -0.0546659342945 -2.14373564720
+vc -3.80922746658 -0.0490531846881 -2.17117857933
+vc -3.51655626297 -0.0386698320508 -1.99008238316
+vc -2.84715819359 -0.0297298487276 -1.60260629654
+vc -2.14412641525 -0.0226897522807 -1.20696616173
+vc -1.51133239269 -0.0194615926594 -0.852131009102
+vc -1.50005686283 -0.0136855924502 -0.847137451172
+vc -1.49151849747 -0.0109421284869 -0.843661487103
+vc -1.48545098305 -0.00639961380512 -0.841555178165
+vc -1.48161351681 -0.00497314799577 -0.840685188770
+vc -1.47974205017 -0.00168254843447 -0.840905010700
+vc -1.47968578339 -0.00114440405741 -0.842131018639
+vc -1.48143446445 0.00146822468378 -0.844357430935
+vc -1.48512482643 0.00158006174024 -0.847660124302
+vc -1.49075710773 0.00345693458803 -0.852039158344
+vc -1.49278020859 0.00253324722871 -0.853530228138
+vc -3.69631242752 0.164881870151 -1.82864356041
+vc -3.71393775940 0.0827928856015 -1.81947934628
+vc -3.62453103065 -0.0318338721991 -1.94099020958
+vc -3.55441665649 -0.0565397106111 -2.05214381218
+vc -3.55441665649 -0.0565397106111 -2.05214381218
+vc -3.56245183945 -0.0566066280007 -2.05678296089
+vc -3.73205494881 -0.0573288910091 -2.15470337868
+vc -3.82335519791 -0.0571045428514 -2.20741558075
+vc -3.54950833321 -0.0521330311894 -2.04930996895
+vc -2.88951587677 -0.0481452606618 -1.66826319695
+vc -2.17963457108 -0.0393860898912 -1.25841283798
+vc -1.52849829197 -0.0354805402458 -0.882479071617
+vc -1.51786100864 -0.0255220606923 -0.876337647438
+vc -1.50993430614 -0.0214124806225 -0.871761202812
+vc -1.50445413589 -0.0120333172381 -0.868597209454
+vc -1.50118219852 -0.00959443580359 -0.866708159447
+vc -1.49985706806 -0.00117364781909 -0.865943074226
+vc -1.50032913685 4.22244847869e-05 -0.866215646267
+vc -1.50258851051 0.00885279569775 -0.867520093918
+vc -1.50677037239 0.00982592441142 -0.869934499264
+vc -1.51287508011 0.0184789095074 -0.873459041119
+vc -1.51503336430 0.0155759835616 -0.874705135822
+vc -3.69097089767 0.162553936243 -1.83915483952
+vc -3.70670580864 0.0761898234487 -1.83444511890
+vc -3.59969544411 -0.0389517359436 -1.98324489594
+vc -3.55441665649 -0.0565397106111 -2.05214381218
+vc -3.55441665649 -0.0565397106111 -2.05214381218
+vc -3.56412005424 -0.0565155819058 -2.05825376511
+vc -3.72297477722 -0.0546659305692 -2.16091132164
+vc -3.78490924835 -0.0490532256663 -2.21329903603
+vc -3.48173952103 -0.0386698246002 -2.05038642883
+vc -2.81147646904 -0.0297299101949 -1.66440868378
+vc -2.11732625961 -0.0226898342371 -1.25338506699
+vc -1.49363315105 -0.0194616839290 -0.882787108421
+vc -1.48367083073 -0.0136856473982 -0.875518918037
+vc -1.47639131546 -0.0109421992674 -0.869862496853
+vc -1.47153353691 -0.00639958214015 -0.865660965443
+vc -1.46886122227 -0.00497310608625 -0.862772643566
+vc -1.46811604500 -0.00168256612960 -0.861042082310
+vc -1.46914958954 -0.00114439486060 -0.860380291939
+vc -1.47195208073 0.00146825239062 -0.860781490803
+vc -1.47665739059 0.00158008735161 -0.862326085567
+vc -1.48326599598 0.00345689314418 -0.865014255047
+vc -1.48556876183 0.00253308471292 -0.866020739079
+vc -4.11531972885 0.156813323498 0.281369388103
+vc -4.12518215179 0.0738224312663 0.301320433617
+vc -4.09934043884 -0.0409938506782 0.165720671415
+vc -4.10428714752 -0.0565397106111 3.58808165402e-07
+vc -4.10428714752 -0.0565397106111 3.58808165402e-07
+vc -4.11574554443 -0.0565155819058 0.000440065050498
+vc -4.30464649200 -0.0546659342945 0.00991667341441
+vc -4.38447713852 -0.0490531846881 0.0243185814470
+vc -4.04046821594 -0.0386698320508 0.0348168723285
+vc -3.26701450348 -0.0297298487276 0.0356819666922
+vc -2.46035099030 -0.0226897522807 0.0268001705408
+vc -1.73491787910 -0.0194615926594 0.0176994800568
+vc -1.72265613079 -0.0136855924502 0.0163861978799
+vc -1.71352374554 -0.0109421284869 0.0151273310184
+vc -1.70721590519 -0.00639961380512 0.0139176305383
+vc -1.70345759392 -0.00497314799577 0.0127523522824
+vc -1.70194685459 -0.00168254843447 0.0116262659431
+vc -1.70251107216 -0.00114440405741 0.0105363931507
+vc -1.70513868332 0.00146822468378 0.00948255881667
+vc -1.70998597145 0.00158006174024 0.00846751872450
+vc -1.71705317497 0.00345693458803 0.00749131198972
+vc -1.71955072880 0.00253324722871 0.00721156550571
+vc -4.11542224884 0.164881870151 0.264505028725
+vc -4.12610435486 0.0827928856015 0.281254351139
+vc -4.10943126678 -0.0318338721991 0.131319373846
+vc -4.10428714752 -0.0565397106111 3.58808165402e-07
+vc -4.10428714752 -0.0565397106111 3.58808165402e-07
+vc -4.11356544495 -0.0566066280007 3.59619320989e-07
+vc -4.30940628052 -0.0573288910091 3.76740274532e-07
+vc -4.41483068466 -0.0571045428514 3.85956752780e-07
+vc -4.09861946106 -0.0521330311894 3.58312689741e-07
+vc -3.33652591705 -0.0481452606618 2.91688365905e-07
+vc -2.51682543755 -0.0393860898912 2.20027871478e-07
+vc -1.76495790482 -0.0354805402458 1.54297524091e-07
+vc -1.75267505646 -0.0255220606923 1.53223723487e-07
+vc -1.74352216721 -0.0214124806225 1.52423552890e-07
+vc -1.73719418049 -0.0120333172381 1.51870338527e-07
+vc -1.73341608047 -0.00959443580359 1.51540049842e-07
+vc -1.73188591003 -0.00117364781909 1.51406268856e-07
+vc -1.73243105412 4.22244847869e-05 1.51453932062e-07
+vc -1.73503994942 0.00885279569775 1.51682016281e-07
+vc -1.73986876011 0.00982592441142 1.52104163931e-07
+vc -1.74691784382 0.0184789095074 1.52720403435e-07
+vc -1.74941003323 0.0155759835616 1.52938284259e-07
+vc -4.11605215073 0.162553936243 0.252731412649
+vc -4.12732410431 0.0761898234487 0.264677554369
+vc -4.10905027390 -0.0389517359436 0.0823080241680
+vc -4.10428714752 -0.0565397106111 3.58808165402e-07
+vc -4.10428714752 -0.0565397106111 3.58808165402e-07
+vc -4.11574554443 -0.0565155819058 -0.000439345429186
+vc -4.30464649200 -0.0546659305692 -0.00991592090577
+vc -4.38447713852 -0.0490532256663 -0.0243178140372
+vc -4.04046821594 -0.0386698246002 -0.0348161645234
+vc -3.26701450348 -0.0297299101949 -0.0356813929975
+vc -2.46035099030 -0.0226898342371 -0.0267997421324
+vc -1.73491787910 -0.0194616839290 -0.0176991783082
+vc -1.72265613079 -0.0136856473982 -0.0163858961314
+vc -1.71352374554 -0.0109421992674 -0.0151270311326
+vc -1.70721590519 -0.00639958214015 -0.0139173325151
+vc -1.70345759392 -0.00497310608625 -0.0127520542592
+vc -1.70194685459 -0.00168256612960 -0.0116259679198
+vc -1.70251107216 -0.00114439486060 -0.0105360951275
+vc -1.70513868332 0.00146825239062 -0.00948226079345
+vc -1.70998597145 0.00158008735161 -0.00846721883863
+vc -1.71705317497 0.00345689314418 -0.00749101210386
+vc -1.71955072880 0.00253308471292 -0.00721126468852
+vc -3.42328691483 0.156813323498 2.30133247375
+vc -3.42185258865 0.0738224312663 2.32354164124
+vc -3.46727299690 -0.0409938506782 2.19318795204
+vc -3.55441713333 -0.0565397106111 2.05214333534
+vc -3.55441713333 -0.0565397106111 2.05214333534
+vc -3.56412053108 -0.0565155819058 2.05825328827
+vc -3.72297525406 -0.0546659342945 2.16091084480
+vc -3.78490972519 -0.0490531846881 2.21329855919
+vc -3.48173999786 -0.0386698320508 2.05038595200
+vc -2.81147694588 -0.0297298487276 1.66440832615
+vc -2.11732649803 -0.0226897522807 1.25338482857
+vc -1.49363338947 -0.0194615926594 0.882786929607
+vc -1.48367106915 -0.0136855924502 0.875518739223
+vc -1.47639155388 -0.0109421284869 0.869862318039
+vc -1.47153365612 -0.00639961380512 0.865660786629
+vc -1.46886146069 -0.00497314799577 0.862772464752
+vc -1.46811628342 -0.00168254843447 0.861041903496
+vc -1.46914982796 -0.00114440405741 0.860380113125
+vc -1.47195231915 0.00146822468378 0.860781311989
+vc -1.47665762901 0.00158006174024 0.862325906754
+vc -1.48326623440 0.00345693458803 0.865014076233
+vc -1.48556900024 0.00253324722871 0.866020560265
+vc -3.43180823326 0.164881870151 2.28677868843
+vc -3.43268442154 0.0827928856015 2.30662512779
+vc -3.49321246147 -0.0318338721991 2.16844105721
+vc -3.55441713333 -0.0565397106111 2.05214333534
+vc -3.55441713333 -0.0565397106111 2.05214333534
+vc -3.56245231628 -0.0566066280007 2.05678248405
+vc -3.73205542564 -0.0573288910091 2.15470290184
+vc -3.82335567474 -0.0571045428514 2.20741510391
+vc -3.54950881004 -0.0521330311894 2.04930949211
+vc -2.88951635361 -0.0481452606618 1.66826283932
+vc -2.17963480949 -0.0393860898912 1.25841259956
+vc -1.52849841118 -0.0354805402458 0.882478892803
+vc -1.51786124706 -0.0255220606923 0.876337468624
+vc -1.50993454456 -0.0214124806225 0.871761023998
+vc -1.50445437431 -0.0120333172381 0.868597030640
+vc -1.50118243694 -0.00959443580359 0.866707980633
+vc -1.49985730648 -0.00117364781909 0.865942895412
+vc -1.50032937527 4.22244847869e-05 0.866215467453
+vc -1.50258874893 0.00885279569775 0.867519915104
+vc -1.50677061081 0.00982592441142 0.869934320450
+vc -1.51287531853 0.0184789095074 0.873458862305
+vc -1.51503360271 0.0155759835616 0.874704957008
+vc -3.43824052811 0.162553936243 2.27689743042
+vc -3.44202923775 0.0761898234487 2.29287910461
+vc -3.51738810539 -0.0389517359436 2.12580537796
+vc -3.55441713333 -0.0565397106111 2.05214333534
+vc -3.55441713333 -0.0565397106111 2.05214333534
+vc -3.56456017494 -0.0565155819058 2.05749177933
+vc -3.73289155960 -0.0546659305692 2.14373517036
+vc -3.80922794342 -0.0490532256663 2.17117810249
+vc -3.51655673981 -0.0386698246002 1.99008190632
+vc -2.84715867043 -0.0297299101949 1.60260593891
+vc -2.14412665367 -0.0226898342371 1.20696592331
+vc -1.51133263111 -0.0194616839290 0.852130830288
+vc -1.50005710125 -0.0136856473982 0.847137272358
+vc -1.49151873589 -0.0109421992674 0.843661308289
+vc -1.48545110226 -0.00639958214015 0.841554999352
+vc -1.48161375523 -0.00497310608625 0.840685009956
+vc -1.47974228859 -0.00168256612960 0.840904831886
+vc -1.47968602180 -0.00114439486060 0.842130839825
+vc -1.48143470287 0.00146825239062 0.844357252121
+vc -1.48512506485 0.00158008735161 0.847659945488
+vc -1.49075734615 0.00345689314418 0.852038979530
+vc -1.49278044701 0.00253308471292 0.853530049324
+vc -1.81398665905 0.156813323498 3.70465612411
+vc -1.80163979530 0.0738224312663 3.72317290306
+vc -1.90615177155 -0.0409938506782 3.63299369812
+vc -2.05214309692 -0.0565397106111 3.55441737175
+vc -2.05214309692 -0.0565397106111 3.55441737175
+vc -2.05749154091 -0.0565155819058 3.56456041336
+vc -2.14373493195 -0.0546659342945 3.73289179802
+vc -2.17117786407 -0.0490531846881 3.80922818184
+vc -1.99008166790 -0.0386698320508 3.51655697823
+vc -1.60260581970 -0.0297298487276 2.84715867043
+vc -1.20696580410 -0.0226897522807 2.14412689209
+vc -0.852130711079 -0.0194615926594 1.51133275032
+vc -0.847137153149 -0.0136855924502 1.50005722046
+vc -0.843661189079 -0.0109421284869 1.49151885509
+vc -0.841554880142 -0.00639961380512 1.48545122147
+vc -0.840684890747 -0.00497314799577 1.48161387444
+vc -0.840904712677 -0.00168254843447 1.47974240780
+vc -0.842130720615 -0.00114440405741 1.47968614101
+vc -0.844357132912 0.00146822468378 1.48143482208
+vc -0.847659826279 0.00158006174024 1.48512518406
+vc -0.852038860321 0.00345693458803 1.49075734615
+vc -0.853529930115 0.00253324722871 1.49278056622
+vc -1.82864284515 0.164881870151 3.69631290436
+vc -1.81947863102 0.0827928856015 3.71393847466
+vc -1.94098949432 -0.0318338721991 3.62453174591
+vc -2.05214309692 -0.0565397106111 3.55441737175
+vc -2.05214309692 -0.0565397106111 3.55441737175
+vc -2.05678224564 -0.0566066280007 3.56245255470
+vc -2.15470266342 -0.0573288910091 3.73205566406
+vc -2.20741486549 -0.0571045428514 3.82335591316
+vc -2.04930925369 -0.0521330311894 3.54950904846
+vc -1.66826260090 -0.0481452606618 2.88951659203
+vc -1.25841248035 -0.0393860898912 2.17963504791
+vc -0.882478773594 -0.0354805402458 1.52849853039
+vc -0.876337349415 -0.0255220606923 1.51786124706
+vc -0.871760904789 -0.0214124806225 1.50993466377
+vc -0.868596911430 -0.0120333172381 1.50445449352
+vc -0.866707861423 -0.00959443580359 1.50118255615
+vc -0.865942776203 -0.00117364781909 1.49985742569
+vc -0.866215348244 4.22244847869e-05 1.50032949448
+vc -0.867519795895 0.00885279569775 1.50258886814
+vc -0.869934201241 0.00982592441142 1.50677073002
+vc -0.873458743095 0.0184789095074 1.51287543774
+vc -0.874704837799 0.0155759835616 1.51503372192
+vc -1.83915412426 0.162553936243 3.69097161293
+vc -1.83444440365 0.0761898234487 3.70670652390
+vc -1.98324418068 -0.0389517359436 3.59969615936
+vc -2.05214309692 -0.0565397106111 3.55441737175
+vc -2.05214309692 -0.0565397106111 3.55441737175
+vc -2.05825304985 -0.0565155819058 3.56412076950
+vc -2.16091060638 -0.0546659305692 3.72297549248
+vc -2.21329832077 -0.0490532256663 3.78490996361
+vc -2.05038571358 -0.0386698246002 3.48174023628
+vc -1.66440820694 -0.0297299101949 2.81147694588
+vc -1.25338470936 -0.0226898342371 2.11732673645
+vc -0.882786810398 -0.0194616839290 1.49363350868
+vc -0.875518620014 -0.0136856473982 1.48367118835
+vc -0.869862198830 -0.0109421992674 1.47639167309
+vc -0.865660667419 -0.00639958214015 1.47153377533
+vc -0.862772345543 -0.00497310608625 1.46886157990
+vc -0.861041784286 -0.00168256612960 1.46811640263
+vc -0.860379993916 -0.00114439486060 1.46914994717
+vc -0.860781192780 0.00146825239062 1.47195243835
+vc -0.862325787544 0.00158008735161 1.47665774822
+vc -0.865013957024 0.00345689314418 1.48326623440
+vc -0.866020441055 0.00253308471292 1.48556911945
+vc 0.281369090080 0.156813323498 4.11531972885
+vc 0.301320135593 0.0738224312663 4.12518215179
+vc 0.165720358491 -0.0409938506782 4.09934043884
+vc 4.89431357664e-08 -0.0565397106111 4.10428714752
+vc 4.89431357664e-08 -0.0565397106111 4.10428714752
+vc 0.000439754308900 -0.0565155819058 4.11574554443
+vc 0.00991634838283 -0.0546659342945 4.30464649200
+vc 0.0243182498962 -0.0490531846881 4.38447713852
+vc 0.0348165668547 -0.0386698320508 4.04046821594
+vc 0.0356817170978 -0.0297298487276 3.26701450348
+vc 0.0267999861389 -0.0226897522807 2.46035099030
+vc 0.0176993496716 -0.0194615926594 1.73491787910
+vc 0.0163860674948 -0.0136855924502 1.72265613079
+vc 0.0151272015646 -0.0109421284869 1.71352374554
+vc 0.0139175020158 -0.00639961380512 1.70721590519
+vc 0.0127522237599 -0.00497314799577 1.70345759392
+vc 0.0116261374205 -0.00168254843447 1.70194685459
+vc 0.0105362646282 -0.00114440405741 1.70251107216
+vc 0.00948243029416 0.00146822468378 1.70513868332
+vc 0.00846738927066 0.00158006174024 1.70998597145
+vc 0.00749118253589 0.00345693458803 1.71705317497
+vc 0.00721143558621 0.00253324722871 1.71955072880
+vc 0.264504730701 0.164881870151 4.11542224884
+vc 0.281254053116 0.0827928856015 4.12610435486
+vc 0.131319060922 -0.0318338721991 4.10943126678
+vc 4.89431357664e-08 -0.0565397106111 4.10428714752
+vc 4.89431357664e-08 -0.0565397106111 4.10428714752
+vc 4.90537779285e-08 -0.0566066280007 4.11356544495
+vc 5.13891542653e-08 -0.0573288910091 4.30940628052
+vc 5.26463281858e-08 -0.0571045428514 4.41483068466
+vc 4.88755489414e-08 -0.0521330311894 4.09861946106
+vc 3.97876718239e-08 -0.0481452606618 3.33652591705
+vc 3.00128419894e-08 -0.0393860898912 2.51682543755
+vc 2.10469117690e-08 -0.0354805402458 1.76495790482
+vc 2.09004404894e-08 -0.0255220606923 1.75267505646
+vc 2.07912940198e-08 -0.0214124806225 1.74352216721
+vc 2.07158326049e-08 -0.0120333172381 1.73719418049
+vc 2.06707806427e-08 -0.00959443580359 1.73341608047
+vc 2.06525321289e-08 -0.00117364781909 1.73188591003
+vc 2.06590335949e-08 4.22244847869e-05 1.73243105412
+vc 2.06901447086e-08 0.00885279569775 1.73503994942
+vc 2.07477270919e-08 0.00982592441142 1.73986876011
+vc 2.08317860739e-08 0.0184789095074 1.74691784382
+vc 2.08615063002e-08 0.0155759835616 1.74941003323
+vc 0.252731114626 0.162553936243 4.11605215073
+vc 0.264677256346 0.0761898234487 4.12732410431
+vc 0.0823077186942 -0.0389517359436 4.10905027390
+vc 4.89431357664e-08 -0.0565397106111 4.10428714752
+vc 4.89431357664e-08 -0.0565397106111 4.10428714752
+vc -0.000439656170784 -0.0565155819058 4.11574554443
+vc -0.00991624593735 -0.0546659305692 4.30464649200
+vc -0.0243181455880 -0.0490532256663 4.38447713852
+vc -0.0348164699972 -0.0386698246002 4.04046821594
+vc -0.0356816425920 -0.0297299101949 3.26701450348
+vc -0.0267999265343 -0.0226898342371 2.46035099030
+vc -0.0176993086934 -0.0194616839290 1.73491787910
+vc -0.0163860265166 -0.0136856473982 1.72265613079
+vc -0.0151271605864 -0.0109421992674 1.71352374554
+vc -0.0139174610376 -0.00639958214015 1.70721590519
+vc -0.0127521827817 -0.00497310608625 1.70345759392
+vc -0.0116260964423 -0.00168256612960 1.70194685459
+vc -0.0105362236500 -0.00114439486060 1.70251107216
+vc -0.00948238931596 0.00146825239062 1.70513868332
+vc -0.00846734829247 0.00158008735161 1.70998597145
+vc -0.00749114155769 0.00345689314418 1.71705317497
+vc -0.00721139460802 0.00253308471292 1.71955072880
+vc 2.30133223534 0.156813323498 3.42328739166
+vc 2.32354140282 0.0738224312663 3.42185282707
+vc 2.19318771362 -0.0409938506782 3.46727323532
+vc 2.05214309692 -0.0565397106111 3.55441737175
+vc 2.05214309692 -0.0565397106111 3.55441737175
+vc 2.05825304985 -0.0565155819058 3.56412076950
+vc 2.16091060638 -0.0546659342945 3.72297549248
+vc 2.21329832077 -0.0490531846881 3.78490996361
+vc 2.05038571358 -0.0386698320508 3.48174023628
+vc 1.66440820694 -0.0297298487276 2.81147694588
+vc 1.25338470936 -0.0226897522807 2.11732673645
+vc 0.882786810398 -0.0194615926594 1.49363350868
+vc 0.875518620014 -0.0136855924502 1.48367118835
+vc 0.869862198830 -0.0109421284869 1.47639167309
+vc 0.865660667419 -0.00639961380512 1.47153377533
+vc 0.862772345543 -0.00497314799577 1.46886157990
+vc 0.861041784286 -0.00168254843447 1.46811640263
+vc 0.860379993916 -0.00114440405741 1.46914994717
+vc 0.860781192780 0.00146822468378 1.47195243835
+vc 0.862325787544 0.00158006174024 1.47665774822
+vc 0.865013957024 0.00345693458803 1.48326623440
+vc 0.866020441055 0.00253324722871 1.48556911945
+vc 2.28677845001 0.164881870151 3.43180847168
+vc 2.30662488937 0.0827928856015 3.43268465996
+vc 2.16844081879 -0.0318338721991 3.49321269989
+vc 2.05214309692 -0.0565397106111 3.55441737175
+vc 2.05214309692 -0.0565397106111 3.55441737175
+vc 2.05678224564 -0.0566066280007 3.56245255470
+vc 2.15470266342 -0.0573288910091 3.73205566406
+vc 2.20741486549 -0.0571045428514 3.82335591316
+vc 2.04930925369 -0.0521330311894 3.54950904846
+vc 1.66826260090 -0.0481452606618 2.88951659203
+vc 1.25841248035 -0.0393860898912 2.17963504791
+vc 0.882478773594 -0.0354805402458 1.52849853039
+vc 0.876337349415 -0.0255220606923 1.51786124706
+vc 0.871760904789 -0.0214124806225 1.50993466377
+vc 0.868596911430 -0.0120333172381 1.50445449352
+vc 0.866707861423 -0.00959443580359 1.50118255615
+vc 0.865942776203 -0.00117364781909 1.49985742569
+vc 0.866215348244 4.22244847869e-05 1.50032949448
+vc 0.867519795895 0.00885279569775 1.50258886814
+vc 0.869934201241 0.00982592441142 1.50677073002
+vc 0.873458743095 0.0184789095074 1.51287543774
+vc 0.874704837799 0.0155759835616 1.51503372192
+vc 2.27689719200 0.162553936243 3.43824076653
+vc 2.29287886620 0.0761898234487 3.44202947617
+vc 2.12580513954 -0.0389517359436 3.51738834381
+vc 2.05214309692 -0.0565397106111 3.55441737175
+vc 2.05214309692 -0.0565397106111 3.55441737175
+vc 2.05749154091 -0.0565155819058 3.56456041336
+vc 2.14373493195 -0.0546659305692 3.73289179802
+vc 2.17117786407 -0.0490532256663 3.80922818184
+vc 1.99008166790 -0.0386698246002 3.51655697823
+vc 1.60260581970 -0.0297299101949 2.84715867043
+vc 1.20696580410 -0.0226898342371 2.14412689209
+vc 0.852130711079 -0.0194616839290 1.51133275032
+vc 0.847137153149 -0.0136856473982 1.50005722046
+vc 0.843661189079 -0.0109421992674 1.49151885509
+vc 0.841554880142 -0.00639958214015 1.48545122147
+vc 0.840684890747 -0.00497310608625 1.48161387444
+vc 0.840904712677 -0.00168256612960 1.47974240780
+vc 0.842130720615 -0.00114439486060 1.47968614101
+vc 0.844357132912 0.00146825239062 1.48143482208
+vc 0.847659826279 0.00158008735161 1.48512518406
+vc 0.852038860321 0.00345689314418 1.49075734615
+vc 0.853529930115 0.00253308471292 1.49278056622
+vc 3.70465564728 0.156813323498 1.81398785114
+vc 3.72317218781 0.0738224312663 1.80164098740
+vc 3.63299298286 -0.0409938506782 1.90615296364
+vc 3.55441665649 -0.0565397106111 2.05214428902
+vc 3.55441665649 -0.0565397106111 2.05214428902
+vc 3.56455969810 -0.0565155819058 2.05749273300
+vc 3.73289108276 -0.0546659342945 2.14373612404
+vc 3.80922746658 -0.0490531846881 2.17117905617
+vc 3.51655626297 -0.0386698320508 1.99008285999
+vc 2.84715819359 -0.0297298487276 1.60260665417
+vc 2.14412641525 -0.0226897522807 1.20696651936
+vc 1.51133239269 -0.0194615926594 0.852131187916
+vc 1.50005686283 -0.0136855924502 0.847137629986
+vc 1.49151849747 -0.0109421284869 0.843661665916
+vc 1.48545098305 -0.00639961380512 0.841555356979
+vc 1.48161351681 -0.00497314799577 0.840685367584
+vc 1.47974205017 -0.00168254843447 0.840905189514
+vc 1.47968578339 -0.00114440405741 0.842131197453
+vc 1.48143446445 0.00146822468378 0.844357609749
+vc 1.48512482643 0.00158006174024 0.847660303116
+vc 1.49075710773 0.00345693458803 0.852039337158
+vc 1.49278020859 0.00253324722871 0.853530406952
+vc 3.69631242752 0.164881870151 1.82864403725
+vc 3.71393799782 0.0827928856015 1.81947982311
+vc 3.62453103065 -0.0318338721991 1.94099080563
+vc 3.55441665649 -0.0565397106111 2.05214428902
+vc 3.55441665649 -0.0565397106111 2.05214428902
+vc 3.56245183945 -0.0566066280007 2.05678343773
+vc 3.73205494881 -0.0573288910091 2.15470385551
+vc 3.82335519791 -0.0571045428514 2.20741605759
+vc 3.54950833321 -0.0521330311894 2.04931044579
+vc 2.88951587677 -0.0481452606618 1.66826355457
+vc 2.17963457108 -0.0393860898912 1.25841319561
+vc 1.52849829197 -0.0354805402458 0.882479250431
+vc 1.51786100864 -0.0255220606923 0.876337826252
+vc 1.50993430614 -0.0214124806225 0.871761381626
+vc 1.50445413589 -0.0120333172381 0.868597388268
+vc 1.50118219852 -0.00959443580359 0.866708338261
+vc 1.49985706806 -0.00117364781909 0.865943253040
+vc 1.50032913685 4.22244847869e-05 0.866215825081
+vc 1.50258851051 0.00885279569775 0.867520272732
+vc 1.50677037239 0.00982592441142 0.869934678078
+vc 1.51287508011 0.0184789095074 0.873459219933
+vc 1.51503336430 0.0155759835616 0.874705314636
+vc 3.69097113609 0.162553936243 1.83915531635
+vc 3.70670604706 0.0761898234487 1.83444559574
+vc 3.59969544411 -0.0389517359436 1.98324537277
+vc 3.55441665649 -0.0565397106111 2.05214428902
+vc 3.55441665649 -0.0565397106111 2.05214428902
+vc 3.56412005424 -0.0565155819058 2.05825424194
+vc 3.72297477722 -0.0546659305692 2.16091179848
+vc 3.78490924835 -0.0490532256663 2.21329951286
+vc 3.48173952103 -0.0386698246002 2.05038690567
+vc 2.81147646904 -0.0297299101949 1.66440904140
+vc 2.11732625961 -0.0226898342371 1.25338542461
+vc 1.49363315105 -0.0194616839290 0.882787287235
+vc 1.48367083073 -0.0136856473982 0.875519096851
+vc 1.47639131546 -0.0109421992674 0.869862675667
+vc 1.47153353691 -0.00639958214015 0.865661144257
+vc 1.46886122227 -0.00497310608625 0.862772822380
+vc 1.46811604500 -0.00168256612960 0.861042261124
+vc 1.46914958954 -0.00114439486060 0.860380470753
+vc 1.47195208073 0.00146825239062 0.860781669617
+vc 1.47665739059 0.00158008735161 0.862326264381
+vc 1.48326599598 0.00345689314418 0.865014433861
+vc 1.48556876183 0.00253308471292 0.866020917892
+vc 0.623781561852 0.288096547127 0.00000000000
+vc 0.0925567969680 0.202633187175 0.00000000000
+vc 0.00000000000 0.146643534303 0.00000000000
+vc 0.00000000000 0.100708149374 0.00000000000
+vc 0.00000000000 0.0852765515447 0.00000000000
+vc 0.00000000000 0.114887557924 0.00000000000
+vc 0.00000000000 0.162790670991 0.00000000000
+vc 0.0573165006936 0.327754139900 0.00000000000
+vc 0.423917353153 0.530728101730 0.00000000000
+vc 0.896508336067 0.00000000000 0.00000000000
+vc 0.262594431639 0.193678647280 0.00000000000
+vc 0.0965362191200 0.0868320018053 0.00000000000
+vc 0.0201515220106 0.0610211640596 0.00000000000
+vc 0.00000000000 0.0355497673154 0.00000000000
+vc 0.0213280897588 0.0723929554224 0.00000000000
+vc 0.0816167220473 0.109585642815 0.00000000000
+vc 0.202828109264 0.296505302191 0.00000000000
+vc 0.752564370632 0.0707675069571 0.00000000000
+vc 0.990458309650 0.00000000000 0.00000000000
+vc 0.577511429787 0.00304530607536 0.00000000000
+vc 0.292958289385 0.0302337408066 0.00000000000
+vc 0.216859877110 0.0267748106271 0.00000000000
+vc 0.180679112673 0.00000000000 0.00000000000
+vc 0.219750732183 0.00000000000 0.00000000000
+vc 0.282094746828 0.0616945065558 0.00000000000
+vc 0.532882153988 0.00000000000 0.00000000000
+vc 0.875091075897 0.00000000000 0.00000000000
+vc 1.06307077408 0.00000000000 0.00000000000
+vc 0.714697122574 0.00000000000 0.00000000000
+vc 0.535878121853 0.00000000000 0.00000000000
+vc 0.428243070841 0.00000000000 0.00000000000
+vc 0.364700585604 0.00000000000 0.00000000000
+vc 0.414661705494 0.00000000000 0.00000000000
+vc 0.528354167938 0.00000000000 0.00000000000
+vc 0.659836113453 0.00000000000 0.00000000000
+vc 1.02076411247 0.00000000000 0.00000000000
+vc 1.02377605438 0.00000000000 0.00000000000
+vc 0.837289929390 0.00000000000 0.00000000000
+vc 0.668966054916 0.00000000000 0.00000000000
+vc 0.553152263165 0.00000000000 0.00000000000
+vc 0.472068071365 0.00000000000 0.00000000000
+vc 0.549732327461 0.00000000000 0.00000000000
+vc 0.664350450039 0.00000000000 0.00000000000
+vc 0.819711029530 0.00000000000 0.00000000000
+vc 1.00753903389 0.00000000000 0.00000000000
+vc 1.15206670761 0.00000000000 0.00000000000
+vc 0.862847387791 0.00000000000 0.00000000000
+vc 0.718556344509 0.00000000000 0.00000000000
+vc 0.631411254406 0.00000000000 0.00000000000
+vc 0.594916045666 0.00000000000 0.00000000000
+vc 0.625579059124 0.00000000000 0.00000000000
+vc 0.726954221725 0.00000000000 0.00000000000
+vc 0.832572042942 0.00000000000 0.00000000000
+vc 1.18331861496 0.00000000000 0.00000000000
+vc 1.08483743668 0.00000000000 0.00000000000
+vc 0.957837045193 0.00000000000 0.00000000000
+vc 0.830688953400 0.00000000000 0.00000000000
+vc 0.746195554733 0.00000000000 0.00000000000
+vc 0.703956723213 0.00000000000 0.00000000000
+vc 0.749912559986 0.00000000000 0.00000000000
+vc 0.828598082066 0.00000000000 0.00000000000
+vc 0.953424215317 0.00000000000 0.00000000000
+vc 1.09652388096 0.00000000000 0.00000000000
+vc 1.18219912052 0.00000000000 0.00000000000
+vc 0.987197101116 0.00000000000 0.00000000000
+vc 0.911307871342 0.00000000000 0.00000000000
+vc 0.858240187168 0.00000000000 0.00000000000
+vc 0.815136969090 0.00000000000 0.00000000000
+vc 0.853607594967 0.00000000000 0.00000000000
+vc 0.900926470757 0.00000000000 0.00000000000
+vc 0.984366476536 0.00000000000 0.00000000000
+vc 1.19876432419 0.00000000000 0.00000000000
+vc 1.12111377716 0.00000000000 0.00000000000
+vc 1.09306633472 0.00000000000 0.00000000000
+vc 1.01257932186 0.00000000000 0.00000000000
+vc 0.957699835300 0.00000000000 0.00000000000
+vc 0.907042980194 0.00000000000 0.00000000000
+vc 0.958411455154 0.00000000000 0.00000000000
+vc 1.01690435410 0.00000000000 0.00000000000
+vc 1.09500980377 0.00000000000 0.00000000000
+vc 1.12458622456 0.00000000000 0.00000000000
+vc 1.06464540958 0.00000000000 0.00000000000
+vc 1.09831213951 0.00000000000 0.00000000000
+vc 1.07981288433 0.00000000000 0.00000000000
+vc 1.03626501560 0.00000000000 0.00000000000
+vc 0.996469676495 0.00000000000 0.00000000000
+vc 1.03697371483 0.00000000000 0.00000000000
+vc 1.07615554333 0.00000000000 0.00000000000
+vc 1.10044658184 0.00000000000 0.00000000000
+vc 1.06807637215 0.00000000000 0.00000000000
+vc 1.00741982460 0.00000000000 0.00000000000
+vc 1.03719818592 0.00000000000 0.00000000000
+vc 1.04009914398 0.00000000000 0.00000000000
+vc 1.03225362301 0.00000000000 0.00000000000
+vc 1.01795840263 0.00000000000 0.00000000000
+vc 1.03377711773 0.00000000000 0.00000000000
+vc 1.04164147377 0.00000000000 0.00000000000
+vc 1.03926873207 0.00000000000 0.00000000000
+vc 1.01056551933 0.00000000000 0.00000000000
+vc 0.949322640896 0.00000000000 0.00000000000
+vc 0.975073277950 0.00000000000 0.00000000000
+vc 0.977650344372 0.00000000000 0.00000000000
+vc 0.970885038376 0.00000000000 0.00000000000
+vc 0.958589911461 0.00000000000 0.00000000000
+vc 0.972243905067 0.00000000000 0.00000000000
+vc 0.979254424572 0.00000000000 0.00000000000
+vc 0.977146804333 0.00000000000 0.00000000000
+vc 0.952293932438 0.00000000000 0.00000000000
+vc 0.890036165714 0.00000000000 0.00000000000
+vc 0.912633776665 0.00000000000 0.00000000000
+vc 0.914667963982 0.00000000000 0.00000000000
+vc 0.908572733402 0.00000000000 0.00000000000
+vc 0.898118615150 0.00000000000 0.00000000000
+vc 0.909938335419 0.00000000000 0.00000000000
+vc 0.916040837765 0.00000000000 0.00000000000
+vc 0.914536774158 0.00000000000 0.00000000000
+vc 0.892783761024 0.00000000000 0.00000000000
+vc 0.829784095287 0.00000000000 0.00000000000
+vc 0.849051535130 0.00000000000 0.00000000000
+vc 0.850814700127 0.00000000000 0.00000000000
+vc 0.845728516579 0.00000000000 0.00000000000
+vc 0.837257325649 0.00000000000 0.00000000000
+vc 0.847144067287 0.00000000000 0.00000000000
+vc 0.852418124676 0.00000000000 0.00000000000
+vc 0.850965142250 0.00000000000 0.00000000000
+vc 0.832304537296 0.00000000000 0.00000000000
+vc 0.768334388733 0.00000000000 0.00000000000
+vc 0.785195827484 0.00000000000 0.00000000000
+vc 0.786499261856 0.00000000000 0.00000000000
+vc 0.781894385815 0.00000000000 0.00000000000
+vc 0.774727165699 0.00000000000 0.00000000000
+vc 0.783278942108 0.00000000000 0.00000000000
+vc 0.787850379944 0.00000000000 0.00000000000
+vc 0.786879003048 0.00000000000 0.00000000000
+vc 0.771372377872 0.00000000000 0.00000000000
+vc 0.706372082233 0.00000000000 0.00000000000
+vc 0.720071554184 0.00000000000 0.00000000000
+vc 0.721233129501 0.00000000000 0.00000000000
+vc 0.717558920383 0.00000000000 0.00000000000
+vc 0.712129116058 0.00000000000 0.00000000000
+vc 0.718982040882 0.00000000000 0.00000000000
+vc 0.722747862339 0.00000000000 0.00000000000
+vc 0.721880674362 0.00000000000 0.00000000000
+vc 0.708906114101 0.00000000000 0.00000000000
+vc 0.643386542797 0.00000000000 0.00000000000
+vc 0.654573440552 0.00000000000 0.00000000000
+vc 0.655293405056 0.00000000000 0.00000000000
+vc 0.652103364468 0.00000000000 0.00000000000
+vc 0.647833347321 0.00000000000 0.00000000000
+vc 0.653706848621 0.00000000000 0.00000000000
+vc 0.657065808773 0.00000000000 0.00000000000
+vc 0.656314074993 0.00000000000 0.00000000000
+vc 0.645535171032 0.00000000000 0.00000000000
+vc 0.579196214676 0.00000000000 0.00000000000
+vc 0.588074386120 0.00000000000 0.00000000000
+vc 0.588605821133 0.00000000000 0.00000000000
+vc 0.586276352406 0.00000000000 0.00000000000
+vc 0.583441078663 0.00000000000 0.00000000000
+vc 0.587792396545 0.00000000000 0.00000000000
+vc 0.590232551098 0.00000000000 0.00000000000
+vc 0.589832007885 0.00000000000 0.00000000000
+vc 0.581534087658 0.00000000000 0.00000000000
+vc 0.514387786388 0.00000000000 0.00000000000
+vc 0.521116554737 0.00000000000 0.00000000000
+vc 0.521350145340 0.00000000000 0.00000000000
+vc 0.519392549992 0.00000000000 0.00000000000
+vc 0.517245233059 0.00000000000 0.00000000000
+vc 0.520956218243 0.00000000000 0.00000000000
+vc 0.523051738739 0.00000000000 0.00000000000
+vc 0.522902905941 0.00000000000 0.00000000000
+vc 0.516510784626 0.00000000000 0.00000000000
+vc 0.448392510414 0.00000000000 0.00000000000
+vc 0.453204989433 0.00000000000 0.00000000000
+vc 0.453178167343 0.00000000000 0.00000000000
+vc 0.451990842819 0.00000000000 0.00000000000
+vc 0.451175451279 0.00000000000 0.00000000000
+vc 0.453590750694 0.00000000000 0.00000000000
+vc 0.454940319061 0.00000000000 0.00000000000
+vc 0.454927206039 0.00000000000 0.00000000000
+vc 0.450366258621 0.00000000000 0.00000000000
+vc 0.381729483604 0.00000000000 0.00000000000
+vc 0.384896278381 0.00000000000 0.00000000000
+vc 0.384611368179 0.00000000000 0.00000000000
+vc 0.383541941643 0.00000000000 0.00000000000
+vc 0.383016347885 0.00000000000 0.00000000000
+vc 0.384993791580 0.00000000000 0.00000000000
+vc 0.386237740517 0.00000000000 0.00000000000
+vc 0.386409878731 0.00000000000 0.00000000000
+vc 0.383426785469 0.00000000000 0.00000000000
+vc 0.313721656799 0.00000000000 0.00000000000
+vc 0.315534710884 0.00000000000 0.00000000000
+vc 0.315058469772 0.00000000000 0.00000000000
+vc 0.314747571945 0.00000000000 0.00000000000
+vc 0.315399169922 0.00000000000 0.00000000000
+vc 0.316258549690 0.00000000000 0.00000000000
+vc 0.316821813583 0.00000000000 0.00000000000
+vc 0.317050933838 0.00000000000 0.00000000000
+vc 0.315386176109 0.00000000000 0.00000000000
+vc 0.244962811470 0.00000000000 0.00000000000
+vc 0.245425462723 0.00000000000 0.00000000000
+vc 0.244793057442 0.00000000000 0.00000000000
+vc 0.244615197182 0.00000000000 0.00000000000
+vc 0.245502710342 0.00000000000 0.00000000000
+vc 0.246272802353 0.00000000000 0.00000000000
+vc 0.246709227562 0.00000000000 0.00000000000
+vc 0.247112512589 0.00000000000 0.00000000000
+vc 0.246777772903 0.00000000000 0.00000000000
+vc 0.175607562065 0.00000000000 0.00000000000
+vc 0.174845695496 0.00000000000 0.00000000000
+vc 0.174018502235 0.00000000000 0.00000000000
+vc 0.174355626106 0.00000000000 0.00000000000
+vc 0.175920009613 0.00000000000 0.00000000000
+vc 0.175931811333 0.00000000000 0.00000000000
+vc 0.175831675529 0.00000000000 0.00000000000
+vc 0.176266789436 0.00000000000 0.00000000000
+vc 0.176836133003 0.00000000000 0.00000000000
+vc 0.104960441589 0.00000000000 0.00000000000
+vc 0.103270053864 0.00000000000 0.00000000000
+vc 0.102258801460 0.00000000000 0.00000000000
+vc 0.102768778801 0.00000000000 0.00000000000
+vc 0.104298233986 0.00000000000 0.00000000000
+vc 0.104399561882 0.00000000000 0.00000000000
+vc 0.104354858398 0.00000000000 0.00000000000
+vc 0.104899764061 0.00000000000 0.00000000000
+vc 0.106104493141 0.00000000000 0.00000000000
+vc 0.0332220792770 0.00000000000 0.00000000000
+vc 0.0312508344650 0.00000000000 0.00000000000
+vc 0.0302327871323 0.00000000000 0.00000000000
+vc 0.0309371948242 0.00000000000 0.00000000000
+vc 0.0328706502914 0.00000000000 0.00000000000
+vc 0.0325299501419 0.00000000000 0.00000000000
+vc 0.0321335792542 0.00000000000 0.00000000000
+vc 0.0327329635620 0.00000000000 0.00000000000
+vc 0.0342955589294 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc -2.72663580603e-08 0.288096547127 -0.623781561852
+vc -4.04578592850e-09 0.202633187175 -0.0925567969680
+vc 0.00000000000 0.146643534303 0.00000000000
+vc 0.00000000000 0.100708149374 0.00000000000
+vc 0.00000000000 0.0852765515447 0.00000000000
+vc 0.00000000000 0.114887557924 0.00000000000
+vc 0.00000000000 0.162790670991 0.00000000000
+vc -2.50538390034e-09 0.327754139900 -0.0573165006936
+vc -1.85300166322e-08 0.530728101730 -0.423917353153
+vc -3.91876255890e-08 0.00000000000 -0.896508336067
+vc -1.14783675897e-08 0.193678647280 -0.262594431639
+vc -4.21973211928e-09 0.0868320018053 -0.0965362191200
+vc -8.80851003249e-10 0.0610211640596 -0.0201515220106
+vc 0.00000000000 0.0355497673154 0.00000000000
+vc -9.32280364019e-10 0.0723929554224 -0.0213280897588
+vc -3.56758023123e-09 0.109585642815 -0.0816167220473
+vc -8.86589823779e-09 0.296505302191 -0.202828109264
+vc -3.28956346607e-08 0.0707675069571 -0.752564370632
+vc -4.32943068063e-08 0.00000000000 -0.990458309650
+vc -2.52438265846e-08 0.00304530607536 -0.577511429787
+vc -1.28056134585e-08 0.0302337408066 -0.292958289385
+vc -9.47924672090e-09 0.0267748106271 -0.216859877110
+vc -7.89773491050e-09 0.00000000000 -0.180679112673
+vc -9.60560964103e-09 0.00000000000 -0.219750732183
+vc -1.23307533073e-08 0.0616945065558 -0.282094746828
+vc -2.32930190691e-08 0.00000000000 -0.532882153988
+vc -3.82514464548e-08 0.00000000000 -0.875091075897
+vc -4.64682976542e-08 0.00000000000 -1.06307077408
+vc -3.12404040415e-08 0.00000000000 -0.714697122574
+vc -2.34239774244e-08 0.00000000000 -0.535878121853
+vc -1.87190991596e-08 0.00000000000 -0.428243070841
+vc -1.59415680656e-08 0.00000000000 -0.364700585604
+vc -1.81254389275e-08 0.00000000000 -0.414661705494
+vc -2.30950938374e-08 0.00000000000 -0.528354167938
+vc -2.88423525063e-08 0.00000000000 -0.659836113453
+vc -4.46190178138e-08 0.00000000000 -1.02076411247
+vc -4.47506742773e-08 0.00000000000 -1.02377605438
+vc -3.65991041917e-08 0.00000000000 -0.837289929390
+vc -2.92414341629e-08 0.00000000000 -0.668966054916
+vc -2.41790534261e-08 0.00000000000 -0.553152263165
+vc -2.06347507969e-08 0.00000000000 -0.472068071365
+vc -2.40295623399e-08 0.00000000000 -0.549732327461
+vc -2.90396808822e-08 0.00000000000 -0.664350450039
+vc -3.58307055137e-08 0.00000000000 -0.819711029530
+vc -4.40409309022e-08 0.00000000000 -1.00753903389
+vc -5.03584338674e-08 0.00000000000 -1.15206670761
+vc -3.77162585607e-08 0.00000000000 -0.862847387791
+vc -3.14090939924e-08 0.00000000000 -0.718556344509
+vc -2.75998619514e-08 0.00000000000 -0.631411254406
+vc -2.60046064682e-08 0.00000000000 -0.594916045666
+vc -2.73449298760e-08 0.00000000000 -0.625579059124
+vc -3.17761781332e-08 0.00000000000 -0.726954221725
+vc -3.63928798208e-08 0.00000000000 -0.832572042942
+vc -5.17244984621e-08 0.00000000000 -1.18331861496
+vc -4.74197499045e-08 0.00000000000 -1.08483743668
+vc -4.18683860914e-08 0.00000000000 -0.957837045193
+vc -3.63105669976e-08 0.00000000000 -0.830688953400
+vc -3.26172440168e-08 0.00000000000 -0.746195554733
+vc -3.07709271397e-08 0.00000000000 -0.703956723213
+vc -3.27797202715e-08 0.00000000000 -0.749912559986
+vc -3.62191734382e-08 0.00000000000 -0.828598082066
+vc -4.16754950550e-08 0.00000000000 -0.953424215317
+vc -4.79305803935e-08 0.00000000000 -1.09652388096
+vc -5.16755633839e-08 0.00000000000 -1.18219912052
+vc -4.31517541699e-08 0.00000000000 -0.987197101116
+vc -3.98345321173e-08 0.00000000000 -0.911307871342
+vc -3.75148694332e-08 0.00000000000 -0.858240187168
+vc -3.56307694460e-08 0.00000000000 -0.815136969090
+vc -3.73123718589e-08 0.00000000000 -0.853607594967
+vc -3.93807475518e-08 0.00000000000 -0.900926470757
+vc -4.30280238106e-08 0.00000000000 -0.984366476536
+vc -5.23996526169e-08 0.00000000000 -1.19876432419
+vc -4.90054397062e-08 0.00000000000 -1.12111377716
+vc -4.77794479536e-08 0.00000000000 -1.09306633472
+vc -4.42612488882e-08 0.00000000000 -1.01257932186
+vc -4.18623891107e-08 0.00000000000 -0.957699835300
+vc -3.96481070197e-08 0.00000000000 -0.907042980194
+vc -4.18934966717e-08 0.00000000000 -0.958411455154
+vc -4.44502994412e-08 0.00000000000 -1.01690435410
+vc -4.78644004431e-08 0.00000000000 -1.09500980377
+vc -4.91572258454e-08 0.00000000000 -1.12458622456
+vc -4.65371279290e-08 0.00000000000 -1.06464540958
+vc -4.80087471999e-08 0.00000000000 -1.09831213951
+vc -4.72001211449e-08 0.00000000000 -1.07981288433
+vc -4.52965807085e-08 0.00000000000 -1.03626501560
+vc -4.35570726154e-08 0.00000000000 -0.996469676495
+vc -4.53275603718e-08 0.00000000000 -1.03697371483
+vc -4.70402525821e-08 0.00000000000 -1.07615554333
+vc -4.81020485665e-08 0.00000000000 -1.10044658184
+vc -4.66871021843e-08 0.00000000000 -1.06807637215
+vc -4.40357190712e-08 0.00000000000 -1.00741982460
+vc -4.53373729670e-08 0.00000000000 -1.03719818592
+vc -4.54641764236e-08 0.00000000000 -1.04009914398
+vc -4.51212400776e-08 0.00000000000 -1.03225362301
+vc -4.44963745849e-08 0.00000000000 -1.01795840263
+vc -4.51878321428e-08 0.00000000000 -1.03377711773
+vc -4.55315962711e-08 0.00000000000 -1.04164147377
+vc -4.54278783479e-08 0.00000000000 -1.03926873207
+vc -4.41732233014e-08 0.00000000000 -1.01056551933
+vc -4.14962109119e-08 0.00000000000 -0.949322640896
+vc -4.26218065286e-08 0.00000000000 -0.975073277950
+vc -4.27344524212e-08 0.00000000000 -0.977650344372
+vc -4.24387316400e-08 0.00000000000 -0.970885038376
+vc -4.19012948782e-08 0.00000000000 -0.958589911461
+vc -4.24981294600e-08 0.00000000000 -0.972243905067
+vc -4.28045687784e-08 0.00000000000 -0.979254424572
+vc -4.27124433600e-08 0.00000000000 -0.977146804333
+vc -4.16260910185e-08 0.00000000000 -0.952293932438
+vc -3.89047158933e-08 0.00000000000 -0.890036165714
+vc -3.98924910883e-08 0.00000000000 -0.912633776665
+vc -3.99814048535e-08 0.00000000000 -0.914667963982
+vc -3.97149761966e-08 0.00000000000 -0.908572733402
+vc -3.92580119524e-08 0.00000000000 -0.898118615150
+vc -3.97746688918e-08 0.00000000000 -0.909938335419
+vc -4.00414172930e-08 0.00000000000 -0.916040837765
+vc -3.99756707736e-08 0.00000000000 -0.914536774158
+vc -3.90248189319e-08 0.00000000000 -0.892783761024
+vc -3.62710146362e-08 0.00000000000 -0.829784095287
+vc -3.71132209409e-08 0.00000000000 -0.849051535130
+vc -3.71902899587e-08 0.00000000000 -0.850814700127
+vc -3.69679682422e-08 0.00000000000 -0.845728516579
+vc -3.65976795536e-08 0.00000000000 -0.837257325649
+vc -3.70298423036e-08 0.00000000000 -0.847144067287
+vc -3.72603778942e-08 0.00000000000 -0.852418124676
+vc -3.71968660318e-08 0.00000000000 -0.850965142250
+vc -3.63811878401e-08 0.00000000000 -0.832304537296
+vc -3.35849641431e-08 0.00000000000 -0.768334388733
+vc -3.43219994647e-08 0.00000000000 -0.785195827484
+vc -3.43789743340e-08 0.00000000000 -0.786499261856
+vc -3.41776882351e-08 0.00000000000 -0.781894385815
+vc -3.38643992848e-08 0.00000000000 -0.774727165699
+vc -3.42382087126e-08 0.00000000000 -0.783278942108
+vc -3.44380346462e-08 0.00000000000 -0.787850379944
+vc -3.43955726123e-08 0.00000000000 -0.786879003048
+vc -3.37177574750e-08 0.00000000000 -0.771372377872
+vc -3.08765031320e-08 0.00000000000 -0.706372082233
+vc -3.14753272335e-08 0.00000000000 -0.720071554184
+vc -3.15261026174e-08 0.00000000000 -0.721233129501
+vc -3.13654950901e-08 0.00000000000 -0.717558920383
+vc -3.11281525001e-08 0.00000000000 -0.712129116058
+vc -3.14277031066e-08 0.00000000000 -0.718982040882
+vc -3.15923109895e-08 0.00000000000 -0.722747862339
+vc -3.15544070872e-08 0.00000000000 -0.721880674362
+vc -3.09872696391e-08 0.00000000000 -0.708906114101
+vc -2.81233187849e-08 0.00000000000 -0.643386542797
+vc -2.86123142956e-08 0.00000000000 -0.654573440552
+vc -2.86437842334e-08 0.00000000000 -0.655293405056
+vc -2.85043437742e-08 0.00000000000 -0.652103364468
+vc -2.83176948557e-08 0.00000000000 -0.647833347321
+vc -2.85744334860e-08 0.00000000000 -0.653706848621
+vc -2.87212582606e-08 0.00000000000 -0.657065808773
+vc -2.86883992118e-08 0.00000000000 -0.656314074993
+vc -2.82172383237e-08 0.00000000000 -0.645535171032
+vc -2.53174707865e-08 0.00000000000 -0.579196214676
+vc -2.57055479125e-08 0.00000000000 -0.588074386120
+vc -2.57287773309e-08 0.00000000000 -0.588605821133
+vc -2.56269530041e-08 0.00000000000 -0.586276352406
+vc -2.55030201401e-08 0.00000000000 -0.583441078663
+vc -2.56932217724e-08 0.00000000000 -0.587792396545
+vc -2.57998848952e-08 0.00000000000 -0.590232551098
+vc -2.57823753458e-08 0.00000000000 -0.589832007885
+vc -2.54196628191e-08 0.00000000000 -0.581534087658
+vc -2.24846044006e-08 0.00000000000 -0.514387786388
+vc -2.27787282370e-08 0.00000000000 -0.521116554737
+vc -2.27889387361e-08 0.00000000000 -0.521350145340
+vc -2.27033698508e-08 0.00000000000 -0.519392549992
+vc -2.26095071554e-08 0.00000000000 -0.517245233059
+vc -2.27717187329e-08 0.00000000000 -0.520956218243
+vc -2.28633183497e-08 0.00000000000 -0.523051738739
+vc -2.28568115546e-08 0.00000000000 -0.522902905941
+vc -2.25774030582e-08 0.00000000000 -0.516510784626
+vc -1.95998595132e-08 0.00000000000 -0.448392510414
+vc -1.98102192428e-08 0.00000000000 -0.453204989433
+vc -1.98090468473e-08 0.00000000000 -0.453178167343
+vc -1.97571470295e-08 0.00000000000 -0.451990842819
+vc -1.97215062059e-08 0.00000000000 -0.451175451279
+vc -1.98270821983e-08 0.00000000000 -0.453590750694
+vc -1.98860732326e-08 0.00000000000 -0.454940319061
+vc -1.98854994693e-08 0.00000000000 -0.454927206039
+vc -1.96861336121e-08 0.00000000000 -0.450366258621
+vc -1.66859255302e-08 0.00000000000 -0.381729483604
+vc -1.68243499132e-08 0.00000000000 -0.384896278381
+vc -1.68118976518e-08 0.00000000000 -0.384611368179
+vc -1.67651510452e-08 0.00000000000 -0.383541941643
+vc -1.67421756458e-08 0.00000000000 -0.383016347885
+vc -1.68286131697e-08 0.00000000000 -0.384993791580
+vc -1.68829874525e-08 0.00000000000 -0.386237740517
+vc -1.68905121001e-08 0.00000000000 -0.386409878731
+vc -1.67601168499e-08 0.00000000000 -0.383426785469
+vc -1.37132092348e-08 0.00000000000 -0.313721656799
+vc -1.37924605070e-08 0.00000000000 -0.315534710884
+vc -1.37716433812e-08 0.00000000000 -0.315058469772
+vc -1.37580533632e-08 0.00000000000 -0.314747571945
+vc -1.37865354688e-08 0.00000000000 -0.315399169922
+vc -1.38241000869e-08 0.00000000000 -0.316258549690
+vc -1.38487212809e-08 0.00000000000 -0.316821813583
+vc -1.38587363807e-08 0.00000000000 -0.317050933838
+vc -1.37859679228e-08 0.00000000000 -0.315386176109
+vc -1.07076649769e-08 0.00000000000 -0.244962811470
+vc -1.07278879113e-08 0.00000000000 -0.245425462723
+vc -1.07002442462e-08 0.00000000000 -0.244793057442
+vc -1.06924700205e-08 0.00000000000 -0.244615197182
+vc -1.07312638775e-08 0.00000000000 -0.245502710342
+vc -1.07649258396e-08 0.00000000000 -0.246272802353
+vc -1.07840030239e-08 0.00000000000 -0.246709227562
+vc -1.08016307010e-08 0.00000000000 -0.247112512589
+vc -1.07869988497e-08 0.00000000000 -0.246777772903
+vc -7.67605001784e-09 0.00000000000 -0.175607562065
+vc -7.64274776799e-09 0.00000000000 -0.174845695496
+vc -7.60659002452e-09 0.00000000000 -0.174018502235
+vc -7.62132668086e-09 0.00000000000 -0.174355626106
+vc -7.68970753739e-09 0.00000000000 -0.175920009613
+vc -7.69022356906e-09 0.00000000000 -0.175931811333
+vc -7.68584662580e-09 0.00000000000 -0.175831675529
+vc -7.70486607848e-09 0.00000000000 -0.176266789436
+vc -7.72975283780e-09 0.00000000000 -0.176836133003
+vc -4.58796645120e-09 0.00000000000 -0.104960441589
+vc -4.51407755619e-09 0.00000000000 -0.103270053864
+vc -4.46987424851e-09 0.00000000000 -0.102258801460
+vc -4.49216619458e-09 0.00000000000 -0.102768778801
+vc -4.55902071650e-09 0.00000000000 -0.104298233986
+vc -4.56344961819e-09 0.00000000000 -0.104399561882
+vc -4.56149562567e-09 0.00000000000 -0.104354858398
+vc -4.58531435044e-09 0.00000000000 -0.104899764061
+vc -4.63797489303e-09 0.00000000000 -0.106104493141
+vc -1.45218315151e-09 0.00000000000 -0.0332220792770
+vc -1.36601741030e-09 0.00000000000 -0.0312508344650
+vc -1.32151711796e-09 0.00000000000 -0.0302327871323
+vc -1.35230771026e-09 0.00000000000 -0.0309371948242
+vc -1.43682177267e-09 0.00000000000 -0.0328706502914
+vc -1.42192924102e-09 0.00000000000 -0.0325299501419
+vc -1.40460332254e-09 0.00000000000 -0.0321335792542
+vc -1.43080325365e-09 0.00000000000 -0.0327329635620
+vc -1.49910650560e-09 0.00000000000 -0.0342955589294
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc -0.623781561852 0.288096547127 5.45327161205e-08
+vc -0.0925567969680 0.202633187175 8.09157185699e-09
+vc 0.00000000000 0.146643534303 0.00000000000
+vc 0.00000000000 0.100708149374 0.00000000000
+vc 0.00000000000 0.0852765515447 0.00000000000
+vc 0.00000000000 0.114887557924 0.00000000000
+vc 0.00000000000 0.162790670991 0.00000000000
+vc -0.0573165006936 0.327754139900 5.01076780068e-09
+vc -0.423917353153 0.530728101730 3.70600332644e-08
+vc -0.896508336067 0.00000000000 7.83752511779e-08
+vc -0.262594431639 0.193678647280 2.29567351795e-08
+vc -0.0965362191200 0.0868320018053 8.43946423856e-09
+vc -0.0201515220106 0.0610211640596 1.76170200650e-09
+vc 0.00000000000 0.0355497673154 0.00000000000
+vc -0.0213280897588 0.0723929554224 1.86456072804e-09
+vc -0.0816167220473 0.109585642815 7.13516046247e-09
+vc -0.202828109264 0.296505302191 1.77317964756e-08
+vc -0.752564370632 0.0707675069571 6.57912693214e-08
+vc -0.990458309650 0.00000000000 8.65886136125e-08
+vc -0.577511429787 0.00304530607536 5.04876531693e-08
+vc -0.292958289385 0.0302337408066 2.56112269170e-08
+vc -0.216859877110 0.0267748106271 1.89584934418e-08
+vc -0.180679112673 0.00000000000 1.57954698210e-08
+vc -0.219750732183 0.00000000000 1.92112192821e-08
+vc -0.282094746828 0.0616945065558 2.46615066146e-08
+vc -0.532882153988 0.00000000000 4.65860381382e-08
+vc -0.875091075897 0.00000000000 7.65028929095e-08
+vc -1.06307077408 0.00000000000 9.29365953084e-08
+vc -0.714697122574 0.00000000000 6.24808080829e-08
+vc -0.535878121853 0.00000000000 4.68479548488e-08
+vc -0.428243070841 0.00000000000 3.74381983193e-08
+vc -0.364700585604 0.00000000000 3.18831361312e-08
+vc -0.414661705494 0.00000000000 3.62508778551e-08
+vc -0.528354167938 0.00000000000 4.61901876747e-08
+vc -0.659836113453 0.00000000000 5.76847050127e-08
+vc -1.02076411247 0.00000000000 8.92380356277e-08
+vc -1.02377605438 0.00000000000 8.95013485547e-08
+vc -0.837289929390 0.00000000000 7.31982083835e-08
+vc -0.668966054916 0.00000000000 5.84828683259e-08
+vc -0.553152263165 0.00000000000 4.83581068522e-08
+vc -0.472068071365 0.00000000000 4.12695015939e-08
+vc -0.549732327461 0.00000000000 4.80591246799e-08
+vc -0.664350450039 0.00000000000 5.80793617644e-08
+vc -0.819711029530 0.00000000000 7.16614110274e-08
+vc -1.00753903389 0.00000000000 8.80818618043e-08
+vc -1.15206670761 0.00000000000 1.00716867735e-07
+vc -0.862847387791 0.00000000000 7.54325171215e-08
+vc -0.718556344509 0.00000000000 6.28181879847e-08
+vc -0.631411254406 0.00000000000 5.51997239029e-08
+vc -0.594916045666 0.00000000000 5.20092129364e-08
+vc -0.625579059124 0.00000000000 5.46898597520e-08
+vc -0.726954221725 0.00000000000 6.35523562664e-08
+vc -0.832572042942 0.00000000000 7.27857596416e-08
+vc -1.18331861496 0.00000000000 1.03448996924e-07
+vc -1.08483743668 0.00000000000 9.48394998090e-08
+vc -0.957837045193 0.00000000000 8.37367721829e-08
+vc -0.830688953400 0.00000000000 7.26211339952e-08
+vc -0.746195554733 0.00000000000 6.52344880336e-08
+vc -0.703956723213 0.00000000000 6.15418542793e-08
+vc -0.749912559986 0.00000000000 6.55594405430e-08
+vc -0.828598082066 0.00000000000 7.24383468764e-08
+vc -0.953424215317 0.00000000000 8.33509901099e-08
+vc -1.09652388096 0.00000000000 9.58611607871e-08
+vc -1.18219912052 0.00000000000 1.03351126768e-07
+vc -0.987197101116 0.00000000000 8.63035083398e-08
+vc -0.911307871342 0.00000000000 7.96690642346e-08
+vc -0.858240187168 0.00000000000 7.50297388663e-08
+vc -0.815136969090 0.00000000000 7.12615388920e-08
+vc -0.853607594967 0.00000000000 7.46247437178e-08
+vc -0.900926470757 0.00000000000 7.87614951037e-08
+vc -0.984366476536 0.00000000000 8.60560476212e-08
+vc -1.19876432419 0.00000000000 1.04799305234e-07
+vc -1.12111377716 0.00000000000 9.80108794124e-08
+vc -1.09306633472 0.00000000000 9.55588959073e-08
+vc -1.01257932186 0.00000000000 8.85224977765e-08
+vc -0.957699835300 0.00000000000 8.37247782215e-08
+vc -0.907042980194 0.00000000000 7.92962140395e-08
+vc -0.958411455154 0.00000000000 8.37869933434e-08
+vc -1.01690435410 0.00000000000 8.89005988824e-08
+vc -1.09500980377 0.00000000000 9.57288008863e-08
+vc -1.12458622456 0.00000000000 9.83144516908e-08
+vc -1.06464540958 0.00000000000 9.30742558580e-08
+vc -1.09831213951 0.00000000000 9.60174943998e-08
+vc -1.07981288433 0.00000000000 9.44002422898e-08
+vc -1.03626501560 0.00000000000 9.05931614170e-08
+vc -0.996469676495 0.00000000000 8.71141452308e-08
+vc -1.03697371483 0.00000000000 9.06551207436e-08
+vc -1.07615554333 0.00000000000 9.40805051641e-08
+vc -1.10044658184 0.00000000000 9.62040971331e-08
+vc -1.06807637215 0.00000000000 9.33742043685e-08
+vc -1.00741982460 0.00000000000 8.80714381424e-08
+vc -1.03719818592 0.00000000000 9.06747459339e-08
+vc -1.04009914398 0.00000000000 9.09283528472e-08
+vc -1.03225362301 0.00000000000 9.02424801552e-08
+vc -1.01795840263 0.00000000000 8.89927491698e-08
+vc -1.03377711773 0.00000000000 9.03756642856e-08
+vc -1.04164147377 0.00000000000 9.10631925422e-08
+vc -1.03926873207 0.00000000000 9.08557566959e-08
+vc -1.01056551933 0.00000000000 8.83464466028e-08
+vc -0.949322640896 0.00000000000 8.29924218237e-08
+vc -0.975073277950 0.00000000000 8.52436130572e-08
+vc -0.977650344372 0.00000000000 8.54689048424e-08
+vc -0.970885038376 0.00000000000 8.48774632800e-08
+vc -0.958589911461 0.00000000000 8.38025897565e-08
+vc -0.972243905067 0.00000000000 8.49962589200e-08
+vc -0.979254424572 0.00000000000 8.56091375567e-08
+vc -0.977146804333 0.00000000000 8.54248867199e-08
+vc -0.952293932438 0.00000000000 8.32521820371e-08
+vc -0.890036165714 0.00000000000 7.78094317866e-08
+vc -0.912633776665 0.00000000000 7.97849821765e-08
+vc -0.914667963982 0.00000000000 7.99628097070e-08
+vc -0.908572733402 0.00000000000 7.94299523932e-08
+vc -0.898118615150 0.00000000000 7.85160239047e-08
+vc -0.909938335419 0.00000000000 7.95493377836e-08
+vc -0.916040837765 0.00000000000 8.00828345859e-08
+vc -0.914536774158 0.00000000000 7.99513415473e-08
+vc -0.892783761024 0.00000000000 7.80496378638e-08
+vc -0.829784095287 0.00000000000 7.25420292724e-08
+vc -0.849051535130 0.00000000000 7.42264418818e-08
+vc -0.850814700127 0.00000000000 7.43805799175e-08
+vc -0.845728516579 0.00000000000 7.39359364843e-08
+vc -0.837257325649 0.00000000000 7.31953591071e-08
+vc -0.847144067287 0.00000000000 7.40596846072e-08
+vc -0.852418124676 0.00000000000 7.45207557884e-08
+vc -0.850965142250 0.00000000000 7.43937320635e-08
+vc -0.832304537296 0.00000000000 7.27623756802e-08
+vc -0.768334388733 0.00000000000 6.71699282861e-08
+vc -0.785195827484 0.00000000000 6.86439989295e-08
+vc -0.786499261856 0.00000000000 6.87579486680e-08
+vc -0.781894385815 0.00000000000 6.83553764702e-08
+vc -0.774727165699 0.00000000000 6.77287985695e-08
+vc -0.783278942108 0.00000000000 6.84764174252e-08
+vc -0.787850379944 0.00000000000 6.88760692924e-08
+vc -0.786879003048 0.00000000000 6.87911452246e-08
+vc -0.771372377872 0.00000000000 6.74355149499e-08
+vc -0.706372082233 0.00000000000 6.17530062641e-08
+vc -0.720071554184 0.00000000000 6.29506544669e-08
+vc -0.721233129501 0.00000000000 6.30522052347e-08
+vc -0.717558920383 0.00000000000 6.27309901802e-08
+vc -0.712129116058 0.00000000000 6.22563050001e-08
+vc -0.718982040882 0.00000000000 6.28554062132e-08
+vc -0.722747862339 0.00000000000 6.31846219790e-08
+vc -0.721880674362 0.00000000000 6.31088141745e-08
+vc -0.708906114101 0.00000000000 6.19745392783e-08
+vc -0.643386542797 0.00000000000 5.62466375698e-08
+vc -0.654573440552 0.00000000000 5.72246285913e-08
+vc -0.655293405056 0.00000000000 5.72875684668e-08
+vc -0.652103364468 0.00000000000 5.70086875484e-08
+vc -0.647833347321 0.00000000000 5.66353897113e-08
+vc -0.653706848621 0.00000000000 5.71488669721e-08
+vc -0.657065808773 0.00000000000 5.74425165212e-08
+vc -0.656314074993 0.00000000000 5.73767984235e-08
+vc -0.645535171032 0.00000000000 5.64344766474e-08
+vc -0.579196214676 0.00000000000 5.06349415730e-08
+vc -0.588074386120 0.00000000000 5.14110958250e-08
+vc -0.588605821133 0.00000000000 5.14575546617e-08
+vc -0.586276352406 0.00000000000 5.12539060082e-08
+vc -0.583441078663 0.00000000000 5.10060402803e-08
+vc -0.587792396545 0.00000000000 5.13864435447e-08
+vc -0.590232551098 0.00000000000 5.15997697903e-08
+vc -0.589832007885 0.00000000000 5.15647506916e-08
+vc -0.581534087658 0.00000000000 5.08393256382e-08
+vc -0.514387786388 0.00000000000 4.49692088011e-08
+vc -0.521116554737 0.00000000000 4.55574564739e-08
+vc -0.521350145340 0.00000000000 4.55778774722e-08
+vc -0.519392549992 0.00000000000 4.54067397015e-08
+vc -0.517245233059 0.00000000000 4.52190143108e-08
+vc -0.520956218243 0.00000000000 4.55434374658e-08
+vc -0.523051738739 0.00000000000 4.57266366993e-08
+vc -0.522902905941 0.00000000000 4.57136231091e-08
+vc -0.516510784626 0.00000000000 4.51548061164e-08
+vc -0.448392510414 0.00000000000 3.91997190263e-08
+vc -0.453204989433 0.00000000000 3.96204384856e-08
+vc -0.453178167343 0.00000000000 3.96180936946e-08
+vc -0.451990842819 0.00000000000 3.95142940590e-08
+vc -0.451175451279 0.00000000000 3.94430124118e-08
+vc -0.453590750694 0.00000000000 3.96541643966e-08
+vc -0.454940319061 0.00000000000 3.97721464651e-08
+vc -0.454927206039 0.00000000000 3.97709989386e-08
+vc -0.450366258621 0.00000000000 3.93722672243e-08
+vc -0.381729483604 0.00000000000 3.33718510603e-08
+vc -0.384896278381 0.00000000000 3.36486998265e-08
+vc -0.384611368179 0.00000000000 3.36237953036e-08
+vc -0.383541941643 0.00000000000 3.35303020904e-08
+vc -0.383016347885 0.00000000000 3.34843512917e-08
+vc -0.384993791580 0.00000000000 3.36572263393e-08
+vc -0.386237740517 0.00000000000 3.37659749050e-08
+vc -0.386409878731 0.00000000000 3.37810242002e-08
+vc -0.383426785469 0.00000000000 3.35202336998e-08
+vc -0.313721656799 0.00000000000 2.74264184696e-08
+vc -0.315534710884 0.00000000000 2.75849210141e-08
+vc -0.315058469772 0.00000000000 2.75432867625e-08
+vc -0.314747571945 0.00000000000 2.75161067265e-08
+vc -0.315399169922 0.00000000000 2.75730709376e-08
+vc -0.316258549690 0.00000000000 2.76482001738e-08
+vc -0.316821813583 0.00000000000 2.76974425617e-08
+vc -0.317050933838 0.00000000000 2.77174727614e-08
+vc -0.315386176109 0.00000000000 2.75719358456e-08
+vc -0.244962811470 0.00000000000 2.14153299538e-08
+vc -0.245425462723 0.00000000000 2.14557758227e-08
+vc -0.244793057442 0.00000000000 2.14004884924e-08
+vc -0.244615197182 0.00000000000 2.13849400410e-08
+vc -0.245502710342 0.00000000000 2.14625277550e-08
+vc -0.246272802353 0.00000000000 2.15298516792e-08
+vc -0.246709227562 0.00000000000 2.15680060478e-08
+vc -0.247112512589 0.00000000000 2.16032614020e-08
+vc -0.246777772903 0.00000000000 2.15739976994e-08
+vc -0.175607562065 0.00000000000 1.53521000357e-08
+vc -0.174845695496 0.00000000000 1.52854955360e-08
+vc -0.174018502235 0.00000000000 1.52131800490e-08
+vc -0.174355626106 0.00000000000 1.52426533617e-08
+vc -0.175920009613 0.00000000000 1.53794150748e-08
+vc -0.175931811333 0.00000000000 1.53804471381e-08
+vc -0.175831675529 0.00000000000 1.53716932516e-08
+vc -0.176266789436 0.00000000000 1.54097321570e-08
+vc -0.176836133003 0.00000000000 1.54595056756e-08
+vc -0.104960441589 0.00000000000 9.17593290239e-09
+vc -0.103270053864 0.00000000000 9.02815511239e-09
+vc -0.102258801460 0.00000000000 8.93974849703e-09
+vc -0.102768778801 0.00000000000 8.98433238916e-09
+vc -0.104298233986 0.00000000000 9.11804143300e-09
+vc -0.104399561882 0.00000000000 9.12689923638e-09
+vc -0.104354858398 0.00000000000 9.12299125133e-09
+vc -0.104899764061 0.00000000000 9.17062870087e-09
+vc -0.106104493141 0.00000000000 9.27594978606e-09
+vc -0.0332220792770 0.00000000000 2.90436630301e-09
+vc -0.0312508344650 0.00000000000 2.73203482060e-09
+vc -0.0302327871323 0.00000000000 2.64303423592e-09
+vc -0.0309371948242 0.00000000000 2.70461542051e-09
+vc -0.0328706502914 0.00000000000 2.87364354534e-09
+vc -0.0325299501419 0.00000000000 2.84385848204e-09
+vc -0.0321335792542 0.00000000000 2.80920664508e-09
+vc -0.0327329635620 0.00000000000 2.86160650731e-09
+vc -0.0342955589294 0.00000000000 2.99821301120e-09
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 7.43852046625e-09 0.288096547127 0.623781561852
+vc 1.10372877504e-09 0.202633187175 0.0925567969680
+vc 0.00000000000 0.146643534303 0.00000000000
+vc 0.00000000000 0.100708149374 0.00000000000
+vc 0.00000000000 0.0852765515447 0.00000000000
+vc 0.00000000000 0.114887557924 0.00000000000
+vc 0.00000000000 0.162790670991 0.00000000000
+vc 6.83492429321e-10 0.327754139900 0.0573165006936
+vc 5.05516384308e-09 0.530728101730 0.423917353153
+vc 1.06907549480e-08 0.00000000000 0.896508336067
+vc 3.13140735564e-09 0.193678647280 0.262594431639
+vc 1.15118292676e-09 0.0868320018053 0.0965362191200
+vc 2.40304498522e-10 0.0610211640596 0.0201515220106
+vc 0.00000000000 0.0355497673154 0.00000000000
+vc 2.54334914240e-10 0.0723929554224 0.0213280897588
+vc 9.73269687066e-10 0.109585642815 0.0816167220473
+vc 2.41870101725e-09 0.296505302191 0.202828109264
+vc 8.97424001778e-09 0.0707675069571 0.752564370632
+vc 1.18110969893e-08 0.00000000000 0.990458309650
+vc 6.88675472205e-09 0.00304530607536 0.577511429787
+vc 3.49349260631e-09 0.0302337408066 0.292958289385
+vc 2.58602805836e-09 0.0267748106271 0.216859877110
+vc 2.15457696129e-09 0.00000000000 0.180679112673
+vc 2.62050114941e-09 0.00000000000 0.219750732183
+vc 3.36394623268e-09 0.0616945065558 0.282094746828
+vc 6.35455599252e-09 0.00000000000 0.532882153988
+vc 1.04353565789e-08 0.00000000000 0.875091075897
+vc 1.26769919007e-08 0.00000000000 1.06307077408
+vc 8.52267767470e-09 0.00000000000 0.714697122574
+vc 6.39028252536e-09 0.00000000000 0.535878121853
+vc 5.10674746934e-09 0.00000000000 0.428243070841
+vc 4.34901092916e-09 0.00000000000 0.364700585604
+vc 4.94479124313e-09 0.00000000000 0.414661705494
+vc 6.30056051776e-09 0.00000000000 0.528354167938
+vc 7.86846676704e-09 0.00000000000 0.659836113453
+vc 1.21724905711e-08 0.00000000000 1.02076411247
+vc 1.22084076182e-08 0.00000000000 1.02377605438
+vc 9.98458205004e-09 0.00000000000 0.837289929390
+vc 7.97734056590e-09 0.00000000000 0.668966054916
+vc 6.59627463762e-09 0.00000000000 0.553152263165
+vc 5.62935520421e-09 0.00000000000 0.472068071365
+vc 6.55549259321e-09 0.00000000000 0.549732327461
+vc 7.92230014923e-09 0.00000000000 0.664350450039
+vc 9.77495595578e-09 0.00000000000 0.819711029530
+vc 1.20147829463e-08 0.00000000000 1.00753903389
+vc 1.37382576426e-08 0.00000000000 1.15206670761
+vc 1.02893524812e-08 0.00000000000 0.862847387791
+vc 8.56869863952e-09 0.00000000000 0.718556344509
+vc 7.52950413130e-09 0.00000000000 0.631411254406
+vc 7.09430292289e-09 0.00000000000 0.594916045666
+vc 7.45995532014e-09 0.00000000000 0.625579059124
+vc 8.66884253270e-09 0.00000000000 0.726954221725
+vc 9.92832216440e-09 0.00000000000 0.832572042942
+vc 1.41109328666e-08 0.00000000000 1.18331861496
+vc 1.29365567147e-08 0.00000000000 1.08483743668
+vc 1.14220926051e-08 0.00000000000 0.957837045193
+vc 9.90586634941e-09 0.00000000000 0.830688953400
+vc 8.89829276929e-09 0.00000000000 0.746195554733
+vc 8.39459968205e-09 0.00000000000 0.703956723213
+vc 8.94261820150e-09 0.00000000000 0.749912559986
+vc 9.88093340482e-09 0.00000000000 0.828598082066
+vc 1.13694698101e-08 0.00000000000 0.953424215317
+vc 1.30759163497e-08 0.00000000000 1.09652388096
+vc 1.40975835450e-08 0.00000000000 1.18219912052
+vc 1.17722072090e-08 0.00000000000 0.987197101116
+vc 1.08672377763e-08 0.00000000000 0.911307871342
+vc 1.02344115405e-08 0.00000000000 0.858240187168
+vc 9.72041114267e-09 0.00000000000 0.815136969090
+vc 1.01791686191e-08 0.00000000000 0.853607594967
+vc 1.07434408037e-08 0.00000000000 0.900926470757
+vc 1.17384528764e-08 0.00000000000 0.984366476536
+vc 1.42951215309e-08 0.00000000000 1.19876432419
+vc 1.33691475668e-08 0.00000000000 1.12111377716
+vc 1.30346853311e-08 0.00000000000 1.09306633472
+vc 1.20748877563e-08 0.00000000000 1.01257932186
+vc 1.14204565804e-08 0.00000000000 0.957699835300
+vc 1.08163789037e-08 0.00000000000 0.907042980194
+vc 1.14289422370e-08 0.00000000000 0.958411455154
+vc 1.21264633890e-08 0.00000000000 1.01690435410
+vc 1.30578614588e-08 0.00000000000 1.09500980377
+vc 1.34105562211e-08 0.00000000000 1.12458622456
+vc 1.26957697688e-08 0.00000000000 1.06464540958
+vc 1.30972415135e-08 0.00000000000 1.09831213951
+vc 1.28766401986e-08 0.00000000000 1.07981288433
+vc 1.23573364874e-08 0.00000000000 1.03626501560
+vc 1.18827818696e-08 0.00000000000 0.996469676495
+vc 1.23657875051e-08 0.00000000000 1.03697371483
+vc 1.28330261973e-08 0.00000000000 1.07615554333
+vc 1.31226940425e-08 0.00000000000 1.10044658184
+vc 1.27366828195e-08 0.00000000000 1.06807637215
+vc 1.20133609727e-08 0.00000000000 1.00741982460
+vc 1.23684644748e-08 0.00000000000 1.03719818592
+vc 1.24030581361e-08 0.00000000000 1.04009914398
+vc 1.23095009741e-08 0.00000000000 1.03225362301
+vc 1.21390328900e-08 0.00000000000 1.01795840263
+vc 1.23276686637e-08 0.00000000000 1.03377711773
+vc 1.24214505348e-08 0.00000000000 1.04164147377
+vc 1.23931558349e-08 0.00000000000 1.03926873207
+vc 1.20508731882e-08 0.00000000000 1.01056551933
+vc 1.13205596008e-08 0.00000000000 0.949322640896
+vc 1.16276321904e-08 0.00000000000 0.975073277950
+vc 1.16583640519e-08 0.00000000000 0.977650344372
+vc 1.15776881415e-08 0.00000000000 0.970885038376
+vc 1.14310703125e-08 0.00000000000 0.958589911461
+vc 1.15938929568e-08 0.00000000000 0.972243905067
+vc 1.16774918624e-08 0.00000000000 0.979254424572
+vc 1.16523590776e-08 0.00000000000 0.977146804333
+vc 1.13559917025e-08 0.00000000000 0.952293932438
+vc 1.06135749078e-08 0.00000000000 0.890036165714
+vc 1.08830491286e-08 0.00000000000 0.912633776665
+vc 1.09073061694e-08 0.00000000000 0.914667963982
+vc 1.08346212002e-08 0.00000000000 0.908572733402
+vc 1.07099573654e-08 0.00000000000 0.898118615150
+vc 1.08509059515e-08 0.00000000000 0.909938335419
+vc 1.09236779622e-08 0.00000000000 0.916040837765
+vc 1.09057420872e-08 0.00000000000 0.914536774158
+vc 1.06463398097e-08 0.00000000000 0.892783761024
+vc 9.89507586979e-09 0.00000000000 0.829784095287
+vc 1.01248378570e-08 0.00000000000 0.849051535130
+vc 1.01458637047e-08 0.00000000000 0.850814700127
+vc 1.00852117768e-08 0.00000000000 0.845728516579
+vc 9.98419391607e-09 0.00000000000 0.837257325649
+vc 1.01020916077e-08 0.00000000000 0.847144067287
+vc 1.01649844098e-08 0.00000000000 0.852418124676
+vc 1.01476578251e-08 0.00000000000 0.850965142250
+vc 9.92513182752e-09 0.00000000000 0.832304537296
+vc 9.16229581094e-09 0.00000000000 0.768334388733
+vc 9.36336608248e-09 0.00000000000 0.785195827484
+vc 9.37891009301e-09 0.00000000000 0.786499261856
+vc 9.32399757403e-09 0.00000000000 0.781894385815
+vc 9.23852905288e-09 0.00000000000 0.774727165699
+vc 9.34050792267e-09 0.00000000000 0.783278942108
+vc 9.39502164954e-09 0.00000000000 0.787850379944
+vc 9.38343802659e-09 0.00000000000 0.786879003048
+vc 9.19852372050e-09 0.00000000000 0.771372377872
+vc 8.42340242002e-09 0.00000000000 0.706372082233
+vc 8.58676774129e-09 0.00000000000 0.720071554184
+vc 8.60061888375e-09 0.00000000000 0.721233129501
+vc 8.55680415413e-09 0.00000000000 0.717558920383
+vc 8.49205505915e-09 0.00000000000 0.712129116058
+vc 8.57377457919e-09 0.00000000000 0.718982040882
+vc 8.61868176827e-09 0.00000000000 0.722747862339
+vc 8.60834070693e-09 0.00000000000 0.721880674362
+vc 8.45362091439e-09 0.00000000000 0.708906114101
+vc 7.67230812215e-09 0.00000000000 0.643386542797
+vc 7.80570985626e-09 0.00000000000 0.654573440552
+vc 7.81429587704e-09 0.00000000000 0.655293405056
+vc 7.77625519532e-09 0.00000000000 0.652103364468
+vc 7.72533503834e-09 0.00000000000 0.647833347321
+vc 7.79537590034e-09 0.00000000000 0.653706848621
+vc 7.83543097072e-09 0.00000000000 0.657065808773
+vc 7.82646658593e-09 0.00000000000 0.656314074993
+vc 7.69793029320e-09 0.00000000000 0.645535171032
+vc 6.90684576199e-09 0.00000000000 0.579196214676
+vc 7.01271707371e-09 0.00000000000 0.588074386120
+vc 7.01905422673e-09 0.00000000000 0.588605821133
+vc 6.99127555848e-09 0.00000000000 0.586276352406
+vc 6.95746527057e-09 0.00000000000 0.583441078663
+vc 7.00935398612e-09 0.00000000000 0.587792396545
+vc 7.03845293160e-09 0.00000000000 0.590232551098
+vc 7.03367630805e-09 0.00000000000 0.589832007885
+vc 6.93472479441e-09 0.00000000000 0.581534087658
+vc 6.13401285321e-09 0.00000000000 0.514387786388
+vc 6.21425266800e-09 0.00000000000 0.521116554737
+vc 6.21703843962e-09 0.00000000000 0.521350145340
+vc 6.19369400212e-09 0.00000000000 0.519392549992
+vc 6.16808781828e-09 0.00000000000 0.517245233059
+vc 6.21234086395e-09 0.00000000000 0.520956218243
+vc 6.23732976379e-09 0.00000000000 0.523051738739
+vc 6.23555473922e-09 0.00000000000 0.522902905941
+vc 6.15932949088e-09 0.00000000000 0.516510784626
+vc 5.34702726540e-09 0.00000000000 0.448392510414
+vc 5.40441558172e-09 0.00000000000 0.453204989433
+vc 5.40409539340e-09 0.00000000000 0.453178167343
+vc 5.38993694121e-09 0.00000000000 0.451990842819
+vc 5.38021360796e-09 0.00000000000 0.451175451279
+vc 5.40901545776e-09 0.00000000000 0.453590750694
+vc 5.42510880663e-09 0.00000000000 0.454940319061
+vc 5.42495248723e-09 0.00000000000 0.454927206039
+vc 5.37056399352e-09 0.00000000000 0.450366258621
+vc 4.55207871397e-09 0.00000000000 0.381729483604
+vc 4.58984228402e-09 0.00000000000 0.384896278381
+vc 4.58644455748e-09 0.00000000000 0.384611368179
+vc 4.57369209172e-09 0.00000000000 0.383541941643
+vc 4.56742421662e-09 0.00000000000 0.383016347885
+vc 4.59100490957e-09 0.00000000000 0.384993791580
+vc 4.60583882145e-09 0.00000000000 0.386237740517
+vc 4.60789184586e-09 0.00000000000 0.386409878731
+vc 4.57231852380e-09 0.00000000000 0.383426785469
+vc 3.74109321299e-09 0.00000000000 0.313721656799
+vc 3.76271369618e-09 0.00000000000 0.315534710884
+vc 3.75703468336e-09 0.00000000000 0.315058469772
+vc 3.75332742664e-09 0.00000000000 0.314747571945
+vc 3.76109765554e-09 0.00000000000 0.315399169922
+vc 3.77134545815e-09 0.00000000000 0.316258549690
+vc 3.77806230745e-09 0.00000000000 0.316821813583
+vc 3.78079434427e-09 0.00000000000 0.317050933838
+vc 3.76094266841e-09 0.00000000000 0.315386176109
+vc 2.92115220901e-09 0.00000000000 0.244962811470
+vc 2.92666935131e-09 0.00000000000 0.245425462723
+vc 2.91912805039e-09 0.00000000000 0.244793057442
+vc 2.91700708033e-09 0.00000000000 0.244615197182
+vc 2.92759061438e-09 0.00000000000 0.245502710342
+vc 2.93677371310e-09 0.00000000000 0.246272802353
+vc 2.94197799455e-09 0.00000000000 0.246709227562
+vc 2.94678725865e-09 0.00000000000 0.247112512589
+vc 2.94279556279e-09 0.00000000000 0.246777772903
+vc 2.09409911633e-09 0.00000000000 0.175607562065
+vc 2.08501393928e-09 0.00000000000 0.174845695496
+vc 2.07514982975e-09 0.00000000000 0.174018502235
+vc 2.07916994732e-09 0.00000000000 0.174355626106
+vc 2.09782502480e-09 0.00000000000 0.175920009613
+vc 2.09796580108e-09 0.00000000000 0.175931811333
+vc 2.09677164520e-09 0.00000000000 0.175831675529
+vc 2.10196038353e-09 0.00000000000 0.176266789436
+vc 2.10874984141e-09 0.00000000000 0.176836133003
+vc 1.25164079101e-09 0.00000000000 0.104960441589
+vc 1.23148302666e-09 0.00000000000 0.103270053864
+vc 1.21942400622e-09 0.00000000000 0.102258801460
+vc 1.22550547488e-09 0.00000000000 0.102768778801
+vc 1.24374399668e-09 0.00000000000 0.104298233986
+vc 1.24495236342e-09 0.00000000000 0.104399561882
+vc 1.24441923433e-09 0.00000000000 0.104354858398
+vc 1.25091714764e-09 0.00000000000 0.104899764061
+vc 1.26528343358e-09 0.00000000000 0.106104493141
+vc 3.96169319572e-10 0.00000000000 0.0332220792770
+vc 3.72662484205e-10 0.00000000000 0.0312508344650
+vc 3.60522389720e-10 0.00000000000 0.0302327871323
+vc 3.68922364880e-10 0.00000000000 0.0309371948242
+vc 3.91978588477e-10 0.00000000000 0.0328706502914
+vc 3.87915782829e-10 0.00000000000 0.0325299501419
+vc 3.83189091568e-10 0.00000000000 0.0321335792542
+vc 3.90336679645e-10 0.00000000000 0.0327329635620
+vc 4.08970440846e-10 0.00000000000 0.0342955589294
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vc 0.00000000000 0.00000000000 0.00000000000
+vt 0.00582895195112 0.650636613369 0.611725687981
+vt 0.0771106034517 0.650636613369 0.611725628376
+vt 0.148390963674 0.650636613369 0.611725628376
+vt 0.219669073820 0.650636613369 0.611725568771
+vt 0.290944486856 0.650636613369 0.611725509167
+vt 0.362216979265 0.650636613369 0.611725449562
+vt 0.433486640453 0.650636613369 0.611725449562
+vt 0.504754304886 0.650636613369 0.611725389957
+vt 0.576021015644 0.650636613369 0.611725389957
+vt 0.00578810228035 0.625035464764 0.575665950775
+vt 0.0770697519183 0.625035464764 0.575665771961
+vt 0.148350208998 0.625035107136 0.575665354729
+vt 0.219628572464 0.625034391880 0.575664699078
+vt 0.290904164314 0.625033915043 0.575663983822
+vt 0.362176924944 0.625033318996 0.575663268566
+vt 0.433447003365 0.625032842159 0.575662612915
+vt 0.504715025425 0.625032603741 0.575662255287
+vt 0.575982093811 0.625032484531 0.575662136078
+vt 0.00574396364391 0.597104012966 0.542801201344
+vt 0.0770257040858 0.597103774548 0.542800903320
+vt 0.148306161165 0.597103059292 0.542800247669
+vt 0.219584524632 0.597101986408 0.542799293995
+vt 0.290860116482 0.597100675106 0.542798221111
+vt 0.362132877111 0.597099363804 0.542797088623
+vt 0.433402955532 0.597098410130 0.542796194553
+vt 0.504671037197 0.597097694874 0.542795598507
+vt 0.575938105583 0.597097575665 0.542795419693
+vt 0.00570363365114 0.567022025585 0.511686921120
+vt 0.0769853740931 0.567021548748 0.511686623096
+vt 0.148265808821 0.567020237446 0.511685967445
+vt 0.219544187188 0.567018568516 0.511685013771
+vt 0.290819883347 0.567016422749 0.511683881283
+vt 0.362092584372 0.567014515400 0.511682748795
+vt 0.433362662792 0.567012846470 0.511681795120
+vt 0.504630804062 0.567011654377 0.511681199074
+vt 0.575897872448 0.567011296749 0.511681020260
+vt 0.00569593161345 0.534782230854 0.480913400650
+vt 0.0769776701927 0.534781515598 0.480913221836
+vt 0.148258119822 0.534779846668 0.480912804604
+vt 0.219536483288 0.534777224064 0.480912178755
+vt 0.290812075138 0.534774363041 0.480911463499
+vt 0.362084805965 0.534771502018 0.480910748243
+vt 0.433354973793 0.534768998623 0.480910181999
+vt 0.504623055458 0.534767448902 0.480909824371
+vt 0.575890123844 0.534766972065 0.480909675360
+vt 0.00574465608224 0.499848902225 0.451278597116
+vt 0.0770263075829 0.499848067760 0.451278626919
+vt 0.148306861520 0.499845683575 0.451278746128
+vt 0.219585210085 0.499842226505 0.451278865337
+vt 0.290860801935 0.499838411808 0.451279044151
+vt 0.362133562565 0.499834597111 0.451279193163
+vt 0.433403670788 0.499831378460 0.451279342175
+vt 0.504671752453 0.499829351902 0.451279431581
+vt 0.575938880444 0.499828636646 0.451279461384
+vt 0.00580229563639 0.461873471737 0.422216087580
+vt 0.0770839527249 0.461872279644 0.422216445208
+vt 0.148364394903 0.461869418621 0.422217339277
+vt 0.219642847776 0.461865246296 0.422218650579
+vt 0.290918439627 0.461860358715 0.422220200300
+vt 0.362191200256 0.461855590343 0.422221720219
+vt 0.433461278677 0.461851537228 0.422222971916
+vt 0.504729390144 0.461849033833 0.422223746777
+vt 0.575996458530 0.461848318577 0.422224014997
+vt 0.00582592235878 0.420156538486 0.394632130861
+vt 0.0771075710654 0.420155227184 0.394632905722
+vt 0.148388028145 0.420151889324 0.394634902477
+vt 0.219666376710 0.420147001743 0.394637793303
+vt 0.290942072868 0.420141279697 0.394641190767
+vt 0.362214803696 0.420135796070 0.394644498825
+vt 0.433484911919 0.420131027699 0.394647270441
+vt 0.504752993584 0.420128047466 0.394649058580
+vt 0.576020061970 0.420127213001 0.394649595022
+vt 0.00582895195112 0.374057829380 0.369725733995
+vt 0.0771106034517 0.374056398869 0.369727045298
+vt 0.148391142488 0.374052703381 0.369730412960
+vt 0.219669431448 0.374047458172 0.369735240936
+vt 0.290945082903 0.374041378498 0.369740843773
+vt 0.362217843533 0.374035298824 0.369746387005
+vt 0.433487892151 0.374030292034 0.369751006365
+vt 0.504756033421 0.374026954174 0.369753986597
+vt 0.576023101807 0.374025881290 0.369754880667
+vt 0.00582895195112 0.323164939880 0.348501473665
+vt 0.0771106034517 0.323163568974 0.348503381014
+vt 0.148391142488 0.323160052299 0.348508119583
+vt 0.219669431448 0.323154807091 0.348515093327
+vt 0.290945082903 0.323148787022 0.348523199558
+vt 0.362217843533 0.323142886162 0.348531246185
+vt 0.433487921953 0.323137879372 0.348537892103
+vt 0.504756033421 0.323134601116 0.348542213440
+vt 0.576023101807 0.323133587837 0.348543494940
+vt 0.00582895195112 0.267601013184 0.335717856884
+vt 0.0771106034517 0.267599821091 0.335720270872
+vt 0.148391142488 0.267596840858 0.335726529360
+vt 0.219669505954 0.267592489719 0.335735589266
+vt 0.290945082903 0.267587304115 0.335746139288
+vt 0.362217843533 0.267582297325 0.335756570101
+vt 0.433487921953 0.267578005791 0.335765242577
+vt 0.504756033421 0.267575323582 0.335770845413
+vt 0.576023101807 0.267574489117 0.335772573948
+vt 0.00582895195112 0.209566950798 0.334688484669
+vt 0.0771106034517 0.209566235542 0.334691405296
+vt 0.148391053081 0.209564208984 0.334698826075
+vt 0.219669431448 0.209561228752 0.334709703922
+vt 0.290945082903 0.209557950497 0.334722280502
+vt 0.362217843533 0.209554553032 0.334734767675
+vt 0.433487921953 0.209551870823 0.334745109081
+vt 0.504756033421 0.209550142288 0.334751844406
+vt 0.576023101807 0.209549605846 0.334753781557
+vt 0.00582895195112 0.151353776455 0.340644299984
+vt 0.0771106034517 0.151353538036 0.340647518635
+vt 0.148391142488 0.151352882385 0.340655714273
+vt 0.219669505954 0.151351869106 0.340667605400
+vt 0.290945082903 0.151350796223 0.340681493282
+vt 0.362217843533 0.151349723339 0.340695053339
+vt 0.433487892151 0.151348829269 0.340706378222
+vt 0.504756033421 0.151348233223 0.340713769197
+vt 0.576023101807 0.151348054409 0.340716004372
+vt 0.00582895195112 0.0930109024048 0.341600179672
+vt 0.0771106034517 0.0930112004280 0.341603428125
+vt 0.148391142488 0.0930119752884 0.341611534357
+vt 0.219669505954 0.0930130481720 0.341623395681
+vt 0.290945082903 0.0930142998695 0.341637283564
+vt 0.362217843533 0.0930155515671 0.341650873423
+vt 0.433487921953 0.0930166244507 0.341662198305
+vt 0.504756033421 0.0930172801018 0.341669529676
+vt 0.576023101807 0.0930174589157 0.341671824455
+vt 0.00582895195112 0.0378581881523 0.323051154613
+vt 0.0771106034517 0.0378589630127 0.323053985834
+vt 0.148391142488 0.0378610491753 0.323061376810
+vt 0.219669431448 0.0378640294075 0.323072046041
+vt 0.290945082903 0.0378675460815 0.323084384203
+vt 0.362217843533 0.0378709435463 0.323096603155
+vt 0.433488011360 0.0378737449646 0.323106735945
+vt 0.504756033421 0.0378755927086 0.323113381863
+vt 0.576023161411 0.0378761291504 0.323115319014
+vt 0.00582895195112 0.00624942779541 0.289594531059
+vt 0.0771106034517 0.00625044107437 0.289597004652
+vt 0.148391142488 0.00625330209732 0.289603412151
+vt 0.219669505954 0.00625747442245 0.289612799883
+vt 0.290945082903 0.00626224279404 0.289623558521
+vt 0.362217843533 0.00626701116562 0.289634257555
+vt 0.433488011360 0.00627094507217 0.289643168449
+vt 0.504756033421 0.00627344846725 0.289648920298
+vt 0.576023161411 0.00627422332764 0.289650768042
+vt 0.581808090210 0.996866106987 0.295587658882
+vt 0.581808090210 0.954363465309 0.295587629080
+vt 0.581808090210 0.911861419678 0.295587569475
+vt 0.581807971001 0.869360744953 0.295587480068
+vt 0.581807851791 0.826861679554 0.295587420464
+vt 0.581807851791 0.784364402294 0.295587331057
+vt 0.581807851791 0.741868615150 0.295587241650
+vt 0.581807851791 0.699374079704 0.295587211847
+vt 0.581807851791 0.656880140305 0.295587211847
+vt 0.525557756424 0.996866106987 0.308058202267
+vt 0.525557637215 0.954363405704 0.308058023453
+vt 0.525557279587 0.911861479282 0.308057606220
+vt 0.525556921959 0.869360685349 0.308057039976
+vt 0.525556325912 0.826861619949 0.308056324720
+vt 0.525555729866 0.784364223480 0.308055639267
+vt 0.525555372238 0.741868495941 0.308055073023
+vt 0.525555014610 0.699373841286 0.308054715395
+vt 0.525554895401 0.656879842281 0.308054596186
+vt 0.473296284676 0.996866106987 0.317884117365
+vt 0.473295927048 0.954363405704 0.317883878946
+vt 0.473295211792 0.911861419678 0.317883282900
+vt 0.473294019699 0.869360685349 0.317882418633
+vt 0.473292589188 0.826861619949 0.317881435156
+vt 0.473291277885 0.784364283085 0.317880481482
+vt 0.473290205002 0.741868495941 0.317879647017
+vt 0.473289489746 0.699373841286 0.317879110575
+vt 0.473289251328 0.656879842281 0.317878961563
+vt 0.423550724983 0.996866106987 0.322069466114
+vt 0.423550128937 0.954363405704 0.322069287300
+vt 0.423548698425 0.911861419678 0.322068899870
+vt 0.423546671867 0.869360685349 0.322068274021
+vt 0.423544287682 0.826861619949 0.322067588568
+vt 0.423541903496 0.784364283085 0.322066932917
+vt 0.423539996147 0.741868495941 0.322066366673
+vt 0.423538804054 0.699373841286 0.322066009045
+vt 0.423538446426 0.656879782677 0.322065889835
+vt 0.374823629856 0.996866106987 0.324172198772
+vt 0.374822914600 0.954363405704 0.324172258377
+vt 0.374820828438 0.911861479282 0.324172496796
+vt 0.374817907810 0.869360744953 0.324172824621
+vt 0.374814569950 0.826861619949 0.324173182249
+vt 0.374811172485 0.784364283085 0.324173569679
+vt 0.374808430672 0.741868495941 0.324173867702
+vt 0.374806642532 0.699373841286 0.324174076319
+vt 0.374806165695 0.656879782677 0.324174135923
+vt 0.326615214348 0.996866106987 0.329102188349
+vt 0.326614141464 0.954363405704 0.329102724791
+vt 0.326611697674 0.911861419678 0.329104036093
+vt 0.326608181000 0.869360744953 0.329105913639
+vt 0.326604127884 0.826861619949 0.329108089209
+vt 0.326600074768 0.784364223480 0.329110234976
+vt 0.326596796513 0.741868495941 0.329111993313
+vt 0.326594591141 0.699373841286 0.329113155603
+vt 0.326593935490 0.656879782677 0.329113483429
+vt 0.278899669647 0.996866166592 0.336456507444
+vt 0.278898596764 0.954363405704 0.336457610130
+vt 0.278896093369 0.911861419678 0.336460322142
+vt 0.278892397881 0.869360744953 0.336464256048
+vt 0.278887987137 0.826861619949 0.336468756199
+vt 0.278883695602 0.784364283085 0.336473196745
+vt 0.278880178928 0.741868495941 0.336476892233
+vt 0.278877913952 0.699373841286 0.336479246616
+vt 0.278877139091 0.656879782677 0.336480021477
+vt 0.231058657169 0.996866166592 0.343259334564
+vt 0.231057703495 0.954363465309 0.343261033297
+vt 0.231055259705 0.911861419678 0.343265295029
+vt 0.231051743031 0.869360744953 0.343271464109
+vt 0.231047689915 0.826861619949 0.343278616667
+vt 0.231043577194 0.784364223480 0.343285590410
+vt 0.231040358543 0.741868495941 0.343291461468
+vt 0.231038272381 0.699373841286 0.343295216560
+vt 0.231037616730 0.656879842281 0.343296319246
+vt 0.181793510914 0.996866166592 0.344054639339
+vt 0.181792736053 0.954363465309 0.344056934118
+vt 0.181790828705 0.911861479282 0.344062685966
+vt 0.181788027287 0.869360744953 0.344070881605
+vt 0.181784868240 0.826861619949 0.344080418348
+vt 0.181781589985 0.784364223480 0.344089835882
+vt 0.181778967381 0.741868495941 0.344097644091
+vt 0.181777358055 0.699373841286 0.344102680683
+vt 0.181776821613 0.656879842281 0.344104140997
+vt 0.130297482014 0.996866166592 0.327336490154
+vt 0.130297064781 0.954363465309 0.327339112759
+vt 0.130295932293 0.911861479282 0.327345669270
+vt 0.130294382572 0.869360804558 0.327355206013
+vt 0.130292534828 0.826861679554 0.327366232872
+vt 0.130290687084 0.784364283085 0.327377080917
+vt 0.130289137363 0.741868495941 0.327386111021
+vt 0.130288243294 0.699373841286 0.327391952276
+vt 0.130287945271 0.656879842281 0.327393651009
+vt 0.0758445858955 0.996866166592 0.300447374582
+vt 0.0758446455002 0.954363465309 0.300449967384
+vt 0.0758446455002 0.911861479282 0.300456613302
+vt 0.0758446455002 0.869360804558 0.300466269255
+vt 0.0758447051048 0.826861679554 0.300477385521
+vt 0.0758447051048 0.784364283085 0.300488322973
+vt 0.0758447647095 0.741868555546 0.300497442484
+vt 0.0758447647095 0.699373900890 0.300503283739
+vt 0.0758447647095 0.656879901886 0.300505012274
+vt 0.0220620632172 0.996866166592 0.326429128647
+vt 0.0220625400543 0.954363465309 0.326431721449
+vt 0.0220636129379 0.911861479282 0.326438337564
+vt 0.0220652818680 0.869360804558 0.326447814703
+vt 0.0220671892166 0.826861679554 0.326458752155
+vt 0.0220689773560 0.784364283085 0.326469540596
+vt 0.0220705270767 0.741868495941 0.326478451490
+vt 0.0220715403557 0.699373841286 0.326484322548
+vt 0.0220718383789 0.656879842281 0.326485991478
+vt 0.00492912530899 0.996866166592 0.380903303623
+vt 0.00492966175079 0.954363465309 0.380906045437
+vt 0.00493103265762 0.911861479282 0.380912810564
+vt 0.00493299961090 0.869360804558 0.380922764540
+vt 0.00493526458740 0.826861679554 0.380934238434
+vt 0.00493746995926 0.784364283085 0.380945473909
+vt 0.00493925809860 0.741868495941 0.380954861641
+vt 0.00494045019150 0.699373841286 0.380960881710
+vt 0.00494080781937 0.656879842281 0.380962640047
+vt 0.00582895195112 0.650636613369 0.611725687981
+vt 0.0771106034517 0.650636613369 0.611725628376
+vt 0.148390963674 0.650636613369 0.611725628376
+vt 0.219669073820 0.650636613369 0.611725568771
+vt 0.290944486856 0.650636613369 0.611725509167
+vt 0.362216979265 0.650636613369 0.611725449562
+vt 0.433486640453 0.650636613369 0.611725449562
+vt 0.504754304886 0.650636613369 0.611725389957
+vt 0.576021015644 0.650636613369 0.611725389957
+vt 0.00578810228035 0.625035464764 0.575665950775
+vt 0.0770697519183 0.625035464764 0.575665771961
+vt 0.148350208998 0.625035107136 0.575665354729
+vt 0.219628572464 0.625034391880 0.575664699078
+vt 0.290904164314 0.625033915043 0.575663983822
+vt 0.362176924944 0.625033318996 0.575663268566
+vt 0.433447003365 0.625032842159 0.575662612915
+vt 0.504715025425 0.625032603741 0.575662255287
+vt 0.575982093811 0.625032484531 0.575662136078
+vt 0.00574396364391 0.597104012966 0.542801201344
+vt 0.0770257040858 0.597103774548 0.542800903320
+vt 0.148306161165 0.597103059292 0.542800247669
+vt 0.219584524632 0.597101986408 0.542799293995
+vt 0.290860116482 0.597100675106 0.542798221111
+vt 0.362132877111 0.597099363804 0.542797088623
+vt 0.433402955532 0.597098410130 0.542796194553
+vt 0.504671037197 0.597097694874 0.542795598507
+vt 0.575938105583 0.597097575665 0.542795419693
+vt 0.00570363365114 0.567022025585 0.511686921120
+vt 0.0769853740931 0.567021548748 0.511686623096
+vt 0.148265808821 0.567020237446 0.511685967445
+vt 0.219544187188 0.567018568516 0.511685013771
+vt 0.290819883347 0.567016422749 0.511683881283
+vt 0.362092584372 0.567014515400 0.511682748795
+vt 0.433362662792 0.567012846470 0.511681795120
+vt 0.504630804062 0.567011654377 0.511681199074
+vt 0.575897872448 0.567011296749 0.511681020260
+vt 0.00569593161345 0.534782230854 0.480913400650
+vt 0.0769776701927 0.534781515598 0.480913221836
+vt 0.148258119822 0.534779846668 0.480912804604
+vt 0.219536483288 0.534777224064 0.480912178755
+vt 0.290812075138 0.534774363041 0.480911463499
+vt 0.362084805965 0.534771502018 0.480910748243
+vt 0.433354973793 0.534768998623 0.480910181999
+vt 0.504623055458 0.534767448902 0.480909824371
+vt 0.575890123844 0.534766972065 0.480909675360
+vt 0.00574465608224 0.499848902225 0.451278597116
+vt 0.0770263075829 0.499848067760 0.451278626919
+vt 0.148306861520 0.499845683575 0.451278746128
+vt 0.219585210085 0.499842226505 0.451278865337
+vt 0.290860801935 0.499838411808 0.451279044151
+vt 0.362133562565 0.499834597111 0.451279193163
+vt 0.433403670788 0.499831378460 0.451279342175
+vt 0.504671752453 0.499829351902 0.451279431581
+vt 0.575938880444 0.499828636646 0.451279461384
+vt 0.00580229563639 0.461873471737 0.422216087580
+vt 0.0770839527249 0.461872279644 0.422216445208
+vt 0.148364394903 0.461869418621 0.422217339277
+vt 0.219642847776 0.461865246296 0.422218650579
+vt 0.290918439627 0.461860358715 0.422220200300
+vt 0.362191200256 0.461855590343 0.422221720219
+vt 0.433461278677 0.461851537228 0.422222971916
+vt 0.504729390144 0.461849033833 0.422223746777
+vt 0.575996458530 0.461848318577 0.422224014997
+vt 0.00582592235878 0.420156538486 0.394632130861
+vt 0.0771075710654 0.420155227184 0.394632905722
+vt 0.148388028145 0.420151889324 0.394634902477
+vt 0.219666376710 0.420147001743 0.394637793303
+vt 0.290942072868 0.420141279697 0.394641190767
+vt 0.362214803696 0.420135796070 0.394644498825
+vt 0.433484911919 0.420131027699 0.394647270441
+vt 0.504752993584 0.420128047466 0.394649058580
+vt 0.576020061970 0.420127213001 0.394649595022
+vt 0.00582895195112 0.374057829380 0.369725733995
+vt 0.0771106034517 0.374056398869 0.369727045298
+vt 0.148391142488 0.374052703381 0.369730412960
+vt 0.219669431448 0.374047458172 0.369735240936
+vt 0.290945082903 0.374041378498 0.369740843773
+vt 0.362217843533 0.374035298824 0.369746387005
+vt 0.433487892151 0.374030292034 0.369751006365
+vt 0.504756033421 0.374026954174 0.369753986597
+vt 0.576023101807 0.374025881290 0.369754880667
+vt 0.00582895195112 0.323164939880 0.348501473665
+vt 0.0771106034517 0.323163568974 0.348503381014
+vt 0.148391142488 0.323160052299 0.348508119583
+vt 0.219669431448 0.323154807091 0.348515093327
+vt 0.290945082903 0.323148787022 0.348523199558
+vt 0.362217843533 0.323142886162 0.348531246185
+vt 0.433487921953 0.323137879372 0.348537892103
+vt 0.504756033421 0.323134601116 0.348542213440
+vt 0.576023101807 0.323133587837 0.348543494940
+vt 0.00582895195112 0.267601013184 0.335717856884
+vt 0.0771106034517 0.267599821091 0.335720270872
+vt 0.148391142488 0.267596840858 0.335726529360
+vt 0.219669505954 0.267592489719 0.335735589266
+vt 0.290945082903 0.267587304115 0.335746139288
+vt 0.362217843533 0.267582297325 0.335756570101
+vt 0.433487921953 0.267578005791 0.335765242577
+vt 0.504756033421 0.267575323582 0.335770845413
+vt 0.576023101807 0.267574489117 0.335772573948
+vt 0.00582895195112 0.209566950798 0.334688484669
+vt 0.0771106034517 0.209566235542 0.334691405296
+vt 0.148391053081 0.209564208984 0.334698826075
+vt 0.219669431448 0.209561228752 0.334709703922
+vt 0.290945082903 0.209557950497 0.334722280502
+vt 0.362217843533 0.209554553032 0.334734767675
+vt 0.433487921953 0.209551870823 0.334745109081
+vt 0.504756033421 0.209550142288 0.334751844406
+vt 0.576023101807 0.209549605846 0.334753781557
+vt 0.00582895195112 0.151353776455 0.340644299984
+vt 0.0771106034517 0.151353538036 0.340647518635
+vt 0.148391142488 0.151352882385 0.340655714273
+vt 0.219669505954 0.151351869106 0.340667605400
+vt 0.290945082903 0.151350796223 0.340681493282
+vt 0.362217843533 0.151349723339 0.340695053339
+vt 0.433487892151 0.151348829269 0.340706378222
+vt 0.504756033421 0.151348233223 0.340713769197
+vt 0.576023101807 0.151348054409 0.340716004372
+vt 0.00582895195112 0.0930109024048 0.341600179672
+vt 0.0771106034517 0.0930112004280 0.341603428125
+vt 0.148391142488 0.0930119752884 0.341611534357
+vt 0.219669505954 0.0930130481720 0.341623395681
+vt 0.290945082903 0.0930142998695 0.341637283564
+vt 0.362217843533 0.0930155515671 0.341650873423
+vt 0.433487921953 0.0930166244507 0.341662198305
+vt 0.504756033421 0.0930172801018 0.341669529676
+vt 0.576023101807 0.0930174589157 0.341671824455
+vt 0.00582895195112 0.0378581881523 0.323051154613
+vt 0.0771106034517 0.0378589630127 0.323053985834
+vt 0.148391142488 0.0378610491753 0.323061376810
+vt 0.219669431448 0.0378640294075 0.323072046041
+vt 0.290945082903 0.0378675460815 0.323084384203
+vt 0.362217843533 0.0378709435463 0.323096603155
+vt 0.433488011360 0.0378737449646 0.323106735945
+vt 0.504756033421 0.0378755927086 0.323113381863
+vt 0.576023161411 0.0378761291504 0.323115319014
+vt 0.00582895195112 0.00624942779541 0.289594531059
+vt 0.0771106034517 0.00625044107437 0.289597004652
+vt 0.148391142488 0.00625330209732 0.289603412151
+vt 0.219669505954 0.00625747442245 0.289612799883
+vt 0.290945082903 0.00626224279404 0.289623558521
+vt 0.362217843533 0.00626701116562 0.289634257555
+vt 0.433488011360 0.00627094507217 0.289643168449
+vt 0.504756033421 0.00627344846725 0.289648920298
+vt 0.576023161411 0.00627422332764 0.289650768042
+vt 0.581808090210 0.996866106987 0.295587658882
+vt 0.581808090210 0.954363465309 0.295587629080
+vt 0.581808090210 0.911861419678 0.295587569475
+vt 0.581807971001 0.869360744953 0.295587480068
+vt 0.581807851791 0.826861679554 0.295587420464
+vt 0.581807851791 0.784364402294 0.295587331057
+vt 0.581807851791 0.741868615150 0.295587241650
+vt 0.581807851791 0.699374079704 0.295587211847
+vt 0.581807851791 0.656880140305 0.295587211847
+vt 0.525557756424 0.996866106987 0.308058202267
+vt 0.525557637215 0.954363405704 0.308058023453
+vt 0.525557279587 0.911861479282 0.308057606220
+vt 0.525556921959 0.869360685349 0.308057039976
+vt 0.525556325912 0.826861619949 0.308056324720
+vt 0.525555729866 0.784364223480 0.308055639267
+vt 0.525555372238 0.741868495941 0.308055073023
+vt 0.525555014610 0.699373841286 0.308054715395
+vt 0.525554895401 0.656879842281 0.308054596186
+vt 0.473296284676 0.996866106987 0.317884117365
+vt 0.473295927048 0.954363405704 0.317883878946
+vt 0.473295211792 0.911861419678 0.317883282900
+vt 0.473294019699 0.869360685349 0.317882418633
+vt 0.473292589188 0.826861619949 0.317881435156
+vt 0.473291277885 0.784364283085 0.317880481482
+vt 0.473290205002 0.741868495941 0.317879647017
+vt 0.473289489746 0.699373841286 0.317879110575
+vt 0.473289251328 0.656879842281 0.317878961563
+vt 0.423550724983 0.996866106987 0.322069466114
+vt 0.423550128937 0.954363405704 0.322069287300
+vt 0.423548698425 0.911861419678 0.322068899870
+vt 0.423546671867 0.869360685349 0.322068274021
+vt 0.423544287682 0.826861619949 0.322067588568
+vt 0.423541903496 0.784364283085 0.322066932917
+vt 0.423539996147 0.741868495941 0.322066366673
+vt 0.423538804054 0.699373841286 0.322066009045
+vt 0.423538446426 0.656879782677 0.322065889835
+vt 0.374823629856 0.996866106987 0.324172198772
+vt 0.374822914600 0.954363405704 0.324172258377
+vt 0.374820828438 0.911861479282 0.324172496796
+vt 0.374817907810 0.869360744953 0.324172824621
+vt 0.374814569950 0.826861619949 0.324173182249
+vt 0.374811172485 0.784364283085 0.324173569679
+vt 0.374808430672 0.741868495941 0.324173867702
+vt 0.374806642532 0.699373841286 0.324174076319
+vt 0.374806165695 0.656879782677 0.324174135923
+vt 0.326615214348 0.996866106987 0.329102188349
+vt 0.326614141464 0.954363405704 0.329102724791
+vt 0.326611697674 0.911861419678 0.329104036093
+vt 0.326608181000 0.869360744953 0.329105913639
+vt 0.326604127884 0.826861619949 0.329108089209
+vt 0.326600074768 0.784364223480 0.329110234976
+vt 0.326596796513 0.741868495941 0.329111993313
+vt 0.326594591141 0.699373841286 0.329113155603
+vt 0.326593935490 0.656879782677 0.329113483429
+vt 0.278899669647 0.996866166592 0.336456507444
+vt 0.278898596764 0.954363405704 0.336457610130
+vt 0.278896093369 0.911861419678 0.336460322142
+vt 0.278892397881 0.869360744953 0.336464256048
+vt 0.278887987137 0.826861619949 0.336468756199
+vt 0.278883695602 0.784364283085 0.336473196745
+vt 0.278880178928 0.741868495941 0.336476892233
+vt 0.278877913952 0.699373841286 0.336479246616
+vt 0.278877139091 0.656879782677 0.336480021477
+vt 0.231058657169 0.996866166592 0.343259334564
+vt 0.231057703495 0.954363465309 0.343261033297
+vt 0.231055259705 0.911861419678 0.343265295029
+vt 0.231051743031 0.869360744953 0.343271464109
+vt 0.231047689915 0.826861619949 0.343278616667
+vt 0.231043577194 0.784364223480 0.343285590410
+vt 0.231040358543 0.741868495941 0.343291461468
+vt 0.231038272381 0.699373841286 0.343295216560
+vt 0.231037616730 0.656879842281 0.343296319246
+vt 0.181793510914 0.996866166592 0.344054639339
+vt 0.181792736053 0.954363465309 0.344056934118
+vt 0.181790828705 0.911861479282 0.344062685966
+vt 0.181788027287 0.869360744953 0.344070881605
+vt 0.181784868240 0.826861619949 0.344080418348
+vt 0.181781589985 0.784364223480 0.344089835882
+vt 0.181778967381 0.741868495941 0.344097644091
+vt 0.181777358055 0.699373841286 0.344102680683
+vt 0.181776821613 0.656879842281 0.344104140997
+vt 0.130297482014 0.996866166592 0.327336490154
+vt 0.130297064781 0.954363465309 0.327339112759
+vt 0.130295932293 0.911861479282 0.327345669270
+vt 0.130294382572 0.869360804558 0.327355206013
+vt 0.130292534828 0.826861679554 0.327366232872
+vt 0.130290687084 0.784364283085 0.327377080917
+vt 0.130289137363 0.741868495941 0.327386111021
+vt 0.130288243294 0.699373841286 0.327391952276
+vt 0.130287945271 0.656879842281 0.327393651009
+vt 0.0758445858955 0.996866166592 0.300447374582
+vt 0.0758446455002 0.954363465309 0.300449967384
+vt 0.0758446455002 0.911861479282 0.300456613302
+vt 0.0758446455002 0.869360804558 0.300466269255
+vt 0.0758447051048 0.826861679554 0.300477385521
+vt 0.0758447051048 0.784364283085 0.300488322973
+vt 0.0758447647095 0.741868555546 0.300497442484
+vt 0.0758447647095 0.699373900890 0.300503283739
+vt 0.0758447647095 0.656879901886 0.300505012274
+vt 0.0220620632172 0.996866166592 0.326429128647
+vt 0.0220625400543 0.954363465309 0.326431721449
+vt 0.0220636129379 0.911861479282 0.326438337564
+vt 0.0220652818680 0.869360804558 0.326447814703
+vt 0.0220671892166 0.826861679554 0.326458752155
+vt 0.0220689773560 0.784364283085 0.326469540596
+vt 0.0220705270767 0.741868495941 0.326478451490
+vt 0.0220715403557 0.699373841286 0.326484322548
+vt 0.0220718383789 0.656879842281 0.326485991478
+vt 0.00492912530899 0.996866166592 0.380903303623
+vt 0.00492966175079 0.954363465309 0.380906045437
+vt 0.00493103265762 0.911861479282 0.380912810564
+vt 0.00493299961090 0.869360804558 0.380922764540
+vt 0.00493526458740 0.826861679554 0.380934238434
+vt 0.00493746995926 0.784364283085 0.380945473909
+vt 0.00493925809860 0.741868495941 0.380954861641
+vt 0.00494045019150 0.699373841286 0.380960881710
+vt 0.00494080781937 0.656879842281 0.380962640047
+vt 0.00582895195112 0.650636613369 0.611725687981
+vt 0.0771106034517 0.650636613369 0.611725628376
+vt 0.148390963674 0.650636613369 0.611725628376
+vt 0.219669073820 0.650636613369 0.611725568771
+vt 0.290944486856 0.650636613369 0.611725509167
+vt 0.362216979265 0.650636613369 0.611725449562
+vt 0.433486640453 0.650636613369 0.611725449562
+vt 0.504754304886 0.650636613369 0.611725389957
+vt 0.576021015644 0.650636613369 0.611725389957
+vt 0.00578810228035 0.625035464764 0.575665950775
+vt 0.0770697519183 0.625035464764 0.575665771961
+vt 0.148350208998 0.625035107136 0.575665354729
+vt 0.219628572464 0.625034391880 0.575664699078
+vt 0.290904164314 0.625033915043 0.575663983822
+vt 0.362176924944 0.625033318996 0.575663268566
+vt 0.433447003365 0.625032842159 0.575662612915
+vt 0.504715025425 0.625032603741 0.575662255287
+vt 0.575982093811 0.625032484531 0.575662136078
+vt 0.00574396364391 0.597104012966 0.542801201344
+vt 0.0770257040858 0.597103774548 0.542800903320
+vt 0.148306161165 0.597103059292 0.542800247669
+vt 0.219584524632 0.597101986408 0.542799293995
+vt 0.290860116482 0.597100675106 0.542798221111
+vt 0.362132877111 0.597099363804 0.542797088623
+vt 0.433402955532 0.597098410130 0.542796194553
+vt 0.504671037197 0.597097694874 0.542795598507
+vt 0.575938105583 0.597097575665 0.542795419693
+vt 0.00570363365114 0.567022025585 0.511686921120
+vt 0.0769853740931 0.567021548748 0.511686623096
+vt 0.148265808821 0.567020237446 0.511685967445
+vt 0.219544187188 0.567018568516 0.511685013771
+vt 0.290819883347 0.567016422749 0.511683881283
+vt 0.362092584372 0.567014515400 0.511682748795
+vt 0.433362662792 0.567012846470 0.511681795120
+vt 0.504630804062 0.567011654377 0.511681199074
+vt 0.575897872448 0.567011296749 0.511681020260
+vt 0.00569593161345 0.534782230854 0.480913400650
+vt 0.0769776701927 0.534781515598 0.480913221836
+vt 0.148258119822 0.534779846668 0.480912804604
+vt 0.219536483288 0.534777224064 0.480912178755
+vt 0.290812075138 0.534774363041 0.480911463499
+vt 0.362084805965 0.534771502018 0.480910748243
+vt 0.433354973793 0.534768998623 0.480910181999
+vt 0.504623055458 0.534767448902 0.480909824371
+vt 0.575890123844 0.534766972065 0.480909675360
+vt 0.00574465608224 0.499848902225 0.451278597116
+vt 0.0770263075829 0.499848067760 0.451278626919
+vt 0.148306861520 0.499845683575 0.451278746128
+vt 0.219585210085 0.499842226505 0.451278865337
+vt 0.290860801935 0.499838411808 0.451279044151
+vt 0.362133562565 0.499834597111 0.451279193163
+vt 0.433403670788 0.499831378460 0.451279342175
+vt 0.504671752453 0.499829351902 0.451279431581
+vt 0.575938880444 0.499828636646 0.451279461384
+vt 0.00580229563639 0.461873471737 0.422216087580
+vt 0.0770839527249 0.461872279644 0.422216445208
+vt 0.148364394903 0.461869418621 0.422217339277
+vt 0.219642847776 0.461865246296 0.422218650579
+vt 0.290918439627 0.461860358715 0.422220200300
+vt 0.362191200256 0.461855590343 0.422221720219
+vt 0.433461278677 0.461851537228 0.422222971916
+vt 0.504729390144 0.461849033833 0.422223746777
+vt 0.575996458530 0.461848318577 0.422224014997
+vt 0.00582592235878 0.420156538486 0.394632130861
+vt 0.0771075710654 0.420155227184 0.394632905722
+vt 0.148388028145 0.420151889324 0.394634902477
+vt 0.219666376710 0.420147001743 0.394637793303
+vt 0.290942072868 0.420141279697 0.394641190767
+vt 0.362214803696 0.420135796070 0.394644498825
+vt 0.433484911919 0.420131027699 0.394647270441
+vt 0.504752993584 0.420128047466 0.394649058580
+vt 0.576020061970 0.420127213001 0.394649595022
+vt 0.00582895195112 0.374057829380 0.369725733995
+vt 0.0771106034517 0.374056398869 0.369727045298
+vt 0.148391142488 0.374052703381 0.369730412960
+vt 0.219669431448 0.374047458172 0.369735240936
+vt 0.290945082903 0.374041378498 0.369740843773
+vt 0.362217843533 0.374035298824 0.369746387005
+vt 0.433487892151 0.374030292034 0.369751006365
+vt 0.504756033421 0.374026954174 0.369753986597
+vt 0.576023101807 0.374025881290 0.369754880667
+vt 0.00582895195112 0.323164939880 0.348501473665
+vt 0.0771106034517 0.323163568974 0.348503381014
+vt 0.148391142488 0.323160052299 0.348508119583
+vt 0.219669431448 0.323154807091 0.348515093327
+vt 0.290945082903 0.323148787022 0.348523199558
+vt 0.362217843533 0.323142886162 0.348531246185
+vt 0.433487921953 0.323137879372 0.348537892103
+vt 0.504756033421 0.323134601116 0.348542213440
+vt 0.576023101807 0.323133587837 0.348543494940
+vt 0.00582895195112 0.267601013184 0.335717856884
+vt 0.0771106034517 0.267599821091 0.335720270872
+vt 0.148391142488 0.267596840858 0.335726529360
+vt 0.219669505954 0.267592489719 0.335735589266
+vt 0.290945082903 0.267587304115 0.335746139288
+vt 0.362217843533 0.267582297325 0.335756570101
+vt 0.433487921953 0.267578005791 0.335765242577
+vt 0.504756033421 0.267575323582 0.335770845413
+vt 0.576023101807 0.267574489117 0.335772573948
+vt 0.00582895195112 0.209566950798 0.334688484669
+vt 0.0771106034517 0.209566235542 0.334691405296
+vt 0.148391053081 0.209564208984 0.334698826075
+vt 0.219669431448 0.209561228752 0.334709703922
+vt 0.290945082903 0.209557950497 0.334722280502
+vt 0.362217843533 0.209554553032 0.334734767675
+vt 0.433487921953 0.209551870823 0.334745109081
+vt 0.504756033421 0.209550142288 0.334751844406
+vt 0.576023101807 0.209549605846 0.334753781557
+vt 0.00582895195112 0.151353776455 0.340644299984
+vt 0.0771106034517 0.151353538036 0.340647518635
+vt 0.148391142488 0.151352882385 0.340655714273
+vt 0.219669505954 0.151351869106 0.340667605400
+vt 0.290945082903 0.151350796223 0.340681493282
+vt 0.362217843533 0.151349723339 0.340695053339
+vt 0.433487892151 0.151348829269 0.340706378222
+vt 0.504756033421 0.151348233223 0.340713769197
+vt 0.576023101807 0.151348054409 0.340716004372
+vt 0.00582895195112 0.0930109024048 0.341600179672
+vt 0.0771106034517 0.0930112004280 0.341603428125
+vt 0.148391142488 0.0930119752884 0.341611534357
+vt 0.219669505954 0.0930130481720 0.341623395681
+vt 0.290945082903 0.0930142998695 0.341637283564
+vt 0.362217843533 0.0930155515671 0.341650873423
+vt 0.433487921953 0.0930166244507 0.341662198305
+vt 0.504756033421 0.0930172801018 0.341669529676
+vt 0.576023101807 0.0930174589157 0.341671824455
+vt 0.00582895195112 0.0378581881523 0.323051154613
+vt 0.0771106034517 0.0378589630127 0.323053985834
+vt 0.148391142488 0.0378610491753 0.323061376810
+vt 0.219669431448 0.0378640294075 0.323072046041
+vt 0.290945082903 0.0378675460815 0.323084384203
+vt 0.362217843533 0.0378709435463 0.323096603155
+vt 0.433488011360 0.0378737449646 0.323106735945
+vt 0.504756033421 0.0378755927086 0.323113381863
+vt 0.576023161411 0.0378761291504 0.323115319014
+vt 0.00582895195112 0.00624942779541 0.289594531059
+vt 0.0771106034517 0.00625044107437 0.289597004652
+vt 0.148391142488 0.00625330209732 0.289603412151
+vt 0.219669505954 0.00625747442245 0.289612799883
+vt 0.290945082903 0.00626224279404 0.289623558521
+vt 0.362217843533 0.00626701116562 0.289634257555
+vt 0.433488011360 0.00627094507217 0.289643168449
+vt 0.504756033421 0.00627344846725 0.289648920298
+vt 0.576023161411 0.00627422332764 0.289650768042
+vt 0.581808090210 0.996866106987 0.295587658882
+vt 0.581808090210 0.954363465309 0.295587629080
+vt 0.581808090210 0.911861419678 0.295587569475
+vt 0.581807971001 0.869360744953 0.295587480068
+vt 0.581807851791 0.826861679554 0.295587420464
+vt 0.581807851791 0.784364402294 0.295587331057
+vt 0.581807851791 0.741868615150 0.295587241650
+vt 0.581807851791 0.699374079704 0.295587211847
+vt 0.581807851791 0.656880140305 0.295587211847
+vt 0.525557756424 0.996866106987 0.308058202267
+vt 0.525557637215 0.954363405704 0.308058023453
+vt 0.525557279587 0.911861479282 0.308057606220
+vt 0.525556921959 0.869360685349 0.308057039976
+vt 0.525556325912 0.826861619949 0.308056324720
+vt 0.525555729866 0.784364223480 0.308055639267
+vt 0.525555372238 0.741868495941 0.308055073023
+vt 0.525555014610 0.699373841286 0.308054715395
+vt 0.525554895401 0.656879842281 0.308054596186
+vt 0.473296284676 0.996866106987 0.317884117365
+vt 0.473295927048 0.954363405704 0.317883878946
+vt 0.473295211792 0.911861419678 0.317883282900
+vt 0.473294019699 0.869360685349 0.317882418633
+vt 0.473292589188 0.826861619949 0.317881435156
+vt 0.473291277885 0.784364283085 0.317880481482
+vt 0.473290205002 0.741868495941 0.317879647017
+vt 0.473289489746 0.699373841286 0.317879110575
+vt 0.473289251328 0.656879842281 0.317878961563
+vt 0.423550724983 0.996866106987 0.322069466114
+vt 0.423550128937 0.954363405704 0.322069287300
+vt 0.423548698425 0.911861419678 0.322068899870
+vt 0.423546671867 0.869360685349 0.322068274021
+vt 0.423544287682 0.826861619949 0.322067588568
+vt 0.423541903496 0.784364283085 0.322066932917
+vt 0.423539996147 0.741868495941 0.322066366673
+vt 0.423538804054 0.699373841286 0.322066009045
+vt 0.423538446426 0.656879782677 0.322065889835
+vt 0.374823629856 0.996866106987 0.324172198772
+vt 0.374822914600 0.954363405704 0.324172258377
+vt 0.374820828438 0.911861479282 0.324172496796
+vt 0.374817907810 0.869360744953 0.324172824621
+vt 0.374814569950 0.826861619949 0.324173182249
+vt 0.374811172485 0.784364283085 0.324173569679
+vt 0.374808430672 0.741868495941 0.324173867702
+vt 0.374806642532 0.699373841286 0.324174076319
+vt 0.374806165695 0.656879782677 0.324174135923
+vt 0.326615214348 0.996866106987 0.329102188349
+vt 0.326614141464 0.954363405704 0.329102724791
+vt 0.326611697674 0.911861419678 0.329104036093
+vt 0.326608181000 0.869360744953 0.329105913639
+vt 0.326604127884 0.826861619949 0.329108089209
+vt 0.326600074768 0.784364223480 0.329110234976
+vt 0.326596796513 0.741868495941 0.329111993313
+vt 0.326594591141 0.699373841286 0.329113155603
+vt 0.326593935490 0.656879782677 0.329113483429
+vt 0.278899669647 0.996866166592 0.336456507444
+vt 0.278898596764 0.954363405704 0.336457610130
+vt 0.278896093369 0.911861419678 0.336460322142
+vt 0.278892397881 0.869360744953 0.336464256048
+vt 0.278887987137 0.826861619949 0.336468756199
+vt 0.278883695602 0.784364283085 0.336473196745
+vt 0.278880178928 0.741868495941 0.336476892233
+vt 0.278877913952 0.699373841286 0.336479246616
+vt 0.278877139091 0.656879782677 0.336480021477
+vt 0.231058657169 0.996866166592 0.343259334564
+vt 0.231057703495 0.954363465309 0.343261033297
+vt 0.231055259705 0.911861419678 0.343265295029
+vt 0.231051743031 0.869360744953 0.343271464109
+vt 0.231047689915 0.826861619949 0.343278616667
+vt 0.231043577194 0.784364223480 0.343285590410
+vt 0.231040358543 0.741868495941 0.343291461468
+vt 0.231038272381 0.699373841286 0.343295216560
+vt 0.231037616730 0.656879842281 0.343296319246
+vt 0.181793510914 0.996866166592 0.344054639339
+vt 0.181792736053 0.954363465309 0.344056934118
+vt 0.181790828705 0.911861479282 0.344062685966
+vt 0.181788027287 0.869360744953 0.344070881605
+vt 0.181784868240 0.826861619949 0.344080418348
+vt 0.181781589985 0.784364223480 0.344089835882
+vt 0.181778967381 0.741868495941 0.344097644091
+vt 0.181777358055 0.699373841286 0.344102680683
+vt 0.181776821613 0.656879842281 0.344104140997
+vt 0.130297482014 0.996866166592 0.327336490154
+vt 0.130297064781 0.954363465309 0.327339112759
+vt 0.130295932293 0.911861479282 0.327345669270
+vt 0.130294382572 0.869360804558 0.327355206013
+vt 0.130292534828 0.826861679554 0.327366232872
+vt 0.130290687084 0.784364283085 0.327377080917
+vt 0.130289137363 0.741868495941 0.327386111021
+vt 0.130288243294 0.699373841286 0.327391952276
+vt 0.130287945271 0.656879842281 0.327393651009
+vt 0.0758445858955 0.996866166592 0.300447374582
+vt 0.0758446455002 0.954363465309 0.300449967384
+vt 0.0758446455002 0.911861479282 0.300456613302
+vt 0.0758446455002 0.869360804558 0.300466269255
+vt 0.0758447051048 0.826861679554 0.300477385521
+vt 0.0758447051048 0.784364283085 0.300488322973
+vt 0.0758447647095 0.741868555546 0.300497442484
+vt 0.0758447647095 0.699373900890 0.300503283739
+vt 0.0758447647095 0.656879901886 0.300505012274
+vt 0.0220620632172 0.996866166592 0.326429128647
+vt 0.0220625400543 0.954363465309 0.326431721449
+vt 0.0220636129379 0.911861479282 0.326438337564
+vt 0.0220652818680 0.869360804558 0.326447814703
+vt 0.0220671892166 0.826861679554 0.326458752155
+vt 0.0220689773560 0.784364283085 0.326469540596
+vt 0.0220705270767 0.741868495941 0.326478451490
+vt 0.0220715403557 0.699373841286 0.326484322548
+vt 0.0220718383789 0.656879842281 0.326485991478
+vt 0.00492912530899 0.996866166592 0.380903303623
+vt 0.00492966175079 0.954363465309 0.380906045437
+vt 0.00493103265762 0.911861479282 0.380912810564
+vt 0.00493299961090 0.869360804558 0.380922764540
+vt 0.00493526458740 0.826861679554 0.380934238434
+vt 0.00493746995926 0.784364283085 0.380945473909
+vt 0.00493925809860 0.741868495941 0.380954861641
+vt 0.00494045019150 0.699373841286 0.380960881710
+vt 0.00494080781937 0.656879842281 0.380962640047
+vt 0.00582895195112 0.650636613369 0.611725687981
+vt 0.0771106034517 0.650636613369 0.611725628376
+vt 0.148390963674 0.650636613369 0.611725628376
+vt 0.219669073820 0.650636613369 0.611725568771
+vt 0.290944486856 0.650636613369 0.611725509167
+vt 0.362216979265 0.650636613369 0.611725449562
+vt 0.433486640453 0.650636613369 0.611725449562
+vt 0.504754304886 0.650636613369 0.611725389957
+vt 0.576021015644 0.650636613369 0.611725389957
+vt 0.00578810228035 0.625035464764 0.575665950775
+vt 0.0770697519183 0.625035464764 0.575665771961
+vt 0.148350208998 0.625035107136 0.575665354729
+vt 0.219628572464 0.625034391880 0.575664699078
+vt 0.290904164314 0.625033915043 0.575663983822
+vt 0.362176924944 0.625033318996 0.575663268566
+vt 0.433447003365 0.625032842159 0.575662612915
+vt 0.504715025425 0.625032603741 0.575662255287
+vt 0.575982093811 0.625032484531 0.575662136078
+vt 0.00574396364391 0.597104012966 0.542801201344
+vt 0.0770257040858 0.597103774548 0.542800903320
+vt 0.148306161165 0.597103059292 0.542800247669
+vt 0.219584524632 0.597101986408 0.542799293995
+vt 0.290860116482 0.597100675106 0.542798221111
+vt 0.362132877111 0.597099363804 0.542797088623
+vt 0.433402955532 0.597098410130 0.542796194553
+vt 0.504671037197 0.597097694874 0.542795598507
+vt 0.575938105583 0.597097575665 0.542795419693
+vt 0.00570363365114 0.567022025585 0.511686921120
+vt 0.0769853740931 0.567021548748 0.511686623096
+vt 0.148265808821 0.567020237446 0.511685967445
+vt 0.219544187188 0.567018568516 0.511685013771
+vt 0.290819883347 0.567016422749 0.511683881283
+vt 0.362092584372 0.567014515400 0.511682748795
+vt 0.433362662792 0.567012846470 0.511681795120
+vt 0.504630804062 0.567011654377 0.511681199074
+vt 0.575897872448 0.567011296749 0.511681020260
+vt 0.00569593161345 0.534782230854 0.480913400650
+vt 0.0769776701927 0.534781515598 0.480913221836
+vt 0.148258119822 0.534779846668 0.480912804604
+vt 0.219536483288 0.534777224064 0.480912178755
+vt 0.290812075138 0.534774363041 0.480911463499
+vt 0.362084805965 0.534771502018 0.480910748243
+vt 0.433354973793 0.534768998623 0.480910181999
+vt 0.504623055458 0.534767448902 0.480909824371
+vt 0.575890123844 0.534766972065 0.480909675360
+vt 0.00574465608224 0.499848902225 0.451278597116
+vt 0.0770263075829 0.499848067760 0.451278626919
+vt 0.148306861520 0.499845683575 0.451278746128
+vt 0.219585210085 0.499842226505 0.451278865337
+vt 0.290860801935 0.499838411808 0.451279044151
+vt 0.362133562565 0.499834597111 0.451279193163
+vt 0.433403670788 0.499831378460 0.451279342175
+vt 0.504671752453 0.499829351902 0.451279431581
+vt 0.575938880444 0.499828636646 0.451279461384
+vt 0.00580229563639 0.461873471737 0.422216087580
+vt 0.0770839527249 0.461872279644 0.422216445208
+vt 0.148364394903 0.461869418621 0.422217339277
+vt 0.219642847776 0.461865246296 0.422218650579
+vt 0.290918439627 0.461860358715 0.422220200300
+vt 0.362191200256 0.461855590343 0.422221720219
+vt 0.433461278677 0.461851537228 0.422222971916
+vt 0.504729390144 0.461849033833 0.422223746777
+vt 0.575996458530 0.461848318577 0.422224014997
+vt 0.00582592235878 0.420156538486 0.394632130861
+vt 0.0771075710654 0.420155227184 0.394632905722
+vt 0.148388028145 0.420151889324 0.394634902477
+vt 0.219666376710 0.420147001743 0.394637793303
+vt 0.290942072868 0.420141279697 0.394641190767
+vt 0.362214803696 0.420135796070 0.394644498825
+vt 0.433484911919 0.420131027699 0.394647270441
+vt 0.504752993584 0.420128047466 0.394649058580
+vt 0.576020061970 0.420127213001 0.394649595022
+vt 0.00582895195112 0.374057829380 0.369725733995
+vt 0.0771106034517 0.374056398869 0.369727045298
+vt 0.148391142488 0.374052703381 0.369730412960
+vt 0.219669431448 0.374047458172 0.369735240936
+vt 0.290945082903 0.374041378498 0.369740843773
+vt 0.362217843533 0.374035298824 0.369746387005
+vt 0.433487892151 0.374030292034 0.369751006365
+vt 0.504756033421 0.374026954174 0.369753986597
+vt 0.576023101807 0.374025881290 0.369754880667
+vt 0.00582895195112 0.323164939880 0.348501473665
+vt 0.0771106034517 0.323163568974 0.348503381014
+vt 0.148391142488 0.323160052299 0.348508119583
+vt 0.219669431448 0.323154807091 0.348515093327
+vt 0.290945082903 0.323148787022 0.348523199558
+vt 0.362217843533 0.323142886162 0.348531246185
+vt 0.433487921953 0.323137879372 0.348537892103
+vt 0.504756033421 0.323134601116 0.348542213440
+vt 0.576023101807 0.323133587837 0.348543494940
+vt 0.00582895195112 0.267601013184 0.335717856884
+vt 0.0771106034517 0.267599821091 0.335720270872
+vt 0.148391142488 0.267596840858 0.335726529360
+vt 0.219669505954 0.267592489719 0.335735589266
+vt 0.290945082903 0.267587304115 0.335746139288
+vt 0.362217843533 0.267582297325 0.335756570101
+vt 0.433487921953 0.267578005791 0.335765242577
+vt 0.504756033421 0.267575323582 0.335770845413
+vt 0.576023101807 0.267574489117 0.335772573948
+vt 0.00582895195112 0.209566950798 0.334688484669
+vt 0.0771106034517 0.209566235542 0.334691405296
+vt 0.148391053081 0.209564208984 0.334698826075
+vt 0.219669431448 0.209561228752 0.334709703922
+vt 0.290945082903 0.209557950497 0.334722280502
+vt 0.362217843533 0.209554553032 0.334734767675
+vt 0.433487921953 0.209551870823 0.334745109081
+vt 0.504756033421 0.209550142288 0.334751844406
+vt 0.576023101807 0.209549605846 0.334753781557
+vt 0.00582895195112 0.151353776455 0.340644299984
+vt 0.0771106034517 0.151353538036 0.340647518635
+vt 0.148391142488 0.151352882385 0.340655714273
+vt 0.219669505954 0.151351869106 0.340667605400
+vt 0.290945082903 0.151350796223 0.340681493282
+vt 0.362217843533 0.151349723339 0.340695053339
+vt 0.433487892151 0.151348829269 0.340706378222
+vt 0.504756033421 0.151348233223 0.340713769197
+vt 0.576023101807 0.151348054409 0.340716004372
+vt 0.00582895195112 0.0930109024048 0.341600179672
+vt 0.0771106034517 0.0930112004280 0.341603428125
+vt 0.148391142488 0.0930119752884 0.341611534357
+vt 0.219669505954 0.0930130481720 0.341623395681
+vt 0.290945082903 0.0930142998695 0.341637283564
+vt 0.362217843533 0.0930155515671 0.341650873423
+vt 0.433487921953 0.0930166244507 0.341662198305
+vt 0.504756033421 0.0930172801018 0.341669529676
+vt 0.576023101807 0.0930174589157 0.341671824455
+vt 0.00582895195112 0.0378581881523 0.323051154613
+vt 0.0771106034517 0.0378589630127 0.323053985834
+vt 0.148391142488 0.0378610491753 0.323061376810
+vt 0.219669431448 0.0378640294075 0.323072046041
+vt 0.290945082903 0.0378675460815 0.323084384203
+vt 0.362217843533 0.0378709435463 0.323096603155
+vt 0.433488011360 0.0378737449646 0.323106735945
+vt 0.504756033421 0.0378755927086 0.323113381863
+vt 0.576023161411 0.0378761291504 0.323115319014
+vt 0.00582895195112 0.00624942779541 0.289594531059
+vt 0.0771106034517 0.00625044107437 0.289597004652
+vt 0.148391142488 0.00625330209732 0.289603412151
+vt 0.219669505954 0.00625747442245 0.289612799883
+vt 0.290945082903 0.00626224279404 0.289623558521
+vt 0.362217843533 0.00626701116562 0.289634257555
+vt 0.433488011360 0.00627094507217 0.289643168449
+vt 0.504756033421 0.00627344846725 0.289648920298
+vt 0.576023161411 0.00627422332764 0.289650768042
+vt 0.581808090210 0.996866106987 0.295587658882
+vt 0.581808090210 0.954363465309 0.295587629080
+vt 0.581808090210 0.911861419678 0.295587569475
+vt 0.581807971001 0.869360744953 0.295587480068
+vt 0.581807851791 0.826861679554 0.295587420464
+vt 0.581807851791 0.784364402294 0.295587331057
+vt 0.581807851791 0.741868615150 0.295587241650
+vt 0.581807851791 0.699374079704 0.295587211847
+vt 0.581807851791 0.656880140305 0.295587211847
+vt 0.525557756424 0.996866106987 0.308058202267
+vt 0.525557637215 0.954363405704 0.308058023453
+vt 0.525557279587 0.911861479282 0.308057606220
+vt 0.525556921959 0.869360685349 0.308057039976
+vt 0.525556325912 0.826861619949 0.308056324720
+vt 0.525555729866 0.784364223480 0.308055639267
+vt 0.525555372238 0.741868495941 0.308055073023
+vt 0.525555014610 0.699373841286 0.308054715395
+vt 0.525554895401 0.656879842281 0.308054596186
+vt 0.473296284676 0.996866106987 0.317884117365
+vt 0.473295927048 0.954363405704 0.317883878946
+vt 0.473295211792 0.911861419678 0.317883282900
+vt 0.473294019699 0.869360685349 0.317882418633
+vt 0.473292589188 0.826861619949 0.317881435156
+vt 0.473291277885 0.784364283085 0.317880481482
+vt 0.473290205002 0.741868495941 0.317879647017
+vt 0.473289489746 0.699373841286 0.317879110575
+vt 0.473289251328 0.656879842281 0.317878961563
+vt 0.423550724983 0.996866106987 0.322069466114
+vt 0.423550128937 0.954363405704 0.322069287300
+vt 0.423548698425 0.911861419678 0.322068899870
+vt 0.423546671867 0.869360685349 0.322068274021
+vt 0.423544287682 0.826861619949 0.322067588568
+vt 0.423541903496 0.784364283085 0.322066932917
+vt 0.423539996147 0.741868495941 0.322066366673
+vt 0.423538804054 0.699373841286 0.322066009045
+vt 0.423538446426 0.656879782677 0.322065889835
+vt 0.374823629856 0.996866106987 0.324172198772
+vt 0.374822914600 0.954363405704 0.324172258377
+vt 0.374820828438 0.911861479282 0.324172496796
+vt 0.374817907810 0.869360744953 0.324172824621
+vt 0.374814569950 0.826861619949 0.324173182249
+vt 0.374811172485 0.784364283085 0.324173569679
+vt 0.374808430672 0.741868495941 0.324173867702
+vt 0.374806642532 0.699373841286 0.324174076319
+vt 0.374806165695 0.656879782677 0.324174135923
+vt 0.326615214348 0.996866106987 0.329102188349
+vt 0.326614141464 0.954363405704 0.329102724791
+vt 0.326611697674 0.911861419678 0.329104036093
+vt 0.326608181000 0.869360744953 0.329105913639
+vt 0.326604127884 0.826861619949 0.329108089209
+vt 0.326600074768 0.784364223480 0.329110234976
+vt 0.326596796513 0.741868495941 0.329111993313
+vt 0.326594591141 0.699373841286 0.329113155603
+vt 0.326593935490 0.656879782677 0.329113483429
+vt 0.278899669647 0.996866166592 0.336456507444
+vt 0.278898596764 0.954363405704 0.336457610130
+vt 0.278896093369 0.911861419678 0.336460322142
+vt 0.278892397881 0.869360744953 0.336464256048
+vt 0.278887987137 0.826861619949 0.336468756199
+vt 0.278883695602 0.784364283085 0.336473196745
+vt 0.278880178928 0.741868495941 0.336476892233
+vt 0.278877913952 0.699373841286 0.336479246616
+vt 0.278877139091 0.656879782677 0.336480021477
+vt 0.231058657169 0.996866166592 0.343259334564
+vt 0.231057703495 0.954363465309 0.343261033297
+vt 0.231055259705 0.911861419678 0.343265295029
+vt 0.231051743031 0.869360744953 0.343271464109
+vt 0.231047689915 0.826861619949 0.343278616667
+vt 0.231043577194 0.784364223480 0.343285590410
+vt 0.231040358543 0.741868495941 0.343291461468
+vt 0.231038272381 0.699373841286 0.343295216560
+vt 0.231037616730 0.656879842281 0.343296319246
+vt 0.181793510914 0.996866166592 0.344054639339
+vt 0.181792736053 0.954363465309 0.344056934118
+vt 0.181790828705 0.911861479282 0.344062685966
+vt 0.181788027287 0.869360744953 0.344070881605
+vt 0.181784868240 0.826861619949 0.344080418348
+vt 0.181781589985 0.784364223480 0.344089835882
+vt 0.181778967381 0.741868495941 0.344097644091
+vt 0.181777358055 0.699373841286 0.344102680683
+vt 0.181776821613 0.656879842281 0.344104140997
+vt 0.130297482014 0.996866166592 0.327336490154
+vt 0.130297064781 0.954363465309 0.327339112759
+vt 0.130295932293 0.911861479282 0.327345669270
+vt 0.130294382572 0.869360804558 0.327355206013
+vt 0.130292534828 0.826861679554 0.327366232872
+vt 0.130290687084 0.784364283085 0.327377080917
+vt 0.130289137363 0.741868495941 0.327386111021
+vt 0.130288243294 0.699373841286 0.327391952276
+vt 0.130287945271 0.656879842281 0.327393651009
+vt 0.0758445858955 0.996866166592 0.300447374582
+vt 0.0758446455002 0.954363465309 0.300449967384
+vt 0.0758446455002 0.911861479282 0.300456613302
+vt 0.0758446455002 0.869360804558 0.300466269255
+vt 0.0758447051048 0.826861679554 0.300477385521
+vt 0.0758447051048 0.784364283085 0.300488322973
+vt 0.0758447647095 0.741868555546 0.300497442484
+vt 0.0758447647095 0.699373900890 0.300503283739
+vt 0.0758447647095 0.656879901886 0.300505012274
+vt 0.0220620632172 0.996866166592 0.326429128647
+vt 0.0220625400543 0.954363465309 0.326431721449
+vt 0.0220636129379 0.911861479282 0.326438337564
+vt 0.0220652818680 0.869360804558 0.326447814703
+vt 0.0220671892166 0.826861679554 0.326458752155
+vt 0.0220689773560 0.784364283085 0.326469540596
+vt 0.0220705270767 0.741868495941 0.326478451490
+vt 0.0220715403557 0.699373841286 0.326484322548
+vt 0.0220718383789 0.656879842281 0.326485991478
+vt 0.00492912530899 0.996866166592 0.380903303623
+vt 0.00492966175079 0.954363465309 0.380906045437
+vt 0.00493103265762 0.911861479282 0.380912810564
+vt 0.00493299961090 0.869360804558 0.380922764540
+vt 0.00493526458740 0.826861679554 0.380934238434
+vt 0.00493746995926 0.784364283085 0.380945473909
+vt 0.00493925809860 0.741868495941 0.380954861641
+vt 0.00494045019150 0.699373841286 0.380960881710
+vt 0.00494080781937 0.656879842281 0.380962640047
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.961602449417 0.947106897831 0.606390535831
+vt 0.960933685303 0.902444243431 0.579910218716
+vt 0.960217714310 0.857138693333 0.562008500099
+vt 0.959469795227 0.811608433723 0.548397898674
+vt 0.958696842194 0.765982270241 0.537145972252
+vt 0.957904815674 0.720290958881 0.527834594250
+vt 0.957095861435 0.674561977386 0.519859433174
+vt 0.956272125244 0.628809273243 0.512861549854
+vt 0.955434799194 0.583040475845 0.506602704525
+vt 0.954585075378 0.537260890007 0.500909626484
+vt 0.953725337982 0.491470277309 0.495848357677
+vt 0.952861785889 0.445668160915 0.491541355848
+vt 0.951999902725 0.399855613708 0.488063991070
+vt 0.951145648956 0.354034334421 0.485473543406
+vt 0.950300455093 0.308207452297 0.483683645725
+vt 0.949467897415 0.262377202511 0.482616335154
+vt 0.948649883270 0.216545283794 0.482186049223
+vt 0.947846889496 0.170713126659 0.482343882322
+vt 0.947062492371 0.124881803989 0.483086526394
+vt 0.946300983429 0.0790526270866 0.484458267689
+vt 0.945565462112 0.0332268476486 0.486459165812
+vt 0.945353984833 0.0197514295578 0.487166404724
+vt 0.940112829208 0.947979748249 0.614888370037
+vt 0.940112829208 0.903316915035 0.588408052921
+vt 0.940112829208 0.858011245728 0.570505857468
+vt 0.940112829208 0.812480807304 0.556894719601
+vt 0.940112829208 0.766854465008 0.545642137527
+vt 0.940112829208 0.721163034439 0.536329746246
+vt 0.940112829208 0.675433874130 0.528353452682
+vt 0.940112829208 0.629680991173 0.521354198456
+vt 0.940112829208 0.583912134171 0.515093803406
+vt 0.940112829208 0.538132309914 0.509398877621
+vt 0.940112829208 0.492341518402 0.504335582256
+vt 0.940112829208 0.446539252996 0.500026345253
+vt 0.940112829208 0.400726556778 0.496546506882
+vt 0.940112829208 0.354905158281 0.493953406811
+vt 0.940112829208 0.309078097343 0.492160648108
+vt 0.940112829208 0.263247668743 0.491090267897
+vt 0.940112829208 0.217415571213 0.490656763315
+vt 0.940112829208 0.171583294868 0.490811228752
+vt 0.940112829208 0.125751852989 0.491550326347
+vt 0.940112829208 0.0799225568771 0.492918372154
+vt 0.940112829208 0.0340966582298 0.494915425777
+vt 0.940112829208 0.0206211209297 0.495621502399
+vt 0.918622732162 0.947106897831 0.606390535831
+vt 0.919291973114 0.902444243431 0.579910218716
+vt 0.920008182526 0.857138693333 0.562008500099
+vt 0.920755624771 0.811608433723 0.548397898674
+vt 0.921528577805 0.765982270241 0.537145972252
+vt 0.922320842743 0.720290958881 0.527834594250
+vt 0.923129796982 0.674561977386 0.519859433174
+vt 0.923953294754 0.628809273243 0.512861549854
+vt 0.924790859222 0.583040475845 0.506602704525
+vt 0.925640583038 0.537260890007 0.500909626484
+vt 0.926499843597 0.491470277309 0.495848357677
+vt 0.927363395691 0.445668160915 0.491541355848
+vt 0.928225278854 0.399855613708 0.488063991070
+vt 0.929080247879 0.354034334421 0.485473543406
+vt 0.929924726486 0.308207452297 0.483683645725
+vt 0.930757284164 0.262377202511 0.482616335154
+vt 0.931576013565 0.216545283794 0.482186049223
+vt 0.932378530502 0.170713126659 0.482343882322
+vt 0.933162927628 0.124881803989 0.483086526394
+vt 0.933924674988 0.0790526270866 0.484458267689
+vt 0.934660196304 0.0332268476486 0.486459165812
+vt 0.934871673584 0.0197514295578 0.487166404724
+vt 0.591539263725 0.00989326834679 0.00000000000
+vt 0.649340569973 0.00989326834679 0.00000000000
+vt 0.669571042061 0.00989326834679 0.00000000000
+vt 0.689801454544 0.00989326834679 0.00000000000
+vt 0.734597504139 0.00989326834679 0.00000000000
+vt 0.779393494129 0.00989326834679 0.00000000000
+vt 0.799623966217 0.00989326834679 0.00000000000
+vt 0.819854438305 0.00989326834679 0.00000000000
+vt 0.877655744553 0.00989326834679 0.00000000000
+vt 0.591539263725 0.0643495768309 0.00000000000
+vt 0.649340569973 0.0643495768309 0.00000000000
+vt 0.669571042061 0.0643495768309 0.00000000000
+vt 0.689801454544 0.0643495768309 0.00000000000
+vt 0.734597504139 0.0643495768309 0.00000000000
+vt 0.779393494129 0.0643495768309 0.00000000000
+vt 0.799623966217 0.0643495768309 0.00000000000
+vt 0.819854438305 0.0643495768309 0.00000000000
+vt 0.877655744553 0.0643495768309 0.00000000000
+vt 0.591539263725 0.100653767586 0.00000000000
+vt 0.649340569973 0.100653767586 0.00000000000
+vt 0.669571042061 0.100653767586 0.00000000000
+vt 0.689801454544 0.100653767586 0.00000000000
+vt 0.734597504139 0.100653767586 0.00000000000
+vt 0.779393494129 0.100653775036 0.00000000000
+vt 0.799623966217 0.100653767586 0.00000000000
+vt 0.819854438305 0.100653767586 0.00000000000
+vt 0.877655744553 0.100653767586 0.00000000000
+vt 0.591539263725 0.136957973242 0.00000000000
+vt 0.649340569973 0.136957973242 0.00000000000
+vt 0.669571042061 0.136957973242 0.00000000000
+vt 0.689801454544 0.136957973242 0.00000000000
+vt 0.734597504139 0.136957973242 0.00000000000
+vt 0.779393494129 0.136957988143 0.00000000000
+vt 0.799623966217 0.136957973242 0.00000000000
+vt 0.819854438305 0.136957973242 0.00000000000
+vt 0.877655744553 0.136957973242 0.00000000000
+vt 0.591539263725 0.173262178898 0.00000000000
+vt 0.649340569973 0.173262193799 0.00000000000
+vt 0.669571042061 0.173262178898 0.00000000000
+vt 0.689801454544 0.173262178898 0.00000000000
+vt 0.734597504139 0.173262178898 0.00000000000
+vt 0.779393494129 0.173262178898 0.00000000000
+vt 0.799623966217 0.173262178898 0.00000000000
+vt 0.819854438305 0.173262178898 0.00000000000
+vt 0.877655744553 0.173262178898 0.00000000000
+vt 0.591539263725 0.209566399455 0.00000000000
+vt 0.649340569973 0.209566414356 0.00000000000
+vt 0.669571042061 0.209566399455 0.00000000000
+vt 0.689801514149 0.209566399455 0.00000000000
+vt 0.734597504139 0.209566399455 0.00000000000
+vt 0.779393494129 0.209566399455 0.00000000000
+vt 0.799623966217 0.209566399455 0.00000000000
+vt 0.819854438305 0.209566399455 0.00000000000
+vt 0.877655744553 0.209566399455 0.00000000000
+vt 0.591539263725 0.245870605111 0.00000000000
+vt 0.649340569973 0.245870605111 0.00000000000
+vt 0.669571042061 0.245870605111 0.00000000000
+vt 0.689801454544 0.245870605111 0.00000000000
+vt 0.734597504139 0.245870605111 0.00000000000
+vt 0.779393494129 0.245870605111 0.00000000000
+vt 0.799623966217 0.245870605111 0.00000000000
+vt 0.819854438305 0.245870605111 0.00000000000
+vt 0.877655744553 0.245870605111 0.00000000000
+vt 0.591539263725 0.282174795866 0.00000000000
+vt 0.649340569973 0.282174795866 0.00000000000
+vt 0.669571042061 0.282174795866 0.00000000000
+vt 0.689801454544 0.282174795866 0.00000000000
+vt 0.734597504139 0.282174795866 0.00000000000
+vt 0.779393494129 0.282174795866 0.00000000000
+vt 0.799623966217 0.282174795866 0.00000000000
+vt 0.819854438305 0.282174795866 0.00000000000
+vt 0.877655744553 0.282174795866 0.00000000000
+vt 0.591539263725 0.318479031324 0.00000000000
+vt 0.649340569973 0.318479031324 0.00000000000
+vt 0.669571042061 0.318479001522 0.00000000000
+vt 0.689801454544 0.318479001522 0.00000000000
+vt 0.734597504139 0.318479001522 0.00000000000
+vt 0.779393494129 0.318479031324 0.00000000000
+vt 0.799623966217 0.318479031324 0.00000000000
+vt 0.819854438305 0.318479001522 0.00000000000
+vt 0.877655744553 0.318479031324 0.00000000000
+vt 0.591539263725 0.354783207178 0.00000000000
+vt 0.649340569973 0.354783236980 0.00000000000
+vt 0.669571042061 0.354783207178 0.00000000000
+vt 0.689801454544 0.354783207178 0.00000000000
+vt 0.734597504139 0.354783207178 0.00000000000
+vt 0.779393494129 0.354783236980 0.00000000000
+vt 0.799623966217 0.354783207178 0.00000000000
+vt 0.819854438305 0.354783207178 0.00000000000
+vt 0.877655744553 0.354783207178 0.00000000000
+vt 0.591539263725 0.391087472439 0.00000000000
+vt 0.649340569973 0.391087472439 0.00000000000
+vt 0.669571042061 0.391087472439 0.00000000000
+vt 0.689801454544 0.391087442636 0.00000000000
+vt 0.734597504139 0.391087442636 0.00000000000
+vt 0.779393494129 0.391087472439 0.00000000000
+vt 0.799623966217 0.391087472439 0.00000000000
+vt 0.819854438305 0.391087442636 0.00000000000
+vt 0.877655744553 0.391087472439 0.00000000000
+vt 0.591539263725 0.427391648293 0.00000000000
+vt 0.649340569973 0.427391678095 0.00000000000
+vt 0.669571042061 0.427391648293 0.00000000000
+vt 0.689801454544 0.427391648293 0.00000000000
+vt 0.734597504139 0.427391648293 0.00000000000
+vt 0.779393494129 0.427391678095 0.00000000000
+vt 0.799623966217 0.427391648293 0.00000000000
+vt 0.819854438305 0.427391648293 0.00000000000
+vt 0.877655744553 0.427391648293 0.00000000000
+vt 0.591539263725 0.463695883751 0.00000000000
+vt 0.649340569973 0.463695883751 0.00000000000
+vt 0.669571042061 0.463695883751 0.00000000000
+vt 0.689801454544 0.463695883751 0.00000000000
+vt 0.734597504139 0.463695883751 0.00000000000
+vt 0.779393494129 0.463695883751 0.00000000000
+vt 0.799623966217 0.463695883751 0.00000000000
+vt 0.819854438305 0.463695883751 0.00000000000
+vt 0.877655744553 0.463695883751 0.00000000000
+vt 0.591539263725 0.500000000000 0.00000000000
+vt 0.649340569973 0.500000000000 0.00000000000
+vt 0.669571042061 0.500000000000 0.00000000000
+vt 0.689801454544 0.500000000000 0.00000000000
+vt 0.734597504139 0.500000000000 0.00000000000
+vt 0.779393494129 0.500000000000 0.00000000000
+vt 0.799623966217 0.500000000000 0.00000000000
+vt 0.819854438305 0.500000000000 0.00000000000
+vt 0.877655744553 0.500000000000 0.00000000000
+vt 0.591539263725 0.536304354668 0.00000000000
+vt 0.649340569973 0.536304354668 0.00000000000
+vt 0.669571042061 0.536304354668 0.00000000000
+vt 0.689801454544 0.536304354668 0.00000000000
+vt 0.734597504139 0.536304354668 0.00000000000
+vt 0.779393494129 0.536304354668 0.00000000000
+vt 0.799623966217 0.536304354668 0.00000000000
+vt 0.819854438305 0.536304354668 0.00000000000
+vt 0.877655744553 0.536304354668 0.00000000000
+vt 0.591539263725 0.572608351707 0.00000000000
+vt 0.649340569973 0.572608351707 0.00000000000
+vt 0.669571042061 0.572608351707 0.00000000000
+vt 0.689801454544 0.572608351707 0.00000000000
+vt 0.734597504139 0.572608351707 0.00000000000
+vt 0.779393494129 0.572608351707 0.00000000000
+vt 0.799623966217 0.572608351707 0.00000000000
+vt 0.819854438305 0.572608351707 0.00000000000
+vt 0.877655744553 0.572608351707 0.00000000000
+vt 0.591539263725 0.608912587166 0.00000000000
+vt 0.649340569973 0.608912587166 0.00000000000
+vt 0.669571042061 0.608912587166 0.00000000000
+vt 0.689801454544 0.608912587166 0.00000000000
+vt 0.734597504139 0.608912587166 0.00000000000
+vt 0.779393494129 0.608912587166 0.00000000000
+vt 0.799623966217 0.608912587166 0.00000000000
+vt 0.819854438305 0.608912587166 0.00000000000
+vt 0.877655744553 0.608912587166 0.00000000000
+vt 0.591539263725 0.645216822624 0.00000000000
+vt 0.649340569973 0.645216822624 0.00000000000
+vt 0.669571042061 0.645216822624 0.00000000000
+vt 0.689801454544 0.645216822624 0.00000000000
+vt 0.734597504139 0.645216822624 0.00000000000
+vt 0.779393494129 0.645216822624 0.00000000000
+vt 0.799623966217 0.645216822624 0.00000000000
+vt 0.819854438305 0.645216822624 0.00000000000
+vt 0.877655744553 0.645216822624 0.00000000000
+vt 0.591539263725 0.681520938873 0.00000000000
+vt 0.649340569973 0.681520938873 0.00000000000
+vt 0.669571042061 0.681520938873 0.00000000000
+vt 0.689801454544 0.681520938873 0.00000000000
+vt 0.734597504139 0.681520938873 0.00000000000
+vt 0.779393494129 0.681520938873 0.00000000000
+vt 0.799623966217 0.681520938873 0.00000000000
+vt 0.819854438305 0.681520938873 0.00000000000
+vt 0.877655744553 0.681520938873 0.00000000000
+vt 0.591539263725 0.717825174332 0.00000000000
+vt 0.649340569973 0.717825174332 0.00000000000
+vt 0.669571042061 0.717825055122 0.00000000000
+vt 0.689801454544 0.717825174332 0.00000000000
+vt 0.734597504139 0.717825174332 0.00000000000
+vt 0.779393494129 0.717825174332 0.00000000000
+vt 0.799623966217 0.717825174332 0.00000000000
+vt 0.819854438305 0.717825174332 0.00000000000
+vt 0.877655744553 0.717825174332 0.00000000000
+vt 0.591539263725 0.754129290581 0.00000000000
+vt 0.649340569973 0.754129290581 0.00000000000
+vt 0.669571042061 0.754129290581 0.00000000000
+vt 0.689801454544 0.754129290581 0.00000000000
+vt 0.734597504139 0.754129290581 0.00000000000
+vt 0.779393494129 0.754129290581 0.00000000000
+vt 0.799623966217 0.754129290581 0.00000000000
+vt 0.819854438305 0.754129290581 0.00000000000
+vt 0.877655744553 0.754129290581 0.00000000000
+vt 0.591539263725 0.790433526039 0.00000000000
+vt 0.649340569973 0.790433526039 0.00000000000
+vt 0.669571042061 0.790433526039 0.00000000000
+vt 0.689801454544 0.790433526039 0.00000000000
+vt 0.734597504139 0.790433526039 0.00000000000
+vt 0.779393494129 0.790433526039 0.00000000000
+vt 0.799623966217 0.790433526039 0.00000000000
+vt 0.819854438305 0.790433406830 0.00000000000
+vt 0.877655744553 0.790433526039 0.00000000000
+vt 0.591539263725 0.826737642288 0.00000000000
+vt 0.649340569973 0.826737642288 0.00000000000
+vt 0.669571042061 0.826737642288 0.00000000000
+vt 0.689801454544 0.826737642288 0.00000000000
+vt 0.734597504139 0.826737642288 0.00000000000
+vt 0.779393494129 0.826737642288 0.00000000000
+vt 0.799623966217 0.826737642288 0.00000000000
+vt 0.819854438305 0.826737642288 0.00000000000
+vt 0.877655744553 0.826737642288 0.00000000000
+vt 0.591539263725 0.863041877747 0.00000000000
+vt 0.649340569973 0.863041877747 0.00000000000
+vt 0.669571042061 0.863041877747 0.00000000000
+vt 0.689801454544 0.863041877747 0.00000000000
+vt 0.734597504139 0.863041877747 0.00000000000
+vt 0.779393494129 0.863041877747 0.00000000000
+vt 0.799623966217 0.863041877747 0.00000000000
+vt 0.819854438305 0.863041758537 0.00000000000
+vt 0.877655744553 0.863041877747 0.00000000000
+vt 0.591539263725 0.899346113205 0.00000000000
+vt 0.649340569973 0.899346113205 0.00000000000
+vt 0.669571042061 0.899346113205 0.00000000000
+vt 0.689801454544 0.899346113205 0.00000000000
+vt 0.734597504139 0.899346113205 0.00000000000
+vt 0.779393494129 0.899346113205 0.00000000000
+vt 0.799623966217 0.899346113205 0.00000000000
+vt 0.819854438305 0.899345993996 0.00000000000
+vt 0.877655744553 0.899346113205 0.00000000000
+vt 0.591539263725 0.935650229454 0.00000000000
+vt 0.649340569973 0.935650229454 0.00000000000
+vt 0.669571042061 0.935650229454 0.00000000000
+vt 0.689801454544 0.935650229454 0.00000000000
+vt 0.734597504139 0.935650229454 0.00000000000
+vt 0.779393494129 0.935650229454 0.00000000000
+vt 0.799623966217 0.935650229454 0.00000000000
+vt 0.819854438305 0.935650229454 0.00000000000
+vt 0.877655744553 0.935650229454 0.00000000000
+vt 0.591539263725 0.990106463432 0.00000000000
+vt 0.649340569973 0.990106463432 0.00000000000
+vt 0.669571042061 0.990106463432 0.00000000000
+vt 0.689801454544 0.990106463432 0.00000000000
+vt 0.734597504139 0.990106463432 0.00000000000
+vt 0.779393494129 0.990106463432 0.00000000000
+vt 0.799623966217 0.990106463432 0.00000000000
+vt 0.819854438305 0.990106463432 0.00000000000
+vt 0.877655744553 0.990106463432 0.00000000000
+vt 0.591539263725 0.00989326834679 0.00000000000
+vt 0.649340569973 0.00989326834679 0.00000000000
+vt 0.669571042061 0.00989326834679 0.00000000000
+vt 0.689801454544 0.00989326834679 0.00000000000
+vt 0.734597504139 0.00989326834679 0.00000000000
+vt 0.779393494129 0.00989326834679 0.00000000000
+vt 0.799623966217 0.00989326834679 0.00000000000
+vt 0.819854438305 0.00989326834679 0.00000000000
+vt 0.877655744553 0.00989326834679 0.00000000000
+vt 0.591539263725 0.0643495768309 0.00000000000
+vt 0.649340569973 0.0643495768309 0.00000000000
+vt 0.669571042061 0.0643495768309 0.00000000000
+vt 0.689801454544 0.0643495768309 0.00000000000
+vt 0.734597504139 0.0643495768309 0.00000000000
+vt 0.779393494129 0.0643495768309 0.00000000000
+vt 0.799623966217 0.0643495768309 0.00000000000
+vt 0.819854438305 0.0643495768309 0.00000000000
+vt 0.877655744553 0.0643495768309 0.00000000000
+vt 0.591539263725 0.100653767586 0.00000000000
+vt 0.649340569973 0.100653767586 0.00000000000
+vt 0.669571042061 0.100653767586 0.00000000000
+vt 0.689801454544 0.100653767586 0.00000000000
+vt 0.734597504139 0.100653767586 0.00000000000
+vt 0.779393494129 0.100653775036 0.00000000000
+vt 0.799623966217 0.100653767586 0.00000000000
+vt 0.819854438305 0.100653767586 0.00000000000
+vt 0.877655744553 0.100653767586 0.00000000000
+vt 0.591539263725 0.136957973242 0.00000000000
+vt 0.649340569973 0.136957973242 0.00000000000
+vt 0.669571042061 0.136957973242 0.00000000000
+vt 0.689801454544 0.136957973242 0.00000000000
+vt 0.734597504139 0.136957973242 0.00000000000
+vt 0.779393494129 0.136957988143 0.00000000000
+vt 0.799623966217 0.136957973242 0.00000000000
+vt 0.819854438305 0.136957973242 0.00000000000
+vt 0.877655744553 0.136957973242 0.00000000000
+vt 0.591539263725 0.173262178898 0.00000000000
+vt 0.649340569973 0.173262193799 0.00000000000
+vt 0.669571042061 0.173262178898 0.00000000000
+vt 0.689801454544 0.173262178898 0.00000000000
+vt 0.734597504139 0.173262178898 0.00000000000
+vt 0.779393494129 0.173262178898 0.00000000000
+vt 0.799623966217 0.173262178898 0.00000000000
+vt 0.819854438305 0.173262178898 0.00000000000
+vt 0.877655744553 0.173262178898 0.00000000000
+vt 0.591539263725 0.209566399455 0.00000000000
+vt 0.649340569973 0.209566414356 0.00000000000
+vt 0.669571042061 0.209566399455 0.00000000000
+vt 0.689801514149 0.209566399455 0.00000000000
+vt 0.734597504139 0.209566399455 0.00000000000
+vt 0.779393494129 0.209566399455 0.00000000000
+vt 0.799623966217 0.209566399455 0.00000000000
+vt 0.819854438305 0.209566399455 0.00000000000
+vt 0.877655744553 0.209566399455 0.00000000000
+vt 0.591539263725 0.245870605111 0.00000000000
+vt 0.649340569973 0.245870605111 0.00000000000
+vt 0.669571042061 0.245870605111 0.00000000000
+vt 0.689801454544 0.245870605111 0.00000000000
+vt 0.734597504139 0.245870605111 0.00000000000
+vt 0.779393494129 0.245870605111 0.00000000000
+vt 0.799623966217 0.245870605111 0.00000000000
+vt 0.819854438305 0.245870605111 0.00000000000
+vt 0.877655744553 0.245870605111 0.00000000000
+vt 0.591539263725 0.282174795866 0.00000000000
+vt 0.649340569973 0.282174795866 0.00000000000
+vt 0.669571042061 0.282174795866 0.00000000000
+vt 0.689801454544 0.282174795866 0.00000000000
+vt 0.734597504139 0.282174795866 0.00000000000
+vt 0.779393494129 0.282174795866 0.00000000000
+vt 0.799623966217 0.282174795866 0.00000000000
+vt 0.819854438305 0.282174795866 0.00000000000
+vt 0.877655744553 0.282174795866 0.00000000000
+vt 0.591539263725 0.318479031324 0.00000000000
+vt 0.649340569973 0.318479031324 0.00000000000
+vt 0.669571042061 0.318479001522 0.00000000000
+vt 0.689801454544 0.318479001522 0.00000000000
+vt 0.734597504139 0.318479001522 0.00000000000
+vt 0.779393494129 0.318479031324 0.00000000000
+vt 0.799623966217 0.318479031324 0.00000000000
+vt 0.819854438305 0.318479001522 0.00000000000
+vt 0.877655744553 0.318479031324 0.00000000000
+vt 0.591539263725 0.354783207178 0.00000000000
+vt 0.649340569973 0.354783236980 0.00000000000
+vt 0.669571042061 0.354783207178 0.00000000000
+vt 0.689801454544 0.354783207178 0.00000000000
+vt 0.734597504139 0.354783207178 0.00000000000
+vt 0.779393494129 0.354783236980 0.00000000000
+vt 0.799623966217 0.354783207178 0.00000000000
+vt 0.819854438305 0.354783207178 0.00000000000
+vt 0.877655744553 0.354783207178 0.00000000000
+vt 0.591539263725 0.391087472439 0.00000000000
+vt 0.649340569973 0.391087472439 0.00000000000
+vt 0.669571042061 0.391087472439 0.00000000000
+vt 0.689801454544 0.391087442636 0.00000000000
+vt 0.734597504139 0.391087442636 0.00000000000
+vt 0.779393494129 0.391087472439 0.00000000000
+vt 0.799623966217 0.391087472439 0.00000000000
+vt 0.819854438305 0.391087442636 0.00000000000
+vt 0.877655744553 0.391087472439 0.00000000000
+vt 0.591539263725 0.427391648293 0.00000000000
+vt 0.649340569973 0.427391678095 0.00000000000
+vt 0.669571042061 0.427391648293 0.00000000000
+vt 0.689801454544 0.427391648293 0.00000000000
+vt 0.734597504139 0.427391648293 0.00000000000
+vt 0.779393494129 0.427391678095 0.00000000000
+vt 0.799623966217 0.427391648293 0.00000000000
+vt 0.819854438305 0.427391648293 0.00000000000
+vt 0.877655744553 0.427391648293 0.00000000000
+vt 0.591539263725 0.463695883751 0.00000000000
+vt 0.649340569973 0.463695883751 0.00000000000
+vt 0.669571042061 0.463695883751 0.00000000000
+vt 0.689801454544 0.463695883751 0.00000000000
+vt 0.734597504139 0.463695883751 0.00000000000
+vt 0.779393494129 0.463695883751 0.00000000000
+vt 0.799623966217 0.463695883751 0.00000000000
+vt 0.819854438305 0.463695883751 0.00000000000
+vt 0.877655744553 0.463695883751 0.00000000000
+vt 0.591539263725 0.500000000000 0.00000000000
+vt 0.649340569973 0.500000000000 0.00000000000
+vt 0.669571042061 0.500000000000 0.00000000000
+vt 0.689801454544 0.500000000000 0.00000000000
+vt 0.734597504139 0.500000000000 0.00000000000
+vt 0.779393494129 0.500000000000 0.00000000000
+vt 0.799623966217 0.500000000000 0.00000000000
+vt 0.819854438305 0.500000000000 0.00000000000
+vt 0.877655744553 0.500000000000 0.00000000000
+vt 0.591539263725 0.536304354668 0.00000000000
+vt 0.649340569973 0.536304354668 0.00000000000
+vt 0.669571042061 0.536304354668 0.00000000000
+vt 0.689801454544 0.536304354668 0.00000000000
+vt 0.734597504139 0.536304354668 0.00000000000
+vt 0.779393494129 0.536304354668 0.00000000000
+vt 0.799623966217 0.536304354668 0.00000000000
+vt 0.819854438305 0.536304354668 0.00000000000
+vt 0.877655744553 0.536304354668 0.00000000000
+vt 0.591539263725 0.572608351707 0.00000000000
+vt 0.649340569973 0.572608351707 0.00000000000
+vt 0.669571042061 0.572608351707 0.00000000000
+vt 0.689801454544 0.572608351707 0.00000000000
+vt 0.734597504139 0.572608351707 0.00000000000
+vt 0.779393494129 0.572608351707 0.00000000000
+vt 0.799623966217 0.572608351707 0.00000000000
+vt 0.819854438305 0.572608351707 0.00000000000
+vt 0.877655744553 0.572608351707 0.00000000000
+vt 0.591539263725 0.608912587166 0.00000000000
+vt 0.649340569973 0.608912587166 0.00000000000
+vt 0.669571042061 0.608912587166 0.00000000000
+vt 0.689801454544 0.608912587166 0.00000000000
+vt 0.734597504139 0.608912587166 0.00000000000
+vt 0.779393494129 0.608912587166 0.00000000000
+vt 0.799623966217 0.608912587166 0.00000000000
+vt 0.819854438305 0.608912587166 0.00000000000
+vt 0.877655744553 0.608912587166 0.00000000000
+vt 0.591539263725 0.645216822624 0.00000000000
+vt 0.649340569973 0.645216822624 0.00000000000
+vt 0.669571042061 0.645216822624 0.00000000000
+vt 0.689801454544 0.645216822624 0.00000000000
+vt 0.734597504139 0.645216822624 0.00000000000
+vt 0.779393494129 0.645216822624 0.00000000000
+vt 0.799623966217 0.645216822624 0.00000000000
+vt 0.819854438305 0.645216822624 0.00000000000
+vt 0.877655744553 0.645216822624 0.00000000000
+vt 0.591539263725 0.681520938873 0.00000000000
+vt 0.649340569973 0.681520938873 0.00000000000
+vt 0.669571042061 0.681520938873 0.00000000000
+vt 0.689801454544 0.681520938873 0.00000000000
+vt 0.734597504139 0.681520938873 0.00000000000
+vt 0.779393494129 0.681520938873 0.00000000000
+vt 0.799623966217 0.681520938873 0.00000000000
+vt 0.819854438305 0.681520938873 0.00000000000
+vt 0.877655744553 0.681520938873 0.00000000000
+vt 0.591539263725 0.717825174332 0.00000000000
+vt 0.649340569973 0.717825174332 0.00000000000
+vt 0.669571042061 0.717825055122 0.00000000000
+vt 0.689801454544 0.717825174332 0.00000000000
+vt 0.734597504139 0.717825174332 0.00000000000
+vt 0.779393494129 0.717825174332 0.00000000000
+vt 0.799623966217 0.717825174332 0.00000000000
+vt 0.819854438305 0.717825174332 0.00000000000
+vt 0.877655744553 0.717825174332 0.00000000000
+vt 0.591539263725 0.754129290581 0.00000000000
+vt 0.649340569973 0.754129290581 0.00000000000
+vt 0.669571042061 0.754129290581 0.00000000000
+vt 0.689801454544 0.754129290581 0.00000000000
+vt 0.734597504139 0.754129290581 0.00000000000
+vt 0.779393494129 0.754129290581 0.00000000000
+vt 0.799623966217 0.754129290581 0.00000000000
+vt 0.819854438305 0.754129290581 0.00000000000
+vt 0.877655744553 0.754129290581 0.00000000000
+vt 0.591539263725 0.790433526039 0.00000000000
+vt 0.649340569973 0.790433526039 0.00000000000
+vt 0.669571042061 0.790433526039 0.00000000000
+vt 0.689801454544 0.790433526039 0.00000000000
+vt 0.734597504139 0.790433526039 0.00000000000
+vt 0.779393494129 0.790433526039 0.00000000000
+vt 0.799623966217 0.790433526039 0.00000000000
+vt 0.819854438305 0.790433406830 0.00000000000
+vt 0.877655744553 0.790433526039 0.00000000000
+vt 0.591539263725 0.826737642288 0.00000000000
+vt 0.649340569973 0.826737642288 0.00000000000
+vt 0.669571042061 0.826737642288 0.00000000000
+vt 0.689801454544 0.826737642288 0.00000000000
+vt 0.734597504139 0.826737642288 0.00000000000
+vt 0.779393494129 0.826737642288 0.00000000000
+vt 0.799623966217 0.826737642288 0.00000000000
+vt 0.819854438305 0.826737642288 0.00000000000
+vt 0.877655744553 0.826737642288 0.00000000000
+vt 0.591539263725 0.863041877747 0.00000000000
+vt 0.649340569973 0.863041877747 0.00000000000
+vt 0.669571042061 0.863041877747 0.00000000000
+vt 0.689801454544 0.863041877747 0.00000000000
+vt 0.734597504139 0.863041877747 0.00000000000
+vt 0.779393494129 0.863041877747 0.00000000000
+vt 0.799623966217 0.863041877747 0.00000000000
+vt 0.819854438305 0.863041758537 0.00000000000
+vt 0.877655744553 0.863041877747 0.00000000000
+vt 0.591539263725 0.899346113205 0.00000000000
+vt 0.649340569973 0.899346113205 0.00000000000
+vt 0.669571042061 0.899346113205 0.00000000000
+vt 0.689801454544 0.899346113205 0.00000000000
+vt 0.734597504139 0.899346113205 0.00000000000
+vt 0.779393494129 0.899346113205 0.00000000000
+vt 0.799623966217 0.899346113205 0.00000000000
+vt 0.819854438305 0.899345993996 0.00000000000
+vt 0.877655744553 0.899346113205 0.00000000000
+vt 0.591539263725 0.935650229454 0.00000000000
+vt 0.649340569973 0.935650229454 0.00000000000
+vt 0.669571042061 0.935650229454 0.00000000000
+vt 0.689801454544 0.935650229454 0.00000000000
+vt 0.734597504139 0.935650229454 0.00000000000
+vt 0.779393494129 0.935650229454 0.00000000000
+vt 0.799623966217 0.935650229454 0.00000000000
+vt 0.819854438305 0.935650229454 0.00000000000
+vt 0.877655744553 0.935650229454 0.00000000000
+vt 0.591539263725 0.990106463432 0.00000000000
+vt 0.649340569973 0.990106463432 0.00000000000
+vt 0.669571042061 0.990106463432 0.00000000000
+vt 0.689801454544 0.990106463432 0.00000000000
+vt 0.734597504139 0.990106463432 0.00000000000
+vt 0.779393494129 0.990106463432 0.00000000000
+vt 0.799623966217 0.990106463432 0.00000000000
+vt 0.819854438305 0.990106463432 0.00000000000
+vt 0.877655744553 0.990106463432 0.00000000000
+vt 0.591539263725 0.00989326834679 0.00000000000
+vt 0.649340569973 0.00989326834679 0.00000000000
+vt 0.669571042061 0.00989326834679 0.00000000000
+vt 0.689801454544 0.00989326834679 0.00000000000
+vt 0.734597504139 0.00989326834679 0.00000000000
+vt 0.779393494129 0.00989326834679 0.00000000000
+vt 0.799623966217 0.00989326834679 0.00000000000
+vt 0.819854438305 0.00989326834679 0.00000000000
+vt 0.877655744553 0.00989326834679 0.00000000000
+vt 0.591539263725 0.0643495768309 0.00000000000
+vt 0.649340569973 0.0643495768309 0.00000000000
+vt 0.669571042061 0.0643495768309 0.00000000000
+vt 0.689801454544 0.0643495768309 0.00000000000
+vt 0.734597504139 0.0643495768309 0.00000000000
+vt 0.779393494129 0.0643495768309 0.00000000000
+vt 0.799623966217 0.0643495768309 0.00000000000
+vt 0.819854438305 0.0643495768309 0.00000000000
+vt 0.877655744553 0.0643495768309 0.00000000000
+vt 0.591539263725 0.100653767586 0.00000000000
+vt 0.649340569973 0.100653767586 0.00000000000
+vt 0.669571042061 0.100653767586 0.00000000000
+vt 0.689801454544 0.100653767586 0.00000000000
+vt 0.734597504139 0.100653767586 0.00000000000
+vt 0.779393494129 0.100653775036 0.00000000000
+vt 0.799623966217 0.100653767586 0.00000000000
+vt 0.819854438305 0.100653767586 0.00000000000
+vt 0.877655744553 0.100653767586 0.00000000000
+vt 0.591539263725 0.136957973242 0.00000000000
+vt 0.649340569973 0.136957973242 0.00000000000
+vt 0.669571042061 0.136957973242 0.00000000000
+vt 0.689801454544 0.136957973242 0.00000000000
+vt 0.734597504139 0.136957973242 0.00000000000
+vt 0.779393494129 0.136957988143 0.00000000000
+vt 0.799623966217 0.136957973242 0.00000000000
+vt 0.819854438305 0.136957973242 0.00000000000
+vt 0.877655744553 0.136957973242 0.00000000000
+vt 0.591539263725 0.173262178898 0.00000000000
+vt 0.649340569973 0.173262193799 0.00000000000
+vt 0.669571042061 0.173262178898 0.00000000000
+vt 0.689801454544 0.173262178898 0.00000000000
+vt 0.734597504139 0.173262178898 0.00000000000
+vt 0.779393494129 0.173262178898 0.00000000000
+vt 0.799623966217 0.173262178898 0.00000000000
+vt 0.819854438305 0.173262178898 0.00000000000
+vt 0.877655744553 0.173262178898 0.00000000000
+vt 0.591539263725 0.209566399455 0.00000000000
+vt 0.649340569973 0.209566414356 0.00000000000
+vt 0.669571042061 0.209566399455 0.00000000000
+vt 0.689801514149 0.209566399455 0.00000000000
+vt 0.734597504139 0.209566399455 0.00000000000
+vt 0.779393494129 0.209566399455 0.00000000000
+vt 0.799623966217 0.209566399455 0.00000000000
+vt 0.819854438305 0.209566399455 0.00000000000
+vt 0.877655744553 0.209566399455 0.00000000000
+vt 0.591539263725 0.245870605111 0.00000000000
+vt 0.649340569973 0.245870605111 0.00000000000
+vt 0.669571042061 0.245870605111 0.00000000000
+vt 0.689801454544 0.245870605111 0.00000000000
+vt 0.734597504139 0.245870605111 0.00000000000
+vt 0.779393494129 0.245870605111 0.00000000000
+vt 0.799623966217 0.245870605111 0.00000000000
+vt 0.819854438305 0.245870605111 0.00000000000
+vt 0.877655744553 0.245870605111 0.00000000000
+vt 0.591539263725 0.282174795866 0.00000000000
+vt 0.649340569973 0.282174795866 0.00000000000
+vt 0.669571042061 0.282174795866 0.00000000000
+vt 0.689801454544 0.282174795866 0.00000000000
+vt 0.734597504139 0.282174795866 0.00000000000
+vt 0.779393494129 0.282174795866 0.00000000000
+vt 0.799623966217 0.282174795866 0.00000000000
+vt 0.819854438305 0.282174795866 0.00000000000
+vt 0.877655744553 0.282174795866 0.00000000000
+vt 0.591539263725 0.318479031324 0.00000000000
+vt 0.649340569973 0.318479031324 0.00000000000
+vt 0.669571042061 0.318479001522 0.00000000000
+vt 0.689801454544 0.318479001522 0.00000000000
+vt 0.734597504139 0.318479001522 0.00000000000
+vt 0.779393494129 0.318479031324 0.00000000000
+vt 0.799623966217 0.318479031324 0.00000000000
+vt 0.819854438305 0.318479001522 0.00000000000
+vt 0.877655744553 0.318479031324 0.00000000000
+vt 0.591539263725 0.354783207178 0.00000000000
+vt 0.649340569973 0.354783236980 0.00000000000
+vt 0.669571042061 0.354783207178 0.00000000000
+vt 0.689801454544 0.354783207178 0.00000000000
+vt 0.734597504139 0.354783207178 0.00000000000
+vt 0.779393494129 0.354783236980 0.00000000000
+vt 0.799623966217 0.354783207178 0.00000000000
+vt 0.819854438305 0.354783207178 0.00000000000
+vt 0.877655744553 0.354783207178 0.00000000000
+vt 0.591539263725 0.391087472439 0.00000000000
+vt 0.649340569973 0.391087472439 0.00000000000
+vt 0.669571042061 0.391087472439 0.00000000000
+vt 0.689801454544 0.391087442636 0.00000000000
+vt 0.734597504139 0.391087442636 0.00000000000
+vt 0.779393494129 0.391087472439 0.00000000000
+vt 0.799623966217 0.391087472439 0.00000000000
+vt 0.819854438305 0.391087442636 0.00000000000
+vt 0.877655744553 0.391087472439 0.00000000000
+vt 0.591539263725 0.427391648293 0.00000000000
+vt 0.649340569973 0.427391678095 0.00000000000
+vt 0.669571042061 0.427391648293 0.00000000000
+vt 0.689801454544 0.427391648293 0.00000000000
+vt 0.734597504139 0.427391648293 0.00000000000
+vt 0.779393494129 0.427391678095 0.00000000000
+vt 0.799623966217 0.427391648293 0.00000000000
+vt 0.819854438305 0.427391648293 0.00000000000
+vt 0.877655744553 0.427391648293 0.00000000000
+vt 0.591539263725 0.463695883751 0.00000000000
+vt 0.649340569973 0.463695883751 0.00000000000
+vt 0.669571042061 0.463695883751 0.00000000000
+vt 0.689801454544 0.463695883751 0.00000000000
+vt 0.734597504139 0.463695883751 0.00000000000
+vt 0.779393494129 0.463695883751 0.00000000000
+vt 0.799623966217 0.463695883751 0.00000000000
+vt 0.819854438305 0.463695883751 0.00000000000
+vt 0.877655744553 0.463695883751 0.00000000000
+vt 0.591539263725 0.500000000000 0.00000000000
+vt 0.649340569973 0.500000000000 0.00000000000
+vt 0.669571042061 0.500000000000 0.00000000000
+vt 0.689801454544 0.500000000000 0.00000000000
+vt 0.734597504139 0.500000000000 0.00000000000
+vt 0.779393494129 0.500000000000 0.00000000000
+vt 0.799623966217 0.500000000000 0.00000000000
+vt 0.819854438305 0.500000000000 0.00000000000
+vt 0.877655744553 0.500000000000 0.00000000000
+vt 0.591539263725 0.536304354668 0.00000000000
+vt 0.649340569973 0.536304354668 0.00000000000
+vt 0.669571042061 0.536304354668 0.00000000000
+vt 0.689801454544 0.536304354668 0.00000000000
+vt 0.734597504139 0.536304354668 0.00000000000
+vt 0.779393494129 0.536304354668 0.00000000000
+vt 0.799623966217 0.536304354668 0.00000000000
+vt 0.819854438305 0.536304354668 0.00000000000
+vt 0.877655744553 0.536304354668 0.00000000000
+vt 0.591539263725 0.572608351707 0.00000000000
+vt 0.649340569973 0.572608351707 0.00000000000
+vt 0.669571042061 0.572608351707 0.00000000000
+vt 0.689801454544 0.572608351707 0.00000000000
+vt 0.734597504139 0.572608351707 0.00000000000
+vt 0.779393494129 0.572608351707 0.00000000000
+vt 0.799623966217 0.572608351707 0.00000000000
+vt 0.819854438305 0.572608351707 0.00000000000
+vt 0.877655744553 0.572608351707 0.00000000000
+vt 0.591539263725 0.608912587166 0.00000000000
+vt 0.649340569973 0.608912587166 0.00000000000
+vt 0.669571042061 0.608912587166 0.00000000000
+vt 0.689801454544 0.608912587166 0.00000000000
+vt 0.734597504139 0.608912587166 0.00000000000
+vt 0.779393494129 0.608912587166 0.00000000000
+vt 0.799623966217 0.608912587166 0.00000000000
+vt 0.819854438305 0.608912587166 0.00000000000
+vt 0.877655744553 0.608912587166 0.00000000000
+vt 0.591539263725 0.645216822624 0.00000000000
+vt 0.649340569973 0.645216822624 0.00000000000
+vt 0.669571042061 0.645216822624 0.00000000000
+vt 0.689801454544 0.645216822624 0.00000000000
+vt 0.734597504139 0.645216822624 0.00000000000
+vt 0.779393494129 0.645216822624 0.00000000000
+vt 0.799623966217 0.645216822624 0.00000000000
+vt 0.819854438305 0.645216822624 0.00000000000
+vt 0.877655744553 0.645216822624 0.00000000000
+vt 0.591539263725 0.681520938873 0.00000000000
+vt 0.649340569973 0.681520938873 0.00000000000
+vt 0.669571042061 0.681520938873 0.00000000000
+vt 0.689801454544 0.681520938873 0.00000000000
+vt 0.734597504139 0.681520938873 0.00000000000
+vt 0.779393494129 0.681520938873 0.00000000000
+vt 0.799623966217 0.681520938873 0.00000000000
+vt 0.819854438305 0.681520938873 0.00000000000
+vt 0.877655744553 0.681520938873 0.00000000000
+vt 0.591539263725 0.717825174332 0.00000000000
+vt 0.649340569973 0.717825174332 0.00000000000
+vt 0.669571042061 0.717825055122 0.00000000000
+vt 0.689801454544 0.717825174332 0.00000000000
+vt 0.734597504139 0.717825174332 0.00000000000
+vt 0.779393494129 0.717825174332 0.00000000000
+vt 0.799623966217 0.717825174332 0.00000000000
+vt 0.819854438305 0.717825174332 0.00000000000
+vt 0.877655744553 0.717825174332 0.00000000000
+vt 0.591539263725 0.754129290581 0.00000000000
+vt 0.649340569973 0.754129290581 0.00000000000
+vt 0.669571042061 0.754129290581 0.00000000000
+vt 0.689801454544 0.754129290581 0.00000000000
+vt 0.734597504139 0.754129290581 0.00000000000
+vt 0.779393494129 0.754129290581 0.00000000000
+vt 0.799623966217 0.754129290581 0.00000000000
+vt 0.819854438305 0.754129290581 0.00000000000
+vt 0.877655744553 0.754129290581 0.00000000000
+vt 0.591539263725 0.790433526039 0.00000000000
+vt 0.649340569973 0.790433526039 0.00000000000
+vt 0.669571042061 0.790433526039 0.00000000000
+vt 0.689801454544 0.790433526039 0.00000000000
+vt 0.734597504139 0.790433526039 0.00000000000
+vt 0.779393494129 0.790433526039 0.00000000000
+vt 0.799623966217 0.790433526039 0.00000000000
+vt 0.819854438305 0.790433406830 0.00000000000
+vt 0.877655744553 0.790433526039 0.00000000000
+vt 0.591539263725 0.826737642288 0.00000000000
+vt 0.649340569973 0.826737642288 0.00000000000
+vt 0.669571042061 0.826737642288 0.00000000000
+vt 0.689801454544 0.826737642288 0.00000000000
+vt 0.734597504139 0.826737642288 0.00000000000
+vt 0.779393494129 0.826737642288 0.00000000000
+vt 0.799623966217 0.826737642288 0.00000000000
+vt 0.819854438305 0.826737642288 0.00000000000
+vt 0.877655744553 0.826737642288 0.00000000000
+vt 0.591539263725 0.863041877747 0.00000000000
+vt 0.649340569973 0.863041877747 0.00000000000
+vt 0.669571042061 0.863041877747 0.00000000000
+vt 0.689801454544 0.863041877747 0.00000000000
+vt 0.734597504139 0.863041877747 0.00000000000
+vt 0.779393494129 0.863041877747 0.00000000000
+vt 0.799623966217 0.863041877747 0.00000000000
+vt 0.819854438305 0.863041758537 0.00000000000
+vt 0.877655744553 0.863041877747 0.00000000000
+vt 0.591539263725 0.899346113205 0.00000000000
+vt 0.649340569973 0.899346113205 0.00000000000
+vt 0.669571042061 0.899346113205 0.00000000000
+vt 0.689801454544 0.899346113205 0.00000000000
+vt 0.734597504139 0.899346113205 0.00000000000
+vt 0.779393494129 0.899346113205 0.00000000000
+vt 0.799623966217 0.899346113205 0.00000000000
+vt 0.819854438305 0.899345993996 0.00000000000
+vt 0.877655744553 0.899346113205 0.00000000000
+vt 0.591539263725 0.935650229454 0.00000000000
+vt 0.649340569973 0.935650229454 0.00000000000
+vt 0.669571042061 0.935650229454 0.00000000000
+vt 0.689801454544 0.935650229454 0.00000000000
+vt 0.734597504139 0.935650229454 0.00000000000
+vt 0.779393494129 0.935650229454 0.00000000000
+vt 0.799623966217 0.935650229454 0.00000000000
+vt 0.819854438305 0.935650229454 0.00000000000
+vt 0.877655744553 0.935650229454 0.00000000000
+vt 0.591539263725 0.990106463432 0.00000000000
+vt 0.649340569973 0.990106463432 0.00000000000
+vt 0.669571042061 0.990106463432 0.00000000000
+vt 0.689801454544 0.990106463432 0.00000000000
+vt 0.734597504139 0.990106463432 0.00000000000
+vt 0.779393494129 0.990106463432 0.00000000000
+vt 0.799623966217 0.990106463432 0.00000000000
+vt 0.819854438305 0.990106463432 0.00000000000
+vt 0.877655744553 0.990106463432 0.00000000000
+vt 0.591539263725 0.00989326834679 0.00000000000
+vt 0.649340569973 0.00989326834679 0.00000000000
+vt 0.669571042061 0.00989326834679 0.00000000000
+vt 0.689801454544 0.00989326834679 0.00000000000
+vt 0.734597504139 0.00989326834679 0.00000000000
+vt 0.779393494129 0.00989326834679 0.00000000000
+vt 0.799623966217 0.00989326834679 0.00000000000
+vt 0.819854438305 0.00989326834679 0.00000000000
+vt 0.877655744553 0.00989326834679 0.00000000000
+vt 0.591539263725 0.0643495768309 0.00000000000
+vt 0.649340569973 0.0643495768309 0.00000000000
+vt 0.669571042061 0.0643495768309 0.00000000000
+vt 0.689801454544 0.0643495768309 0.00000000000
+vt 0.734597504139 0.0643495768309 0.00000000000
+vt 0.779393494129 0.0643495768309 0.00000000000
+vt 0.799623966217 0.0643495768309 0.00000000000
+vt 0.819854438305 0.0643495768309 0.00000000000
+vt 0.877655744553 0.0643495768309 0.00000000000
+vt 0.591539263725 0.100653767586 0.00000000000
+vt 0.649340569973 0.100653767586 0.00000000000
+vt 0.669571042061 0.100653767586 0.00000000000
+vt 0.689801454544 0.100653767586 0.00000000000
+vt 0.734597504139 0.100653767586 0.00000000000
+vt 0.779393494129 0.100653775036 0.00000000000
+vt 0.799623966217 0.100653767586 0.00000000000
+vt 0.819854438305 0.100653767586 0.00000000000
+vt 0.877655744553 0.100653767586 0.00000000000
+vt 0.591539263725 0.136957973242 0.00000000000
+vt 0.649340569973 0.136957973242 0.00000000000
+vt 0.669571042061 0.136957973242 0.00000000000
+vt 0.689801454544 0.136957973242 0.00000000000
+vt 0.734597504139 0.136957973242 0.00000000000
+vt 0.779393494129 0.136957988143 0.00000000000
+vt 0.799623966217 0.136957973242 0.00000000000
+vt 0.819854438305 0.136957973242 0.00000000000
+vt 0.877655744553 0.136957973242 0.00000000000
+vt 0.591539263725 0.173262178898 0.00000000000
+vt 0.649340569973 0.173262193799 0.00000000000
+vt 0.669571042061 0.173262178898 0.00000000000
+vt 0.689801454544 0.173262178898 0.00000000000
+vt 0.734597504139 0.173262178898 0.00000000000
+vt 0.779393494129 0.173262178898 0.00000000000
+vt 0.799623966217 0.173262178898 0.00000000000
+vt 0.819854438305 0.173262178898 0.00000000000
+vt 0.877655744553 0.173262178898 0.00000000000
+vt 0.591539263725 0.209566399455 0.00000000000
+vt 0.649340569973 0.209566414356 0.00000000000
+vt 0.669571042061 0.209566399455 0.00000000000
+vt 0.689801514149 0.209566399455 0.00000000000
+vt 0.734597504139 0.209566399455 0.00000000000
+vt 0.779393494129 0.209566399455 0.00000000000
+vt 0.799623966217 0.209566399455 0.00000000000
+vt 0.819854438305 0.209566399455 0.00000000000
+vt 0.877655744553 0.209566399455 0.00000000000
+vt 0.591539263725 0.245870605111 0.00000000000
+vt 0.649340569973 0.245870605111 0.00000000000
+vt 0.669571042061 0.245870605111 0.00000000000
+vt 0.689801454544 0.245870605111 0.00000000000
+vt 0.734597504139 0.245870605111 0.00000000000
+vt 0.779393494129 0.245870605111 0.00000000000
+vt 0.799623966217 0.245870605111 0.00000000000
+vt 0.819854438305 0.245870605111 0.00000000000
+vt 0.877655744553 0.245870605111 0.00000000000
+vt 0.591539263725 0.282174795866 0.00000000000
+vt 0.649340569973 0.282174795866 0.00000000000
+vt 0.669571042061 0.282174795866 0.00000000000
+vt 0.689801454544 0.282174795866 0.00000000000
+vt 0.734597504139 0.282174795866 0.00000000000
+vt 0.779393494129 0.282174795866 0.00000000000
+vt 0.799623966217 0.282174795866 0.00000000000
+vt 0.819854438305 0.282174795866 0.00000000000
+vt 0.877655744553 0.282174795866 0.00000000000
+vt 0.591539263725 0.318479031324 0.00000000000
+vt 0.649340569973 0.318479031324 0.00000000000
+vt 0.669571042061 0.318479001522 0.00000000000
+vt 0.689801454544 0.318479001522 0.00000000000
+vt 0.734597504139 0.318479001522 0.00000000000
+vt 0.779393494129 0.318479031324 0.00000000000
+vt 0.799623966217 0.318479031324 0.00000000000
+vt 0.819854438305 0.318479001522 0.00000000000
+vt 0.877655744553 0.318479031324 0.00000000000
+vt 0.591539263725 0.354783207178 0.00000000000
+vt 0.649340569973 0.354783236980 0.00000000000
+vt 0.669571042061 0.354783207178 0.00000000000
+vt 0.689801454544 0.354783207178 0.00000000000
+vt 0.734597504139 0.354783207178 0.00000000000
+vt 0.779393494129 0.354783236980 0.00000000000
+vt 0.799623966217 0.354783207178 0.00000000000
+vt 0.819854438305 0.354783207178 0.00000000000
+vt 0.877655744553 0.354783207178 0.00000000000
+vt 0.591539263725 0.391087472439 0.00000000000
+vt 0.649340569973 0.391087472439 0.00000000000
+vt 0.669571042061 0.391087472439 0.00000000000
+vt 0.689801454544 0.391087442636 0.00000000000
+vt 0.734597504139 0.391087442636 0.00000000000
+vt 0.779393494129 0.391087472439 0.00000000000
+vt 0.799623966217 0.391087472439 0.00000000000
+vt 0.819854438305 0.391087442636 0.00000000000
+vt 0.877655744553 0.391087472439 0.00000000000
+vt 0.591539263725 0.427391648293 0.00000000000
+vt 0.649340569973 0.427391678095 0.00000000000
+vt 0.669571042061 0.427391648293 0.00000000000
+vt 0.689801454544 0.427391648293 0.00000000000
+vt 0.734597504139 0.427391648293 0.00000000000
+vt 0.779393494129 0.427391678095 0.00000000000
+vt 0.799623966217 0.427391648293 0.00000000000
+vt 0.819854438305 0.427391648293 0.00000000000
+vt 0.877655744553 0.427391648293 0.00000000000
+vt 0.591539263725 0.463695883751 0.00000000000
+vt 0.649340569973 0.463695883751 0.00000000000
+vt 0.669571042061 0.463695883751 0.00000000000
+vt 0.689801454544 0.463695883751 0.00000000000
+vt 0.734597504139 0.463695883751 0.00000000000
+vt 0.779393494129 0.463695883751 0.00000000000
+vt 0.799623966217 0.463695883751 0.00000000000
+vt 0.819854438305 0.463695883751 0.00000000000
+vt 0.877655744553 0.463695883751 0.00000000000
+vt 0.591539263725 0.500000000000 0.00000000000
+vt 0.649340569973 0.500000000000 0.00000000000
+vt 0.669571042061 0.500000000000 0.00000000000
+vt 0.689801454544 0.500000000000 0.00000000000
+vt 0.734597504139 0.500000000000 0.00000000000
+vt 0.779393494129 0.500000000000 0.00000000000
+vt 0.799623966217 0.500000000000 0.00000000000
+vt 0.819854438305 0.500000000000 0.00000000000
+vt 0.877655744553 0.500000000000 0.00000000000
+vt 0.591539263725 0.536304354668 0.00000000000
+vt 0.649340569973 0.536304354668 0.00000000000
+vt 0.669571042061 0.536304354668 0.00000000000
+vt 0.689801454544 0.536304354668 0.00000000000
+vt 0.734597504139 0.536304354668 0.00000000000
+vt 0.779393494129 0.536304354668 0.00000000000
+vt 0.799623966217 0.536304354668 0.00000000000
+vt 0.819854438305 0.536304354668 0.00000000000
+vt 0.877655744553 0.536304354668 0.00000000000
+vt 0.591539263725 0.572608351707 0.00000000000
+vt 0.649340569973 0.572608351707 0.00000000000
+vt 0.669571042061 0.572608351707 0.00000000000
+vt 0.689801454544 0.572608351707 0.00000000000
+vt 0.734597504139 0.572608351707 0.00000000000
+vt 0.779393494129 0.572608351707 0.00000000000
+vt 0.799623966217 0.572608351707 0.00000000000
+vt 0.819854438305 0.572608351707 0.00000000000
+vt 0.877655744553 0.572608351707 0.00000000000
+vt 0.591539263725 0.608912587166 0.00000000000
+vt 0.649340569973 0.608912587166 0.00000000000
+vt 0.669571042061 0.608912587166 0.00000000000
+vt 0.689801454544 0.608912587166 0.00000000000
+vt 0.734597504139 0.608912587166 0.00000000000
+vt 0.779393494129 0.608912587166 0.00000000000
+vt 0.799623966217 0.608912587166 0.00000000000
+vt 0.819854438305 0.608912587166 0.00000000000
+vt 0.877655744553 0.608912587166 0.00000000000
+vt 0.591539263725 0.645216822624 0.00000000000
+vt 0.649340569973 0.645216822624 0.00000000000
+vt 0.669571042061 0.645216822624 0.00000000000
+vt 0.689801454544 0.645216822624 0.00000000000
+vt 0.734597504139 0.645216822624 0.00000000000
+vt 0.779393494129 0.645216822624 0.00000000000
+vt 0.799623966217 0.645216822624 0.00000000000
+vt 0.819854438305 0.645216822624 0.00000000000
+vt 0.877655744553 0.645216822624 0.00000000000
+vt 0.591539263725 0.681520938873 0.00000000000
+vt 0.649340569973 0.681520938873 0.00000000000
+vt 0.669571042061 0.681520938873 0.00000000000
+vt 0.689801454544 0.681520938873 0.00000000000
+vt 0.734597504139 0.681520938873 0.00000000000
+vt 0.779393494129 0.681520938873 0.00000000000
+vt 0.799623966217 0.681520938873 0.00000000000
+vt 0.819854438305 0.681520938873 0.00000000000
+vt 0.877655744553 0.681520938873 0.00000000000
+vt 0.591539263725 0.717825174332 0.00000000000
+vt 0.649340569973 0.717825174332 0.00000000000
+vt 0.669571042061 0.717825055122 0.00000000000
+vt 0.689801454544 0.717825174332 0.00000000000
+vt 0.734597504139 0.717825174332 0.00000000000
+vt 0.779393494129 0.717825174332 0.00000000000
+vt 0.799623966217 0.717825174332 0.00000000000
+vt 0.819854438305 0.717825174332 0.00000000000
+vt 0.877655744553 0.717825174332 0.00000000000
+vt 0.591539263725 0.754129290581 0.00000000000
+vt 0.649340569973 0.754129290581 0.00000000000
+vt 0.669571042061 0.754129290581 0.00000000000
+vt 0.689801454544 0.754129290581 0.00000000000
+vt 0.734597504139 0.754129290581 0.00000000000
+vt 0.779393494129 0.754129290581 0.00000000000
+vt 0.799623966217 0.754129290581 0.00000000000
+vt 0.819854438305 0.754129290581 0.00000000000
+vt 0.877655744553 0.754129290581 0.00000000000
+vt 0.591539263725 0.790433526039 0.00000000000
+vt 0.649340569973 0.790433526039 0.00000000000
+vt 0.669571042061 0.790433526039 0.00000000000
+vt 0.689801454544 0.790433526039 0.00000000000
+vt 0.734597504139 0.790433526039 0.00000000000
+vt 0.779393494129 0.790433526039 0.00000000000
+vt 0.799623966217 0.790433526039 0.00000000000
+vt 0.819854438305 0.790433406830 0.00000000000
+vt 0.877655744553 0.790433526039 0.00000000000
+vt 0.591539263725 0.826737642288 0.00000000000
+vt 0.649340569973 0.826737642288 0.00000000000
+vt 0.669571042061 0.826737642288 0.00000000000
+vt 0.689801454544 0.826737642288 0.00000000000
+vt 0.734597504139 0.826737642288 0.00000000000
+vt 0.779393494129 0.826737642288 0.00000000000
+vt 0.799623966217 0.826737642288 0.00000000000
+vt 0.819854438305 0.826737642288 0.00000000000
+vt 0.877655744553 0.826737642288 0.00000000000
+vt 0.591539263725 0.863041877747 0.00000000000
+vt 0.649340569973 0.863041877747 0.00000000000
+vt 0.669571042061 0.863041877747 0.00000000000
+vt 0.689801454544 0.863041877747 0.00000000000
+vt 0.734597504139 0.863041877747 0.00000000000
+vt 0.779393494129 0.863041877747 0.00000000000
+vt 0.799623966217 0.863041877747 0.00000000000
+vt 0.819854438305 0.863041758537 0.00000000000
+vt 0.877655744553 0.863041877747 0.00000000000
+vt 0.591539263725 0.899346113205 0.00000000000
+vt 0.649340569973 0.899346113205 0.00000000000
+vt 0.669571042061 0.899346113205 0.00000000000
+vt 0.689801454544 0.899346113205 0.00000000000
+vt 0.734597504139 0.899346113205 0.00000000000
+vt 0.779393494129 0.899346113205 0.00000000000
+vt 0.799623966217 0.899346113205 0.00000000000
+vt 0.819854438305 0.899345993996 0.00000000000
+vt 0.877655744553 0.899346113205 0.00000000000
+vt 0.591539263725 0.935650229454 0.00000000000
+vt 0.649340569973 0.935650229454 0.00000000000
+vt 0.669571042061 0.935650229454 0.00000000000
+vt 0.689801454544 0.935650229454 0.00000000000
+vt 0.734597504139 0.935650229454 0.00000000000
+vt 0.779393494129 0.935650229454 0.00000000000
+vt 0.799623966217 0.935650229454 0.00000000000
+vt 0.819854438305 0.935650229454 0.00000000000
+vt 0.877655744553 0.935650229454 0.00000000000
+vt 0.591539263725 0.990106463432 0.00000000000
+vt 0.649340569973 0.990106463432 0.00000000000
+vt 0.669571042061 0.990106463432 0.00000000000
+vt 0.689801454544 0.990106463432 0.00000000000
+vt 0.734597504139 0.990106463432 0.00000000000
+vt 0.779393494129 0.990106463432 0.00000000000
+vt 0.799623966217 0.990106463432 0.00000000000
+vt 0.819854438305 0.990106463432 0.00000000000
+vt 0.877655744553 0.990106463432 0.00000000000
+i 116
+i 125
+i 124
+i 369
+i 379
+i 378
+i 115
+i 116
+i 124
+i 369
+i 370
+i 379
+i 124
+i 125
+i 134
+i 378
+i 379
+i 387
+i 106
+i 116
+i 115
+i 361
+i 370
+i 369
+i 106
+i 107
+i 116
+i 360
+i 361
+i 369
+i 114
+i 115
+i 124
+i 370
+i 371
+i 379
+i 124
+i 134
+i 133
+i 379
+i 388
+i 387
+i 106
+i 115
+i 114
+i 361
+i 371
+i 370
+i 114
+i 124
+i 123
+i 371
+i 380
+i 379
+i 98
+i 107
+i 106
+i 351
+i 361
+i 360
+i 124
+i 133
+i 132
+i 379
+i 389
+i 388
+i 123
+i 124
+i 132
+i 379
+i 380
+i 389
+i 105
+i 106
+i 114
+i 361
+i 362
+i 371
+i 97
+i 98
+i 106
+i 351
+i 352
+i 361
+i 133
+i 134
+i 142
+i 387
+i 388
+i 397
+i 134
+i 143
+i 142
+i 387
+i 397
+i 396
+i 96
+i 97
+i 106
+i 352
+i 353
+i 361
+i 96
+i 106
+i 105
+i 353
+i 362
+i 361
+i 114
+i 123
+i 122
+i 371
+i 381
+i 380
+i 132
+i 133
+i 142
+i 388
+i 389
+i 397
+i 88
+i 98
+i 97
+i 343
+i 352
+i 351
+i 122
+i 123
+i 132
+i 380
+i 381
+i 389
+i 1242
+i 1265
+i 1264
+i 1264
+i 1265
+i 1286
+i 104
+i 105
+i 114
+i 362
+i 363
+i 371
+i 88
+i 89
+i 98
+i 342
+i 343
+i 351
+i 113
+i 114
+i 122
+i 371
+i 372
+i 381
+i 1242
+i 1243
+i 1265
+i 1265
+i 1287
+i 1286
+i 88
+i 97
+i 96
+i 343
+i 353
+i 352
+i 104
+i 114
+i 113
+i 363
+i 372
+i 371
+i 132
+i 142
+i 141
+i 389
+i 398
+i 397
+i 250
+i 260
+i 259
+i 505
+i 514
+i 513
+i 96
+i 105
+i 104
+i 353
+i 363
+i 362
+i 1243
+i 1244
+i 1265
+i 1265
+i 1288
+i 1287
+i 250
+i 251
+i 260
+i 504
+i 505
+i 513
+i 1244
+i 1266
+i 1265
+i 1265
+i 1266
+i 1288
+i 122
+i 132
+i 131
+i 381
+i 390
+i 389
+i 250
+i 259
+i 258
+i 505
+i 515
+i 514
+i 80
+i 89
+i 88
+i 333
+i 343
+i 342
+i 87
+i 88
+i 96
+i 343
+i 344
+i 353
+i 1244
+i 1267
+i 1266
+i 1266
+i 1267
+i 1288
+i 232
+i 233
+i 242
+i 486
+i 487
+i 495
+i 242
+i 251
+i 250
+i 495
+i 505
+i 504
+i 224
+i 233
+i 232
+i 477
+i 487
+i 486
+i 1244
+i 1245
+i 1267
+i 1267
+i 1289
+i 1288
+i 132
+i 141
+i 140
+i 389
+i 399
+i 398
+i 95
+i 96
+i 104
+i 353
+i 354
+i 363
+i 131
+i 132
+i 140
+i 389
+i 390
+i 399
+i 79
+i 80
+i 88
+i 333
+i 334
+i 343
+i 232
+i 242
+i 241
+i 487
+i 496
+i 495
+i 241
+i 242
+i 250
+i 495
+i 496
+i 505
+i 1245
+i 1246
+i 1267
+i 1267
+i 1290
+i 1289
+i 1246
+i 1268
+i 1267
+i 1267
+i 1268
+i 1290
+i 223
+i 224
+i 232
+i 477
+i 478
+i 487
+i 249
+i 250
+i 258
+i 505
+i 506
+i 515
+i 112
+i 113
+i 122
+i 372
+i 373
+i 381
+i 1246
+i 1269
+i 1268
+i 1268
+i 1269
+i 1290
+i 78
+i 88
+i 87
+i 335
+i 344
+i 343
+i 86
+i 87
+i 96
+i 344
+i 345
+i 353
+i 104
+i 113
+i 112
+i 363
+i 373
+i 372
+i 78
+i 79
+i 88
+i 334
+i 335
+i 343
+i 232
+i 241
+i 240
+i 487
+i 497
+i 496
+i 240
+i 241
+i 250
+i 496
+i 497
+i 505
+i 1246
+i 1247
+i 1269
+i 1269
+i 1291
+i 1290
+i 222
+i 223
+i 232
+i 478
+i 479
+i 487
+i 86
+i 96
+i 95
+i 345
+i 354
+i 353
+i 231
+i 232
+i 240
+i 487
+i 488
+i 497
+i 1248
+i 1270
+i 1269
+i 1269
+i 1270
+i 1292
+i 1247
+i 1248
+i 1269
+i 1269
+i 1292
+i 1291
+i 240
+i 250
+i 249
+i 497
+i 506
+i 505
+i 222
+i 232
+i 231
+i 479
+i 488
+i 487
+i 122
+i 131
+i 130
+i 381
+i 391
+i 390
+i 1176
+i 1199
+i 1198
+i 1330
+i 1331
+i 1352
+i 1248
+i 1271
+i 1270
+i 1270
+i 1271
+i 1292
+i 214
+i 224
+i 223
+i 469
+i 478
+i 477
+i 1198
+i 1199
+i 1220
+i 1308
+i 1331
+i 1330
+i 1248
+i 1249
+i 1271
+i 1271
+i 1293
+i 1292
+i 248
+i 249
+i 258
+i 506
+i 507
+i 515
+i 1176
+i 1177
+i 1199
+i 1331
+i 1353
+i 1352
+i 112
+i 122
+i 121
+i 373
+i 382
+i 381
+i 325
+i 334
+i 333
+i 70
+i 80
+i 79
+i 1250
+i 1272
+i 1271
+i 1271
+i 1272
+i 1294
+i 1249
+i 1250
+i 1271
+i 1271
+i 1294
+i 1293
+i 248
+i 258
+i 257
+i 507
+i 516
+i 515
+i 1250
+i 1273
+i 1272
+i 1272
+i 1273
+i 1294
+i 78
+i 87
+i 86
+i 335
+i 345
+i 344
+i 214
+i 223
+i 222
+i 469
+i 479
+i 478
+i 1199
+i 1221
+i 1220
+i 1308
+i 1309
+i 1331
+i 214
+i 215
+i 224
+i 468
+i 469
+i 477
+i 121
+i 122
+i 130
+i 381
+i 382
+i 391
+i 94
+i 95
+i 104
+i 354
+i 355
+i 363
+i 1250
+i 1251
+i 1273
+i 1273
+i 1295
+i 1294
+i 1252
+i 1274
+i 1273
+i 1273
+i 1274
+i 1296
+i 103
+i 104
+i 112
+i 363
+i 364
+i 373
+i 130
+i 131
+i 140
+i 390
+i 391
+i 399
+i 1177
+i 1178
+i 1199
+i 1331
+i 1354
+i 1353
+i 1251
+i 1252
+i 1273
+i 1273
+i 1296
+i 1295
+i 325
+i 335
+i 334
+i 70
+i 79
+i 78
+i 324
+i 325
+i 333
+i 70
+i 71
+i 80
+i 230
+i 231
+i 240
+i 488
+i 489
+i 497
+i 1252
+i 1275
+i 1274
+i 1274
+i 1275
+i 1296
+i 240
+i 249
+i 248
+i 497
+i 507
+i 506
+i 222
+i 231
+i 230
+i 479
+i 489
+i 488
+i 1178
+i 1200
+i 1199
+i 1331
+i 1332
+i 1354
+i 1199
+i 1222
+i 1221
+i 1309
+i 1310
+i 1331
+i 1252
+i 1253
+i 1275
+i 1275
+i 1297
+i 1296
+i 1199
+i 1200
+i 1222
+i 1310
+i 1332
+i 1331
+i 1254
+i 1276
+i 1275
+i 1275
+i 1276
+i 1298
+i 1253
+i 1254
+i 1275
+i 1275
+i 1298
+i 1297
+i 1254
+i 1277
+i 1276
+i 1276
+i 1277
+i 1298
+i 1262
+i 1285
+i 1284
+i 1284
+i 1285
+i 1306
+i 1262
+i 1284
+i 1283
+i 1283
+i 1284
+i 1306
+i 1256
+i 1278
+i 1277
+i 1277
+i 1278
+i 1300
+i 1262
+i 1263
+i 1285
+i 1285
+i 1307
+i 1306
+i 1260
+i 1283
+i 1282
+i 1282
+i 1283
+i 1304
+i 1178
+i 1201
+i 1200
+i 1332
+i 1333
+i 1354
+i 1254
+i 1255
+i 1277
+i 1277
+i 1299
+i 1298
+i 1256
+i 1279
+i 1278
+i 1278
+i 1279
+i 1300
+i 94
+i 104
+i 103
+i 355
+i 364
+i 363
+i 1260
+i 1282
+i 1281
+i 1281
+i 1282
+i 1304
+i 1258
+i 1280
+i 1279
+i 1279
+i 1280
+i 1302
+i 1261
+i 1262
+i 1283
+i 1283
+i 1306
+i 1305
+i 1258
+i 1281
+i 1280
+i 1280
+i 1281
+i 1302
+i 1255
+i 1256
+i 1277
+i 1277
+i 1300
+i 1299
+i 1260
+i 1261
+i 1283
+i 1283
+i 1305
+i 1304
+i 1200
+i 1201
+i 1222
+i 1310
+i 1333
+i 1332
+i 1256
+i 1257
+i 1279
+i 1279
+i 1301
+i 1300
+i 1259
+i 1260
+i 1281
+i 1281
+i 1304
+i 1303
+i 1257
+i 1258
+i 1279
+i 1279
+i 1302
+i 1301
+i 86
+i 95
+i 94
+i 345
+i 355
+i 354
+i 1258
+i 1259
+i 1281
+i 1281
+i 1303
+i 1302
+i 1178
+i 1179
+i 1201
+i 1333
+i 1355
+i 1354
+i 213
+i 214
+i 222
+i 469
+i 470
+i 479
+i 77
+i 78
+i 86
+i 335
+i 336
+i 345
+i 230
+i 240
+i 239
+i 489
+i 498
+i 497
+i 239
+i 240
+i 248
+i 497
+i 498
+i 507
+i 1201
+i 1223
+i 1222
+i 1310
+i 1311
+i 1333
+i 1179
+i 1180
+i 1201
+i 1333
+i 1356
+i 1355
+i 221
+i 222
+i 230
+i 479
+i 480
+i 489
+i 1180
+i 1202
+i 1201
+i 1333
+i 1334
+i 1356
+i 325
+i 326
+i 335
+i 69
+i 70
+i 78
+i 1201
+i 1202
+i 1224
+i 1312
+i 1334
+i 1333
+i 1201
+i 1224
+i 1223
+i 1311
+i 1312
+i 1333
+i 1180
+i 1203
+i 1202
+i 1334
+i 1335
+i 1356
+i 206
+i 215
+i 214
+i 459
+i 469
+i 468
+i 248
+i 257
+i 256
+i 507
+i 517
+i 516
+i 1202
+i 1203
+i 1224
+i 1312
+i 1335
+i 1334
+i 1180
+i 1181
+i 1203
+i 1335
+i 1357
+i 1356
+i 130
+i 140
+i 139
+i 391
+i 400
+i 399
+i 315
+i 325
+i 324
+i 62
+i 71
+i 70
+i 1181
+i 1182
+i 1203
+i 1335
+i 1358
+i 1357
+i 1203
+i 1225
+i 1224
+i 1312
+i 1313
+i 1335
+i 1182
+i 1204
+i 1203
+i 1335
+i 1336
+i 1358
+i 212
+i 213
+i 222
+i 470
+i 471
+i 479
+i 212
+i 222
+i 221
+i 471
+i 480
+i 479
+i 1203
+i 1204
+i 1226
+i 1314
+i 1336
+i 1335
+i 1203
+i 1226
+i 1225
+i 1313
+i 1314
+i 1335
+i 1182
+i 1205
+i 1204
+i 1336
+i 1337
+i 1358
+i 112
+i 121
+i 120
+i 373
+i 383
+i 382
+i 1204
+i 1205
+i 1226
+i 1314
+i 1337
+i 1336
+i 1182
+i 1183
+i 1205
+i 1337
+i 1359
+i 1358
+i 327
+i 336
+i 335
+i 68
+i 78
+i 77
+i 326
+i 327
+i 335
+i 68
+i 69
+i 78
+i 85
+i 86
+i 94
+i 345
+i 346
+i 355
+i 1183
+i 1184
+i 1205
+i 1337
+i 1360
+i 1359
+i 1184
+i 1206
+i 1205
+i 1337
+i 1338
+i 1360
+i 1205
+i 1227
+i 1226
+i 1314
+i 1315
+i 1337
+i 204
+i 214
+i 213
+i 461
+i 470
+i 469
+i 1205
+i 1206
+i 1228
+i 1316
+i 1338
+i 1337
+i 120
+i 121
+i 130
+i 382
+i 383
+i 391
+i 205
+i 206
+i 214
+i 459
+i 460
+i 469
+i 1184
+i 1207
+i 1206
+i 1338
+i 1339
+i 1360
+i 1205
+i 1228
+i 1227
+i 1315
+i 1316
+i 1337
+i 102
+i 103
+i 112
+i 364
+i 365
+i 373
+i 1206
+i 1207
+i 1228
+i 1316
+i 1339
+i 1338
+i 1184
+i 1185
+i 1207
+i 1339
+i 1361
+i 1360
+i 76
+i 77
+i 86
+i 336
+i 337
+i 345
+i 315
+i 316
+i 325
+i 61
+i 62
+i 70
+i 230
+i 239
+i 238
+i 489
+i 499
+i 498
+i 317
+i 326
+i 325
+i 60
+i 70
+i 69
+i 238
+i 239
+i 248
+i 498
+i 499
+i 507
+i 220
+i 221
+i 230
+i 480
+i 481
+i 489
+i 1186
+i 1208
+i 1207
+i 1339
+i 1340
+i 1362
+i 1185
+i 1186
+i 1207
+i 1339
+i 1362
+i 1361
+i 1207
+i 1229
+i 1228
+i 1316
+i 1317
+i 1339
+i 1207
+i 1208
+i 1230
+i 1318
+i 1340
+i 1339
+i 1186
+i 1209
+i 1208
+i 1340
+i 1341
+i 1362
+i 1207
+i 1230
+i 1229
+i 1317
+i 1318
+i 1339
+i 204
+i 205
+i 214
+i 460
+i 461
+i 469
+i 1208
+i 1209
+i 1230
+i 1318
+i 1341
+i 1340
+i 247
+i 248
+i 256
+i 507
+i 508
+i 517
+i 1186
+i 1187
+i 1209
+i 1341
+i 1363
+i 1362
+i 1188
+i 1210
+i 1209
+i 1341
+i 1342
+i 1364
+i 1187
+i 1188
+i 1209
+i 1341
+i 1364
+i 1363
+i 76
+i 86
+i 85
+i 337
+i 346
+i 345
+i 316
+i 317
+i 325
+i 60
+i 61
+i 70
+i 1209
+i 1210
+i 1232
+i 1320
+i 1342
+i 1341
+i 94
+i 103
+i 102
+i 355
+i 365
+i 364
+i 1209
+i 1231
+i 1230
+i 1318
+i 1319
+i 1341
+i 1188
+i 1211
+i 1210
+i 1342
+i 1343
+i 1364
+i 1196
+i 1219
+i 1218
+i 1350
+i 1351
+i 1372
+i 1210
+i 1211
+i 1232
+i 1320
+i 1343
+i 1342
+i 1218
+i 1219
+i 1240
+i 1328
+i 1351
+i 1350
+i 1196
+i 1218
+i 1217
+i 1349
+i 1350
+i 1372
+i 1209
+i 1232
+i 1231
+i 1319
+i 1320
+i 1341
+i 1217
+i 1218
+i 1240
+i 1328
+i 1350
+i 1349
+i 1188
+i 1189
+i 1211
+i 1343
+i 1365
+i 1364
+i 1190
+i 1212
+i 1211
+i 1343
+i 1344
+i 1366
+i 1196
+i 1197
+i 1219
+i 1351
+i 1373
+i 1372
+i 1190
+i 1213
+i 1212
+i 1344
+i 1345
+i 1366
+i 1194
+i 1217
+i 1216
+i 1348
+i 1349
+i 1370
+i 1189
+i 1190
+i 1211
+i 1343
+i 1366
+i 1365
+i 1211
+i 1212
+i 1234
+i 1322
+i 1344
+i 1343
+i 1194
+i 1216
+i 1215
+i 1347
+i 1348
+i 1370
+i 1219
+i 1241
+i 1240
+i 1328
+i 1329
+i 1351
+i 1195
+i 1196
+i 1217
+i 1349
+i 1372
+i 1371
+i 1216
+i 1217
+i 1238
+i 1326
+i 1349
+i 1348
+i 1192
+i 1214
+i 1213
+i 1345
+i 1346
+i 1368
+i 1192
+i 1215
+i 1214
+i 1346
+i 1347
+i 1368
+i 1212
+i 1213
+i 1234
+i 1322
+i 1345
+i 1344
+i 1215
+i 1216
+i 1238
+i 1326
+i 1348
+i 1347
+i 1194
+i 1195
+i 1217
+i 1349
+i 1371
+i 1370
+i 1211
+i 1233
+i 1232
+i 1320
+i 1321
+i 1343
+i 1213
+i 1214
+i 1236
+i 1324
+i 1346
+i 1345
+i 1214
+i 1215
+i 1236
+i 1324
+i 1347
+i 1346
+i 1190
+i 1191
+i 1213
+i 1345
+i 1367
+i 1366
+i 1217
+i 1240
+i 1239
+i 1327
+i 1328
+i 1349
+i 1191
+i 1192
+i 1213
+i 1345
+i 1368
+i 1367
+i 1193
+i 1194
+i 1215
+i 1347
+i 1370
+i 1369
+i 1192
+i 1193
+i 1215
+i 1347
+i 1369
+i 1368
+i 1211
+i 1234
+i 1233
+i 1321
+i 1322
+i 1343
+i 1217
+i 1239
+i 1238
+i 1326
+i 1327
+i 1349
+i 204
+i 213
+i 212
+i 461
+i 471
+i 470
+i 229
+i 230
+i 238
+i 489
+i 490
+i 499
+i 1213
+i 1235
+i 1234
+i 1322
+i 1323
+i 1345
+i 1215
+i 1238
+i 1237
+i 1325
+i 1326
+i 1347
+i 1213
+i 1236
+i 1235
+i 1323
+i 1324
+i 1345
+i 1215
+i 1237
+i 1236
+i 1324
+i 1325
+i 1347
+i 238
+i 248
+i 247
+i 499
+i 508
+i 507
+i 220
+i 230
+i 229
+i 481
+i 490
+i 489
+i 212
+i 221
+i 220
+i 471
+i 481
+i 480
+i 111
+i 112
+i 120
+i 373
+i 374
+i 383
+i 317
+i 327
+i 326
+i 60
+i 69
+i 68
+i 102
+i 112
+i 111
+i 365
+i 374
+i 373
+i 327
+i 337
+i 336
+i 68
+i 77
+i 76
+i 130
+i 139
+i 138
+i 391
+i 401
+i 400
+i 120
+i 130
+i 129
+i 383
+i 392
+i 391
+i 307
+i 316
+i 315
+i 52
+i 62
+i 61
+i 196
+i 206
+i 205
+i 451
+i 460
+i 459
+i 84
+i 85
+i 94
+i 346
+i 347
+i 355
+i 93
+i 94
+i 102
+i 355
+i 356
+i 365
+i 307
+i 317
+i 316
+i 52
+i 61
+i 60
+i 129
+i 130
+i 138
+i 391
+i 392
+i 401
+i 203
+i 204
+i 212
+i 461
+i 462
+i 471
+i 196
+i 205
+i 204
+i 451
+i 461
+i 460
+i 317
+i 318
+i 327
+i 59
+i 60
+i 68
+i 211
+i 212
+i 220
+i 471
+i 472
+i 481
+i 246
+i 247
+i 256
+i 508
+i 509
+i 517
+i 306
+i 307
+i 315
+i 52
+i 53
+i 62
+i 327
+i 328
+i 337
+i 67
+i 68
+i 76
+i 76
+i 85
+i 84
+i 337
+i 347
+i 346
+i 196
+i 197
+i 206
+i 450
+i 451
+i 459
+i 84
+i 94
+i 93
+i 347
+i 356
+i 355
+i 228
+i 229
+i 238
+i 490
+i 491
+i 499
+i 238
+i 247
+i 246
+i 499
+i 509
+i 508
+i 220
+i 229
+i 228
+i 481
+i 491
+i 490
+i 246
+i 256
+i 255
+i 509
+i 518
+i 517
+i 307
+i 308
+i 317
+i 51
+i 52
+i 60
+i 202
+i 203
+i 212
+i 462
+i 463
+i 471
+i 202
+i 212
+i 211
+i 463
+i 472
+i 471
+i 195
+i 196
+i 204
+i 451
+i 452
+i 461
+i 318
+i 319
+i 327
+i 58
+i 59
+i 68
+i 319
+i 328
+i 327
+i 58
+i 68
+i 67
+i 309
+i 318
+i 317
+i 50
+i 60
+i 59
+i 194
+i 204
+i 203
+i 453
+i 462
+i 461
+i 110
+i 111
+i 120
+i 374
+i 375
+i 383
+i 308
+i 309
+i 317
+i 50
+i 51
+i 60
+i 102
+i 111
+i 110
+i 365
+i 375
+i 374
+i 210
+i 211
+i 220
+i 472
+i 473
+i 481
+i 194
+i 195
+i 204
+i 452
+i 453
+i 461
+i 228
+i 238
+i 237
+i 491
+i 500
+i 499
+i 75
+i 76
+i 84
+i 337
+i 338
+i 347
+i 237
+i 238
+i 246
+i 499
+i 500
+i 509
+i 2079
+i 2089
+i 2088
+i 2087
+i 2096
+i 2095
+i 219
+i 220
+i 228
+i 481
+i 482
+i 491
+i 297
+i 307
+i 306
+i 44
+i 53
+i 52
+i 120
+i 129
+i 128
+i 383
+i 393
+i 392
+i 328
+i 329
+i 337
+i 66
+i 67
+i 76
+i 2088
+i 2089
+i 2097
+i 2095
+i 2096
+i 2105
+i 188
+i 197
+i 196
+i 441
+i 451
+i 450
+i 210
+i 220
+i 219
+i 473
+i 482
+i 481
+i 92
+i 93
+i 102
+i 356
+i 357
+i 365
+i 299
+i 308
+i 307
+i 42
+i 52
+i 51
+i 309
+i 319
+i 318
+i 50
+i 59
+i 58
+i 329
+i 338
+i 337
+i 66
+i 76
+i 75
+i 128
+i 129
+i 138
+i 392
+i 393
+i 401
+i 194
+i 203
+i 202
+i 453
+i 463
+i 462
+i 2105
+i 2114
+i 2113
+i 2097
+i 2107
+i 2106
+i 297
+i 298
+i 307
+i 43
+i 44
+i 52
+i 202
+i 211
+i 210
+i 463
+i 473
+i 472
+i 186
+i 196
+i 195
+i 443
+i 452
+i 451
+i 84
+i 93
+i 92
+i 347
+i 357
+i 356
+i 1396
+i 1397
+i 1418
+i 1110
+i 1133
+i 1132
+i 319
+i 329
+i 328
+i 58
+i 67
+i 66
+i 2086
+i 2087
+i 2095
+i 2079
+i 2080
+i 2089
+i 110
+i 120
+i 119
+i 375
+i 384
+i 383
+i 298
+i 299
+i 307
+i 42
+i 43
+i 52
+i 1397
+i 1419
+i 1418
+i 1110
+i 1111
+i 1133
+i 299
+i 309
+i 308
+i 2113
+i 2114
+i 2123
+i 42
+i 51
+i 50
+i 119
+i 120
+i 128
+i 383
+i 384
+i 393
+i 1374
+i 1397
+i 1396
+i 1132
+i 1133
+i 1154
+i 2106
+i 2107
+i 2115
+i 101
+i 102
+i 110
+i 365
+i 366
+i 375
+i 187
+i 188
+i 196
+i 441
+i 442
+i 451
+i 246
+i 255
+i 254
+i 509
+i 519
+i 518
+i 1397
+i 1420
+i 1419
+i 1111
+i 1112
+i 1133
+i 2123
+i 2132
+i 2131
+i 1374
+i 1375
+i 1397
+i 1133
+i 1155
+i 1154
+i 1397
+i 1398
+i 1420
+i 1112
+i 1134
+i 1133
+i 186
+i 195
+i 194
+i 443
+i 453
+i 452
+i 2089
+i 2098
+i 2097
+i 2095
+i 2105
+i 2104
+i 92
+i 102
+i 101
+i 357
+i 366
+i 365
+i 186
+i 187
+i 196
+i 442
+i 443
+i 451
+i 2115
+i 2125
+i 2124
+i 309
+i 310
+i 319
+i 49
+i 50
+i 58
+i 1376
+i 1398
+i 1397
+i 1133
+i 1134
+i 1156
+i 1398
+i 1399
+i 1420
+i 1112
+i 1135
+i 1134
+i 1375
+i 1376
+i 1397
+i 1133
+i 1156
+i 1155
+i 1399
+i 1421
+i 1420
+i 1112
+i 1113
+i 1135
+i 2097
+i 2098
+i 2107
+i 2131
+i 2132
+i 2141
+i 2104
+i 2105
+i 2113
+i 193
+i 194
+i 202
+i 453
+i 454
+i 463
+i 1376
+i 1399
+i 1398
+i 1134
+i 1135
+i 1156
+i 1399
+i 1422
+i 1421
+i 1113
+i 1114
+i 1135
+i 74
+i 75
+i 84
+i 338
+i 339
+i 347
+i 2124
+i 2125
+i 2133
+i 228
+i 237
+i 236
+i 491
+i 501
+i 500
+i 236
+i 237
+i 246
+i 500
+i 501
+i 509
+i 218
+i 219
+i 228
+i 482
+i 483
+i 491
+i 1399
+i 1400
+i 1422
+i 1114
+i 1136
+i 1135
+i 128
+i 138
+i 137
+i 393
+i 402
+i 401
+i 1376
+i 1377
+i 1399
+i 1135
+i 1157
+i 1156
+i 1400
+i 1401
+i 1422
+i 1114
+i 1137
+i 1136
+i 1401
+i 1423
+i 1422
+i 1114
+i 1115
+i 1137
+i 201
+i 202
+i 210
+i 463
+i 464
+i 473
+i 1378
+i 1400
+i 1399
+i 1135
+i 1136
+i 1158
+i 299
+i 300
+i 309
+i 41
+i 42
+i 50
+i 1377
+i 1378
+i 1399
+i 1135
+i 1158
+i 1157
+i 319
+i 320
+i 329
+i 57
+i 58
+i 66
+i 1401
+i 1424
+i 1423
+i 1115
+i 1116
+i 1137
+i 2141
+i 2150
+i 2149
+i 1378
+i 1401
+i 1400
+i 1136
+i 1137
+i 1158
+i 1401
+i 1402
+i 1424
+i 1116
+i 1138
+i 1137
+i 2133
+i 2143
+i 2142
+i 2113
+i 2123
+i 2122
+i 289
+i 298
+i 297
+i 34
+i 44
+i 43
+i 83
+i 84
+i 92
+i 347
+i 348
+i 357
+i 2107
+i 2116
+i 2115
+i 1402
+i 1403
+i 1424
+i 1116
+i 1139
+i 1138
+i 1403
+i 1425
+i 1424
+i 1116
+i 1117
+i 1139
+i 210
+i 219
+i 218
+i 473
+i 483
+i 482
+i 1378
+i 1379
+i 1401
+i 1137
+i 1159
+i 1158
+i 1380
+i 1402
+i 1401
+i 1137
+i 1138
+i 1160
+i 2149
+i 2150
+i 2159
+i 1403
+i 1426
+i 1425
+i 1117
+i 1118
+i 1139
+i 2122
+i 2123
+i 2131
+i 1379
+i 1380
+i 1401
+i 1137
+i 1160
+i 1159
+i 1380
+i 1403
+i 1402
+i 1138
+i 1139
+i 1160
+i 1403
+i 1404
+i 1426
+i 1118
+i 1140
+i 1139
+i 2115
+i 2116
+i 2125
+i 329
+i 339
+i 338
+i 66
+i 75
+i 74
+i 2142
+i 2143
+i 2151
+i 289
+i 299
+i 298
+i 34
+i 43
+i 42
+i 1404
+i 1405
+i 1426
+i 1118
+i 1141
+i 1140
+i 185
+i 186
+i 194
+i 443
+i 444
+i 453
+i 1405
+i 1427
+i 1426
+i 1118
+i 1119
+i 1141
+i 1382
+i 1404
+i 1403
+i 1139
+i 1140
+i 1162
+i 1380
+i 1381
+i 1403
+i 1139
+i 1161
+i 1160
+i 1405
+i 1428
+i 1427
+i 1119
+i 1120
+i 1141
+i 245
+i 246
+i 254
+i 509
+i 510
+i 519
+i 1382
+i 1405
+i 1404
+i 1140
+i 1141
+i 1162
+i 301
+i 310
+i 309
+i 1405
+i 1406
+i 1428
+i 1120
+i 1142
+i 1141
+i 40
+i 50
+i 49
+i 1381
+i 1382
+i 1403
+i 1139
+i 1162
+i 1161
+i 74
+i 84
+i 83
+i 339
+i 348
+i 347
+i 310
+i 311
+i 319
+i 1406
+i 1407
+i 1428
+i 1120
+i 1143
+i 1142
+i 48
+i 49
+i 58
+i 1407
+i 1429
+i 1428
+i 1120
+i 1121
+i 1143
+i 2159
+i 2168
+i 2167
+i 1384
+i 1406
+i 1405
+i 1141
+i 1142
+i 1164
+i 1407
+i 1430
+i 1429
+i 1121
+i 1122
+i 1143
+i 1382
+i 1383
+i 1405
+i 1141
+i 1163
+i 1162
+i 300
+i 301
+i 309
+i 40
+i 41
+i 50
+i 1407
+i 1408
+i 1430
+i 1122
+i 1144
+i 1143
+i 1384
+i 1407
+i 1406
+i 1142
+i 1143
+i 1164
+i 192
+i 193
+i 202
+i 454
+i 455
+i 463
+i 1383
+i 1384
+i 1405
+i 1141
+i 1164
+i 1163
+i 1408
+i 1409
+i 1430
+i 1122
+i 1145
+i 1144
+i 1409
+i 1431
+i 1430
+i 1122
+i 1123
+i 1145
+i 227
+i 228
+i 236
+i 491
+i 492
+i 501
+i 1416
+i 1417
+i 1438
+i 1130
+i 1153
+i 1152
+i 218
+i 228
+i 227
+i 483
+i 492
+i 491
+i 236
+i 246
+i 245
+i 501
+i 510
+i 509
+i 2167
+i 2168
+i 2177
+i 2151
+i 2161
+i 2160
+i 1415
+i 1416
+i 1438
+i 1130
+i 1152
+i 1151
+i 1409
+i 1432
+i 1431
+i 1123
+i 1124
+i 1145
+i 1409
+i 1410
+i 1432
+i 1124
+i 1146
+i 1145
+i 1386
+i 1408
+i 1407
+i 1143
+i 1144
+i 1166
+i 1417
+i 1439
+i 1438
+i 1130
+i 1131
+i 1153
+i 2125
+i 2134
+i 2133
+i 1410
+i 1411
+i 1432
+i 1124
+i 1147
+i 1146
+i 1394
+i 1417
+i 1416
+i 1152
+i 1153
+i 1174
+i 2131
+i 2141
+i 2140
+i 311
+i 320
+i 319
+i 48
+i 58
+i 57
+i 1414
+i 1415
+i 1436
+i 1128
+i 1151
+i 1150
+i 1415
+i 1438
+i 1437
+i 1129
+i 1130
+i 1151
+i 1394
+i 1416
+i 1415
+i 1151
+i 1152
+i 1174
+i 1386
+i 1409
+i 1408
+i 1144
+i 1145
+i 1166
+i 1411
+i 1433
+i 1432
+i 1124
+i 1125
+i 1147
+i 1413
+i 1414
+i 1436
+i 1128
+i 1150
+i 1149
+i 1411
+i 1412
+i 1434
+i 1126
+i 1148
+i 1147
+i 1412
+i 1413
+i 1434
+i 1126
+i 1149
+i 1148
+i 1384
+i 1385
+i 1407
+i 1143
+i 1165
+i 1164
+i 1415
+i 1437
+i 1436
+i 1128
+i 1129
+i 1151
+i 1411
+i 1434
+i 1433
+i 1125
+i 1126
+i 1147
+i 192
+i 202
+i 201
+i 455
+i 464
+i 463
+i 1413
+i 1435
+i 1434
+i 1126
+i 1127
+i 1149
+i 1413
+i 1436
+i 1435
+i 1127
+i 1128
+i 1149
+i 184
+i 194
+i 193
+i 445
+i 454
+i 453
+i 1388
+i 1410
+i 1409
+i 1145
+i 1146
+i 1168
+i 1392
+i 1415
+i 1414
+i 1150
+i 1151
+i 1172
+i 1385
+i 1386
+i 1407
+i 1143
+i 1166
+i 1165
+i 1394
+i 1395
+i 1417
+i 1153
+i 1175
+i 1174
+i 1392
+i 1414
+i 1413
+i 1149
+i 1150
+i 1172
+i 1388
+i 1411
+i 1410
+i 1146
+i 1147
+i 1168
+i 1390
+i 1412
+i 1411
+i 1147
+i 1148
+i 1170
+i 1390
+i 1413
+i 1412
+i 1148
+i 1149
+i 1170
+i 288
+i 289
+i 297
+i 34
+i 35
+i 44
+i 178
+i 188
+i 187
+i 433
+i 442
+i 441
+i 1393
+i 1394
+i 1415
+i 1151
+i 1174
+i 1173
+i 1386
+i 1387
+i 1409
+i 1145
+i 1167
+i 1166
+i 1392
+i 1393
+i 1415
+i 1151
+i 1173
+i 1172
+i 2160
+i 2161
+i 2169
+i 1387
+i 1388
+i 1409
+i 1145
+i 1168
+i 1167
+i 1391
+i 1392
+i 1413
+i 1149
+i 1172
+i 1171
+i 1390
+i 1391
+i 1413
+i 1149
+i 1171
+i 1170
+i 1388
+i 1389
+i 1411
+i 1147
+i 1169
+i 1168
+i 1389
+i 1390
+i 1411
+i 1147
+i 1170
+i 1169
+i 2133
+i 2134
+i 2143
+i 2140
+i 2141
+i 2149
+i 2085
+i 2086
+i 2095
+i 2177
+i 2186
+i 2185
+i 184
+i 185
+i 194
+i 444
+i 445
+i 453
+i 2080
+i 2081
+i 2089
+i 178
+i 187
+i 186
+i 433
+i 443
+i 442
+i 2185
+i 2186
+i 2195
+i 2149
+i 2159
+i 2158
+i 291
+i 300
+i 299
+i 2095
+i 2104
+i 2103
+i 32
+i 42
+i 41
+i 2169
+i 2179
+i 2178
+i 289
+i 290
+i 299
+i 33
+i 34
+i 42
+i 2089
+i 2099
+i 2098
+i 2178
+i 2179
+i 2187
+i 2195
+i 2204
+i 2203
+i 2143
+i 2152
+i 2151
+i 2158
+i 2159
+i 2167
+i 2203
+i 2204
+i 2213
+i 200
+i 201
+i 210
+i 464
+i 465
+i 473
+i 209
+i 210
+i 218
+i 473
+i 474
+i 483
+i 2187
+i 2197
+i 2196
+i 2103
+i 2104
+i 2113
+i 2151
+i 2152
+i 2161
+i 2213
+i 2222
+i 2221
+i 320
+i 321
+i 329
+i 2098
+i 2099
+i 2107
+i 56
+i 57
+i 66
+i 2167
+i 2177
+i 2176
+i 329
+i 330
+i 339
+i 65
+i 66
+i 74
+i 110
+i 119
+i 118
+i 375
+i 385
+i 384
+i 301
+i 311
+i 310
+i 40
+i 49
+i 48
+i 2113
+i 2122
+i 2121
+i 2176
+i 2177
+i 2185
+i 2107
+i 2117
+i 2116
+i 290
+i 291
+i 299
+i 32
+i 33
+i 42
+i 2221
+i 2222
+i 2231
+i 178
+i 179
+i 188
+i 432
+i 433
+i 441
+i 2196
+i 2197
+i 2205
+i 1844
+i 1853
+i 1852
+i 2161
+i 2170
+i 2169
+i 2231
+i 2240
+i 2239
+i 2305
+i 2314
+i 2313
+i 118
+i 119
+i 128
+i 384
+i 385
+i 393
+i 100
+i 101
+i 110
+i 366
+i 367
+i 375
+i 2239
+i 2240
+i 2249
+i 2293
+i 2294
+i 2303
+i 2249
+i 2258
+i 2257
+i 2121
+i 2122
+i 2131
+i 2205
+i 2215
+i 2214
+i 2116
+i 2117
+i 2125
+i 2311
+i 2312
+i 2321
+i 2311
+i 2321
+i 2320
+i 2303
+i 2312
+i 2311
+i 2286
+i 2287
+i 2295
+i 2169
+i 2170
+i 2179
+i 176
+i 186
+i 185
+i 435
+i 444
+i 443
+i 2268
+i 2269
+i 2277
+i 2257
+i 2258
+i 2267
+i 2223
+i 2233
+i 2232
+i 2214
+i 2215
+i 2223
+i 2322
+i 2332
+i 2331
+i 2185
+i 2195
+i 2194
+i 184
+i 193
+i 192
+i 445
+i 455
+i 454
+i 2275
+i 2276
+i 2285
+i 2287
+i 2296
+i 2295
+i 2194
+i 2195
+i 2203
+i 291
+i 301
+i 300
+i 32
+i 41
+i 40
+i 2302
+i 2303
+i 2311
+i 2267
+i 2276
+i 2275
+i 2125
+i 2135
+i 2134
+i 2241
+i 2251
+i 2250
+i 2250
+i 2251
+i 2259
+i 2295
+i 2296
+i 2305
+i 2285
+i 2294
+i 2293
+i 2131
+i 2140
+i 2139
+i 200
+i 210
+i 209
+i 465
+i 474
+i 473
+i 2293
+i 2303
+i 2302
+i 1852
+i 1853
+i 1862
+i 2232
+i 2233
+i 2241
+i 2187
+i 2188
+i 2197
+i 2304
+i 2305
+i 2313
+i 92
+i 101
+i 100
+i 357
+i 367
+i 366
+i 2179
+i 2188
+i 2187
+i 2085
+i 2095
+i 2094
+i 2081
+i 2090
+i 2089
+i 2259
+i 2269
+i 2268
+i 2094
+i 2095
+i 2103
+i 177
+i 178
+i 186
+i 433
+i 434
+i 443
+i 2212
+i 2213
+i 2221
+i 321
+i 330
+i 329
+i 56
+i 66
+i 65
+i 2277
+i 2287
+i 2286
+i 2089
+i 2090
+i 2099
+i 2203
+i 2213
+i 2212
+i 2295
+i 2305
+i 2304
+i 2134
+i 2135
+i 2143
+i 2139
+i 2140
+i 2149
+i 2149
+i 2158
+i 2157
+i 2269
+i 2278
+i 2277
+i 2311
+i 2320
+i 2319
+i 2331
+i 2332
+i 2340
+i 128
+i 137
+i 136
+i 393
+i 403
+i 402
+i 311
+i 321
+i 320
+i 2275
+i 2285
+i 2284
+i 48
+i 57
+i 56
+i 2284
+i 2285
+i 2293
+i 2197
+i 2206
+i 2205
+i 2143
+i 2153
+i 2152
+i 2205
+i 2206
+i 2215
+i 2230
+i 2231
+i 2239
+i 2248
+i 2249
+i 2257
+i 2277
+i 2278
+i 2287
+i 192
+i 201
+i 200
+i 455
+i 465
+i 464
+i 2221
+i 2231
+i 2230
+i 2103
+i 2113
+i 2112
+i 2305
+i 2315
+i 2314
+i 2157
+i 2158
+i 2167
+i 2239
+i 2249
+i 2248
+i 2112
+i 2113
+i 2121
+i 1843
+i 1844
+i 1852
+i 176
+i 177
+i 186
+i 434
+i 435
+i 443
+i 2099
+i 2108
+i 2107
+i 2287
+i 2297
+i 2296
+i 2257
+i 2267
+i 2266
+i 2107
+i 2108
+i 2117
+i 2266
+i 2267
+i 2275
+i 279
+i 289
+i 288
+i 26
+i 35
+i 34
+i 2301
+i 2302
+i 2311
+i 2152
+i 2153
+i 2161
+i 2223
+i 2224
+i 2233
+i 2167
+i 2176
+i 2175
+i 2296
+i 2297
+i 2305
+i 82
+i 83
+i 92
+i 348
+i 349
+i 357
+i 2161
+i 2171
+i 2170
+i 2293
+i 2302
+i 2301
+i 176
+i 185
+i 184
+i 435
+i 445
+i 444
+i 2215
+i 2224
+i 2223
+i 2310
+i 2311
+i 2319
+i 2175
+i 2176
+i 2185
+i 2121
+i 2131
+i 2130
+i 2259
+i 2260
+i 2269
+i 2170
+i 2171
+i 2179
+i 2301
+i 2311
+i 2310
+i 2241
+i 2242
+i 2251
+i 301
+i 302
+i 311
+i 2251
+i 2260
+i 2259
+i 39
+i 40
+i 48
+i 2130
+i 2131
+i 2139
+i 1862
+i 1871
+i 1870
+i 2233
+i 2242
+i 2241
+i 2322
+i 2323
+i 2332
+i 2269
+i 2279
+i 2278
+i 2117
+i 2126
+i 2125
+i 2125
+i 2126
+i 2135
+i 281
+i 290
+i 289
+i 2275
+i 2284
+i 2283
+i 24
+i 34
+i 33
+i 2283
+i 2284
+i 2293
+i 244
+i 245
+i 254
+i 510
+i 511
+i 519
+i 2188
+i 2189
+i 2197
+i 2278
+i 2279
+i 2287
+i 2287
+i 2288
+i 2297
+i 2292
+i 2293
+i 2301
+i 2185
+i 2194
+i 2193
+i 2179
+i 2189
+i 2188
+i 2305
+i 2306
+i 2315
+i 2193
+i 2194
+i 2203
+i 2309
+i 2310
+i 2319
+i 2297
+i 2306
+i 2305
+i 2269
+i 2270
+i 2279
+i 2197
+i 2207
+i 2206
+i 1870
+i 1871
+i 1880
+i 2206
+i 2207
+i 2215
+i 74
+i 83
+i 82
+i 339
+i 349
+i 348
+i 2283
+i 2293
+i 2292
+i 2340
+i 2350
+i 2349
+i 291
+i 292
+i 301
+i 31
+i 32
+i 40
+i 2211
+i 2212
+i 2221
+i 2247
+i 2248
+i 2257
+i 2257
+i 2266
+i 2265
+i 2274
+i 2275
+i 2283
+i 2265
+i 2266
+i 2275
+i 2279
+i 2288
+i 2287
+i 2203
+i 2212
+i 2211
+i 2135
+i 2144
+i 2143
+i 2309
+i 2319
+i 2318
+i 2301
+i 2310
+i 2309
+i 2229
+i 2230
+i 2239
+i 2239
+i 2248
+i 2247
+i 2221
+i 2230
+i 2229
+i 183
+i 184
+i 192
+i 445
+i 446
+i 455
+i 2143
+i 2144
+i 2153
+i 226
+i 227
+i 236
+i 492
+i 493
+i 501
+i 2224
+i 2225
+i 2233
+i 2261
+i 2270
+i 2269
+i 1852
+i 1862
+i 1861
+i 236
+i 245
+i 244
+i 501
+i 511
+i 510
+i 218
+i 227
+i 226
+i 483
+i 493
+i 492
+i 2265
+i 2275
+i 2274
+i 2260
+i 2261
+i 2269
+i 2148
+i 2149
+i 2157
+i 2139
+i 2149
+i 2148
+i 2251
+i 2261
+i 2260
+i 2349
+i 2350
+i 2358
+i 2251
+i 2252
+i 2261
+i 2242
+i 2243
+i 2251
+i 2256
+i 2257
+i 2265
+i 109
+i 110
+i 118
+i 375
+i 376
+i 385
+i 2307
+i 2316
+i 2315
+i 2243
+i 2252
+i 2251
+i 2215
+i 2225
+i 2224
+i 2247
+i 2257
+i 2256
+i 2233
+i 2243
+i 2242
+i 100
+i 110
+i 109
+i 367
+i 376
+i 375
+i 2291
+i 2292
+i 2301
+i 2306
+i 2307
+i 2315
+i 281
+i 291
+i 290
+i 24
+i 33
+i 32
+i 2288
+i 2289
+i 2297
+i 2289
+i 2298
+i 2297
+i 2297
+i 2307
+i 2306
+i 2300
+i 2301
+i 2309
+i 2238
+i 2239
+i 2247
+i 1861
+i 1862
+i 1870
+i 2229
+i 2239
+i 2238
+i 2161
+i 2162
+i 2171
+i 2157
+i 2167
+i 2166
+i 2233
+i 2234
+i 2243
+i 2225
+i 2234
+i 2233
+i 2297
+i 2298
+i 2307
+i 2153
+i 2162
+i 2161
+i 2166
+i 2167
+i 2175
+i 2283
+i 2292
+i 2291
+i 2220
+i 2221
+i 2229
+i 2291
+i 2301
+i 2300
+i 2270
+i 2271
+i 2279
+i 279
+i 280
+i 289
+i 25
+i 26
+i 34
+i 118
+i 128
+i 127
+i 385
+i 394
+i 393
+i 2211
+i 2221
+i 2220
+i 2189
+i 2198
+i 2197
+i 2175
+i 2185
+i 2184
+i 2279
+i 2289
+i 2288
+i 2197
+i 2198
+i 2207
+i 2207
+i 2216
+i 2215
+i 2171
+i 2180
+i 2179
+i 2309
+i 2318
+i 2317
+i 2273
+i 2274
+i 2283
+i 2215
+i 2216
+i 2225
+i 2193
+i 2203
+i 2202
+i 2179
+i 2180
+i 2189
+i 2184
+i 2185
+i 2193
+i 2202
+i 2203
+i 2211
+i 2332
+i 2341
+i 2340
+i 280
+i 281
+i 289
+i 170
+i 179
+i 178
+i 423
+i 433
+i 432
+i 24
+i 25
+i 34
+i 311
+i 312
+i 321
+i 47
+i 48
+i 56
+i 2265
+i 2274
+i 2273
+i 2307
+i 2317
+i 2316
+i 2261
+i 2271
+i 2270
+i 127
+i 128
+i 136
+i 393
+i 394
+i 403
+i 2282
+i 2283
+i 2291
+i 208
+i 209
+i 218
+i 474
+i 475
+i 483
+i 2271
+i 2280
+i 2279
+i 2279
+i 2280
+i 2289
+i 91
+i 92
+i 100
+i 357
+i 358
+i 367
+i 191
+i 192
+i 200
+i 455
+i 456
+i 465
+i 2255
+i 2256
+i 2265
+i 293
+i 302
+i 301
+i 30
+i 40
+i 39
+i 2247
+i 2256
+i 2255
+i 175
+i 176
+i 184
+i 435
+i 436
+i 445
+i 2273
+i 2283
+i 2282
+i 2252
+i 2253
+i 2261
+i 2243
+i 2253
+i 2252
+i 2299
+i 2300
+i 2309
+i 330
+i 331
+i 339
+i 64
+i 65
+i 74
+i 292
+i 293
+i 301
+i 30
+i 31
+i 40
+i 2340
+i 2341
+i 2350
+i 2289
+i 2299
+i 2298
+i 2308
+i 2309
+i 2317
+i 2298
+i 2299
+i 2307
+i 1880
+i 1889
+i 1888
+i 2291
+i 2300
+i 2299
+i 1870
+i 1880
+i 1879
+i 82
+i 92
+i 91
+i 349
+i 358
+i 357
+i 168
+i 178
+i 177
+i 425
+i 434
+i 433
+i 2237
+i 2238
+i 2247
+i 2229
+i 2238
+i 2237
+i 302
+i 303
+i 311
+i 38
+i 39
+i 48
+i 2299
+i 2309
+i 2308
+i 2358
+i 2368
+i 2367
+i 2234
+i 2235
+i 2243
+i 2225
+i 2235
+i 2234
+i 2307
+i 2308
+i 2317
+i 1888
+i 1889
+i 1898
+i 2264
+i 2265
+i 2273
+i 2261
+i 2262
+i 2271
+i 2281
+i 2282
+i 2291
+i 2271
+i 2281
+i 2280
+i 2255
+i 2265
+i 2264
+i 2246
+i 2247
+i 2255
+i 2280
+i 2281
+i 2289
+i 2085
+i 2094
+i 2093
+i 244
+i 254
+i 253
+i 511
+i 520
+i 519
+i 2219
+i 2220
+i 2229
+i 2299
+i 2308
+i 2307
+i 2290
+i 2291
+i 2299
+i 2093
+i 2094
+i 2103
+i 2273
+i 2282
+i 2281
+i 1879
+i 1880
+i 1888
+i 2081
+i 2091
+i 2090
+i 2211
+i 2220
+i 2219
+i 2253
+i 2262
+i 2261
+i 2243
+i 2244
+i 2253
+i 2289
+i 2290
+i 2299
+i 2207
+i 2217
+i 2216
+i 2103
+i 2112
+i 2111
+i 2237
+i 2247
+i 2246
+i 2090
+i 2091
+i 2099
+i 2367
+i 2368
+i 2376
+i 2281
+i 2291
+i 2290
+i 2189
+i 2199
+i 2198
+i 174
+i 184
+i 183
+i 437
+i 446
+i 445
+i 2111
+i 2112
+i 2121
+i 2099
+i 2109
+i 2108
+i 2216
+i 2217
+i 2225
+i 182
+i 183
+i 192
+i 446
+i 447
+i 455
+i 2198
+i 2199
+i 2207
+i 2108
+i 2109
+i 2117
+i 303
+i 312
+i 311
+i 200
+i 209
+i 208
+i 465
+i 475
+i 474
+i 2121
+i 2130
+i 2129
+i 1842
+i 1843
+i 1852
+i 38
+i 48
+i 47
+i 168
+i 177
+i 176
+i 425
+i 435
+i 434
+i 2281
+i 2290
+i 2289
+i 2228
+i 2229
+i 2237
+i 2193
+i 2202
+i 2201
+i 2235
+i 2244
+i 2243
+i 2135
+i 2145
+i 2144
+i 281
+i 282
+i 291
+i 2171
+i 2181
+i 2180
+i 283
+i 292
+i 291
+i 23
+i 24
+i 32
+i 22
+i 32
+i 31
+i 2129
+i 2130
+i 2139
+i 2201
+i 2202
+i 2211
+i 2350
+i 2359
+i 2358
+i 2117
+i 2127
+i 2126
+i 2271
+i 2272
+i 2281
+i 321
+i 331
+i 330
+i 56
+i 65
+i 64
+i 2157
+i 2166
+i 2165
+i 2175
+i 2184
+i 2183
+i 2126
+i 2127
+i 2135
+i 2144
+i 2145
+i 2153
+i 2180
+i 2181
+i 2189
+i 2272
+i 2273
+i 2281
+i 2225
+i 2226
+i 2235
+i 2165
+i 2166
+i 2175
+i 2162
+i 2163
+i 2171
+i 2147
+i 2148
+i 2157
+i 2139
+i 2148
+i 2147
+i 2219
+i 2229
+i 2228
+i 2183
+i 2184
+i 2193
+i 2153
+i 2163
+i 2162
+i 174
+i 175
+i 184
+i 436
+i 437
+i 445
+i 182
+i 192
+i 191
+i 447
+i 456
+i 455
+i 1898
+i 1907
+i 1906
+i 226
+i 236
+i 235
+i 493
+i 502
+i 501
+i 235
+i 236
+i 244
+i 501
+i 502
+i 511
+i 2207
+i 2208
+i 2217
+i 2210
+i 2211
+i 2219
+i 2217
+i 2226
+i 2225
+i 73
+i 74
+i 82
+i 339
+i 340
+i 349
+i 217
+i 218
+i 226
+i 483
+i 484
+i 493
+i 2358
+i 2359
+i 2368
+i 2199
+i 2208
+i 2207
+i 169
+i 170
+i 178
+i 423
+i 424
+i 433
+i 2262
+i 2263
+i 2271
+i 2263
+i 2272
+i 2271
+i 2263
+i 2264
+i 2273
+i 1888
+i 1898
+i 1897
+i 2189
+i 2190
+i 2199
+i 2201
+i 2211
+i 2210
+i 2263
+i 2273
+i 2272
+i 2192
+i 2193
+i 2201
+i 2245
+i 2246
+i 2255
+i 2255
+i 2264
+i 2263
+i 2253
+i 2263
+i 2262
+i 168
+i 169
+i 178
+i 424
+i 425
+i 433
+i 2174
+i 2175
+i 2183
+i 2244
+i 2245
+i 2253
+i 2181
+i 2190
+i 2189
+i 2171
+i 2172
+i 2181
+i 282
+i 283
+i 291
+i 22
+i 23
+i 32
+i 208
+i 218
+i 217
+i 475
+i 484
+i 483
+i 1897
+i 1898
+i 1906
+i 2165
+i 2175
+i 2174
+i 2183
+i 2193
+i 2192
+i 2237
+i 2246
+i 2245
+i 331
+i 340
+i 339
+i 64
+i 74
+i 73
+i 2163
+i 2172
+i 2171
+i 2323
+i 2324
+i 2332
+i 2156
+i 2157
+i 2165
+i 2376
+i 2386
+i 2385
+i 1906
+i 1907
+i 1916
+i 2235
+i 2245
+i 2244
+i 1852
+i 1861
+i 1860
+i 2253
+i 2254
+i 2263
+i 2254
+i 2255
+i 2263
+i 2147
+i 2157
+i 2156
+i 2245
+i 2254
+i 2253
+i 2245
+i 2255
+i 2254
+i 2153
+i 2154
+i 2163
+i 293
+i 303
+i 302
+i 30
+i 39
+i 38
+i 2145
+i 2154
+i 2153
+i 2138
+i 2139
+i 2147
+i 2227
+i 2228
+i 2237
+i 2135
+i 2136
+i 2145
+i 2129
+i 2139
+i 2138
+i 2226
+i 2227
+i 2235
+i 2127
+i 2136
+i 2135
+i 2120
+i 2121
+i 2129
+i 2117
+i 2118
+i 2127
+i 1860
+i 1861
+i 1870
+i 2102
+i 2103
+i 2111
+i 2385
+i 2386
+i 2394
+i 2093
+i 2103
+i 2102
+i 283
+i 293
+i 292
+i 2109
+i 2118
+i 2117
+i 22
+i 31
+i 30
+i 2219
+i 2228
+i 2227
+i 2111
+i 2121
+i 2120
+i 2084
+i 2085
+i 2093
+i 2368
+i 2377
+i 2376
+i 166
+i 176
+i 175
+i 427
+i 436
+i 435
+i 2099
+i 2100
+i 2109
+i 2236
+i 2237
+i 2245
+i 2235
+i 2236
+i 2245
+i 2217
+i 2227
+i 2226
+i 1842
+i 1852
+i 1851
+i 1916
+i 1925
+i 1924
+i 2081
+i 2082
+i 2091
+i 2376
+i 2377
+i 2386
+i 2091
+i 2100
+i 2099
+i 2227
+i 2237
+i 2236
+i 2227
+i 2236
+i 2235
+i 312
+i 313
+i 321
+i 271
+i 280
+i 279
+i 16
+i 26
+i 25
+i 46
+i 47
+i 56
+i 167
+i 168
+i 176
+i 425
+i 426
+i 435
+i 190
+i 191
+i 200
+i 456
+i 457
+i 465
+i 2332
+i 2342
+i 2341
+i 2209
+i 2210
+i 2219
+i 174
+i 183
+i 182
+i 437
+i 447
+i 446
+i 2208
+i 2209
+i 2217
+i 271
+i 281
+i 280
+i 16
+i 25
+i 24
+i 2199
+i 2209
+i 2208
+i 1906
+i 1916
+i 1915
+i 2201
+i 2210
+i 2209
+i 1851
+i 1852
+i 1860
+i 2394
+i 2404
+i 2403
+i 2218
+i 2219
+i 2227
+i 1924
+i 1925
+i 1934
+i 2217
+i 2218
+i 2227
+i 2341
+i 2342
+i 2350
+i 1915
+i 1916
+i 1924
+i 1870
+i 1879
+i 1878
+i 199
+i 200
+i 208
+i 465
+i 466
+i 475
+i 166
+i 167
+i 176
+i 426
+i 427
+i 435
+i 2190
+i 2191
+i 2199
+i 321
+i 322
+i 331
+i 2191
+i 2192
+i 2201
+i 55
+i 56
+i 64
+i 2209
+i 2219
+i 2218
+i 2209
+i 2218
+i 2217
+i 2181
+i 2191
+i 2190
+i 2386
+i 2395
+i 2394
+i 2183
+i 2192
+i 2191
+i 2403
+i 2404
+i 2412
+i 166
+i 175
+i 174
+i 427
+i 437
+i 436
+i 273
+i 282
+i 281
+i 14
+i 24
+i 23
+i 1860
+i 1870
+i 1869
+i 2324
+i 2333
+i 2332
+i 1878
+i 1879
+i 1888
+i 2394
+i 2395
+i 2404
+i 2199
+i 2200
+i 2209
+i 2200
+i 2201
+i 2209
+i 2173
+i 2174
+i 2183
+i 303
+i 313
+i 312
+i 38
+i 47
+i 46
+i 2172
+i 2173
+i 2181
+i 293
+i 294
+i 303
+i 29
+i 30
+i 38
+i 2165
+i 2174
+i 2173
+i 1934
+i 1943
+i 1942
+i 313
+i 322
+i 321
+i 46
+i 56
+i 55
+i 190
+i 200
+i 199
+i 457
+i 466
+i 465
+i 2163
+i 2173
+i 2172
+i 283
+i 284
+i 293
+i 21
+i 22
+i 30
+i 2191
+i 2200
+i 2199
+i 2191
+i 2201
+i 2200
+i 1869
+i 1870
+i 1878
+i 182
+i 191
+i 190
+i 447
+i 457
+i 456
+i 2332
+i 2333
+i 2342
+i 2412
+i 2422
+i 2421
+i 270
+i 271
+i 279
+i 16
+i 17
+i 26
+i 2350
+i 2360
+i 2359
+i 1924
+i 1934
+i 1933
+i 273
+i 283
+i 282
+i 14
+i 23
+i 22
+i 2155
+i 2156
+i 2165
+i 1942
+i 1943
+i 1952
+i 2154
+i 2155
+i 2163
+i 2181
+i 2182
+i 2191
+i 2147
+i 2156
+i 2155
+i 2145
+i 2155
+i 2154
+i 160
+i 170
+i 169
+i 415
+i 424
+i 423
+i 1888
+i 1897
+i 1896
+i 173
+i 174
+i 182
+i 437
+i 438
+i 447
+i 2182
+i 2183
+i 2191
+i 271
+i 272
+i 281
+i 15
+i 16
+i 24
+i 1933
+i 1934
+i 1942
+i 2404
+i 2413
+i 2412
+i 2359
+i 2360
+i 2368
+i 2342
+i 2351
+i 2350
+i 1896
+i 1897
+i 1906
+i 1878
+i 1888
+i 1887
+i 160
+i 169
+i 168
+i 415
+i 425
+i 424
+i 2421
+i 2422
+i 2430
+i 2173
+i 2182
+i 2181
+i 2173
+i 2183
+i 2182
+i 2137
+i 2138
+i 2147
+i 2412
+i 2413
+i 2422
+i 272
+i 273
+i 281
+i 14
+i 15
+i 24
+i 1842
+i 1851
+i 1850
+i 2136
+i 2137
+i 2145
+i 2129
+i 2138
+i 2137
+i 108
+i 109
+i 118
+i 376
+i 377
+i 385
+i 2127
+i 2137
+i 2136
+i 1887
+i 1888
+i 1896
+i 285
+i 294
+i 293
+i 20
+i 30
+i 29
+i 100
+i 109
+i 108
+i 367
+i 377
+i 376
+i 284
+i 285
+i 293
+i 20
+i 21
+i 30
+i 2350
+i 2351
+i 2360
+i 118
+i 127
+i 126
+i 385
+i 395
+i 394
+i 1952
+i 1961
+i 1960
+i 2164
+i 2165
+i 2173
+i 165
+i 166
+i 174
+i 427
+i 428
+i 437
+i 2163
+i 2164
+i 2173
+i 1896
+i 1906
+i 1905
+i 90
+i 91
+i 100
+i 358
+i 359
+i 367
+i 2118
+i 2119
+i 2127
+i 158
+i 168
+i 167
+i 417
+i 426
+i 425
+i 1850
+i 1851
+i 1860
+i 2119
+i 2120
+i 2129
+i 2109
+i 2119
+i 2118
+i 1942
+i 1952
+i 1951
+i 126
+i 127
+i 136
+i 394
+i 395
+i 403
+i 2368
+i 2378
+i 2377
+i 2111
+i 2120
+i 2119
+i 2430
+i 2440
+i 2439
+i 2155
+i 2165
+i 2164
+i 2439
+i 2440
+i 2448
+i 294
+i 295
+i 303
+i 28
+i 29
+i 38
+i 303
+i 304
+i 313
+i 2422
+i 2431
+i 2430
+i 2360
+i 2369
+i 2368
+i 2155
+i 2164
+i 2163
+i 1905
+i 1906
+i 1914
+i 37
+i 38
+i 46
+i 82
+i 91
+i 90
+i 349
+i 359
+i 358
+i 1960
+i 1961
+i 1970
+i 2377
+i 2378
+i 2386
+i 1860
+i 1869
+i 1868
+i 1906
+i 1915
+i 1914
+i 2547
+i 2548
+i 2556
+i 275
+i 284
+i 283
+i 12
+i 22
+i 21
+i 1951
+i 1952
+i 1960
+i 2538
+i 2548
+i 2547
+i 244
+i 253
+i 252
+i 511
+i 521
+i 520
+i 1841
+i 1842
+i 1850
+i 2101
+i 2102
+i 2111
+i 2093
+i 2102
+i 2101
+i 164
+i 174
+i 173
+i 429
+i 438
+i 437
+i 2145
+i 2146
+i 2155
+i 158
+i 167
+i 166
+i 417
+i 427
+i 426
+i 181
+i 182
+i 190
+i 447
+i 448
+i 457
+i 2100
+i 2101
+i 2109
+i 2368
+i 2369
+i 2378
+i 2146
+i 2147
+i 2155
+i 160
+i 161
+i 170
+i 414
+i 415
+i 423
+i 273
+i 274
+i 283
+i 13
+i 14
+i 22
+i 1914
+i 1915
+i 1924
+i 72
+i 73
+i 82
+i 340
+i 341
+i 349
+i 2091
+i 2101
+i 2100
+i 2430
+i 2431
+i 2440
+i 2137
+i 2146
+i 2145
+i 164
+i 165
+i 174
+i 428
+i 429
+i 437
+i 226
+i 235
+i 234
+i 493
+i 503
+i 502
+i 234
+i 235
+i 244
+i 502
+i 503
+i 511
+i 1868
+i 1869
+i 1878
+i 2448
+i 2458
+i 2457
+i 216
+i 217
+i 226
+i 484
+i 485
+i 493
+i 2324
+i 2334
+i 2333
+i 2137
+i 2147
+i 2146
+i 172
+i 173
+i 182
+i 438
+i 439
+i 447
+i 1914
+i 1924
+i 1923
+i 295
+i 304
+i 303
+i 28
+i 38
+i 37
+i 2083
+i 2084
+i 2093
+i 159
+i 160
+i 168
+i 415
+i 416
+i 425
+i 2386
+i 2396
+i 2395
+i 2440
+i 2449
+i 2448
+i 2127
+i 2128
+i 2137
+i 2128
+i 2129
+i 2137
+i 2082
+i 2083
+i 2091
+i 1923
+i 1924
+i 1932
+i 2457
+i 2458
+i 2466
+i 1960
+i 1970
+i 1969
+i 2378
+i 2387
+i 2386
+i 208
+i 217
+i 216
+i 475
+i 485
+i 484
+i 158
+i 159
+i 168
+i 416
+i 417
+i 425
+i 274
+i 275
+i 283
+i 12
+i 13
+i 22
+i 1878
+i 1887
+i 1886
+i 2333
+i 2334
+i 2342
+i 331
+i 341
+i 340
+i 64
+i 73
+i 72
+i 2448
+i 2449
+i 2458
+i 2395
+i 2396
+i 2404
+i 2119
+i 2128
+i 2127
+i 2386
+i 2387
+i 2396
+i 1850
+i 1860
+i 1859
+i 2119
+i 2129
+i 2128
+i 1859
+i 1860
+i 1868
+i 172
+i 182
+i 181
+i 439
+i 448
+i 447
+i 1970
+i 1979
+i 1978
+i 2458
+i 2467
+i 2466
+i 1924
+i 1933
+i 1932
+i 2520
+i 2530
+i 2529
+i 1978
+i 1979
+i 1988
+i 1886
+i 1887
+i 1896
+i 285
+i 295
+i 294
+i 20
+i 29
+i 28
+i 2396
+i 2405
+i 2404
+i 2466
+i 2476
+i 2475
+i 275
+i 285
+i 284
+i 2476
+i 2485
+i 2484
+i 12
+i 21
+i 20
+i 1896
+i 1905
+i 1904
+i 1932
+i 1942
+i 1941
+i 2475
+i 2476
+i 2484
+i 1941
+i 1942
+i 1950
+i 2342
+i 2352
+i 2351
+i 1969
+i 1970
+i 1978
+i 2529
+i 2530
+i 2538
+i 198
+i 199
+i 208
+i 466
+i 467
+i 475
+i 2548
+i 2549
+i 2558
+i 156
+i 166
+i 165
+i 419
+i 428
+i 427
+i 2548
+i 2557
+i 2556
+i 322
+i 323
+i 331
+i 54
+i 55
+i 64
+i 1932
+i 1933
+i 1942
+i 2466
+i 2467
+i 2476
+i 2324
+i 2325
+i 2334
+i 2109
+i 2110
+i 2119
+i 1868
+i 1878
+i 1877
+i 1978
+i 1988
+i 1987
+i 2484
+i 2485
+i 2494
+i 2110
+i 2111
+i 2119
+i 2502
+i 2503
+i 2512
+i 1942
+i 1951
+i 1950
+i 2494
+i 2503
+i 2502
+i 2502
+i 2512
+i 2511
+i 2404
+i 2414
+i 2413
+i 2404
+i 2405
+i 2414
+i 1877
+i 1878
+i 1886
+i 157
+i 158
+i 166
+i 417
+i 418
+i 427
+i 1904
+i 1905
+i 1914
+i 2484
+i 2494
+i 2493
+i 2520
+i 2521
+i 2530
+i 2540
+i 2549
+i 2548
+i 2351
+i 2352
+i 2360
+i 2538
+i 2539
+i 2548
+i 1987
+i 1988
+i 1996
+i 1988
+i 1997
+i 1996
+i 2413
+i 2414
+i 2422
+i 2101
+i 2110
+i 2109
+i 2549
+i 2550
+i 2558
+i 2334
+i 2343
+i 2342
+i 2493
+i 2494
+i 2502
+i 164
+i 173
+i 172
+i 429
+i 439
+i 438
+i 2101
+i 2111
+i 2110
+i 2548
+i 2558
+i 2557
+i 2422
+i 2423
+i 2432
+i 2414
+i 2423
+i 2422
+i 2360
+i 2370
+i 2369
+i 2511
+i 2512
+i 2520
+i 2422
+i 2432
+i 2431
+i 313
+i 323
+i 322
+i 46
+i 55
+i 54
+i 1950
+i 1951
+i 1960
+i 261
+i 271
+i 270
+i 8
+i 17
+i 16
+i 190
+i 199
+i 198
+i 457
+i 467
+i 466
+i 156
+i 157
+i 166
+i 418
+i 419
+i 427
+i 1950
+i 1960
+i 1959
+i 1914
+i 1923
+i 1922
+i 1959
+i 1960
+i 1968
+i 2342
+i 2343
+i 2352
+i 263
+i 272
+i 271
+i 6
+i 16
+i 15
+i 1960
+i 1969
+i 1968
+i 1996
+i 1997
+i 2006
+i 1886
+i 1896
+i 1895
+i 2512
+i 2521
+i 2520
+i 2540
+i 2550
+i 2549
+i 2092
+i 2093
+i 2101
+i 2369
+i 2370
+i 2378
+i 156
+i 165
+i 164
+i 419
+i 429
+i 428
+i 1922
+i 1923
+i 1932
+i 1996
+i 2006
+i 2005
+i 1895
+i 1896
+i 1904
+i 2091
+i 2092
+i 2101
+i 2530
+i 2539
+i 2538
+i 2503
+i 2504
+i 2512
+i 2494
+i 2504
+i 2503
+i 263
+i 273
+i 272
+i 6
+i 15
+i 14
+i 108
+i 118
+i 117
+i 117
+i 118
+i 126
+i 377
+i 386
+i 385
+i 385
+i 386
+i 395
+i 2458
+i 2468
+i 2467
+i 2431
+i 2432
+i 2440
+i 2083
+i 2093
+i 2092
+i 2476
+i 2486
+i 2485
+i 2521
+i 2522
+i 2530
+i 2522
+i 2531
+i 2530
+i 2440
+i 2450
+i 2449
+i 90
+i 100
+i 99
+i 99
+i 100
+i 108
+i 359
+i 368
+i 367
+i 367
+i 368
+i 377
+i 285
+i 286
+i 295
+i 275
+i 276
+i 285
+i 11
+i 12
+i 20
+i 1932
+i 1941
+i 1940
+i 19
+i 20
+i 28
+i 2539
+i 2540
+i 2548
+i 2083
+i 2092
+i 2091
+i 1940
+i 1941
+i 1950
+i 2550
+i 2559
+i 2558
+i 304
+i 305
+i 313
+i 36
+i 37
+i 46
+i 2432
+i 2441
+i 2440
+i 2378
+i 2388
+i 2387
+i 2005
+i 2006
+i 2014
+i 2440
+i 2441
+i 2450
+i 2485
+i 2486
+i 2494
+i 1968
+i 1969
+i 1978
+i 2396
+i 2406
+i 2405
+i 2458
+i 2459
+i 2468
+i 2006
+i 2015
+i 2014
+i 180
+i 181
+i 190
+i 448
+i 449
+i 457
+i 1840
+i 1841
+i 1850
+i 2387
+i 2388
+i 2396
+i 2023
+i 2024
+i 2032
+i 2014
+i 2024
+i 2023
+i 2352
+i 2361
+i 2360
+i 2449
+i 2450
+i 2458
+i 2024
+i 2033
+i 2032
+i 126
+i 136
+i 135
+i 395
+i 404
+i 403
+i 265
+i 274
+i 273
+i 4
+i 14
+i 13
+i 2467
+i 2468
+i 2476
+i 2522
+i 2532
+i 2531
+i 2014
+i 2015
+i 2024
+i 2530
+i 2531
+i 2540
+i 1904
+i 1914
+i 1913
+i 72
+i 82
+i 81
+i 81
+i 82
+i 90
+i 341
+i 350
+i 349
+i 349
+i 350
+i 359
+i 2360
+i 2361
+i 2370
+i 2042
+i 2051
+i 2050
+i 1978
+i 1987
+i 1986
+i 2450
+i 2459
+i 2458
+i 1968
+i 1978
+i 1977
+i 2512
+i 2522
+i 2521
+i 216
+i 226
+i 225
+i 225
+i 226
+i 234
+i 485
+i 494
+i 493
+i 493
+i 494
+i 503
+i 1913
+i 1914
+i 1922
+i 234
+i 244
+i 243
+i 243
+i 244
+i 252
+i 503
+i 512
+i 511
+i 511
+i 512
+i 521
+i 1850
+i 1859
+i 1858
+i 1950
+i 1959
+i 1958
+i 1858
+i 1859
+i 1868
+i 2405
+i 2406
+i 2414
+i 2504
+i 2505
+i 2514
+i 1868
+i 1877
+i 1876
+i 1958
+i 1959
+i 1968
+i 152
+i 161
+i 160
+i 405
+i 415
+i 414
+i 429
+i 430
+i 439
+i 163
+i 164
+i 172
+i 2550
+i 2560
+i 2559
+i 2530
+i 2540
+i 2539
+i 1977
+i 1978
+i 1986
+i 2068
+i 2069
+i 2078
+i 2496
+i 2505
+i 2504
+i 2531
+i 2532
+i 2540
+i 2504
+i 2513
+i 2512
+i 2522
+i 2523
+i 2532
+i 2032
+i 2033
+i 2042
+i 2370
+i 2379
+i 2378
+i 2060
+i 2069
+i 2068
+i 150
+i 160
+i 159
+i 407
+i 416
+i 415
+i 276
+i 277
+i 285
+i 10
+i 11
+i 20
+i 277
+i 286
+i 285
+i 10
+i 20
+i 19
+i 2378
+i 2379
+i 2388
+i 2476
+i 2477
+i 2486
+i 295
+i 305
+i 304
+i 2540
+i 2541
+i 2550
+i 1986
+i 1987
+i 1996
+i 28
+i 37
+i 36
+i 2041
+i 2042
+i 2050
+i 2459
+i 2460
+i 2468
+i 1876
+i 1877
+i 1886
+i 2423
+i 2424
+i 2432
+i 2414
+i 2424
+i 2423
+i 265
+i 275
+i 274
+i 4
+i 13
+i 12
+i 198
+i 208
+i 207
+i 207
+i 208
+i 216
+i 467
+i 476
+i 475
+i 475
+i 476
+i 485
+i 1996
+i 2005
+i 2004
+i 419
+i 420
+i 429
+i 155
+i 156
+i 164
+i 323
+i 332
+i 331
+i 331
+i 332
+i 341
+i 54
+i 64
+i 63
+i 63
+i 64
+i 72
+i 150
+i 159
+i 158
+i 407
+i 417
+i 416
+i 1940
+i 1950
+i 1949
+i 2468
+i 2477
+i 2476
+i 2032
+i 2042
+i 2041
+i 2504
+i 2514
+i 2513
+i 2494
+i 2495
+i 2504
+i 172
+i 181
+i 180
+i 439
+i 449
+i 448
+i 2512
+i 2513
+i 2522
+i 2450
+i 2460
+i 2459
+i 2541
+i 2542
+i 2550
+i 2396
+i 2397
+i 2406
+i 1922
+i 1932
+i 1931
+i 2050
+i 2051
+i 2060
+i 1931
+i 1932
+i 1940
+i 2550
+i 2551
+i 2560
+i 1968
+i 1977
+i 1976
+i 1886
+i 1895
+i 1894
+i 2432
+i 2442
+i 2441
+i 1949
+i 1950
+i 1958
+i 2460
+i 2469
+i 2468
+i 2514
+i 2523
+i 2522
+i 2441
+i 2442
+i 2450
+i 2388
+i 2397
+i 2396
+i 2478
+i 2487
+i 2486
+i 2542
+i 2551
+i 2550
+i 2532
+i 2541
+i 2540
+i 2486
+i 2487
+i 2496
+i 2486
+i 2495
+i 2494
+i 2477
+i 2478
+i 2486
+i 2022
+i 2023
+i 2032
+i 2014
+i 2023
+i 2022
+i 148
+i 158
+i 157
+i 409
+i 418
+i 417
+i 2004
+i 2005
+i 2014
+i 1894
+i 1895
+i 1904
+i 1958
+i 1968
+i 1967
+i 2495
+i 2496
+i 2504
+i 2513
+i 2514
+i 2522
+i 1976
+i 1977
+i 1986
+i 421
+i 430
+i 429
+i 154
+i 164
+i 163
+i 1995
+i 1996
+i 2004
+i 1986
+i 1996
+i 1995
+i 420
+i 421
+i 429
+i 154
+i 155
+i 164
+i 2523
+i 2524
+i 2532
+i 2468
+i 2478
+i 2477
+i 2468
+i 2469
+i 2478
+i 261
+i 262
+i 271
+i 262
+i 263
+i 271
+i 6
+i 7
+i 16
+i 7
+i 8
+i 16
+i 2325
+i 2326
+i 2334
+i 1904
+i 1913
+i 1912
+i 1967
+i 1968
+i 1976
+i 2532
+i 2542
+i 2541
+i 2334
+i 2344
+i 2343
+i 286
+i 287
+i 295
+i 267
+i 276
+i 275
+i 2
+i 12
+i 11
+i 18
+i 19
+i 28
+i 2486
+i 2496
+i 2495
+i 305
+i 314
+i 313
+i 313
+i 314
+i 323
+i 36
+i 46
+i 45
+i 45
+i 46
+i 54
+i 2040
+i 2041
+i 2050
+i 2450
+i 2451
+i 2460
+i 1912
+i 1913
+i 1922
+i 180
+i 190
+i 189
+i 189
+i 190
+i 198
+i 449
+i 458
+i 457
+i 457
+i 458
+i 467
+i 2406
+i 2415
+i 2414
+i 1840
+i 1850
+i 1849
+i 148
+i 157
+i 156
+i 409
+i 419
+i 418
+i 1849
+i 1850
+i 1858
+i 1858
+i 1868
+i 1867
+i 1867
+i 1868
+i 1876
+i 2424
+i 2433
+i 2432
+i 2505
+i 2506
+i 2514
+i 2068
+i 2078
+i 2077
+i 263
+i 264
+i 273
+i 264
+i 265
+i 273
+i 4
+i 5
+i 14
+i 5
+i 6
+i 14
+i 2432
+i 2433
+i 2442
+i 2442
+i 2451
+i 2450
+i 2414
+i 2415
+i 2424
+i 2032
+i 2041
+i 2040
+i 2532
+i 2533
+i 2542
+i 2343
+i 2344
+i 2352
+i 2059
+i 2060
+i 2068
+i 2496
+i 2506
+i 2505
+i 430
+i 431
+i 439
+i 162
+i 163
+i 172
+i 2040
+i 2050
+i 2049
+i 1976
+i 1986
+i 1985
+i 2050
+i 2060
+i 2059
+i 2524
+i 2533
+i 2532
+i 1940
+i 1949
+i 1948
+i 2514
+i 2524
+i 2523
+i 1876
+i 1886
+i 1885
+i 1994
+i 1995
+i 2004
+i 1885
+i 1886
+i 1894
+i 2021
+i 2022
+i 2030
+i 2013
+i 2014
+i 2022
+i 2022
+i 2032
+i 2031
+i 1986
+i 1995
+i 1994
+i 2012
+i 2022
+i 2021
+i 1922
+i 1931
+i 1930
+i 2004
+i 2014
+i 2013
+i 2460
+i 2470
+i 2469
+i 1930
+i 1931
+i 1940
+i 2058
+i 2068
+i 2067
+i 2352
+i 2362
+i 2361
+i 150
+i 151
+i 160
+i 151
+i 152
+i 160
+i 405
+i 406
+i 415
+i 406
+i 407
+i 415
+i 1985
+i 1986
+i 1994
+i 1894
+i 1904
+i 1903
+i 1948
+i 1949
+i 1958
+i 1994
+i 2004
+i 2003
+i 2067
+i 2068
+i 2076
+i 411
+i 420
+i 419
+i 146
+i 156
+i 155
+i 1903
+i 1904
+i 1912
+i 2049
+i 2050
+i 2058
+i 2370
+i 2380
+i 2379
+i 2478
+i 2488
+i 2487
+i 2361
+i 2362
+i 2370
+i 2379
+i 2380
+i 2388
+i 1958
+i 1967
+i 1966
+i 2031
+i 2032
+i 2040
+i 2058
+i 2059
+i 2068
+i 2487
+i 2488
+i 2496
+i 2050
+i 2059
+i 2058
+i 2397
+i 2398
+i 2406
+i 2022
+i 2031
+i 2030
+i 2003
+i 2004
+i 2012
+i 148
+i 149
+i 158
+i 149
+i 150
+i 158
+i 407
+i 408
+i 417
+i 408
+i 409
+i 417
+i 2068
+i 2077
+i 2076
+i 267
+i 277
+i 276
+i 2
+i 11
+i 10
+i 2451
+i 2452
+i 2460
+i 277
+i 287
+i 286
+i 10
+i 19
+i 18
+i 2469
+i 2470
+i 2478
+i 287
+i 296
+i 295
+i 295
+i 296
+i 305
+i 18
+i 28
+i 27
+i 27
+i 28
+i 36
+i 2012
+i 2013
+i 2022
+i 2040
+i 2049
+i 2048
+i 1912
+i 1922
+i 1921
+i 265
+i 266
+i 275
+i 266
+i 267
+i 275
+i 2
+i 3
+i 12
+i 3
+i 4
+i 12
+i 1921
+i 1922
+i 1930
+i 2004
+i 2013
+i 2012
+i 2388
+i 2398
+i 2397
+i 1966
+i 1967
+i 1976
+i 2406
+i 2416
+i 2415
+i 1930
+i 1940
+i 1939
+i 2442
+i 2452
+i 2451
+i 2424
+i 2434
+i 2433
+i 2514
+i 2515
+i 2524
+i 162
+i 172
+i 171
+i 171
+i 172
+i 180
+i 431
+i 440
+i 439
+i 439
+i 440
+i 449
+i 1939
+i 1940
+i 1948
+i 2039
+i 2040
+i 2048
+i 2030
+i 2040
+i 2039
+i 2433
+i 2434
+i 2442
+i 2030
+i 2031
+i 2040
+i 2506
+i 2515
+i 2514
+i 2415
+i 2416
+i 2424
+i 421
+i 431
+i 430
+i 154
+i 163
+i 162
+i 2058
+i 2067
+i 2066
+i 2048
+i 2049
+i 2058
+i 1976
+i 1985
+i 1984
+i 411
+i 421
+i 420
+i 146
+i 155
+i 154
+i 2460
+i 2461
+i 2470
+i 2066
+i 2067
+i 2076
+i 409
+i 410
+i 419
+i 410
+i 411
+i 419
+i 146
+i 147
+i 156
+i 147
+i 148
+i 156
+i 2551
+i 2552
+i 2560
+i 2334
+i 2335
+i 2344
+i 2326
+i 2335
+i 2334
+i 2496
+i 2497
+i 2506
+i 2452
+i 2461
+i 2460
+i 1948
+i 1958
+i 1957
+i 1957
+i 1958
+i 1966
+i 2488
+i 2497
+i 2496
+i 2542
+i 2552
+i 2551
+i 2478
+i 2479
+i 2488
+i 2048
+i 2058
+i 2057
+i 1984
+i 1985
+i 1994
+i 2057
+i 2058
+i 2066
+i 2470
+i 2479
+i 2478
+i 2406
+i 2407
+i 2416
+i 2398
+i 2407
+i 2406
+i 2442
+i 2443
+i 2452
+i 2533
+i 2534
+i 2542
+i 1044
+i 1045
+i 1067
+i 1463
+i 1485
+i 1484
+i 2020
+i 2021
+i 2030
+i 2424
+i 2425
+i 2434
+i 2434
+i 2443
+i 2442
+i 1994
+i 2003
+i 2002
+i 1045
+i 1046
+i 1067
+i 1463
+i 1486
+i 1485
+i 2352
+i 2353
+i 2362
+i 2012
+i 2021
+i 2020
+i 2416
+i 2425
+i 2424
+i 2344
+i 2353
+i 2352
+i 1046
+i 1047
+i 1069
+i 1465
+i 1487
+i 1486
+i 2524
+i 2534
+i 2533
+i 1047
+i 1048
+i 1069
+i 1465
+i 1488
+i 1487
+i 1966
+i 1976
+i 1975
+i 2066
+i 2076
+i 2075
+i 2388
+i 2389
+i 2398
+i 1048
+i 1049
+i 1071
+i 1467
+i 1489
+i 1488
+i 2370
+i 2371
+i 2380
+i 267
+i 268
+i 277
+i 268
+i 269
+i 277
+i 269
+i 278
+i 277
+i 277
+i 278
+i 287
+i 0
+i 1
+i 10
+i 0
+i 10
+i 9
+i 1
+i 2
+i 10
+i 9
+i 10
+i 18
+i 1049
+i 1050
+i 1071
+i 1467
+i 1490
+i 1489
+i 2380
+i 2389
+i 2388
+i 2362
+i 2371
+i 2370
+i 2515
+i 2516
+i 2524
+i 1975
+i 1976
+i 1984
+i 1050
+i 1051
+i 1073
+i 1469
+i 1491
+i 1490
+i 1051
+i 1052
+i 1073
+i 1469
+i 1492
+i 1491
+i 2002
+i 2003
+i 2012
+i 1052
+i 1053
+i 1075
+i 1471
+i 1493
+i 1492
+i 1053
+i 1054
+i 1075
+i 1471
+i 1494
+i 1493
+i 2506
+i 2516
+i 2515
+i 1044
+i 1067
+i 1066
+i 1462
+i 1463
+i 1484
+i 411
+i 412
+i 421
+i 412
+i 413
+i 421
+i 413
+i 422
+i 421
+i 421
+i 422
+i 431
+i 144
+i 145
+i 154
+i 144
+i 154
+i 153
+i 145
+i 146
+i 154
+i 153
+i 154
+i 162
+i 1054
+i 1055
+i 1077
+i 1473
+i 1495
+i 1494
+i 2497
+i 2498
+i 2506
+i 1055
+i 1056
+i 1077
+i 1473
+i 1496
+i 1495
+i 1046
+i 1068
+i 1067
+i 1046
+i 1069
+i 1068
+i 1464
+i 1465
+i 1486
+i 1463
+i 1464
+i 1486
+i 1056
+i 1057
+i 1079
+i 1475
+i 1497
+i 1496
+i 2552
+i 2561
+i 2560
+i 1057
+i 1058
+i 1079
+i 1475
+i 1498
+i 1497
+i 1048
+i 1070
+i 1069
+i 1048
+i 1071
+i 1070
+i 1466
+i 1467
+i 1488
+i 1465
+i 1466
+i 1488
+i 2488
+i 2498
+i 2497
+i 1058
+i 1059
+i 1081
+i 1477
+i 1499
+i 1498
+i 1050
+i 1072
+i 1071
+i 1050
+i 1073
+i 1072
+i 1468
+i 1469
+i 1490
+i 1467
+i 1468
+i 1490
+i 1059
+i 1060
+i 1081
+i 1477
+i 1500
+i 1499
+i 1060
+i 1061
+i 1083
+i 1479
+i 1501
+i 1500
+i 1052
+i 1074
+i 1073
+i 1052
+i 1075
+i 1074
+i 1470
+i 1471
+i 1492
+i 1469
+i 1470
+i 1492
+i 2038
+i 2039
+i 2048
+i 1061
+i 1062
+i 1083
+i 1479
+i 1502
+i 1501
+i 2030
+i 2039
+i 2038
+i 1054
+i 1076
+i 1075
+i 1054
+i 1077
+i 1076
+i 1472
+i 1473
+i 1494
+i 1471
+i 1472
+i 1494
+i 1062
+i 1063
+i 1085
+i 1481
+i 1503
+i 1502
+i 1056
+i 1078
+i 1077
+i 1056
+i 1079
+i 1078
+i 1474
+i 1475
+i 1496
+i 1473
+i 1474
+i 1496
+i 1063
+i 1064
+i 1085
+i 1481
+i 1504
+i 1503
+i 1064
+i 1065
+i 1087
+i 1483
+i 1505
+i 1504
+i 1058
+i 1080
+i 1079
+i 1058
+i 1081
+i 1080
+i 1476
+i 1477
+i 1498
+i 1475
+i 1476
+i 1498
+i 1984
+i 1994
+i 1993
+i 1060
+i 1082
+i 1081
+i 1060
+i 1083
+i 1082
+i 1478
+i 1479
+i 1500
+i 1477
+i 1478
+i 1500
+i 1062
+i 1084
+i 1083
+i 1062
+i 1085
+i 1084
+i 1479
+i 1480
+i 1502
+i 1480
+i 1481
+i 1502
+i 1064
+i 1086
+i 1085
+i 1064
+i 1087
+i 1086
+i 1481
+i 1482
+i 1504
+i 1482
+i 1483
+i 1504
+i 1993
+i 1994
+i 2002
+i 2048
+i 2057
+i 2056
+i 2542
+i 2543
+i 2552
+i 2056
+i 2057
+i 2066
+i 2534
+i 2543
+i 2542
+i 2479
+i 2480
+i 2488
+i 1085
+i 1086
+i 1108
+i 1086
+i 1087
+i 1108
+i 1460
+i 1482
+i 1481
+i 1460
+i 1483
+i 1482
+i 1083
+i 1084
+i 1106
+i 1084
+i 1085
+i 1106
+i 1458
+i 1480
+i 1479
+i 1458
+i 1481
+i 1480
+i 1081
+i 1082
+i 1104
+i 1082
+i 1083
+i 1104
+i 1456
+i 1479
+i 1478
+i 1456
+i 1478
+i 1477
+i 2470
+i 2480
+i 2479
+i 1079
+i 1080
+i 1102
+i 1080
+i 1081
+i 1102
+i 1454
+i 1477
+i 1476
+i 1454
+i 1476
+i 1475
+i 1087
+i 1109
+i 1108
+i 1460
+i 1461
+i 1483
+i 1085
+i 1108
+i 1107
+i 1459
+i 1460
+i 1481
+i 1077
+i 1078
+i 1100
+i 1078
+i 1079
+i 1100
+i 1452
+i 1475
+i 1474
+i 1452
+i 1474
+i 1473
+i 1085
+i 1107
+i 1106
+i 1458
+i 1459
+i 1481
+i 1075
+i 1076
+i 1098
+i 1076
+i 1077
+i 1098
+i 1450
+i 1473
+i 1472
+i 1450
+i 1472
+i 1471
+i 2516
+i 2525
+i 2524
+i 1083
+i 1106
+i 1105
+i 1457
+i 1458
+i 1479
+i 2524
+i 2525
+i 2534
+i 1073
+i 1074
+i 1096
+i 1074
+i 1075
+i 1096
+i 1448
+i 1471
+i 1470
+i 1448
+i 1470
+i 1469
+i 1083
+i 1105
+i 1104
+i 1456
+i 1457
+i 1479
+i 1081
+i 1104
+i 1103
+i 1455
+i 1456
+i 1477
+i 1071
+i 1072
+i 1094
+i 1072
+i 1073
+i 1094
+i 1446
+i 1469
+i 1468
+i 1446
+i 1468
+i 1467
+i 1081
+i 1103
+i 1102
+i 1454
+i 1455
+i 1477
+i 2002
+i 2012
+i 2011
+i 1069
+i 1070
+i 1092
+i 1070
+i 1071
+i 1092
+i 1444
+i 1467
+i 1466
+i 1444
+i 1466
+i 1465
+i 1079
+i 1102
+i 1101
+i 1453
+i 1454
+i 1475
+i 2066
+i 2075
+i 2074
+i 1079
+i 1101
+i 1100
+i 1452
+i 1453
+i 1475
+i 1067
+i 1068
+i 1090
+i 1068
+i 1069
+i 1090
+i 1442
+i 1465
+i 1464
+i 1442
+i 1464
+i 1463
+i 1077
+i 1100
+i 1099
+i 1451
+i 1452
+i 1473
+i 2011
+i 2012
+i 2020
+i 1077
+i 1099
+i 1098
+i 1450
+i 1451
+i 1473
+i 666
+i 667
+i 676
+i 666
+i 676
+i 675
+i 667
+i 668
+i 676
+i 675
+i 676
+i 684
+i 933
+i 934
+i 943
+i 934
+i 935
+i 943
+i 935
+i 944
+i 943
+i 943
+i 944
+i 953
+i 1066
+i 1067
+i 1088
+i 1440
+i 1463
+i 1462
+i 2020
+i 2030
+i 2029
+i 1075
+i 1098
+i 1097
+i 1449
+i 1450
+i 1471
+i 1075
+i 1097
+i 1096
+i 1448
+i 1449
+i 1471
+i 2488
+i 2489
+i 2498
+i 1073
+i 1096
+i 1095
+i 1447
+i 1448
+i 1469
+i 1073
+i 1095
+i 1094
+i 1446
+i 1447
+i 1469
+i 2461
+i 2462
+i 2470
+i 2029
+i 2030
+i 2038
+i 1876
+i 1885
+i 1884
+i 1894
+i 1903
+i 1902
+i 1071
+i 1094
+i 1093
+i 1445
+i 1446
+i 1467
+i 522
+i 523
+i 532
+i 522
+i 532
+i 531
+i 523
+i 524
+i 532
+i 531
+i 532
+i 540
+i 789
+i 790
+i 799
+i 790
+i 791
+i 799
+i 791
+i 800
+i 799
+i 799
+i 800
+i 809
+i 1884
+i 1885
+i 1894
+i 1071
+i 1093
+i 1092
+i 1444
+i 1445
+i 1467
+i 1902
+i 1903
+i 1912
+i 2552
+i 2562
+i 2561
+i 2452
+i 2462
+i 2461
+i 1069
+i 1092
+i 1091
+i 1443
+i 1444
+i 1465
+i 2038
+i 2048
+i 2047
+i 1069
+i 1091
+i 1090
+i 1442
+i 1443
+i 1465
+i 1858
+i 1867
+i 1866
+i 1930
+i 1939
+i 1938
+i 2498
+i 2507
+i 2506
+i 1866
+i 1867
+i 1876
+i 1067
+i 1090
+i 1089
+i 1441
+i 1442
+i 1463
+i 2480
+i 2489
+i 2488
+i 1948
+i 1957
+i 1956
+i 1938
+i 1939
+i 1948
+i 2506
+i 2507
+i 2516
+i 1067
+i 1089
+i 1088
+i 1440
+i 1441
+i 1463
+i 2047
+i 2048
+i 2056
+i 1956
+i 1957
+i 1966
+i 1912
+i 1921
+i 1920
+i 1920
+i 1921
+i 1930
+i 1984
+i 1993
+i 1992
+i 2543
+i 2544
+i 2552
+i 2470
+i 2471
+i 2480
+i 2534
+i 2544
+i 2543
+i 1992
+i 1993
+i 2002
+i 2056
+i 2066
+i 2065
+i 2002
+i 2011
+i 2010
+i 2443
+i 2444
+i 2452
+i 2434
+i 2444
+i 2443
+i 1966
+i 1975
+i 1974
+i 2010
+i 2011
+i 2020
+i 1840
+i 1849
+i 1848
+i 1848
+i 1849
+i 1858
+i 2065
+i 2066
+i 2074
+i 668
+i 669
+i 678
+i 669
+i 670
+i 678
+i 931
+i 932
+i 941
+i 932
+i 933
+i 941
+i 2552
+i 2553
+i 2562
+i 1974
+i 1975
+i 1984
+i 668
+i 677
+i 676
+i 933
+i 943
+i 942
+i 2462
+i 2471
+i 2470
+i 2534
+i 2535
+i 2544
+i 2544
+i 2553
+i 2552
+i 676
+i 685
+i 684
+i 943
+i 953
+i 952
+i 1929
+i 1930
+i 1938
+i 2020
+i 2029
+i 2028
+i 2516
+i 2517
+i 2526
+i 1947
+i 1948
+i 1956
+i 2516
+i 2526
+i 2525
+i 2525
+i 2526
+i 2534
+i 2425
+i 2426
+i 2434
+i 953
+i 962
+i 961
+i 961
+i 962
+i 971
+i 684
+i 694
+i 693
+i 693
+i 694
+i 702
+i 2028
+i 2029
+i 2038
+i 1938
+i 1948
+i 1947
+i 1956
+i 1966
+i 1965
+i 2416
+i 2426
+i 2425
+i 1920
+i 1930
+i 1929
+i 2452
+i 2453
+i 2462
+i 1902
+i 1912
+i 1911
+i 2490
+i 2499
+i 2498
+i 2407
+i 2408
+i 2416
+i 524
+i 525
+i 534
+i 525
+i 526
+i 534
+i 787
+i 788
+i 797
+i 788
+i 789
+i 797
+i 2398
+i 2408
+i 2407
+i 2526
+i 2535
+i 2534
+i 2498
+i 2499
+i 2508
+i 540
+i 550
+i 549
+i 549
+i 550
+i 558
+i 809
+i 818
+i 817
+i 817
+i 818
+i 827
+i 1983
+i 1984
+i 1992
+i 532
+i 541
+i 540
+i 799
+i 809
+i 808
+i 1965
+i 1966
+i 1974
+i 524
+i 533
+i 532
+i 789
+i 799
+i 798
+i 2554
+i 2563
+i 2562
+i 929
+i 930
+i 939
+i 930
+i 931
+i 939
+i 670
+i 671
+i 680
+i 671
+i 672
+i 680
+i 2489
+i 2490
+i 2498
+i 2508
+i 2517
+i 2516
+i 1911
+i 1912
+i 1920
+i 2536
+i 2545
+i 2544
+i 2001
+i 2002
+i 2010
+i 2544
+i 2545
+i 2554
+i 2517
+i 2518
+i 2526
+i 2444
+i 2453
+i 2452
+i 1893
+i 1894
+i 1902
+i 1875
+i 1876
+i 1884
+i 1992
+i 2002
+i 2001
+i 1884
+i 1894
+i 1893
+i 2535
+i 2536
+i 2544
+i 2389
+i 2390
+i 2398
+i 668
+i 678
+i 677
+i 933
+i 942
+i 941
+i 2553
+i 2554
+i 2562
+i 2480
+i 2490
+i 2489
+i 2434
+i 2435
+i 2444
+i 2380
+i 2390
+i 2389
+i 2471
+i 2472
+i 2480
+i 927
+i 928
+i 937
+i 928
+i 929
+i 937
+i 672
+i 673
+i 682
+i 673
+i 674
+i 682
+i 1866
+i 1876
+i 1875
+i 2544
+i 2554
+i 2553
+i 2416
+i 2417
+i 2426
+i 1974
+i 1984
+i 1983
+i 2490
+i 2500
+i 2499
+i 2408
+i 2417
+i 2416
+i 2498
+i 2508
+i 2507
+i 2472
+i 2481
+i 2480
+i 2508
+i 2518
+i 2517
+i 2499
+i 2500
+i 2508
+i 2507
+i 2508
+i 2516
+i 2371
+i 2372
+i 2380
+i 2480
+i 2481
+i 2490
+i 2362
+i 2372
+i 2371
+i 2028
+i 2038
+i 2037
+i 2426
+i 2435
+i 2434
+i 2038
+i 2047
+i 2046
+i 2536
+i 2546
+i 2545
+i 2462
+i 2472
+i 2471
+i 2526
+i 2536
+i 2535
+i 952
+i 953
+i 961
+i 684
+i 685
+i 694
+i 2010
+i 2020
+i 2019
+i 2545
+i 2546
+i 2554
+i 1857
+i 1858
+i 1866
+i 2046
+i 2047
+i 2056
+i 2518
+i 2527
+i 2526
+i 1928
+i 1929
+i 1938
+i 1956
+i 1965
+i 1964
+i 1946
+i 1947
+i 1956
+i 526
+i 527
+i 536
+i 527
+i 528
+i 536
+i 785
+i 786
+i 795
+i 786
+i 787
+i 795
+i 2554
+i 2564
+i 2563
+i 2019
+i 2020
+i 2028
+i 1938
+i 1947
+i 1946
+i 2353
+i 2354
+i 2362
+i 2344
+i 2354
+i 2353
+i 2335
+i 2336
+i 2344
+i 931
+i 941
+i 940
+i 670
+i 679
+i 678
+i 2326
+i 2336
+i 2335
+i 1920
+i 1929
+i 1928
+i 971
+i 980
+i 979
+i 979
+i 980
+i 989
+i 702
+i 712
+i 711
+i 711
+i 712
+i 720
+i 2398
+i 2399
+i 2408
+i 1964
+i 1965
+i 1974
+i 2526
+i 2527
+i 2536
+i 558
+i 568
+i 567
+i 567
+i 568
+i 576
+i 827
+i 836
+i 835
+i 835
+i 836
+i 845
+i 2000
+i 2010
+i 2009
+i 540
+i 541
+i 550
+i 524
+i 534
+i 533
+i 789
+i 798
+i 797
+i 808
+i 809
+i 817
+i 1848
+i 1858
+i 1857
+i 2046
+i 2056
+i 2055
+i 2453
+i 2454
+i 2462
+i 2390
+i 2399
+i 2398
+i 1839
+i 1840
+i 1848
+i 528
+i 529
+i 538
+i 529
+i 530
+i 538
+i 783
+i 784
+i 793
+i 784
+i 785
+i 793
+i 1982
+i 1983
+i 1992
+i 1982
+i 1992
+i 1991
+i 2037
+i 2038
+i 2046
+i 676
+i 677
+i 686
+i 942
+i 943
+i 951
+i 2472
+i 2482
+i 2481
+i 2481
+i 2482
+i 2490
+i 676
+i 686
+i 685
+i 943
+i 952
+i 951
+i 2462
+i 2463
+i 2472
+i 2027
+i 2028
+i 2036
+i 2009
+i 2010
+i 2018
+i 2444
+i 2454
+i 2453
+i 2380
+i 2381
+i 2390
+i 2490
+i 2491
+i 2500
+i 931
+i 940
+i 939
+i 670
+i 680
+i 679
+i 2500
+i 2509
+i 2508
+i 2508
+i 2509
+i 2518
+i 1991
+i 1992
+i 2000
+i 2000
+i 2009
+i 2008
+i 2000
+i 2001
+i 2010
+i 2046
+i 2055
+i 2054
+i 2056
+i 2065
+i 2064
+i 1992
+i 2001
+i 2000
+i 1902
+i 1911
+i 1910
+i 1955
+i 1956
+i 1964
+i 2028
+i 2037
+i 2036
+i 1974
+i 1983
+i 1982
+i 2435
+i 2436
+i 2444
+i 1946
+i 1956
+i 1955
+i 2372
+i 2381
+i 2380
+i 2454
+i 2463
+i 2462
+i 2064
+i 2065
+i 2074
+i 2417
+i 2418
+i 2426
+i 2536
+i 2537
+i 2546
+i 2408
+i 2418
+i 2417
+i 1910
+i 1911
+i 1920
+i 2055
+i 2056
+i 2064
+i 1964
+i 1974
+i 1973
+i 2026
+i 2027
+i 2036
+i 961
+i 971
+i 970
+i 694
+i 703
+i 702
+i 2008
+i 2009
+i 2018
+i 2018
+i 2028
+i 2027
+i 2518
+i 2528
+i 2527
+i 1982
+i 1991
+i 1990
+i 2426
+i 2436
+i 2435
+i 929
+i 939
+i 938
+i 672
+i 681
+i 680
+i 576
+i 586
+i 585
+i 585
+i 586
+i 594
+i 845
+i 854
+i 853
+i 853
+i 854
+i 863
+i 677
+i 678
+i 686
+i 941
+i 942
+i 951
+i 2482
+i 2491
+i 2490
+i 989
+i 998
+i 997
+i 997
+i 998
+i 1007
+i 720
+i 730
+i 729
+i 729
+i 730
+i 738
+i 526
+i 535
+i 534
+i 787
+i 797
+i 796
+i 1928
+i 1938
+i 1937
+i 1937
+i 1938
+i 1946
+i 2362
+i 2363
+i 2372
+i 1973
+i 1974
+i 1982
+i 2527
+i 2528
+i 2536
+i 550
+i 559
+i 558
+i 2472
+i 2473
+i 2482
+i 2054
+i 2055
+i 2064
+i 817
+i 827
+i 826
+i 1990
+i 1991
+i 2000
+i 1892
+i 1893
+i 1902
+i 532
+i 542
+i 541
+i 799
+i 808
+i 807
+i 532
+i 533
+i 542
+i 798
+i 799
+i 807
+i 929
+i 938
+i 937
+i 672
+i 682
+i 681
+i 2546
+i 2555
+i 2554
+i 1884
+i 1893
+i 1892
+i 2518
+i 2519
+i 2528
+i 2036
+i 2037
+i 2046
+i 2018
+i 2027
+i 2026
+i 2045
+i 2046
+i 2054
+i 2010
+i 2019
+i 2018
+i 2554
+i 2555
+i 2564
+i 2463
+i 2464
+i 2472
+i 2044
+i 2054
+i 2053
+i 2064
+i 2074
+i 2073
+i 951
+i 952
+i 961
+i 685
+i 686
+i 694
+i 927
+i 937
+i 936
+i 674
+i 683
+i 682
+i 2444
+i 2445
+i 2454
+i 2354
+i 2363
+i 2362
+i 2018
+i 2019
+i 2028
+i 1919
+i 1920
+i 1928
+i 2344
+i 2345
+i 2354
+i 2436
+i 2445
+i 2444
+i 2336
+i 2345
+i 2344
+i 1025
+i 1034
+i 1033
+i 1033
+i 1034
+i 1043
+i 756
+i 766
+i 765
+i 765
+i 766
+i 774
+i 2399
+i 2400
+i 2408
+i 1007
+i 1016
+i 1015
+i 1015
+i 1016
+i 1025
+i 738
+i 748
+i 747
+i 747
+i 748
+i 756
+i 2026
+i 2036
+i 2035
+i 2454
+i 2464
+i 2463
+i 1964
+i 1973
+i 1972
+i 2464
+i 2473
+i 2472
+i 2528
+i 2537
+i 2536
+i 1874
+i 1875
+i 1884
+i 863
+i 872
+i 871
+i 871
+i 872
+i 881
+i 594
+i 604
+i 603
+i 603
+i 604
+i 612
+i 2390
+i 2400
+i 2399
+i 2044
+i 2045
+i 2054
+i 2500
+i 2501
+i 2510
+i 2036
+i 2046
+i 2045
+i 1981
+i 1982
+i 1990
+i 526
+i 536
+i 535
+i 787
+i 796
+i 795
+i 917
+i 926
+i 925
+i 648
+i 658
+i 657
+i 2510
+i 2519
+i 2518
+i 1963
+i 1964
+i 1972
+i 1866
+i 1875
+i 1874
+i 2500
+i 2510
+i 2509
+i 2509
+i 2510
+i 2518
+i 1901
+i 1902
+i 1910
+i 2326
+i 2327
+i 2336
+i 970
+i 971
+i 979
+i 702
+i 703
+i 712
+i 2492
+i 2501
+i 2500
+i 1972
+i 1973
+i 1982
+i 1910
+i 1920
+i 1919
+i 2454
+i 2455
+i 2464
+i 1999
+i 2000
+i 2008
+i 1954
+i 1955
+i 1964
+i 2491
+i 2492
+i 2500
+i 1892
+i 1902
+i 1901
+i 1946
+i 1955
+i 1954
+i 558
+i 559
+i 568
+i 826
+i 827
+i 835
+i 2064
+i 2073
+i 2072
+i 2426
+i 2427
+i 2436
+i 2569
+i 2578
+i 2577
+i 2053
+i 2054
+i 2062
+i 541
+i 542
+i 550
+i 2418
+i 2427
+i 2426
+i 533
+i 534
+i 542
+i 797
+i 798
+i 807
+i 807
+i 808
+i 817
+i 881
+i 890
+i 889
+i 889
+i 890
+i 899
+i 612
+i 622
+i 621
+i 621
+i 622
+i 630
+i 1954
+i 1964
+i 1963
+i 2036
+i 2045
+i 2044
+i 2035
+i 2036
+i 2044
+i 1990
+i 2000
+i 1999
+i 2569
+i 2579
+i 2578
+i 1945
+i 1946
+i 1954
+i 1972
+i 1982
+i 1981
+i 899
+i 908
+i 907
+i 907
+i 908
+i 917
+i 630
+i 640
+i 639
+i 639
+i 640
+i 648
+i 528
+i 537
+i 536
+i 785
+i 795
+i 794
+i 2008
+i 2018
+i 2017
+i 2017
+i 2018
+i 2026
+i 2044
+i 2053
+i 2052
+i 2577
+i 2578
+i 2587
+i 2381
+i 2382
+i 2390
+i 2482
+i 2492
+i 2491
+i 2408
+i 2409
+i 2418
+i 941
+i 951
+i 950
+i 678
+i 687
+i 686
+i 1883
+i 1884
+i 1892
+i 2578
+i 2579
+i 2587
+i 2054
+i 2064
+i 2063
+i 2026
+i 2035
+i 2034
+i 2372
+i 2382
+i 2381
+i 2482
+i 2483
+i 2492
+i 2446
+i 2455
+i 2454
+i 528
+i 538
+i 537
+i 785
+i 794
+i 793
+i 1856
+i 1857
+i 1866
+i 2445
+i 2446
+i 2454
+i 2400
+i 2409
+i 2408
+i 2436
+i 2446
+i 2445
+i 940
+i 941
+i 949
+i 678
+i 679
+i 688
+i 979
+i 989
+i 988
+i 712
+i 721
+i 720
+i 530
+i 539
+i 538
+i 783
+i 793
+i 792
+i 2436
+i 2437
+i 2446
+i 568
+i 577
+i 576
+i 835
+i 845
+i 844
+i 1936
+i 1946
+i 1945
+i 2025
+i 2026
+i 2034
+i 1874
+i 1884
+i 1883
+i 1928
+i 1937
+i 1936
+i 1936
+i 1937
+i 1946
+i 2062
+i 2072
+i 2071
+i 2587
+i 2597
+i 2596
+i 951
+i 961
+i 960
+i 686
+i 695
+i 694
+i 2007
+i 2008
+i 2016
+i 1848
+i 1857
+i 1856
+i 2063
+i 2064
+i 2072
+i 2587
+i 2596
+i 2595
+i 1927
+i 1928
+i 1936
+i 2474
+i 2483
+i 2482
+i 2473
+i 2474
+i 2482
+i 2052
+i 2053
+i 2062
+i 1865
+i 1866
+i 1874
+i 2054
+i 2063
+i 2062
+i 2034
+i 2035
+i 2044
+i 1998
+i 2008
+i 2007
+i 2390
+i 2391
+i 2400
+i 939
+i 940
+i 949
+i 679
+i 680
+i 688
+i 2363
+i 2364
+i 2372
+i 1918
+i 1919
+i 1928
+i 1918
+i 1928
+i 1927
+i 2016
+i 2026
+i 2025
+i 2008
+i 2017
+i 2016
+i 2428
+i 2437
+i 2436
+i 2016
+i 2017
+i 2026
+i 2596
+i 2597
+i 2605
+i 1998
+i 1999
+i 2008
+i 2464
+i 2474
+i 2473
+i 2354
+i 2364
+i 2363
+i 2595
+i 2596
+i 2605
+i 1838
+i 1839
+i 1848
+i 1980
+i 1981
+i 1990
+i 2418
+i 2419
+i 2428
+i 576
+i 577
+i 586
+i 844
+i 845
+i 853
+i 2062
+i 2071
+i 2070
+i 941
+i 950
+i 949
+i 678
+i 688
+i 687
+i 2062
+i 2063
+i 2072
+i 988
+i 989
+i 997
+i 720
+i 721
+i 730
+i 2043
+i 2044
+i 2052
+i 2455
+i 2456
+i 2464
+i 1856
+i 1866
+i 1865
+i 2427
+i 2428
+i 2436
+i 1989
+i 1990
+i 1998
+i 2418
+i 2428
+i 2427
+i 2382
+i 2391
+i 2390
+i 534
+i 543
+i 542
+i 1990
+i 1999
+i 1998
+i 797
+i 807
+i 806
+i 1980
+i 1990
+i 1989
+i 1910
+i 1919
+i 1918
+i 542
+i 551
+i 550
+i 807
+i 817
+i 816
+i 2372
+i 2373
+i 2382
+i 2464
+i 2465
+i 2474
+i 2034
+i 2044
+i 2043
+i 2410
+i 2419
+i 2418
+i 1972
+i 1981
+i 1980
+i 2456
+i 2465
+i 2464
+i 961
+i 970
+i 969
+i 694
+i 704
+i 703
+i 2345
+i 2346
+i 2354
+i 2605
+i 2615
+i 2614
+i 2336
+i 2346
+i 2345
+i 1900
+i 1901
+i 1910
+i 2605
+i 2614
+i 2613
+i 1909
+i 1910
+i 1918
+i 1962
+i 1963
+i 1972
+i 586
+i 595
+i 594
+i 853
+i 863
+i 862
+i 1847
+i 1848
+i 1856
+i 2364
+i 2373
+i 2372
+i 534
+i 535
+i 544
+i 796
+i 797
+i 805
+i 938
+i 939
+i 947
+i 680
+i 681
+i 690
+i 997
+i 1007
+i 1006
+i 730
+i 739
+i 738
+i 1892
+i 1901
+i 1900
+i 2446
+i 2456
+i 2455
+i 1971
+i 1972
+i 1980
+i 2409
+i 2410
+i 2418
+i 2568
+i 2569
+i 2577
+i 2614
+i 2615
+i 2623
+i 2613
+i 2614
+i 2623
+i 1954
+i 1963
+i 1962
+i 1900
+i 1910
+i 1909
+i 937
+i 938
+i 947
+i 681
+i 682
+i 690
+i 2569
+i 2570
+i 2579
+i 550
+i 560
+i 559
+i 817
+i 826
+i 825
+i 2400
+i 2410
+i 2409
+i 960
+i 961
+i 969
+i 694
+i 695
+i 704
+i 2623
+i 2633
+i 2632
+i 1838
+i 1848
+i 1847
+i 1006
+i 1007
+i 1015
+i 738
+i 739
+i 748
+i 1962
+i 1972
+i 1971
+i 2354
+i 2355
+i 2364
+i 1024
+i 1025
+i 1033
+i 756
+i 757
+i 766
+i 1015
+i 1025
+i 1024
+i 748
+i 757
+i 756
+i 950
+i 951
+i 959
+i 686
+i 687
+i 696
+i 2623
+i 2632
+i 2631
+i 1944
+i 1945
+i 1954
+i 2577
+i 2587
+i 2586
+i 862
+i 863
+i 871
+i 594
+i 595
+i 604
+i 2400
+i 2401
+i 2410
+i 535
+i 536
+i 544
+i 795
+i 796
+i 805
+i 936
+i 937
+i 945
+i 682
+i 683
+i 692
+i 2632
+i 2633
+i 2641
+i 1882
+i 1883
+i 1892
+i 2586
+i 2587
+i 2595
+i 969
+i 970
+i 979
+i 703
+i 704
+i 712
+i 939
+i 949
+i 948
+i 680
+i 689
+i 688
+i 2631
+i 2632
+i 2641
+i 951
+i 960
+i 959
+i 686
+i 696
+i 695
+i 2579
+i 2588
+i 2587
+i 2587
+i 2588
+i 2597
+i 2327
+i 2328
+i 2336
+i 1033
+i 1043
+i 1042
+i 766
+i 775
+i 774
+i 2052
+i 2062
+i 2061
+i 2437
+i 2438
+i 2446
+i 534
+i 544
+i 543
+i 797
+i 806
+i 805
+i 2061
+i 2062
+i 2070
+i 2392
+i 2401
+i 2400
+i 2346
+i 2355
+i 2354
+i 1891
+i 1892
+i 1900
+i 2446
+i 2447
+i 2456
+i 871
+i 881
+i 880
+i 604
+i 613
+i 612
+i 559
+i 560
+i 568
+i 2391
+i 2392
+i 2400
+i 2641
+i 2650
+i 2649
+i 1874
+i 1883
+i 1882
+i 1936
+i 1945
+i 1944
+i 825
+i 826
+i 835
+i 550
+i 551
+i 560
+i 816
+i 817
+i 825
+i 1953
+i 1954
+i 1962
+i 2641
+i 2651
+i 2650
+i 1944
+i 1954
+i 1953
+i 2597
+i 2606
+i 2605
+i 1882
+i 1892
+i 1891
+i 916
+i 917
+i 925
+i 648
+i 649
+i 658
+i 2428
+i 2438
+i 2437
+i 2595
+i 2605
+i 2604
+i 2605
+i 2606
+i 2615
+i 2336
+i 2337
+i 2346
+i 939
+i 948
+i 947
+i 680
+i 690
+i 689
+i 2604
+i 2605
+i 2613
+i 880
+i 881
+i 889
+i 612
+i 613
+i 622
+i 2382
+i 2392
+i 2391
+i 2649
+i 2650
+i 2659
+i 949
+i 950
+i 959
+i 687
+i 688
+i 696
+i 2650
+i 2651
+i 2659
+i 2438
+i 2447
+i 2446
+i 907
+i 917
+i 916
+i 640
+i 649
+i 648
+i 1864
+i 1865
+i 1874
+i 542
+i 543
+i 552
+i 806
+i 807
+i 815
+i 889
+i 899
+i 898
+i 622
+i 631
+i 630
+i 542
+i 552
+i 551
+i 807
+i 816
+i 815
+i 2373
+i 2374
+i 2382
+i 2613
+i 2623
+i 2622
+i 898
+i 899
+i 907
+i 630
+i 631
+i 640
+i 2615
+i 2624
+i 2623
+i 2622
+i 2623
+i 2631
+i 2328
+i 2337
+i 2336
+i 536
+i 537
+i 546
+i 794
+i 795
+i 803
+i 1926
+i 1927
+i 1936
+i 2623
+i 2624
+i 2633
+i 2659
+i 2669
+i 2668
+i 2659
+i 2668
+i 2667
+i 1935
+i 1936
+i 1944
+i 937
+i 947
+i 946
+i 682
+i 691
+i 690
+i 2364
+i 2374
+i 2373
+i 2382
+i 2383
+i 2392
+i 1856
+i 1865
+i 1864
+i 1873
+i 1874
+i 1882
+i 1918
+i 1927
+i 1926
+i 2419
+i 2420
+i 2428
+i 537
+i 538
+i 546
+i 793
+i 794
+i 803
+i 2668
+i 2669
+i 2677
+i 959
+i 960
+i 969
+i 695
+i 696
+i 704
+i 2374
+i 2383
+i 2382
+i 937
+i 946
+i 945
+i 682
+i 692
+i 691
+i 2631
+i 2641
+i 2640
+i 2633
+i 2642
+i 2641
+i 2667
+i 2668
+i 2677
+i 2640
+i 2641
+i 2649
+i 2428
+i 2429
+i 2438
+i 2641
+i 2642
+i 2651
+i 536
+i 545
+i 544
+i 795
+i 805
+i 804
+i 2410
+i 2420
+i 2419
+i 1864
+i 1874
+i 1873
+i 538
+i 539
+i 548
+i 792
+i 793
+i 801
+i 1926
+i 1936
+i 1935
+i 1846
+i 1847
+i 1856
+i 969
+i 979
+i 978
+i 704
+i 713
+i 712
+i 2355
+i 2356
+i 2364
+i 2677
+i 2687
+i 2686
+i 2677
+i 2686
+i 2685
+i 543
+i 544
+i 552
+i 805
+i 806
+i 815
+i 2649
+i 2659
+i 2658
+i 979
+i 988
+i 987
+i 712
+i 722
+i 721
+i 568
+i 578
+i 577
+i 835
+i 844
+i 843
+i 2420
+i 2429
+i 2428
+i 2651
+i 2660
+i 2659
+i 551
+i 552
+i 560
+i 815
+i 816
+i 825
+i 2658
+i 2659
+i 2667
+i 560
+i 569
+i 568
+i 825
+i 835
+i 834
+i 2659
+i 2660
+i 2669
+i 2686
+i 2687
+i 2695
+i 2685
+i 2686
+i 2695
+i 1908
+i 1909
+i 1918
+i 2364
+i 2365
+i 2374
+i 1838
+i 1847
+i 1846
+i 2346
+i 2356
+i 2355
+i 536
+i 546
+i 545
+i 795
+i 804
+i 803
+i 949
+i 959
+i 958
+i 688
+i 697
+i 696
+i 1917
+i 1918
+i 1926
+i 2669
+i 2678
+i 2677
+i 1900
+i 1909
+i 1908
+i 2667
+i 2677
+i 2676
+i 2695
+i 2704
+i 2703
+i 2695
+i 2705
+i 2704
+i 577
+i 578
+i 586
+i 2677
+i 2678
+i 2687
+i 843
+i 844
+i 853
+i 2676
+i 2677
+i 2685
+i 948
+i 949
+i 957
+i 688
+i 689
+i 698
+i 987
+i 988
+i 997
+i 721
+i 722
+i 730
+i 2356
+i 2365
+i 2364
+i 2401
+i 2402
+i 2410
+i 1855
+i 1856
+i 1864
+i 2703
+i 2704
+i 2713
+i 2410
+i 2411
+i 2420
+i 2704
+i 2705
+i 2713
+i 1908
+i 1918
+i 1917
+i 2337
+i 2338
+i 2346
+i 2687
+i 2696
+i 2695
+i 2392
+i 2402
+i 2401
+i 2685
+i 2695
+i 2694
+i 538
+i 547
+i 546
+i 793
+i 803
+i 802
+i 2694
+i 2695
+i 2703
+i 959
+i 969
+i 968
+i 696
+i 705
+i 704
+i 2695
+i 2696
+i 2705
+i 1846
+i 1856
+i 1855
+i 978
+i 979
+i 987
+i 712
+i 713
+i 722
+i 947
+i 948
+i 957
+i 689
+i 690
+i 698
+i 568
+i 569
+i 578
+i 538
+i 548
+i 547
+i 793
+i 802
+i 801
+i 834
+i 835
+i 843
+i 2713
+i 2722
+i 2721
+i 2713
+i 2723
+i 2722
+i 2577
+i 2586
+i 2585
+i 1890
+i 1891
+i 1900
+i 2567
+i 2568
+i 2577
+i 2402
+i 2411
+i 2410
+i 2328
+i 2338
+i 2337
+i 2703
+i 2713
+i 2712
+i 2721
+i 2722
+i 2731
+i 2722
+i 2723
+i 2731
+i 2585
+i 2586
+i 2595
+i 949
+i 958
+i 957
+i 688
+i 698
+i 697
+i 1882
+i 1891
+i 1890
+i 2570
+i 2571
+i 2579
+i 2597
+i 2607
+i 2606
+i 2705
+i 2714
+i 2713
+i 544
+i 553
+i 552
+i 2595
+i 2604
+i 2603
+i 805
+i 815
+i 814
+i 2579
+i 2589
+i 2588
+i 1899
+i 1900
+i 1908
+i 2588
+i 2589
+i 2597
+i 2346
+i 2347
+i 2356
+i 2603
+i 2604
+i 2613
+i 2606
+i 2607
+i 2615
+i 2613
+i 2622
+i 2621
+i 2712
+i 2713
+i 2721
+i 2615
+i 2625
+i 2624
+i 2621
+i 2622
+i 2631
+i 2713
+i 2714
+i 2723
+i 2624
+i 2625
+i 2633
+i 2631
+i 2640
+i 2639
+i 552
+i 561
+i 560
+i 815
+i 825
+i 824
+i 2639
+i 2640
+i 2649
+i 2731
+i 2741
+i 2740
+i 2731
+i 2740
+i 2739
+i 2633
+i 2643
+i 2642
+i 2740
+i 2741
+i 2749
+i 2739
+i 2740
+i 2749
+i 2338
+i 2347
+i 2346
+i 2721
+i 2731
+i 2730
+i 2392
+i 2393
+i 2402
+i 1890
+i 1900
+i 1899
+i 2642
+i 2643
+i 2651
+i 1837
+i 1838
+i 1846
+i 2649
+i 2658
+i 2657
+i 586
+i 596
+i 595
+i 853
+i 862
+i 861
+i 2723
+i 2732
+i 2731
+i 2669
+i 2679
+i 2678
+i 2651
+i 2661
+i 2660
+i 2383
+i 2384
+i 2392
+i 997
+i 1006
+i 1005
+i 730
+i 740
+i 739
+i 544
+i 545
+i 554
+i 804
+i 805
+i 813
+i 2657
+i 2658
+i 2667
+i 2667
+i 2676
+i 2675
+i 2730
+i 2731
+i 2739
+i 2660
+i 2661
+i 2669
+i 946
+i 947
+i 955
+i 690
+i 691
+i 700
+i 2739
+i 2749
+i 2748
+i 2741
+i 2750
+i 2749
+i 2731
+i 2732
+i 2741
+i 2678
+i 2679
+i 2687
+i 2749
+i 2759
+i 2758
+i 2687
+i 2697
+i 2696
+i 2675
+i 2676
+i 2685
+i 2374
+i 2384
+i 2383
+i 2749
+i 2750
+i 2759
+i 2749
+i 2758
+i 2757
+i 2748
+i 2749
+i 2757
+i 945
+i 946
+i 955
+i 691
+i 692
+i 700
+i 2685
+i 2694
+i 2693
+i 1872
+i 1873
+i 1882
+i 1005
+i 1006
+i 1015
+i 739
+i 740
+i 748
+i 861
+i 862
+i 871
+i 595
+i 596
+i 604
+i 2703
+i 2712
+i 2711
+i 2696
+i 2697
+i 2705
+i 2693
+i 2694
+i 2703
+i 1023
+i 1024
+i 1033
+i 757
+i 758
+i 766
+i 1015
+i 1024
+i 1023
+i 748
+i 758
+i 757
+i 2384
+i 2393
+i 2392
+i 969
+i 978
+i 977
+i 704
+i 714
+i 713
+i 958
+i 959
+i 967
+i 696
+i 697
+i 706
+i 2639
+i 2649
+i 2648
+i 2669
+i 2670
+i 2679
+i 2705
+i 2715
+i 2714
+i 2625
+i 2634
+i 2633
+i 2633
+i 2634
+i 2643
+i 2648
+i 2649
+i 2657
+i 2651
+i 2652
+i 2661
+i 2711
+i 2712
+i 2721
+i 2758
+i 2759
+i 2767
+i 2666
+i 2667
+i 2675
+i 2630
+i 2631
+i 2639
+i 2612
+i 2613
+i 2621
+i 2661
+i 2670
+i 2669
+i 2643
+i 2652
+i 2651
+i 578
+i 587
+i 586
+i 843
+i 853
+i 852
+i 2757
+i 2758
+i 2767
+i 2603
+i 2613
+i 2612
+i 1864
+i 1873
+i 1872
+i 2687
+i 2688
+i 2697
+i 2615
+i 2616
+i 2625
+i 544
+i 554
+i 553
+i 545
+i 546
+i 554
+i 805
+i 814
+i 813
+i 2657
+i 2667
+i 2666
+i 803
+i 804
+i 813
+i 2621
+i 2631
+i 2630
+i 2721
+i 2730
+i 2729
+i 2679
+i 2688
+i 2687
+i 2714
+i 2715
+i 2723
+i 2767
+i 2776
+i 2775
+i 947
+i 957
+i 956
+i 690
+i 699
+i 698
+i 560
+i 570
+i 569
+i 2328
+i 2329
+i 2338
+i 2607
+i 2616
+i 2615
+i 987
+i 997
+i 996
+i 722
+i 731
+i 730
+i 825
+i 834
+i 833
+i 2594
+i 2595
+i 2603
+i 2684
+i 2685
+i 2693
+i 968
+i 969
+i 977
+i 704
+i 705
+i 714
+i 2702
+i 2703
+i 2711
+i 2585
+i 2595
+i 2594
+i 2597
+i 2598
+i 2607
+i 959
+i 968
+i 967
+i 696
+i 706
+i 705
+i 2675
+i 2685
+i 2684
+i 2767
+i 2777
+i 2776
+i 1881
+i 1882
+i 1890
+i 2576
+i 2577
+i 2585
+i 2723
+i 2733
+i 2732
+i 2589
+i 2598
+i 2597
+i 2693
+i 2703
+i 2702
+i 2775
+i 2776
+i 2785
+i 2729
+i 2730
+i 2739
+i 2739
+i 2748
+i 2747
+i 2697
+i 2706
+i 2705
+i 2567
+i 2577
+i 2576
+i 2365
+i 2366
+i 2374
+i 2759
+i 2768
+i 2767
+i 2579
+i 2580
+i 2589
+i 2776
+i 2777
+i 2785
+i 2785
+i 2794
+i 2793
+i 2705
+i 2706
+i 2715
+i 1033
+i 1042
+i 1041
+i 766
+i 776
+i 775
+i 2571
+i 2580
+i 2579
+i 2766
+i 2767
+i 2775
+i 2732
+i 2733
+i 2741
+i 2741
+i 2751
+i 2750
+i 2757
+i 2767
+i 2766
+i 2767
+i 2768
+i 2777
+i 2747
+i 2748
+i 2757
+i 2750
+i 2751
+i 2759
+i 2374
+i 2375
+i 2384
+i 2793
+i 2794
+i 2803
+i 2711
+i 2721
+i 2720
+i 2720
+i 2721
+i 2729
+i 1872
+i 1882
+i 1881
+i 2785
+i 2795
+i 2794
+i 560
+i 561
+i 570
+i 824
+i 825
+i 833
+i 2715
+i 2724
+i 2723
+i 2723
+i 2724
+i 2733
+i 947
+i 956
+i 955
+i 690
+i 700
+i 699
+i 871
+i 880
+i 879
+i 604
+i 614
+i 613
+i 2356
+i 2366
+i 2365
+i 2777
+i 2786
+i 2785
+i 2366
+i 2375
+i 2374
+i 2784
+i 2785
+i 2793
+i 2794
+i 2795
+i 2803
+i 2775
+i 2785
+i 2784
+i 1854
+i 1855
+i 1864
+i 552
+i 553
+i 562
+i 814
+i 815
+i 823
+i 586
+i 587
+i 596
+i 852
+i 853
+i 861
+i 2785
+i 2786
+i 2795
+i 2729
+i 2739
+i 2738
+i 2738
+i 2739
+i 2747
+i 2759
+i 2769
+i 2768
+i 957
+i 958
+i 967
+i 697
+i 698
+i 706
+i 2733
+i 2742
+i 2741
+i 552
+i 562
+i 561
+i 815
+i 824
+i 823
+i 2741
+i 2742
+i 2751
+i 977
+i 978
+i 987
+i 713
+i 714
+i 722
+i 879
+i 880
+i 889
+i 613
+i 614
+i 622
+i 2765
+i 2766
+i 2775
+i 2757
+i 2766
+i 2765
+i 996
+i 997
+i 1005
+i 730
+i 731
+i 740
+i 2768
+i 2769
+i 2777
+i 915
+i 916
+i 925
+i 649
+i 650
+i 658
+i 2747
+i 2757
+i 2756
+i 2793
+i 2803
+i 2802
+i 2751
+i 2760
+i 2759
+i 569
+i 570
+i 578
+i 833
+i 834
+i 843
+i 546
+i 547
+i 556
+i 945
+i 955
+i 954
+i 692
+i 701
+i 700
+i 802
+i 803
+i 811
+i 1846
+i 1855
+i 1854
+i 2688
+i 2689
+i 2697
+i 2670
+i 2671
+i 2679
+i 2665
+i 2666
+i 2675
+i 2679
+i 2689
+i 2688
+i 2701
+i 2702
+i 2711
+i 2759
+i 2760
+i 2769
+i 2795
+i 2804
+i 2803
+i 2657
+i 2666
+i 2665
+i 2693
+i 2702
+i 2701
+i 2683
+i 2684
+i 2693
+i 2765
+i 2775
+i 2774
+i 2661
+i 2671
+i 2670
+i 2675
+i 2684
+i 2683
+i 2697
+i 2707
+i 2706
+i 907
+i 916
+i 915
+i 640
+i 650
+i 649
+i 547
+i 548
+i 556
+i 801
+i 802
+i 811
+i 2756
+i 2757
+i 2765
+i 2777
+i 2787
+i 2786
+i 2706
+i 2707
+i 2715
+i 2769
+i 2778
+i 2777
+i 2652
+i 2653
+i 2661
+i 2639
+i 2648
+i 2647
+i 2783
+i 2784
+i 2793
+i 2711
+i 2720
+i 2719
+i 2719
+i 2720
+i 2729
+i 2643
+i 2653
+i 2652
+i 2647
+i 2648
+i 2657
+i 2715
+i 2725
+i 2724
+i 2347
+i 2348
+i 2356
+i 2724
+i 2725
+i 2733
+i 2786
+i 2787
+i 2795
+i 2783
+i 2793
+i 2792
+i 2775
+i 2784
+i 2783
+i 2774
+i 2775
+i 2783
+i 546
+i 555
+i 554
+i 803
+i 813
+i 812
+i 2792
+i 2793
+i 2801
+i 2777
+i 2778
+i 2787
+i 889
+i 898
+i 897
+i 622
+i 632
+i 631
+i 2719
+i 2729
+i 2728
+i 2733
+i 2743
+i 2742
+i 2701
+i 2711
+i 2710
+i 2729
+i 2738
+i 2737
+i 2793
+i 2802
+i 2801
+i 897
+i 898
+i 907
+i 631
+i 632
+i 640
+i 2742
+i 2743
+i 2751
+i 2728
+i 2729
+i 2737
+i 2737
+i 2738
+i 2747
+i 1863
+i 1864
+i 1872
+i 2737
+i 2747
+i 2746
+i 2625
+i 2635
+i 2634
+i 2634
+i 2635
+i 2643
+i 2746
+i 2747
+i 2755
+i 2751
+i 2761
+i 2760
+i 1005
+i 1015
+i 1014
+i 740
+i 749
+i 748
+i 1023
+i 1033
+i 1032
+i 758
+i 767
+i 766
+i 2338
+i 2348
+i 2347
+i 2747
+i 2756
+i 2755
+i 2710
+i 2711
+i 2719
+i 1014
+i 1015
+i 1023
+i 748
+i 749
+i 758
+i 2629
+i 2630
+i 2639
+i 967
+i 968
+i 977
+i 705
+i 706
+i 714
+i 2707
+i 2716
+i 2715
+i 2725
+i 2734
+i 2733
+i 2715
+i 2716
+i 2725
+i 2787
+i 2796
+i 2795
+i 2795
+i 2805
+i 2804
+i 2621
+i 2630
+i 2629
+i 2689
+i 2698
+i 2697
+i 2765
+i 2774
+i 2773
+i 2751
+i 2752
+i 2761
+i 2760
+i 2761
+i 2769
+i 2743
+i 2752
+i 2751
+i 2733
+i 2734
+i 2743
+i 2697
+i 2698
+i 2707
+i 553
+i 554
+i 562
+i 813
+i 814
+i 823
+i 1854
+i 1864
+i 1863
+i 2769
+i 2779
+i 2778
+i 861
+i 871
+i 870
+i 596
+i 605
+i 604
+i 2692
+i 2693
+i 2701
+i 2356
+i 2357
+i 2366
+i 2683
+i 2693
+i 2692
+i 2755
+i 2756
+i 2765
+i 2783
+i 2792
+i 2791
+i 2795
+i 2796
+i 2805
+i 2679
+i 2680
+i 2689
+i 2791
+i 2792
+i 2801
+i 2665
+i 2675
+i 2674
+i 2671
+i 2680
+i 2679
+i 2778
+i 2779
+i 2787
+i 2773
+i 2774
+i 2783
+i 2764
+i 2765
+i 2773
+i 2674
+i 2675
+i 2683
+i 1032
+i 1033
+i 1041
+i 766
+i 767
+i 776
+i 2769
+i 2770
+i 2779
+i 546
+i 556
+i 555
+i 2761
+i 2770
+i 2769
+i 803
+i 812
+i 811
+i 2611
+i 2612
+i 2621
+i 2603
+i 2612
+i 2611
+i 2755
+i 2765
+i 2764
+i 1836
+i 1837
+i 1846
+i 2719
+i 2728
+i 2727
+i 2348
+i 2357
+i 2356
+i 2616
+i 2617
+i 2625
+i 561
+i 562
+i 570
+i 2737
+i 2746
+i 2745
+i 823
+i 824
+i 833
+i 2727
+i 2728
+i 2737
+i 2787
+i 2797
+i 2796
+i 2656
+i 2657
+i 2665
+i 2745
+i 2746
+i 2755
+i 2607
+i 2617
+i 2616
+i 2661
+i 2662
+i 2671
+i 2796
+i 2797
+i 2805
+i 2701
+i 2710
+i 2709
+i 957
+i 967
+i 966
+i 698
+i 707
+i 706
+i 2779
+i 2788
+i 2787
+i 2647
+i 2657
+i 2656
+i 870
+i 871
+i 879
+i 604
+i 605
+i 614
+i 2782
+i 2783
+i 2791
+i 2653
+i 2662
+i 2661
+i 2709
+i 2710
+i 2719
+i 2638
+i 2639
+i 2647
+i 2787
+i 2788
+i 2797
+i 548
+i 557
+i 556
+i 801
+i 811
+i 810
+i 2752
+i 2753
+i 2761
+i 2593
+i 2594
+i 2603
+i 2743
+i 2753
+i 2752
+i 2773
+i 2783
+i 2782
+i 2585
+i 2594
+i 2593
+i 956
+i 957
+i 965
+i 698
+i 699
+i 708
+i 2329
+i 2330
+i 2338
+i 2598
+i 2599
+i 2607
+i 2725
+i 2735
+i 2734
+i 2643
+i 2644
+i 2653
+i 2791
+i 2801
+i 2800
+i 2589
+i 2599
+i 2598
+i 2707
+i 2717
+i 2716
+i 977
+i 987
+i 986
+i 714
+i 723
+i 722
+i 2763
+i 2764
+i 2773
+i 2734
+i 2735
+i 2743
+i 2716
+i 2717
+i 2725
+i 2691
+i 2692
+i 2701
+i 2629
+i 2639
+i 2638
+i 2683
+i 2692
+i 2691
+i 2770
+i 2771
+i 2779
+i 570
+i 579
+i 578
+i 2761
+i 2771
+i 2770
+i 833
+i 843
+i 842
+i 915
+i 925
+i 924
+i 650
+i 659
+i 658
+i 1845
+i 1846
+i 1854
+i 2797
+i 2806
+i 2805
+i 2755
+i 2764
+i 2763
+i 2635
+i 2644
+i 2643
+i 2625
+i 2626
+i 2635
+i 2620
+i 2621
+i 2629
+i 2781
+i 2791
+i 2790
+i 2689
+i 2699
+i 2698
+i 2575
+i 2576
+i 2585
+i 2763
+i 2773
+i 2772
+i 578
+i 588
+i 587
+i 843
+i 852
+i 851
+i 2698
+i 2699
+i 2707
+i 955
+i 956
+i 965
+i 699
+i 700
+i 708
+i 2580
+i 2581
+i 2589
+i 2745
+i 2755
+i 2754
+i 2567
+i 2576
+i 2575
+i 2571
+i 2581
+i 2580
+i 2665
+i 2674
+i 2673
+i 879
+i 889
+i 888
+i 614
+i 623
+i 622
+i 2790
+i 2791
+i 2799
+i 2673
+i 2674
+i 2683
+i 2718
+i 2719
+i 2727
+i 2338
+i 2339
+i 2348
+i 2779
+i 2789
+i 2788
+i 987
+i 996
+i 995
+i 722
+i 732
+i 731
+i 2617
+i 2626
+i 2625
+i 2771
+i 2780
+i 2779
+i 2781
+i 2782
+i 2791
+i 2736
+i 2737
+i 2745
+i 2727
+i 2737
+i 2736
+i 2611
+i 2621
+i 2620
+i 2753
+i 2762
+i 2761
+i 2788
+i 2789
+i 2797
+i 554
+i 563
+i 562
+i 813
+i 823
+i 822
+i 2680
+i 2681
+i 2689
+i 2773
+i 2782
+i 2781
+i 2761
+i 2762
+i 2771
+i 967
+i 977
+i 976
+i 706
+i 715
+i 714
+i 2671
+i 2681
+i 2680
+i 1836
+i 1846
+i 1845
+i 2700
+i 2701
+i 2709
+i 2709
+i 2719
+i 2718
+i 2743
+i 2744
+i 2753
+i 2754
+i 2755
+i 2763
+i 957
+i 966
+i 965
+i 698
+i 708
+i 707
+i 2655
+i 2656
+i 2665
+i 2772
+i 2773
+i 2781
+i 2789
+i 2798
+i 2797
+i 2797
+i 2807
+i 2806
+i 2797
+i 2798
+i 2807
+i 2602
+i 2603
+i 2611
+i 2691
+i 2701
+i 2700
+i 2607
+i 2608
+i 2617
+i 2735
+i 2744
+i 2743
+i 2779
+i 2780
+i 2789
+i 2725
+i 2726
+i 2735
+i 888
+i 889
+i 897
+i 622
+i 623
+i 632
+i 906
+i 907
+i 915
+i 640
+i 641
+i 650
+i 2791
+i 2800
+i 2799
+i 2717
+i 2726
+i 2725
+i 2647
+i 2656
+i 2655
+i 2330
+i 2339
+i 2338
+i 2682
+i 2683
+i 2691
+i 954
+i 955
+i 963
+i 700
+i 701
+i 710
+i 2707
+i 2708
+i 2717
+i 554
+i 555
+i 564
+i 812
+i 813
+i 821
+i 2593
+i 2603
+i 2602
+i 2662
+i 2663
+i 2671
+i 2599
+i 2608
+i 2607
+i 562
+i 571
+i 570
+i 823
+i 833
+i 832
+i 897
+i 907
+i 906
+i 632
+i 641
+i 640
+i 587
+i 588
+i 596
+i 851
+i 852
+i 861
+i 2653
+i 2663
+i 2662
+i 578
+i 579
+i 588
+i 2584
+i 2585
+i 2593
+i 842
+i 843
+i 851
+i 2699
+i 2708
+i 2707
+i 2637
+i 2638
+i 2647
+i 2589
+i 2590
+i 2599
+i 2673
+i 2683
+i 2682
+i 995
+i 996
+i 1005
+i 731
+i 732
+i 740
+i 986
+i 987
+i 995
+i 722
+i 723
+i 732
+i 2689
+i 2690
+i 2699
+i 2644
+i 2645
+i 2653
+i 2629
+i 2638
+i 2637
+i 2681
+i 2690
+i 2689
+i 2664
+i 2665
+i 2673
+i 2575
+i 2585
+i 2584
+i 555
+i 556
+i 564
+i 811
+i 812
+i 821
+i 2655
+i 2665
+i 2664
+i 554
+i 564
+i 563
+i 2581
+i 2590
+i 2589
+i 813
+i 822
+i 821
+i 2635
+i 2645
+i 2644
+i 2671
+i 2672
+i 2681
+i 955
+i 965
+i 964
+i 700
+i 709
+i 708
+i 2566
+i 2567
+i 2575
+i 966
+i 967
+i 975
+i 706
+i 707
+i 716
+i 2663
+i 2672
+i 2671
+i 2571
+i 2572
+i 2581
+i 2626
+i 2627
+i 2635
+i 2619
+i 2620
+i 2629
+i 1543
+i 1566
+i 1565
+i 1785
+i 1786
+i 1807
+i 1543
+i 1565
+i 1564
+i 1784
+i 1785
+i 1807
+i 1545
+i 1567
+i 1566
+i 1786
+i 1787
+i 1809
+i 1545
+i 1568
+i 1567
+i 1787
+i 1788
+i 1809
+i 1541
+i 1564
+i 1563
+i 1783
+i 1784
+i 1805
+i 2646
+i 2647
+i 2655
+i 1547
+i 1569
+i 1568
+i 1788
+i 1789
+i 1811
+i 1541
+i 1563
+i 1562
+i 1782
+i 1783
+i 1805
+i 1547
+i 1570
+i 1569
+i 1789
+i 1790
+i 1811
+i 955
+i 964
+i 963
+i 700
+i 710
+i 709
+i 556
+i 557
+i 566
+i 810
+i 811
+i 819
+i 1544
+i 1545
+i 1566
+i 1786
+i 1809
+i 1808
+i 1543
+i 1544
+i 1566
+i 1786
+i 1808
+i 1807
+i 1542
+i 1543
+i 1564
+i 1784
+i 1807
+i 1806
+i 1545
+i 1546
+i 1568
+i 1788
+i 1810
+i 1809
+i 1549
+i 1571
+i 1570
+i 1790
+i 1791
+i 1813
+i 1539
+i 1562
+i 1561
+i 1781
+i 1782
+i 1803
+i 1546
+i 1547
+i 1568
+i 1788
+i 1811
+i 1810
+i 1541
+i 1542
+i 1564
+i 1784
+i 1806
+i 1805
+i 967
+i 976
+i 975
+i 706
+i 716
+i 715
+i 1523
+i 1524
+i 1545
+i 1809
+i 1832
+i 1831
+i 1522
+i 1523
+i 1545
+i 1809
+i 1831
+i 1830
+i 977
+i 986
+i 985
+i 714
+i 724
+i 723
+i 1521
+i 1522
+i 1543
+i 1807
+i 1830
+i 1829
+i 1524
+i 1525
+i 1547
+i 1811
+i 1833
+i 1832
+i 1539
+i 1561
+i 1560
+i 1780
+i 1781
+i 1803
+i 1522
+i 1545
+i 1544
+i 1808
+i 1809
+i 1830
+i 1522
+i 1544
+i 1543
+i 1807
+i 1808
+i 1830
+i 1524
+i 1546
+i 1545
+i 1809
+i 1810
+i 1832
+i 1520
+i 1521
+i 1543
+i 1807
+i 1829
+i 1828
+i 1540
+i 1541
+i 1562
+i 1782
+i 1805
+i 1804
+i 1547
+i 1548
+i 1570
+i 1790
+i 1812
+i 1811
+i 1525
+i 1526
+i 1547
+i 1811
+i 1834
+i 1833
+i 1524
+i 1547
+i 1546
+i 1810
+i 1811
+i 1832
+i 570
+i 580
+i 579
+i 833
+i 842
+i 841
+i 2617
+i 2627
+i 2626
+i 1548
+i 1549
+i 1570
+i 1790
+i 1813
+i 1812
+i 1520
+i 1543
+i 1542
+i 1806
+i 1807
+i 1828
+i 2611
+i 2620
+i 2619
+i 1526
+i 1527
+i 1549
+i 1813
+i 1835
+i 1834
+i 1539
+i 1540
+i 1562
+i 1782
+i 1804
+i 1803
+i 1520
+i 1542
+i 1541
+i 1805
+i 1806
+i 1828
+i 1519
+i 1520
+i 1541
+i 1805
+i 1828
+i 1827
+i 1526
+i 1548
+i 1547
+i 1811
+i 1812
+i 1834
+i 2637
+i 2647
+i 2646
+i 2653
+i 2654
+i 2663
+i 1023
+i 1032
+i 1031
+i 758
+i 768
+i 767
+i 1005
+i 1014
+i 1013
+i 740
+i 750
+i 749
+i 1526
+i 1549
+i 1548
+i 1812
+i 1813
+i 1834
+i 1013
+i 1014
+i 1023
+i 749
+i 750
+i 758
+i 1518
+i 1519
+i 1541
+i 1805
+i 1827
+i 1826
+i 1518
+i 1541
+i 1540
+i 1804
+i 1805
+i 1826
+i 1537
+i 1560
+i 1559
+i 1779
+i 1780
+i 1801
+i 976
+i 977
+i 985
+i 714
+i 715
+i 724
+i 1538
+i 1539
+i 1560
+i 1780
+i 1803
+i 1802
+i 1518
+i 1540
+i 1539
+i 1803
+i 1804
+i 1826
+i 562
+i 563
+i 572
+i 822
+i 823
+i 831
+i 1537
+i 1559
+i 1558
+i 1778
+i 1779
+i 1801
+i 1517
+i 1518
+i 1539
+i 1803
+i 1826
+i 1825
+i 1537
+i 1538
+i 1560
+i 1780
+i 1802
+i 1801
+i 2645
+i 2654
+i 2653
+i 1516
+i 1517
+i 1539
+i 1803
+i 1825
+i 1824
+i 570
+i 571
+i 580
+i 1516
+i 1539
+i 1538
+i 1802
+i 1803
+i 1824
+i 832
+i 833
+i 841
+i 861
+i 870
+i 869
+i 596
+i 606
+i 605
+i 1535
+i 1558
+i 1557
+i 1777
+i 1778
+i 1799
+i 562
+i 572
+i 571
+i 1516
+i 1538
+i 1537
+i 1801
+i 1802
+i 1824
+i 823
+i 832
+i 831
+i 1536
+i 1537
+i 1558
+i 1778
+i 1801
+i 1800
+i 1031
+i 1032
+i 1041
+i 767
+i 768
+i 776
+i 1515
+i 1516
+i 1537
+i 1801
+i 1824
+i 1823
+i 1535
+i 1557
+i 1556
+i 1776
+i 1777
+i 1799
+i 1535
+i 1536
+i 1558
+i 1778
+i 1800
+i 1799
+i 1514
+i 1515
+i 1537
+i 1801
+i 1823
+i 1822
+i 965
+i 966
+i 975
+i 707
+i 708
+i 716
+i 1514
+i 1537
+i 1536
+i 1800
+i 1801
+i 1822
+i 556
+i 565
+i 564
+i 811
+i 821
+i 820
+i 2628
+i 2629
+i 2637
+i 588
+i 597
+i 596
+i 851
+i 861
+i 860
+i 2601
+i 2602
+i 2611
+i 1514
+i 1536
+i 1535
+i 1799
+i 1800
+i 1822
+i 1534
+i 1535
+i 1556
+i 1776
+i 1799
+i 1798
+i 1533
+i 1556
+i 1555
+i 1775
+i 1776
+i 1797
+i 2608
+i 2609
+i 2617
+i 1513
+i 1514
+i 1535
+i 1799
+i 1822
+i 1821
+i 2635
+i 2636
+i 2645
+i 1533
+i 1534
+i 1556
+i 1776
+i 1798
+i 1797
+i 1533
+i 1555
+i 1554
+i 1774
+i 1775
+i 1797
+i 995
+i 1005
+i 1004
+i 732
+i 741
+i 740
+i 1512
+i 1513
+i 1535
+i 1799
+i 1821
+i 1820
+i 1512
+i 1535
+i 1534
+i 1798
+i 1799
+i 1820
+i 2593
+i 2602
+i 2601
+i 869
+i 870
+i 879
+i 605
+i 606
+i 614
+i 556
+i 566
+i 565
+i 811
+i 820
+i 819
+i 2599
+i 2609
+i 2608
+i 2619
+i 2629
+i 2628
+i 1512
+i 1534
+i 1533
+i 1797
+i 1798
+i 1820
+i 1532
+i 1533
+i 1554
+i 1774
+i 1797
+i 1796
+i 2627
+i 2636
+i 2635
+i 1511
+i 1512
+i 1533
+i 1797
+i 1820
+i 1819
+i 579
+i 580
+i 588
+i 841
+i 842
+i 851
+i 1531
+i 1554
+i 1553
+i 1773
+i 1774
+i 1795
+i 563
+i 564
+i 572
+i 821
+i 822
+i 831
+i 1531
+i 1532
+i 1554
+i 1774
+i 1796
+i 1795
+i 985
+i 986
+i 995
+i 723
+i 724
+i 732
+i 1510
+i 1511
+i 1533
+i 1797
+i 1819
+i 1818
+i 1510
+i 1533
+i 1532
+i 1796
+i 1797
+i 1818
+i 1531
+i 1553
+i 1552
+i 1772
+i 1773
+i 1795
+i 915
+i 924
+i 923
+i 650
+i 660
+i 659
+i 1510
+i 1532
+i 1531
+i 1795
+i 1796
+i 1818
+i 1004
+i 1005
+i 1013
+i 740
+i 741
+i 750
+i 1022
+i 1023
+i 1031
+i 758
+i 759
+i 768
+i 1013
+i 1023
+i 1022
+i 750
+i 759
+i 758
+i 2610
+i 2611
+i 2619
+i 860
+i 861
+i 869
+i 596
+i 597
+i 606
+i 1509
+i 1510
+i 1531
+i 1795
+i 1818
+i 1817
+i 1530
+i 1531
+i 1552
+i 1772
+i 1795
+i 1794
+i 975
+i 976
+i 985
+i 715
+i 716
+i 724
+i 2590
+i 2591
+i 2599
+i 2617
+i 2618
+i 2627
+i 2583
+i 2584
+i 2593
+i 1508
+i 1509
+i 1531
+i 1795
+i 1817
+i 1816
+i 1529
+i 1552
+i 1551
+i 1771
+i 1772
+i 1793
+i 1508
+i 1531
+i 1530
+i 1794
+i 1795
+i 1816
+i 1529
+i 1530
+i 1552
+i 1772
+i 1794
+i 1793
+i 571
+i 572
+i 580
+i 831
+i 832
+i 841
+i 2601
+i 2611
+i 2610
+i 964
+i 965
+i 973
+i 708
+i 709
+i 718
+i 879
+i 888
+i 887
+i 614
+i 624
+i 623
+i 2581
+i 2591
+i 2590
+i 2575
+i 2584
+i 2583
+i 965
+i 975
+i 974
+i 708
+i 717
+i 716
+i 1508
+i 1530
+i 1529
+i 1793
+i 1794
+i 1816
+i 1529
+i 1551
+i 1550
+i 1770
+i 1771
+i 1793
+i 2609
+i 2618
+i 2617
+i 1507
+i 1508
+i 1529
+i 1793
+i 1816
+i 1815
+i 1031
+i 1041
+i 1040
+i 768
+i 777
+i 776
+i 963
+i 964
+i 973
+i 709
+i 710
+i 718
+i 887
+i 888
+i 897
+i 623
+i 624
+i 632
+i 2592
+i 2593
+i 2601
+i 1528
+i 1529
+i 1550
+i 1770
+i 1793
+i 1792
+i 905
+i 906
+i 915
+i 641
+i 642
+i 650
+i 564
+i 573
+i 572
+i 2599
+i 2600
+i 2609
+i 821
+i 831
+i 830
+i 1506
+i 1507
+i 1529
+i 1793
+i 1815
+i 1814
+i 564
+i 565
+i 574
+i 820
+i 821
+i 829
+i 897
+i 906
+i 905
+i 632
+i 642
+i 641
+i 2565
+i 2566
+i 2575
+i 2572
+i 2573
+i 2581
+i 580
+i 589
+i 588
+i 841
+i 851
+i 850
+i 1506
+i 1529
+i 1528
+i 1792
+i 1793
+i 1814
+i 869
+i 879
+i 878
+i 606
+i 615
+i 614
+i 965
+i 974
+i 973
+i 708
+i 718
+i 717
+i 985
+i 995
+i 994
+i 724
+i 733
+i 732
+i 565
+i 566
+i 574
+i 819
+i 820
+i 829
+i 2583
+i 2593
+i 2592
+i 2591
+i 2600
+i 2599
+i 975
+i 985
+i 984
+i 716
+i 725
+i 724
+i 914
+i 915
+i 923
+i 650
+i 651
+i 660
+i 588
+i 598
+i 597
+i 851
+i 860
+i 859
+i 572
+i 581
+i 580
+i 831
+i 841
+i 840
+i 564
+i 574
+i 573
+i 821
+i 830
+i 829
+i 878
+i 879
+i 887
+i 614
+i 615
+i 624
+i 995
+i 1004
+i 1003
+i 732
+i 742
+i 741
+i 963
+i 973
+i 972
+i 710
+i 719
+i 718
+i 2581
+i 2582
+i 2591
+i 2574
+i 2575
+i 2583
+i 588
+i 589
+i 598
+i 850
+i 851
+i 859
+i 905
+i 915
+i 914
+i 642
+i 651
+i 650
+i 566
+i 575
+i 574
+i 819
+i 829
+i 828
+i 1003
+i 1004
+i 1013
+i 741
+i 742
+i 750
+i 2573
+i 2582
+i 2581
+i 2565
+i 2575
+i 2574
+i 1021
+i 1022
+i 1031
+i 759
+i 760
+i 768
+i 859
+i 860
+i 869
+i 597
+i 598
+i 606
+i 1013
+i 1022
+i 1021
+i 750
+i 760
+i 759
+i 974
+i 975
+i 983
+i 716
+i 717
+i 726
+i 994
+i 995
+i 1003
+i 732
+i 733
+i 742
+i 887
+i 897
+i 896
+i 624
+i 633
+i 632
+i 572
+i 573
+i 582
+i 830
+i 831
+i 839
+i 896
+i 897
+i 905
+i 632
+i 633
+i 642
+i 975
+i 984
+i 983
+i 716
+i 726
+i 725
+i 572
+i 582
+i 581
+i 831
+i 840
+i 839
+i 580
+i 590
+i 589
+i 841
+i 850
+i 849
+i 580
+i 581
+i 590
+i 840
+i 841
+i 849
+i 973
+i 974
+i 983
+i 717
+i 718
+i 726
+i 985
+i 994
+i 993
+i 724
+i 734
+i 733
+i 984
+i 985
+i 993
+i 724
+i 725
+i 734
+i 573
+i 574
+i 582
+i 829
+i 830
+i 839
+i 1031
+i 1040
+i 1039
+i 768
+i 778
+i 777
+i 1003
+i 1013
+i 1012
+i 742
+i 751
+i 750
+i 1021
+i 1031
+i 1030
+i 760
+i 769
+i 768
+i 1012
+i 1013
+i 1021
+i 750
+i 751
+i 760
+i 869
+i 878
+i 877
+i 606
+i 616
+i 615
+i 972
+i 973
+i 981
+i 718
+i 719
+i 728
+i 859
+i 869
+i 868
+i 598
+i 607
+i 606
+i 589
+i 590
+i 598
+i 849
+i 850
+i 859
+i 574
+i 575
+i 584
+i 828
+i 829
+i 837
+i 1030
+i 1031
+i 1039
+i 768
+i 769
+i 778
+i 993
+i 994
+i 1003
+i 733
+i 734
+i 742
+i 581
+i 582
+i 590
+i 839
+i 840
+i 849
+i 973
+i 983
+i 982
+i 718
+i 727
+i 726
+i 983
+i 984
+i 993
+i 725
+i 726
+i 734
+i 913
+i 914
+i 923
+i 651
+i 652
+i 660
+i 574
+i 583
+i 582
+i 829
+i 839
+i 838
+i 877
+i 878
+i 887
+i 615
+i 616
+i 624
+i 868
+i 869
+i 877
+i 606
+i 607
+i 616
+i 973
+i 982
+i 981
+i 718
+i 728
+i 727
+i 574
+i 584
+i 583
+i 829
+i 838
+i 837
+i 905
+i 914
+i 913
+i 642
+i 652
+i 651
+i 913
+i 923
+i 922
+i 652
+i 661
+i 660
+i 590
+i 599
+i 598
+i 849
+i 859
+i 858
+i 887
+i 896
+i 895
+i 624
+i 634
+i 633
+i 582
+i 591
+i 590
+i 839
+i 849
+i 848
+i 895
+i 896
+i 905
+i 633
+i 634
+i 642
+i 993
+i 1003
+i 1002
+i 734
+i 743
+i 742
+i 1003
+i 1012
+i 1011
+i 742
+i 752
+i 751
+i 1021
+i 1030
+i 1029
+i 760
+i 770
+i 769
+i 1611
+i 1633
+i 1632
+i 1720
+i 1721
+i 1743
+i 1609
+i 1632
+i 1631
+i 1719
+i 1720
+i 1741
+i 1611
+i 1634
+i 1633
+i 1721
+i 1722
+i 1743
+i 1609
+i 1631
+i 1630
+i 1718
+i 1719
+i 1741
+i 1011
+i 1012
+i 1021
+i 751
+i 752
+i 760
+i 983
+i 993
+i 992
+i 726
+i 735
+i 734
+i 1613
+i 1635
+i 1634
+i 1722
+i 1723
+i 1745
+i 1607
+i 1630
+i 1629
+i 1717
+i 1718
+i 1739
+i 1588
+i 1589
+i 1611
+i 1743
+i 1765
+i 1764
+i 1589
+i 1590
+i 1611
+i 1743
+i 1766
+i 1765
+i 1587
+i 1588
+i 1609
+i 1741
+i 1764
+i 1763
+i 1613
+i 1636
+i 1635
+i 1723
+i 1724
+i 1745
+i 1586
+i 1587
+i 1609
+i 1741
+i 1763
+i 1762
+i 1610
+i 1611
+i 1632
+i 1720
+i 1743
+i 1742
+i 1609
+i 1610
+i 1632
+i 1720
+i 1742
+i 1741
+i 1607
+i 1629
+i 1628
+i 1716
+i 1717
+i 1739
+i 1590
+i 1591
+i 1613
+i 1745
+i 1767
+i 1766
+i 1611
+i 1612
+i 1634
+i 1722
+i 1744
+i 1743
+i 1608
+i 1609
+i 1630
+i 1718
+i 1741
+i 1740
+i 1588
+i 1611
+i 1610
+i 1742
+i 1743
+i 1764
+i 1588
+i 1610
+i 1609
+i 1741
+i 1742
+i 1764
+i 1612
+i 1613
+i 1634
+i 1722
+i 1745
+i 1744
+i 1591
+i 1592
+i 1613
+i 1745
+i 1768
+i 1767
+i 1615
+i 1637
+i 1636
+i 1724
+i 1725
+i 1747
+i 1590
+i 1612
+i 1611
+i 1743
+i 1744
+i 1766
+i 1607
+i 1608
+i 1630
+i 1718
+i 1740
+i 1739
+i 1585
+i 1586
+i 1607
+i 1739
+i 1762
+i 1761
+i 1590
+i 1613
+i 1612
+i 1744
+i 1745
+i 1766
+i 1586
+i 1609
+i 1608
+i 1740
+i 1741
+i 1762
+i 1592
+i 1593
+i 1615
+i 1747
+i 1769
+i 1768
+i 1586
+i 1608
+i 1607
+i 1739
+i 1740
+i 1762
+i 1584
+i 1585
+i 1607
+i 1739
+i 1761
+i 1760
+i 1613
+i 1614
+i 1636
+i 1724
+i 1746
+i 1745
+i 1605
+i 1628
+i 1627
+i 1715
+i 1716
+i 1737
+i 1592
+i 1614
+i 1613
+i 1745
+i 1746
+i 1768
+i 1614
+i 1615
+i 1636
+i 1724
+i 1747
+i 1746
+i 1606
+i 1607
+i 1628
+i 1716
+i 1739
+i 1738
+i 1592
+i 1615
+i 1614
+i 1746
+i 1747
+i 1768
+i 1584
+i 1607
+i 1606
+i 1738
+i 1739
+i 1760
+i 1605
+i 1627
+i 1626
+i 1714
+i 1715
+i 1737
+i 877
+i 887
+i 886
+i 616
+i 625
+i 624
+i 1605
+i 1606
+i 1628
+i 1716
+i 1738
+i 1737
+i 582
+i 583
+i 592
+i 838
+i 839
+i 847
+i 859
+i 868
+i 867
+i 598
+i 608
+i 607
+i 1583
+i 1584
+i 1605
+i 1737
+i 1760
+i 1759
+i 1584
+i 1606
+i 1605
+i 1737
+i 1738
+i 1760
+i 1582
+i 1583
+i 1605
+i 1737
+i 1759
+i 1758
+i 1029
+i 1030
+i 1039
+i 769
+i 770
+i 778
+i 1604
+i 1605
+i 1626
+i 1714
+i 1737
+i 1736
+i 982
+i 983
+i 991
+i 726
+i 727
+i 736
+i 1603
+i 1626
+i 1625
+i 1713
+i 1714
+i 1735
+i 1582
+i 1605
+i 1604
+i 1736
+i 1737
+i 1758
+i 1603
+i 1604
+i 1626
+i 1714
+i 1736
+i 1735
+i 1603
+i 1625
+i 1624
+i 1712
+i 1713
+i 1735
+i 1581
+i 1582
+i 1603
+i 1735
+i 1758
+i 1757
+i 1582
+i 1604
+i 1603
+i 1735
+i 1736
+i 1758
+i 1002
+i 1003
+i 1011
+i 742
+i 743
+i 752
+i 1020
+i 1021
+i 1029
+i 760
+i 761
+i 770
+i 582
+i 592
+i 591
+i 839
+i 848
+i 847
+i 1011
+i 1021
+i 1020
+i 752
+i 761
+i 760
+i 583
+i 584
+i 592
+i 837
+i 838
+i 847
+i 858
+i 859
+i 867
+i 598
+i 599
+i 608
+i 1580
+i 1581
+i 1603
+i 1735
+i 1757
+i 1756
+i 1602
+i 1603
+i 1624
+i 1712
+i 1735
+i 1734
+i 886
+i 887
+i 895
+i 624
+i 625
+i 634
+i 1601
+i 1624
+i 1623
+i 1711
+i 1712
+i 1733
+i 1580
+i 1603
+i 1602
+i 1734
+i 1735
+i 1756
+i 981
+i 982
+i 991
+i 727
+i 728
+i 736
+i 904
+i 905
+i 913
+i 642
+i 643
+i 652
+i 1601
+i 1602
+i 1624
+i 1712
+i 1734
+i 1733
+i 983
+i 992
+i 991
+i 726
+i 736
+i 735
+i 1601
+i 1623
+i 1622
+i 1710
+i 1711
+i 1733
+i 1580
+i 1602
+i 1601
+i 1733
+i 1734
+i 1756
+i 1579
+i 1580
+i 1601
+i 1733
+i 1756
+i 1755
+i 867
+i 868
+i 877
+i 607
+i 608
+i 616
+i 590
+i 591
+i 600
+i 848
+i 849
+i 857
+i 590
+i 600
+i 599
+i 849
+i 858
+i 857
+i 1578
+i 1579
+i 1601
+i 1733
+i 1755
+i 1754
+i 1600
+i 1601
+i 1622
+i 1710
+i 1733
+i 1732
+i 895
+i 905
+i 904
+i 634
+i 643
+i 642
+i 1578
+i 1601
+i 1600
+i 1732
+i 1733
+i 1754
+i 1599
+i 1622
+i 1621
+i 1709
+i 1710
+i 1731
+i 1599
+i 1600
+i 1622
+i 1710
+i 1732
+i 1731
+i 993
+i 1002
+i 1001
+i 734
+i 744
+i 743
+i 992
+i 993
+i 1001
+i 734
+i 735
+i 744
+i 1578
+i 1600
+i 1599
+i 1731
+i 1732
+i 1754
+i 1599
+i 1621
+i 1620
+i 1708
+i 1709
+i 1731
+i 1577
+i 1578
+i 1599
+i 1731
+i 1754
+i 1753
+i 584
+i 593
+i 592
+i 837
+i 847
+i 846
+i 913
+i 922
+i 921
+i 652
+i 662
+i 661
+i 1576
+i 1577
+i 1599
+i 1731
+i 1753
+i 1752
+i 1598
+i 1599
+i 1620
+i 1708
+i 1731
+i 1730
+i 1029
+i 1039
+i 1038
+i 770
+i 779
+i 778
+i 981
+i 991
+i 990
+i 728
+i 737
+i 736
+i 1576
+i 1599
+i 1598
+i 1730
+i 1731
+i 1752
+i 1597
+i 1620
+i 1619
+i 1707
+i 1708
+i 1729
+i 1597
+i 1598
+i 1620
+i 1708
+i 1730
+i 1729
+i 591
+i 592
+i 600
+i 847
+i 848
+i 857
+i 1576
+i 1598
+i 1597
+i 1729
+i 1730
+i 1752
+i 1001
+i 1002
+i 1011
+i 743
+i 744
+i 752
+i 1575
+i 1576
+i 1597
+i 1729
+i 1752
+i 1751
+i 1597
+i 1619
+i 1618
+i 1706
+i 1707
+i 1729
+i 1019
+i 1020
+i 1029
+i 761
+i 762
+i 770
+i 1011
+i 1020
+i 1019
+i 752
+i 762
+i 761
+i 857
+i 858
+i 867
+i 599
+i 600
+i 608
+i 991
+i 992
+i 1001
+i 735
+i 736
+i 744
+i 1574
+i 1575
+i 1597
+i 1729
+i 1751
+i 1750
+i 1654
+i 1655
+i 1677
+i 1677
+i 1699
+i 1698
+i 867
+i 877
+i 876
+i 608
+i 617
+i 616
+i 1653
+i 1654
+i 1675
+i 1675
+i 1698
+i 1697
+i 1655
+i 1656
+i 1677
+i 1677
+i 1700
+i 1699
+i 1652
+i 1653
+i 1675
+i 1675
+i 1697
+i 1696
+i 1596
+i 1597
+i 1618
+i 1706
+i 1729
+i 1728
+i 1656
+i 1657
+i 1679
+i 1679
+i 1701
+i 1700
+i 1651
+i 1652
+i 1673
+i 1673
+i 1696
+i 1695
+i 1654
+i 1677
+i 1676
+i 1676
+i 1677
+i 1698
+i 1657
+i 1658
+i 1679
+i 1679
+i 1702
+i 1701
+i 1654
+i 1676
+i 1675
+i 1675
+i 1676
+i 1698
+i 1656
+i 1678
+i 1677
+i 1677
+i 1678
+i 1700
+i 877
+i 886
+i 885
+i 616
+i 626
+i 625
+i 1652
+i 1675
+i 1674
+i 1674
+i 1675
+i 1696
+i 1650
+i 1651
+i 1673
+i 1673
+i 1695
+i 1694
+i 1574
+i 1597
+i 1596
+i 1728
+i 1729
+i 1750
+i 1656
+i 1679
+i 1678
+i 1678
+i 1679
+i 1700
+i 1658
+i 1659
+i 1681
+i 1681
+i 1703
+i 1702
+i 1652
+i 1674
+i 1673
+i 1673
+i 1674
+i 1696
+i 1658
+i 1680
+i 1679
+i 1679
+i 1680
+i 1702
+i 1658
+i 1681
+i 1680
+i 1680
+i 1681
+i 1702
+i 1650
+i 1673
+i 1672
+i 1672
+i 1673
+i 1694
+i 1649
+i 1650
+i 1671
+i 1671
+i 1694
+i 1693
+i 1650
+i 1672
+i 1671
+i 1671
+i 1672
+i 1694
+i 1595
+i 1596
+i 1618
+i 1706
+i 1728
+i 1727
+i 1648
+i 1649
+i 1671
+i 1671
+i 1693
+i 1692
+i 1595
+i 1618
+i 1617
+i 1705
+i 1706
+i 1727
+i 1574
+i 1596
+i 1595
+i 1727
+i 1728
+i 1750
+i 1001
+i 1011
+i 1010
+i 744
+i 753
+i 752
+i 1019
+i 1029
+i 1028
+i 762
+i 771
+i 770
+i 1648
+i 1671
+i 1670
+i 1670
+i 1671
+i 1692
+i 1010
+i 1011
+i 1019
+i 752
+i 753
+i 762
+i 592
+i 593
+i 602
+i 846
+i 847
+i 855
+i 592
+i 601
+i 600
+i 847
+i 857
+i 856
+i 1647
+i 1648
+i 1669
+i 1669
+i 1692
+i 1691
+i 1573
+i 1574
+i 1595
+i 1727
+i 1750
+i 1749
+i 912
+i 913
+i 921
+i 652
+i 653
+i 662
+i 885
+i 886
+i 895
+i 625
+i 626
+i 634
+i 1648
+i 1670
+i 1669
+i 1669
+i 1670
+i 1692
+i 1646
+i 1647
+i 1669
+i 1669
+i 1691
+i 1690
+i 876
+i 877
+i 885
+i 616
+i 617
+i 626
+i 903
+i 904
+i 913
+i 643
+i 644
+i 652
+i 990
+i 991
+i 999
+i 736
+i 737
+i 746
+i 1595
+i 1617
+i 1616
+i 1704
+i 1705
+i 1727
+i 991
+i 1001
+i 1000
+i 736
+i 745
+i 744
+i 857
+i 867
+i 866
+i 600
+i 609
+i 608
+i 1646
+i 1669
+i 1668
+i 1668
+i 1669
+i 1690
+i 1029
+i 1038
+i 1037
+i 770
+i 780
+i 779
+i 1645
+i 1646
+i 1667
+i 1667
+i 1690
+i 1689
+i 1646
+i 1668
+i 1667
+i 1667
+i 1668
+i 1690
+i 592
+i 602
+i 601
+i 847
+i 856
+i 855
+i 895
+i 904
+i 903
+i 634
+i 644
+i 643
+i 1572
+i 1573
+i 1595
+i 1727
+i 1749
+i 1748
+i 1028
+i 1029
+i 1037
+i 770
+i 771
+i 780
+i 1644
+i 1645
+i 1667
+i 1667
+i 1689
+i 1688
+i 1594
+i 1595
+i 1616
+i 1704
+i 1727
+i 1726
+i 991
+i 1000
+i 999
+i 736
+i 746
+i 745
+i 1644
+i 1667
+i 1666
+i 1666
+i 1667
+i 1688
+i 1572
+i 1595
+i 1594
+i 1726
+i 1727
+i 1748
+i 903
+i 913
+i 912
+i 644
+i 653
+i 652
+i 1001
+i 1010
+i 1009
+i 744
+i 754
+i 753
+i 1019
+i 1028
+i 1027
+i 762
+i 772
+i 771
+i 1643
+i 1644
+i 1665
+i 1665
+i 1688
+i 1687
+i 1644
+i 1666
+i 1665
+i 1665
+i 1666
+i 1688
+i 1009
+i 1010
+i 1019
+i 753
+i 754
+i 762
+i 867
+i 876
+i 875
+i 608
+i 618
+i 617
+i 1000
+i 1001
+i 1009
+i 744
+i 745
+i 754
+i 1642
+i 1643
+i 1665
+i 1665
+i 1687
+i 1686
+i 1018
+i 1019
+i 1027
+i 762
+i 763
+i 772
+i 1009
+i 1019
+i 1018
+i 754
+i 763
+i 762
+i 856
+i 857
+i 865
+i 600
+i 601
+i 610
+i 885
+i 895
+i 894
+i 626
+i 635
+i 634
+i 866
+i 867
+i 875
+i 608
+i 609
+i 618
+i 857
+i 866
+i 865
+i 600
+i 610
+i 609
+i 1642
+i 1665
+i 1664
+i 1664
+i 1665
+i 1686
+i 894
+i 895
+i 903
+i 634
+i 635
+i 644
+i 1027
+i 1028
+i 1037
+i 771
+i 772
+i 780
+i 999
+i 1000
+i 1009
+i 745
+i 746
+i 754
+i 1642
+i 1664
+i 1663
+i 1663
+i 1664
+i 1686
+i 1641
+i 1642
+i 1663
+i 1663
+i 1686
+i 1685
+i 1017
+i 1018
+i 1027
+i 763
+i 764
+i 772
+i 1009
+i 1018
+i 1017
+i 754
+i 764
+i 763
+i 855
+i 856
+i 865
+i 601
+i 602
+i 610
+i 911
+i 912
+i 921
+i 653
+i 654
+i 662
+i 875
+i 876
+i 885
+i 617
+i 618
+i 626
+i 911
+i 921
+i 920
+i 654
+i 663
+i 662
+i 1640
+i 1641
+i 1663
+i 1663
+i 1685
+i 1684
+i 999
+i 1009
+i 1008
+i 746
+i 755
+i 754
+i 1017
+i 1027
+i 1026
+i 764
+i 773
+i 772
+i 1008
+i 1009
+i 1017
+i 754
+i 755
+i 764
+i 1640
+i 1663
+i 1662
+i 1662
+i 1663
+i 1684
+i 865
+i 866
+i 875
+i 609
+i 610
+i 618
+i 855
+i 865
+i 864
+i 602
+i 611
+i 610
+i 1027
+i 1037
+i 1036
+i 772
+i 781
+i 780
+i 903
+i 912
+i 911
+i 644
+i 654
+i 653
+i 1640
+i 1662
+i 1661
+i 1661
+i 1662
+i 1684
+i 1026
+i 1027
+i 1035
+i 772
+i 773
+i 782
+i 1639
+i 1640
+i 1661
+i 1661
+i 1684
+i 1683
+i 875
+i 885
+i 884
+i 618
+i 627
+i 626
+i 1027
+i 1036
+i 1035
+i 772
+i 782
+i 781
+i 911
+i 920
+i 919
+i 654
+i 664
+i 663
+i 885
+i 894
+i 893
+i 626
+i 636
+i 635
+i 865
+i 875
+i 874
+i 610
+i 619
+i 618
+i 1638
+i 1639
+i 1661
+i 1661
+i 1683
+i 1682
+i 893
+i 894
+i 903
+i 635
+i 636
+i 644
+i 864
+i 865
+i 873
+i 610
+i 611
+i 620
+i 884
+i 885
+i 893
+i 626
+i 627
+i 636
+i 1638
+i 1661
+i 1660
+i 1660
+i 1661
+i 1682
+i 902
+i 903
+i 911
+i 644
+i 645
+i 654
+i 865
+i 874
+i 873
+i 610
+i 620
+i 619
+i 910
+i 911
+i 919
+i 654
+i 655
+i 664
+i 893
+i 903
+i 902
+i 636
+i 645
+i 644
+i 875
+i 884
+i 883
+i 618
+i 628
+i 627
+i 874
+i 875
+i 883
+i 618
+i 619
+i 628
+i 909
+i 919
+i 918
+i 656
+i 665
+i 664
+i 909
+i 910
+i 919
+i 655
+i 656
+i 664
+i 873
+i 874
+i 883
+i 619
+i 620
+i 628
+i 883
+i 884
+i 893
+i 627
+i 628
+i 636
+i 901
+i 902
+i 911
+i 645
+i 646
+i 654
+i 901
+i 911
+i 910
+i 646
+i 655
+i 654
+i 873
+i 883
+i 882
+i 620
+i 629
+i 628
+i 893
+i 902
+i 901
+i 636
+i 646
+i 645
+i 883
+i 893
+i 892
+i 628
+i 637
+i 636
+i 901
+i 910
+i 909
+i 646
+i 656
+i 655
+i 892
+i 893
+i 901
+i 636
+i 637
+i 646
+i 882
+i 883
+i 891
+i 628
+i 629
+i 638
+i 883
+i 892
+i 891
+i 628
+i 638
+i 637
+i 900
+i 901
+i 909
+i 646
+i 647
+i 656
+i 891
+i 892
+i 901
+i 637
+i 638
+i 646
+i 891
+i 901
+i 900
+i 638
+i 647
+i 646
diff --git a/data/shaders/README.shaders b/data/shaders/README.shaders
new file mode 100644
index 0000000..3bc8c88
--- /dev/null
+++ b/data/shaders/README.shaders
@@ -0,0 +1,5 @@
+This directory contains the shader sources used by glmark2 benchmarks.
+
+Note that many of the shaders are either incomplete or are templates and can't
+be used directly! Missing pieces (eg constants, precision statements, actual
+code) are added dynamically at runtime.
diff --git a/data/shaders/buffer-wireframe.frag b/data/shaders/buffer-wireframe.frag
new file mode 100644
index 0000000..866c281
--- /dev/null
+++ b/data/shaders/buffer-wireframe.frag
@@ -0,0 +1,17 @@
+varying vec4 dist;
+
+const vec4 LINE_COLOR = vec4(1.0);
+const vec4 TRIANGLE_COLOR = vec4(0.0, 0.5, 0.8, 0.8);
+
+void main(void)
+{
+ // Get the minimum distance of this fragment from a triangle edge.
+ // We need to multiply with dist.w to undo the workaround we had
+ // to perform to get linear interpolation (instead of perspective correct).
+ float d = min(dist.x * dist.w, min(dist.y * dist.w, dist.z * dist.w));
+
+ // Get the intensity of the wireframe line
+ float I = exp2(-2.0 * d * d);
+
+ gl_FragColor = mix(TRIANGLE_COLOR, LINE_COLOR, I);
+}
diff --git a/data/shaders/buffer-wireframe.vert b/data/shaders/buffer-wireframe.vert
new file mode 100644
index 0000000..e9041f7
--- /dev/null
+++ b/data/shaders/buffer-wireframe.vert
@@ -0,0 +1,57 @@
+// Wireframe shader based on:
+// J. A. Bærentzen, S. Munk-Lund, M. Gjøl, and B. D. Larsen,
+// “Two methods for antialiased wireframe drawing with hidden
+// line removal,†in Proceedings of the Spring Conference in
+// Computer Graphics, 2008.
+//
+// We are not using geometry shaders, though, as they are not
+// available in GLES 2.0.
+
+attribute vec3 position;
+// Coordinates of the triangle vertices this vertex belongs to
+attribute vec3 tvertex0;
+attribute vec3 tvertex1;
+attribute vec3 tvertex2;
+
+uniform vec2 Viewport;
+uniform mat4 ModelViewProjectionMatrix;
+
+varying vec4 dist;
+
+void main(void)
+{
+ // Get the clip coordinates of all vertices
+ vec4 pos = ModelViewProjectionMatrix * vec4(position, 1.0);
+ vec4 pos0 = ModelViewProjectionMatrix * vec4(tvertex0, 1.0);
+ vec4 pos1 = ModelViewProjectionMatrix * vec4(tvertex1, 1.0);
+ vec4 pos2 = ModelViewProjectionMatrix * vec4(tvertex2, 1.0);
+
+ // Get the screen coordinates of all vertices
+ vec3 p = vec3(0.5 * Viewport * (pos.xy / pos.w), 0.0);
+ vec3 p0 = vec3(0.5 * Viewport * (pos0.xy / pos0.w), 0.0);
+ vec3 p1 = vec3(0.5 * Viewport * (pos1.xy / pos1.w), 0.0);
+ vec3 p2 = vec3(0.5 * Viewport * (pos2.xy / pos2.w), 0.0);
+
+ // Get the vectors representing the edges of the current
+ // triangle primitive. 'vN' is the edge opposite vertex N.
+ vec3 v0 = p2 - p1;
+ vec3 v1 = p2 - p0;
+ vec3 v2 = p1 - p0;
+
+ // Calculate the distance of the current vertex from all
+ // the triangle edges. The distance of point p from line
+ // v is length(cross(p - p1, v)) / length(v), where
+ // p1 is any of the two edge points of v.
+ float d0 = length(cross(p - p1, v0)) / length(v0);
+ float d1 = length(cross(p - p2, v1)) / length(v1);
+ float d2 = length(cross(p - p0, v2)) / length(v2);
+
+ // OpenGL(ES) performs perspective-correct interpolation
+ // (it divides by .w) but we want linear interpolation. To
+ // work around this, we premultiply by pos.w here and then
+ // multiple with the inverse (stored in dist.w) in the fragment
+ // shader to undo this operation.
+ dist = vec4(pos.w * d0, pos.w * d1, pos.w * d2, 1.0 / pos.w);
+
+ gl_Position = pos;
+}
diff --git a/data/shaders/bump-height.frag b/data/shaders/bump-height.frag
new file mode 100644
index 0000000..73203b7
--- /dev/null
+++ b/data/shaders/bump-height.frag
@@ -0,0 +1,56 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+uniform sampler2D HeightMap;
+
+varying vec2 TextureCoord;
+varying vec3 NormalEye;
+varying vec3 TangentEye;
+varying vec3 BitangentEye;
+
+void main(void)
+{
+ const vec4 LightSourceAmbient = vec4(0.1, 0.1, 0.1, 1.0);
+ const vec4 LightSourceDiffuse = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 LightSourceSpecular = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 MaterialAmbient = vec4(1.0, 1.0, 1.0, 1.0);
+ const vec4 MaterialDiffuse = vec4(1.0, 1.0, 1.0, 1.0);
+ const vec4 MaterialSpecular = vec4(0.2, 0.2, 0.2, 1.0);
+ const float MaterialShininess = 100.0;
+ const float height_factor = 13.0;
+
+ // Get the data from the height map
+ float height0 = texture2D(HeightMap, TextureCoord).x;
+ float heightX = texture2D(HeightMap, TextureCoord + vec2(TextureStepX, 0.0)).x;
+ float heightY = texture2D(HeightMap, TextureCoord + vec2(0.0, TextureStepY)).x;
+ vec2 dh = vec2(heightX - height0, heightY - height0);
+
+ // Adjust the normal based on the height map data
+ vec3 N = NormalEye - height_factor * dh.x * TangentEye -
+ height_factor * dh.y * BitangentEye;
+ N = normalize(N);
+
+ // In the lighting model we are using here (Blinn-Phong with light at
+ // infinity, viewer at infinity), the light position/direction and the
+ // half vector is constant for the all the fragments.
+ vec3 L = normalize(LightSourcePosition.xyz);
+ vec3 H = normalize(LightSourceHalfVector);
+
+ // Calculate the diffuse color according to Lambertian reflectance
+ vec4 diffuse = MaterialDiffuse * LightSourceDiffuse * max(dot(N, L), 0.0);
+
+ // Calculate the ambient color
+ vec4 ambient = MaterialAmbient * LightSourceAmbient;
+
+ // Calculate the specular color according to the Blinn-Phong model
+ vec4 specular = MaterialSpecular * LightSourceSpecular *
+ pow(max(dot(N,H), 0.0), MaterialShininess);
+
+ // Calculate the final color
+ gl_FragColor = ambient + specular + diffuse;
+
+ //gl_FragColor = vec4(height_diff_raw.xy, 0.0, 1.0);
+ //gl_FragColor = vec4(height_diff_scaled.xy, 0.0, 1.0);
+ //gl_FragColor = vec4(Tangent, 1.0);
+}
diff --git a/data/shaders/bump-height.vert b/data/shaders/bump-height.vert
new file mode 100644
index 0000000..cf49d7a
--- /dev/null
+++ b/data/shaders/bump-height.vert
@@ -0,0 +1,28 @@
+attribute vec3 position;
+attribute vec2 texcoord;
+attribute vec3 normal;
+attribute vec3 tangent;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 NormalMatrix;
+
+varying vec2 TextureCoord;
+varying vec3 NormalEye;
+varying vec3 TangentEye;
+varying vec3 BitangentEye;
+
+void main(void)
+{
+ TextureCoord = texcoord;
+
+ // Transform normal, tangent and bitangent to eye space, keeping
+ // all of them perpendicular to the Normal. That is why we use
+ // NormalMatrix, instead of ModelView, to transform the tangent and
+ // bitangent.
+ NormalEye = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));
+ TangentEye = normalize(vec3(NormalMatrix * vec4(tangent, 1.0)));
+ BitangentEye = normalize(vec3(NormalMatrix * vec4(cross(normal, tangent), 1.0)));
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
diff --git a/data/shaders/bump-normals-tangent.frag b/data/shaders/bump-normals-tangent.frag
new file mode 100644
index 0000000..3ffe9c5
--- /dev/null
+++ b/data/shaders/bump-normals-tangent.frag
@@ -0,0 +1,49 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+uniform sampler2D NormalMap;
+
+varying vec2 TextureCoord;
+varying mat4 TangentToEyeMatrix;
+
+void main(void)
+{
+ const vec4 LightSourceAmbient = vec4(0.1, 0.1, 0.1, 1.0);
+ const vec4 LightSourceDiffuse = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 LightSourceSpecular = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 MaterialAmbient = vec4(1.0, 1.0, 1.0, 1.0);
+ const vec4 MaterialDiffuse = vec4(1.0, 1.0, 1.0, 1.0);
+ const vec4 MaterialSpecular = vec4(0.2, 0.2, 0.2, 1.0);
+ const float MaterialShininess = 100.0;
+
+ // Get the raw normal XYZ data from the normal map
+ vec3 normal_raw = texture2D(NormalMap, TextureCoord).xyz;
+
+ // Map "color" range [0, 1.0] to normal range [-1.0, 1.0]
+ vec3 normal_scaled = normal_raw * 2.0 - 1.0;
+
+ // The normal data is in tangent space, convert it to eye space so that
+ // lighting calculations can work (light information is in eye space).
+ vec3 N = normalize(vec3(TangentToEyeMatrix * vec4(normal_scaled, 1.0)));
+
+ // In the lighting model we are using here (Blinn-Phong with light at
+ // infinity, viewer at infinity), the light position/direction and the
+ // half vector is constant for the all the fragments.
+ vec3 L = normalize(LightSourcePosition.xyz);
+ vec3 H = normalize(LightSourceHalfVector);
+
+ // Calculate the diffuse color according to Lambertian reflectance
+ vec4 diffuse = MaterialDiffuse * LightSourceDiffuse * max(dot(N, L), 0.0);
+
+ // Calculate the ambient color
+ vec4 ambient = MaterialAmbient * LightSourceAmbient;
+
+ // Calculate the specular color according to the Blinn-Phong model
+ vec4 specular = MaterialSpecular * LightSourceSpecular *
+ pow(max(dot(N,H), 0.0), MaterialShininess);
+
+ // Calculate the final color
+ gl_FragColor = ambient + specular + diffuse;
+ //gl_FragColor = vec4(N, 1.0);
+}
diff --git a/data/shaders/bump-normals-tangent.vert b/data/shaders/bump-normals-tangent.vert
new file mode 100644
index 0000000..0a61a00
--- /dev/null
+++ b/data/shaders/bump-normals-tangent.vert
@@ -0,0 +1,39 @@
+attribute vec3 position;
+attribute vec2 texcoord;
+attribute vec3 normal;
+attribute vec3 tangent;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 NormalMatrix;
+
+varying vec2 TextureCoord;
+varying mat4 TangentToEyeMatrix;
+
+void main(void)
+{
+ TextureCoord = texcoord;
+
+ // Calculate bitangent
+ vec3 bitangent = normalize(cross(normal, tangent));
+
+ // Calculate tangent space to eye space transformation matrix.
+ // We need this matrix in the fragment shader to transform the data
+ // from the normal map, which is in tangent space, to eye space,
+ // so that we can perform meaningful lighting calculations. Alternatively,
+ // we could have used an EyeToTangentMatrix, to convert light direction etc
+ // to tangent space.
+
+ // First calculate a tangent space to object space transformation matrix.
+ mat4 TangentToObject = mat4(tangent.x, tangent.y, tangent.z, 0.0,
+ bitangent.x, bitangent.y, bitangent.z, 0.0,
+ normal.x, normal.y, normal.z, 0.0,
+ 0.0, 0.0, 0.0, 1.0);
+
+ // Multiply with the NormalMatrix to further transform from object
+ // space to eye space (we are manipulating normals, so we can't use
+ // the ModelView matrix for this step!).
+ TangentToEyeMatrix = NormalMatrix * TangentToObject;
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
diff --git a/data/shaders/bump-normals.frag b/data/shaders/bump-normals.frag
new file mode 100644
index 0000000..027abed
--- /dev/null
+++ b/data/shaders/bump-normals.frag
@@ -0,0 +1,44 @@
+uniform sampler2D NormalMap;
+uniform mat4 NormalMatrix;
+
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ const vec4 LightSourceAmbient = vec4(0.1, 0.1, 0.1, 1.0);
+ const vec4 LightSourceDiffuse = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 LightSourceSpecular = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 MaterialAmbient = vec4(1.0, 1.0, 1.0, 1.0);
+ const vec4 MaterialDiffuse = vec4(1.0, 1.0, 1.0, 1.0);
+ const vec4 MaterialSpecular = vec4(0.2, 0.2, 0.2, 1.0);
+ const float MaterialShininess = 100.0;
+
+ // Get the raw normal XYZ data from the normal map
+ vec3 normal_raw = texture2D(NormalMap, TextureCoord).xyz;
+ // Map "color" range [0, 1.0] to normal range [-1.0, 1.0]
+ vec3 normal_scaled = normal_raw * 2.0 - 1.0;
+
+ // Convert the normal to eye coordinates. Note that the normal map
+ // we are using is using object coordinates (not tangent!) for the
+ // normals, so we can multiply by the NormalMatrix as usual.
+ vec3 N = normalize(vec3(NormalMatrix * vec4(normal_scaled, 1.0)));
+
+ // In the lighting model we are using here (Blinn-Phong with light at
+ // infinity, viewer at infinity), the light position/direction and the
+ // half vector is constant for the all the fragments.
+ vec3 L = normalize(LightSourcePosition.xyz);
+ vec3 H = normalize(LightSourceHalfVector);
+
+ // Calculate the diffuse color according to Lambertian reflectance
+ vec4 diffuse = MaterialDiffuse * LightSourceDiffuse * max(dot(N, L), 0.0);
+
+ // Calculate the ambient color
+ vec4 ambient = MaterialAmbient * LightSourceAmbient;
+
+ // Calculate the specular color according to the Blinn-Phong model
+ vec4 specular = MaterialSpecular * LightSourceSpecular *
+ pow(max(dot(N,H), 0.0), MaterialShininess);
+
+ // Calculate the final color
+ gl_FragColor = ambient + specular + diffuse;
+}
diff --git a/data/shaders/bump-normals.vert b/data/shaders/bump-normals.vert
new file mode 100644
index 0000000..cfa12b3
--- /dev/null
+++ b/data/shaders/bump-normals.vert
@@ -0,0 +1,14 @@
+attribute vec3 position;
+attribute vec2 texcoord;
+
+uniform mat4 ModelViewProjectionMatrix;
+
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ TextureCoord = texcoord;
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
diff --git a/data/shaders/bump-poly.frag b/data/shaders/bump-poly.frag
new file mode 100644
index 0000000..ffd4c6c
--- /dev/null
+++ b/data/shaders/bump-poly.frag
@@ -0,0 +1,33 @@
+varying vec3 Normal;
+
+void main(void)
+{
+ const vec4 LightSourceAmbient = vec4(0.1, 0.1, 0.1, 1.0);
+ const vec4 LightSourceDiffuse = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 LightSourceSpecular = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 MaterialAmbient = vec4(1.0, 1.0, 1.0, 1.0);
+ const vec4 MaterialDiffuse = vec4(1.0, 1.0, 1.0, 1.0);
+ const vec4 MaterialSpecular = vec4(0.2, 0.2, 0.2, 1.0);
+ const float MaterialShininess = 100.0;
+
+ vec3 N = normalize(Normal);
+
+ // In the lighting model we are using here (Blinn-Phong with light at
+ // infinity, viewer at infinity), the light position/direction and the
+ // half vector is constant for the all the fragments.
+ vec3 L = normalize(LightSourcePosition.xyz);
+ vec3 H = normalize(LightSourceHalfVector);
+
+ // Calculate the diffuse color according to Lambertian reflectance
+ vec4 diffuse = MaterialDiffuse * LightSourceDiffuse * max(dot(N, L), 0.0);
+
+ // Calculate the ambient color
+ vec4 ambient = MaterialAmbient * LightSourceAmbient;
+
+ // Calculate the specular color according to the Blinn-Phong model
+ vec4 specular = MaterialSpecular * LightSourceSpecular *
+ pow(max(dot(N,H), 0.0), MaterialShininess);
+
+ // Calculate the final color
+ gl_FragColor = ambient + specular + diffuse;
+}
diff --git a/data/shaders/bump-poly.vert b/data/shaders/bump-poly.vert
new file mode 100644
index 0000000..0207c37
--- /dev/null
+++ b/data/shaders/bump-poly.vert
@@ -0,0 +1,16 @@
+attribute vec3 position;
+attribute vec3 normal;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 NormalMatrix;
+
+varying vec3 Normal;
+
+void main(void)
+{
+ // Transform the normal to eye coordinates
+ Normal = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
diff --git a/data/shaders/conditionals-step-conditional.all b/data/shaders/conditionals-step-conditional.all
new file mode 100644
index 0000000..e8ca730
--- /dev/null
+++ b/data/shaders/conditionals-step-conditional.all
@@ -0,0 +1,4 @@
+ if (d >= 0.5)
+ d = fract(2.0 * d);
+ else
+ d = fract(3.0 * d);
diff --git a/data/shaders/conditionals-step-simple.all b/data/shaders/conditionals-step-simple.all
new file mode 100644
index 0000000..9b64c37
--- /dev/null
+++ b/data/shaders/conditionals-step-simple.all
@@ -0,0 +1 @@
+ d = fract(3.0 * d);
diff --git a/data/shaders/conditionals.frag b/data/shaders/conditionals.frag
new file mode 100644
index 0000000..3bd2507
--- /dev/null
+++ b/data/shaders/conditionals.frag
@@ -0,0 +1,11 @@
+varying vec4 dummy;
+
+void main(void)
+{
+ float d = fract(gl_FragCoord.x * gl_FragCoord.y * 0.0001);
+
+$MAIN$
+
+ gl_FragColor = vec4(d, d, d, 1.0);
+}
+
diff --git a/data/shaders/conditionals.vert b/data/shaders/conditionals.vert
new file mode 100644
index 0000000..83eb9cc
--- /dev/null
+++ b/data/shaders/conditionals.vert
@@ -0,0 +1,25 @@
+attribute vec3 position;
+
+uniform mat4 ModelViewProjectionMatrix;
+
+// Removing this varying causes an inexplicable performance regression
+// with r600g... Keeping it for now.
+varying vec4 dummy;
+
+void main(void)
+{
+ dummy = vec4(1.0);
+
+ float d = fract(position.x);
+
+$MAIN$
+
+ vec4 pos = vec4(position.x,
+ position.y + 0.1 * d * fract(position.x),
+ position.z, 1.0);
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * pos;
+}
+
+
diff --git a/data/shaders/depth.frag b/data/shaders/depth.frag
new file mode 100644
index 0000000..e2a5256
--- /dev/null
+++ b/data/shaders/depth.frag
@@ -0,0 +1,6 @@
+varying vec3 Normal;
+
+void main()
+{
+ gl_FragColor = vec4(Normal, 1.0);
+}
diff --git a/data/shaders/depth.vert b/data/shaders/depth.vert
new file mode 100644
index 0000000..f424032
--- /dev/null
+++ b/data/shaders/depth.vert
@@ -0,0 +1,12 @@
+attribute vec3 position;
+attribute vec3 normal;
+
+uniform mat4 ModelViewProjectionMatrix;
+
+varying vec3 Normal;
+
+void main(void)
+{
+ Normal = normal;
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
diff --git a/data/shaders/desktop-blur.frag b/data/shaders/desktop-blur.frag
new file mode 100644
index 0000000..1b29ff5
--- /dev/null
+++ b/data/shaders/desktop-blur.frag
@@ -0,0 +1,13 @@
+uniform sampler2D Texture0;
+
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ vec4 result;
+
+ $CONVOLUTION$
+
+ gl_FragColor = vec4(result.xyz, 1.0);
+}
+
diff --git a/data/shaders/desktop.frag b/data/shaders/desktop.frag
new file mode 100644
index 0000000..f7ed2fd
--- /dev/null
+++ b/data/shaders/desktop.frag
@@ -0,0 +1,10 @@
+uniform sampler2D MaterialTexture0;
+
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ vec4 texel = texture2D(MaterialTexture0, TextureCoord);
+ gl_FragColor = texel;
+}
+
diff --git a/data/shaders/desktop.vert b/data/shaders/desktop.vert
new file mode 100644
index 0000000..1ebaaab
--- /dev/null
+++ b/data/shaders/desktop.vert
@@ -0,0 +1,11 @@
+attribute vec2 position;
+attribute vec2 texcoord;
+
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ gl_Position = vec4(position, 0.0, 1.0);
+
+ TextureCoord = texcoord;
+}
diff --git a/data/shaders/effect-2d-convolution.frag b/data/shaders/effect-2d-convolution.frag
new file mode 100644
index 0000000..63763e8
--- /dev/null
+++ b/data/shaders/effect-2d-convolution.frag
@@ -0,0 +1,12 @@
+uniform sampler2D Texture0;
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ vec4 result;
+
+ $CONVOLUTION$
+
+ gl_FragColor = vec4(result.xyz, 1.0);
+}
+
diff --git a/data/shaders/effect-2d.vert b/data/shaders/effect-2d.vert
new file mode 100644
index 0000000..d0aa488
--- /dev/null
+++ b/data/shaders/effect-2d.vert
@@ -0,0 +1,10 @@
+attribute vec3 position;
+
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ gl_Position = vec4(position, 1.0);
+
+ TextureCoord = position.xy * 0.5 + 0.5;
+}
diff --git a/data/shaders/function-call.all b/data/shaders/function-call.all
new file mode 100644
index 0000000..9bb02a4
--- /dev/null
+++ b/data/shaders/function-call.all
@@ -0,0 +1 @@
+ d = process(d);
diff --git a/data/shaders/function-step-low.all b/data/shaders/function-step-low.all
new file mode 100644
index 0000000..9b64c37
--- /dev/null
+++ b/data/shaders/function-step-low.all
@@ -0,0 +1 @@
+ d = fract(3.0 * d);
diff --git a/data/shaders/function-step-medium.all b/data/shaders/function-step-medium.all
new file mode 100644
index 0000000..90b900b
--- /dev/null
+++ b/data/shaders/function-step-medium.all
@@ -0,0 +1,2 @@
+ d = fract(3.0 * d) * fract(3.0 * d);
+ d = fract(sqrt(d));
diff --git a/data/shaders/function.frag b/data/shaders/function.frag
new file mode 100644
index 0000000..3e3c74f
--- /dev/null
+++ b/data/shaders/function.frag
@@ -0,0 +1,16 @@
+varying vec4 dummy;
+
+float process(float d)
+{
+$PROCESS$
+ return d;
+}
+
+void main(void)
+{
+ float d = fract(gl_FragCoord.x * gl_FragCoord.y * 0.0001);
+
+$MAIN$
+
+ gl_FragColor = vec4(d, d, d, 1.0);
+}
diff --git a/data/shaders/function.vert b/data/shaders/function.vert
new file mode 100644
index 0000000..5fa357e
--- /dev/null
+++ b/data/shaders/function.vert
@@ -0,0 +1,30 @@
+attribute vec3 position;
+
+uniform mat4 ModelViewProjectionMatrix;
+
+// Removing this varying causes an inexplicable performance regression
+// with r600g... Keeping it for now.
+varying vec4 dummy;
+
+float process(float d)
+{
+ $PROCESS$
+ return d;
+}
+
+void main(void)
+{
+ dummy = vec4(1.0);
+
+ float d = fract(position.x);
+
+ $MAIN$
+
+ vec4 pos = vec4(position.x,
+ position.y + 0.1 * d * fract(position.x),
+ position.z, 1.0);
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * pos;
+}
+
diff --git a/data/shaders/gradient.frag b/data/shaders/gradient.frag
new file mode 100644
index 0000000..e93bf00
--- /dev/null
+++ b/data/shaders/gradient.frag
@@ -0,0 +1,10 @@
+uniform vec3 color1;
+uniform vec3 color2;
+
+varying vec2 uv;
+
+void main()
+{
+ vec3 color = mix(color1, color2, uv.x * uv.y);
+ gl_FragColor = vec4(color, 1.0);
+}
diff --git a/data/shaders/gradient.vert b/data/shaders/gradient.vert
new file mode 100644
index 0000000..f9c8a88
--- /dev/null
+++ b/data/shaders/gradient.vert
@@ -0,0 +1,10 @@
+attribute vec2 position;
+attribute vec2 uvIn;
+
+varying vec2 uv;
+
+void main()
+{
+ uv = uvIn;
+ gl_Position = vec4(position, 1.0, 1.0);
+}
diff --git a/data/shaders/ideas-lamp-lit.frag b/data/shaders/ideas-lamp-lit.frag
new file mode 100644
index 0000000..8664241
--- /dev/null
+++ b/data/shaders/ideas-lamp-lit.frag
@@ -0,0 +1,68 @@
+struct LightSourceParameters
+{
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 specular;
+ vec4 position;
+};
+LightSourceParameters lightSource[3];
+uniform mat4 modelview;
+uniform vec4 light0Position;
+uniform vec4 light1Position;
+uniform vec4 light2Position;
+varying vec3 vertex_normal;
+varying vec4 vertex_position;
+varying vec3 eye_direction;
+
+vec3 unitvec(vec4 v1, vec4 v2)
+{
+ if (v1.w == 0.0 && v2.w == 0.0)
+ return vec3(v2 - v1);
+ if (v1.w == 0.0)
+ return vec3(-v1);
+ if (v2.w == 0.0)
+ return vec3(v2);
+ return v2.xyz/v2.w - v1.xyz/v1.w;
+}
+
+void main()
+{
+ lightSource[0] = LightSourceParameters(
+ vec4(0.0, 0.0, 0.0, 1.0),
+ vec4(1.0, 1.0, 1.0, 1.0),
+ vec4(1.0, 1.0, 1.0, 1.0),
+ vec4(0.0, 1.0, 0.0, 0.0)
+ );
+ lightSource[1] = LightSourceParameters(
+ vec4(0.0, 0.0, 0.0, 1.0),
+ vec4(0.3, 0.3, 0.5, 1.0),
+ vec4(0.3, 0.3, 0.5, 1.0),
+ vec4(-1.0, 0.0, 0.0, 0.0)
+ );
+ lightSource[2] = LightSourceParameters(
+ vec4(0.2, 0.2, 0.2, 1.0),
+ vec4(0.2, 0.2, 0.2, 1.0),
+ vec4(0.2, 0.2, 0.2, 1.0),
+ vec4(0.0, -1.0, 0.0, 0.0)
+ );
+ vec4 matAmbient = vec4(0.0, 0.0, 0.0, 1.0);
+ vec4 matDiffuse = vec4(1.0, 0.2, 0.2, 1.0);
+ vec4 matSpecular = vec4(0.5, 0.5, 0.5, 1.0);
+ float matShininess = 20.0;
+ vec4 diffuseSum = vec4(0.0, 0.0, 0.0, 0.0);
+ vec4 specularSum = vec4(0.0, 0.0, 0.0, 0.0);
+ vec4 ambientSum = vec4(0.0, 0.0, 0.0, 0.0);
+ vec3 normalized_normal = normalize(vertex_normal);
+ lightSource[0].position = light0Position;
+ lightSource[1].position = light1Position;
+ lightSource[2].position = light2Position;
+ for (int light = 0; light < 3; light++) {
+ vec4 light_position = lightSource[light].position;
+ vec3 light_direction = normalize(unitvec(vertex_position, light_position));
+ vec3 reflection = reflect(-light_direction, normalized_normal);
+ specularSum += pow(max(0.0, dot(reflection, eye_direction)), matShininess) * lightSource[light].specular;
+ diffuseSum += max(0.0, dot(normalized_normal, light_direction)) * lightSource[light].diffuse;
+ ambientSum += lightSource[light].ambient;
+ }
+ gl_FragColor = (matSpecular * specularSum) + (matAmbient * ambientSum) + (matDiffuse * diffuseSum);
+}
diff --git a/data/shaders/ideas-lamp-lit.vert b/data/shaders/ideas-lamp-lit.vert
new file mode 100644
index 0000000..8098ce4
--- /dev/null
+++ b/data/shaders/ideas-lamp-lit.vert
@@ -0,0 +1,28 @@
+uniform mat4 projection;
+uniform mat4 modelview;
+uniform mat3 normalMatrix;
+varying vec3 vertex_normal;
+varying vec4 vertex_position;
+varying vec3 eye_direction;
+attribute vec3 vertex;
+attribute vec3 normal;
+
+vec3 unitvec(vec4 v1, vec4 v2)
+{
+ if (v1.w == 0.0 && v2.w == 0.0)
+ return vec3(v2 - v1);
+ if (v1.w == 0.0)
+ return vec3(-v1);
+ if (v2.w == 0.0)
+ return vec3(v2);
+ return v2.xyz/v2.w - v1.xyz/v1.w;
+}
+
+void main()
+{
+ vec4 curVertex = vec4(vertex.x, vertex.y, vertex.z, 1.0);
+ gl_Position = projection * modelview * curVertex;
+ vertex_normal = normalMatrix * normal;
+ vertex_position = modelview * curVertex;
+ eye_direction = normalize(unitvec(vertex_position, vec4(0.0, 0.0, 0.0, 1.0)));
+}
diff --git a/data/shaders/ideas-lamp-unlit.frag b/data/shaders/ideas-lamp-unlit.frag
new file mode 100644
index 0000000..b290d9d
--- /dev/null
+++ b/data/shaders/ideas-lamp-unlit.frag
@@ -0,0 +1,6 @@
+varying vec4 color;
+
+void main()
+{
+ gl_FragColor = color;
+}
diff --git a/data/shaders/ideas-lamp-unlit.vert b/data/shaders/ideas-lamp-unlit.vert
new file mode 100644
index 0000000..e8d6044
--- /dev/null
+++ b/data/shaders/ideas-lamp-unlit.vert
@@ -0,0 +1,11 @@
+uniform mat4 projection;
+uniform mat4 modelview;
+attribute vec3 vertex;
+varying vec4 color;
+
+void main()
+{
+ vec4 curVertex = vec4(vertex.x, vertex.y, vertex.z, 1.0);
+ gl_Position = projection * modelview * curVertex;
+ color = vec4(1.0, 1.0, 1.0, 1.0);
+}
diff --git a/data/shaders/ideas-logo-flat.frag b/data/shaders/ideas-logo-flat.frag
new file mode 100644
index 0000000..509e58d
--- /dev/null
+++ b/data/shaders/ideas-logo-flat.frag
@@ -0,0 +1,6 @@
+uniform vec4 logoColor;
+
+void main()
+{
+ gl_FragColor = logoColor;
+}
diff --git a/data/shaders/ideas-logo-flat.vert b/data/shaders/ideas-logo-flat.vert
new file mode 100644
index 0000000..664cc73
--- /dev/null
+++ b/data/shaders/ideas-logo-flat.vert
@@ -0,0 +1,9 @@
+uniform mat4 projection;
+uniform mat4 modelview;
+attribute vec3 vertex;
+
+void main()
+{
+ vec4 curVertex = vec4(vertex.x, vertex.y, vertex.z, 1.0);
+ gl_Position = projection * modelview * curVertex;
+}
diff --git a/data/shaders/ideas-logo-shadow.frag b/data/shaders/ideas-logo-shadow.frag
new file mode 100644
index 0000000..6b9e83a
--- /dev/null
+++ b/data/shaders/ideas-logo-shadow.frag
@@ -0,0 +1,10 @@
+uniform sampler2D tex;
+
+void main()
+{
+ vec2 curPos = gl_FragCoord.xy / 32.0;
+ vec4 color = texture2D(tex, curPos);
+ if (color.w < 0.5)
+ discard;
+ gl_FragColor = color;
+}
diff --git a/data/shaders/ideas-logo-shadow.vert b/data/shaders/ideas-logo-shadow.vert
new file mode 100644
index 0000000..664cc73
--- /dev/null
+++ b/data/shaders/ideas-logo-shadow.vert
@@ -0,0 +1,9 @@
+uniform mat4 projection;
+uniform mat4 modelview;
+attribute vec3 vertex;
+
+void main()
+{
+ vec4 curVertex = vec4(vertex.x, vertex.y, vertex.z, 1.0);
+ gl_Position = projection * modelview * curVertex;
+}
diff --git a/data/shaders/ideas-logo.frag b/data/shaders/ideas-logo.frag
new file mode 100644
index 0000000..61b1d4f
--- /dev/null
+++ b/data/shaders/ideas-logo.frag
@@ -0,0 +1,35 @@
+uniform vec4 light0Position;
+varying vec3 vertex_normal;
+varying vec4 vertex_position;
+varying vec3 eye_direction;
+
+vec3 unitvec(vec4 v1, vec4 v2)
+{
+ if (v1.w == 0.0 && v2.w == 0.0)
+ return vec3(v2 - v1);
+ if (v1.w == 0.0)
+ return vec3(-v1);
+ if (v2.w == 0.0)
+ return vec3(v2);
+ return v2.xyz/v2.w - v1.xyz/v1.w;
+}
+
+void main()
+{
+ vec4 lightAmbient = vec4(0.0, 0.0, 0.0, 1.0);
+ vec4 lightDiffuse = vec4(1.0, 1.0, 1.0, 1.0);
+ vec4 lightSpecular = vec4(1.0, 1.0, 1.0, 1.0);
+ vec4 matAmbient = vec4(0.1, 0.1, 0.1, 1.0);
+ vec4 matDiffuse = vec4(0.5, 0.4, 0.7, 1.0);
+ vec4 matSpecular = vec4(1.0, 1.0, 1.0, 1.0);
+ float matShininess = 30.0;
+ vec3 light_direction = normalize(unitvec(vertex_position, light0Position));
+ vec3 normalized_normal = normalize(vertex_normal);
+ vec3 reflection = reflect(-light_direction, normalized_normal);
+ float specularTerm = pow(max(0.0, dot(reflection, eye_direction)), matShininess);
+ float diffuseTerm = max(0.0, dot(normalized_normal, light_direction));
+ vec4 specular = (lightSpecular * matSpecular);
+ vec4 ambient = (lightAmbient * matAmbient);
+ vec4 diffuse = (lightDiffuse * matDiffuse);
+ gl_FragColor = (specular * specularTerm) + ambient + (diffuse * diffuseTerm);
+}
diff --git a/data/shaders/ideas-logo.vert b/data/shaders/ideas-logo.vert
new file mode 100644
index 0000000..8098ce4
--- /dev/null
+++ b/data/shaders/ideas-logo.vert
@@ -0,0 +1,28 @@
+uniform mat4 projection;
+uniform mat4 modelview;
+uniform mat3 normalMatrix;
+varying vec3 vertex_normal;
+varying vec4 vertex_position;
+varying vec3 eye_direction;
+attribute vec3 vertex;
+attribute vec3 normal;
+
+vec3 unitvec(vec4 v1, vec4 v2)
+{
+ if (v1.w == 0.0 && v2.w == 0.0)
+ return vec3(v2 - v1);
+ if (v1.w == 0.0)
+ return vec3(-v1);
+ if (v2.w == 0.0)
+ return vec3(v2);
+ return v2.xyz/v2.w - v1.xyz/v1.w;
+}
+
+void main()
+{
+ vec4 curVertex = vec4(vertex.x, vertex.y, vertex.z, 1.0);
+ gl_Position = projection * modelview * curVertex;
+ vertex_normal = normalMatrix * normal;
+ vertex_position = modelview * curVertex;
+ eye_direction = normalize(unitvec(vertex_position, vec4(0.0, 0.0, 0.0, 1.0)));
+}
diff --git a/data/shaders/ideas-paper.frag b/data/shaders/ideas-paper.frag
new file mode 100644
index 0000000..b290d9d
--- /dev/null
+++ b/data/shaders/ideas-paper.frag
@@ -0,0 +1,6 @@
+varying vec4 color;
+
+void main()
+{
+ gl_FragColor = color;
+}
diff --git a/data/shaders/ideas-paper.vert b/data/shaders/ideas-paper.vert
new file mode 100644
index 0000000..74571c6
--- /dev/null
+++ b/data/shaders/ideas-paper.vert
@@ -0,0 +1,22 @@
+uniform mat4 projection;
+uniform mat4 modelview;
+uniform vec3 lightPosition;
+uniform vec3 logoDirection;
+uniform float currentTime;
+attribute vec3 vertex;
+varying vec4 color;
+
+void main()
+{
+ vec4 curVertex = vec4(vertex.x, vertex.y, vertex.z, 1.0);
+ gl_Position = projection * modelview * curVertex;
+ float referenceTime = 15.0;
+ vec3 lightDirection = normalize(lightPosition - vertex);
+ float c = max(dot(lightDirection, logoDirection), 0.0);
+ c = c * c * c * lightDirection.y;
+ if ((currentTime > referenceTime - 5.0) && (currentTime < referenceTime - 3.0))
+ {
+ c *= 1.0 - (currentTime - (referenceTime - 5.0)) * 0.5;
+ }
+ color = vec4(c, c, (c * 0.78125), 1.0);
+}
diff --git a/data/shaders/ideas-table.frag b/data/shaders/ideas-table.frag
new file mode 100644
index 0000000..b290d9d
--- /dev/null
+++ b/data/shaders/ideas-table.frag
@@ -0,0 +1,6 @@
+varying vec4 color;
+
+void main()
+{
+ gl_FragColor = color;
+}
diff --git a/data/shaders/ideas-table.vert b/data/shaders/ideas-table.vert
new file mode 100644
index 0000000..0994d64
--- /dev/null
+++ b/data/shaders/ideas-table.vert
@@ -0,0 +1,22 @@
+uniform mat4 projection;
+uniform mat4 modelview;
+uniform vec3 lightPosition;
+uniform vec3 logoDirection;
+uniform float currentTime;
+attribute vec3 vertex;
+varying vec4 color;
+
+void main()
+{
+ vec4 curVertex = vec4(vertex.x, vertex.y, vertex.z, 1.0);
+ gl_Position = projection * modelview * curVertex;
+ float referenceTime = 15.0;
+ vec3 lightDirection = normalize(lightPosition - vertex);
+ float c = max(dot(lightDirection, logoDirection), 0.0);
+ c = c * c * c * lightDirection.y;
+ if ((currentTime > referenceTime - 5.0) && (currentTime < referenceTime - 3.0))
+ {
+ c *= 1.0 - (currentTime - (referenceTime - 5.0)) * 0.5;
+ }
+ color = vec4(c, c, c, 1.0);
+}
diff --git a/data/shaders/ideas-text.frag b/data/shaders/ideas-text.frag
new file mode 100644
index 0000000..b290d9d
--- /dev/null
+++ b/data/shaders/ideas-text.frag
@@ -0,0 +1,6 @@
+varying vec4 color;
+
+void main()
+{
+ gl_FragColor = color;
+}
diff --git a/data/shaders/ideas-text.vert b/data/shaders/ideas-text.vert
new file mode 100644
index 0000000..38a3126
--- /dev/null
+++ b/data/shaders/ideas-text.vert
@@ -0,0 +1,18 @@
+uniform mat4 projection;
+uniform mat4 modelview;
+uniform float currentTime;
+attribute vec2 vertex;
+varying vec4 color;
+
+void main()
+{
+ vec4 curVertex = vec4(vertex.x, vertex.y, 0.0, 1.0);
+ gl_Position = projection * modelview * curVertex;
+ float referenceTime = 15.0;
+ float c = 0.0;
+ if (currentTime > referenceTime * 1.0 - 5.0)
+ {
+ c = (currentTime - (referenceTime * 1.0 - 5.0)) / 2.0;
+ }
+ color = vec4(c, c, c, 1.0);
+}
diff --git a/data/shaders/ideas-under-table.frag b/data/shaders/ideas-under-table.frag
new file mode 100644
index 0000000..b290d9d
--- /dev/null
+++ b/data/shaders/ideas-under-table.frag
@@ -0,0 +1,6 @@
+varying vec4 color;
+
+void main()
+{
+ gl_FragColor = color;
+}
diff --git a/data/shaders/ideas-under-table.vert b/data/shaders/ideas-under-table.vert
new file mode 100644
index 0000000..cd19539
--- /dev/null
+++ b/data/shaders/ideas-under-table.vert
@@ -0,0 +1,11 @@
+uniform mat4 projection;
+uniform mat4 modelview;
+attribute vec3 vertex;
+varying vec4 color;
+
+void main()
+{
+ vec4 curVertex = vec4(vertex.x, vertex.y, vertex.z, 1.0);
+ gl_Position = projection * modelview * curVertex;
+ color = vec4(0.0, 0.0, 0.0, 1.0);
+}
diff --git a/data/shaders/jellyfish.frag b/data/shaders/jellyfish.frag
new file mode 100644
index 0000000..62c9960
--- /dev/null
+++ b/data/shaders/jellyfish.frag
@@ -0,0 +1,21 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+
+uniform sampler2D uSampler;
+uniform sampler2D uSampler1;
+uniform float uCurrentTime;
+
+varying vec2 vTextureCoord;
+varying vec4 vWorld;
+varying vec3 vDiffuse;
+varying vec3 vAmbient;
+varying vec3 vFresnel;
+
+void main(void)
+{
+ vec4 caustics = texture2D(uSampler1, vec2(vWorld.x / 24.0 + uCurrentTime / 20.0, (vWorld.z - vWorld.y)/48.0 + uCurrentTime / 40.0));
+ vec4 colorMap = texture2D(uSampler, vTextureCoord);
+ float transparency = colorMap.a + pow(vFresnel.r, 2.0) - 0.3;
+ gl_FragColor = vec4(((vAmbient + vDiffuse + caustics.rgb) * colorMap.rgb), transparency);
+}
diff --git a/data/shaders/jellyfish.vert b/data/shaders/jellyfish.vert
new file mode 100644
index 0000000..c125370
--- /dev/null
+++ b/data/shaders/jellyfish.vert
@@ -0,0 +1,56 @@
+attribute vec3 aVertexPosition;
+attribute vec3 aVertexNormal;
+attribute vec3 aVertexColor;
+attribute vec3 aTextureCoord;
+
+uniform mat4 uWorld;
+uniform mat4 uWorldViewProj;
+uniform mat4 uWorldInvTranspose;
+uniform vec3 uLightPos;
+uniform float uLightRadius;
+uniform vec4 uLightCol;
+uniform vec4 uAmbientCol;
+uniform vec4 uFresnelCol;
+uniform float uFresnelPower;
+uniform float uCurrentTime;
+
+varying vec2 vTextureCoord;
+varying vec4 vWorld;
+varying vec3 vDiffuse;
+varying vec3 vAmbient;
+varying vec3 vFresnel;
+
+void main(void)
+{
+ //Vertex Animation
+ float speed = uCurrentTime / 15.0;
+ float offset = smoothstep(0.0, 1.0, max(0.0, -aVertexPosition.y-0.8) / 10.0);
+ vec3 pos = aVertexPosition +
+ aVertexColor / 12.0 *
+ sin(speed * 15.0 + aVertexPosition.y / 2.0) * (1.0 - offset);
+ pos = pos + aVertexColor / 8.0 *
+ sin(speed * 30.0 + aVertexPosition.y / 0.5) * (1.0 - offset);
+ vec4 pos4 = vec4(pos, 1.0);
+ gl_Position = uWorldViewProj * pos4;
+
+ vWorld = uWorld * pos4;
+ vec3 vVertexNormal = normalize((uWorldInvTranspose * vec4(aVertexNormal, 1.0)).xyz);
+
+ //diffuse
+ vec3 lightDir = normalize(uLightPos - vWorld.xyz);
+ float diffuseProduct = max(dot(normalize(vVertexNormal.xyz), lightDir), 0.0);
+ float lightFalloff = pow(max(1.0-(distance(uLightPos, vWorld.xyz)/uLightRadius), 0.0),2.0);
+ vDiffuse = uLightCol.rgb * vec3(diffuseProduct * lightFalloff * uLightCol.a);
+
+ //ambient (top)
+ vAmbient = uAmbientCol.rgb * vec3(uAmbientCol.a) * vVertexNormal.y;
+
+ //fresnel
+ vec4 worldPos = uWorld * pos4;
+ vec3 vWorldEyeVec = normalize(worldPos.xyz/worldPos.w);
+ float fresnelProduct = pow(1.0 - max(abs(dot(vVertexNormal, -vWorldEyeVec)), 0.0), uFresnelPower);
+ vFresnel = uFresnelCol.rgb * vec3(uFresnelCol.a * fresnelProduct);
+
+ // texcoord
+ vTextureCoord = aTextureCoord.xy;
+}
diff --git a/data/shaders/light-advanced.frag b/data/shaders/light-advanced.frag
new file mode 100644
index 0000000..054c7e0
--- /dev/null
+++ b/data/shaders/light-advanced.frag
@@ -0,0 +1,33 @@
+varying vec3 Normal;
+
+void main(void)
+{
+ const vec4 LightSourceAmbient = vec4(0.1, 0.1, 0.1, 1.0);
+ const vec4 LightSourceDiffuse = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 LightSourceSpecular = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 MaterialAmbient = vec4(1.0, 1.0, 1.0, 1.0);
+ const vec4 MaterialDiffuse = vec4(0.0, 0.0, 1.0, 1.0);
+ const vec4 MaterialSpecular = vec4(1.0, 1.0, 1.0, 1.0);
+ const float MaterialShininess = 100.0;
+
+ vec3 N = normalize(Normal);
+
+ // In the lighting model we are using here (Blinn-Phong with light at
+ // infinity, viewer at infinity), the light position/direction and the
+ // half vector is constant for the all the fragments.
+ vec3 L = normalize(LightSourcePosition.xyz);
+ vec3 H = normalize(LightSourceHalfVector);
+
+ // Calculate the diffuse color according to Lambertian reflectance
+ vec4 diffuse = MaterialDiffuse * LightSourceDiffuse * max(dot(N, L), 0.0);
+
+ // Calculate the ambient color
+ vec4 ambient = MaterialAmbient * LightSourceAmbient;
+
+ // Calculate the specular color according to the Blinn-Phong model
+ vec4 specular = MaterialSpecular * LightSourceSpecular *
+ pow(max(dot(N,H), 0.0), MaterialShininess);
+
+ // Calculate the final color
+ gl_FragColor = vec4((ambient + specular + diffuse).xyz, 1.0);
+}
diff --git a/data/shaders/light-advanced.vert b/data/shaders/light-advanced.vert
new file mode 100644
index 0000000..0207c37
--- /dev/null
+++ b/data/shaders/light-advanced.vert
@@ -0,0 +1,16 @@
+attribute vec3 position;
+attribute vec3 normal;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 NormalMatrix;
+
+varying vec3 Normal;
+
+void main(void)
+{
+ // Transform the normal to eye coordinates
+ Normal = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
diff --git a/data/shaders/light-basic-tex-bilinear.frag b/data/shaders/light-basic-tex-bilinear.frag
new file mode 100644
index 0000000..ffeba8a
--- /dev/null
+++ b/data/shaders/light-basic-tex-bilinear.frag
@@ -0,0 +1,31 @@
+uniform sampler2D MaterialTexture0;
+
+varying vec4 Color;
+varying vec2 TextureCoord;
+
+const vec2 TexelSize = vec2(1.0 / TextureSize.x, 1.0 / TextureSize.y);
+
+/*
+ * See http://www.gamerendering.com/2008/10/05/bilinear-interpolation/
+ * for a more thorough explanation of how this works.
+ */
+vec4 texture2DBilinear(sampler2D sampler, vec2 uv)
+{
+ // Get the needed texture samples
+ vec4 tl = texture2D(sampler, uv);
+ vec4 tr = texture2D(sampler, uv + vec2(TexelSize.x, 0));
+ vec4 bl = texture2D(sampler, uv + vec2(0, TexelSize.y));
+ vec4 br = texture2D(sampler, uv + vec2(TexelSize.x , TexelSize.y));
+
+ // Mix the samples according to the GL specification
+ vec2 f = fract(uv * TextureSize);
+ vec4 tA = mix(tl, tr, f.x);
+ vec4 tB = mix(bl, br, f.x);
+ return mix(tA, tB, f.y);
+}
+
+void main(void)
+{
+ vec4 texel = texture2DBilinear(MaterialTexture0, TextureCoord);
+ gl_FragColor = texel * Color;
+}
diff --git a/data/shaders/light-basic-tex.frag b/data/shaders/light-basic-tex.frag
new file mode 100644
index 0000000..f87ced1
--- /dev/null
+++ b/data/shaders/light-basic-tex.frag
@@ -0,0 +1,11 @@
+uniform sampler2D MaterialTexture0;
+
+varying vec4 Color;
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ vec4 texel = texture2D(MaterialTexture0, TextureCoord);
+ gl_FragColor = texel * Color;
+}
+
diff --git a/data/shaders/light-basic-texgen.vert b/data/shaders/light-basic-texgen.vert
new file mode 100644
index 0000000..6198a64
--- /dev/null
+++ b/data/shaders/light-basic-texgen.vert
@@ -0,0 +1,30 @@
+attribute vec3 position;
+attribute vec3 normal;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 NormalMatrix;
+uniform vec3 CenterPoint;
+
+varying vec4 Color;
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ // Transform the normal to eye coordinates
+ vec3 N = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));
+
+ // The LightSourcePosition is actually its direction for directional light
+ vec3 L = normalize(LightSourcePosition.xyz);
+
+ // Multiply the diffuse value by the vertex color (which is fixed in this case)
+ // to get the actual color that we will use to draw this vertex with
+ float diffuse = max(dot(N, L), 0.0);
+ Color = vec4(diffuse * MaterialDiffuse.rgb, MaterialDiffuse.a);
+
+ // Compute the texture coordinate and as a varying
+ vec3 vnorm = normalize(position - CenterPoint);
+ TextureCoord = asin(vnorm.xy) / PI + 0.5;
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
diff --git a/data/shaders/light-basic.frag b/data/shaders/light-basic.frag
new file mode 100644
index 0000000..a5278db
--- /dev/null
+++ b/data/shaders/light-basic.frag
@@ -0,0 +1,7 @@
+varying vec4 Color;
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ gl_FragColor = Color;
+}
diff --git a/data/shaders/light-basic.vert b/data/shaders/light-basic.vert
new file mode 100644
index 0000000..609c9c0
--- /dev/null
+++ b/data/shaders/light-basic.vert
@@ -0,0 +1,29 @@
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec2 texcoord;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 NormalMatrix;
+
+varying vec4 Color;
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ // Transform the normal to eye coordinates
+ vec3 N = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));
+
+ // The LightSourcePosition is actually its direction for directional light
+ vec3 L = normalize(LightSourcePosition.xyz);
+
+ // Multiply the diffuse value by the vertex color (which is fixed in this case)
+ // to get the actual color that we will use to draw this vertex with
+ float diffuse = max(dot(N, L), 0.0);
+ Color = vec4(diffuse * MaterialDiffuse.rgb, MaterialDiffuse.a);
+
+ // Set the texture coordinates as a varying
+ TextureCoord = texcoord;
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
diff --git a/data/shaders/light-phong.frag b/data/shaders/light-phong.frag
new file mode 100644
index 0000000..bbc7a3d
--- /dev/null
+++ b/data/shaders/light-phong.frag
@@ -0,0 +1,29 @@
+varying vec3 vertex_normal;
+varying vec4 vertex_position;
+
+vec4
+compute_color(vec4 light_position, vec4 diffuse_light_color)
+{
+ const vec4 lightAmbient = vec4(0.1, 0.1, 0.1, 1.0);
+ const vec4 lightSpecular = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 matAmbient = vec4(0.2, 0.2, 0.2, 1.0);
+ const vec4 matSpecular = vec4(1.0, 1.0, 1.0, 1.0);
+ const float matShininess = 100.0;
+ vec3 eye_direction = normalize(-vertex_position.xyz);
+ vec3 light_direction = normalize(light_position.xyz/light_position.w -
+ vertex_position.xyz/vertex_position.w);
+ vec3 normalized_normal = normalize(vertex_normal);
+ vec3 reflection = reflect(-light_direction, normalized_normal);
+ float specularTerm = pow(max(0.0, dot(reflection, eye_direction)), matShininess);
+ float diffuseTerm = max(0.0, dot(normalized_normal, light_direction));
+ vec4 specular = (lightSpecular * matSpecular);
+ vec4 ambient = (lightAmbient * matAmbient);
+ vec4 diffuse = (diffuse_light_color * MaterialDiffuse);
+ vec4 result = (specular * specularTerm) + ambient + (diffuse * diffuseTerm);
+ return result;
+}
+
+void main(void)
+{
+$DO_LIGHTS$
+}
diff --git a/data/shaders/light-phong.vert b/data/shaders/light-phong.vert
new file mode 100644
index 0000000..8a95ca7
--- /dev/null
+++ b/data/shaders/light-phong.vert
@@ -0,0 +1,23 @@
+attribute vec3 position;
+attribute vec3 normal;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 NormalMatrix;
+uniform mat4 ModelViewMatrix;
+
+varying vec3 vertex_normal;
+varying vec4 vertex_position;
+
+void main(void)
+{
+ vec4 current_position = vec4(position, 1.0);
+
+ // Transform the normal to eye coordinates
+ vertex_normal = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));
+
+ // Transform the current position to eye coordinates
+ vertex_position = ModelViewMatrix * current_position;
+
+ // Transform the current position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * current_position;
+}
diff --git a/data/shaders/light-refract.frag b/data/shaders/light-refract.frag
new file mode 100644
index 0000000..d1f1397
--- /dev/null
+++ b/data/shaders/light-refract.frag
@@ -0,0 +1,45 @@
+uniform sampler2D DistanceMap;
+uniform sampler2D NormalMap;
+uniform sampler2D ImageMap;
+
+varying vec3 vertex_normal;
+varying vec4 vertex_position;
+varying vec4 MapCoord;
+
+void main()
+{
+ const vec4 lightSpecular = vec4(0.8, 0.8, 0.8, 1.0);
+ const vec4 matSpecular = vec4(1.0, 1.0, 1.0, 1.0);
+ const float matShininess = 100.0;
+ const vec2 point_five = vec2(0.5);
+ // Need the normalized eye direction and surface normal vectors to
+ // compute the transmitted vector through the "front" surface of the object.
+ vec3 eye_direction = normalize(-vertex_position.xyz);
+ vec3 normalized_normal = normalize(vertex_normal);
+ vec3 front_refraction = refract(eye_direction, normalized_normal, RefractiveIndex);
+ // Find our best distance approximation through the object so we can
+ // project the transmitted vector to the back of the object to find
+ // the exit point.
+ vec3 mc_perspective = (MapCoord.xyz / MapCoord.w) + front_refraction;
+ vec2 dcoord = mc_perspective.st * point_five + point_five;
+ vec4 distance_value = texture2D(DistanceMap, dcoord);
+ vec3 back_position = vertex_position.xyz + front_refraction * distance_value.z;
+ // Use the exit point to index the map of back-side normals, and use the
+ // back-side position and normal to find the transmitted vector out of the
+ // object.
+ vec2 normcoord = back_position.st * point_five + point_five;
+ vec3 back_normal = texture2D(NormalMap, normcoord).xyz;
+ vec3 back_refraction = refract(back_position, back_normal, 1.0);
+ // Use the transmitted vector from the exit point to determine where
+ // the vector would intersect the environment (in this case a background
+ // image.
+ vec2 imagecoord = back_refraction.st * point_five + point_five;
+ vec4 texel = texture2D(ImageMap, imagecoord);
+ // Add in specular reflection, and we have our fragment value.
+ vec3 light_direction = normalize(vertex_position.xyz/vertex_position.w -
+ LightSourcePosition.xyz/LightSourcePosition.w);
+ vec3 reflection = reflect(light_direction, normalized_normal);
+ float specularTerm = pow(max(0.0, dot(reflection, eye_direction)), matShininess);
+ vec4 specular = (lightSpecular * matSpecular);
+ gl_FragColor = (specular * specularTerm) + texel;
+}
diff --git a/data/shaders/light-refract.vert b/data/shaders/light-refract.vert
new file mode 100644
index 0000000..9beeb9c
--- /dev/null
+++ b/data/shaders/light-refract.vert
@@ -0,0 +1,28 @@
+attribute vec3 position;
+attribute vec3 normal;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 NormalMatrix;
+uniform mat4 ModelViewMatrix;
+uniform mat4 LightMatrix;
+
+varying vec3 vertex_normal;
+varying vec4 vertex_position;
+varying vec4 MapCoord;
+
+void main(void)
+{
+ vec4 current_position = vec4(position, 1.0);
+
+ // Transform the normal to eye coordinates
+ vertex_normal = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));
+
+ // Transform the current position to eye coordinates
+ vertex_position = ModelViewMatrix * current_position;
+
+ // Transform the current position for use as texture coordinates
+ MapCoord = LightMatrix * current_position;
+
+ // Transform the current position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * current_position;
+}
diff --git a/data/shaders/loop-step-loop.all b/data/shaders/loop-step-loop.all
new file mode 100644
index 0000000..31b41f2
--- /dev/null
+++ b/data/shaders/loop-step-loop.all
@@ -0,0 +1,2 @@
+ for (int i = 0; i < $NLOOPS$; i++)
+ d = fract(3.0 * d);
diff --git a/data/shaders/loop-step-simple.all b/data/shaders/loop-step-simple.all
new file mode 100644
index 0000000..9b64c37
--- /dev/null
+++ b/data/shaders/loop-step-simple.all
@@ -0,0 +1 @@
+ d = fract(3.0 * d);
diff --git a/data/shaders/loop.frag b/data/shaders/loop.frag
new file mode 100644
index 0000000..31ae23e
--- /dev/null
+++ b/data/shaders/loop.frag
@@ -0,0 +1,12 @@
+varying vec4 dummy;
+uniform int FragmentLoops;
+
+void main(void)
+{
+ float d = fract(gl_FragCoord.x * gl_FragCoord.y * 0.0001);
+
+$MAIN$
+
+ gl_FragColor = vec4(d, d, d, 1.0);
+}
+
diff --git a/data/shaders/loop.vert b/data/shaders/loop.vert
new file mode 100644
index 0000000..853fab6
--- /dev/null
+++ b/data/shaders/loop.vert
@@ -0,0 +1,26 @@
+attribute vec3 position;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform int VertexLoops;
+
+// Removing this varying causes an inexplicable performance regression
+// with r600g... Keeping it for now.
+varying vec4 dummy;
+
+void main(void)
+{
+ dummy = vec4(1.0);
+
+ float d = fract(position.x);
+
+$MAIN$
+
+ vec4 pos = vec4(position.x,
+ position.y + 0.1 * d * fract(position.x),
+ position.z, 1.0);
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * pos;
+}
+
+
diff --git a/data/shaders/pulsar-light.vert b/data/shaders/pulsar-light.vert
new file mode 100644
index 0000000..57b96a6
--- /dev/null
+++ b/data/shaders/pulsar-light.vert
@@ -0,0 +1,31 @@
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec4 vtxcolor;
+attribute vec2 texcoord;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 NormalMatrix;
+
+varying vec4 Color;
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ // Transform the normal to eye coordinates
+ vec3 N = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));
+
+ // The LightSourcePosition is actually its direction for directional light
+ vec3 L = normalize(LightSourcePosition.xyz);
+
+ // Multiply the diffuse value by the vertex color
+ // to get the actual color that we will use to draw this vertex with
+ float diffuse = max(abs(dot(N, L)), 0.0);
+ Color = diffuse * vtxcolor;
+
+ // Set the texture coordinates as a varying
+ TextureCoord = texcoord;
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
+
diff --git a/data/shaders/pulsar.vert b/data/shaders/pulsar.vert
new file mode 100644
index 0000000..50b24da
--- /dev/null
+++ b/data/shaders/pulsar.vert
@@ -0,0 +1,19 @@
+attribute vec3 position;
+attribute vec4 vtxcolor;
+attribute vec2 texcoord;
+attribute vec3 normal;
+
+uniform mat4 ModelViewProjectionMatrix;
+
+varying vec4 Color;
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ Color = vtxcolor;
+ TextureCoord = texcoord;
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
+
diff --git a/data/shaders/shadow.frag b/data/shaders/shadow.frag
new file mode 100644
index 0000000..6b86ace
--- /dev/null
+++ b/data/shaders/shadow.frag
@@ -0,0 +1,17 @@
+uniform sampler2D ShadowMap;
+
+varying vec4 Color;
+varying vec4 ShadowCoord;
+
+void main()
+{
+ vec4 sc_perspective = ShadowCoord / ShadowCoord.w;
+ sc_perspective.z += 0.1505;
+ vec4 shadow_value = texture2D(ShadowMap, sc_perspective.st);
+ float light_distance = shadow_value.z;
+ float shadow = 1.0;
+ if (ShadowCoord.w > 0.0 && light_distance < sc_perspective.z) {
+ shadow = 0.5;
+ }
+ gl_FragColor = vec4(shadow * Color.rgb, 1.0);
+}
diff --git a/data/shaders/shadow.vert b/data/shaders/shadow.vert
new file mode 100644
index 0000000..a8ba2b4
--- /dev/null
+++ b/data/shaders/shadow.vert
@@ -0,0 +1,16 @@
+attribute vec2 position;
+
+uniform mat4 LightMatrix;
+uniform mat4 ModelViewProjectionMatrix;
+
+varying vec4 ShadowCoord;
+varying vec4 Color;
+
+void main()
+{
+ Color = MaterialDiffuse;
+
+ vec4 pos4 = vec4(position, 0.0, 1.0);
+ ShadowCoord = LightMatrix * pos4;
+ gl_Position = ModelViewProjectionMatrix * pos4;
+}
diff --git a/data/shaders/terrain-blur.frag b/data/shaders/terrain-blur.frag
new file mode 100644
index 0000000..a532e03
--- /dev/null
+++ b/data/shaders/terrain-blur.frag
@@ -0,0 +1,14 @@
+uniform sampler2D Texture0;
+
+varying vec2 vUv;
+
+void main(void)
+{
+ vec4 result;
+ vec2 TextureCoord = vUv;
+
+ $CONVOLUTION$
+
+ gl_FragColor = vec4(result.xyz, 1.0);
+}
+
diff --git a/data/shaders/terrain-luminance.frag b/data/shaders/terrain-luminance.frag
new file mode 100644
index 0000000..596862f
--- /dev/null
+++ b/data/shaders/terrain-luminance.frag
@@ -0,0 +1,15 @@
+uniform sampler2D tDiffuse;
+
+varying vec2 vUv;
+
+void main()
+{
+ vec4 texel = texture2D( tDiffuse, vUv );
+
+ vec3 luma = vec3( 0.299, 0.587, 0.114 );
+
+ float v = dot( texel.xyz, luma );
+
+ gl_FragColor = vec4( v, v, v, texel.w );
+}
+
diff --git a/data/shaders/terrain-noise.frag b/data/shaders/terrain-noise.frag
new file mode 100644
index 0000000..7fea5c0
--- /dev/null
+++ b/data/shaders/terrain-noise.frag
@@ -0,0 +1,124 @@
+//
+// Description : Array and textureless GLSL 3D simplex noise function.
+// Author : Ian McEwan, Ashima Arts.
+// Maintainer : ijm
+// Lastmod : 20110409 (stegu)
+// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
+// Distributed under the MIT License. See LICENSE file.
+//
+
+#ifdef GL_ES
+#define MEDIUMP mediump
+#else
+#define MEDIUMP
+#endif
+
+uniform float time;
+uniform MEDIUMP vec2 uvScale;
+varying vec2 vUv;
+
+vec4 permute(vec4 x)
+{
+ return mod(((x * 34.0) + 1.0) * x, 289.0);
+}
+
+vec4 taylorInvSqrt(vec4 r)
+{
+ return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+float snoise(vec3 v)
+{
+ const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);
+ const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
+
+ // First corner
+ vec3 i = floor(v + dot(v, C.yyy));
+ vec3 x0 = v - i + dot(i, C.xxx);
+
+ // Other corners
+ vec3 g = step(x0.yzx, x0.xyz);
+ vec3 l = 1.0 - g;
+ vec3 i1 = min(g.xyz, l.zxy);
+ vec3 i2 = max(g.xyz, l.zxy);
+
+ vec3 x1 = x0 - i1 + 1.0 * C.xxx;
+ vec3 x2 = x0 - i2 + 2.0 * C.xxx;
+ vec3 x3 = x0 - 1. + 3.0 * C.xxx;
+
+ // Permutations
+ i = mod(i, 289.0);
+ vec4 p = permute(permute(permute(
+ i.z + vec4(0.0, i1.z, i2.z, 1.0))
+ + i.y + vec4(0.0, i1.y, i2.y, 1.0))
+ + i.x + vec4(0.0, i1.x, i2.x, 1.0));
+
+ // Gradients
+ // (N*N points uniformly over a square, mapped onto an octahedron.)
+
+ float n_ = 1.0 / 7.0; // N=7
+
+ vec3 ns = n_ * D.wyz - D.xzx;
+
+ vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N)
+
+ vec4 x_ = floor(j * ns.z);
+ vec4 y_ = floor(j - 7.0 * x_); // mod(j,N)
+
+ vec4 x = x_ *ns.x + ns.yyyy;
+ vec4 y = y_ *ns.x + ns.yyyy;
+ vec4 h = 1.0 - abs(x) - abs(y);
+
+ vec4 b0 = vec4(x.xy, y.xy);
+ vec4 b1 = vec4(x.zw, y.zw);
+
+
+ vec4 s0 = floor(b0) * 2.0 + 1.0;
+ vec4 s1 = floor(b1) * 2.0 + 1.0;
+ vec4 sh = -step(h, vec4(0.0));
+
+ vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
+ vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
+
+ vec3 p0 = vec3(a0.xy, h.x);
+ vec3 p1 = vec3(a0.zw, h.y);
+ vec3 p2 = vec3(a1.xy, h.z);
+ vec3 p3 = vec3(a1.zw, h.w);
+
+ // Normalise gradients
+
+ vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
+ p0 *= norm.x;
+ p1 *= norm.y;
+ p2 *= norm.z;
+ p3 *= norm.w;
+
+ // Mix final noise value
+
+ vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
+ m = m * m;
+ return 42.0 * dot(m*m, vec4(dot(p0, x0), dot(p1, x1),
+ dot(p2, x2), dot(p3, x3)));
+}
+
+float surface3(vec3 coord)
+{
+ float n = 0.0;
+
+ n += 1.0 * abs(snoise(coord));
+ n += 0.5 * abs(snoise(coord * 2.0));
+ n += 0.25 * abs(snoise(coord * 4.0));
+ n += 0.125 * abs(snoise(coord * 8.0));
+
+ return n;
+}
+
+void main(void)
+{
+ vec3 coord = vec3(vUv.x, uvScale.y - vUv.y, -time);
+ float n = surface3(coord);
+
+ gl_FragColor = vec4(vec3(n, n, n), 1.0);
+}
+
+
diff --git a/data/shaders/terrain-normalmap.frag b/data/shaders/terrain-normalmap.frag
new file mode 100644
index 0000000..74529ae
--- /dev/null
+++ b/data/shaders/terrain-normalmap.frag
@@ -0,0 +1,15 @@
+uniform float height;
+uniform vec2 resolution;
+uniform sampler2D heightMap;
+
+varying vec2 vUv;
+
+void main()
+{
+ float val = texture2D( heightMap, vUv ).x;
+
+ float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;
+ float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;
+
+ gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height ) ) + 0.5 ), 1.0 );
+}
diff --git a/data/shaders/terrain-overlay.frag b/data/shaders/terrain-overlay.frag
new file mode 100644
index 0000000..43fd168
--- /dev/null
+++ b/data/shaders/terrain-overlay.frag
@@ -0,0 +1,10 @@
+uniform float opacity;
+uniform sampler2D tDiffuse;
+
+varying vec2 vUv;
+
+void main()
+{
+ vec4 texel = texture2D(tDiffuse, vUv);
+ gl_FragColor = opacity * texel;
+}
diff --git a/data/shaders/terrain-texture.vert b/data/shaders/terrain-texture.vert
new file mode 100644
index 0000000..021436a
--- /dev/null
+++ b/data/shaders/terrain-texture.vert
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#define MEDIUMP mediump
+#else
+#define MEDIUMP
+#endif
+
+uniform vec2 uvOffset;
+uniform MEDIUMP vec2 uvScale;
+
+attribute vec3 position;
+
+varying vec2 vUv;
+
+void main()
+{
+ vUv = uvScale * (position.xy * 0.5 + 0.5) + uvOffset;
+ gl_Position = vec4( position, 1.0);
+}
diff --git a/data/shaders/terrain.frag b/data/shaders/terrain.frag
new file mode 100644
index 0000000..23bdf19
--- /dev/null
+++ b/data/shaders/terrain.frag
@@ -0,0 +1,112 @@
+uniform vec3 uAmbientColor;
+uniform vec3 uDiffuseColor;
+uniform vec3 uSpecularColor;
+uniform float uShininess;
+uniform float uOpacity;
+uniform bool enableDiffuse1;
+uniform bool enableDiffuse2;
+uniform bool enableSpecular;
+uniform sampler2D tDiffuse1;
+uniform sampler2D tDiffuse2;
+uniform sampler2D tDetail;
+uniform sampler2D tNormal;
+uniform sampler2D tSpecular;
+uniform sampler2D tDisplacement;
+uniform float uNormalScale;
+uniform vec2 uRepeatOverlay;
+uniform vec2 uOffset;
+varying vec3 vTangent;
+varying vec3 vBinormal;
+varying vec3 vNormal;
+varying vec2 vUv;
+uniform vec3 ambientLightColor;
+uniform mat4 viewMatrix;
+
+#define MAX_POINT_LIGHTS 1
+//#define USE_FOG
+//#define FOG_EXP2
+
+#if MAX_POINT_LIGHTS > 0
+uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];
+uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];
+uniform float pointLightDistance[ MAX_POINT_LIGHTS ];
+#endif
+
+varying vec3 vViewPosition;
+
+// CHUNK: fog_pars_fragment
+#ifdef USE_FOG
+uniform vec3 fogColor;
+#ifdef FOG_EXP2
+uniform float fogDensity;
+#else
+uniform float fogNear;
+uniform float fogFar;
+#endif
+#endif
+
+void main() {
+ gl_FragColor = vec4( vec3( 1.0 ), uOpacity );
+ vec3 specularTex = vec3( 1.0 );
+ vec2 uvOverlay = uRepeatOverlay * vUv + uOffset;
+ vec3 normalTex = texture2D( tDetail, uvOverlay ).xyz * 2.0 - 1.0;
+ normalTex.xy *= uNormalScale;
+ normalTex = normalize( normalTex );
+
+ vec4 colDiffuse1 = texture2D( tDiffuse1, uvOverlay );
+ vec4 colDiffuse2 = texture2D( tDiffuse2, uvOverlay );
+ gl_FragColor = gl_FragColor * mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, vUv) );
+
+ specularTex = texture2D( tSpecular, uvOverlay ).xyz;
+
+ mat3 tbn= mat3( vTangent, vBinormal, vNormal );
+ vec3 finalNormal = tbn * normalTex;
+ vec3 normal = normalize( finalNormal );
+ vec3 viewPosition = normalize( vViewPosition );
+
+ // point lights
+#if MAX_POINT_LIGHTS > 0
+ vec3 pointDiffuse = vec3( 0.0 );
+ vec3 pointSpecular = vec3( 0.0 );
+ for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {
+ vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );
+ vec3 lVector = lPosition.xyz + vViewPosition.xyz;
+ float lDistance = 1.0;
+ if ( pointLightDistance[ i ] > 0.0 )
+ lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );
+ lVector = normalize( lVector );
+ vec3 pointHalfVector = normalize( lVector + viewPosition );
+ float pointDistance = lDistance;
+ float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );
+ float pointDiffuseWeight = max( dot( normal, lVector ), 0.0 );
+ float pointSpecularWeight = specularTex.r * pow( pointDotNormalHalf, uShininess );
+ pointDiffuse += pointDistance * pointLightColor[ i ] * uDiffuseColor * pointDiffuseWeight;
+ pointSpecular += pointDistance * pointLightColor[ i ] * uSpecularColor * pointSpecularWeight * pointDiffuseWeight;
+ }
+#endif
+
+ // all lights contribution summation
+ vec3 totalDiffuse = vec3( 0.0 );
+ vec3 totalSpecular = vec3( 0.0 );
+
+
+#if MAX_POINT_LIGHTS > 0
+ totalDiffuse += pointDiffuse;
+ totalSpecular += pointSpecular;
+#endif
+
+ gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );
+
+ //CHUNK: fog_fragment
+#ifdef USE_FOG
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+#ifdef FOG_EXP2
+ const float LOG2 = 1.442695;
+ float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );
+ fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );
+#else
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+#endif
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+#endif
+}
diff --git a/data/shaders/terrain.vert b/data/shaders/terrain.vert
new file mode 100644
index 0000000..dd5b863
--- /dev/null
+++ b/data/shaders/terrain.vert
@@ -0,0 +1,48 @@
+// Transformation matrices
+uniform mat4 modelViewMatrix;
+uniform mat4 normalMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+
+// Vertex attributes
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 tangent;
+attribute vec2 uv;
+
+// Uniforms
+uniform sampler2D tNormal;
+uniform sampler2D tDisplacement;
+uniform float uDisplacementScale;
+uniform float uDisplacementBias;
+
+// Varyings
+varying vec3 vTangent;
+varying vec3 vBinormal;
+varying vec3 vNormal;
+varying vec2 vUv;
+varying vec3 vViewPosition;
+
+void main()
+{
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ vViewPosition = -mvPosition.xyz;
+ vNormal = normalize(vec3(normalMatrix * vec4(normal, 1.0)));
+
+ // tangent and binormal vectors
+ vTangent = normalize(vec3(normalMatrix * vec4(tangent, 1.0)));
+ vBinormal = cross( vNormal, vTangent );
+ vBinormal = normalize( vBinormal );
+
+ // texture coordinates
+ vUv = uv;
+
+ // displacement mapping
+ vec3 dv = texture2D( tDisplacement, uv ).xyz;
+ float df = uDisplacementScale * dv.x + uDisplacementBias;
+ vec4 displacedPosition = vec4(vNormal.xyz * df, 0.0 ) + mvPosition;
+ gl_Position = projectionMatrix * displacedPosition;
+
+ vec3 normalTex = texture2D(tNormal, uv).xyz * 2.0 - 1.0;
+ vNormal = vec3(normalMatrix * vec4(normalTex, 1.0));
+}
diff --git a/data/shaders/text-renderer.frag b/data/shaders/text-renderer.frag
new file mode 100644
index 0000000..c7422a8
--- /dev/null
+++ b/data/shaders/text-renderer.frag
@@ -0,0 +1,10 @@
+uniform sampler2D Texture0;
+
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ vec4 texel = texture2D(Texture0, TextureCoord);
+ gl_FragColor = texel;
+}
+
diff --git a/data/shaders/text-renderer.vert b/data/shaders/text-renderer.vert
new file mode 100644
index 0000000..d6cadbd
--- /dev/null
+++ b/data/shaders/text-renderer.vert
@@ -0,0 +1,10 @@
+attribute vec2 position;
+attribute vec2 texcoord;
+
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ TextureCoord = texcoord;
+ gl_Position = vec4(position, 0.0, 1.0);
+}
diff --git a/data/textures/asteroid-height-map.png b/data/textures/asteroid-height-map.png
new file mode 100644
index 0000000..0d36e0f
--- /dev/null
+++ b/data/textures/asteroid-height-map.png
Binary files differ
diff --git a/data/textures/asteroid-normal-map-tangent.png b/data/textures/asteroid-normal-map-tangent.png
new file mode 100644
index 0000000..fe2e294
--- /dev/null
+++ b/data/textures/asteroid-normal-map-tangent.png
Binary files differ
diff --git a/data/textures/asteroid-normal-map.png b/data/textures/asteroid-normal-map.png
new file mode 100644
index 0000000..916fc02
--- /dev/null
+++ b/data/textures/asteroid-normal-map.png
Binary files differ
diff --git a/data/textures/crate-base.png b/data/textures/crate-base.png
new file mode 100644
index 0000000..1323e4b
--- /dev/null
+++ b/data/textures/crate-base.png
Binary files differ
diff --git a/data/textures/desktop-shadow-corner.png b/data/textures/desktop-shadow-corner.png
new file mode 100644
index 0000000..1802fe3
--- /dev/null
+++ b/data/textures/desktop-shadow-corner.png
Binary files differ
diff --git a/data/textures/desktop-shadow.png b/data/textures/desktop-shadow.png
new file mode 100644
index 0000000..74eab29
--- /dev/null
+++ b/data/textures/desktop-shadow.png
Binary files differ
diff --git a/data/textures/desktop-window.png b/data/textures/desktop-window.png
new file mode 100644
index 0000000..d906c78
--- /dev/null
+++ b/data/textures/desktop-window.png
Binary files differ
diff --git a/data/textures/effect-2d.png b/data/textures/effect-2d.png
new file mode 100644
index 0000000..732fd27
--- /dev/null
+++ b/data/textures/effect-2d.png
Binary files differ
diff --git a/data/textures/glyph-atlas.png b/data/textures/glyph-atlas.png
new file mode 100644
index 0000000..8e64f34
--- /dev/null
+++ b/data/textures/glyph-atlas.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-01.png b/data/textures/jellyfish-caustics-01.png
new file mode 100644
index 0000000..1106dce
--- /dev/null
+++ b/data/textures/jellyfish-caustics-01.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-02.png b/data/textures/jellyfish-caustics-02.png
new file mode 100644
index 0000000..a80f0b5
--- /dev/null
+++ b/data/textures/jellyfish-caustics-02.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-03.png b/data/textures/jellyfish-caustics-03.png
new file mode 100644
index 0000000..5422bc3
--- /dev/null
+++ b/data/textures/jellyfish-caustics-03.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-04.png b/data/textures/jellyfish-caustics-04.png
new file mode 100644
index 0000000..54ff74f
--- /dev/null
+++ b/data/textures/jellyfish-caustics-04.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-05.png b/data/textures/jellyfish-caustics-05.png
new file mode 100644
index 0000000..5884028
--- /dev/null
+++ b/data/textures/jellyfish-caustics-05.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-06.png b/data/textures/jellyfish-caustics-06.png
new file mode 100644
index 0000000..af56e17
--- /dev/null
+++ b/data/textures/jellyfish-caustics-06.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-07.png b/data/textures/jellyfish-caustics-07.png
new file mode 100644
index 0000000..40ab56e
--- /dev/null
+++ b/data/textures/jellyfish-caustics-07.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-08.png b/data/textures/jellyfish-caustics-08.png
new file mode 100644
index 0000000..a94827e
--- /dev/null
+++ b/data/textures/jellyfish-caustics-08.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-09.png b/data/textures/jellyfish-caustics-09.png
new file mode 100644
index 0000000..d3f9fd5
--- /dev/null
+++ b/data/textures/jellyfish-caustics-09.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-10.png b/data/textures/jellyfish-caustics-10.png
new file mode 100644
index 0000000..93ff0ca
--- /dev/null
+++ b/data/textures/jellyfish-caustics-10.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-11.png b/data/textures/jellyfish-caustics-11.png
new file mode 100644
index 0000000..3fcefb5
--- /dev/null
+++ b/data/textures/jellyfish-caustics-11.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-12.png b/data/textures/jellyfish-caustics-12.png
new file mode 100644
index 0000000..cea8464
--- /dev/null
+++ b/data/textures/jellyfish-caustics-12.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-13.png b/data/textures/jellyfish-caustics-13.png
new file mode 100644
index 0000000..b2a1b80
--- /dev/null
+++ b/data/textures/jellyfish-caustics-13.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-14.png b/data/textures/jellyfish-caustics-14.png
new file mode 100644
index 0000000..332dc11
--- /dev/null
+++ b/data/textures/jellyfish-caustics-14.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-15.png b/data/textures/jellyfish-caustics-15.png
new file mode 100644
index 0000000..3bcca56
--- /dev/null
+++ b/data/textures/jellyfish-caustics-15.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-16.png b/data/textures/jellyfish-caustics-16.png
new file mode 100644
index 0000000..59c4aae
--- /dev/null
+++ b/data/textures/jellyfish-caustics-16.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-17.png b/data/textures/jellyfish-caustics-17.png
new file mode 100644
index 0000000..b1d66aa
--- /dev/null
+++ b/data/textures/jellyfish-caustics-17.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-18.png b/data/textures/jellyfish-caustics-18.png
new file mode 100644
index 0000000..599ed61
--- /dev/null
+++ b/data/textures/jellyfish-caustics-18.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-19.png b/data/textures/jellyfish-caustics-19.png
new file mode 100644
index 0000000..aa15d4a
--- /dev/null
+++ b/data/textures/jellyfish-caustics-19.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-20.png b/data/textures/jellyfish-caustics-20.png
new file mode 100644
index 0000000..2b15211
--- /dev/null
+++ b/data/textures/jellyfish-caustics-20.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-21.png b/data/textures/jellyfish-caustics-21.png
new file mode 100644
index 0000000..851ccd6
--- /dev/null
+++ b/data/textures/jellyfish-caustics-21.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-22.png b/data/textures/jellyfish-caustics-22.png
new file mode 100644
index 0000000..7ac4b92
--- /dev/null
+++ b/data/textures/jellyfish-caustics-22.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-23.png b/data/textures/jellyfish-caustics-23.png
new file mode 100644
index 0000000..753b9a9
--- /dev/null
+++ b/data/textures/jellyfish-caustics-23.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-24.png b/data/textures/jellyfish-caustics-24.png
new file mode 100644
index 0000000..b4a8469
--- /dev/null
+++ b/data/textures/jellyfish-caustics-24.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-25.png b/data/textures/jellyfish-caustics-25.png
new file mode 100644
index 0000000..d34203a
--- /dev/null
+++ b/data/textures/jellyfish-caustics-25.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-26.png b/data/textures/jellyfish-caustics-26.png
new file mode 100644
index 0000000..1463548
--- /dev/null
+++ b/data/textures/jellyfish-caustics-26.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-27.png b/data/textures/jellyfish-caustics-27.png
new file mode 100644
index 0000000..40d8366
--- /dev/null
+++ b/data/textures/jellyfish-caustics-27.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-28.png b/data/textures/jellyfish-caustics-28.png
new file mode 100644
index 0000000..e65f676
--- /dev/null
+++ b/data/textures/jellyfish-caustics-28.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-29.png b/data/textures/jellyfish-caustics-29.png
new file mode 100644
index 0000000..4156dcf
--- /dev/null
+++ b/data/textures/jellyfish-caustics-29.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-30.png b/data/textures/jellyfish-caustics-30.png
new file mode 100644
index 0000000..54c1360
--- /dev/null
+++ b/data/textures/jellyfish-caustics-30.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-31.png b/data/textures/jellyfish-caustics-31.png
new file mode 100644
index 0000000..3a53f03
--- /dev/null
+++ b/data/textures/jellyfish-caustics-31.png
Binary files differ
diff --git a/data/textures/jellyfish-caustics-32.png b/data/textures/jellyfish-caustics-32.png
new file mode 100644
index 0000000..7033b65
--- /dev/null
+++ b/data/textures/jellyfish-caustics-32.png
Binary files differ
diff --git a/data/textures/jellyfish256.png b/data/textures/jellyfish256.png
new file mode 100644
index 0000000..b54b7b4
--- /dev/null
+++ b/data/textures/jellyfish256.png
Binary files differ
diff --git a/data/textures/nasa1.png b/data/textures/nasa1.png
new file mode 100644
index 0000000..e1bf8c6
--- /dev/null
+++ b/data/textures/nasa1.png
Binary files differ
diff --git a/data/textures/nasa2.png b/data/textures/nasa2.png
new file mode 100644
index 0000000..c8fd209
--- /dev/null
+++ b/data/textures/nasa2.png
Binary files differ
diff --git a/data/textures/nasa3.png b/data/textures/nasa3.png
new file mode 100644
index 0000000..494a1af
--- /dev/null
+++ b/data/textures/nasa3.png
Binary files differ
diff --git a/data/textures/terrain-backgrounddetailed6.jpg b/data/textures/terrain-backgrounddetailed6.jpg
new file mode 100644
index 0000000..1c3ba04
--- /dev/null
+++ b/data/textures/terrain-backgrounddetailed6.jpg
Binary files differ
diff --git a/data/textures/terrain-grasslight-512-nm.jpg b/data/textures/terrain-grasslight-512-nm.jpg
new file mode 100644
index 0000000..3200002
--- /dev/null
+++ b/data/textures/terrain-grasslight-512-nm.jpg
Binary files differ
diff --git a/data/textures/terrain-grasslight-512.jpg b/data/textures/terrain-grasslight-512.jpg
new file mode 100644
index 0000000..242192a
--- /dev/null
+++ b/data/textures/terrain-grasslight-512.jpg
Binary files differ
diff --git a/data/wscript_build b/data/wscript_build
new file mode 100644
index 0000000..e613b08
--- /dev/null
+++ b/data/wscript_build
@@ -0,0 +1,8 @@
+bld.install_files('${GLMARK_DATA_PATH}/models',
+ bld.path.ant_glob('models/*'))
+
+bld.install_files('${GLMARK_DATA_PATH}/shaders',
+ bld.path.ant_glob('shaders/*'))
+
+bld.install_files('${GLMARK_DATA_PATH}/textures',
+ bld.path.ant_glob('textures/*'))
diff --git a/debian/bzr-builder.manifest b/debian/bzr-builder.manifest
new file mode 100644
index 0000000..bec8b51
--- /dev/null
+++ b/debian/bzr-builder.manifest
@@ -0,0 +1,3 @@
+# bzr-builder format 0.3 deb-version {debupstream}+20121219+bzr258+pkg26
+lp:glmark2 revid:jesse.barker@linaro.org-20121218194434-f2r1bkjaqj0k5s33
+nest-part packaging lp:~glmark2-dev/glmark2/glmark2-package debian debian revid:jesse.barker@linaro.org-20121218194819-oxo9ngy1hkv60dl7
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..5bfc95b
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,158 @@
+glmark2 (2012.12-0~linaro1~quantal1) quantal; urgency=low
+
+ * New upstream release 2012.12.
+
+ -- Jesse Barker <jesse.barker@linaro.org> Tue, 18 Dec 2012 11:47:27 -0800
+
+glmark2 (2012.11-0~linaro1~quantal1) quantal; urgency=low
+
+ * New upstream release 2012.11.
+
+ -- Jesse Barker <jesse.barker@linaro.org> Wed, 28 Nov 2012 15:58:59 -0800
+
+glmark2 (2012.08-0~linaro1~precise1) precise; urgency=low
+
+ * New upstream release 2012.08.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Fri, 17 Aug 2012 13:52:13 +0300
+
+glmark2 (2012.07-0~linaro1~precise1) precise; urgency=low
+
+ * New upstream release 2012.07.
+ * debian/changelog:
+ - Update dates to -2012 where needed.
+ - Add section for src/scene-ideas*.
+ - Add section for src/libjpeg-turbo/*.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Thu, 19 Jul 2012 12:32:37 +0300
+
+glmark2 (2012.06-0~linaro1~precise2) precise; urgency=low
+
+ * debian/control:
+ - Add libjpeg-dev build dependency.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Thu, 28 Jun 2012 13:46:52 +0300
+
+glmark2 (2012.06-0~linaro1~precise1) precise; urgency=low
+
+ * New upstream release 2012.06.
+ * debian/rules:
+ - Clean compiled python code from unpacked waflib/ directory, as
+ described in http://wiki.debian.org/UnpackWaf .
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Thu, 21 Jun 2012 16:55:53 +0300
+
+glmark2 (2012.05-0~linaro1~precise1) precise; urgency=low
+
+ * New upstream release 2012.05.
+ * debian/control:
+ - Update Standards-Version to 3.9.3.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Thu, 24 May 2012 13:45:13 +0300
+
+glmark2 (2012.03-0~linaro1~precise1) precise; urgency=low
+
+ * New upstream release 2012.03.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Thu, 22 Mar 2012 11:53:33 +0200
+
+glmark2 (2012.02-0~linaro1~precise1) precise; urgency=low
+
+ * New upstream release 2012.02.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Thu, 16 Feb 2012 13:19:11 +0200
+
+glmark2 (2012.01-0~linaro1~precise1) precise; urgency=low
+
+ * New upstream release 2012.01.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Thu, 19 Jan 2012 20:20:05 +0200
+
+glmark2 (2011.12-0~linaro1~oneiric1) oneiric; urgency=low
+
+ * New upstream release 2011.12.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Thu, 15 Dec 2011 16:08:48 +0200
+
+glmark2 (2011.11-0~linaro1) oneiric; urgency=low
+
+ * New upstream release 2011.11.
+ * debian/copyright:
+ - Update Linaro copyright date entries from '2010' to '2010-2011'.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Wed, 16 Nov 2011 13:13:22 +0200
+
+glmark2 (2011.10-0~linaro1) oneiric; urgency=low
+
+ * New upstream release 2011.10.
+ * debian/control:
+ - Use libegl1-x11-dev as an build-dep alternative instead of libegl1-dev.
+ - Update description of glmark2-data binary package.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Tue, 18 Oct 2011 16:05:00 +0300
+
+glmark2 (2011.09-0~linaro1) oneiric; urgency=low
+
+ * New upstream release 2011.09.
+ * debian/control:
+ - Start the description of the glmark2-data package with
+ a lowercase letter.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Thu, 22 Sep 2011 11:32:17 +0300
+
+glmark2 (2011.08-0~linaro1) oneiric; urgency=low
+
+ * New upstream release 2011.08.
+ * debian/copyright:
+ - Add copyright information for src/libpng.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Fri, 19 Aug 2011 00:49:08 +0300
+
+glmark2 (2011.07-0~linaro1) oneiric; urgency=low
+
+ * New upstream release 2011.07.
+ * debian/copyright:
+ - Use a standalone license paragraph for the GPL3+ license text.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Thu, 21 Jul 2011 12:19:15 +0300
+
+glmark2 (2011.06-0~linaro1) oneiric; urgency=low
+
+ * New upstream release 2011.06.
+ * debian/copyright:
+ - Added copyright information for src/libmatrix/*
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Fri, 24 Jun 2011 14:54:40 +0300
+
+glmark2 (11.05-0~linaro1) natty; urgency=low
+
+ * New upstream release 11.05.
+ * debian/control:
+ - Change maintainer to "Alexandros Frantzis".
+ - Update Standards-Version to 3.9.2
+ - Use python (>= 2.4) as a build-dependency instead of explicitly
+ stating alternative python versions.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Mon, 30 May 2011 14:07:36 +0300
+
+glmark2 (11.01-0ubuntu1) natty; urgency=low
+
+ * New upstream version 11.01 (LP: #707492).
+ * debian/rules:
+ - Use the new --enable-glesv2, --enable-gl configure flags.
+ * debian/copyright:
+ - Update copyright.
+ - Change main source license to GPL-3+ (from GPL-3).
+ * debian/control:
+ - Change maintainer to "Linaro Graphics Working Group".
+ * debian/watch:
+ - Add watch file.
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Tue, 25 Jan 2011 17:53:50 +0200
+
+glmark2 (10.07.1-0ubuntu1) maverick; urgency=low
+
+ * Initial release for linaro/maverick (LP: #605901)
+ - see: https://blueprints.launchpad.net/ubuntu/+spec/arm-m-ui-and-test-heads
+
+ -- Alexandros Frantzis <alexandros.frantzis@linaro.org> Wed, 28 Jul 2010 18:22:35 +0300
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..7f8f011
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..1f52bed
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,45 @@
+Source: glmark2
+Section: misc
+Priority: optional
+Maintainer: Alexandros Frantzis <alexandros.frantzis@linaro.org>
+Build-Depends: debhelper (>= 7.0.50~),
+ libegl1-mesa-dev | libegl1-x11-dev,
+ libgl1-mesa-dev | libgl1-dev,
+ libgles2-mesa-dev | libgles2-dev,
+ libjpeg-dev,
+ libpng12-dev,
+ libx11-dev,
+ pkg-config,
+ python (>= 2.4)
+Standards-Version: 3.9.3
+Homepage: https://launchpad.net/glmark2
+
+Package: glmark2
+Architecture: any
+Depends: glmark2-data (= ${source:Version}), ${misc:Depends}, ${shlibs:Depends}
+Description: OpenGL (ES) 2.0 benchmark
+ A benchmark for OpenGL (ES) 2.0 that uses only the OpenGL ES 2.0 compatible
+ API. It contains tests for standard OpenGL (ES) 2.0 features, such as vertex
+ arrays, VBOs, texturing and shaders.
+ .
+ This package contains the OpenGL 2.0 variant of the benchmark.
+
+Package: glmark2-es2
+Architecture: any
+Depends: glmark2-data (= ${source:Version}), ${misc:Depends}, ${shlibs:Depends}
+Description: OpenGL (ES) 2.0 benchmark
+ A benchmark for OpenGL (ES) 2.0 that uses only the OpenGL ES 2.0 compatible
+ API. It contains tests for standard OpenGL (ES) 2.0 features, such as vertex
+ arrays, VBOs, texturing and shaders.
+ .
+ This package contains the OpenGL ES 2.0 variant of the benchmark.
+
+Package: glmark2-data
+Architecture: all
+Depends: ${misc:Depends}
+Description: data files for the glmark2 OpenGL (ES) 2.0 benchmark
+ A benchmark for OpenGL (ES) 2.0 that uses only the OpenGL ES 2.0 compatible
+ API. It contains tests for standard OpenGL (ES) 2.0 features, such as vertex
+ arrays, VBOs, texturing and shaders.
+ .
+ This package contains the data files used by the glmark2 benchmark.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..a7908c6
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,102 @@
+Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135
+Name: glmark2
+Source: http://launchpad.net/glmark2
+
+Files: *
+Copyright: 2008 Ben Smith
+ 2010-2012 Linaro Limited
+License: GPL-3+
+
+Files: src/scene-ideas*
+Copyright: 1993 Silicon Graphics, Inc
+ 2012 Linaro Limited
+License: GPL-3+
+
+Files: src/libmatrix/*
+Copyright: 2010-2012 Linaro Limited
+License:
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+ .
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+Files: src/libpng/*
+Copyright: 1998-2011 Glenn Randers-Pehrson
+ 1996-1997 Andreas Dilger
+ 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+License: Zlib
+ This software is provided 'as-is', without any express or implied warranty. In
+ no event will the authors be held liable for any damages arising from the use
+ of this software.
+ .
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ .
+ 1. The origin of this software must not be misrepresented; you must not claim
+ that you wrote the original software. If you use this software in a product,
+ an acknowledgment in the product documentation would be appreciated but is not
+ required.
+ .
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ .
+ 3. This notice may not be removed or altered from any source distribution.
+
+Files: src/libjpeg-turbo/*
+Copyright: 1991-2010 Thomas G. Lane, Guido Vollbeding
+ 1999-2006 MIYASAKA Masaru
+ 2009 Pierre Ossman for Cendio AB
+ 2009-2012 D. R. Commander
+ 2009-2011 Nokia Corporation and/or its subsidiary(-ies)
+License:
+ Permission is hereby granted to use, copy, modify, and distribute this
+ software (or portions thereof) for any purpose, without fee, subject to these
+ conditions:
+ .
+ (1) If any part of the source code for this software is distributed, then this
+ README file must be included, with this copyright and no-warranty notice
+ unaltered; and any additions, deletions, or changes to the original files
+ must be clearly indicated in accompanying documentation.
+ .
+ (2) If only executable code is distributed, then the accompanying
+ documentation must state that "this software is based in part on the work of
+ the Independent JPEG Group".
+ .
+ (3) Permission for use of this software is granted only if the user accepts
+ full responsibility for any undesirable consequences; the authors accept
+ NO LIABILITY for damages of any kind.
+
+Files: debian/*
+Copyright: 2010-2012 Linaro
+License: GPL-3+
+
+License: GPL-3+
+ 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 3 of the License, or (at your option) any later
+ version.
+ .
+ This package 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, see <http://www.gnu.org/licenses/>.
+
+ On Debian systems, the full text of the GNU General Public License
+ version 3 can be found in the file `/usr/share/common-licenses/GPL-3'
diff --git a/debian/glmark2-data.install b/debian/glmark2-data.install
new file mode 100644
index 0000000..4b7ef99
--- /dev/null
+++ b/debian/glmark2-data.install
@@ -0,0 +1 @@
+usr/share/glmark2
diff --git a/debian/glmark2-es2.install b/debian/glmark2-es2.install
new file mode 100644
index 0000000..081050f
--- /dev/null
+++ b/debian/glmark2-es2.install
@@ -0,0 +1 @@
+usr/bin/glmark2-es2
diff --git a/debian/glmark2-es2.manpages b/debian/glmark2-es2.manpages
new file mode 100644
index 0000000..b5b4747
--- /dev/null
+++ b/debian/glmark2-es2.manpages
@@ -0,0 +1 @@
+debian/tmp/usr/share/man/man1/glmark2-es2.1
diff --git a/debian/glmark2.install b/debian/glmark2.install
new file mode 100644
index 0000000..8b4b050
--- /dev/null
+++ b/debian/glmark2.install
@@ -0,0 +1 @@
+usr/bin/glmark2
diff --git a/debian/glmark2.manpages b/debian/glmark2.manpages
new file mode 100644
index 0000000..f994c0f
--- /dev/null
+++ b/debian/glmark2.manpages
@@ -0,0 +1 @@
+debian/tmp/usr/share/man/man1/glmark2.1
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..1054455
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,27 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# This has to be exported to make some magic below work.
+export DH_OPTIONS
+
+
+%:
+ dh $@
+
+override_dh_auto_configure:
+ ./waf configure --enable-gl --enable-glesv2 --prefix=/usr
+
+override_dh_auto_build:
+ ./waf
+
+override_dh_auto_install:
+ ./waf install --destdir=debian/tmp
+
+override_dh_auto_clean:
+ ./waf distclean
+ # Clean compiled python code from unpacked waflib/ directory, as
+ # described in http://wiki.debian.org/UnpackWaf .
+ -find waflib -name "*.pyc" -delete
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 0000000..fa60fce
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,2 @@
+version=3
+http://launchpad.net/glmark2/+download http://launchpad.net/glmark2/trunk/.*/\+download/glmark2-(.*)\.tar\.gz
diff --git a/doc/glmark2.1.in b/doc/glmark2.1.in
new file mode 100644
index 0000000..f2409df
--- /dev/null
+++ b/doc/glmark2.1.in
@@ -0,0 +1,115 @@
+.TH @APPNAME@ "1" "December 2012" "@appname@ @appversion@"
+.SH NAME
+@appname@ \- OpenGL (ES) 2.0 benchmark suite
+.SH SYNOPSIS
+.B @appname@ [options]
+.SH DESCRIPTION
+\fB@appname@\fP is a benchmark for OpenGL (ES) 2.0. It only uses the subset of
+the OpenGL 2.0 API that is compatible with OpenGL ES 2.0.
+.SH OPTIONS
+.TP
+\fB\-b\fR, \fB\-\-benchmark\fR BENCH
+A benchmark to run: 'scene(:opt1=val1)*'
+(the option can be used multiple times)
+.TP
+\fB\-f\fR, \fB\-\-benchmark-file\fR FILE
+Load benchmarks to run from a file containing a
+list of benchmark descriptions (one per line)
+(the option can be used multiple times)
+.TP
+\fB\-\-validate\fR
+Run a quick output validation test instead of
+running the benchmarks
+.TP
+\fB\-\-frame-end\fR METHOD
+How to end a frame [default,none,swap,finish,readpixels]
+.TP
+\fB\-\-off-screen\fR
+Render to an off-screen surface
+.TP
+\fB--visual-config\fR
+The visual configuration to use for the rendering target:
+\'red=R:green=G:blue=B:alpha=A:buffer=BUF'. The parameters may be defined
+in any order, and any omitted parameters assume a default value of '1'
+.TP
+\fB\-\-reuse\-context\fR
+Use a single context for all scenes
+(by default, each scene gets its own context)
+.TP
+\fB\-s\fR, \fB\-\-size\fR WxH
+Size of the output window (default: 800x600)
+.TP
+\fB\-\-fullscreen\fR
+Run in fullscreen mode (equivalent to --size -1x-1)
+.TP
+\fB\-l\fR, \fB\-\-list\-scenes\fR
+Display information about the available scenes
+and their options
+.TP
+\fB\-\-show-all-options\fR
+Show all scene option values used for benchmarks
+(only explicitly set options are shown by default)
+.TP
+\fB\-\-run-forever\fR
+Run indefinitely, looping from the last benchmark
+back to the first
+.TP
+\fB\-\-annotate\fR
+Annotate the benchmarks with on-screen information
+(same as -b :show-fps=true:title=#info#)
+.TP
+\fB\-d\fR, \fB\-\-debug\fR
+Display debug messages
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Display help
+.SH BENCHMARKS
+@appname@ offers a suite of scenes that can be used to measure many aspects
+of OpenGL (ES) 2.0 performance. The way in which each scene is rendered is
+configurable through a set of options. To get the available scenes and their
+acceptable options you can use the \fB\-l\fR, \fB\-\-list\-scenes\fR command
+line option.
+
+In @appname@, a benchmark is defined as a scene plus a set of option values.
+You can specify the list and order of the benchmarks to run by using the
+\fB\-b\fR, \fB\-\-benchmark\fR command line option (possibly multiple times).
+If no benchmarks are specified, a default set of benchmarks is used. If a
+benchmark option is not specified it assumes its default value (listed with
+\fB\-l\fR, \fB\-\-list\-scenes\fR).
+
+As a special case, a benchmark description string is allowed to not contain a
+scene name (i.e. to start with ':'). In this case, any specified option values
+are used as the default values for benchmarks following this description
+string.
+
+.SH EXAMPLES
+To run the default benchmarks:
+.PP
+.RS
+\fB@appname@\fR
+.RE
+.PP
+To run a benchmark using scene 'shading' with a 'duration' of '5.0' seconds and
+ 'shading' of type 'phong':
+.PP
+.RS
+\fB@appname@ -b shading:duration=5.0:shading=phong\fR
+.RE
+.PP
+To run a series of benchmarks use the \fB\-b\fR, \fB\-\-benchmark\fR command
+line option multiple times:
+.PP
+.RS
+\fB@appname@ -b shading:duration=5.0 -b build:use-vbo=false -b texture\fR
+.RE
+.PP
+To set default option values for benchmarks:
+.PP
+.RS
+\fB@appname@ -b :duration=2.0 -b shading -b build -b :duration=5.0 -b texture\fR
+.RE
+.PP
+
+.SH AUTHOR
+@appname@ was written by Alexandros Frantzis based on the original glmark by
+Ben Smith.
diff --git a/doc/wscript_build b/doc/wscript_build
new file mode 100644
index 0000000..8b23b79
--- /dev/null
+++ b/doc/wscript_build
@@ -0,0 +1,21 @@
+if bld.env.USE_GL:
+ bld(
+ features = 'subst',
+ source = 'glmark2.1.in',
+ target = bld.path.find_or_declare('glmark2.1'),
+ APPNAME = 'GLMARK2',
+ appname = 'glmark2',
+ appversion = bld.env.GLMARK2_VERSION,
+ install_path = '${MANDIR}/man1'
+ )
+
+if bld.env.USE_GLESv2:
+ bld(
+ features = 'subst',
+ source = 'glmark2.1.in',
+ target = bld.path.find_or_declare('glmark2-es2.1'),
+ APPNAME = 'GLMARK2-ES2',
+ appname = 'glmark2-es2',
+ appversion = bld.env.GLMARK2_VERSION,
+ install_path = '${MANDIR}/man1'
+ )
diff --git a/src/android.cpp b/src/android.cpp
new file mode 100644
index 0000000..d098626
--- /dev/null
+++ b/src/android.cpp
@@ -0,0 +1,532 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ * Copyright © 2011 0xlab - http://0xlab.org/
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ * Jim Huang (Strict JNI registration using JNI_OnLoad())
+ */
+#include <assert.h>
+#include <jni.h>
+#include <vector>
+#include <string>
+#include <fstream>
+#include "canvas-android.h"
+#include "benchmark.h"
+#include "options.h"
+#include "log.h"
+#include "util.h"
+#include "main-loop.h"
+#include "benchmark-collection.h"
+
+static Canvas *g_canvas;
+static MainLoop *g_loop;
+static BenchmarkCollection *g_benchmark_collection;
+static std::ostream *g_log_extra;
+
+class MainLoopAndroid : public MainLoop
+{
+public:
+ MainLoopAndroid(Canvas &canvas, const std::vector<Benchmark *> &benchmarks) :
+ MainLoop(canvas, benchmarks) {}
+
+ virtual void log_scene_info() {}
+
+ virtual void log_scene_result()
+ {
+ if (scene_setup_status_ == SceneSetupStatusSuccess) {
+ Log::info("%s FPS: %u FrameTime: %.3f ms\n",
+ scene_->info_string().c_str(),
+ scene_->average_fps(),
+ 1000.0 / scene_->average_fps());
+ }
+ else if (scene_setup_status_ == SceneSetupStatusUnsupported) {
+ Log::info("%s Unsupported\n",
+ scene_->info_string().c_str());
+ }
+ else {
+ Log::info("%s Set up failed\n",
+ scene_->info_string().c_str());
+ }
+ }
+};
+
+class MainLoopDecorationAndroid : public MainLoopDecoration
+{
+public:
+ MainLoopDecorationAndroid(Canvas &canvas, const std::vector<Benchmark *> &benchmarks) :
+ MainLoopDecoration(canvas, benchmarks) {}
+
+ virtual void log_scene_info() {}
+
+ virtual void log_scene_result()
+ {
+ if (scene_setup_status_ == SceneSetupStatusSuccess) {
+ Log::info("%s FPS: %u FrameTime: %.3f ms\n",
+ scene_->info_string().c_str(),
+ scene_->average_fps(),
+ 1000.0 / scene_->average_fps());
+ }
+ else if (scene_setup_status_ == SceneSetupStatusUnsupported) {
+ Log::info("%s Unsupported\n",
+ scene_->info_string().c_str());
+ }
+ else {
+ Log::info("%s Set up failed\n",
+ scene_->info_string().c_str());
+ }
+ }
+};
+
+/**
+ * Converts an std::vector containing arguments to argc,argv.
+ */
+static void
+arg_vector_to_argv(const std::vector<std::string> &arguments, int &argc, char **&argv)
+{
+ argc = arguments.size() + 1;
+ argv = new char* [argc];
+ argv[0] = strdup("glmark2");
+
+ for (unsigned int i = 0; i < arguments.size(); i++)
+ argv[i + 1] = strdup(arguments[i].c_str());
+}
+
+/**
+ * Populates the command line arguments from the arguments file.
+ *
+ * @param argc the number of arguments
+ * @param argv the argument array
+ */
+static void
+get_args_from_file(const std::string &arguments_file, int &argc, char **&argv)
+{
+ std::vector<std::string> arguments;
+ std::ifstream ifs(arguments_file.c_str());
+
+ if (!ifs.fail()) {
+ std::string line;
+ while (getline(ifs, line)) {
+ if (!line.empty())
+ Util::split(line, ' ', arguments, Util::SplitModeQuoted);
+ }
+ }
+
+ arg_vector_to_argv(arguments, argc, argv);
+}
+
+/**
+ * Populates the command line arguments from the arguments file.
+ *
+ * @param argc the number of arguments
+ * @param argv the argument array
+ */
+static void
+get_args_from_string(const std::string &args_str, int &argc, char **&argv)
+{
+ std::vector<std::string> arguments;
+ Util::split(args_str, ' ', arguments, Util::SplitModeQuoted);
+
+ arg_vector_to_argv(arguments, argc, argv);
+}
+
+/**
+ * Releases the command line arguments.
+ *
+ * @param argc the number of arguments
+ * @param argv the argument array
+ */
+static void
+release_args(int argc, char **argv)
+{
+ for (int i = 0; i < argc; i++)
+ free(argv[i]);
+
+ delete[] argv;
+}
+
+/**
+ * Converts a GLVisualConfig Java object to a GLVisualConfig C++ object.
+ *
+ * @param env the JNIEnv
+ * @param jvc the Java VisualConfig object to convert
+ * @param vc the C++ VisualConfig object to fill
+ */
+static void
+gl_visual_config_from_jobject(JNIEnv *env, jobject jvc, GLVisualConfig &vc)
+{
+ jclass cls = env->GetObjectClass(jvc);
+ jfieldID fid;
+
+ fid = env->GetFieldID(cls, "red", "I");
+ vc.red = env->GetIntField(jvc, fid);
+
+ fid = env->GetFieldID(cls, "green", "I");
+ vc.green = env->GetIntField(jvc, fid);
+
+ fid = env->GetFieldID(cls, "blue", "I");
+ vc.blue = env->GetIntField(jvc, fid);
+
+ fid = env->GetFieldID(cls, "alpha", "I");
+ vc.alpha = env->GetIntField(jvc, fid);
+
+ fid = env->GetFieldID(cls, "depth", "I");
+ vc.depth = env->GetIntField(jvc, fid);
+
+ fid = env->GetFieldID(cls, "buffer", "I");
+ vc.buffer = env->GetIntField(jvc, fid);
+}
+
+/**
+ * Creates a SceneInfo Java object from a Scene.
+ *
+ * @param env the JNIEnv
+ */
+static jobject
+scene_info_from_scene(JNIEnv *env, Scene &scene)
+{
+ jclass cls = env->FindClass("org/linaro/glmark2/SceneInfo");
+ jmethodID constructor = env->GetMethodID(cls, "<init>", "(Ljava/lang/String;)V");
+ jmethodID add_option = env->GetMethodID(cls, "addOption", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V");
+
+ /* Create the SceneInfo object */
+ jstring name = env->NewStringUTF(scene.name().c_str());
+ jobject scene_info = env->NewObject(cls, constructor, name);
+
+ const std::map<std::string, Scene::Option> &options = scene.options();
+
+ /* Add options to the SceneInfo object */
+ for (std::map<std::string, Scene::Option>::const_iterator opt_iter = options.begin();
+ opt_iter != options.end();
+ opt_iter++)
+ {
+ const Scene::Option &opt = opt_iter->second;
+ jstring opt_name = env->NewStringUTF(opt.name.c_str());
+ jstring opt_description = env->NewStringUTF(opt.description.c_str());
+ jstring opt_default_value = env->NewStringUTF(opt.default_value.c_str());
+
+ /* Create and populate the acceptable values array */
+ jclass string_cls = env->FindClass("java/lang/String");
+ jobjectArray opt_acceptable_values = env->NewObjectArray(opt.acceptable_values.size(),
+ string_cls, 0);
+
+ for (size_t i = 0; i < opt.acceptable_values.size(); i++) {
+ jstring opt_value = env->NewStringUTF(opt.acceptable_values[i].c_str());
+ env->SetObjectArrayElement(opt_acceptable_values, i, opt_value);
+ env->DeleteLocalRef(opt_value);
+ }
+
+ env->CallVoidMethod(scene_info, add_option,
+ opt_name,
+ opt_description,
+ opt_default_value,
+ opt_acceptable_values);
+
+ env->DeleteLocalRef(opt_name);
+ env->DeleteLocalRef(opt_description);
+ env->DeleteLocalRef(opt_default_value);
+ env->DeleteLocalRef(opt_acceptable_values);
+ }
+
+ return scene_info;
+}
+
+class DummyCanvas : public Canvas {
+public:
+ DummyCanvas() : Canvas(0, 0) {}
+};
+
+/**
+ * Creates all the available scenes and adds them to the supplied vector.
+ *
+ * @param scenes the vector to add the scenes to
+ * @param canvas the canvas to create the scenes with
+ */
+static void
+create_and_add_scenes(std::vector<Scene*>& scenes, Canvas& canvas)
+{
+ scenes.push_back(new SceneDefaultOptions(canvas));
+ scenes.push_back(new SceneBuild(canvas));
+ scenes.push_back(new SceneTexture(canvas));
+ scenes.push_back(new SceneShading(canvas));
+ scenes.push_back(new SceneConditionals(canvas));
+ scenes.push_back(new SceneFunction(canvas));
+ scenes.push_back(new SceneLoop(canvas));
+ scenes.push_back(new SceneBump(canvas));
+ scenes.push_back(new SceneEffect2D(canvas));
+ scenes.push_back(new ScenePulsar(canvas));
+ scenes.push_back(new SceneDesktop(canvas));
+ scenes.push_back(new SceneBuffer(canvas));
+ scenes.push_back(new SceneIdeas(canvas));
+ scenes.push_back(new SceneTerrain(canvas));
+ scenes.push_back(new SceneJellyfish(canvas));
+ scenes.push_back(new SceneShadow(canvas));
+ scenes.push_back(new SceneRefract(canvas));
+}
+
+
+void
+Java_org_linaro_glmark2_native_init(JNIEnv* env, jclass clazz,
+ jobject asset_manager,
+ jstring args,
+ jstring log_file)
+{
+ static_cast<void>(clazz);
+ static const std::string arguments_file("/data/glmark2/args");
+ int argc = 0;
+ char **argv = 0;
+
+ /* Load arguments from argument string or arguments file and parse them */
+ if (args) {
+ if (env->GetStringUTFLength(args) > 0) {
+ const char *args_c_str = env->GetStringUTFChars(args, 0);
+ if (args_c_str) {
+ get_args_from_string(std::string(args_c_str), argc, argv);
+ env->ReleaseStringUTFChars(args, args_c_str);
+ }
+ }
+ }
+ else {
+ get_args_from_file(arguments_file, argc, argv);
+ }
+
+ Options::parse_args(argc, argv);
+ release_args(argc, argv);
+
+ /* Get the log file path and open the log file */
+ const char *log_file_c_str = env->GetStringUTFChars(log_file, 0);
+ if (log_file_c_str) {
+ g_log_extra = new std::ofstream(log_file_c_str, std::ios::binary);
+ env->ReleaseStringUTFChars(log_file, log_file_c_str);
+ }
+
+ /* Force reuse of EGL/GL context */
+ Options::reuse_context = true;
+
+ Log::init("glmark2", Options::show_debug, g_log_extra);
+ Util::android_set_asset_manager(AAssetManager_fromJava(env, asset_manager));
+
+ g_canvas = new CanvasAndroid(100, 100);
+ g_canvas->init();
+
+ Log::info("glmark2 %s\n", GLMARK_VERSION);
+ g_canvas->print_info();
+
+ std::vector<Scene*> scenes;
+
+ /* Add and register scenes */
+ create_and_add_scenes(scenes, *g_canvas);
+
+ for (std::vector<Scene*>::const_iterator iter = scenes.begin();
+ iter != scenes.end();
+ iter++)
+ {
+ Benchmark::register_scene(**iter);
+ }
+
+ g_benchmark_collection = new BenchmarkCollection();
+ g_benchmark_collection->populate_from_options();
+
+ if (g_benchmark_collection->needs_decoration()) {
+ g_loop = new MainLoopDecorationAndroid(*g_canvas,
+ g_benchmark_collection->benchmarks());
+ }
+ else {
+ g_loop = new MainLoopAndroid(*g_canvas,
+ g_benchmark_collection->benchmarks());
+ }
+}
+
+void
+Java_org_linaro_glmark2_native_resize(JNIEnv* env,
+ jclass clazz,
+ jint w,
+ jint h)
+{
+ static_cast<void>(env);
+ static_cast<void>(clazz);
+
+ Log::debug("Resizing to %d x %d\n", w, h);
+ g_canvas->resize(w, h);
+}
+
+void
+Java_org_linaro_glmark2_native_done(JNIEnv* env)
+{
+ static_cast<void>(env);
+
+ delete g_loop;
+ delete g_benchmark_collection;
+ delete g_canvas;
+ delete g_log_extra;
+}
+
+jboolean
+Java_org_linaro_glmark2_native_render(JNIEnv* env)
+{
+ static_cast<void>(env);
+
+ if (!g_loop->step()) {
+ Log::info("glmark2 Score: %u\n", g_loop->score());
+ return false;
+ }
+
+ return true;
+}
+
+jint
+Java_org_linaro_glmark2_native_scoreConfig(JNIEnv* env, jclass clazz,
+ jobject jvc, jobject jtarget)
+{
+ static_cast<void>(clazz);
+
+ GLVisualConfig vc;
+ GLVisualConfig target;
+
+ gl_visual_config_from_jobject(env, jvc, vc);
+ gl_visual_config_from_jobject(env, jtarget, target);
+
+ return vc.match_score(target);
+}
+
+jobjectArray
+Java_org_linaro_glmark2_native_getSceneInfo(JNIEnv* env, jclass clazz,
+ jobject asset_manager)
+{
+ static_cast<void>(clazz);
+
+ Util::android_set_asset_manager(AAssetManager_fromJava(env, asset_manager));
+
+ std::vector<Scene*> scenes;
+ DummyCanvas canvas;
+ std::vector<jobject> si_vector;
+
+ create_and_add_scenes(scenes, canvas);
+
+ /* Create SceneInfo instances for all the scenes */
+ for (std::vector<Scene*>::const_iterator iter = scenes.begin();
+ iter != scenes.end();
+ iter++)
+ {
+ jobject si = scene_info_from_scene(env, **iter);
+ si_vector.push_back(si);
+ }
+
+ /* Create a SceneInfo[] array */
+ jclass si_cls = env->FindClass("org/linaro/glmark2/SceneInfo");
+ jobjectArray si_array = env->NewObjectArray(si_vector.size(), si_cls, 0);
+
+ /* Populate the SceneInfo[] array */
+ for (size_t i = 0; i < si_vector.size(); i++)
+ env->SetObjectArrayElement(si_array, i, si_vector[i]);
+
+ Util::dispose_pointer_vector(scenes);
+
+ return si_array;
+}
+
+static JNINativeMethod glmark2_native_methods[] = {
+ {
+ "init",
+ "(Landroid/content/res/AssetManager;Ljava/lang/String;Ljava/lang/String;)V",
+ reinterpret_cast<void*>(Java_org_linaro_glmark2_native_init)
+ },
+ {
+ "resize",
+ "(II)V",
+ reinterpret_cast<void*>(Java_org_linaro_glmark2_native_resize)
+ },
+ {
+ "done",
+ "()V",
+ reinterpret_cast<void*>(Java_org_linaro_glmark2_native_done)
+ },
+ {
+ "render",
+ "()Z",
+ reinterpret_cast<void*>(Java_org_linaro_glmark2_native_render)
+ },
+ {
+ "scoreConfig",
+ "(Lorg/linaro/glmark2/GLVisualConfig;Lorg/linaro/glmark2/GLVisualConfig;)I",
+ reinterpret_cast<void*>(Java_org_linaro_glmark2_native_scoreConfig)
+ },
+ {
+ "getSceneInfo",
+ "(Landroid/content/res/AssetManager;)[Lorg/linaro/glmark2/SceneInfo;",
+ reinterpret_cast<void*>(Java_org_linaro_glmark2_native_getSceneInfo)
+ }
+};
+
+static int
+register_native_methods(JNIEnv* env, const char* className,
+ JNINativeMethod* gMethods, int numMethods)
+{
+ jclass clazz;
+
+ clazz = env->FindClass(className);
+ if (clazz == NULL) {
+ Log::error("Native registration unable to find class '%s'\n",
+ className);
+ return JNI_FALSE;
+ }
+ if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
+ Log::error("RegisterNatives failed for '%s'\n", className);
+ return JNI_FALSE;
+ }
+
+ return JNI_TRUE;
+}
+
+static int
+register_natives(JNIEnv *env)
+{
+ const char* const class_path_name = "org/linaro/glmark2/Glmark2Native";
+ return register_native_methods(env, class_path_name,
+ glmark2_native_methods,
+ sizeof(glmark2_native_methods) /
+ sizeof(glmark2_native_methods[0]));
+}
+
+/*
+ * Returns the JNI version on success, -1 on failure.
+ */
+extern "C" jint
+JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+ static_cast<void>(reserved);
+ JNIEnv* env = NULL;
+ jint result = -1;
+
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_4) != JNI_OK) {
+ Log::error("JNI_OnLoad: GetEnv failed\n");
+ goto bail;
+ }
+ assert(env != NULL);
+
+ if (!register_natives(env)) {
+ Log::error("JNI_OnLoad: glmark2 native registration failed\n");
+ goto bail;
+ }
+
+ /* success -- return valid version number */
+ result = JNI_VERSION_1_4;
+
+bail:
+ return result;
+}
diff --git a/src/benchmark-collection.cpp b/src/benchmark-collection.cpp
new file mode 100644
index 0000000..3e73202
--- /dev/null
+++ b/src/benchmark-collection.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include <fstream>
+#include "benchmark-collection.h"
+#include "default-benchmarks.h"
+#include "options.h"
+#include "log.h"
+#include "util.h"
+
+BenchmarkCollection::~BenchmarkCollection()
+{
+ Util::dispose_pointer_vector(benchmarks_);
+}
+
+void
+BenchmarkCollection::add(const std::vector<std::string> &benchmarks)
+{
+ for (std::vector<std::string>::const_iterator iter = benchmarks.begin();
+ iter != benchmarks.end();
+ iter++)
+ {
+ benchmarks_.push_back(new Benchmark(*iter));
+ }
+}
+
+void
+BenchmarkCollection::populate_from_options()
+{
+ if (Options::annotate) {
+ std::vector<std::string> annotate;
+ annotate.push_back(":show-fps=true:title=#info#");
+ add(annotate);
+ }
+
+ if (!Options::benchmarks.empty())
+ add(Options::benchmarks);
+
+ if (!Options::benchmark_files.empty())
+ add_benchmarks_from_files();
+
+ if (!benchmarks_contain_normal_scenes())
+ add(DefaultBenchmarks::get());
+}
+
+bool
+BenchmarkCollection::needs_decoration()
+{
+ for (std::vector<Benchmark *>::const_iterator bench_iter = benchmarks_.begin();
+ bench_iter != benchmarks_.end();
+ bench_iter++)
+ {
+ const Benchmark *bench = *bench_iter;
+ if (bench->needs_decoration())
+ return true;
+ }
+
+ return false;
+}
+
+
+void
+BenchmarkCollection::add_benchmarks_from_files()
+{
+ for (std::vector<std::string>::const_iterator iter = Options::benchmark_files.begin();
+ iter != Options::benchmark_files.end();
+ iter++)
+ {
+ std::ifstream ifs(iter->c_str());
+
+ if (!ifs.fail()) {
+ std::string line;
+
+ while (getline(ifs, line)) {
+ if (!line.empty())
+ benchmarks_.push_back(new Benchmark(line));
+ }
+ }
+ else {
+ Log::error("Cannot open benchmark file %s\n",
+ iter->c_str());
+ }
+
+ }
+}
+
+bool
+BenchmarkCollection::benchmarks_contain_normal_scenes()
+{
+ for (std::vector<Benchmark *>::const_iterator bench_iter = benchmarks_.begin();
+ bench_iter != benchmarks_.end();
+ bench_iter++)
+ {
+ const Benchmark *bench = *bench_iter;
+ if (!bench->scene().name().empty())
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/src/benchmark-collection.h b/src/benchmark-collection.h
new file mode 100644
index 0000000..f1dc0eb
--- /dev/null
+++ b/src/benchmark-collection.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#ifndef GLMARK2_BENCHMARK_COLLECTION_H_
+#define GLMARK2_BENCHMARK_COLLECTION_H_
+
+#include <vector>
+#include <string>
+#include "benchmark.h"
+
+class BenchmarkCollection
+{
+public:
+ BenchmarkCollection() {}
+ ~BenchmarkCollection();
+
+ /*
+ * Adds benchmarks to the collection.
+ */
+ void add(const std::vector<std::string> &benchmarks);
+
+ /*
+ * Populates the collection guided by the global options.
+ */
+ void populate_from_options();
+
+ /*
+ * Whether the benchmarks in this collection need decoration.
+ */
+ bool needs_decoration();
+
+ const std::vector<Benchmark *>& benchmarks() { return benchmarks_; }
+
+private:
+ void add_benchmarks_from_files();
+ bool benchmarks_contain_normal_scenes();
+
+ std::vector<Benchmark *> benchmarks_;
+};
+
+#endif /* GLMARK2_BENCHMARK_COLLECTION_H_ */
diff --git a/src/benchmark.cpp b/src/benchmark.cpp
new file mode 100644
index 0000000..1f39c39
--- /dev/null
+++ b/src/benchmark.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+
+#include "benchmark.h"
+#include "log.h"
+#include "util.h"
+
+using std::string;
+using std::vector;
+using std::map;
+
+std::map<string, Scene *> Benchmark::sceneMap_;
+
+static Scene &
+get_scene_from_description(const string &s)
+{
+ vector<string> elems;
+
+ Util::split(s, ':', elems, Util::SplitModeNormal);
+
+ const string &name = !elems.empty() ? elems[0] : "";
+
+ return Benchmark::get_scene_by_name(name);
+}
+
+static vector<Benchmark::OptionPair>
+get_options_from_description(const string &s)
+{
+ vector<Benchmark::OptionPair> options;
+ vector<string> elems;
+
+ Util::split(s, ':', elems, Util::SplitModeNormal);
+
+ for (vector<string>::const_iterator iter = elems.begin() + 1;
+ iter != elems.end();
+ iter++)
+ {
+ vector<string> opt;
+
+ Util::split(*iter, '=', opt, Util::SplitModeNormal);
+ if (opt.size() == 2)
+ options.push_back(Benchmark::OptionPair(opt[0], opt[1]));
+ else
+ Log::info("Warning: ignoring invalid option string '%s' "
+ "in benchmark description\n",
+ iter->c_str());
+ }
+
+ return options;
+}
+
+void
+Benchmark::register_scene(Scene &scene)
+{
+ sceneMap_[scene.name()] = &scene;
+}
+
+Scene &
+Benchmark::get_scene_by_name(const string &name)
+{
+ map<string, Scene *>::const_iterator iter;
+
+ if ((iter = sceneMap_.find(name)) != sceneMap_.end())
+ return *(iter->second);
+ else
+ return Scene::dummy();
+}
+
+Benchmark::Benchmark(Scene &scene, const vector<OptionPair> &options) :
+ scene_(scene), options_(options)
+{
+}
+
+Benchmark::Benchmark(const string &name, const vector<OptionPair> &options) :
+ scene_(Benchmark::get_scene_by_name(name)), options_(options)
+{
+}
+
+Benchmark::Benchmark(const string &s) :
+ scene_(get_scene_from_description(s)),
+ options_(get_options_from_description(s))
+{
+}
+
+Scene &
+Benchmark::setup_scene()
+{
+ scene_.reset_options();
+ load_options();
+
+ scene_.load();
+ scene_.setup();
+
+ return scene_;
+}
+
+void
+Benchmark::teardown_scene()
+{
+ scene_.teardown();
+ scene_.unload();
+}
+
+bool
+Benchmark::needs_decoration() const
+{
+ for (vector<OptionPair>::const_iterator iter = options_.begin();
+ iter != options_.end();
+ iter++)
+ {
+ if ((iter->first == "show-fps" && iter->second == "true") ||
+ (iter->first == "title" && !iter->second.empty()))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+Benchmark::load_options()
+{
+ for (vector<OptionPair>::iterator iter = options_.begin();
+ iter != options_.end();
+ iter++)
+ {
+ if (!scene_.set_option(iter->first, iter->second)) {
+ map<string, Scene::Option>::const_iterator opt_iter = scene_.options().find(iter->first);
+
+ if (opt_iter == scene_.options().end()) {
+ Log::info("Warning: Scene '%s' doesn't accept option '%s'\n",
+ scene_.name().c_str(), iter->first.c_str());
+ }
+ else {
+ Log::info("Warning: Scene '%s' doesn't accept value '%s' for option '%s'\n",
+ scene_.name().c_str(), iter->second.c_str(), iter->first.c_str());
+ }
+ }
+ }
+}
+
diff --git a/src/benchmark.h b/src/benchmark.h
new file mode 100644
index 0000000..73bff5a
--- /dev/null
+++ b/src/benchmark.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#ifndef GLMARK2_BENCHMARK_H_
+#define GLMARK2_BENCHMARK_H_
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include "scene.h"
+
+/**
+ * A glmark2 benchmark.
+ *
+ * A benchmark is a Scene configured with a set of option values.
+ */
+class Benchmark
+{
+public:
+ typedef std::pair<std::string, std::string> OptionPair;
+
+ /**
+ * Creates a benchmark using a scene object reference.
+ *
+ * @param scene the scene to use
+ * @param options the options to use
+ */
+ Benchmark(Scene &scene, const std::vector<OptionPair> &options);
+
+ /**
+ * Creates a benchmark using a scene name.
+ *
+ * To use a scene by name, that scene must have been previously registered
+ * using ::register_scene().
+ *
+ * @param name the name of the scene to use
+ * @param options the options to use
+ */
+ Benchmark(const std::string &name, const std::vector<OptionPair> &options);
+
+ /**
+ * Creates a benchmark from a description string.
+ *
+ * The description string is of the form scene[:opt1=val1:opt2=val2...].
+ * The specified scene must have been previously registered using
+ * ::register_scene().
+ *
+ * @param s a description string
+ */
+ Benchmark(const std::string &s);
+
+ /**
+ * Gets the Scene associated with the benchmark.
+ *
+ * This method doesn't prepare the scene for a run.
+ * (See ::setup_scene())
+ *
+ * @return the Scene
+ */
+ Scene &scene() const { return scene_; }
+
+ /**
+ * Sets up the Scene associated with the benchmark.
+ *
+ * @return the Scene
+ */
+ Scene &setup_scene();
+
+ /**
+ * Tears down the Scene associated with the benchmark.
+ */
+ void teardown_scene();
+
+ /**
+ * Whether the benchmark needs extra decoration.
+ */
+ bool needs_decoration() const;
+
+ /**
+ * Registers a Scene, so that it becomes accessible by name.
+ */
+ static void register_scene(Scene &scene);
+
+ /**
+ * Gets a registered scene by its name.
+ *
+ * @return the Scene
+ */
+ static Scene &get_scene_by_name(const std::string &name);
+
+ /**
+ * Gets the registered scenes.
+ *
+ * @return the Scene
+ */
+ static const std::map<std::string, Scene *> &scenes() { return sceneMap_; }
+
+private:
+ Scene &scene_;
+ std::vector<OptionPair> options_;
+
+ void load_options();
+
+ static std::map<std::string, Scene *> sceneMap_;
+};
+
+#endif
diff --git a/src/canvas-android.cpp b/src/canvas-android.cpp
new file mode 100644
index 0000000..b06dc64
--- /dev/null
+++ b/src/canvas-android.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker
+ */
+#include "canvas-android.h"
+#include "log.h"
+#include "options.h"
+#include "gl-headers.h"
+#include <EGL/egl.h>
+
+#include <fstream>
+#include <sstream>
+
+/******************
+ * Public methods *
+ ******************/
+
+bool
+CanvasAndroid::init()
+{
+ EGLint attribs[] = {
+ EGL_CONFIG_ID, 0,
+ EGL_NONE
+ };
+
+ /* Get the current EGL config */
+ EGLDisplay egl_display(eglGetCurrentDisplay());
+ EGLContext egl_context(eglGetCurrentContext());
+ EGLConfig egl_config(0);
+ EGLint num_configs;
+
+ eglQueryContext(egl_display, egl_context, EGL_CONFIG_ID, &(attribs[1]));
+
+ eglChooseConfig(egl_display, attribs, &egl_config, 1, &num_configs);
+
+ resize(width_, height_);
+
+ if (!eglSwapInterval(egl_display, 0))
+ Log::info("** Failed to set swap interval. Results may be bounded above by refresh rate.\n");
+
+ init_gl_extensions();
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+
+ clear();
+
+ if (Options::show_debug) {
+ int buf, red, green, blue, alpha, depth, id, native_id;
+ eglGetConfigAttrib(egl_display, egl_config, EGL_CONFIG_ID, &id);
+ eglGetConfigAttrib(egl_display, egl_config, EGL_NATIVE_VISUAL_ID, &native_id);
+ eglGetConfigAttrib(egl_display, egl_config, EGL_BUFFER_SIZE, &buf);
+ eglGetConfigAttrib(egl_display, egl_config, EGL_RED_SIZE, &red);
+ eglGetConfigAttrib(egl_display, egl_config, EGL_GREEN_SIZE, &green);
+ eglGetConfigAttrib(egl_display, egl_config, EGL_BLUE_SIZE, &blue);
+ eglGetConfigAttrib(egl_display, egl_config, EGL_ALPHA_SIZE, &alpha);
+ eglGetConfigAttrib(egl_display, egl_config, EGL_DEPTH_SIZE, &depth);
+ Log::debug("EGL chosen config ID: 0x%x Native Visual ID: 0x%x\n"
+ " Buffer: %d bits\n"
+ " Red: %d bits\n"
+ " Green: %d bits\n"
+ " Blue: %d bits\n"
+ " Alpha: %d bits\n"
+ " Depth: %d bits\n",
+ id, native_id,
+ buf, red, green, blue, alpha, depth);
+ }
+
+ return true;
+}
+
+void
+CanvasAndroid::visible(bool visible)
+{
+ static_cast<void>(visible);
+}
+
+void
+CanvasAndroid::clear()
+{
+ glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
+ glClearDepthf(1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+void
+CanvasAndroid::update()
+{
+}
+
+void
+CanvasAndroid::print_info()
+{
+ std::stringstream ss;
+
+ ss << " OpenGL Information" << std::endl;
+ ss << " GL_VENDOR: " << glGetString(GL_VENDOR) << std::endl;
+ ss << " GL_RENDERER: " << glGetString(GL_RENDERER) << std::endl;
+ ss << " GL_VERSION: " << glGetString(GL_VERSION) << std::endl;
+
+ Log::info("%s", ss.str().c_str());
+}
+
+Canvas::Pixel
+CanvasAndroid::read_pixel(int x, int y)
+{
+ uint8_t pixel[4];
+
+ glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
+
+ return Canvas::Pixel(pixel[0], pixel[1], pixel[2], pixel[3]);
+}
+
+void
+CanvasAndroid::write_to_file(std::string &filename)
+{
+ char *pixels = new char[width_ * height_ * 4];
+
+ for (int i = 0; i < height_; i++) {
+ glReadPixels(0, i, width_, 1, GL_RGBA, GL_UNSIGNED_BYTE,
+ &pixels[(height_ - i - 1) * width_ * 4]);
+ }
+
+ std::ofstream output (filename.c_str(), std::ios::out | std::ios::binary);
+ output.write(pixels, 4 * width_ * height_);
+
+ delete [] pixels;
+}
+
+bool
+CanvasAndroid::should_quit()
+{
+ return false;
+}
+
+void
+CanvasAndroid::resize(int width, int height)
+{
+ width_ = width;
+ height_ = height;
+
+ glViewport(0, 0, width_, height_);
+ projection_ = LibMatrix::Mat4::perspective(60.0, width_ / static_cast<float>(height_),
+ 1.0, 1024.0);
+}
+
+/*******************
+ * Private methods *
+ *******************/
+
+void
+CanvasAndroid::init_gl_extensions()
+{
+ /*
+ * Parse the extensions we care about from the extension string.
+ * Don't even bother to get function pointers until we know the
+ * extension is present.
+ */
+ std::string extString;
+ const char* exts = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
+ if (exts) {
+ extString = exts;
+ }
+
+ if (extString.find("GL_OES_mapbuffer") != std::string::npos) {
+ GLExtensions::MapBuffer =
+ reinterpret_cast<PFNGLMAPBUFFEROESPROC>(eglGetProcAddress("glMapBufferOES"));
+ GLExtensions::UnmapBuffer =
+ reinterpret_cast<PFNGLUNMAPBUFFEROESPROC>(eglGetProcAddress("glUnmapBufferOES"));
+ }
+}
diff --git a/src/canvas-android.h b/src/canvas-android.h
new file mode 100644
index 0000000..3749748
--- /dev/null
+++ b/src/canvas-android.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#ifndef GLMARK2_CANVAS_ANDROID_H_
+#define GLMARK2_CANVAS_ANDROID_H_
+
+#include "canvas.h"
+
+/**
+ * Canvas for rendering to Android surfaces.
+ *
+ * This class doesn't perform any GLES2.0 surface and context management
+ * (contrary to the CanvasX11* classes); these are handled in the Java
+ * Android code.
+ */
+class CanvasAndroid : public Canvas
+{
+public:
+ CanvasAndroid(int width, int height) :
+ Canvas(width, height) {}
+ ~CanvasAndroid() {}
+
+ bool init();
+ void visible(bool visible);
+ void clear();
+ void update();
+ void print_info();
+ Pixel read_pixel(int x, int y);
+ void write_to_file(std::string &filename);
+ bool should_quit();
+ void resize(int width, int height);
+
+private:
+ void init_gl_extensions();
+};
+
+#endif
+
+
diff --git a/src/canvas-drm.cpp b/src/canvas-drm.cpp
new file mode 100644
index 0000000..7d11e85
--- /dev/null
+++ b/src/canvas-drm.cpp
@@ -0,0 +1,587 @@
+//
+// Copyright © 2012 Linaro Limited
+//
+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+//
+// glmark2 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 3 of the License, or (at your option) any later
+// version.
+//
+// glmark2 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
+// glmark2. If not, see <http://www.gnu.org/licenses/>.
+//
+// Authors:
+// Simon Que
+// Jesse Barker
+//
+#include "canvas-drm.h"
+#include "log.h"
+#include "options.h"
+#include "util.h"
+
+#include <fcntl.h>
+#include <poll.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+
+#include <fstream>
+#include <sstream>
+#include <list>
+
+/******************
+ * Public methods *
+ ******************/
+
+bool
+CanvasDRM::reset()
+{
+ if (!reset_context())
+ return false;
+
+ if (!make_current())
+ return false;
+
+ if (!supports_gl2()) {
+ Log::error("Glmark2 needs OpenGL(ES) version >= 2.0 to run"
+ " (but version string is: '%s')!\n",
+ glGetString(GL_VERSION));
+ return false;
+ }
+
+ glViewport(0, 0, width_, height_);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+
+ clear();
+ egl_.swap();
+
+ if (!drm_.reset()) {
+ return false;
+ }
+
+ return true;
+}
+
+void
+DRMState::fb_destroy_callback(gbm_bo* bo, void* data)
+{
+ DRMFBState* fb = reinterpret_cast<DRMFBState*>(data);
+ if (fb && fb->fb_id) {
+ drmModeRmFB(fb->fd, fb->fb_id);
+ }
+ delete fb;
+ gbm_device* dev = gbm_bo_get_device(bo);
+ Log::debug("Got GBM device handle %p from buffer object\n", dev);
+}
+
+DRMFBState*
+DRMState::fb_get_from_bo(gbm_bo* bo)
+{
+ DRMFBState* fb = reinterpret_cast<DRMFBState*>(gbm_bo_get_user_data(bo));
+ if (fb) {
+ return fb;
+ }
+
+ unsigned int width = gbm_bo_get_width(bo);
+ unsigned int height = gbm_bo_get_height(bo);
+ unsigned int stride = gbm_bo_get_stride(bo);
+ unsigned int handle = gbm_bo_get_handle(bo).u32;
+ unsigned int fb_id(0);
+ int status = drmModeAddFB(fd_, width, height, 24, 32, stride, handle, &fb_id);
+ if (status < 0) {
+ Log::error("Failed to create FB: %d\n", status);
+ return 0;
+ }
+
+ fb = new DRMFBState();
+ fb->fd = fd_;
+ fb->bo = bo;
+ fb->fb_id = fb_id;
+
+ gbm_bo_set_user_data(bo, fb, fb_destroy_callback);
+ return fb;
+}
+
+bool
+DRMState::init_gbm()
+{
+ dev_ = gbm_create_device(fd_);
+ if (!dev_) {
+ Log::error("Failed to create GBM device\n");
+ return false;
+ }
+
+ surface_ = gbm_surface_create(dev_, mode_->hdisplay, mode_->vdisplay,
+ GBM_FORMAT_XRGB8888,
+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+ if (!surface_) {
+ Log::error("Failed to create GBM surface\n");
+ return false;
+ }
+
+ return true;
+}
+
+bool
+DRMState::init()
+{
+ // TODO: Replace this with something that explicitly probes for the loaded
+ // driver (udev?).
+ static const char* drm_modules[] = {
+ "i915",
+ "nouveau",
+ "radeon",
+ "vmgfx",
+ "omapdrm",
+ "exynos"
+ };
+
+ unsigned int num_modules(sizeof(drm_modules)/sizeof(drm_modules[0]));
+ for (unsigned int m = 0; m < num_modules; m++) {
+ fd_ = drmOpen(drm_modules[m], 0);
+ if (fd_ < 0) {
+ Log::debug("Failed to open DRM module '%s'\n", drm_modules[m]);
+ continue;
+ }
+ Log::debug("Opened DRM module '%s'\n", drm_modules[m]);
+ break;
+ }
+
+ if (fd_ < 0) {
+ Log::error("Failed to find a suitable DRM device\n");
+ return false;
+ }
+
+ resources_ = drmModeGetResources(fd_);
+ if (!resources_) {
+ Log::error("drmModeGetResources failed\n");
+ return false;
+ }
+
+ // Find a connected connector
+ for (int c = 0; c < resources_->count_connectors; c++) {
+ connector_ = drmModeGetConnector(fd_, resources_->connectors[c]);
+ if (DRM_MODE_CONNECTED == connector_->connection) {
+ break;
+ }
+ drmModeFreeConnector(connector_);
+ connector_ = 0;
+ }
+
+ if (!connector_) {
+ Log::error("Failed to find a suitable connector\n");
+ return false;
+ }
+
+ // Find the best resolution (we will always operate full-screen).
+ unsigned int bestArea(0);
+ for (int m = 0; m < connector_->count_modes; m++) {
+ drmModeModeInfo* curMode = &connector_->modes[m];
+ unsigned int curArea = curMode->hdisplay * curMode->vdisplay;
+ if (curArea > bestArea) {
+ mode_ = curMode;
+ bestArea = curArea;
+ }
+ }
+
+ if (!mode_) {
+ Log::error("Failed to find a suitable mode\n");
+ return false;
+ }
+
+ // Find a suitable encoder
+ for (int e = 0; e < resources_->count_encoders; e++) {
+ encoder_ = drmModeGetEncoder(fd_, resources_->encoders[e]);
+ if (encoder_ && encoder_->encoder_id == connector_->encoder_id) {
+ break;
+ }
+ drmModeFreeEncoder(encoder_);
+ encoder_ = 0;
+ }
+
+ if (!encoder_) {
+ Log::error("Failed to find a suitable encoder\n");
+ return false;
+ }
+
+ if (!init_gbm()) {
+ return false;
+ }
+
+ crtc_ = drmModeGetCrtc(fd_, encoder_->crtc_id);
+ if (!crtc_) {
+ Log::error("Failed to get current CRTC\n");
+ return false;
+ }
+
+ signal(SIGINT, &DRMState::quit_handler);
+
+ return true;
+}
+
+bool
+DRMState::reset()
+{
+ if (bo_) {
+ gbm_surface_release_buffer(surface_, bo_);
+ }
+
+ bo_ = gbm_surface_lock_front_buffer(surface_);
+ fb_ = fb_get_from_bo(bo_);
+
+ int status = drmModeSetCrtc(fd_, encoder_->crtc_id, fb_->fb_id, 0, 0,
+ &connector_->connector_id, 1, mode_);
+ if (status < 0) {
+ Log::error("Failed to set CRTC: %d\n", status);
+ return false;
+ }
+
+ return true;
+}
+
+
+bool DRMState::should_quit_ = false;
+
+void
+DRMState::quit_handler(int signo)
+{
+ Log::debug("Got SIGINT (%d).\n", signo);
+ should_quit_ = true;
+}
+void
+DRMState::page_flip_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void* data)
+{
+ unsigned int* waiting = reinterpret_cast<unsigned int*>(data);
+ *waiting = 0;
+ // Deal with unused parameters
+ static_cast<void>(fd);
+ static_cast<void>(frame);
+ static_cast<void>(sec);
+ static_cast<void>(usec);
+}
+
+void
+DRMState::do_flip()
+{
+ gbm_bo* next = gbm_surface_lock_front_buffer(surface_);
+ fb_ = fb_get_from_bo(next);
+ unsigned int waiting(1);
+ int status = drmModePageFlip(fd_, encoder_->crtc_id, fb_->fb_id,
+ DRM_MODE_PAGE_FLIP_EVENT, &waiting);
+ if (status < 0) {
+ Log::error("Failed to enqueue page flip: %d\n", status);
+ return;
+ }
+
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(fd_, &fds);
+ drmEventContext evCtx;
+ evCtx.version = DRM_EVENT_CONTEXT_VERSION;
+ evCtx.page_flip_handler = page_flip_handler;
+
+ while (waiting) {
+ status = select(fd_ + 1, &fds, 0, 0, 0);
+ if (status < 0) {
+ // Most of the time, select() will return an error because the
+ // user pressed Ctrl-C. So, only print out a message in debug
+ // mode, and just check for the likely condition and release
+ // the current buffer object before getting out.
+ Log::debug("Error in select\n");
+ if (should_quit()) {
+ gbm_surface_release_buffer(surface_, bo_);
+ bo_ = next;
+ }
+ return;
+ }
+ drmHandleEvent(fd_, &evCtx);
+ }
+
+ gbm_surface_release_buffer(surface_, bo_);
+ bo_ = next;
+}
+
+void
+DRMState::cleanup()
+{
+ // Restore CRTC state if necessary
+ if (crtc_) {
+ int status = drmModeSetCrtc(fd_, crtc_->crtc_id, crtc_->buffer_id,
+ crtc_->x, crtc_->y, &connector_->connector_id,
+ 1, &crtc_->mode);
+ if (status < 0) {
+ Log::error("Failed to restore original CRTC: %d\n", status);
+ }
+ drmModeFreeCrtc(crtc_);
+ crtc_ = 0;
+ }
+ if (surface_) {
+ gbm_surface_destroy(surface_);
+ surface_ = 0;
+ }
+ if (dev_) {
+ gbm_device_destroy(dev_);
+ dev_ = 0;
+ }
+ if (connector_) {
+ drmModeFreeConnector(connector_);
+ connector_ = 0;
+ }
+ if (encoder_) {
+ drmModeFreeEncoder(encoder_);
+ encoder_ = 0;
+ }
+ if (resources_) {
+ drmModeFreeResources(resources_);
+ resources_ = 0;
+ }
+ if (fd_ > 0) {
+ drmClose(fd_);
+ }
+ fd_ = 0;
+ mode_ = 0;
+}
+
+bool
+CanvasDRM::init()
+{
+ Log::info("NOTE: The DRM canvas is still experimental and its behavior\n");
+ Log::info(" is subject to change as GBM and modesetting behavior\n");
+ Log::info(" evolves\n");
+
+ if (!drm_.init()) {
+ Log::error("Failed to initialize the DRM canvas\n");
+ drm_.cleanup();
+ return false;
+ }
+
+ width_ = drm_.mode_width();
+ height_ = drm_.mode_height();
+ resize_no_viewport(width_, height_);
+
+ if (!egl_.init_display(drm_.device(), visual_config_)) {
+ return false;
+ }
+ if (!egl_.init_surface(drm_.surface())) {
+ return false;
+ }
+ if (!egl_.valid()) {
+ return false;
+ }
+
+ return reset();
+}
+
+
+CanvasDRM::~CanvasDRM()
+{
+ drm_.cleanup();
+}
+
+void
+CanvasDRM::visible(bool /* visible */)
+{
+}
+
+void
+CanvasDRM::clear()
+{
+ glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
+#if USE_GL
+ glClearDepth(1.0f);
+#elif USE_GLESv2
+ glClearDepthf(1.0f);
+#endif
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+void
+CanvasDRM::update()
+{
+ Options::FrameEnd m = Options::frame_end;
+
+ if (m == Options::FrameEndDefault) {
+ if (offscreen_)
+ m = Options::FrameEndFinish;
+ else
+ m = Options::FrameEndSwap;
+ }
+
+ switch(m) {
+ case Options::FrameEndSwap:
+ swap_buffers();
+ break;
+ case Options::FrameEndFinish:
+ glFinish();
+ break;
+ case Options::FrameEndReadPixels:
+ read_pixel(width_ / 2, height_ / 2);
+ break;
+ case Options::FrameEndNone:
+ default:
+ break;
+ }
+}
+
+void
+CanvasDRM::print_info()
+{
+ make_current();
+
+ std::stringstream ss;
+ ss << " OpenGL Information" << std::endl;
+ ss << " GL_VENDOR: " << glGetString(GL_VENDOR) << std::endl;
+ ss << " GL_RENDERER: " << glGetString(GL_RENDERER) << std::endl;
+ ss << " GL_VERSION: " << glGetString(GL_VERSION) << std::endl;
+ Log::info("%s", ss.str().c_str());
+}
+
+Canvas::Pixel
+CanvasDRM::read_pixel(int x, int y)
+{
+ uint8_t pixel[4];
+ glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
+ return Canvas::Pixel(pixel[0], pixel[1], pixel[2], pixel[3]);
+}
+
+void
+CanvasDRM::write_to_file(std::string &filename)
+{
+ char *pixels = new char[width_ * height_ * 4];
+
+ for (int i = 0; i < height_; i++) {
+ glReadPixels(0, i, width_, 1, GL_RGBA, GL_UNSIGNED_BYTE,
+ &pixels[(height_ - i - 1) * width_ * 4]);
+ }
+
+ std::ofstream output (filename.c_str(), std::ios::out | std::ios::binary);
+ output.write(pixels, 4 * width_ * height_);
+
+ delete [] pixels;
+}
+
+bool
+CanvasDRM::should_quit()
+{
+ return drm_.should_quit();
+}
+
+void
+CanvasDRM::resize(int width, int height)
+{
+ resize_no_viewport(width, height);
+ glViewport(0, 0, width_, height_);
+}
+
+/*********************
+ * Protected methods *
+ *********************/
+
+bool
+CanvasDRM::supports_gl2()
+{
+ std::string gl_version_str(
+ reinterpret_cast<const char*>(glGetString(GL_VERSION)));
+ int gl_major = 0;
+
+ size_t point_pos(gl_version_str.find('.'));
+
+ if (point_pos != std::string::npos) {
+ point_pos--;
+
+ size_t start_pos(gl_version_str.rfind(' ', point_pos));
+ if (start_pos == std::string::npos)
+ start_pos = 0;
+ else
+ start_pos++;
+
+ gl_major = Util::fromString<int>(
+ gl_version_str.substr(start_pos, point_pos - start_pos + 1)
+ );
+ }
+
+ return gl_major >= 2;
+}
+
+bool
+CanvasDRM::make_current()
+{
+ if (!egl_.valid()) {
+ Log::error("CanvasDRM: Invalid EGL state\n");
+ return false;
+ }
+
+ init_gl_extensions();
+
+ return true;
+}
+
+bool
+CanvasDRM::reset_context()
+{
+ return egl_.reset();
+}
+
+void
+CanvasDRM::swap_buffers()
+{
+ egl_.swap();
+ drm_.do_flip();
+}
+
+void
+CanvasDRM::init_gl_extensions()
+{
+#if USE_GLESv2
+ /*
+ * Parse the extensions we care about from the extension string.
+ * Don't even bother to get function pointers until we know the
+ * extension is present.
+ */
+ std::string extString;
+ const char* exts =
+ reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
+ if (exts)
+ extString = exts;
+
+ if (extString.find("GL_OES_mapbuffer") != std::string::npos) {
+ GLExtensions::MapBuffer = reinterpret_cast<PFNGLMAPBUFFEROESPROC>(
+ eglGetProcAddress("glMapBufferOES"));
+ GLExtensions::UnmapBuffer = reinterpret_cast<PFNGLUNMAPBUFFEROESPROC>(
+ eglGetProcAddress("glUnmapBufferOES"));
+ }
+#elif USE_GL
+ GLExtensions::MapBuffer = glMapBuffer;
+ GLExtensions::UnmapBuffer = glUnmapBuffer;
+#endif
+}
+
+
+/*******************
+ * Private methods *
+ *******************/
+
+void
+CanvasDRM::resize_no_viewport(int width, int height)
+{
+ width_ = drm_.mode_width();
+ height_ = drm_.mode_height();
+
+ if (!width_)
+ width_ = width;
+ if (!height_)
+ height_ = height;
+
+ projection_ =
+ LibMatrix::Mat4::perspective(60.0, width_ / static_cast<float>(height_),
+ 1.0, 1024.0);
+}
diff --git a/src/canvas-drm.h b/src/canvas-drm.h
new file mode 100644
index 0000000..e355131
--- /dev/null
+++ b/src/canvas-drm.h
@@ -0,0 +1,132 @@
+//
+// Copyright © 2012 Linaro Limited
+//
+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+//
+// glmark2 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 3 of the License, or (at your option) any later
+// version.
+//
+// glmark2 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
+// glmark2. If not, see <http://www.gnu.org/licenses/>.
+//
+// Authors:
+// Simon Que
+// Jesse Barker
+//
+#ifndef GLMARK2_CANVAS_DRM_H_
+#define GLMARK2_CANVAS_DRM_H_
+
+#include <cstring>
+#include <gbm.h>
+#include <drm.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include "canvas.h"
+#include "egl-state.h"
+
+struct DRMFBState
+{
+ int fd;
+ gbm_bo* bo;
+ uint32_t fb_id;
+};
+
+class DRMState
+{
+ static void page_flip_handler(int fd, unsigned int frame, unsigned int sec,
+ unsigned int usec, void* data);
+ static void fb_destroy_callback(gbm_bo* bo, void* data);
+ static void quit_handler(int signum);
+ static bool should_quit_;
+ DRMFBState* fb_get_from_bo(gbm_bo* bo);
+ bool init_gbm();
+ int fd_;
+ drmModeRes* resources_;
+ drmModeConnector* connector_;
+ drmModeEncoder* encoder_;
+ drmModeCrtcPtr crtc_;
+ drmModeModeInfo* mode_;
+ gbm_device* dev_;
+ gbm_surface* surface_;
+ gbm_bo* bo_;
+ DRMFBState* fb_;
+
+public:
+ DRMState() :
+ fd_(0),
+ resources_(0),
+ connector_(0),
+ encoder_(0),
+ mode_(0),
+ dev_(0),
+ surface_(0),
+ bo_(0),
+ fb_(0) {}
+ ~DRMState() { cleanup(); }
+ void cleanup();
+ bool init();
+ bool reset();
+ void do_flip();
+ bool should_quit() const { return should_quit_; }
+ gbm_device* device() const { return dev_; }
+ gbm_surface* surface() const { return surface_; }
+ unsigned int mode_width() const
+ {
+ if (mode_) {
+ return mode_->hdisplay;
+ }
+ return 0;
+ }
+ unsigned int mode_height() const
+ {
+ if (mode_) {
+ return mode_->vdisplay;
+ }
+ return 0;
+ }
+};
+
+/**
+ * Canvas for direct rendering with EGL.
+ */
+class CanvasDRM: public Canvas
+{
+public:
+ CanvasDRM(int width, int height) :
+ Canvas(width, height) {}
+ ~CanvasDRM();
+
+ virtual bool init();
+ virtual bool reset();
+ virtual void visible(bool visible);
+ virtual void clear();
+ virtual void update();
+ virtual void print_info();
+ virtual Pixel read_pixel(int x, int y);
+ virtual void write_to_file(std::string &filename);
+ virtual bool should_quit();
+ virtual void resize(int width, int height);
+
+protected:
+ virtual bool make_current();
+ virtual bool reset_context();
+ virtual void swap_buffers();
+ virtual bool supports_gl2();
+
+private:
+ DRMState drm_;
+ EGLState egl_;
+
+ void resize_no_viewport(int width, int height);
+ void init_gl_extensions();
+};
+
+#endif
diff --git a/src/canvas-x11-egl.cpp b/src/canvas-x11-egl.cpp
new file mode 100644
index 0000000..f7e548b
--- /dev/null
+++ b/src/canvas-x11-egl.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#include "canvas-x11-egl.h"
+#include "log.h"
+#include "options.h"
+
+#include <fstream>
+#include <sstream>
+#include <climits>
+
+/*********************
+ * Protected methods *
+ *********************/
+
+bool
+CanvasX11EGL::init_gl_winsys()
+{
+ egl_.init_display(xdpy_, visual_config_);
+ return true;
+}
+
+XVisualInfo *
+CanvasX11EGL::get_xvisualinfo()
+{
+ XVisualInfo vis_tmpl;
+ XVisualInfo *vis_info;
+ int num_visuals;
+ EGLint vid;
+
+ if (!egl_.gotNativeConfig(vid))
+ {
+ Log::error("Failed to get a native-renderable EGLConfig\n");
+ return 0;
+ }
+
+ /* The X window visual must match the EGL config */
+ vis_tmpl.visualid = vid;
+ vis_info = XGetVisualInfo(xdpy_, VisualIDMask, &vis_tmpl,
+ &num_visuals);
+ if (!vis_info) {
+ Log::error("couldn't get X visual\n");
+ return 0;
+ }
+
+ return vis_info;
+}
+
+bool
+CanvasX11EGL::make_current()
+{
+ egl_.init_surface(xwin_);
+ if (!egl_.valid()) {
+ Log::error("CanvasX11EGL: Invalid EGL state\n");
+ return false;
+ }
+
+ init_gl_extensions();
+
+ return true;
+}
+
+void
+CanvasX11EGL::swap_buffers()
+{
+ egl_.swap();
+}
+
+void
+CanvasX11EGL::get_glvisualconfig(GLVisualConfig &visual_config)
+{
+ egl_.getVisualConfig(visual_config);
+}
+
+/*******************
+ * Private methods *
+ *******************/
+
+bool
+CanvasX11EGL::reset_context()
+{
+ return egl_.reset();
+}
+
+void
+CanvasX11EGL::init_gl_extensions()
+{
+#if USE_GLESv2
+ if (GLExtensions::support("GL_OES_mapbuffer")) {
+ GLExtensions::MapBuffer =
+ reinterpret_cast<PFNGLMAPBUFFEROESPROC>(eglGetProcAddress("glMapBufferOES"));
+ GLExtensions::UnmapBuffer =
+ reinterpret_cast<PFNGLUNMAPBUFFEROESPROC>(eglGetProcAddress("glUnmapBufferOES"));
+ }
+#elif USE_GL
+ GLExtensions::MapBuffer = glMapBuffer;
+ GLExtensions::UnmapBuffer = glUnmapBuffer;
+#endif
+}
diff --git a/src/canvas-x11-egl.h b/src/canvas-x11-egl.h
new file mode 100644
index 0000000..d5f581c
--- /dev/null
+++ b/src/canvas-x11-egl.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker
+ */
+#ifndef GLMARK2_CANVAS_X11_EGL_H_
+#define GLMARK2_CANVAS_X11_EGL_H_
+
+#include "canvas-x11.h"
+#include "egl-state.h"
+
+/**
+ * Canvas for rendering to an X11 window using EGL.
+ */
+class CanvasX11EGL : public CanvasX11
+{
+public:
+ CanvasX11EGL(int width, int height) :
+ CanvasX11(width, height) {}
+ ~CanvasX11EGL() {}
+
+protected:
+ XVisualInfo *get_xvisualinfo();
+ bool make_current();
+ bool reset_context();
+ void swap_buffers();
+ void get_glvisualconfig(GLVisualConfig &visual_config);
+ bool init_gl_winsys();
+
+private:
+ void init_gl_extensions();
+ EGLState egl_;
+};
+
+#endif
diff --git a/src/canvas-x11-glx.cpp b/src/canvas-x11-glx.cpp
new file mode 100644
index 0000000..db016b8
--- /dev/null
+++ b/src/canvas-x11-glx.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#include "canvas-x11-glx.h"
+#include "log.h"
+#include "options.h"
+
+#include <string>
+#include <climits>
+
+static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT_;
+static PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA_;
+static PFNGLXGETSWAPINTERVALMESAPROC glXGetSwapIntervalMESA_;
+
+/*********************
+ * Protected methods *
+ *********************/
+
+XVisualInfo *
+CanvasX11GLX::get_xvisualinfo()
+{
+ if (!ensure_glx_fbconfig())
+ return 0;
+
+ XVisualInfo *vis_info = glXGetVisualFromFBConfig(xdpy_, glx_fbconfig_ );
+
+ return vis_info;
+}
+
+bool
+CanvasX11GLX::make_current()
+{
+ if (!ensure_glx_context())
+ return false;
+
+ if (glx_context_ == glXGetCurrentContext())
+ return true;
+
+ init_extensions();
+
+ if (!glXMakeCurrent(xdpy_, xwin_, glx_context_)) {
+ Log::error("glXMakeCurrent failed\n");
+ return false;
+ }
+
+ unsigned int desired_swap(0);
+ unsigned int actual_swap(-1);
+ if (glXSwapIntervalEXT_) {
+ glXSwapIntervalEXT_(xdpy_, xwin_, desired_swap);
+ glXQueryDrawable(xdpy_, xwin_, GLX_SWAP_INTERVAL_EXT, &actual_swap);
+ if (actual_swap == desired_swap)
+ return true;
+ }
+
+ if (glXSwapIntervalMESA_) {
+ glXSwapIntervalMESA_(desired_swap);
+ actual_swap = glXGetSwapIntervalMESA_();
+ if (actual_swap == desired_swap)
+ return true;
+ }
+
+ Log::info("** Failed to set swap interval. Results may be bounded above by refresh rate.\n");
+
+ return true;
+}
+
+void
+CanvasX11GLX::get_glvisualconfig(GLVisualConfig &visual_config)
+{
+ if (!ensure_glx_fbconfig())
+ return;
+
+ get_glvisualconfig_glx(glx_fbconfig_, visual_config);
+}
+
+/*******************
+ * Private methods *
+ *******************/
+
+bool
+CanvasX11GLX::check_glx_version()
+{
+ int glx_major, glx_minor;
+
+ if (!glXQueryVersion(xdpy_, &glx_major, &glx_minor ) ||
+ (glx_major == 1 && glx_minor < 3) || glx_major < 1)
+ {
+ Log::error("GLX version >= 1.3 is required\n");
+ return false;
+ }
+
+ return true;
+}
+
+void
+CanvasX11GLX::init_extensions()
+{
+ /*
+ * Parse the extensions we care about from the extension string.
+ * Don't even bother to get function pointers until we know the
+ * extension is present.
+ */
+ std::string extString;
+ const char* exts = glXQueryExtensionsString(xdpy_, 0);
+ if (exts) {
+ extString = exts;
+ }
+
+ /*
+ * GLX_EXT_swap_control or GL_MESA_swap_control. Note that
+ * GLX_SGI_swap_control is not enough because it doesn't allow 0 as a valid
+ * value (i.e. you can't turn off VSync).
+ */
+ if (extString.find("GLX_EXT_swap_control") != std::string::npos) {
+ glXSwapIntervalEXT_ =
+ reinterpret_cast<PFNGLXSWAPINTERVALEXTPROC>(
+ glXGetProcAddress(
+ reinterpret_cast<const GLubyte *>("glXSwapIntervalEXT")
+ )
+ );
+ }
+ else if (extString.find("GLX_MESA_swap_control") != std::string::npos) {
+ glXSwapIntervalMESA_ =
+ reinterpret_cast<PFNGLXSWAPINTERVALMESAPROC>(
+ glXGetProcAddress(
+ reinterpret_cast<const GLubyte *>("glXSwapIntervalMESA")
+ )
+ );
+ glXGetSwapIntervalMESA_ =
+ reinterpret_cast<PFNGLXGETSWAPINTERVALMESAPROC>(
+ glXGetProcAddress(
+ reinterpret_cast<const GLubyte *>("glXGetSwapIntervalMESA")
+ )
+ );
+ }
+
+
+ if (!glXSwapIntervalEXT_ && !glXSwapIntervalMESA_) {
+ Log::info("** GLX does not support GLX_EXT_swap_control or GLX_MESA_swap_control!\n");
+ }
+}
+
+bool
+CanvasX11GLX::ensure_glx_fbconfig()
+{
+ static int attribs[] = {
+ GLX_X_RENDERABLE, True,
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
+ GLX_RED_SIZE, visual_config_.red,
+ GLX_GREEN_SIZE, visual_config_.green,
+ GLX_BLUE_SIZE, visual_config_.blue,
+ GLX_ALPHA_SIZE, visual_config_.alpha,
+ GLX_DEPTH_SIZE, visual_config_.depth,
+ GLX_STENCIL_SIZE, visual_config_.stencil,
+ GLX_BUFFER_SIZE, visual_config_.buffer,
+ GLX_DOUBLEBUFFER, True,
+ None
+ };
+ int num_configs;
+
+ if (glx_fbconfig_)
+ return true;
+
+ if (!check_glx_version())
+ return false;
+
+ GLXFBConfig *fbc = glXChooseFBConfig(xdpy_, DefaultScreen(xdpy_),
+ attribs, &num_configs);
+ if (!fbc) {
+ Log::error("glXChooseFBConfig() failed\n");
+ return false;
+ }
+
+ std::vector<GLXFBConfig> configs(fbc, fbc + num_configs);
+
+ Log::debug("Found %d matching FB configs.\n", num_configs);
+
+ /* Select the best matching config */
+ glx_fbconfig_ = select_best_config(configs);
+
+ XFree(fbc);
+
+ if (Options::show_debug) {
+ int buf, red, green, blue, alpha, depth, stencil, id, native_id;
+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_FBCONFIG_ID, &id);
+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_VISUAL_ID, &native_id);
+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_BUFFER_SIZE, &buf);
+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_RED_SIZE, &red);
+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_GREEN_SIZE, &green);
+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_BLUE_SIZE, &blue);
+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_ALPHA_SIZE, &alpha);
+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_DEPTH_SIZE, &depth);
+ glXGetFBConfigAttrib(xdpy_, glx_fbconfig_, GLX_STENCIL_SIZE, &stencil);
+ Log::debug("GLX chosen config ID: 0x%x Native Visual ID: 0x%x\n"
+ " Buffer: %d bits\n"
+ " Red: %d bits\n"
+ " Green: %d bits\n"
+ " Blue: %d bits\n"
+ " Alpha: %d bits\n"
+ " Depth: %d bits\n"
+ " Stencil: %d bits\n",
+ id, native_id,
+ buf, red, green, blue, alpha, depth, stencil);
+ }
+
+
+ return true;
+}
+
+void
+CanvasX11GLX::init_gl_extensions()
+{
+ GLExtensions::MapBuffer = glMapBuffer;
+ GLExtensions::UnmapBuffer = glUnmapBuffer;
+}
+
+bool
+CanvasX11GLX::reset_context()
+{
+ glXDestroyContext(xdpy_, glx_context_);
+ glx_context_ = 0;
+
+ return true;
+}
+
+bool
+CanvasX11GLX::ensure_glx_context()
+{
+ if (glx_context_)
+ return true;
+
+ if (!ensure_glx_fbconfig())
+ return false;
+
+ glx_context_ = glXCreateNewContext(xdpy_, glx_fbconfig_, GLX_RGBA_TYPE,
+ 0, True);
+ if (!glx_context_) {
+ Log::error("glXCreateNewContext failed\n");
+ return false;
+ }
+
+ init_gl_extensions();
+
+ return true;
+}
+
+void
+CanvasX11GLX::get_glvisualconfig_glx(const GLXFBConfig config, GLVisualConfig &visual_config)
+{
+ glXGetFBConfigAttrib(xdpy_, config, GLX_BUFFER_SIZE, &visual_config.buffer);
+ glXGetFBConfigAttrib(xdpy_, config, GLX_RED_SIZE, &visual_config.red);
+ glXGetFBConfigAttrib(xdpy_, config, GLX_GREEN_SIZE, &visual_config.green);
+ glXGetFBConfigAttrib(xdpy_, config, GLX_BLUE_SIZE, &visual_config.blue);
+ glXGetFBConfigAttrib(xdpy_, config, GLX_ALPHA_SIZE, &visual_config.alpha);
+ glXGetFBConfigAttrib(xdpy_, config, GLX_DEPTH_SIZE, &visual_config.depth);
+ glXGetFBConfigAttrib(xdpy_, config, GLX_STENCIL_SIZE, &visual_config.stencil);
+}
+
+GLXFBConfig
+CanvasX11GLX::select_best_config(std::vector<GLXFBConfig> configs)
+{
+ int best_score(INT_MIN);
+ GLXFBConfig best_config(0);
+
+ /*
+ * Go through all the configs and choose the one with the best score,
+ * i.e., the one better matching the requested config.
+ */
+ for (std::vector<GLXFBConfig>::const_iterator iter = configs.begin();
+ iter != configs.end();
+ iter++)
+ {
+ const GLXFBConfig config(*iter);
+ GLVisualConfig vc;
+ int score;
+
+ get_glvisualconfig_glx(config, vc);
+
+ score = vc.match_score(visual_config_);
+
+ if (score > best_score) {
+ best_score = score;
+ best_config = config;
+ }
+ }
+
+ return best_config;
+}
diff --git a/src/canvas-x11-glx.h b/src/canvas-x11-glx.h
new file mode 100644
index 0000000..f787087
--- /dev/null
+++ b/src/canvas-x11-glx.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#ifndef GLMARK2_CANVAS_X11_GLX_H_
+#define GLMARK2_CANVAS_X11_GLX_H_
+
+#include "canvas-x11.h"
+
+#define GLX_GLXEXT_PROTOTYPES
+#include <GL/glx.h>
+#include <GL/glxext.h>
+#include <vector>
+
+/**
+ * Canvas for rendering to an X11 window using GLX.
+ */
+class CanvasX11GLX : public CanvasX11
+{
+public:
+ CanvasX11GLX(int width, int height) :
+ CanvasX11(width, height), glx_fbconfig_(0), glx_context_(0) {}
+ ~CanvasX11GLX() {}
+
+protected:
+ XVisualInfo *get_xvisualinfo();
+ bool make_current();
+ bool reset_context();
+ void swap_buffers() { glXSwapBuffers(xdpy_, xwin_); }
+ void get_glvisualconfig(GLVisualConfig &visual_config);
+ bool init_gl_winsys() { return true; }
+
+private:
+ bool check_glx_version();
+ void init_extensions();
+ bool ensure_glx_fbconfig();
+ bool ensure_glx_context();
+ void init_gl_extensions();
+ void get_glvisualconfig_glx(GLXFBConfig config, GLVisualConfig &visual_config);
+ GLXFBConfig select_best_config(std::vector<GLXFBConfig> configs);
+
+ GLXFBConfig glx_fbconfig_;
+ GLXContext glx_context_;
+
+};
+
+#endif
+
diff --git a/src/canvas-x11.cpp b/src/canvas-x11.cpp
new file mode 100644
index 0000000..c1b19c0
--- /dev/null
+++ b/src/canvas-x11.cpp
@@ -0,0 +1,526 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker
+ */
+#include "canvas-x11.h"
+#include "log.h"
+#include "options.h"
+#include "util.h"
+
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+#include <fstream>
+#include <sstream>
+
+/******************
+ * Public methods *
+ ******************/
+bool
+CanvasX11::reset()
+{
+ release_fbo();
+
+ if (!reset_context())
+ return false;
+
+ if (!do_make_current())
+ return false;
+
+ if (!supports_gl2()) {
+ Log::error("Glmark2 needs OpenGL(ES) version >= 2.0 to run"
+ " (but version string is: '%s')!\n",
+ glGetString(GL_VERSION));
+ return false;
+ }
+
+ glViewport(0, 0, width_, height_);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+
+ clear();
+
+ return true;
+}
+
+bool
+CanvasX11::init()
+{
+ xdpy_ = XOpenDisplay(NULL);
+ if (!xdpy_)
+ return false;
+
+ if (!init_gl_winsys())
+ return false;
+
+ resize_no_viewport(width_, height_);
+
+ if (!xwin_)
+ return false;
+
+ return reset();
+}
+
+void
+CanvasX11::visible(bool visible)
+{
+ if (visible && !offscreen_)
+ XMapWindow(xdpy_, xwin_);
+}
+
+void
+CanvasX11::clear()
+{
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+#if USE_GL
+ glClearDepth(1.0f);
+#elif USE_GLESv2
+ glClearDepthf(1.0f);
+#endif
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+void
+CanvasX11::update()
+{
+ Options::FrameEnd m = Options::frame_end;
+
+ if (m == Options::FrameEndDefault) {
+ if (offscreen_)
+ m = Options::FrameEndFinish;
+ else
+ m = Options::FrameEndSwap;
+ }
+
+ switch(m) {
+ case Options::FrameEndSwap:
+ swap_buffers();
+ break;
+ case Options::FrameEndFinish:
+ glFinish();
+ break;
+ case Options::FrameEndReadPixels:
+ read_pixel(width_ / 2, height_ / 2);
+ break;
+ case Options::FrameEndNone:
+ default:
+ break;
+ }
+}
+
+void
+CanvasX11::print_info()
+{
+ do_make_current();
+
+ std::stringstream ss;
+
+ ss << " OpenGL Information" << std::endl;
+ ss << " GL_VENDOR: " << glGetString(GL_VENDOR) << std::endl;
+ ss << " GL_RENDERER: " << glGetString(GL_RENDERER) << std::endl;
+ ss << " GL_VERSION: " << glGetString(GL_VERSION) << std::endl;
+
+ Log::info("%s", ss.str().c_str());
+}
+
+Canvas::Pixel
+CanvasX11::read_pixel(int x, int y)
+{
+ uint8_t pixel[4];
+
+ glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
+
+ return Canvas::Pixel(pixel[0], pixel[1], pixel[2], pixel[3]);
+}
+
+void
+CanvasX11::write_to_file(std::string &filename)
+{
+ char *pixels = new char[width_ * height_ * 4];
+
+ for (int i = 0; i < height_; i++) {
+ glReadPixels(0, i, width_, 1, GL_RGBA, GL_UNSIGNED_BYTE,
+ &pixels[(height_ - i - 1) * width_ * 4]);
+ }
+
+ std::ofstream output (filename.c_str(), std::ios::out | std::ios::binary);
+ output.write(pixels, 4 * width_ * height_);
+
+ delete [] pixels;
+}
+
+bool
+CanvasX11::should_quit()
+{
+ XEvent event;
+
+ if (!XPending(xdpy_))
+ return false;
+
+ XNextEvent(xdpy_, &event);
+
+ if (event.type == KeyPress) {
+ if (XLookupKeysym(&event.xkey, 0) == XK_Escape)
+ return true;
+ }
+ else if (event.type == ClientMessage) {
+ /* Window Delete event from window manager */
+ return true;
+ }
+
+ return false;
+}
+
+void
+CanvasX11::resize(int width, int height)
+{
+ resize_no_viewport(width, height);
+ glViewport(0, 0, width_, height_);
+}
+
+unsigned int
+CanvasX11::fbo()
+{
+ return fbo_;
+}
+
+bool
+CanvasX11::supports_gl2()
+{
+ std::string gl_version_str(reinterpret_cast<const char*>(glGetString(GL_VERSION)));
+ int gl_major(0);
+
+ size_t point_pos(gl_version_str.find('.'));
+
+ if (point_pos != std::string::npos) {
+ point_pos--;
+
+ size_t start_pos(gl_version_str.rfind(' ', point_pos));
+ if (start_pos == std::string::npos)
+ start_pos = 0;
+ else
+ start_pos++;
+
+ gl_major = Util::fromString<int>(
+ gl_version_str.substr(start_pos, point_pos - start_pos + 1)
+ );
+ }
+
+ return gl_major >= 2;
+}
+
+/*******************
+ * Private methods *
+ *******************/
+
+bool
+CanvasX11::ensure_x_window()
+{
+ static const char *win_name("glmark2 "GLMARK_VERSION);
+
+ if (xwin_)
+ return true;
+
+ if (!xdpy_) {
+ Log::error("Error: X11 Display has not been initialized!\n");
+ return false;
+ }
+
+ XVisualInfo *vis_info = get_xvisualinfo();
+ if (!vis_info) {
+ Log::error("Error: Could not get a valid XVisualInfo!\n");
+ return false;
+ }
+
+ Log::debug("Creating XWindow W: %d H: %d VisualID: 0x%x\n",
+ width_, height_, vis_info->visualid);
+
+ /* window attributes */
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root = RootWindow(xdpy_, DefaultScreen(xdpy_));
+
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap(xdpy_, root, vis_info->visual, AllocNone);
+ attr.event_mask = KeyPressMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ xwin_ = XCreateWindow(xdpy_, root, 0, 0, width_, height_,
+ 0, vis_info->depth, InputOutput,
+ vis_info->visual, mask, &attr);
+
+ XFree(vis_info);
+
+ if (!xwin_) {
+ Log::error("Error: XCreateWindow() failed!\n");
+ return false;
+ }
+
+ /* set hints and properties */
+ if (fullscreen_) {
+ Atom atom = XInternAtom(xdpy_, "_NET_WM_STATE_FULLSCREEN", True);
+ XChangeProperty(xdpy_, xwin_,
+ XInternAtom(xdpy_, "_NET_WM_STATE", True),
+ XA_ATOM, 32, PropModeReplace,
+ reinterpret_cast<unsigned char*>(&atom), 1);
+ }
+ else {
+ XSizeHints sizehints;
+ sizehints.min_width = width_;
+ sizehints.min_height = height_;
+ sizehints.max_width = width_;
+ sizehints.max_height = height_;
+ sizehints.flags = PMaxSize | PMinSize;
+
+ XSetWMProperties(xdpy_, xwin_, NULL, NULL,
+ NULL, 0, &sizehints, NULL, NULL);
+ }
+
+ /* Set the window name */
+ XStoreName(xdpy_ , xwin_, win_name);
+
+ /* Gracefully handle Window Delete event from window manager */
+ Atom wmDelete = XInternAtom(xdpy_, "WM_DELETE_WINDOW", True);
+ XSetWMProtocols(xdpy_, xwin_, &wmDelete, 1);
+
+ return true;
+}
+
+void
+CanvasX11::resize_no_viewport(int width, int height)
+{
+ bool request_fullscreen = (width == -1 || height == -1);
+
+ /* Recreate an existing window only if it has actually been resized */
+ if (xwin_) {
+ if (width_ != width || height_ != height ||
+ fullscreen_ != request_fullscreen)
+ {
+ XDestroyWindow(xdpy_, xwin_);
+ xwin_ = 0;
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ fullscreen_ = request_fullscreen;
+
+ if (fullscreen_) {
+ /* Get the screen (root window) size */
+ XWindowAttributes window_attr;
+ XGetWindowAttributes(xdpy_, RootWindow(xdpy_, DefaultScreen(xdpy_)),
+ &window_attr);
+ width_ = window_attr.width;
+ height_ = window_attr.height;
+ }
+ else {
+ width_ = width;
+ height_ = height;
+ }
+
+ if (!ensure_x_window())
+ Log::error("Error: Couldn't create X Window!\n");
+
+ if (color_renderbuffer_) {
+ glBindRenderbuffer(GL_RENDERBUFFER, color_renderbuffer_);
+ glRenderbufferStorage(GL_RENDERBUFFER, gl_color_format_,
+ width_, height_);
+ }
+
+ if (depth_renderbuffer_) {
+ glBindRenderbuffer(GL_RENDERBUFFER, depth_renderbuffer_);
+ glRenderbufferStorage(GL_RENDERBUFFER, gl_depth_format_,
+ width_, height_);
+ }
+
+ projection_ = LibMatrix::Mat4::perspective(60.0, width_ / static_cast<float>(height_),
+ 1.0, 1024.0);
+}
+
+bool
+CanvasX11::do_make_current()
+{
+ if (!make_current())
+ return false;
+
+ if (offscreen_) {
+ if (!ensure_fbo())
+ return false;
+
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ }
+
+ return true;
+}
+
+bool
+CanvasX11::ensure_gl_formats()
+{
+ if (gl_color_format_ && gl_depth_format_)
+ return true;
+
+ GLVisualConfig vc;
+ get_glvisualconfig(vc);
+
+ gl_color_format_ = 0;
+ gl_depth_format_ = 0;
+
+ bool supports_rgba8(false);
+ bool supports_rgb8(false);
+ bool supports_depth24(false);
+ bool supports_depth32(false);
+
+#if USE_GLESv2
+ if (GLExtensions::support("GL_ARM_rgba8"))
+ supports_rgba8 = true;
+
+ if (GLExtensions::support("GL_OES_rgb8_rgba8")) {
+ supports_rgba8 = true;
+ supports_rgb8 = true;
+ }
+
+ if (GLExtensions::support("GL_OES_depth24"))
+ supports_depth24 = true;
+
+ if (GLExtensions::support("GL_OES_depth32"))
+ supports_depth32 = true;
+#elif USE_GL
+ supports_rgba8 = true;
+ supports_rgb8 = true;
+ supports_depth24 = true;
+ supports_depth32 = true;
+#endif
+
+ if (vc.buffer == 32) {
+ if (supports_rgba8)
+ gl_color_format_ = GL_RGBA8;
+ else
+ gl_color_format_ = GL_RGBA4;
+ }
+ else if (vc.buffer == 24) {
+ if (supports_rgb8)
+ gl_color_format_ = GL_RGB8;
+ else
+ gl_color_format_ = GL_RGB565;
+ }
+ else if (vc.buffer == 16) {
+ if (vc.red == 4 && vc.green == 4 &&
+ vc.blue == 4 && vc.alpha == 4)
+ {
+ gl_color_format_ = GL_RGBA4;
+ }
+ else if (vc.red == 5 && vc.green == 5 &&
+ vc.blue == 5 && vc.alpha == 1)
+ {
+ gl_color_format_ = GL_RGB5_A1;
+ }
+ else if (vc.red == 5 && vc.green == 6 &&
+ vc.blue == 5 && vc.alpha == 0)
+ {
+ gl_color_format_ = GL_RGB565;
+ }
+ }
+
+ if (vc.depth == 32 && supports_depth32)
+ gl_depth_format_ = GL_DEPTH_COMPONENT32;
+ else if (vc.depth >= 24 && supports_depth24)
+ gl_depth_format_ = GL_DEPTH_COMPONENT24;
+ else if (vc.depth == 16)
+ gl_depth_format_ = GL_DEPTH_COMPONENT16;
+
+ Log::debug("Selected Renderbuffer ColorFormat: %s DepthFormat: %s\n",
+ get_gl_format_str(gl_color_format_),
+ get_gl_format_str(gl_depth_format_));
+
+ return (gl_color_format_ && gl_depth_format_);
+}
+
+bool
+CanvasX11::ensure_fbo()
+{
+ if (!fbo_) {
+ if (!ensure_gl_formats())
+ return false;
+
+ /* Create a texture for the color attachment */
+ glGenRenderbuffers(1, &color_renderbuffer_);
+ glBindRenderbuffer(GL_RENDERBUFFER, color_renderbuffer_);
+ glRenderbufferStorage(GL_RENDERBUFFER, gl_color_format_,
+ width_, height_);
+
+ /* Create a renderbuffer for the depth attachment */
+ glGenRenderbuffers(1, &depth_renderbuffer_);
+ glBindRenderbuffer(GL_RENDERBUFFER, depth_renderbuffer_);
+ glRenderbufferStorage(GL_RENDERBUFFER, gl_depth_format_,
+ width_, height_);
+
+ /* Create a FBO and set it up */
+ glGenFramebuffers(1, &fbo_);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, color_renderbuffer_);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, depth_renderbuffer_);
+ }
+
+ return true;
+}
+
+void
+CanvasX11::release_fbo()
+{
+ glDeleteFramebuffers(1, &fbo_);
+ glDeleteRenderbuffers(1, &color_renderbuffer_);
+ glDeleteRenderbuffers(1, &depth_renderbuffer_);
+ fbo_ = 0;
+ color_renderbuffer_ = 0;
+ depth_renderbuffer_ = 0;
+
+ gl_color_format_ = 0;
+ gl_depth_format_ = 0;
+}
+
+const char *
+CanvasX11::get_gl_format_str(GLenum f)
+{
+ const char *str;
+
+ switch(f) {
+ case GL_RGBA8: str = "GL_RGBA8"; break;
+ case GL_RGB8: str = "GL_RGB8"; break;
+ case GL_RGBA4: str = "GL_RGBA4"; break;
+ case GL_RGB5_A1: str = "GL_RGB5_A1"; break;
+ case GL_RGB565: str = "GL_RGB565"; break;
+ case GL_DEPTH_COMPONENT16: str = "GL_DEPTH_COMPONENT16"; break;
+ case GL_DEPTH_COMPONENT24: str = "GL_DEPTH_COMPONENT24"; break;
+ case GL_DEPTH_COMPONENT32: str = "GL_DEPTH_COMPONENT32"; break;
+ case GL_NONE: str = "GL_NONE"; break;
+ default: str = "Unknown"; break;
+ }
+
+ return str;
+}
+
diff --git a/src/canvas-x11.h b/src/canvas-x11.h
new file mode 100644
index 0000000..7b3b456
--- /dev/null
+++ b/src/canvas-x11.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#ifndef GLMARK2_CANVAS_X11_H_
+#define GLMARK2_CANVAS_X11_H_
+
+#include "canvas.h"
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+/**
+ * Canvas for rendering with GL to an X11 window.
+ */
+class CanvasX11 : public Canvas
+{
+public:
+ ~CanvasX11() {}
+
+ virtual bool init();
+ virtual bool reset();
+ virtual void visible(bool visible);
+ virtual void clear();
+ virtual void update();
+ virtual void print_info();
+ virtual Pixel read_pixel(int x, int y);
+ virtual void write_to_file(std::string &filename);
+ virtual bool should_quit();
+ virtual void resize(int width, int height);
+ virtual unsigned int fbo();
+
+protected:
+ CanvasX11(int width, int height) :
+ Canvas(width, height), xwin_(0), xdpy_(0), fullscreen_(false),
+ gl_color_format_(0), gl_depth_format_(0),
+ color_renderbuffer_(0), depth_renderbuffer_(0), fbo_(0) {}
+
+ /**
+ * Gets the XVisualInfo to use for creating the X window with.
+ *
+ * The caller should XFree() the returned XVisualInfo when done.
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @return the XVisualInfo
+ */
+ virtual XVisualInfo *get_xvisualinfo() = 0;
+
+ /**
+ * Initializes window system interfaces for GL rendering.
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @return whether the operation succeeded
+ */
+ virtual bool init_gl_winsys() = 0;
+
+ /**
+ * Makes the canvas the current target for GL rendering.
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @return whether the operation succeeded
+ */
+ virtual bool make_current() = 0;
+
+ /**
+ * Resets the underlying GL context for rendering.
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @return whether the operation succeeded
+ */
+ virtual bool reset_context() = 0;
+
+ /**
+ * Swaps the GL buffers (assuming double buffering is used).
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @return whether the operation succeeded
+ */
+ virtual void swap_buffers() = 0;
+
+ /**
+ * Gets information about the GL visual used for this canvas.
+ *
+ * This method should be implemented in derived classes.
+ */
+ virtual void get_glvisualconfig(GLVisualConfig &visual_config) = 0;
+
+ /**
+ * Whether the current implementation supports GL(ES) 2.0.
+ *
+ * @return true if it supports GL(ES) 2.0, false otherwise
+ */
+ bool supports_gl2();
+
+
+ /** The X window associated with this canvas. */
+ Window xwin_;
+ /** The X display associated with this canvas. */
+ Display *xdpy_;
+
+private:
+ void resize_no_viewport(int width, int height);
+ bool ensure_x_window();
+ bool do_make_current();
+ bool ensure_gl_formats();
+ bool ensure_fbo();
+ void release_fbo();
+
+ const char *get_gl_format_str(GLenum f);
+
+ bool fullscreen_;
+ GLenum gl_color_format_;
+ GLenum gl_depth_format_;
+ GLuint color_renderbuffer_;
+ GLuint depth_renderbuffer_;
+ GLuint fbo_;
+};
+
+#endif
+
diff --git a/src/canvas.h b/src/canvas.h
new file mode 100644
index 0000000..4983ada
--- /dev/null
+++ b/src/canvas.h
@@ -0,0 +1,261 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker
+ */
+#ifndef GLMARK2_CANVAS_H_
+#define GLMARK2_CANVAS_H_
+
+#include "gl-headers.h"
+#include "mat.h"
+#include "gl-visual-config.h"
+
+#include <stdint.h>
+#include <string>
+#include <stdio.h>
+#include <cmath>
+
+/**
+ * Abstraction for a GL rendering target.
+ */
+class Canvas
+{
+public:
+ virtual ~Canvas() {}
+
+ /**
+ * A pixel value.
+ */
+ struct Pixel {
+ Pixel():
+ r(0), g(0), b(0), a(0) {}
+ Pixel(uint8_t r, uint8_t g, uint8_t b, uint8_t a):
+ r(r), g(g), b(b), a(a) {}
+ /**
+ * Gets the pixel value as a 32-bit integer in 0xAABBGGRR format.
+ *
+ * @return the pixel value
+ */
+ uint32_t to_le32()
+ {
+ return static_cast<uint32_t>(r) +
+ (static_cast<uint32_t>(g) << 8) +
+ (static_cast<uint32_t>(b) << 16) +
+ (static_cast<uint32_t>(a) << 24);
+
+ }
+
+ /**
+ * Gets the euclidian distance from this pixel in 3D RGB space.
+ *
+ * @param p the pixel to get the distance from
+ *
+ * @return the euclidian distance
+ */
+ double distance_rgb(const Canvas::Pixel &p)
+ {
+ // These work without casts because of integer promotion rules
+ // (the uint8_ts are promoted to ints)
+ double d = (r - p.r) * (r - p.r) +
+ (g - p.g) * (g - p.g) +
+ (b - p.b) * (b - p.b);
+ return std::sqrt(d);
+ }
+
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+ uint8_t a;
+ };
+
+
+ /**
+ * Initializes the canvas and makes it the target of GL operations.
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @return whether initialization succeeded
+ */
+ virtual bool init() { return false; }
+
+ /**
+ * Resets the canvas, destroying and recreating resources to give each new
+ * test scenario a fresh context for rendering.
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @return whether reset succeeded
+ */
+ virtual bool reset() { return false; }
+
+ /**
+ * Changes the visibility of the canvas.
+ *
+ * The canvas is initially not visible.
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @param visible true to make the Canvas visible, false otherwise
+ */
+ virtual void visible(bool visible) { static_cast<void>(visible); }
+
+ /**
+ * Clears the canvas.
+ * This method should be implemented in derived classes.
+ */
+ virtual void clear() {}
+
+ /**
+ * Ensures that the canvas on-screen representation gets updated
+ * with the latest canvas contents.
+ *
+ * This method should be implemented in derived classes.
+ */
+ virtual void update() {}
+
+ /**
+ * Prints information about the canvas.
+ *
+ * This method should be implemented in derived classes.
+ */
+ virtual void print_info() {}
+
+ /**
+ * Reads a pixel from the canvas.
+ *
+ * The (0, 0) point is the lower left corner. The X and Y coordinates
+ * increase towards the right and top, respectively.
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @param x the X coordinate
+ * @param y the Y coordinate
+ *
+ * @return the pixel
+ */
+ virtual Pixel read_pixel(int x, int y)
+ {
+ static_cast<void>(x);
+ static_cast<void>(y);
+ return Pixel();
+ }
+
+ /**
+ * Writes the canvas contents to a file.
+ *
+ * The pixel save order is upper left to lower right. Each pixel value
+ * is stored as four consecutive bytes R,G,B,A.
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @param filename the name of the file to write to
+ */
+ virtual void write_to_file(std::string &filename) { static_cast<void>(filename); }
+
+ /**
+ * Whether we should quit the application.
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @return true if we should quit, false otherwise
+ */
+ virtual bool should_quit() { return false; }
+
+ /**
+ * Resizes the canvas.
+ *
+ * This method should be implemented in derived classes.
+ *
+ * @param width the new width in pixels
+ * @param height the new height in pixels
+ *
+ * @return true if we should quit, false otherwise
+ */
+ virtual void resize(int width, int height) { static_cast<void>(width); static_cast<void>(height); }
+
+ /**
+ * Gets the FBO associated with the canvas.
+ *
+ * @return the FBO
+ */
+ virtual unsigned int fbo() { return 0; }
+
+ /**
+ * Gets a dummy canvas object.
+ *
+ * @return the dummy canvas
+ */
+ static Canvas &dummy()
+ {
+ static Canvas dummy_canvas(0, 0);
+ return dummy_canvas;
+ }
+
+ /**
+ * Gets the width of the canvas.
+ *
+ * @return the width in pixels
+ */
+ int width() { return width_; }
+
+ /**
+ * Gets the height of the canvas.
+ *
+ * @return the height in pixels
+ */
+ int height() { return height_; }
+
+ /**
+ * Gets the projection matrix recommended for use with the canvas.
+ *
+ * It's not mandatory to use this projection matrix.
+ *
+ * @return the projection matrix
+ */
+ const LibMatrix::mat4 &projection() { return projection_; }
+
+ /**
+ * Sets whether the canvas should be backed by an off-screen surface.
+ *
+ * This takes effect after the next init()/reset().
+ */
+ void offscreen(bool offscreen) { offscreen_ = offscreen; }
+
+ /**
+ * Sets the preferred visual configuration.
+ *
+ * This takes effect after the next init()/reset().
+ */
+ void visual_config(GLVisualConfig &config) { visual_config_ = config; }
+
+protected:
+ Canvas(int width, int height) :
+ width_(width), height_(height), offscreen_(false) {}
+
+ int width_;
+ int height_;
+ LibMatrix::mat4 projection_;
+ bool offscreen_;
+ GLVisualConfig visual_config_;
+};
+
+#endif
diff --git a/src/default-benchmarks.h b/src/default-benchmarks.h
new file mode 100644
index 0000000..3726a61
--- /dev/null
+++ b/src/default-benchmarks.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#ifndef GLMARK2_DEFAULT_BENCHMARKS_H_
+#define GLMARK2_DEFAULT_BENCHMARKS_H_
+
+#include <string>
+#include <vector>
+
+class DefaultBenchmarks
+{
+public:
+ static const std::vector<std::string>& get()
+ {
+ static std::vector<std::string> default_benchmarks;
+
+ if (default_benchmarks.empty())
+ populate(default_benchmarks);
+
+ return default_benchmarks;
+ }
+
+private:
+ static void populate(std::vector<std::string>& benchmarks)
+ {
+ benchmarks.push_back("build:use-vbo=false");
+ benchmarks.push_back("build:use-vbo=true");
+ benchmarks.push_back("texture:texture-filter=nearest");
+ benchmarks.push_back("texture:texture-filter=linear");
+ benchmarks.push_back("texture:texture-filter=mipmap");
+ benchmarks.push_back("shading:shading=gouraud");
+ benchmarks.push_back("shading:shading=blinn-phong-inf");
+ benchmarks.push_back("shading:shading=phong");
+ benchmarks.push_back("bump:bump-render=high-poly");
+ benchmarks.push_back("bump:bump-render=normals");
+ benchmarks.push_back("bump:bump-render=height");
+ benchmarks.push_back("effect2d:kernel=0,1,0;1,-4,1;0,1,0;");
+ benchmarks.push_back("effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;");
+ benchmarks.push_back("pulsar:quads=5:texture=false:light=false");
+ benchmarks.push_back("desktop:windows=4:effect=blur:blur-radius=5:passes=1:separable=true");
+ benchmarks.push_back("desktop:windows=4:effect=shadow");
+ benchmarks.push_back("buffer:update-fraction=0.5:update-dispersion=0.9:columns=200:update-method=map:interleave=false");
+ benchmarks.push_back("buffer:update-fraction=0.5:update-dispersion=0.9:columns=200:update-method=subdata:interleave=false");
+ benchmarks.push_back("buffer:update-fraction=0.5:update-dispersion=0.9:columns=200:update-method=map:interleave=true");
+ benchmarks.push_back("ideas:speed=duration");
+ benchmarks.push_back("jellyfish");
+ benchmarks.push_back("terrain");
+ benchmarks.push_back("shadow");
+ benchmarks.push_back("refract");
+ benchmarks.push_back("conditionals:vertex-steps=0:fragment-steps=0");
+ benchmarks.push_back("conditionals:vertex-steps=0:fragment-steps=5");
+ benchmarks.push_back("conditionals:vertex-steps=5:fragment-steps=0");
+ benchmarks.push_back("function:fragment-steps=5:fragment-complexity=low");
+ benchmarks.push_back("function:fragment-steps=5:fragment-complexity=medium");
+ benchmarks.push_back("loop:vertex-steps=5:fragment-steps=5:fragment-loop=false");
+ benchmarks.push_back("loop:vertex-steps=5:fragment-steps=5:fragment-uniform=false");
+ benchmarks.push_back("loop:vertex-steps=5:fragment-steps=5:fragment-uniform=true");
+ }
+};
+
+#endif
diff --git a/src/egl-state.cpp b/src/egl-state.cpp
new file mode 100644
index 0000000..639421a
--- /dev/null
+++ b/src/egl-state.cpp
@@ -0,0 +1,578 @@
+//
+// Copyright © 2012 Linaro Limited
+//
+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+//
+// glmark2 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 3 of the License, or (at your option) any later
+// version.
+//
+// glmark2 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
+// glmark2. If not, see <http://www.gnu.org/licenses/>.
+//
+// Authors:
+// Jesse Barker
+//
+#include "egl-state.h"
+#include "log.h"
+#include "options.h"
+#include "limits.h"
+#include <iomanip>
+#include <sstream>
+
+using std::vector;
+using std::string;
+
+EglConfig::EglConfig(EGLDisplay dpy, EGLConfig config) :
+ handle_(config),
+ bufferSize_(0),
+ redSize_(0),
+ greenSize_(0),
+ blueSize_(0),
+ luminanceSize_(0),
+ alphaSize_(0),
+ alphaMaskSize_(0),
+ bindTexRGB_(false),
+ bindTexRGBA_(false),
+ bufferType_(EGL_RGB_BUFFER),
+ caveat_(0),
+ configID_(0),
+ conformant_(0),
+ depthSize_(0),
+ level_(0),
+ pbufferWidth_(0),
+ pbufferHeight_(0),
+ pbufferPixels_(0),
+ minSwapInterval_(0),
+ maxSwapInterval_(0),
+ nativeID_(0),
+ nativeType_(0),
+ nativeRenderable_(false),
+ sampleBuffers_(0),
+ samples_(0),
+ stencilSize_(0),
+ surfaceType_(0),
+ xparentType_(0),
+ xparentRedValue_(0),
+ xparentGreenValue_(0),
+ xparentBlueValue_(0)
+{
+ vector<string> badAttribVec;
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_CONFIG_ID, &configID_))
+ {
+ badAttribVec.push_back("EGL_CONFIG_ID");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_CONFIG_CAVEAT, &caveat_))
+ {
+ badAttribVec.push_back("EGL_CONFIG_CAVEAT");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_CONFORMANT, &conformant_))
+ {
+ badAttribVec.push_back("EGL_CONFORMANT");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_COLOR_BUFFER_TYPE, &bufferType_))
+ {
+ badAttribVec.push_back("EGL_COLOR_BUFFER_TYPE");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_BUFFER_SIZE, &bufferSize_))
+ {
+ badAttribVec.push_back("EGL_BUFFER_SIZE");
+ }
+
+ if (bufferType_ == EGL_RGB_BUFFER)
+ {
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_RED_SIZE, &redSize_))
+ {
+ badAttribVec.push_back("EGL_RED_SIZE");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_GREEN_SIZE, &greenSize_))
+ {
+ badAttribVec.push_back("EGL_GREEN_SIZE");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_BLUE_SIZE, &blueSize_))
+ {
+ badAttribVec.push_back("EGL_BLUE_SIZE");
+ }
+ }
+ else
+ {
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_LUMINANCE_SIZE, &luminanceSize_))
+ {
+ badAttribVec.push_back("EGL_LUMINANCE_SIZE");
+ }
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_ALPHA_SIZE, &alphaSize_))
+ {
+ badAttribVec.push_back("EGL_ALPHA_SIZE");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_ALPHA_MASK_SIZE, &alphaMaskSize_))
+ {
+ badAttribVec.push_back("EGL_ALPHA_MASK_SIZE");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_DEPTH_SIZE, &depthSize_))
+ {
+ badAttribVec.push_back("EGL_DEPTH_SIZE");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_STENCIL_SIZE, &stencilSize_))
+ {
+ badAttribVec.push_back("EGL_STENCIL_SIZE");
+ }
+ EGLint doBind(EGL_FALSE);
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_BIND_TO_TEXTURE_RGB, &doBind))
+ {
+ badAttribVec.push_back("EGL_BIND_TO_TEXTURE_RGB");
+ }
+ bindTexRGB_ = (doBind == EGL_TRUE);
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_BIND_TO_TEXTURE_RGBA, &doBind))
+ {
+ badAttribVec.push_back("EGL_BIND_TO_TEXTURE_RGBA");
+ }
+ bindTexRGBA_ = (doBind == EGL_TRUE);
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_LEVEL, &level_))
+ {
+ badAttribVec.push_back("EGL_LEVEL");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_MAX_PBUFFER_WIDTH, &pbufferWidth_))
+ {
+ badAttribVec.push_back("EGL_MAX_PBUFFER_WIDTH");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_MAX_PBUFFER_HEIGHT, &pbufferHeight_))
+ {
+ badAttribVec.push_back("EGL_MAX_PBUFFER_HEIGHT");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_MAX_PBUFFER_PIXELS, &pbufferPixels_))
+ {
+ badAttribVec.push_back("EGL_MAX_PBUFFER_PIXELS");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_MIN_SWAP_INTERVAL, &minSwapInterval_))
+ {
+ badAttribVec.push_back("EGL_MIN_SWAP_INTERVAL");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_MAX_SWAP_INTERVAL, &maxSwapInterval_))
+ {
+ badAttribVec.push_back("EGL_MAX_SWAP_INTERVAL");
+ }
+ EGLint doNative(EGL_FALSE);
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_NATIVE_RENDERABLE, &doNative))
+ {
+ badAttribVec.push_back("EGL_NATIVE_RENDERABLE");
+ }
+ nativeRenderable_ = (doNative == EGL_TRUE);
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_NATIVE_VISUAL_TYPE, &nativeType_))
+ {
+ badAttribVec.push_back("EGL_NATIVE_VISUAL_TYPE");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_NATIVE_VISUAL_ID, &nativeID_))
+ {
+ badAttribVec.push_back("EGL_NATIVE_VISUAL_ID");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_SURFACE_TYPE, &surfaceType_))
+ {
+ badAttribVec.push_back("EGL_SURFACE_TYPE");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_SAMPLE_BUFFERS, &sampleBuffers_))
+ {
+ badAttribVec.push_back("EGL_SAMPLE_BUFFERS");
+ }
+ if (sampleBuffers_)
+ {
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_SAMPLES, &samples_))
+ {
+ badAttribVec.push_back("EGL_SAMPLES");
+ }
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_TRANSPARENT_TYPE, &xparentType_))
+ {
+ badAttribVec.push_back("EGL_TRANSPARENT_TYPE");
+ }
+ //if (xparentType_ != EGL_NONE)
+ {
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_TRANSPARENT_RED_VALUE, &xparentRedValue_))
+ {
+ badAttribVec.push_back("EGL_TRANSPARENT_RED_VALUE");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_TRANSPARENT_GREEN_VALUE, &xparentGreenValue_))
+ {
+ badAttribVec.push_back("EGL_TRANSPARENT_GREEN_VALUE");
+ }
+ if (!eglGetConfigAttrib(dpy, handle_, EGL_TRANSPARENT_BLUE_VALUE, &xparentBlueValue_))
+ {
+ badAttribVec.push_back("EGL_TRANSPARENT_BLUE_VALUE");
+ }
+ }
+
+ if (!badAttribVec.empty())
+ {
+ Log::error("Failed to get the following config attributes for config 0x%x:\n",
+ config);
+ for (vector<string>::const_iterator attribIt = badAttribVec.begin();
+ attribIt != badAttribVec.end();
+ attribIt++)
+ {
+ Log::error("%s\n", attribIt->c_str());
+ }
+ }
+}
+
+void
+EglConfig::print_header()
+{
+ Log::debug("\n");
+ Log::debug(" cfg buf rgb colorbuffer dp st config native support surface sample\n");
+ Log::debug(" id sz lum r g b a th cl caveat render visid type buf ns\n");
+ Log::debug("------------------------------------------------------------------------\n");
+}
+
+void
+EglConfig::print() const
+{
+ std::ostringstream s;
+ s.setf(std::ios::showbase);
+ s.fill(' ');
+ s << std::setw(7) << std::hex << configID_;
+ s << std::setw(4) << std::dec << bufferSize_;
+ if (bufferType_ == EGL_RGB_BUFFER)
+ {
+ s << std::setw(5) << "rgb";
+ s << std::setw(3) << redSize_;
+ s << std::setw(3) << greenSize_;
+ s << std::setw(3) << blueSize_;
+ }
+ else
+ {
+ s << std::setw(5) << "lum";
+ s << std::setw(3) << luminanceSize_;
+ s << std::setw(3) << 0;
+ s << std::setw(3) << 0;
+ }
+ s << std::setw(3) << alphaSize_;
+ s << std::setw(4) << depthSize_;
+ s << std::setw(3) << stencilSize_;
+ string caveat("None");
+ switch (caveat_)
+ {
+ case EGL_SLOW_CONFIG:
+ caveat = string("Slow");
+ break;
+ case EGL_NON_CONFORMANT_CONFIG:
+ caveat = string("Ncon");
+ break;
+ case EGL_NONE:
+ // Initialized to none.
+ break;
+ }
+ s << std::setw(7) << caveat;
+ string doNative(nativeRenderable_ ? "true" : "false");
+ s << std::setw(7) << doNative;
+ s << std::setw(8) << std::hex << nativeID_;
+ s << std::setw(8) << std::hex << surfaceType_;
+ s << std::setw(4) << std::dec << sampleBuffers_;
+ s << std::setw(3) << std::dec << samples_;
+ Log::debug("%s\n", s.str().c_str());
+}
+
+
+bool
+EGLState::init_display(EGLNativeDisplayType native_display, GLVisualConfig& visual_config)
+{
+ native_display_ = native_display;
+ visual_config_ = visual_config;
+
+ return gotValidDisplay();
+}
+
+bool
+EGLState::init_surface(EGLNativeWindowType native_window)
+{
+ native_window_ = reinterpret_cast<EGLNativeWindowType>(native_window);
+
+ return gotValidSurface();
+}
+
+void
+EGLState::swap()
+{
+ eglSwapBuffers(egl_display_, egl_surface_);
+}
+
+bool
+EGLState::gotValidDisplay()
+{
+ if (egl_display_)
+ return true;
+
+ egl_display_ = eglGetDisplay(native_display_);
+ if (!egl_display_) {
+ Log::error("eglGetDisplay() failed with error: 0x%x\n", eglGetError());
+ return false;
+ }
+ int egl_major(-1);
+ int egl_minor(-1);
+ if (!eglInitialize(egl_display_, &egl_major, &egl_minor)) {
+ Log::error("eglInitialize() failed with error: 0x%x\n", eglGetError());
+ egl_display_ = 0;
+ return false;
+ }
+
+#if USE_GLESv2
+ EGLenum apiType(EGL_OPENGL_ES_API);
+#elif USE_GL
+ EGLenum apiType(EGL_OPENGL_API);
+#endif
+ if (!eglBindAPI(apiType)) {
+ Log::error("Failed to bind api EGL_OPENGL_ES_API\n");
+ return false;
+ }
+
+ return true;
+}
+
+void
+EGLState::get_glvisualconfig(EGLConfig config, GLVisualConfig& visual_config)
+{
+ eglGetConfigAttrib(egl_display_, config, EGL_BUFFER_SIZE, &visual_config.buffer);
+ eglGetConfigAttrib(egl_display_, config, EGL_RED_SIZE, &visual_config.red);
+ eglGetConfigAttrib(egl_display_, config, EGL_GREEN_SIZE, &visual_config.green);
+ eglGetConfigAttrib(egl_display_, config, EGL_BLUE_SIZE, &visual_config.blue);
+ eglGetConfigAttrib(egl_display_, config, EGL_ALPHA_SIZE, &visual_config.alpha);
+ eglGetConfigAttrib(egl_display_, config, EGL_DEPTH_SIZE, &visual_config.depth);
+ eglGetConfigAttrib(egl_display_, config, EGL_STENCIL_SIZE, &visual_config.stencil);
+}
+
+EGLConfig
+EGLState::select_best_config(std::vector<EGLConfig>& configs)
+{
+ int best_score(INT_MIN);
+ EGLConfig best_config(0);
+
+ /*
+ * Go through all the configs and choose the one with the best score,
+ * i.e., the one better matching the requested config.
+ */
+ for (std::vector<EGLConfig>::const_iterator iter = configs.begin();
+ iter != configs.end();
+ iter++)
+ {
+ const EGLConfig config(*iter);
+ GLVisualConfig vc;
+ int score;
+
+ get_glvisualconfig(config, vc);
+
+ score = vc.match_score(visual_config_);
+
+ if (score > best_score) {
+ best_score = score;
+ best_config = config;
+ }
+ }
+
+ return best_config;
+}
+
+bool
+EGLState::gotValidConfig()
+{
+ if (egl_config_)
+ return true;
+
+ if (!gotValidDisplay())
+ return false;
+
+ const EGLint config_attribs[] = {
+ EGL_RED_SIZE, visual_config_.red,
+ EGL_GREEN_SIZE, visual_config_.green,
+ EGL_BLUE_SIZE, visual_config_.blue,
+ EGL_ALPHA_SIZE, visual_config_.alpha,
+ EGL_DEPTH_SIZE, visual_config_.depth,
+ EGL_STENCIL_SIZE, visual_config_.stencil,
+#if USE_GLESv2
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#elif USE_GL
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+#endif
+ EGL_NONE
+ };
+
+ // Find out how many configs match the attributes.
+ EGLint num_configs(0);
+ if (!eglChooseConfig(egl_display_, config_attribs, 0, 0, &num_configs)) {
+ Log::error("eglChooseConfig() (count query) failed with error: %d\n",
+ eglGetError());
+ return false;
+ }
+
+ if (num_configs == 0) {
+ Log::error("eglChooseConfig() didn't return any configs\n");
+ return false;
+ }
+
+ // Get all the matching configs
+ vector<EGLConfig> configs(num_configs);
+ if (!eglChooseConfig(egl_display_, config_attribs, &configs.front(),
+ num_configs, &num_configs))
+ {
+ Log::error("eglChooseConfig() failed with error: %d\n",
+ eglGetError());
+ return false;
+ }
+
+ // Select the best matching config
+ egl_config_ = select_best_config(configs);
+
+ vector<EglConfig> configVec;
+ for (vector<EGLConfig>::const_iterator configIt = configs.begin();
+ configIt != configs.end();
+ configIt++)
+ {
+ EglConfig cfg(egl_display_, *configIt);
+ configVec.push_back(cfg);
+ if (*configIt == egl_config_) {
+ best_config_ = cfg;
+ }
+ }
+
+ // Print out the config information, and let the user know the decision
+ // about the "best" one with respect to the options.
+ unsigned int lineNumber(0);
+ Log::debug("Got %u suitable EGLConfigs:\n", num_configs);
+ for (vector<EglConfig>::const_iterator configIt = configVec.begin();
+ configIt != configVec.end();
+ configIt++, lineNumber++)
+ {
+ if (!(lineNumber % 32))
+ {
+ configIt->print_header();
+ }
+ configIt->print();
+ }
+ Log::debug("\n");
+ Log::debug("Best EGLConfig ID: 0x%x\n", best_config_.configID());
+
+ return true;
+}
+
+bool
+EGLState::gotValidSurface()
+{
+ if (egl_surface_)
+ return true;
+
+ if (!gotValidDisplay())
+ return false;
+
+ if (!gotValidConfig())
+ return false;
+
+ egl_surface_ = eglCreateWindowSurface(egl_display_, egl_config_, native_window_, 0);
+ if (!egl_surface_) {
+ Log::error("eglCreateWindowSurface failed with error: 0x%x\n", eglGetError());
+ return false;
+ }
+
+ return true;
+}
+
+bool
+EGLState::gotValidContext()
+{
+ if (egl_context_)
+ return true;
+
+ if (!gotValidDisplay())
+ return false;
+
+ if (!gotValidConfig())
+ return false;
+
+ static const EGLint context_attribs[] = {
+#ifdef USE_GLESv2
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+#endif
+ EGL_NONE
+ };
+
+ egl_context_ = eglCreateContext(egl_display_, egl_config_,
+ EGL_NO_CONTEXT, context_attribs);
+ if (!egl_context_) {
+ Log::error("eglCreateContext() failed with error: 0x%x\n",
+ eglGetError());
+ return false;
+ }
+
+ return true;
+}
+
+bool
+EGLState::valid()
+{
+ if (!gotValidDisplay())
+ return false;
+
+ if (!gotValidConfig())
+ return false;
+
+ if (!gotValidSurface())
+ return false;
+
+ if (!gotValidContext())
+ return false;
+
+ if (egl_context_ == eglGetCurrentContext())
+ return true;
+
+ if (!eglMakeCurrent(egl_display_, egl_surface_, egl_surface_, egl_context_)) {
+ Log::error("eglMakeCurrent failed with error: 0x%x\n", eglGetError());
+ return false;
+ }
+
+ if (!eglSwapInterval(egl_display_, 0)) {
+ Log::info("** Failed to set swap interval. Results may be bounded above by refresh rate.\n");
+ }
+
+ return true;
+}
+
+bool
+EGLState::gotNativeConfig(int& vid)
+{
+ if (!gotValidConfig())
+ return false;
+
+ EGLint native_id;
+ if (!eglGetConfigAttrib(egl_display_, egl_config_, EGL_NATIVE_VISUAL_ID,
+ &native_id))
+ {
+ Log::debug("Failed to get native visual id for EGLConfig 0x%x\n", egl_config_);
+ return false;
+ }
+
+ vid = native_id;
+ return true;
+}
+
+bool
+EGLState::reset()
+{
+ if (!gotValidDisplay()) {
+ return false;
+ }
+
+ if (!egl_context_) {
+ return true;
+ }
+
+ if (EGL_FALSE == eglDestroyContext(egl_display_, egl_context_)) {
+ Log::debug("eglDestroyContext failed with error: 0x%x\n", eglGetError());
+ }
+
+ egl_context_ = 0;
+
+ return true;
+}
diff --git a/src/egl-state.h b/src/egl-state.h
new file mode 100644
index 0000000..2eaeba3
--- /dev/null
+++ b/src/egl-state.h
@@ -0,0 +1,151 @@
+//
+// Copyright © 2012 Linaro Limited
+//
+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+//
+// glmark2 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 3 of the License, or (at your option) any later
+// version.
+//
+// glmark2 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
+// glmark2. If not, see <http://www.gnu.org/licenses/>.
+//
+// Authors:
+// Jesse Barker
+//
+#ifndef EGL_STATE_H_
+#define EGL_STATE_H_
+
+#include <vector>
+#include <EGL/egl.h>
+#include "gl-visual-config.h"
+
+class EglConfig
+{
+ EGLConfig handle_;
+ // Color buffer attributes.
+ EGLint bufferSize_;
+ EGLint redSize_;
+ EGLint greenSize_;
+ EGLint blueSize_;
+ EGLint luminanceSize_;
+ EGLint alphaSize_;
+ EGLint alphaMaskSize_;
+ bool bindTexRGB_;
+ bool bindTexRGBA_;
+ EGLint bufferType_;
+ // Base config attributes
+ EGLint caveat_;
+ EGLint configID_;
+ EGLint conformant_;
+ // Depth buffer
+ EGLint depthSize_;
+ // Framebuffer level
+ EGLint level_;
+ // Pbuffers
+ EGLint pbufferWidth_;
+ EGLint pbufferHeight_;
+ EGLint pbufferPixels_;
+ // Swap interval
+ EGLint minSwapInterval_;
+ EGLint maxSwapInterval_;
+ // Native window system attributes.
+ EGLint nativeID_;
+ EGLint nativeType_;
+ bool nativeRenderable_;
+ // Multisample support
+ EGLint sampleBuffers_;
+ EGLint samples_;
+ // Stencil buffer
+ EGLint stencilSize_;
+ EGLint surfaceType_;
+ // Transparency
+ EGLint xparentType_; // Should be RGB or NONE
+ EGLint xparentRedValue_;
+ EGLint xparentGreenValue_;
+ EGLint xparentBlueValue_;
+
+public:
+ EglConfig() :
+ handle_(0),
+ bufferSize_(0),
+ redSize_(0),
+ greenSize_(0),
+ blueSize_(0),
+ luminanceSize_(0),
+ alphaSize_(0),
+ alphaMaskSize_(0),
+ bindTexRGB_(false),
+ bindTexRGBA_(false),
+ bufferType_(EGL_RGB_BUFFER),
+ caveat_(0),
+ configID_(0),
+ conformant_(0),
+ depthSize_(0),
+ level_(0),
+ pbufferWidth_(0),
+ pbufferHeight_(0),
+ pbufferPixels_(0),
+ minSwapInterval_(0),
+ maxSwapInterval_(0),
+ nativeID_(0),
+ nativeType_(0),
+ nativeRenderable_(false),
+ sampleBuffers_(0),
+ samples_(0),
+ stencilSize_(0),
+ surfaceType_(0),
+ xparentType_(0),
+ xparentRedValue_(0),
+ xparentGreenValue_(0),
+ xparentBlueValue_(0) {}
+ EglConfig(EGLDisplay dpy, EGLConfig config);
+ ~EglConfig() {}
+ void print() const;
+ static void print_header();
+ bool isWindowConfig() const { return surfaceType_ & EGL_WINDOW_BIT; }
+ EGLint configID() const { return configID_; }
+};
+
+class EGLState
+{
+ EGLNativeDisplayType native_display_;
+ EGLNativeWindowType native_window_;
+ EGLDisplay egl_display_;
+ EGLConfig egl_config_;
+ EGLContext egl_context_;
+ EGLSurface egl_surface_;
+ GLVisualConfig visual_config_;
+ EglConfig best_config_;
+ bool gotValidDisplay();
+ bool gotValidConfig();
+ bool gotValidSurface();
+ bool gotValidContext();
+ void get_glvisualconfig(EGLConfig config, GLVisualConfig& visual_config);
+ EGLConfig select_best_config(std::vector<EGLConfig>& configs);
+public:
+ EGLState() :
+ native_display_(0),
+ native_window_(0),
+ egl_display_(0),
+ egl_config_(0),
+ egl_context_(0),
+ egl_surface_(0) {}
+ ~EGLState() {}
+ bool valid();
+ bool init_display(EGLNativeDisplayType native_display, GLVisualConfig& config_pref);
+ bool init_surface(EGLNativeWindowType native_window);
+ bool reset();
+ void swap();
+ // Performs a config search, returning a native visual ID on success
+ bool gotNativeConfig(int& vid);
+ void getVisualConfig(GLVisualConfig& vc) { vc = visual_config_; }
+};
+
+#endif // EGL_STATE_H_
diff --git a/src/gl-headers.cpp b/src/gl-headers.cpp
new file mode 100644
index 0000000..487c3c1
--- /dev/null
+++ b/src/gl-headers.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#include "gl-headers.h"
+
+void* (*GLExtensions::MapBuffer) (GLenum target, GLenum access) = 0;
+GLboolean (*GLExtensions::UnmapBuffer) (GLenum target) = 0;
+
+bool
+GLExtensions::support(const std::string &ext)
+{
+ std::string ext_string;
+ const char* exts = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
+ if (exts) {
+ ext_string = exts;
+ }
+
+ const size_t ext_size = ext.size();
+ size_t pos = 0;
+
+ while ((pos = ext_string.find(ext, pos)) != std::string::npos) {
+ char c = ext_string[pos + ext_size];
+ if (c == ' ' || c == '\0')
+ break;
+ }
+
+ return pos != std::string::npos;
+}
diff --git a/src/gl-headers.h b/src/gl-headers.h
new file mode 100644
index 0000000..e9a9818
--- /dev/null
+++ b/src/gl-headers.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#ifndef GLMARK2_GL_HEADERS_H_
+#define GLMARK2_GL_HEADERS_H_
+
+#define GL_GLEXT_PROTOTYPES
+
+#if USE_GL
+#include <GL/gl.h>
+#include <GL/glext.h>
+#ifndef GL_RGB565
+#define GL_RGB565 0x8D62
+#endif
+#elif USE_GLESv2
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#ifndef GL_WRITE_ONLY
+#define GL_WRITE_ONLY GL_WRITE_ONLY_OES
+#endif
+#ifndef GL_DEPTH_COMPONENT24
+#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES
+#endif
+#ifndef GL_DEPTH_COMPONENT32
+#define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES
+#endif
+#ifndef GL_RGBA8
+#define GL_RGBA8 GL_RGBA8_OES
+#endif
+#ifndef GL_RGB8
+#define GL_RGB8 GL_RGB8_OES
+#endif
+#endif
+
+#include <string>
+
+/**
+ * Struct that holds pointers to functions that belong to extensions
+ * in either GL2.0 or GLES2.0.
+ */
+struct GLExtensions {
+ /**
+ * Whether the current context has support for a GL extension.
+ *
+ * @return true if the extension is supported
+ */
+ static bool support(const std::string &ext);
+
+ static void* (*MapBuffer) (GLenum target, GLenum access);
+ static GLboolean (*UnmapBuffer) (GLenum target);
+};
+
+#endif
diff --git a/src/gl-visual-config.cpp b/src/gl-visual-config.cpp
new file mode 100644
index 0000000..dbd87d2
--- /dev/null
+++ b/src/gl-visual-config.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ */
+#include "gl-visual-config.h"
+#include "util.h"
+#include "log.h"
+
+#include <vector>
+
+GLVisualConfig::GLVisualConfig(const std::string &s) :
+ red(1), green(1), blue(1), alpha(1), depth(1), stencil(0), buffer(1)
+{
+ std::vector<std::string> elems;
+
+ Util::split(s, ':', elems, Util::SplitModeNormal);
+
+ for (std::vector<std::string>::const_iterator iter = elems.begin();
+ iter != elems.end();
+ iter++)
+ {
+ std::vector<std::string> opt;
+
+ Util::split(*iter, '=', opt, Util::SplitModeNormal);
+ if (opt.size() == 2) {
+ if (opt[0] == "r" || opt[0] == "red")
+ red = Util::fromString<int>(opt[1]);
+ else if (opt[0] == "g" || opt[0] == "green")
+ green = Util::fromString<int>(opt[1]);
+ else if (opt[0] == "b" || opt[0] == "blue")
+ blue = Util::fromString<int>(opt[1]);
+ else if (opt[0] == "a" || opt[0] == "alpha")
+ alpha = Util::fromString<int>(opt[1]);
+ else if (opt[0] == "d" || opt[0] == "depth")
+ depth = Util::fromString<int>(opt[1]);
+ else if (opt[0] == "s" || opt[0] == "stencil")
+ stencil = Util::fromString<int>(opt[1]);
+ else if (opt[0] == "buf" || opt[0] == "buffer")
+ buffer = Util::fromString<int>(opt[1]);
+ }
+ else
+ Log::info("Warning: ignoring invalid option string '%s' "
+ "in GLVisualConfig description\n",
+ iter->c_str());
+ }
+}
+
+int
+GLVisualConfig::match_score(const GLVisualConfig &target) const
+{
+ int score(0);
+
+ /*
+ * R,G,B,A integer values are at most 8 bits wide (for current widespread
+ * hardware), so we need to scale them by 4 to get them in the [0,32] range.
+ */
+ score += score_component(red, target.red, 4);
+ score += score_component(green, target.green, 4);
+ score += score_component(blue, target.blue, 4);
+ score += score_component(alpha, target.alpha, 4);
+ score += score_component(depth, target.depth, 1);
+ score += score_component(stencil, target.stencil, 0);
+ score += score_component(buffer, target.buffer, 1);
+
+ return score;
+}
+
+int
+GLVisualConfig::score_component(int component, int target, int scale) const
+{
+ /*
+ * The maximum (positive) score that can be returned is based
+ * on the maximum bit width of the components. We assume this to
+ * be 32 bits, which is a reasonable assumption for current platforms.
+ */
+ static const int MAXIMUM_COMPONENT_SCORE = 32;
+ static const int UNACCEPTABLE_COMPONENT_PENALTY = -1000;
+ int score(0);
+
+ if ((component > 0 && target == 0) ||
+ (component == 0 && target > 0))
+ {
+ /*
+ * Penalize components that are not present but have been requested,
+ * and components that have been excluded but are present.
+ */
+ score = UNACCEPTABLE_COMPONENT_PENALTY;
+ }
+ else if (component == target)
+ {
+ /* Reward exact matches with the maximum per component score */
+ score = MAXIMUM_COMPONENT_SCORE;
+ }
+ else
+ {
+ /*
+ * Reward deeper than requested component values, penalize shallower
+ * than requested component values. Because the ranges of component
+ * values vary we use a scaling factor to even them out, so that the
+ * score for all components ranges from [0,MAXIMUM_COMPONENT_SCORE).
+ */
+ score = scale * (component - target);
+ }
+
+ return score;
+}
diff --git a/src/gl-visual-config.h b/src/gl-visual-config.h
new file mode 100644
index 0000000..dc035cd
--- /dev/null
+++ b/src/gl-visual-config.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ */
+#ifndef GLMARK2_GL_VISUAL_CONFIG_H_
+#define GLMARK2_GL_VISUAL_CONFIG_H_
+
+#include <string>
+
+/**
+ * Configuration parameters for a GL visual
+ */
+class GLVisualConfig
+{
+public:
+ GLVisualConfig():
+ red(1), green(1), blue(1), alpha(1), depth(1), stencil(0), buffer(1) {}
+ GLVisualConfig(int r, int g, int b, int a, int d, int s, int buf):
+ red(r), green(g), blue(b), alpha(a), depth(d), stencil(s), buffer(buf) {}
+ GLVisualConfig(const std::string &s);
+
+ /**
+ * How well a GLVisualConfig matches another target config.
+ *
+ * The returned score has no meaning on its own. Its only purpose is
+ * to allow comparison of how well different configs match a target
+ * config, with a higher scores denoting a better match.
+ *
+ * Also note that this operation is not commutative:
+ * a.match_score(b) != b.match_score(a)
+ *
+ * @return the match score
+ */
+ int match_score(const GLVisualConfig &target) const;
+
+ int red;
+ int green;
+ int blue;
+ int alpha;
+ int depth;
+ int stencil;
+ int buffer;
+
+private:
+ int score_component(int component, int target, int scale) const;
+};
+
+#endif
diff --git a/src/image-reader.cpp b/src/image-reader.cpp
new file mode 100644
index 0000000..58407bc
--- /dev/null
+++ b/src/image-reader.cpp
@@ -0,0 +1,386 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include <cstdio>
+#include <png.h>
+#include <jpeglib.h>
+#include <memory>
+
+#include "image-reader.h"
+#include "log.h"
+#include "util.h"
+
+/*******
+ * PNG *
+ *******/
+
+struct PNGReaderPrivate
+{
+ PNGReaderPrivate() :
+ png(0), info(0), rows(0), png_error(0),
+ current_row(0), row_stride(0) {}
+
+ static void png_read_fn(png_structp png_ptr, png_bytep data, png_size_t length)
+ {
+ std::istream *is = reinterpret_cast<std::istream*>(png_get_io_ptr(png_ptr));
+ is->read(reinterpret_cast<char *>(data), length);
+ }
+
+ png_structp png;
+ png_infop info;
+ png_bytepp rows;
+ bool png_error;
+ unsigned int current_row;
+ unsigned int row_stride;
+};
+
+PNGReader::PNGReader(const std::string& filename):
+ priv_(new PNGReaderPrivate())
+{
+ priv_->png_error = !init(filename);
+}
+
+PNGReader::~PNGReader()
+{
+ finish();
+ delete priv_;
+}
+
+bool
+PNGReader::error()
+{
+ return priv_->png_error;
+}
+
+bool
+PNGReader::nextRow(unsigned char *dst)
+{
+ bool ret;
+
+ if (priv_->current_row < height()) {
+ memcpy(dst, priv_->rows[priv_->current_row], priv_->row_stride);
+ priv_->current_row++;
+ ret = true;
+ }
+ else {
+ ret = false;
+ }
+
+ return ret;
+}
+
+unsigned int
+PNGReader::width() const
+{
+ return png_get_image_width(priv_->png, priv_->info);
+}
+
+unsigned int
+PNGReader::height() const
+{
+ return png_get_image_height(priv_->png, priv_->info);
+}
+
+unsigned int
+PNGReader::pixelBytes() const
+{
+ if (png_get_color_type(priv_->png, priv_->info) == PNG_COLOR_TYPE_RGB)
+ {
+ return 3;
+ }
+ return 4;
+}
+
+
+bool
+PNGReader::init(const std::string& filename)
+{
+ static const int png_transforms = PNG_TRANSFORM_STRIP_16 |
+ PNG_TRANSFORM_GRAY_TO_RGB |
+ PNG_TRANSFORM_PACKING |
+ PNG_TRANSFORM_EXPAND;
+
+ Log::debug("Reading PNG file %s\n", filename.c_str());
+
+ const std::auto_ptr<std::istream> is_ptr(Util::get_resource(filename));
+ if (!(*is_ptr)) {
+ Log::error("Cannot open file %s!\n", filename.c_str());
+ return false;
+ }
+
+ /* Set up all the libpng structs we need */
+ priv_->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+ if (!priv_->png) {
+ Log::error("Couldn't create libpng read struct\n");
+ return false;
+ }
+
+ priv_->info = png_create_info_struct(priv_->png);
+ if (!priv_->info) {
+ Log::error("Couldn't create libpng info struct\n");
+ return false;
+ }
+
+ /* Set up libpng error handling */
+ if (setjmp(png_jmpbuf(priv_->png))) {
+ Log::error("libpng error while reading file %s\n", filename.c_str());
+ return false;
+ }
+
+ /* Read the image information and data */
+ png_set_read_fn(priv_->png, reinterpret_cast<voidp>(is_ptr.get()),
+ PNGReaderPrivate::png_read_fn);
+
+ png_read_png(priv_->png, priv_->info, png_transforms, 0);
+
+ priv_->rows = png_get_rows(priv_->png, priv_->info);
+
+ priv_->current_row = 0;
+ priv_->row_stride = width() * pixelBytes();
+
+ return true;
+}
+
+void
+PNGReader::finish()
+{
+ if (priv_->png)
+ {
+ png_destroy_read_struct(&priv_->png, &priv_->info, 0);
+ }
+}
+
+
+/********
+ * JPEG *
+ ********/
+
+struct JPEGErrorMgr
+{
+ struct jpeg_error_mgr pub;
+ jmp_buf jmp_buffer;
+
+ JPEGErrorMgr()
+ {
+ jpeg_std_error(&pub);
+ pub.error_exit = error_exit;
+ }
+
+ static void error_exit(j_common_ptr cinfo)
+ {
+ JPEGErrorMgr *err =
+ reinterpret_cast<JPEGErrorMgr *>(cinfo->err);
+
+ char buffer[JMSG_LENGTH_MAX];
+
+ /* Create the message */
+ (*cinfo->err->format_message)(cinfo, buffer);
+ std::string msg(std::string(buffer) + "\n");
+ Log::error(msg.c_str());
+
+ longjmp(err->jmp_buffer, 1);
+ }
+};
+
+struct JPEGIStreamSourceMgr
+{
+ static const int BUFFER_SIZE = 4096;
+ struct jpeg_source_mgr pub;
+ std::istream *is;
+ JOCTET buffer[BUFFER_SIZE];
+
+ JPEGIStreamSourceMgr(const std::string& filename) : is(0)
+ {
+ is = Util::get_resource(filename);
+
+ /* Fill in jpeg_source_mgr pub struct */
+ pub.init_source = init_source;
+ pub.fill_input_buffer = fill_input_buffer;
+ pub.skip_input_data = skip_input_data;
+ pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
+ pub.term_source = term_source;
+ pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
+ pub.next_input_byte = NULL; /* until buffer loaded */
+ }
+
+ ~JPEGIStreamSourceMgr()
+ {
+ delete is;
+ }
+
+ bool error()
+ {
+ return !is || (is->fail() && !is->eof());
+ }
+
+ static void init_source(j_decompress_ptr cinfo)
+ {
+ static_cast<void>(cinfo);
+ }
+
+ static boolean fill_input_buffer(j_decompress_ptr cinfo)
+ {
+ JPEGIStreamSourceMgr *src =
+ reinterpret_cast<JPEGIStreamSourceMgr *>(cinfo->src);
+
+ src->is->read(reinterpret_cast<char *>(src->buffer), BUFFER_SIZE);
+
+ src->pub.next_input_byte = src->buffer;
+ src->pub.bytes_in_buffer = src->is->gcount();
+
+ /*
+ * If the decoder needs more data, but we have no more bytes left to
+ * read mark the end of input.
+ */
+ if (src->pub.bytes_in_buffer == 0) {
+ src->pub.bytes_in_buffer = 2;
+ src->buffer[0] = 0xFF;
+ src->buffer[0] = JPEG_EOI;
+ }
+
+ return TRUE;
+ }
+
+ static void skip_input_data(j_decompress_ptr cinfo, long num_bytes)
+ {
+ JPEGIStreamSourceMgr *src =
+ reinterpret_cast<JPEGIStreamSourceMgr *>(cinfo->src);
+
+ if (num_bytes > 0) {
+ size_t n = static_cast<size_t>(num_bytes);
+ while (n > src->pub.bytes_in_buffer) {
+ n -= src->pub.bytes_in_buffer;
+ (*src->fill_input_buffer)(cinfo);
+ }
+ src->pub.next_input_byte += n;
+ src->pub.bytes_in_buffer -= n;
+ }
+ }
+
+ static void term_source(j_decompress_ptr cinfo)
+ {
+ static_cast<void>(cinfo);
+ }
+};
+
+struct JPEGReaderPrivate
+{
+ JPEGReaderPrivate(const std::string& filename) :
+ source_mgr(filename), jpeg_error(false) {}
+
+ struct jpeg_decompress_struct cinfo;
+ JPEGErrorMgr error_mgr;
+ JPEGIStreamSourceMgr source_mgr;
+ bool jpeg_error;
+};
+
+
+JPEGReader::JPEGReader(const std::string& filename) :
+ priv_(new JPEGReaderPrivate(filename))
+{
+ priv_->jpeg_error = !init(filename);
+}
+
+JPEGReader::~JPEGReader()
+{
+ finish();
+ delete priv_;
+}
+
+bool
+JPEGReader::error()
+{
+ return priv_->jpeg_error || priv_->source_mgr.error();
+}
+
+bool
+JPEGReader::nextRow(unsigned char *dst)
+{
+ bool ret = true;
+ unsigned char *buffer[1];
+ buffer[0] = dst;
+
+ /* Set up error handling */
+ if (setjmp(priv_->error_mgr.jmp_buffer)) {
+ return false;
+ }
+
+ /* While there are lines left, read next line */
+ if (priv_->cinfo.output_scanline < priv_->cinfo.output_height) {
+ jpeg_read_scanlines(&priv_->cinfo, buffer, 1);
+ }
+ else {
+ jpeg_finish_decompress(&priv_->cinfo);
+ ret = false;
+ }
+
+ return ret;
+}
+
+unsigned int
+JPEGReader::width() const
+{
+ return priv_->cinfo.output_width;
+}
+
+unsigned int
+JPEGReader::height() const
+{
+ return priv_->cinfo.output_height;
+}
+
+unsigned int
+JPEGReader::pixelBytes() const
+{
+ return priv_->cinfo.output_components;
+}
+
+bool
+JPEGReader::init(const std::string& filename)
+{
+ Log::debug("Reading JPEG file %s\n", filename.c_str());
+
+ /* Initialize error manager */
+ priv_->cinfo.err = reinterpret_cast<jpeg_error_mgr*>(&priv_->error_mgr);
+
+ if (setjmp(priv_->error_mgr.jmp_buffer)) {
+ return false;
+ }
+
+ jpeg_create_decompress(&priv_->cinfo);
+ priv_->cinfo.src = reinterpret_cast<jpeg_source_mgr*>(&priv_->source_mgr);
+
+ /* Read header */
+ jpeg_read_header(&priv_->cinfo, TRUE);
+
+ jpeg_start_decompress(&priv_->cinfo);
+
+ return true;
+}
+
+void
+JPEGReader::finish()
+{
+ jpeg_destroy_decompress(&priv_->cinfo);
+}
+
+
+
diff --git a/src/image-reader.h b/src/image-reader.h
new file mode 100644
index 0000000..f4d1fc8
--- /dev/null
+++ b/src/image-reader.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include <string>
+
+class ImageReader
+{
+public:
+ virtual bool error() = 0;
+ virtual bool nextRow(unsigned char *dst) = 0;
+ virtual unsigned int width() const = 0;
+ virtual unsigned int height() const = 0;
+ virtual unsigned int pixelBytes() const = 0;
+ virtual ~ImageReader() {}
+};
+
+class PNGReaderPrivate;
+
+class PNGReader : public ImageReader
+{
+public:
+ PNGReader(const std::string& filename);
+
+ virtual ~PNGReader();
+ bool error();
+ bool nextRow(unsigned char *dst);
+
+ unsigned int width() const;
+ unsigned int height() const;
+ unsigned int pixelBytes() const;
+
+private:
+ bool init(const std::string& filename);
+ void finish();
+
+ PNGReaderPrivate *priv_;
+};
+
+class JPEGReaderPrivate;
+
+class JPEGReader : public ImageReader
+{
+public:
+ JPEGReader(const std::string& filename);
+
+ virtual ~JPEGReader();
+ bool error();
+ bool nextRow(unsigned char *dst);
+ unsigned int width() const;
+ unsigned int height() const;
+ unsigned int pixelBytes() const;
+
+private:
+ bool init(const std::string& filename);
+ void finish();
+
+ JPEGReaderPrivate *priv_;
+};
+
diff --git a/src/libjpeg-turbo/README b/src/libjpeg-turbo/README
new file mode 100644
index 0000000..0e9b429
--- /dev/null
+++ b/src/libjpeg-turbo/README
@@ -0,0 +1,290 @@
+libjpeg-turbo note: This file contains portions of the libjpeg v6b and v8
+README files, with additional wordsmithing by The libjpeg-turbo Project.
+It is included only for reference, as some parts of it may not apply to
+libjpeg-turbo. Please see README-turbo.txt for information specific to
+libjpeg-turbo.
+
+
+The Independent JPEG Group's JPEG software
+==========================================
+
+This distribution contains a release of the Independent JPEG Group's free JPEG
+software. You are welcome to redistribute this software and to use it for any
+purpose, subject to the conditions under LEGAL ISSUES, below.
+
+This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone,
+Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson,
+Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
+and other members of the Independent JPEG Group.
+
+IJG is not affiliated with the official ISO JPEG standards committee.
+
+
+DOCUMENTATION ROADMAP
+=====================
+
+This file contains the following sections:
+
+OVERVIEW General description of JPEG and the IJG software.
+LEGAL ISSUES Copyright, lack of warranty, terms of distribution.
+REFERENCES Where to learn more about JPEG.
+ARCHIVE LOCATIONS Where to find newer versions of this software.
+FILE FORMAT WARS Software *not* to get.
+TO DO Plans for future IJG releases.
+
+Other documentation files in the distribution are:
+
+User documentation:
+ install.txt How to configure and install the IJG software.
+ usage.txt Usage instructions for cjpeg, djpeg, jpegtran,
+ rdjpgcom, and wrjpgcom.
+ *.1 Unix-style man pages for programs (same info as usage.txt).
+ wizard.txt Advanced usage instructions for JPEG wizards only.
+ change.log Version-to-version change highlights.
+Programmer and internal documentation:
+ libjpeg.txt How to use the JPEG library in your own programs.
+ example.c Sample code for calling the JPEG library.
+ structure.txt Overview of the JPEG library's internal structure.
+ filelist.txt Road map of IJG files.
+ coderules.txt Coding style rules --- please read if you contribute code.
+
+Please read at least the files install.txt and usage.txt. Some information
+can also be found in the JPEG FAQ (Frequently Asked Questions) article. See
+ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
+
+If you want to understand how the JPEG code works, we suggest reading one or
+more of the REFERENCES, then looking at the documentation files (in roughly
+the order listed) before diving into the code.
+
+
+OVERVIEW
+========
+
+This package contains C software to implement JPEG image encoding, decoding,
+and transcoding. JPEG (pronounced "jay-peg") is a standardized compression
+method for full-color and gray-scale images. JPEG's strong suit is compressing
+photographic images or other types of images that have smooth color and
+brightness transitions between neighboring pixels. Images with sharp lines or
+other abrupt features may not compress well with JPEG, and a higher JPEG
+quality may have to be used to avoid visible compression artifacts with such
+images.
+
+JPEG is lossy, meaning that the output pixels are not necessarily identical to
+the input pixels. However, on photographic content and other "smooth" images,
+very good compression ratios can be obtained with no visible compression
+artifacts, and extremely high compression ratios are possible if you are
+willing to sacrifice image quality (by reducing the "quality" setting in the
+compressor.)
+
+This software implements JPEG baseline, extended-sequential, and progressive
+compression processes. Provision is made for supporting all variants of these
+processes, although some uncommon parameter settings aren't implemented yet.
+We have made no provision for supporting the hierarchical or lossless
+processes defined in the standard.
+
+We provide a set of library routines for reading and writing JPEG image files,
+plus two sample applications "cjpeg" and "djpeg", which use the library to
+perform conversion between JPEG and some other popular image file formats.
+The library is intended to be reused in other applications.
+
+In order to support file conversion and viewing software, we have included
+considerable functionality beyond the bare JPEG coding/decoding capability;
+for example, the color quantization modules are not strictly part of JPEG
+decoding, but they are essential for output to colormapped file formats or
+colormapped displays. These extra functions can be compiled out of the
+library if not required for a particular application.
+
+We have also included "jpegtran", a utility for lossless transcoding between
+different JPEG processes, and "rdjpgcom" and "wrjpgcom", two simple
+applications for inserting and extracting textual comments in JFIF files.
+
+The emphasis in designing this software has been on achieving portability and
+flexibility, while also making it fast enough to be useful. In particular,
+the software is not intended to be read as a tutorial on JPEG. (See the
+REFERENCES section for introductory material.) Rather, it is intended to
+be reliable, portable, industrial-strength code. We do not claim to have
+achieved that goal in every aspect of the software, but we strive for it.
+
+We welcome the use of this software as a component of commercial products.
+No royalty is required, but we do ask for an acknowledgement in product
+documentation, as described under LEGAL ISSUES.
+
+
+LEGAL ISSUES
+============
+
+In plain English:
+
+1. We don't promise that this software works. (But if you find any bugs,
+ please let us know!)
+2. You can use this software for whatever you want. You don't have to pay us.
+3. You may not pretend that you wrote this software. If you use it in a
+ program, you must acknowledge somewhere in your documentation that
+ you've used the IJG code.
+
+In legalese:
+
+The authors make NO WARRANTY or representation, either express or implied,
+with respect to this software, its quality, accuracy, merchantability, or
+fitness for a particular purpose. This software is provided "AS IS", and you,
+its user, assume the entire risk as to its quality and accuracy.
+
+This software is copyright (C) 1991-2010, Thomas G. Lane, Guido Vollbeding.
+All Rights Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to these
+conditions:
+(1) If any part of the source code for this software is distributed, then this
+README file must be included, with this copyright and no-warranty notice
+unaltered; and any additions, deletions, or changes to the original files
+must be clearly indicated in accompanying documentation.
+(2) If only executable code is distributed, then the accompanying
+documentation must state that "this software is based in part on the work of
+the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user accepts
+full responsibility for any undesirable consequences; the authors accept
+NO LIABILITY for damages of any kind.
+
+These conditions apply to any software derived from or based on the IJG code,
+not just to the unmodified library. If you use our work, you ought to
+acknowledge us.
+
+Permission is NOT granted for the use of any IJG author's name or company name
+in advertising or publicity relating to this software or products derived from
+it. This software may be referred to only as "the Independent JPEG Group's
+software".
+
+We specifically permit and encourage the use of this software as the basis of
+commercial products, provided that all warranty or liability claims are
+assumed by the product vendor.
+
+
+ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
+sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
+ansi2knr.c is NOT covered by the above copyright and conditions, but instead
+by the usual distribution terms of the Free Software Foundation; principally,
+that you must include source code if you redistribute it. (See the file
+ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
+of any program generated from the IJG code, this does not limit you more than
+the foregoing paragraphs do.
+
+The Unix configuration script "configure" was produced with GNU Autoconf.
+It is copyright by the Free Software Foundation but is freely distributable.
+The same holds for its supporting scripts (config.guess, config.sub,
+ltmain.sh). Another support script, install-sh, is copyright by X Consortium
+but is also freely distributable.
+
+The IJG distribution formerly included code to read and write GIF files.
+To avoid entanglement with the Unisys LZW patent, GIF reading support has
+been removed altogether, and the GIF writer has been simplified to produce
+"uncompressed GIFs". This technique does not use the LZW algorithm; the
+resulting GIF files are larger than usual, but are readable by all standard
+GIF decoders.
+
+We are required to state that
+ "The Graphics Interchange Format(c) is the Copyright property of
+ CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ CompuServe Incorporated."
+
+
+REFERENCES
+==========
+
+We recommend reading one or more of these references before trying to
+understand the innards of the JPEG software.
+
+The best short technical introduction to the JPEG compression algorithm is
+ Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
+ Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
+(Adjacent articles in that issue discuss MPEG motion picture compression,
+applications of JPEG, and related topics.) If you don't have the CACM issue
+handy, a PostScript file containing a revised version of Wallace's article is
+available at http://www.ijg.org/files/wallace.ps.gz. The file (actually
+a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
+omits the sample images that appeared in CACM, but it includes corrections
+and some added material. Note: the Wallace article is copyright ACM and IEEE,
+and it may not be used for commercial purposes.
+
+A somewhat less technical, more leisurely introduction to JPEG can be found in
+"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
+M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides
+good explanations and example C code for a multitude of compression methods
+including JPEG. It is an excellent source if you are comfortable reading C
+code but don't know much about data compression in general. The book's JPEG
+sample code is far from industrial-strength, but when you are ready to look
+at a full implementation, you've got one here...
+
+The best currently available description of JPEG is the textbook "JPEG Still
+Image Data Compression Standard" by William B. Pennebaker and Joan L.
+Mitchell, published by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1.
+Price US$59.95, 638 pp. The book includes the complete text of the ISO JPEG
+standards (DIS 10918-1 and draft DIS 10918-2).
+
+The original JPEG standard is divided into two parts, Part 1 being the actual
+specification, while Part 2 covers compliance testing methods. Part 1 is
+titled "Digital Compression and Coding of Continuous-tone Still Images,
+Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
+10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of
+Continuous-tone Still Images, Part 2: Compliance testing" and has document
+numbers ISO/IEC IS 10918-2, ITU-T T.83.
+
+The JPEG standard does not specify all details of an interchangeable file
+format. For the omitted details we follow the "JFIF" conventions, revision
+1.02. JFIF 1.02 has been adopted as an Ecma International Technical Report
+and thus received a formal publication status. It is available as a free
+download in PDF format from
+http://www.ecma-international.org/publications/techreports/E-TR-098.htm.
+A PostScript version of the JFIF document is available at
+http://www.ijg.org/files/jfif.ps.gz. There is also a plain text version at
+http://www.ijg.org/files/jfif.txt.gz, but it is missing the figures.
+
+The TIFF 6.0 file format specification can be obtained by FTP from
+ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
+found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
+IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
+Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
+(Compression tag 7). Copies of this Note can be obtained from
+http://www.ijg.org/files/. It is expected that the next revision
+of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
+Although IJG's own code does not support TIFF/JPEG, the free libtiff library
+uses our library to implement TIFF/JPEG per the Note.
+
+
+ARCHIVE LOCATIONS
+=================
+
+The "official" archive site for this software is www.ijg.org.
+The most recent released version can always be found there in
+directory "files". This particular version will be archived as
+http://www.ijg.org/files/jpegsrc.v8d.tar.gz, and in Windows-compatible
+"zip" archive format as http://www.ijg.org/files/jpegsr8d.zip.
+
+The JPEG FAQ (Frequently Asked Questions) article is a source of some
+general information about JPEG.
+It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
+and other news.answers archive sites, including the official news.answers
+archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
+If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
+with body
+ send usenet/news.answers/jpeg-faq/part1
+ send usenet/news.answers/jpeg-faq/part2
+
+
+FILE FORMAT WARS
+================
+
+The ISO JPEG standards committee actually promotes different formats like
+"JPEG 2000" or "JPEG XR", which are incompatible with original DCT-based
+JPEG. IJG therefore does not support these formats (see REFERENCES). Indeed,
+one of the original reasons for developing this free software was to help
+force convergence on common, interoperable format standards for JPEG files.
+Don't use an incompatible file format!
+(In any case, our decoder will remain capable of reading existing JPEG
+image files indefinitely.)
+
+
+TO DO
+=====
+
+Please send bug reports, offers of help, etc. to jpeg-info@jpegclub.org.
diff --git a/src/libjpeg-turbo/README-turbo.txt b/src/libjpeg-turbo/README-turbo.txt
new file mode 100755
index 0000000..899a368
--- /dev/null
+++ b/src/libjpeg-turbo/README-turbo.txt
@@ -0,0 +1,361 @@
+*******************************************************************************
+** Background
+*******************************************************************************
+
+libjpeg-turbo is a derivative of libjpeg that uses SIMD instructions (MMX,
+SSE2, NEON) to accelerate baseline JPEG compression and decompression on x86,
+x86-64, and ARM systems. On such systems, libjpeg-turbo is generally 2-4x as
+fast as the unmodified version of libjpeg, all else being equal.
+
+libjpeg-turbo was originally based on libjpeg/SIMD by Miyasaka Masaru, but
+the TigerVNC and VirtualGL projects made numerous enhancements to the codec in
+2009, including improved support for Mac OS X, 64-bit support, support for
+32-bit and big-endian pixel formats (RGBX, XBGR, etc.), accelerated Huffman
+encoding/decoding, and various bug fixes. The goal was to produce a fully
+open-source codec that could replace the partially closed-source TurboJPEG/IPP
+codec used by VirtualGL and TurboVNC. libjpeg-turbo generally achieves 80-120%
+of the performance of TurboJPEG/IPP. It is faster in some areas but slower in
+others.
+
+In early 2010, libjpeg-turbo spun off into its own independent project, with
+the goal of making high-speed JPEG compression/decompression technology
+available to a broader range of users and developers.
+
+
+*******************************************************************************
+** License
+*******************************************************************************
+
+Most of libjpeg-turbo inherits the non-restrictive, BSD-style license used by
+libjpeg (see README.) The TurboJPEG/OSS wrapper (both C and Java versions) and
+associated test programs bear a similar license, which is reproduced below:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+- Neither the name of the libjpeg-turbo Project nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+
+*******************************************************************************
+** Using libjpeg-turbo
+*******************************************************************************
+
+libjpeg-turbo includes two APIs that can be used to compress and decompress
+JPEG images:
+
+ TurboJPEG API: This API provides an easy-to-use interface for compressing
+ and decompressing JPEG images in memory. It also provides some functionality
+ that would not be straightforward to achieve using the underlying libjpeg
+ API, such as generating planar YUV images and performing multiple
+ simultaneous lossless transforms on an image. The Java interface for
+ libjpeg-turbo is written on top of the TurboJPEG API.
+
+ libjpeg API: This is the de facto industry-standard API for compressing and
+ decompressing JPEG images. It is more difficult to use than the TurboJPEG
+ API but also more powerful. libjpeg-turbo is both API/ABI-compatible and
+ mathematically compatible with libjpeg v6b. It can also optionally be
+ configured to be API/ABI-compatible with libjpeg v7 and v8 (see below.)
+
+
+=============================
+Replacing libjpeg at Run Time
+=============================
+
+If a Unix application is dynamically linked with libjpeg, then you can replace
+libjpeg with libjpeg-turbo at run time by manipulating LD_LIBRARY_PATH.
+For instance:
+
+ [Using libjpeg]
+ > time cjpeg <vgl_5674_0098.ppm >vgl_5674_0098.jpg
+ real 0m0.392s
+ user 0m0.074s
+ sys 0m0.020s
+
+ [Using libjpeg-turbo]
+ > export LD_LIBRARY_PATH=/opt/libjpeg-turbo/{lib}:$LD_LIBRARY_PATH
+ > time cjpeg <vgl_5674_0098.ppm >vgl_5674_0098.jpg
+ real 0m0.109s
+ user 0m0.029s
+ sys 0m0.010s
+
+NOTE: {lib} can be lib, lib32, lib64, or lib/64, depending on the O/S and
+architecture.
+
+System administrators can also replace the libjpeg sym links in /usr/{lib} with
+links to the libjpeg-turbo dynamic library located in /opt/libjpeg-turbo/{lib}.
+This will effectively accelerate every application that uses the libjpeg
+dynamic library on the system.
+
+The libjpeg-turbo SDK for Visual C++ installs the libjpeg-turbo DLL
+(jpeg62.dll, jpeg7.dll, or jpeg8.dll, depending on whether it was built with
+libjpeg v6b, v7, or v8 emulation) into c:\libjpeg-turbo[64]\bin, and the PATH
+environment variable can be modified such that this directory is searched
+before any others that might contain a libjpeg DLL. However, if a libjpeg
+DLL exists in an application's install directory, then Windows will load this
+DLL first whenever the application is launched. Thus, if an application ships
+with jpeg62.dll, jpeg7.dll, or jpeg8.dll, then back up the application's
+version of this DLL and copy c:\libjpeg-turbo[64]\bin\jpeg*.dll into the
+application's install directory to accelerate it.
+
+The version of the libjpeg-turbo DLL distributed in the libjpeg-turbo SDK for
+Visual C++ requires the Visual C++ 2008 C run-time DLL (msvcr90.dll).
+msvcr90.dll ships with more recent versions of Windows, but users of older
+Windows releases can obtain it from the Visual C++ 2008 Redistributable
+Package, which is available as a free download from Microsoft's web site.
+
+NOTE: Features of libjpeg that require passing a C run-time structure, such
+as a file handle, from an application to libjpeg will probably not work with
+the version of the libjpeg-turbo DLL distributed in the libjpeg-turbo SDK for
+Visual C++, unless the application is also built to use the Visual C++ 2008 C
+run-time DLL. In particular, this affects jpeg_stdio_dest() and
+jpeg_stdio_src().
+
+Mac applications typically embed their own copies of the libjpeg dylib inside
+the (hidden) application bundle, so it is not possible to globally replace
+libjpeg on OS X systems. If an application uses a shared library version of
+libjpeg, then it may be possible to replace the application's version of it.
+This would generally involve copying libjpeg.*.dylib from libjpeg-turbo into
+the appropriate place in the application bundle and using install_name_tool to
+repoint the dylib to the new directory. This requires an advanced knowledge of
+OS X and would not survive an upgrade or a re-install of the application.
+Thus, it is not recommended for most users.
+
+=======================
+Replacing TurboJPEG/IPP
+=======================
+
+libjpeg-turbo is a drop-in replacement for the TurboJPEG/IPP SDK used by
+VirtualGL 2.1.x and TurboVNC 0.6 (and prior.) libjpeg-turbo contains a wrapper
+library (TurboJPEG/OSS) that emulates the TurboJPEG API using libjpeg-turbo
+instead of the closed-source Intel Performance Primitives. You can replace the
+TurboJPEG/IPP package on Linux systems with the libjpeg-turbo package in order
+to make existing releases of VirtualGL 2.1.x and TurboVNC 0.x use the new codec
+at run time. Note that the 64-bit libjpeg-turbo packages contain only 64-bit
+binaries, whereas the TurboJPEG/IPP 64-bit packages contained both 64-bit and
+32-bit binaries. Thus, to replace a TurboJPEG/IPP 64-bit package, install
+both the 64-bit and 32-bit versions of libjpeg-turbo.
+
+You can also build the VirtualGL 2.1.x and TurboVNC 0.6 source code with
+the libjpeg-turbo SDK instead of TurboJPEG/IPP. It should work identically.
+libjpeg-turbo also includes static library versions of TurboJPEG/OSS, which
+are used to build VirtualGL 2.2 and TurboVNC 1.0 and later.
+
+========================================
+Using libjpeg-turbo in Your Own Programs
+========================================
+
+For the most part, libjpeg-turbo should work identically to libjpeg, so in
+most cases, an application can be built against libjpeg and then run against
+libjpeg-turbo. On Unix systems (including Cygwin), you can build against
+libjpeg-turbo instead of libjpeg by setting
+
+ CPATH=/opt/libjpeg-turbo/include
+ and
+ LIBRARY_PATH=/opt/libjpeg-turbo/{lib}
+
+({lib} = lib32 or lib64, depending on whether you are building a 32-bit or a
+64-bit application.)
+
+If using MinGW, then set
+
+ CPATH=/c/libjpeg-turbo-gcc[64]/include
+ and
+ LIBRARY_PATH=/c/libjpeg-turbo-gcc[64]/lib
+
+Building against libjpeg-turbo is useful, for instance, if you want to build an
+application that leverages the libjpeg-turbo colorspace extensions (see below.)
+On Linux and Solaris systems, you would still need to manipulate
+LD_LIBRARY_PATH or create appropriate sym links to use libjpeg-turbo at run
+time. On such systems, you can pass -R /opt/libjpeg-turbo/{lib} to the linker
+to force the use of libjpeg-turbo at run time rather than libjpeg (also useful
+if you want to leverage the colorspace extensions), or you can link against the
+libjpeg-turbo static library.
+
+To force a Linux, Solaris, or MinGW application to link against the static
+version of libjpeg-turbo, you can use the following linker options:
+
+ -Wl,-Bstatic -ljpeg -Wl,-Bdynamic
+
+On OS X, simply add /opt/libjpeg-turbo/lib/libjpeg.a to the linker command
+line (this also works on Linux and Solaris.)
+
+To build Visual C++ applications using libjpeg-turbo, add
+c:\libjpeg-turbo[64]\include to the system or user INCLUDE environment
+variable and c:\libjpeg-turbo[64]\lib to the system or user LIB environment
+variable, and then link against either jpeg.lib (to use the DLL version of
+libjpeg-turbo) or jpeg-static.lib (to use the static version of libjpeg-turbo.)
+
+=====================
+Colorspace Extensions
+=====================
+
+libjpeg-turbo includes extensions that allow JPEG images to be compressed
+directly from (and decompressed directly to) buffers that use BGR, BGRX,
+RGBX, XBGR, and XRGB pixel ordering. This is implemented with ten new
+colorspace constants:
+
+ JCS_EXT_RGB /* red/green/blue */
+ JCS_EXT_RGBX /* red/green/blue/x */
+ JCS_EXT_BGR /* blue/green/red */
+ JCS_EXT_BGRX /* blue/green/red/x */
+ JCS_EXT_XBGR /* x/blue/green/red */
+ JCS_EXT_XRGB /* x/red/green/blue */
+ JCS_EXT_RGBA /* red/green/blue/alpha */
+ JCS_EXT_BGRA /* blue/green/red/alpha */
+ JCS_EXT_ABGR /* alpha/blue/green/red */
+ JCS_EXT_ARGB /* alpha/red/green/blue */
+
+Setting cinfo.in_color_space (compression) or cinfo.out_color_space
+(decompression) to one of these values will cause libjpeg-turbo to read the
+red, green, and blue values from (or write them to) the appropriate position in
+the pixel when compressing from/decompressing to an RGB buffer.
+
+Your application can check for the existence of these extensions at compile
+time with:
+
+ #ifdef JCS_EXTENSIONS
+
+At run time, attempting to use these extensions with a version of libjpeg
+that doesn't support them will result in a "Bogus input colorspace" error.
+
+When using the RGBX, BGRX, XBGR, and XRGB colorspaces during decompression, the
+X byte is undefined, and in order to ensure the best performance, libjpeg-turbo
+can set that byte to whatever value it wishes. If an application expects the X
+byte to be used as an alpha channel, then it should specify JCS_EXT_RGBA,
+JCS_EXT_BGRA, JCS_EXT_ABGR, or JCS_EXT_ARGB. When these colorspace constants
+are used, the X byte is guaranteed to be 0xFF, which is interpreted as opaque.
+
+Your application can check for the existence of the alpha channel colorspace
+extensions at compile time with:
+
+ #ifdef JCS_ALPHA_EXTENSIONS
+
+jcstest.c, located in the libjpeg-turbo source tree, demonstrates how to check
+for the existence of the colorspace extensions at compile time and run time.
+
+=================================
+libjpeg v7 and v8 API/ABI support
+=================================
+
+With libjpeg v7 and v8, new features were added that necessitated extending the
+compression and decompression structures. Unfortunately, due to the exposed
+nature of those structures, extending them also necessitated breaking backward
+ABI compatibility with previous libjpeg releases. Thus, programs that are
+built to use libjpeg v7 or v8 did not work with libjpeg-turbo, since it is
+based on the libjpeg v6b code base. Although libjpeg v7 and v8 are still not
+as widely used as v6b, enough programs (including a few Linux distros) have
+made the switch that it was desirable to provide support for the libjpeg v7/v8
+API/ABI in libjpeg-turbo. Although libjpeg-turbo can now be configured as a
+drop-in replacement for libjpeg v7 or v8, it should be noted that not all of
+the features in libjpeg v7 and v8 are supported (see below.)
+
+By passing an argument of --with-jpeg7 or --with-jpeg8 to configure, or an
+argument of -DWITH_JPEG7=1 or -DWITH_JPEG8=1 to cmake, you can build a version
+of libjpeg-turbo that emulates the libjpeg v7 or v8 API/ABI, so that programs
+that are built against libjpeg v7 or v8 can be run with libjpeg-turbo. The
+following section describes which libjpeg v7+ features are supported and which
+aren't.
+
+libjpeg v7 and v8 Features:
+---------------------------
+
+Fully supported:
+
+-- cjpeg: Separate quality settings for luminance and chrominance
+ Note that the libpjeg v7+ API was extended to accommodate this feature only
+ for convenience purposes. It has always been possible to implement this
+ feature with libjpeg v6b (see rdswitch.c for an example.)
+
+-- cjpeg: 32-bit BMP support
+
+-- jpegtran: lossless cropping
+
+-- jpegtran: -perfect option
+
+-- rdjpgcom: -raw option
+
+-- rdjpgcom: locale awareness
+
+
+Fully supported when using libjpeg v7/v8 emulation:
+
+-- libjpeg: In-memory source and destination managers
+
+
+Not supported:
+
+-- libjpeg: DCT scaling in compressor
+ cinfo.scale_num and cinfo.scale_denom are silently ignored.
+ There is no technical reason why DCT scaling cannot be supported, but
+ without the SmartScale extension (see below), it would only be able to
+ down-scale using ratios of 1/2, 8/15, 4/7, 8/13, 2/3, 8/11, 4/5, and 8/9,
+ which is of limited usefulness.
+
+-- libjpeg: SmartScale
+ cinfo.block_size is silently ignored.
+ SmartScale is an extension to the JPEG format that allows for DCT block
+ sizes other than 8x8. It would be difficult to support this feature while
+ retaining backward compatibility with libjpeg v6b.
+
+-- libjpeg: IDCT scaling extensions in decompressor
+ libjpeg-turbo still supports IDCT scaling with scaling factors of 1/2, 1/4,
+ and 1/8 (same as libjpeg v6b.)
+
+-- libjpeg: Fancy downsampling in compressor
+ cinfo.do_fancy_downsampling is silently ignored.
+ This requires the DCT scaling feature, which is not supported.
+
+-- jpegtran: Scaling
+ This requires both the DCT scaling and SmartScale features, which are not
+ supported.
+
+-- Lossless RGB JPEG files
+ This requires the SmartScale feature, which is not supported.
+
+
+*******************************************************************************
+** Performance pitfalls
+*******************************************************************************
+
+===============
+Restart Markers
+===============
+
+The optimized Huffman decoder in libjpeg-turbo does not handle restart markers
+in a way that makes the rest of the libjpeg infrastructure happy, so it is
+necessary to use the slow Huffman decoder when decompressing a JPEG image that
+has restart markers. This can cause the decompression performance to drop by
+as much as 20%, but the performance will still be much greater than that of
+libjpeg. Many consumer packages, such as PhotoShop, use restart markers when
+generating JPEG images, so images generated by those programs will experience
+this issue.
+
+===============================================
+Fast Integer Forward DCT at High Quality Levels
+===============================================
+
+The algorithm used by the SIMD-accelerated quantization function cannot produce
+correct results whenever the fast integer forward DCT is used along with a JPEG
+quality of 98-100. Thus, libjpeg-turbo must use the non-SIMD quantization
+function in those cases. This causes performance to drop by as much as 40%.
+It is therefore strongly advised that you use the slow integer forward DCT
+whenever encoding images with a JPEG quality of 98 or higher.
diff --git a/src/libjpeg-turbo/config.h b/src/libjpeg-turbo/config.h
new file mode 100644
index 0000000..7dc483e
--- /dev/null
+++ b/src/libjpeg-turbo/config.h
@@ -0,0 +1,137 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Build number */
+#define BUILD "20120626"
+
+/* Support arithmetic encoding */
+#define C_ARITH_CODING_SUPPORTED 1
+
+/* Support arithmetic decoding */
+#define D_ARITH_CODING_SUPPORTED 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <jni.h> header file. */
+/* #undef HAVE_JNI_H */
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Define if your compiler supports prototypes */
+#define HAVE_PROTOTYPES 1
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if the system has the type `unsigned char'. */
+#define HAVE_UNSIGNED_CHAR 1
+
+/* Define to 1 if the system has the type `unsigned short'. */
+#define HAVE_UNSIGNED_SHORT 1
+
+/* Compiler does not support pointers to undefined structures. */
+/* #undef INCOMPLETE_TYPES_BROKEN */
+
+/* How to obtain function inlining. */
+#define INLINE __attribute__((always_inline))
+
+/* libjpeg API version */
+#define JPEG_LIB_VERSION 62
+
+/* libjpeg-turbo version */
+#define LIBJPEG_TURBO_VERSION 1.2.0
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LT_OBJDIR ".libs/"
+
+/* Define if you have BSD-like bzero and bcopy */
+/* #undef NEED_BSD_STRINGS */
+
+/* Define if you need short function names */
+/* #undef NEED_SHORT_EXTERNAL_NAMES */
+
+/* Define if you have sys/types.h */
+#define NEED_SYS_TYPES_H 1
+
+/* Name of package */
+#define PACKAGE "libjpeg-turbo"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libjpeg-turbo"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libjpeg-turbo 1.2.0"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libjpeg-turbo"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.2.0"
+
+/* Define if shift is unsigned */
+/* #undef RIGHT_SHIFT_IS_UNSIGNED */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "1.2.0"
+
+/* Use accelerated SIMD routines. */
+#define WITH_SIMD 1
+
+/* Define to 1 if type `char' is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+/* # undef __CHAR_UNSIGNED__ */
+#endif
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/src/libjpeg-turbo/jaricom.c b/src/libjpeg-turbo/jaricom.c
new file mode 100644
index 0000000..f43e2ea
--- /dev/null
+++ b/src/libjpeg-turbo/jaricom.c
@@ -0,0 +1,153 @@
+/*
+ * jaricom.c
+ *
+ * Developed 1997-2009 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains probability estimation tables for common use in
+ * arithmetic entropy encoding and decoding routines.
+ *
+ * This data represents Table D.2 in the JPEG spec (ISO/IEC IS 10918-1
+ * and CCITT Recommendation ITU-T T.81) and Table 24 in the JBIG spec
+ * (ISO/IEC IS 11544 and CCITT Recommendation ITU-T T.82).
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+/* The following #define specifies the packing of the four components
+ * into the compact INT32 representation.
+ * Note that this formula must match the actual arithmetic encoder
+ * and decoder implementation. The implementation has to be changed
+ * if this formula is changed.
+ * The current organization is leaned on Markus Kuhn's JBIG
+ * implementation (jbig_tab.c).
+ */
+
+#define V(i,a,b,c,d) (((INT32)a << 16) | ((INT32)c << 8) | ((INT32)d << 7) | b)
+
+const INT32 jpeg_aritab[113+1] = {
+/*
+ * Index, Qe_Value, Next_Index_LPS, Next_Index_MPS, Switch_MPS
+ */
+ V( 0, 0x5a1d, 1, 1, 1 ),
+ V( 1, 0x2586, 14, 2, 0 ),
+ V( 2, 0x1114, 16, 3, 0 ),
+ V( 3, 0x080b, 18, 4, 0 ),
+ V( 4, 0x03d8, 20, 5, 0 ),
+ V( 5, 0x01da, 23, 6, 0 ),
+ V( 6, 0x00e5, 25, 7, 0 ),
+ V( 7, 0x006f, 28, 8, 0 ),
+ V( 8, 0x0036, 30, 9, 0 ),
+ V( 9, 0x001a, 33, 10, 0 ),
+ V( 10, 0x000d, 35, 11, 0 ),
+ V( 11, 0x0006, 9, 12, 0 ),
+ V( 12, 0x0003, 10, 13, 0 ),
+ V( 13, 0x0001, 12, 13, 0 ),
+ V( 14, 0x5a7f, 15, 15, 1 ),
+ V( 15, 0x3f25, 36, 16, 0 ),
+ V( 16, 0x2cf2, 38, 17, 0 ),
+ V( 17, 0x207c, 39, 18, 0 ),
+ V( 18, 0x17b9, 40, 19, 0 ),
+ V( 19, 0x1182, 42, 20, 0 ),
+ V( 20, 0x0cef, 43, 21, 0 ),
+ V( 21, 0x09a1, 45, 22, 0 ),
+ V( 22, 0x072f, 46, 23, 0 ),
+ V( 23, 0x055c, 48, 24, 0 ),
+ V( 24, 0x0406, 49, 25, 0 ),
+ V( 25, 0x0303, 51, 26, 0 ),
+ V( 26, 0x0240, 52, 27, 0 ),
+ V( 27, 0x01b1, 54, 28, 0 ),
+ V( 28, 0x0144, 56, 29, 0 ),
+ V( 29, 0x00f5, 57, 30, 0 ),
+ V( 30, 0x00b7, 59, 31, 0 ),
+ V( 31, 0x008a, 60, 32, 0 ),
+ V( 32, 0x0068, 62, 33, 0 ),
+ V( 33, 0x004e, 63, 34, 0 ),
+ V( 34, 0x003b, 32, 35, 0 ),
+ V( 35, 0x002c, 33, 9, 0 ),
+ V( 36, 0x5ae1, 37, 37, 1 ),
+ V( 37, 0x484c, 64, 38, 0 ),
+ V( 38, 0x3a0d, 65, 39, 0 ),
+ V( 39, 0x2ef1, 67, 40, 0 ),
+ V( 40, 0x261f, 68, 41, 0 ),
+ V( 41, 0x1f33, 69, 42, 0 ),
+ V( 42, 0x19a8, 70, 43, 0 ),
+ V( 43, 0x1518, 72, 44, 0 ),
+ V( 44, 0x1177, 73, 45, 0 ),
+ V( 45, 0x0e74, 74, 46, 0 ),
+ V( 46, 0x0bfb, 75, 47, 0 ),
+ V( 47, 0x09f8, 77, 48, 0 ),
+ V( 48, 0x0861, 78, 49, 0 ),
+ V( 49, 0x0706, 79, 50, 0 ),
+ V( 50, 0x05cd, 48, 51, 0 ),
+ V( 51, 0x04de, 50, 52, 0 ),
+ V( 52, 0x040f, 50, 53, 0 ),
+ V( 53, 0x0363, 51, 54, 0 ),
+ V( 54, 0x02d4, 52, 55, 0 ),
+ V( 55, 0x025c, 53, 56, 0 ),
+ V( 56, 0x01f8, 54, 57, 0 ),
+ V( 57, 0x01a4, 55, 58, 0 ),
+ V( 58, 0x0160, 56, 59, 0 ),
+ V( 59, 0x0125, 57, 60, 0 ),
+ V( 60, 0x00f6, 58, 61, 0 ),
+ V( 61, 0x00cb, 59, 62, 0 ),
+ V( 62, 0x00ab, 61, 63, 0 ),
+ V( 63, 0x008f, 61, 32, 0 ),
+ V( 64, 0x5b12, 65, 65, 1 ),
+ V( 65, 0x4d04, 80, 66, 0 ),
+ V( 66, 0x412c, 81, 67, 0 ),
+ V( 67, 0x37d8, 82, 68, 0 ),
+ V( 68, 0x2fe8, 83, 69, 0 ),
+ V( 69, 0x293c, 84, 70, 0 ),
+ V( 70, 0x2379, 86, 71, 0 ),
+ V( 71, 0x1edf, 87, 72, 0 ),
+ V( 72, 0x1aa9, 87, 73, 0 ),
+ V( 73, 0x174e, 72, 74, 0 ),
+ V( 74, 0x1424, 72, 75, 0 ),
+ V( 75, 0x119c, 74, 76, 0 ),
+ V( 76, 0x0f6b, 74, 77, 0 ),
+ V( 77, 0x0d51, 75, 78, 0 ),
+ V( 78, 0x0bb6, 77, 79, 0 ),
+ V( 79, 0x0a40, 77, 48, 0 ),
+ V( 80, 0x5832, 80, 81, 1 ),
+ V( 81, 0x4d1c, 88, 82, 0 ),
+ V( 82, 0x438e, 89, 83, 0 ),
+ V( 83, 0x3bdd, 90, 84, 0 ),
+ V( 84, 0x34ee, 91, 85, 0 ),
+ V( 85, 0x2eae, 92, 86, 0 ),
+ V( 86, 0x299a, 93, 87, 0 ),
+ V( 87, 0x2516, 86, 71, 0 ),
+ V( 88, 0x5570, 88, 89, 1 ),
+ V( 89, 0x4ca9, 95, 90, 0 ),
+ V( 90, 0x44d9, 96, 91, 0 ),
+ V( 91, 0x3e22, 97, 92, 0 ),
+ V( 92, 0x3824, 99, 93, 0 ),
+ V( 93, 0x32b4, 99, 94, 0 ),
+ V( 94, 0x2e17, 93, 86, 0 ),
+ V( 95, 0x56a8, 95, 96, 1 ),
+ V( 96, 0x4f46, 101, 97, 0 ),
+ V( 97, 0x47e5, 102, 98, 0 ),
+ V( 98, 0x41cf, 103, 99, 0 ),
+ V( 99, 0x3c3d, 104, 100, 0 ),
+ V( 100, 0x375e, 99, 93, 0 ),
+ V( 101, 0x5231, 105, 102, 0 ),
+ V( 102, 0x4c0f, 106, 103, 0 ),
+ V( 103, 0x4639, 107, 104, 0 ),
+ V( 104, 0x415e, 103, 99, 0 ),
+ V( 105, 0x5627, 105, 106, 1 ),
+ V( 106, 0x50e7, 108, 107, 0 ),
+ V( 107, 0x4b85, 109, 103, 0 ),
+ V( 108, 0x5597, 110, 109, 0 ),
+ V( 109, 0x504f, 111, 107, 0 ),
+ V( 110, 0x5a10, 110, 111, 1 ),
+ V( 111, 0x5522, 112, 109, 0 ),
+ V( 112, 0x59eb, 112, 111, 1 ),
+/*
+ * This last entry is used for fixed probability estimate of 0.5
+ * as recommended in Section 10.3 Table 5 of ITU-T Rec. T.851.
+ */
+ V( 113, 0x5a1d, 113, 113, 0 )
+};
diff --git a/src/libjpeg-turbo/jcapimin.c b/src/libjpeg-turbo/jcapimin.c
new file mode 100644
index 0000000..20ba9e9
--- /dev/null
+++ b/src/libjpeg-turbo/jcapimin.c
@@ -0,0 +1,292 @@
+/*
+ * jcapimin.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * Modified 2003-2010 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains application interface code for the compression half
+ * of the JPEG library. These are the "minimum" API routines that may be
+ * needed in either the normal full-compression case or the transcoding-only
+ * case.
+ *
+ * Most of the routines intended to be called directly by an application
+ * are in this file or in jcapistd.c. But also see jcparam.c for
+ * parameter-setup helper routines, jcomapi.c for routines shared by
+ * compression and decompression, and jctrans.c for the transcoding case.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Initialization of a JPEG compression object.
+ * The error manager must already be set up (in case memory manager fails).
+ */
+
+GLOBAL(void)
+jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
+{
+ int i;
+
+ /* Guard against version mismatches between library and caller. */
+ cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
+ if (version != JPEG_LIB_VERSION)
+ ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
+ if (structsize != SIZEOF(struct jpeg_compress_struct))
+ ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
+ (int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
+
+ /* For debugging purposes, we zero the whole master structure.
+ * But the application has already set the err pointer, and may have set
+ * client_data, so we have to save and restore those fields.
+ * Note: if application hasn't set client_data, tools like Purify may
+ * complain here.
+ */
+ {
+ struct jpeg_error_mgr * err = cinfo->err;
+ void * client_data = cinfo->client_data; /* ignore Purify complaint here */
+ MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
+ cinfo->err = err;
+ cinfo->client_data = client_data;
+ }
+ cinfo->is_decompressor = FALSE;
+
+ /* Initialize a memory manager instance for this object */
+ jinit_memory_mgr((j_common_ptr) cinfo);
+
+ /* Zero out pointers to permanent structures. */
+ cinfo->progress = NULL;
+ cinfo->dest = NULL;
+
+ cinfo->comp_info = NULL;
+
+ for (i = 0; i < NUM_QUANT_TBLS; i++) {
+ cinfo->quant_tbl_ptrs[i] = NULL;
+#if JPEG_LIB_VERSION >= 70
+ cinfo->q_scale_factor[i] = 100;
+#endif
+ }
+
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ cinfo->dc_huff_tbl_ptrs[i] = NULL;
+ cinfo->ac_huff_tbl_ptrs[i] = NULL;
+ }
+
+#if JPEG_LIB_VERSION >= 80
+ /* Must do it here for emit_dqt in case jpeg_write_tables is used */
+ cinfo->block_size = DCTSIZE;
+ cinfo->natural_order = jpeg_natural_order;
+ cinfo->lim_Se = DCTSIZE2-1;
+#endif
+
+ cinfo->script_space = NULL;
+
+ cinfo->input_gamma = 1.0; /* in case application forgets */
+
+ /* OK, I'm ready */
+ cinfo->global_state = CSTATE_START;
+}
+
+
+/*
+ * Destruction of a JPEG compression object
+ */
+
+GLOBAL(void)
+jpeg_destroy_compress (j_compress_ptr cinfo)
+{
+ jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Abort processing of a JPEG compression operation,
+ * but don't destroy the object itself.
+ */
+
+GLOBAL(void)
+jpeg_abort_compress (j_compress_ptr cinfo)
+{
+ jpeg_abort((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Forcibly suppress or un-suppress all quantization and Huffman tables.
+ * Marks all currently defined tables as already written (if suppress)
+ * or not written (if !suppress). This will control whether they get emitted
+ * by a subsequent jpeg_start_compress call.
+ *
+ * This routine is exported for use by applications that want to produce
+ * abbreviated JPEG datastreams. It logically belongs in jcparam.c, but
+ * since it is called by jpeg_start_compress, we put it here --- otherwise
+ * jcparam.o would be linked whether the application used it or not.
+ */
+
+GLOBAL(void)
+jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
+{
+ int i;
+ JQUANT_TBL * qtbl;
+ JHUFF_TBL * htbl;
+
+ for (i = 0; i < NUM_QUANT_TBLS; i++) {
+ if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL)
+ qtbl->sent_table = suppress;
+ }
+
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL)
+ htbl->sent_table = suppress;
+ if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL)
+ htbl->sent_table = suppress;
+ }
+}
+
+
+/*
+ * Finish JPEG compression.
+ *
+ * If a multipass operating mode was selected, this may do a great deal of
+ * work including most of the actual output.
+ */
+
+GLOBAL(void)
+jpeg_finish_compress (j_compress_ptr cinfo)
+{
+ JDIMENSION iMCU_row;
+
+ if (cinfo->global_state == CSTATE_SCANNING ||
+ cinfo->global_state == CSTATE_RAW_OK) {
+ /* Terminate first pass */
+ if (cinfo->next_scanline < cinfo->image_height)
+ ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
+ (*cinfo->master->finish_pass) (cinfo);
+ } else if (cinfo->global_state != CSTATE_WRCOEFS)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ /* Perform any remaining passes */
+ while (! cinfo->master->is_last_pass) {
+ (*cinfo->master->prepare_for_pass) (cinfo);
+ for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) {
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) iMCU_row;
+ cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+ /* We bypass the main controller and invoke coef controller directly;
+ * all work is being done from the coefficient buffer.
+ */
+ if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL))
+ ERREXIT(cinfo, JERR_CANT_SUSPEND);
+ }
+ (*cinfo->master->finish_pass) (cinfo);
+ }
+ /* Write EOI, do final cleanup */
+ (*cinfo->marker->write_file_trailer) (cinfo);
+ (*cinfo->dest->term_destination) (cinfo);
+ /* We can use jpeg_abort to release memory and reset global_state */
+ jpeg_abort((j_common_ptr) cinfo);
+}
+
+
+/*
+ * Write a special marker.
+ * This is only recommended for writing COM or APPn markers.
+ * Must be called after jpeg_start_compress() and before
+ * first call to jpeg_write_scanlines() or jpeg_write_raw_data().
+ */
+
+GLOBAL(void)
+jpeg_write_marker (j_compress_ptr cinfo, int marker,
+ const JOCTET *dataptr, unsigned int datalen)
+{
+ JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val));
+
+ if (cinfo->next_scanline != 0 ||
+ (cinfo->global_state != CSTATE_SCANNING &&
+ cinfo->global_state != CSTATE_RAW_OK &&
+ cinfo->global_state != CSTATE_WRCOEFS))
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
+ write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */
+ while (datalen--) {
+ (*write_marker_byte) (cinfo, *dataptr);
+ dataptr++;
+ }
+}
+
+/* Same, but piecemeal. */
+
+GLOBAL(void)
+jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
+{
+ if (cinfo->next_scanline != 0 ||
+ (cinfo->global_state != CSTATE_SCANNING &&
+ cinfo->global_state != CSTATE_RAW_OK &&
+ cinfo->global_state != CSTATE_WRCOEFS))
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
+}
+
+GLOBAL(void)
+jpeg_write_m_byte (j_compress_ptr cinfo, int val)
+{
+ (*cinfo->marker->write_marker_byte) (cinfo, val);
+}
+
+
+/*
+ * Alternate compression function: just write an abbreviated table file.
+ * Before calling this, all parameters and a data destination must be set up.
+ *
+ * To produce a pair of files containing abbreviated tables and abbreviated
+ * image data, one would proceed as follows:
+ *
+ * initialize JPEG object
+ * set JPEG parameters
+ * set destination to table file
+ * jpeg_write_tables(cinfo);
+ * set destination to image file
+ * jpeg_start_compress(cinfo, FALSE);
+ * write data...
+ * jpeg_finish_compress(cinfo);
+ *
+ * jpeg_write_tables has the side effect of marking all tables written
+ * (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress
+ * will not re-emit the tables unless it is passed write_all_tables=TRUE.
+ */
+
+GLOBAL(void)
+jpeg_write_tables (j_compress_ptr cinfo)
+{
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ /* (Re)initialize error mgr and destination modules */
+ (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+ (*cinfo->dest->init_destination) (cinfo);
+ /* Initialize the marker writer ... bit of a crock to do it here. */
+ jinit_marker_writer(cinfo);
+ /* Write them tables! */
+ (*cinfo->marker->write_tables_only) (cinfo);
+ /* And clean up. */
+ (*cinfo->dest->term_destination) (cinfo);
+ /*
+ * In library releases up through v6a, we called jpeg_abort() here to free
+ * any working memory allocated by the destination manager and marker
+ * writer. Some applications had a problem with that: they allocated space
+ * of their own from the library memory manager, and didn't want it to go
+ * away during write_tables. So now we do nothing. This will cause a
+ * memory leak if an app calls write_tables repeatedly without doing a full
+ * compression cycle or otherwise resetting the JPEG object. However, that
+ * seems less bad than unexpectedly freeing memory in the normal case.
+ * An app that prefers the old behavior can call jpeg_abort for itself after
+ * each call to jpeg_write_tables().
+ */
+}
diff --git a/src/libjpeg-turbo/jcapistd.c b/src/libjpeg-turbo/jcapistd.c
new file mode 100644
index 0000000..c0320b1
--- /dev/null
+++ b/src/libjpeg-turbo/jcapistd.c
@@ -0,0 +1,161 @@
+/*
+ * jcapistd.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains application interface code for the compression half
+ * of the JPEG library. These are the "standard" API routines that are
+ * used in the normal full-compression case. They are not used by a
+ * transcoding-only application. Note that if an application links in
+ * jpeg_start_compress, it will end up linking in the entire compressor.
+ * We thus must separate this file from jcapimin.c to avoid linking the
+ * whole compression library into a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Compression initialization.
+ * Before calling this, all parameters and a data destination must be set up.
+ *
+ * We require a write_all_tables parameter as a failsafe check when writing
+ * multiple datastreams from the same compression object. Since prior runs
+ * will have left all the tables marked sent_table=TRUE, a subsequent run
+ * would emit an abbreviated stream (no tables) by default. This may be what
+ * is wanted, but for safety's sake it should not be the default behavior:
+ * programmers should have to make a deliberate choice to emit abbreviated
+ * images. Therefore the documentation and examples should encourage people
+ * to pass write_all_tables=TRUE; then it will take active thought to do the
+ * wrong thing.
+ */
+
+GLOBAL(void)
+jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
+{
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ if (write_all_tables)
+ jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
+
+ /* (Re)initialize error mgr and destination modules */
+ (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+ (*cinfo->dest->init_destination) (cinfo);
+ /* Perform master selection of active modules */
+ jinit_compress_master(cinfo);
+ /* Set up for the first pass */
+ (*cinfo->master->prepare_for_pass) (cinfo);
+ /* Ready for application to drive first pass through jpeg_write_scanlines
+ * or jpeg_write_raw_data.
+ */
+ cinfo->next_scanline = 0;
+ cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
+}
+
+
+/*
+ * Write some scanlines of data to the JPEG compressor.
+ *
+ * The return value will be the number of lines actually written.
+ * This should be less than the supplied num_lines only in case that
+ * the data destination module has requested suspension of the compressor,
+ * or if more than image_height scanlines are passed in.
+ *
+ * Note: we warn about excess calls to jpeg_write_scanlines() since
+ * this likely signals an application programmer error. However,
+ * excess scanlines passed in the last valid call are *silently* ignored,
+ * so that the application need not adjust num_lines for end-of-image
+ * when using a multiple-scanline buffer.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
+ JDIMENSION num_lines)
+{
+ JDIMENSION row_ctr, rows_left;
+
+ if (cinfo->global_state != CSTATE_SCANNING)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ if (cinfo->next_scanline >= cinfo->image_height)
+ WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) cinfo->next_scanline;
+ cinfo->progress->pass_limit = (long) cinfo->image_height;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+
+ /* Give master control module another chance if this is first call to
+ * jpeg_write_scanlines. This lets output of the frame/scan headers be
+ * delayed so that application can write COM, etc, markers between
+ * jpeg_start_compress and jpeg_write_scanlines.
+ */
+ if (cinfo->master->call_pass_startup)
+ (*cinfo->master->pass_startup) (cinfo);
+
+ /* Ignore any extra scanlines at bottom of image. */
+ rows_left = cinfo->image_height - cinfo->next_scanline;
+ if (num_lines > rows_left)
+ num_lines = rows_left;
+
+ row_ctr = 0;
+ (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
+ cinfo->next_scanline += row_ctr;
+ return row_ctr;
+}
+
+
+/*
+ * Alternate entry point to write raw data.
+ * Processes exactly one iMCU row per call, unless suspended.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
+ JDIMENSION num_lines)
+{
+ JDIMENSION lines_per_iMCU_row;
+
+ if (cinfo->global_state != CSTATE_RAW_OK)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ if (cinfo->next_scanline >= cinfo->image_height) {
+ WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+ return 0;
+ }
+
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) cinfo->next_scanline;
+ cinfo->progress->pass_limit = (long) cinfo->image_height;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+
+ /* Give master control module another chance if this is first call to
+ * jpeg_write_raw_data. This lets output of the frame/scan headers be
+ * delayed so that application can write COM, etc, markers between
+ * jpeg_start_compress and jpeg_write_raw_data.
+ */
+ if (cinfo->master->call_pass_startup)
+ (*cinfo->master->pass_startup) (cinfo);
+
+ /* Verify that at least one iMCU row has been passed. */
+ lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
+ if (num_lines < lines_per_iMCU_row)
+ ERREXIT(cinfo, JERR_BUFFER_SIZE);
+
+ /* Directly compress the row. */
+ if (! (*cinfo->coef->compress_data) (cinfo, data)) {
+ /* If compressor did not consume the whole row, suspend processing. */
+ return 0;
+ }
+
+ /* OK, we processed one iMCU row. */
+ cinfo->next_scanline += lines_per_iMCU_row;
+ return lines_per_iMCU_row;
+}
diff --git a/src/libjpeg-turbo/jcarith.c b/src/libjpeg-turbo/jcarith.c
new file mode 100644
index 0000000..a9ca1c3
--- /dev/null
+++ b/src/libjpeg-turbo/jcarith.c
@@ -0,0 +1,925 @@
+/*
+ * jcarith.c
+ *
+ * Developed 1997-2009 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains portable arithmetic entropy encoding routines for JPEG
+ * (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
+ *
+ * Both sequential and progressive modes are supported in this single module.
+ *
+ * Suspension is not currently supported in this module.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Expanded entropy encoder object for arithmetic encoding. */
+
+typedef struct {
+ struct jpeg_entropy_encoder pub; /* public fields */
+
+ INT32 c; /* C register, base of coding interval, layout as in sec. D.1.3 */
+ INT32 a; /* A register, normalized size of coding interval */
+ INT32 sc; /* counter for stacked 0xFF values which might overflow */
+ INT32 zc; /* counter for pending 0x00 output values which might *
+ * be discarded at the end ("Pacman" termination) */
+ int ct; /* bit shift counter, determines when next byte will be written */
+ int buffer; /* buffer for most recent output byte != 0xFF */
+
+ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+ int dc_context[MAX_COMPS_IN_SCAN]; /* context index for DC conditioning */
+
+ unsigned int restarts_to_go; /* MCUs left in this restart interval */
+ int next_restart_num; /* next restart number to write (0-7) */
+
+ /* Pointers to statistics areas (these workspaces have image lifespan) */
+ unsigned char * dc_stats[NUM_ARITH_TBLS];
+ unsigned char * ac_stats[NUM_ARITH_TBLS];
+
+ /* Statistics bin for coding with fixed probability 0.5 */
+ unsigned char fixed_bin[4];
+} arith_entropy_encoder;
+
+typedef arith_entropy_encoder * arith_entropy_ptr;
+
+/* The following two definitions specify the allocation chunk size
+ * for the statistics area.
+ * According to sections F.1.4.4.1.3 and F.1.4.4.2, we need at least
+ * 49 statistics bins for DC, and 245 statistics bins for AC coding.
+ *
+ * We use a compact representation with 1 byte per statistics bin,
+ * thus the numbers directly represent byte sizes.
+ * This 1 byte per statistics bin contains the meaning of the MPS
+ * (more probable symbol) in the highest bit (mask 0x80), and the
+ * index into the probability estimation state machine table
+ * in the lower bits (mask 0x7F).
+ */
+
+#define DC_STAT_BINS 64
+#define AC_STAT_BINS 256
+
+/* NOTE: Uncomment the following #define if you want to use the
+ * given formula for calculating the AC conditioning parameter Kx
+ * for spectral selection progressive coding in section G.1.3.2
+ * of the spec (Kx = Kmin + SRL (8 + Se - Kmin) 4).
+ * Although the spec and P&M authors claim that this "has proven
+ * to give good results for 8 bit precision samples", I'm not
+ * convinced yet that this is really beneficial.
+ * Early tests gave only very marginal compression enhancements
+ * (a few - around 5 or so - bytes even for very large files),
+ * which would turn out rather negative if we'd suppress the
+ * DAC (Define Arithmetic Conditioning) marker segments for
+ * the default parameters in the future.
+ * Note that currently the marker writing module emits 12-byte
+ * DAC segments for a full-component scan in a color image.
+ * This is not worth worrying about IMHO. However, since the
+ * spec defines the default values to be used if the tables
+ * are omitted (unlike Huffman tables, which are required
+ * anyway), one might optimize this behaviour in the future,
+ * and then it would be disadvantageous to use custom tables if
+ * they don't provide sufficient gain to exceed the DAC size.
+ *
+ * On the other hand, I'd consider it as a reasonable result
+ * that the conditioning has no significant influence on the
+ * compression performance. This means that the basic
+ * statistical model is already rather stable.
+ *
+ * Thus, at the moment, we use the default conditioning values
+ * anyway, and do not use the custom formula.
+ *
+#define CALCULATE_SPECTRAL_CONDITIONING
+ */
+
+/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
+ * We assume that int right shift is unsigned if INT32 right shift is,
+ * which should be safe.
+ */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define ISHIFT_TEMPS int ishift_temp;
+#define IRIGHT_SHIFT(x,shft) \
+ ((ishift_temp = (x)) < 0 ? \
+ (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
+ (ishift_temp >> (shft)))
+#else
+#define ISHIFT_TEMPS
+#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
+#endif
+
+
+LOCAL(void)
+emit_byte (int val, j_compress_ptr cinfo)
+/* Write next output byte; we do not support suspension in this module. */
+{
+ struct jpeg_destination_mgr * dest = cinfo->dest;
+
+ *dest->next_output_byte++ = (JOCTET) val;
+ if (--dest->free_in_buffer == 0)
+ if (! (*dest->empty_output_buffer) (cinfo))
+ ERREXIT(cinfo, JERR_CANT_SUSPEND);
+}
+
+
+/*
+ * Finish up at the end of an arithmetic-compressed scan.
+ */
+
+METHODDEF(void)
+finish_pass (j_compress_ptr cinfo)
+{
+ arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
+ INT32 temp;
+
+ /* Section D.1.8: Termination of encoding */
+
+ /* Find the e->c in the coding interval with the largest
+ * number of trailing zero bits */
+ if ((temp = (e->a - 1 + e->c) & 0xFFFF0000L) < e->c)
+ e->c = temp + 0x8000L;
+ else
+ e->c = temp;
+ /* Send remaining bytes to output */
+ e->c <<= e->ct;
+ if (e->c & 0xF8000000L) {
+ /* One final overflow has to be handled */
+ if (e->buffer >= 0) {
+ if (e->zc)
+ do emit_byte(0x00, cinfo);
+ while (--e->zc);
+ emit_byte(e->buffer + 1, cinfo);
+ if (e->buffer + 1 == 0xFF)
+ emit_byte(0x00, cinfo);
+ }
+ e->zc += e->sc; /* carry-over converts stacked 0xFF bytes to 0x00 */
+ e->sc = 0;
+ } else {
+ if (e->buffer == 0)
+ ++e->zc;
+ else if (e->buffer >= 0) {
+ if (e->zc)
+ do emit_byte(0x00, cinfo);
+ while (--e->zc);
+ emit_byte(e->buffer, cinfo);
+ }
+ if (e->sc) {
+ if (e->zc)
+ do emit_byte(0x00, cinfo);
+ while (--e->zc);
+ do {
+ emit_byte(0xFF, cinfo);
+ emit_byte(0x00, cinfo);
+ } while (--e->sc);
+ }
+ }
+ /* Output final bytes only if they are not 0x00 */
+ if (e->c & 0x7FFF800L) {
+ if (e->zc) /* output final pending zero bytes */
+ do emit_byte(0x00, cinfo);
+ while (--e->zc);
+ emit_byte((e->c >> 19) & 0xFF, cinfo);
+ if (((e->c >> 19) & 0xFF) == 0xFF)
+ emit_byte(0x00, cinfo);
+ if (e->c & 0x7F800L) {
+ emit_byte((e->c >> 11) & 0xFF, cinfo);
+ if (((e->c >> 11) & 0xFF) == 0xFF)
+ emit_byte(0x00, cinfo);
+ }
+ }
+}
+
+
+/*
+ * The core arithmetic encoding routine (common in JPEG and JBIG).
+ * This needs to go as fast as possible.
+ * Machine-dependent optimization facilities
+ * are not utilized in this portable implementation.
+ * However, this code should be fairly efficient and
+ * may be a good base for further optimizations anyway.
+ *
+ * Parameter 'val' to be encoded may be 0 or 1 (binary decision).
+ *
+ * Note: I've added full "Pacman" termination support to the
+ * byte output routines, which is equivalent to the optional
+ * Discard_final_zeros procedure (Figure D.15) in the spec.
+ * Thus, we always produce the shortest possible output
+ * stream compliant to the spec (no trailing zero bytes,
+ * except for FF stuffing).
+ *
+ * I've also introduced a new scheme for accessing
+ * the probability estimation state machine table,
+ * derived from Markus Kuhn's JBIG implementation.
+ */
+
+LOCAL(void)
+arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
+{
+ register arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
+ register unsigned char nl, nm;
+ register INT32 qe, temp;
+ register int sv;
+
+ /* Fetch values from our compact representation of Table D.2:
+ * Qe values and probability estimation state machine
+ */
+ sv = *st;
+ qe = jpeg_aritab[sv & 0x7F]; /* => Qe_Value */
+ nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */
+ nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */
+
+ /* Encode & estimation procedures per sections D.1.4 & D.1.5 */
+ e->a -= qe;
+ if (val != (sv >> 7)) {
+ /* Encode the less probable symbol */
+ if (e->a >= qe) {
+ /* If the interval size (qe) for the less probable symbol (LPS)
+ * is larger than the interval size for the MPS, then exchange
+ * the two symbols for coding efficiency, otherwise code the LPS
+ * as usual: */
+ e->c += e->a;
+ e->a = qe;
+ }
+ *st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
+ } else {
+ /* Encode the more probable symbol */
+ if (e->a >= 0x8000L)
+ return; /* A >= 0x8000 -> ready, no renormalization required */
+ if (e->a < qe) {
+ /* If the interval size (qe) for the less probable symbol (LPS)
+ * is larger than the interval size for the MPS, then exchange
+ * the two symbols for coding efficiency: */
+ e->c += e->a;
+ e->a = qe;
+ }
+ *st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
+ }
+
+ /* Renormalization & data output per section D.1.6 */
+ do {
+ e->a <<= 1;
+ e->c <<= 1;
+ if (--e->ct == 0) {
+ /* Another byte is ready for output */
+ temp = e->c >> 19;
+ if (temp > 0xFF) {
+ /* Handle overflow over all stacked 0xFF bytes */
+ if (e->buffer >= 0) {
+ if (e->zc)
+ do emit_byte(0x00, cinfo);
+ while (--e->zc);
+ emit_byte(e->buffer + 1, cinfo);
+ if (e->buffer + 1 == 0xFF)
+ emit_byte(0x00, cinfo);
+ }
+ e->zc += e->sc; /* carry-over converts stacked 0xFF bytes to 0x00 */
+ e->sc = 0;
+ /* Note: The 3 spacer bits in the C register guarantee
+ * that the new buffer byte can't be 0xFF here
+ * (see page 160 in the P&M JPEG book). */
+ e->buffer = temp & 0xFF; /* new output byte, might overflow later */
+ } else if (temp == 0xFF) {
+ ++e->sc; /* stack 0xFF byte (which might overflow later) */
+ } else {
+ /* Output all stacked 0xFF bytes, they will not overflow any more */
+ if (e->buffer == 0)
+ ++e->zc;
+ else if (e->buffer >= 0) {
+ if (e->zc)
+ do emit_byte(0x00, cinfo);
+ while (--e->zc);
+ emit_byte(e->buffer, cinfo);
+ }
+ if (e->sc) {
+ if (e->zc)
+ do emit_byte(0x00, cinfo);
+ while (--e->zc);
+ do {
+ emit_byte(0xFF, cinfo);
+ emit_byte(0x00, cinfo);
+ } while (--e->sc);
+ }
+ e->buffer = temp & 0xFF; /* new output byte (can still overflow) */
+ }
+ e->c &= 0x7FFFFL;
+ e->ct += 8;
+ }
+ } while (e->a < 0x8000L);
+}
+
+
+/*
+ * Emit a restart marker & resynchronize predictions.
+ */
+
+LOCAL(void)
+emit_restart (j_compress_ptr cinfo, int restart_num)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ int ci;
+ jpeg_component_info * compptr;
+
+ finish_pass(cinfo);
+
+ emit_byte(0xFF, cinfo);
+ emit_byte(JPEG_RST0 + restart_num, cinfo);
+
+ /* Re-initialize statistics areas */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* DC needs no table for refinement scan */
+ if (cinfo->progressive_mode == 0 || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
+ MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
+ /* Reset DC predictions to 0 */
+ entropy->last_dc_val[ci] = 0;
+ entropy->dc_context[ci] = 0;
+ }
+ /* AC needs no table when not present */
+ if (cinfo->progressive_mode == 0 || cinfo->Se) {
+ MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
+ }
+ }
+
+ /* Reset arithmetic encoding variables */
+ entropy->c = 0;
+ entropy->a = 0x10000L;
+ entropy->sc = 0;
+ entropy->zc = 0;
+ entropy->ct = 11;
+ entropy->buffer = -1; /* empty */
+}
+
+
+/*
+ * MCU encoding for DC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ JBLOCKROW block;
+ unsigned char *st;
+ int blkn, ci, tbl;
+ int v, v2, m;
+ ISHIFT_TEMPS
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ emit_restart(cinfo, entropy->next_restart_num);
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ /* Encode the MCU data blocks */
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+ ci = cinfo->MCU_membership[blkn];
+ tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
+
+ /* Compute the DC value after the required point transform by Al.
+ * This is simply an arithmetic right shift.
+ */
+ m = IRIGHT_SHIFT((int) ((*block)[0]), cinfo->Al);
+
+ /* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
+
+ /* Table F.4: Point to statistics bin S0 for DC coefficient coding */
+ st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
+
+ /* Figure F.4: Encode_DC_DIFF */
+ if ((v = m - entropy->last_dc_val[ci]) == 0) {
+ arith_encode(cinfo, st, 0);
+ entropy->dc_context[ci] = 0; /* zero diff category */
+ } else {
+ entropy->last_dc_val[ci] = m;
+ arith_encode(cinfo, st, 1);
+ /* Figure F.6: Encoding nonzero value v */
+ /* Figure F.7: Encoding the sign of v */
+ if (v > 0) {
+ arith_encode(cinfo, st + 1, 0); /* Table F.4: SS = S0 + 1 */
+ st += 2; /* Table F.4: SP = S0 + 2 */
+ entropy->dc_context[ci] = 4; /* small positive diff category */
+ } else {
+ v = -v;
+ arith_encode(cinfo, st + 1, 1); /* Table F.4: SS = S0 + 1 */
+ st += 3; /* Table F.4: SN = S0 + 3 */
+ entropy->dc_context[ci] = 8; /* small negative diff category */
+ }
+ /* Figure F.8: Encoding the magnitude category of v */
+ m = 0;
+ if (v -= 1) {
+ arith_encode(cinfo, st, 1);
+ m = 1;
+ v2 = v;
+ st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
+ while (v2 >>= 1) {
+ arith_encode(cinfo, st, 1);
+ m <<= 1;
+ st += 1;
+ }
+ }
+ arith_encode(cinfo, st, 0);
+ /* Section F.1.4.4.1.2: Establish dc_context conditioning category */
+ if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
+ entropy->dc_context[ci] = 0; /* zero diff category */
+ else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
+ entropy->dc_context[ci] += 8; /* large diff category */
+ /* Figure F.9: Encoding the magnitude bit pattern of v */
+ st += 14;
+ while (m >>= 1)
+ arith_encode(cinfo, st, (m & v) ? 1 : 0);
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU encoding for AC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ JBLOCKROW block;
+ unsigned char *st;
+ int tbl, k, ke;
+ int v, v2, m;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ emit_restart(cinfo, entropy->next_restart_num);
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ /* Encode the MCU data block */
+ block = MCU_data[0];
+ tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
+
+ /* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
+
+ /* Establish EOB (end-of-block) index */
+ for (ke = cinfo->Se; ke > 0; ke--)
+ /* We must apply the point transform by Al. For AC coefficients this
+ * is an integer division with rounding towards 0. To do this portably
+ * in C, we shift after obtaining the absolute value.
+ */
+ if ((v = (*block)[jpeg_natural_order[ke]]) >= 0) {
+ if (v >>= cinfo->Al) break;
+ } else {
+ v = -v;
+ if (v >>= cinfo->Al) break;
+ }
+
+ /* Figure F.5: Encode_AC_Coefficients */
+ for (k = cinfo->Ss; k <= ke; k++) {
+ st = entropy->ac_stats[tbl] + 3 * (k - 1);
+ arith_encode(cinfo, st, 0); /* EOB decision */
+ for (;;) {
+ if ((v = (*block)[jpeg_natural_order[k]]) >= 0) {
+ if (v >>= cinfo->Al) {
+ arith_encode(cinfo, st + 1, 1);
+ arith_encode(cinfo, entropy->fixed_bin, 0);
+ break;
+ }
+ } else {
+ v = -v;
+ if (v >>= cinfo->Al) {
+ arith_encode(cinfo, st + 1, 1);
+ arith_encode(cinfo, entropy->fixed_bin, 1);
+ break;
+ }
+ }
+ arith_encode(cinfo, st + 1, 0); st += 3; k++;
+ }
+ st += 2;
+ /* Figure F.8: Encoding the magnitude category of v */
+ m = 0;
+ if (v -= 1) {
+ arith_encode(cinfo, st, 1);
+ m = 1;
+ v2 = v;
+ if (v2 >>= 1) {
+ arith_encode(cinfo, st, 1);
+ m <<= 1;
+ st = entropy->ac_stats[tbl] +
+ (k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
+ while (v2 >>= 1) {
+ arith_encode(cinfo, st, 1);
+ m <<= 1;
+ st += 1;
+ }
+ }
+ }
+ arith_encode(cinfo, st, 0);
+ /* Figure F.9: Encoding the magnitude bit pattern of v */
+ st += 14;
+ while (m >>= 1)
+ arith_encode(cinfo, st, (m & v) ? 1 : 0);
+ }
+ /* Encode EOB decision only if k <= cinfo->Se */
+ if (k <= cinfo->Se) {
+ st = entropy->ac_stats[tbl] + 3 * (k - 1);
+ arith_encode(cinfo, st, 1);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU encoding for DC successive approximation refinement scan.
+ */
+
+METHODDEF(boolean)
+encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ unsigned char *st;
+ int Al, blkn;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ emit_restart(cinfo, entropy->next_restart_num);
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ st = entropy->fixed_bin; /* use fixed probability estimation */
+ Al = cinfo->Al;
+
+ /* Encode the MCU data blocks */
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ /* We simply emit the Al'th bit of the DC coefficient value. */
+ arith_encode(cinfo, st, (MCU_data[blkn][0][0] >> Al) & 1);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU encoding for AC successive approximation refinement scan.
+ */
+
+METHODDEF(boolean)
+encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ JBLOCKROW block;
+ unsigned char *st;
+ int tbl, k, ke, kex;
+ int v;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ emit_restart(cinfo, entropy->next_restart_num);
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ /* Encode the MCU data block */
+ block = MCU_data[0];
+ tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
+
+ /* Section G.1.3.3: Encoding of AC coefficients */
+
+ /* Establish EOB (end-of-block) index */
+ for (ke = cinfo->Se; ke > 0; ke--)
+ /* We must apply the point transform by Al. For AC coefficients this
+ * is an integer division with rounding towards 0. To do this portably
+ * in C, we shift after obtaining the absolute value.
+ */
+ if ((v = (*block)[jpeg_natural_order[ke]]) >= 0) {
+ if (v >>= cinfo->Al) break;
+ } else {
+ v = -v;
+ if (v >>= cinfo->Al) break;
+ }
+
+ /* Establish EOBx (previous stage end-of-block) index */
+ for (kex = ke; kex > 0; kex--)
+ if ((v = (*block)[jpeg_natural_order[kex]]) >= 0) {
+ if (v >>= cinfo->Ah) break;
+ } else {
+ v = -v;
+ if (v >>= cinfo->Ah) break;
+ }
+
+ /* Figure G.10: Encode_AC_Coefficients_SA */
+ for (k = cinfo->Ss; k <= ke; k++) {
+ st = entropy->ac_stats[tbl] + 3 * (k - 1);
+ if (k > kex)
+ arith_encode(cinfo, st, 0); /* EOB decision */
+ for (;;) {
+ if ((v = (*block)[jpeg_natural_order[k]]) >= 0) {
+ if (v >>= cinfo->Al) {
+ if (v >> 1) /* previously nonzero coef */
+ arith_encode(cinfo, st + 2, (v & 1));
+ else { /* newly nonzero coef */
+ arith_encode(cinfo, st + 1, 1);
+ arith_encode(cinfo, entropy->fixed_bin, 0);
+ }
+ break;
+ }
+ } else {
+ v = -v;
+ if (v >>= cinfo->Al) {
+ if (v >> 1) /* previously nonzero coef */
+ arith_encode(cinfo, st + 2, (v & 1));
+ else { /* newly nonzero coef */
+ arith_encode(cinfo, st + 1, 1);
+ arith_encode(cinfo, entropy->fixed_bin, 1);
+ }
+ break;
+ }
+ }
+ arith_encode(cinfo, st + 1, 0); st += 3; k++;
+ }
+ }
+ /* Encode EOB decision only if k <= cinfo->Se */
+ if (k <= cinfo->Se) {
+ st = entropy->ac_stats[tbl] + 3 * (k - 1);
+ arith_encode(cinfo, st, 1);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Encode and output one MCU's worth of arithmetic-compressed coefficients.
+ */
+
+METHODDEF(boolean)
+encode_mcu (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ jpeg_component_info * compptr;
+ JBLOCKROW block;
+ unsigned char *st;
+ int blkn, ci, tbl, k, ke;
+ int v, v2, m;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ emit_restart(cinfo, entropy->next_restart_num);
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ /* Encode the MCU data blocks */
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+
+ /* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
+
+ tbl = compptr->dc_tbl_no;
+
+ /* Table F.4: Point to statistics bin S0 for DC coefficient coding */
+ st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
+
+ /* Figure F.4: Encode_DC_DIFF */
+ if ((v = (*block)[0] - entropy->last_dc_val[ci]) == 0) {
+ arith_encode(cinfo, st, 0);
+ entropy->dc_context[ci] = 0; /* zero diff category */
+ } else {
+ entropy->last_dc_val[ci] = (*block)[0];
+ arith_encode(cinfo, st, 1);
+ /* Figure F.6: Encoding nonzero value v */
+ /* Figure F.7: Encoding the sign of v */
+ if (v > 0) {
+ arith_encode(cinfo, st + 1, 0); /* Table F.4: SS = S0 + 1 */
+ st += 2; /* Table F.4: SP = S0 + 2 */
+ entropy->dc_context[ci] = 4; /* small positive diff category */
+ } else {
+ v = -v;
+ arith_encode(cinfo, st + 1, 1); /* Table F.4: SS = S0 + 1 */
+ st += 3; /* Table F.4: SN = S0 + 3 */
+ entropy->dc_context[ci] = 8; /* small negative diff category */
+ }
+ /* Figure F.8: Encoding the magnitude category of v */
+ m = 0;
+ if (v -= 1) {
+ arith_encode(cinfo, st, 1);
+ m = 1;
+ v2 = v;
+ st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
+ while (v2 >>= 1) {
+ arith_encode(cinfo, st, 1);
+ m <<= 1;
+ st += 1;
+ }
+ }
+ arith_encode(cinfo, st, 0);
+ /* Section F.1.4.4.1.2: Establish dc_context conditioning category */
+ if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
+ entropy->dc_context[ci] = 0; /* zero diff category */
+ else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
+ entropy->dc_context[ci] += 8; /* large diff category */
+ /* Figure F.9: Encoding the magnitude bit pattern of v */
+ st += 14;
+ while (m >>= 1)
+ arith_encode(cinfo, st, (m & v) ? 1 : 0);
+ }
+
+ /* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
+
+ tbl = compptr->ac_tbl_no;
+
+ /* Establish EOB (end-of-block) index */
+ for (ke = DCTSIZE2 - 1; ke > 0; ke--)
+ if ((*block)[jpeg_natural_order[ke]]) break;
+
+ /* Figure F.5: Encode_AC_Coefficients */
+ for (k = 1; k <= ke; k++) {
+ st = entropy->ac_stats[tbl] + 3 * (k - 1);
+ arith_encode(cinfo, st, 0); /* EOB decision */
+ while ((v = (*block)[jpeg_natural_order[k]]) == 0) {
+ arith_encode(cinfo, st + 1, 0); st += 3; k++;
+ }
+ arith_encode(cinfo, st + 1, 1);
+ /* Figure F.6: Encoding nonzero value v */
+ /* Figure F.7: Encoding the sign of v */
+ if (v > 0) {
+ arith_encode(cinfo, entropy->fixed_bin, 0);
+ } else {
+ v = -v;
+ arith_encode(cinfo, entropy->fixed_bin, 1);
+ }
+ st += 2;
+ /* Figure F.8: Encoding the magnitude category of v */
+ m = 0;
+ if (v -= 1) {
+ arith_encode(cinfo, st, 1);
+ m = 1;
+ v2 = v;
+ if (v2 >>= 1) {
+ arith_encode(cinfo, st, 1);
+ m <<= 1;
+ st = entropy->ac_stats[tbl] +
+ (k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
+ while (v2 >>= 1) {
+ arith_encode(cinfo, st, 1);
+ m <<= 1;
+ st += 1;
+ }
+ }
+ }
+ arith_encode(cinfo, st, 0);
+ /* Figure F.9: Encoding the magnitude bit pattern of v */
+ st += 14;
+ while (m >>= 1)
+ arith_encode(cinfo, st, (m & v) ? 1 : 0);
+ }
+ /* Encode EOB decision only if k <= DCTSIZE2 - 1 */
+ if (k <= DCTSIZE2 - 1) {
+ st = entropy->ac_stats[tbl] + 3 * (k - 1);
+ arith_encode(cinfo, st, 1);
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Initialize for an arithmetic-compressed scan.
+ */
+
+METHODDEF(void)
+start_pass (j_compress_ptr cinfo, boolean gather_statistics)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ int ci, tbl;
+ jpeg_component_info * compptr;
+
+ if (gather_statistics)
+ /* Make sure to avoid that in the master control logic!
+ * We are fully adaptive here and need no extra
+ * statistics gathering pass!
+ */
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+
+ /* We assume jcmaster.c already validated the progressive scan parameters. */
+
+ /* Select execution routines */
+ if (cinfo->progressive_mode) {
+ if (cinfo->Ah == 0) {
+ if (cinfo->Ss == 0)
+ entropy->pub.encode_mcu = encode_mcu_DC_first;
+ else
+ entropy->pub.encode_mcu = encode_mcu_AC_first;
+ } else {
+ if (cinfo->Ss == 0)
+ entropy->pub.encode_mcu = encode_mcu_DC_refine;
+ else
+ entropy->pub.encode_mcu = encode_mcu_AC_refine;
+ }
+ } else
+ entropy->pub.encode_mcu = encode_mcu;
+
+ /* Allocate & initialize requested statistics areas */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* DC needs no table for refinement scan */
+ if (cinfo->progressive_mode == 0 || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
+ tbl = compptr->dc_tbl_no;
+ if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
+ ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
+ if (entropy->dc_stats[tbl] == NULL)
+ entropy->dc_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, DC_STAT_BINS);
+ MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
+ /* Initialize DC predictions to 0 */
+ entropy->last_dc_val[ci] = 0;
+ entropy->dc_context[ci] = 0;
+ }
+ /* AC needs no table when not present */
+ if (cinfo->progressive_mode == 0 || cinfo->Se) {
+ tbl = compptr->ac_tbl_no;
+ if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
+ ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
+ if (entropy->ac_stats[tbl] == NULL)
+ entropy->ac_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS);
+ MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
+#ifdef CALCULATE_SPECTRAL_CONDITIONING
+ if (cinfo->progressive_mode)
+ /* Section G.1.3.2: Set appropriate arithmetic conditioning value Kx */
+ cinfo->arith_ac_K[tbl] = cinfo->Ss + ((8 + cinfo->Se - cinfo->Ss) >> 4);
+#endif
+ }
+ }
+
+ /* Initialize arithmetic encoding variables */
+ entropy->c = 0;
+ entropy->a = 0x10000L;
+ entropy->sc = 0;
+ entropy->zc = 0;
+ entropy->ct = 11;
+ entropy->buffer = -1; /* empty */
+
+ /* Initialize restart stuff */
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num = 0;
+}
+
+
+/*
+ * Module initialization routine for arithmetic entropy encoding.
+ */
+
+GLOBAL(void)
+jinit_arith_encoder (j_compress_ptr cinfo)
+{
+ arith_entropy_ptr entropy;
+ int i;
+
+ entropy = (arith_entropy_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(arith_entropy_encoder));
+ cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
+ entropy->pub.start_pass = start_pass;
+ entropy->pub.finish_pass = finish_pass;
+
+ /* Mark tables unallocated */
+ for (i = 0; i < NUM_ARITH_TBLS; i++) {
+ entropy->dc_stats[i] = NULL;
+ entropy->ac_stats[i] = NULL;
+ }
+
+ /* Initialize index for fixed probability estimation */
+ entropy->fixed_bin[0] = 113;
+}
diff --git a/src/libjpeg-turbo/jccoefct.c b/src/libjpeg-turbo/jccoefct.c
new file mode 100644
index 0000000..1963ddb
--- /dev/null
+++ b/src/libjpeg-turbo/jccoefct.c
@@ -0,0 +1,449 @@
+/*
+ * jccoefct.c
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the coefficient buffer controller for compression.
+ * This controller is the top level of the JPEG compressor proper.
+ * The coefficient buffer lies between forward-DCT and entropy encoding steps.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* We use a full-image coefficient buffer when doing Huffman optimization,
+ * and also for writing multiple-scan JPEG files. In all cases, the DCT
+ * step is run during the first pass, and subsequent passes need only read
+ * the buffered coefficients.
+ */
+#ifdef ENTROPY_OPT_SUPPORTED
+#define FULL_COEF_BUFFER_SUPPORTED
+#else
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+#define FULL_COEF_BUFFER_SUPPORTED
+#endif
+#endif
+
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_c_coef_controller pub; /* public fields */
+
+ JDIMENSION iMCU_row_num; /* iMCU row # within image */
+ JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
+ int MCU_vert_offset; /* counts MCU rows within iMCU row */
+ int MCU_rows_per_iMCU_row; /* number of such rows needed */
+
+ /* For single-pass compression, it's sufficient to buffer just one MCU
+ * (although this may prove a bit slow in practice). We allocate a
+ * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each
+ * MCU constructed and sent. (On 80x86, the workspace is FAR even though
+ * it's not really very big; this is to keep the module interfaces unchanged
+ * when a large coefficient buffer is necessary.)
+ * In multi-pass modes, this array points to the current MCU's blocks
+ * within the virtual arrays.
+ */
+ JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
+
+ /* In multi-pass modes, we need a virtual block array for each component. */
+ jvirt_barray_ptr whole_image[MAX_COMPONENTS];
+} my_coef_controller;
+
+typedef my_coef_controller * my_coef_ptr;
+
+
+/* Forward declarations */
+METHODDEF(boolean) compress_data
+ JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+METHODDEF(boolean) compress_first_pass
+ JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
+METHODDEF(boolean) compress_output
+ JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
+#endif
+
+
+LOCAL(void)
+start_iMCU_row (j_compress_ptr cinfo)
+/* Reset within-iMCU-row counters for a new row */
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ /* In an interleaved scan, an MCU row is the same as an iMCU row.
+ * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
+ * But at the bottom of the image, process only what's left.
+ */
+ if (cinfo->comps_in_scan > 1) {
+ coef->MCU_rows_per_iMCU_row = 1;
+ } else {
+ if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
+ else
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
+ }
+
+ coef->mcu_ctr = 0;
+ coef->MCU_vert_offset = 0;
+}
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ coef->iMCU_row_num = 0;
+ start_iMCU_row(cinfo);
+
+ switch (pass_mode) {
+ case JBUF_PASS_THRU:
+ if (coef->whole_image[0] != NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ coef->pub.compress_data = compress_data;
+ break;
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+ case JBUF_SAVE_AND_PASS:
+ if (coef->whole_image[0] == NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ coef->pub.compress_data = compress_first_pass;
+ break;
+ case JBUF_CRANK_DEST:
+ if (coef->whole_image[0] == NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ coef->pub.compress_data = compress_output;
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ break;
+ }
+}
+
+
+/*
+ * Process some data in the single-pass case.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the image.
+ * Returns TRUE if the iMCU row is completed, FALSE if suspended.
+ *
+ * NB: input_buf contains a plane for each component in image,
+ * which we index according to the component's SOF position.
+ */
+
+METHODDEF(boolean)
+compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION MCU_col_num; /* index of current MCU within row */
+ JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ int blkn, bi, ci, yindex, yoffset, blockcnt;
+ JDIMENSION ypos, xpos;
+ jpeg_component_info *compptr;
+
+ /* Loop to write as much as one whole iMCU row */
+ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+ yoffset++) {
+ for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
+ MCU_col_num++) {
+ /* Determine where data comes from in input_buf and do the DCT thing.
+ * Each call on forward_DCT processes a horizontal row of DCT blocks
+ * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
+ * sequentially. Dummy blocks at the right or bottom edge are filled in
+ * specially. The data in them does not matter for image reconstruction,
+ * so we fill them with values that will encode to the smallest amount of
+ * data, viz: all zeroes in the AC entries, DC entries equal to previous
+ * block's DC value. (Thanks to Thomas Kinsman for this idea.)
+ */
+ blkn = 0;
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
+ : compptr->last_col_width;
+ xpos = MCU_col_num * compptr->MCU_sample_width;
+ ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
+ for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+ if (coef->iMCU_row_num < last_iMCU_row ||
+ yoffset+yindex < compptr->last_row_height) {
+ (*cinfo->fdct->forward_DCT) (cinfo, compptr,
+ input_buf[compptr->component_index],
+ coef->MCU_buffer[blkn],
+ ypos, xpos, (JDIMENSION) blockcnt);
+ if (blockcnt < compptr->MCU_width) {
+ /* Create some dummy blocks at the right edge of the image. */
+ jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
+ (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
+ for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
+ coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
+ }
+ }
+ } else {
+ /* Create a row of dummy blocks at the bottom of the image. */
+ jzero_far((void FAR *) coef->MCU_buffer[blkn],
+ compptr->MCU_width * SIZEOF(JBLOCK));
+ for (bi = 0; bi < compptr->MCU_width; bi++) {
+ coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
+ }
+ }
+ blkn += compptr->MCU_width;
+ ypos += DCTSIZE;
+ }
+ }
+ /* Try to write the MCU. In event of a suspension failure, we will
+ * re-DCT the MCU on restart (a bit inefficient, could be fixed...)
+ */
+ if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
+ /* Suspension forced; update state counters and exit */
+ coef->MCU_vert_offset = yoffset;
+ coef->mcu_ctr = MCU_col_num;
+ return FALSE;
+ }
+ }
+ /* Completed an MCU row, but perhaps not an iMCU row */
+ coef->mcu_ctr = 0;
+ }
+ /* Completed the iMCU row, advance counters for next one */
+ coef->iMCU_row_num++;
+ start_iMCU_row(cinfo);
+ return TRUE;
+}
+
+
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+
+/*
+ * Process some data in the first pass of a multi-pass case.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the image.
+ * This amount of data is read from the source buffer, DCT'd and quantized,
+ * and saved into the virtual arrays. We also generate suitable dummy blocks
+ * as needed at the right and lower edges. (The dummy blocks are constructed
+ * in the virtual arrays, which have been padded appropriately.) This makes
+ * it possible for subsequent passes not to worry about real vs. dummy blocks.
+ *
+ * We must also emit the data to the entropy encoder. This is conveniently
+ * done by calling compress_output() after we've loaded the current strip
+ * of the virtual arrays.
+ *
+ * NB: input_buf contains a plane for each component in image. All
+ * components are DCT'd and loaded into the virtual arrays in this pass.
+ * However, it may be that only a subset of the components are emitted to
+ * the entropy encoder during this first pass; be careful about looking
+ * at the scan-dependent variables (MCU dimensions, etc).
+ */
+
+METHODDEF(boolean)
+compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ JDIMENSION blocks_across, MCUs_across, MCUindex;
+ int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
+ JCOEF lastDC;
+ jpeg_component_info *compptr;
+ JBLOCKARRAY buffer;
+ JBLOCKROW thisblockrow, lastblockrow;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Align the virtual buffer for this component. */
+ buffer = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[ci],
+ coef->iMCU_row_num * compptr->v_samp_factor,
+ (JDIMENSION) compptr->v_samp_factor, TRUE);
+ /* Count non-dummy DCT block rows in this iMCU row. */
+ if (coef->iMCU_row_num < last_iMCU_row)
+ block_rows = compptr->v_samp_factor;
+ else {
+ /* NB: can't use last_row_height here, since may not be set! */
+ block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+ if (block_rows == 0) block_rows = compptr->v_samp_factor;
+ }
+ blocks_across = compptr->width_in_blocks;
+ h_samp_factor = compptr->h_samp_factor;
+ /* Count number of dummy blocks to be added at the right margin. */
+ ndummy = (int) (blocks_across % h_samp_factor);
+ if (ndummy > 0)
+ ndummy = h_samp_factor - ndummy;
+ /* Perform DCT for all non-dummy blocks in this iMCU row. Each call
+ * on forward_DCT processes a complete horizontal row of DCT blocks.
+ */
+ for (block_row = 0; block_row < block_rows; block_row++) {
+ thisblockrow = buffer[block_row];
+ (*cinfo->fdct->forward_DCT) (cinfo, compptr,
+ input_buf[ci], thisblockrow,
+ (JDIMENSION) (block_row * DCTSIZE),
+ (JDIMENSION) 0, blocks_across);
+ if (ndummy > 0) {
+ /* Create dummy blocks at the right edge of the image. */
+ thisblockrow += blocks_across; /* => first dummy block */
+ jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
+ lastDC = thisblockrow[-1][0];
+ for (bi = 0; bi < ndummy; bi++) {
+ thisblockrow[bi][0] = lastDC;
+ }
+ }
+ }
+ /* If at end of image, create dummy block rows as needed.
+ * The tricky part here is that within each MCU, we want the DC values
+ * of the dummy blocks to match the last real block's DC value.
+ * This squeezes a few more bytes out of the resulting file...
+ */
+ if (coef->iMCU_row_num == last_iMCU_row) {
+ blocks_across += ndummy; /* include lower right corner */
+ MCUs_across = blocks_across / h_samp_factor;
+ for (block_row = block_rows; block_row < compptr->v_samp_factor;
+ block_row++) {
+ thisblockrow = buffer[block_row];
+ lastblockrow = buffer[block_row-1];
+ jzero_far((void FAR *) thisblockrow,
+ (size_t) (blocks_across * SIZEOF(JBLOCK)));
+ for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
+ lastDC = lastblockrow[h_samp_factor-1][0];
+ for (bi = 0; bi < h_samp_factor; bi++) {
+ thisblockrow[bi][0] = lastDC;
+ }
+ thisblockrow += h_samp_factor; /* advance to next MCU in row */
+ lastblockrow += h_samp_factor;
+ }
+ }
+ }
+ }
+ /* NB: compress_output will increment iMCU_row_num if successful.
+ * A suspension return will result in redoing all the work above next time.
+ */
+
+ /* Emit data to the entropy encoder, sharing code with subsequent passes */
+ return compress_output(cinfo, input_buf);
+}
+
+
+/*
+ * Process some data in subsequent passes of a multi-pass case.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the scan.
+ * The data is obtained from the virtual arrays and fed to the entropy coder.
+ * Returns TRUE if the iMCU row is completed, FALSE if suspended.
+ *
+ * NB: input_buf is ignored; it is likely to be a NULL pointer.
+ */
+
+METHODDEF(boolean)
+compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION MCU_col_num; /* index of current MCU within row */
+ int blkn, ci, xindex, yindex, yoffset;
+ JDIMENSION start_col;
+ JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
+ JBLOCKROW buffer_ptr;
+ jpeg_component_info *compptr;
+
+ /* Align the virtual buffers for the components used in this scan.
+ * NB: during first pass, this is safe only because the buffers will
+ * already be aligned properly, so jmemmgr.c won't need to do any I/O.
+ */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ buffer[ci] = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
+ coef->iMCU_row_num * compptr->v_samp_factor,
+ (JDIMENSION) compptr->v_samp_factor, FALSE);
+ }
+
+ /* Loop to process one whole iMCU row */
+ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+ yoffset++) {
+ for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
+ MCU_col_num++) {
+ /* Construct list of pointers to DCT blocks belonging to this MCU */
+ blkn = 0; /* index of current DCT block within MCU */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ start_col = MCU_col_num * compptr->MCU_width;
+ for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+ buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
+ for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
+ coef->MCU_buffer[blkn++] = buffer_ptr++;
+ }
+ }
+ }
+ /* Try to write the MCU. */
+ if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
+ /* Suspension forced; update state counters and exit */
+ coef->MCU_vert_offset = yoffset;
+ coef->mcu_ctr = MCU_col_num;
+ return FALSE;
+ }
+ }
+ /* Completed an MCU row, but perhaps not an iMCU row */
+ coef->mcu_ctr = 0;
+ }
+ /* Completed the iMCU row, advance counters for next one */
+ coef->iMCU_row_num++;
+ start_iMCU_row(cinfo);
+ return TRUE;
+}
+
+#endif /* FULL_COEF_BUFFER_SUPPORTED */
+
+
+/*
+ * Initialize coefficient buffer controller.
+ */
+
+GLOBAL(void)
+jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
+{
+ my_coef_ptr coef;
+
+ coef = (my_coef_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_coef_controller));
+ cinfo->coef = (struct jpeg_c_coef_controller *) coef;
+ coef->pub.start_pass = start_pass_coef;
+
+ /* Create the coefficient buffer. */
+ if (need_full_buffer) {
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+ /* Allocate a full-image virtual array for each component, */
+ /* padded to a multiple of samp_factor DCT blocks in each direction. */
+ int ci;
+ jpeg_component_info *compptr;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
+ (JDIMENSION) jround_up((long) compptr->width_in_blocks,
+ (long) compptr->h_samp_factor),
+ (JDIMENSION) jround_up((long) compptr->height_in_blocks,
+ (long) compptr->v_samp_factor),
+ (JDIMENSION) compptr->v_samp_factor);
+ }
+#else
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif
+ } else {
+ /* We only need a single-MCU buffer. */
+ JBLOCKROW buffer;
+ int i;
+
+ buffer = (JBLOCKROW)
+ (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+ for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
+ coef->MCU_buffer[i] = buffer + i;
+ }
+ coef->whole_image[0] = NULL; /* flag for no virtual arrays */
+ }
+}
diff --git a/src/libjpeg-turbo/jccolext.c.inc b/src/libjpeg-turbo/jccolext.c.inc
new file mode 100644
index 0000000..acbfa23
--- /dev/null
+++ b/src/libjpeg-turbo/jccolext.c.inc
@@ -0,0 +1,114 @@
+/*
+ * jccolext.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 2009-2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains input colorspace conversion routines.
+ */
+
+
+/* This file is included by jccolor.c */
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ *
+ * Note that we change from the application's interleaved-pixel format
+ * to our internal noninterleaved, one-plane-per-component format.
+ * The input buffer is therefore three times as wide as the output buffer.
+ *
+ * A starting row offset is provided only for the output buffer. The caller
+ * can easily adjust the passed input_buf value to accommodate any row
+ * offset required on that side.
+ */
+
+INLINE
+LOCAL(void)
+rgb_ycc_convert_internal (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ register int r, g, b;
+ register INT32 * ctab = cconvert->rgb_ycc_tab;
+ register JSAMPROW inptr;
+ register JSAMPROW outptr0, outptr1, outptr2;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->image_width;
+
+ while (--num_rows >= 0) {
+ inptr = *input_buf++;
+ outptr0 = output_buf[0][output_row];
+ outptr1 = output_buf[1][output_row];
+ outptr2 = output_buf[2][output_row];
+ output_row++;
+ for (col = 0; col < num_cols; col++) {
+ r = GETJSAMPLE(inptr[RGB_RED]);
+ g = GETJSAMPLE(inptr[RGB_GREEN]);
+ b = GETJSAMPLE(inptr[RGB_BLUE]);
+ inptr += RGB_PIXELSIZE;
+ /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
+ * must be too; we do not need an explicit range-limiting operation.
+ * Hence the value being shifted is never negative, and we don't
+ * need the general RIGHT_SHIFT macro.
+ */
+ /* Y */
+ outptr0[col] = (JSAMPLE)
+ ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+ >> SCALEBITS);
+ /* Cb */
+ outptr1[col] = (JSAMPLE)
+ ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
+ >> SCALEBITS);
+ /* Cr */
+ outptr2[col] = (JSAMPLE)
+ ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
+ >> SCALEBITS);
+ }
+ }
+}
+
+
+/**************** Cases other than RGB -> YCbCr **************/
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles RGB->grayscale conversion, which is the same
+ * as the RGB->Y portion of RGB->YCbCr.
+ * We assume rgb_ycc_start has been called (we only use the Y tables).
+ */
+
+INLINE
+LOCAL(void)
+rgb_gray_convert_internal (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ register int r, g, b;
+ register INT32 * ctab = cconvert->rgb_ycc_tab;
+ register JSAMPROW inptr;
+ register JSAMPROW outptr;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->image_width;
+
+ while (--num_rows >= 0) {
+ inptr = *input_buf++;
+ outptr = output_buf[0][output_row];
+ output_row++;
+ for (col = 0; col < num_cols; col++) {
+ r = GETJSAMPLE(inptr[RGB_RED]);
+ g = GETJSAMPLE(inptr[RGB_GREEN]);
+ b = GETJSAMPLE(inptr[RGB_BLUE]);
+ inptr += RGB_PIXELSIZE;
+ /* Y */
+ outptr[col] = (JSAMPLE)
+ ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+ >> SCALEBITS);
+ }
+ }
+}
diff --git a/src/libjpeg-turbo/jccolor.c b/src/libjpeg-turbo/jccolor.c
new file mode 100644
index 0000000..ec80df8
--- /dev/null
+++ b/src/libjpeg-turbo/jccolor.c
@@ -0,0 +1,599 @@
+/*
+ * jccolor.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright (C) 2009-2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains input colorspace conversion routines.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jsimd.h"
+#include "config.h"
+
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_color_converter pub; /* public fields */
+
+ /* Private state for RGB->YCC conversion */
+ INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */
+} my_color_converter;
+
+typedef my_color_converter * my_cconvert_ptr;
+
+
+/**************** RGB -> YCbCr conversion: most common case **************/
+
+/*
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
+ * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
+ * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
+ * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
+ * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
+ * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
+ * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
+ * were not represented exactly. Now we sacrifice exact representation of
+ * maximum red and maximum blue in order to get exact grayscales.
+ *
+ * To avoid floating-point arithmetic, we represent the fractional constants
+ * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
+ * the products by 2^16, with appropriate rounding, to get the correct answer.
+ *
+ * For even more speed, we avoid doing any multiplications in the inner loop
+ * by precalculating the constants times R,G,B for all possible values.
+ * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
+ * for 12-bit samples it is still acceptable. It's not very reasonable for
+ * 16-bit samples, but if you want lossless storage you shouldn't be changing
+ * colorspace anyway.
+ * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
+ * in the tables to save adding them separately in the inner loop.
+ */
+
+#define SCALEBITS 16 /* speediest right-shift on some machines */
+#define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS)
+#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
+#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
+
+/* We allocate one big table and divide it up into eight parts, instead of
+ * doing eight alloc_small requests. This lets us use a single table base
+ * address, which can be held in a register in the inner loops on many
+ * machines (more than can hold all eight addresses, anyway).
+ */
+
+#define R_Y_OFF 0 /* offset to R => Y section */
+#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */
+#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */
+#define R_CB_OFF (3*(MAXJSAMPLE+1))
+#define G_CB_OFF (4*(MAXJSAMPLE+1))
+#define B_CB_OFF (5*(MAXJSAMPLE+1))
+#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */
+#define G_CR_OFF (6*(MAXJSAMPLE+1))
+#define B_CR_OFF (7*(MAXJSAMPLE+1))
+#define TABLE_SIZE (8*(MAXJSAMPLE+1))
+
+
+/* Include inline routines for colorspace extensions */
+
+#include "jccolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+
+#define RGB_RED EXT_RGB_RED
+#define RGB_GREEN EXT_RGB_GREEN
+#define RGB_BLUE EXT_RGB_BLUE
+#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
+#define rgb_ycc_convert_internal extrgb_ycc_convert_internal
+#define rgb_gray_convert_internal extrgb_gray_convert_internal
+#include "jccolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
+
+#define RGB_RED EXT_RGBX_RED
+#define RGB_GREEN EXT_RGBX_GREEN
+#define RGB_BLUE EXT_RGBX_BLUE
+#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
+#define rgb_ycc_convert_internal extrgbx_ycc_convert_internal
+#define rgb_gray_convert_internal extrgbx_gray_convert_internal
+#include "jccolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
+
+#define RGB_RED EXT_BGR_RED
+#define RGB_GREEN EXT_BGR_GREEN
+#define RGB_BLUE EXT_BGR_BLUE
+#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
+#define rgb_ycc_convert_internal extbgr_ycc_convert_internal
+#define rgb_gray_convert_internal extbgr_gray_convert_internal
+#include "jccolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
+
+#define RGB_RED EXT_BGRX_RED
+#define RGB_GREEN EXT_BGRX_GREEN
+#define RGB_BLUE EXT_BGRX_BLUE
+#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
+#define rgb_ycc_convert_internal extbgrx_ycc_convert_internal
+#define rgb_gray_convert_internal extbgrx_gray_convert_internal
+#include "jccolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
+
+#define RGB_RED EXT_XBGR_RED
+#define RGB_GREEN EXT_XBGR_GREEN
+#define RGB_BLUE EXT_XBGR_BLUE
+#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
+#define rgb_ycc_convert_internal extxbgr_ycc_convert_internal
+#define rgb_gray_convert_internal extxbgr_gray_convert_internal
+#include "jccolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
+
+#define RGB_RED EXT_XRGB_RED
+#define RGB_GREEN EXT_XRGB_GREEN
+#define RGB_BLUE EXT_XRGB_BLUE
+#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
+#define rgb_ycc_convert_internal extxrgb_ycc_convert_internal
+#define rgb_gray_convert_internal extxrgb_gray_convert_internal
+#include "jccolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef rgb_ycc_convert_internal
+#undef rgb_gray_convert_internal
+
+
+/*
+ * Initialize for RGB->YCC colorspace conversion.
+ */
+
+METHODDEF(void)
+rgb_ycc_start (j_compress_ptr cinfo)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ INT32 * rgb_ycc_tab;
+ INT32 i;
+
+ /* Allocate and fill in the conversion tables. */
+ cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (TABLE_SIZE * SIZEOF(INT32)));
+
+ for (i = 0; i <= MAXJSAMPLE; i++) {
+ rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
+ rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
+ rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
+ rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
+ rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
+ /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
+ * This ensures that the maximum output will round to MAXJSAMPLE
+ * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
+ */
+ rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
+/* B=>Cb and R=>Cr tables are the same
+ rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
+*/
+ rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
+ rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
+ }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ */
+
+METHODDEF(void)
+rgb_ycc_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ switch (cinfo->in_color_space) {
+ case JCS_EXT_RGB:
+ extrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ case JCS_EXT_RGBX:
+ case JCS_EXT_RGBA:
+ extrgbx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ case JCS_EXT_BGR:
+ extbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ case JCS_EXT_BGRX:
+ case JCS_EXT_BGRA:
+ extbgrx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ case JCS_EXT_XBGR:
+ case JCS_EXT_ABGR:
+ extxbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ case JCS_EXT_XRGB:
+ case JCS_EXT_ARGB:
+ extxrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ default:
+ rgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ }
+}
+
+
+/**************** Cases other than RGB -> YCbCr **************/
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ */
+
+METHODDEF(void)
+rgb_gray_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ switch (cinfo->in_color_space) {
+ case JCS_EXT_RGB:
+ extrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ case JCS_EXT_RGBX:
+ case JCS_EXT_RGBA:
+ extrgbx_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ case JCS_EXT_BGR:
+ extbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ case JCS_EXT_BGRX:
+ case JCS_EXT_BGRA:
+ extbgrx_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ case JCS_EXT_XBGR:
+ case JCS_EXT_ABGR:
+ extxbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ case JCS_EXT_XRGB:
+ case JCS_EXT_ARGB:
+ extxrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ default:
+ rgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
+ num_rows);
+ break;
+ }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles Adobe-style CMYK->YCCK conversion,
+ * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
+ * conversion as above, while passing K (black) unchanged.
+ * We assume rgb_ycc_start has been called.
+ */
+
+METHODDEF(void)
+cmyk_ycck_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ register int r, g, b;
+ register INT32 * ctab = cconvert->rgb_ycc_tab;
+ register JSAMPROW inptr;
+ register JSAMPROW outptr0, outptr1, outptr2, outptr3;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->image_width;
+
+ while (--num_rows >= 0) {
+ inptr = *input_buf++;
+ outptr0 = output_buf[0][output_row];
+ outptr1 = output_buf[1][output_row];
+ outptr2 = output_buf[2][output_row];
+ outptr3 = output_buf[3][output_row];
+ output_row++;
+ for (col = 0; col < num_cols; col++) {
+ r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
+ g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
+ b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
+ /* K passes through as-is */
+ outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
+ inptr += 4;
+ /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
+ * must be too; we do not need an explicit range-limiting operation.
+ * Hence the value being shifted is never negative, and we don't
+ * need the general RIGHT_SHIFT macro.
+ */
+ /* Y */
+ outptr0[col] = (JSAMPLE)
+ ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+ >> SCALEBITS);
+ /* Cb */
+ outptr1[col] = (JSAMPLE)
+ ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
+ >> SCALEBITS);
+ /* Cr */
+ outptr2[col] = (JSAMPLE)
+ ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
+ >> SCALEBITS);
+ }
+ }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles grayscale output with no conversion.
+ * The source can be either plain grayscale or YCbCr (since Y == gray).
+ */
+
+METHODDEF(void)
+grayscale_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ register JSAMPROW inptr;
+ register JSAMPROW outptr;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->image_width;
+ int instride = cinfo->input_components;
+
+ while (--num_rows >= 0) {
+ inptr = *input_buf++;
+ outptr = output_buf[0][output_row];
+ output_row++;
+ for (col = 0; col < num_cols; col++) {
+ outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
+ inptr += instride;
+ }
+ }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles multi-component colorspaces without conversion.
+ * We assume input_components == num_components.
+ */
+
+METHODDEF(void)
+null_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ register JSAMPROW inptr;
+ register JSAMPROW outptr;
+ register JDIMENSION col;
+ register int ci;
+ int nc = cinfo->num_components;
+ JDIMENSION num_cols = cinfo->image_width;
+
+ while (--num_rows >= 0) {
+ /* It seems fastest to make a separate pass for each component. */
+ for (ci = 0; ci < nc; ci++) {
+ inptr = *input_buf;
+ outptr = output_buf[ci][output_row];
+ for (col = 0; col < num_cols; col++) {
+ outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
+ inptr += nc;
+ }
+ }
+ input_buf++;
+ output_row++;
+ }
+}
+
+
+/*
+ * Empty method for start_pass.
+ */
+
+METHODDEF(void)
+null_method (j_compress_ptr cinfo)
+{
+ /* no work needed */
+}
+
+
+/*
+ * Module initialization routine for input colorspace conversion.
+ */
+
+GLOBAL(void)
+jinit_color_converter (j_compress_ptr cinfo)
+{
+ my_cconvert_ptr cconvert;
+
+ cconvert = (my_cconvert_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_color_converter));
+ cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
+ /* set start_pass to null method until we find out differently */
+ cconvert->pub.start_pass = null_method;
+
+ /* Make sure input_components agrees with in_color_space */
+ switch (cinfo->in_color_space) {
+ case JCS_GRAYSCALE:
+ if (cinfo->input_components != 1)
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ break;
+
+ case JCS_RGB:
+ case JCS_EXT_RGB:
+ case JCS_EXT_RGBX:
+ case JCS_EXT_BGR:
+ case JCS_EXT_BGRX:
+ case JCS_EXT_XBGR:
+ case JCS_EXT_XRGB:
+ case JCS_EXT_RGBA:
+ case JCS_EXT_BGRA:
+ case JCS_EXT_ABGR:
+ case JCS_EXT_ARGB:
+ if (cinfo->input_components != rgb_pixelsize[cinfo->in_color_space])
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ break;
+
+ case JCS_YCbCr:
+ if (cinfo->input_components != 3)
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ break;
+
+ case JCS_CMYK:
+ case JCS_YCCK:
+ if (cinfo->input_components != 4)
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ break;
+
+ default: /* JCS_UNKNOWN can be anything */
+ if (cinfo->input_components < 1)
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ break;
+ }
+
+ /* Check num_components, set conversion method based on requested space */
+ switch (cinfo->jpeg_color_space) {
+ case JCS_GRAYSCALE:
+ if (cinfo->num_components != 1)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ if (cinfo->in_color_space == JCS_GRAYSCALE)
+ cconvert->pub.color_convert = grayscale_convert;
+ else if (cinfo->in_color_space == JCS_RGB ||
+ cinfo->in_color_space == JCS_EXT_RGB ||
+ cinfo->in_color_space == JCS_EXT_RGBX ||
+ cinfo->in_color_space == JCS_EXT_BGR ||
+ cinfo->in_color_space == JCS_EXT_BGRX ||
+ cinfo->in_color_space == JCS_EXT_XBGR ||
+ cinfo->in_color_space == JCS_EXT_XRGB ||
+ cinfo->in_color_space == JCS_EXT_RGBA ||
+ cinfo->in_color_space == JCS_EXT_BGRA ||
+ cinfo->in_color_space == JCS_EXT_ABGR ||
+ cinfo->in_color_space == JCS_EXT_ARGB) {
+ if (jsimd_can_rgb_gray())
+ cconvert->pub.color_convert = jsimd_rgb_gray_convert;
+ else {
+ cconvert->pub.start_pass = rgb_ycc_start;
+ cconvert->pub.color_convert = rgb_gray_convert;
+ }
+ } else if (cinfo->in_color_space == JCS_YCbCr)
+ cconvert->pub.color_convert = grayscale_convert;
+ else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_RGB:
+ case JCS_EXT_RGB:
+ case JCS_EXT_RGBX:
+ case JCS_EXT_BGR:
+ case JCS_EXT_BGRX:
+ case JCS_EXT_XBGR:
+ case JCS_EXT_XRGB:
+ case JCS_EXT_RGBA:
+ case JCS_EXT_BGRA:
+ case JCS_EXT_ABGR:
+ case JCS_EXT_ARGB:
+ if (cinfo->num_components != 3)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ if (cinfo->in_color_space == cinfo->jpeg_color_space &&
+ rgb_pixelsize[cinfo->in_color_space] == 3)
+ cconvert->pub.color_convert = null_convert;
+ else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_YCbCr:
+ if (cinfo->num_components != 3)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ if (cinfo->in_color_space == JCS_RGB ||
+ cinfo->in_color_space == JCS_EXT_RGB ||
+ cinfo->in_color_space == JCS_EXT_RGBX ||
+ cinfo->in_color_space == JCS_EXT_BGR ||
+ cinfo->in_color_space == JCS_EXT_BGRX ||
+ cinfo->in_color_space == JCS_EXT_XBGR ||
+ cinfo->in_color_space == JCS_EXT_XRGB ||
+ cinfo->in_color_space == JCS_EXT_RGBA ||
+ cinfo->in_color_space == JCS_EXT_BGRA ||
+ cinfo->in_color_space == JCS_EXT_ABGR ||
+ cinfo->in_color_space == JCS_EXT_ARGB) {
+ if (jsimd_can_rgb_ycc())
+ cconvert->pub.color_convert = jsimd_rgb_ycc_convert;
+ else {
+ cconvert->pub.start_pass = rgb_ycc_start;
+ cconvert->pub.color_convert = rgb_ycc_convert;
+ }
+ } else if (cinfo->in_color_space == JCS_YCbCr)
+ cconvert->pub.color_convert = null_convert;
+ else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_CMYK:
+ if (cinfo->num_components != 4)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ if (cinfo->in_color_space == JCS_CMYK)
+ cconvert->pub.color_convert = null_convert;
+ else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_YCCK:
+ if (cinfo->num_components != 4)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ if (cinfo->in_color_space == JCS_CMYK) {
+ cconvert->pub.start_pass = rgb_ycc_start;
+ cconvert->pub.color_convert = cmyk_ycck_convert;
+ } else if (cinfo->in_color_space == JCS_YCCK)
+ cconvert->pub.color_convert = null_convert;
+ else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ default: /* allow null conversion of JCS_UNKNOWN */
+ if (cinfo->jpeg_color_space != cinfo->in_color_space ||
+ cinfo->num_components != cinfo->input_components)
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ cconvert->pub.color_convert = null_convert;
+ break;
+ }
+}
diff --git a/src/libjpeg-turbo/jcdctmgr.c b/src/libjpeg-turbo/jcdctmgr.c
new file mode 100644
index 0000000..12f8872
--- /dev/null
+++ b/src/libjpeg-turbo/jcdctmgr.c
@@ -0,0 +1,642 @@
+/*
+ * jcdctmgr.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 1999-2006, MIYASAKA Masaru.
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright (C) 2011 D. R. Commander
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the forward-DCT management logic.
+ * This code selects a particular DCT implementation to be used,
+ * and it performs related housekeeping chores including coefficient
+ * quantization.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+#include "jsimddct.h"
+
+
+/* Private subobject for this module */
+
+typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
+typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
+
+typedef JMETHOD(void, convsamp_method_ptr,
+ (JSAMPARRAY sample_data, JDIMENSION start_col,
+ DCTELEM * workspace));
+typedef JMETHOD(void, float_convsamp_method_ptr,
+ (JSAMPARRAY sample_data, JDIMENSION start_col,
+ FAST_FLOAT *workspace));
+
+typedef JMETHOD(void, quantize_method_ptr,
+ (JCOEFPTR coef_block, DCTELEM * divisors,
+ DCTELEM * workspace));
+typedef JMETHOD(void, float_quantize_method_ptr,
+ (JCOEFPTR coef_block, FAST_FLOAT * divisors,
+ FAST_FLOAT * workspace));
+
+METHODDEF(void) quantize (JCOEFPTR, DCTELEM *, DCTELEM *);
+
+typedef struct {
+ struct jpeg_forward_dct pub; /* public fields */
+
+ /* Pointer to the DCT routine actually in use */
+ forward_DCT_method_ptr dct;
+ convsamp_method_ptr convsamp;
+ quantize_method_ptr quantize;
+
+ /* The actual post-DCT divisors --- not identical to the quant table
+ * entries, because of scaling (especially for an unnormalized DCT).
+ * Each table is given in normal array order.
+ */
+ DCTELEM * divisors[NUM_QUANT_TBLS];
+
+ /* work area for FDCT subroutine */
+ DCTELEM * workspace;
+
+#ifdef DCT_FLOAT_SUPPORTED
+ /* Same as above for the floating-point case. */
+ float_DCT_method_ptr float_dct;
+ float_convsamp_method_ptr float_convsamp;
+ float_quantize_method_ptr float_quantize;
+ FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
+ FAST_FLOAT * float_workspace;
+#endif
+} my_fdct_controller;
+
+typedef my_fdct_controller * my_fdct_ptr;
+
+
+/*
+ * Find the highest bit in an integer through binary search.
+ */
+LOCAL(int)
+flss (UINT16 val)
+{
+ int bit;
+
+ bit = 16;
+
+ if (!val)
+ return 0;
+
+ if (!(val & 0xff00)) {
+ bit -= 8;
+ val <<= 8;
+ }
+ if (!(val & 0xf000)) {
+ bit -= 4;
+ val <<= 4;
+ }
+ if (!(val & 0xc000)) {
+ bit -= 2;
+ val <<= 2;
+ }
+ if (!(val & 0x8000)) {
+ bit -= 1;
+ val <<= 1;
+ }
+
+ return bit;
+}
+
+/*
+ * Compute values to do a division using reciprocal.
+ *
+ * This implementation is based on an algorithm described in
+ * "How to optimize for the Pentium family of microprocessors"
+ * (http://www.agner.org/assem/).
+ * More information about the basic algorithm can be found in
+ * the paper "Integer Division Using Reciprocals" by Robert Alverson.
+ *
+ * The basic idea is to replace x/d by x * d^-1. In order to store
+ * d^-1 with enough precision we shift it left a few places. It turns
+ * out that this algoright gives just enough precision, and also fits
+ * into DCTELEM:
+ *
+ * b = (the number of significant bits in divisor) - 1
+ * r = (word size) + b
+ * f = 2^r / divisor
+ *
+ * f will not be an integer for most cases, so we need to compensate
+ * for the rounding error introduced:
+ *
+ * no fractional part:
+ *
+ * result = input >> r
+ *
+ * fractional part of f < 0.5:
+ *
+ * round f down to nearest integer
+ * result = ((input + 1) * f) >> r
+ *
+ * fractional part of f > 0.5:
+ *
+ * round f up to nearest integer
+ * result = (input * f) >> r
+ *
+ * This is the original algorithm that gives truncated results. But we
+ * want properly rounded results, so we replace "input" with
+ * "input + divisor/2".
+ *
+ * In order to allow SIMD implementations we also tweak the values to
+ * allow the same calculation to be made at all times:
+ *
+ * dctbl[0] = f rounded to nearest integer
+ * dctbl[1] = divisor / 2 (+ 1 if fractional part of f < 0.5)
+ * dctbl[2] = 1 << ((word size) * 2 - r)
+ * dctbl[3] = r - (word size)
+ *
+ * dctbl[2] is for stupid instruction sets where the shift operation
+ * isn't member wise (e.g. MMX).
+ *
+ * The reason dctbl[2] and dctbl[3] reduce the shift with (word size)
+ * is that most SIMD implementations have a "multiply and store top
+ * half" operation.
+ *
+ * Lastly, we store each of the values in their own table instead
+ * of in a consecutive manner, yet again in order to allow SIMD
+ * routines.
+ */
+LOCAL(int)
+compute_reciprocal (UINT16 divisor, DCTELEM * dtbl)
+{
+ UDCTELEM2 fq, fr;
+ UDCTELEM c;
+ int b, r;
+
+ b = flss(divisor) - 1;
+ r = sizeof(DCTELEM) * 8 + b;
+
+ fq = ((UDCTELEM2)1 << r) / divisor;
+ fr = ((UDCTELEM2)1 << r) % divisor;
+
+ c = divisor / 2; /* for rounding */
+
+ if (fr == 0) { /* divisor is power of two */
+ /* fq will be one bit too large to fit in DCTELEM, so adjust */
+ fq >>= 1;
+ r--;
+ } else if (fr <= (divisor / 2U)) { /* fractional part is < 0.5 */
+ c++;
+ } else { /* fractional part is > 0.5 */
+ fq++;
+ }
+
+ dtbl[DCTSIZE2 * 0] = (DCTELEM) fq; /* reciprocal */
+ dtbl[DCTSIZE2 * 1] = (DCTELEM) c; /* correction + roundfactor */
+ dtbl[DCTSIZE2 * 2] = (DCTELEM) (1 << (sizeof(DCTELEM)*8*2 - r)); /* scale */
+ dtbl[DCTSIZE2 * 3] = (DCTELEM) r - sizeof(DCTELEM)*8; /* shift */
+
+ if(r <= 16) return 0;
+ else return 1;
+}
+
+/*
+ * Initialize for a processing pass.
+ * Verify that all referenced Q-tables are present, and set up
+ * the divisor table for each one.
+ * In the current implementation, DCT of all components is done during
+ * the first pass, even if only some components will be output in the
+ * first scan. Hence all components should be examined here.
+ */
+
+METHODDEF(void)
+start_pass_fdctmgr (j_compress_ptr cinfo)
+{
+ my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
+ int ci, qtblno, i;
+ jpeg_component_info *compptr;
+ JQUANT_TBL * qtbl;
+ DCTELEM * dtbl;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ qtblno = compptr->quant_tbl_no;
+ /* Make sure specified quantization table is present */
+ if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
+ cinfo->quant_tbl_ptrs[qtblno] == NULL)
+ ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
+ qtbl = cinfo->quant_tbl_ptrs[qtblno];
+ /* Compute divisors for this quant table */
+ /* We may do this more than once for same table, but it's not a big deal */
+ switch (cinfo->dct_method) {
+#ifdef DCT_ISLOW_SUPPORTED
+ case JDCT_ISLOW:
+ /* For LL&M IDCT method, divisors are equal to raw quantization
+ * coefficients multiplied by 8 (to counteract scaling).
+ */
+ if (fdct->divisors[qtblno] == NULL) {
+ fdct->divisors[qtblno] = (DCTELEM *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (DCTSIZE2 * 4) * SIZEOF(DCTELEM));
+ }
+ dtbl = fdct->divisors[qtblno];
+ for (i = 0; i < DCTSIZE2; i++) {
+ if(!compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i])
+ && fdct->quantize == jsimd_quantize)
+ fdct->quantize = quantize;
+ }
+ break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+ case JDCT_IFAST:
+ {
+ /* For AA&N IDCT method, divisors are equal to quantization
+ * coefficients scaled by scalefactor[row]*scalefactor[col], where
+ * scalefactor[0] = 1
+ * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
+ * We apply a further scale factor of 8.
+ */
+#define CONST_BITS 14
+ static const INT16 aanscales[DCTSIZE2] = {
+ /* precomputed values scaled up by 14 bits */
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
+ 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
+ 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
+ 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
+ 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
+ };
+ SHIFT_TEMPS
+
+ if (fdct->divisors[qtblno] == NULL) {
+ fdct->divisors[qtblno] = (DCTELEM *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (DCTSIZE2 * 4) * SIZEOF(DCTELEM));
+ }
+ dtbl = fdct->divisors[qtblno];
+ for (i = 0; i < DCTSIZE2; i++) {
+ if(!compute_reciprocal(
+ DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
+ (INT32) aanscales[i]),
+ CONST_BITS-3), &dtbl[i])
+ && fdct->quantize == jsimd_quantize)
+ fdct->quantize = quantize;
+ }
+ }
+ break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+ case JDCT_FLOAT:
+ {
+ /* For float AA&N IDCT method, divisors are equal to quantization
+ * coefficients scaled by scalefactor[row]*scalefactor[col], where
+ * scalefactor[0] = 1
+ * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
+ * We apply a further scale factor of 8.
+ * What's actually stored is 1/divisor so that the inner loop can
+ * use a multiplication rather than a division.
+ */
+ FAST_FLOAT * fdtbl;
+ int row, col;
+ static const double aanscalefactor[DCTSIZE] = {
+ 1.0, 1.387039845, 1.306562965, 1.175875602,
+ 1.0, 0.785694958, 0.541196100, 0.275899379
+ };
+
+ if (fdct->float_divisors[qtblno] == NULL) {
+ fdct->float_divisors[qtblno] = (FAST_FLOAT *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ DCTSIZE2 * SIZEOF(FAST_FLOAT));
+ }
+ fdtbl = fdct->float_divisors[qtblno];
+ i = 0;
+ for (row = 0; row < DCTSIZE; row++) {
+ for (col = 0; col < DCTSIZE; col++) {
+ fdtbl[i] = (FAST_FLOAT)
+ (1.0 / (((double) qtbl->quantval[i] *
+ aanscalefactor[row] * aanscalefactor[col] * 8.0)));
+ i++;
+ }
+ }
+ }
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ break;
+ }
+ }
+}
+
+
+/*
+ * Load data into workspace, applying unsigned->signed conversion.
+ */
+
+METHODDEF(void)
+convsamp (JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM * workspace)
+{
+ register DCTELEM *workspaceptr;
+ register JSAMPROW elemptr;
+ register int elemr;
+
+ workspaceptr = workspace;
+ for (elemr = 0; elemr < DCTSIZE; elemr++) {
+ elemptr = sample_data[elemr] + start_col;
+
+#if DCTSIZE == 8 /* unroll the inner loop */
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+#else
+ {
+ register int elemc;
+ for (elemc = DCTSIZE; elemc > 0; elemc--)
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ }
+#endif
+ }
+}
+
+
+/*
+ * Quantize/descale the coefficients, and store into coef_blocks[].
+ */
+
+METHODDEF(void)
+quantize (JCOEFPTR coef_block, DCTELEM * divisors, DCTELEM * workspace)
+{
+ int i;
+ DCTELEM temp;
+ UDCTELEM recip, corr, shift;
+ UDCTELEM2 product;
+ JCOEFPTR output_ptr = coef_block;
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ temp = workspace[i];
+ recip = divisors[i + DCTSIZE2 * 0];
+ corr = divisors[i + DCTSIZE2 * 1];
+ shift = divisors[i + DCTSIZE2 * 3];
+
+ if (temp < 0) {
+ temp = -temp;
+ product = (UDCTELEM2)(temp + corr) * recip;
+ product >>= shift + sizeof(DCTELEM)*8;
+ temp = product;
+ temp = -temp;
+ } else {
+ product = (UDCTELEM2)(temp + corr) * recip;
+ product >>= shift + sizeof(DCTELEM)*8;
+ temp = product;
+ }
+
+ output_ptr[i] = (JCOEF) temp;
+ }
+}
+
+
+/*
+ * Perform forward DCT on one or more blocks of a component.
+ *
+ * The input samples are taken from the sample_data[] array starting at
+ * position start_row/start_col, and moving to the right for any additional
+ * blocks. The quantized coefficients are returned in coef_blocks[].
+ */
+
+METHODDEF(void)
+forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
+ JDIMENSION start_row, JDIMENSION start_col,
+ JDIMENSION num_blocks)
+/* This version is used for integer DCT implementations. */
+{
+ /* This routine is heavily used, so it's worth coding it tightly. */
+ my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
+ DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
+ DCTELEM * workspace;
+ JDIMENSION bi;
+
+ /* Make sure the compiler doesn't look up these every pass */
+ forward_DCT_method_ptr do_dct = fdct->dct;
+ convsamp_method_ptr do_convsamp = fdct->convsamp;
+ quantize_method_ptr do_quantize = fdct->quantize;
+ workspace = fdct->workspace;
+
+ sample_data += start_row; /* fold in the vertical offset once */
+
+ for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
+ /* Load data into workspace, applying unsigned->signed conversion */
+ (*do_convsamp) (sample_data, start_col, workspace);
+
+ /* Perform the DCT */
+ (*do_dct) (workspace);
+
+ /* Quantize/descale the coefficients, and store into coef_blocks[] */
+ (*do_quantize) (coef_blocks[bi], divisors, workspace);
+ }
+}
+
+
+#ifdef DCT_FLOAT_SUPPORTED
+
+
+METHODDEF(void)
+convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col, FAST_FLOAT * workspace)
+{
+ register FAST_FLOAT *workspaceptr;
+ register JSAMPROW elemptr;
+ register int elemr;
+
+ workspaceptr = workspace;
+ for (elemr = 0; elemr < DCTSIZE; elemr++) {
+ elemptr = sample_data[elemr] + start_col;
+#if DCTSIZE == 8 /* unroll the inner loop */
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+#else
+ {
+ register int elemc;
+ for (elemc = DCTSIZE; elemc > 0; elemc--)
+ *workspaceptr++ = (FAST_FLOAT)
+ (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ }
+#endif
+ }
+}
+
+
+METHODDEF(void)
+quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors, FAST_FLOAT * workspace)
+{
+ register FAST_FLOAT temp;
+ register int i;
+ register JCOEFPTR output_ptr = coef_block;
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ /* Apply the quantization and scaling factor */
+ temp = workspace[i] * divisors[i];
+
+ /* Round to nearest integer.
+ * Since C does not specify the direction of rounding for negative
+ * quotients, we have to force the dividend positive for portability.
+ * The maximum coefficient size is +-16K (for 12-bit data), so this
+ * code should work for either 16-bit or 32-bit ints.
+ */
+ output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
+ }
+}
+
+
+METHODDEF(void)
+forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
+ JDIMENSION start_row, JDIMENSION start_col,
+ JDIMENSION num_blocks)
+/* This version is used for floating-point DCT implementations. */
+{
+ /* This routine is heavily used, so it's worth coding it tightly. */
+ my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
+ FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
+ FAST_FLOAT * workspace;
+ JDIMENSION bi;
+
+
+ /* Make sure the compiler doesn't look up these every pass */
+ float_DCT_method_ptr do_dct = fdct->float_dct;
+ float_convsamp_method_ptr do_convsamp = fdct->float_convsamp;
+ float_quantize_method_ptr do_quantize = fdct->float_quantize;
+ workspace = fdct->float_workspace;
+
+ sample_data += start_row; /* fold in the vertical offset once */
+
+ for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
+ /* Load data into workspace, applying unsigned->signed conversion */
+ (*do_convsamp) (sample_data, start_col, workspace);
+
+ /* Perform the DCT */
+ (*do_dct) (workspace);
+
+ /* Quantize/descale the coefficients, and store into coef_blocks[] */
+ (*do_quantize) (coef_blocks[bi], divisors, workspace);
+ }
+}
+
+#endif /* DCT_FLOAT_SUPPORTED */
+
+
+/*
+ * Initialize FDCT manager.
+ */
+
+GLOBAL(void)
+jinit_forward_dct (j_compress_ptr cinfo)
+{
+ my_fdct_ptr fdct;
+ int i;
+
+ fdct = (my_fdct_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_fdct_controller));
+ cinfo->fdct = (struct jpeg_forward_dct *) fdct;
+ fdct->pub.start_pass = start_pass_fdctmgr;
+
+ /* First determine the DCT... */
+ switch (cinfo->dct_method) {
+#ifdef DCT_ISLOW_SUPPORTED
+ case JDCT_ISLOW:
+ fdct->pub.forward_DCT = forward_DCT;
+ if (jsimd_can_fdct_islow())
+ fdct->dct = jsimd_fdct_islow;
+ else
+ fdct->dct = jpeg_fdct_islow;
+ break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+ case JDCT_IFAST:
+ fdct->pub.forward_DCT = forward_DCT;
+ if (jsimd_can_fdct_ifast())
+ fdct->dct = jsimd_fdct_ifast;
+ else
+ fdct->dct = jpeg_fdct_ifast;
+ break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+ case JDCT_FLOAT:
+ fdct->pub.forward_DCT = forward_DCT_float;
+ if (jsimd_can_fdct_float())
+ fdct->float_dct = jsimd_fdct_float;
+ else
+ fdct->float_dct = jpeg_fdct_float;
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ break;
+ }
+
+ /* ...then the supporting stages. */
+ switch (cinfo->dct_method) {
+#ifdef DCT_ISLOW_SUPPORTED
+ case JDCT_ISLOW:
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+ case JDCT_IFAST:
+#endif
+#if defined(DCT_ISLOW_SUPPORTED) || defined(DCT_IFAST_SUPPORTED)
+ if (jsimd_can_convsamp())
+ fdct->convsamp = jsimd_convsamp;
+ else
+ fdct->convsamp = convsamp;
+ if (jsimd_can_quantize())
+ fdct->quantize = jsimd_quantize;
+ else
+ fdct->quantize = quantize;
+ break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+ case JDCT_FLOAT:
+ if (jsimd_can_convsamp_float())
+ fdct->float_convsamp = jsimd_convsamp_float;
+ else
+ fdct->float_convsamp = convsamp_float;
+ if (jsimd_can_quantize_float())
+ fdct->float_quantize = jsimd_quantize_float;
+ else
+ fdct->float_quantize = quantize_float;
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ break;
+ }
+
+ /* Allocate workspace memory */
+#ifdef DCT_FLOAT_SUPPORTED
+ if (cinfo->dct_method == JDCT_FLOAT)
+ fdct->float_workspace = (FAST_FLOAT *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(FAST_FLOAT) * DCTSIZE2);
+ else
+#endif
+ fdct->workspace = (DCTELEM *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(DCTELEM) * DCTSIZE2);
+
+ /* Mark divisor tables unallocated */
+ for (i = 0; i < NUM_QUANT_TBLS; i++) {
+ fdct->divisors[i] = NULL;
+#ifdef DCT_FLOAT_SUPPORTED
+ fdct->float_divisors[i] = NULL;
+#endif
+ }
+}
diff --git a/src/libjpeg-turbo/jchuff.c b/src/libjpeg-turbo/jchuff.c
new file mode 100644
index 0000000..fd4fa46
--- /dev/null
+++ b/src/libjpeg-turbo/jchuff.c
@@ -0,0 +1,1026 @@
+/*
+ * jchuff.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Copyright (C) 2009-2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains Huffman entropy encoding routines.
+ *
+ * Much of the complexity here has to do with supporting output suspension.
+ * If the data destination module demands suspension, we want to be able to
+ * back up to the start of the current MCU. To do this, we copy state
+ * variables into local working storage, and update them back to the
+ * permanent JPEG objects only upon successful completion of an MCU.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jchuff.h" /* Declarations shared with jcphuff.c */
+#include <limits.h>
+
+static unsigned char jpeg_nbits_table[65536];
+static int jpeg_nbits_table_init = 0;
+
+#ifndef min
+ #define min(a,b) ((a)<(b)?(a):(b))
+#endif
+
+
+/* Expanded entropy encoder object for Huffman encoding.
+ *
+ * The savable_state subrecord contains fields that change within an MCU,
+ * but must not be updated permanently until we complete the MCU.
+ */
+
+typedef struct {
+ size_t put_buffer; /* current bit-accumulation buffer */
+ int put_bits; /* # of bits now in it */
+ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+} savable_state;
+
+/* This macro is to work around compilers with missing or broken
+ * structure assignment. You'll need to fix this code if you have
+ * such a compiler and you change MAX_COMPS_IN_SCAN.
+ */
+
+#ifndef NO_STRUCT_ASSIGN
+#define ASSIGN_STATE(dest,src) ((dest) = (src))
+#else
+#if MAX_COMPS_IN_SCAN == 4
+#define ASSIGN_STATE(dest,src) \
+ ((dest).put_buffer = (src).put_buffer, \
+ (dest).put_bits = (src).put_bits, \
+ (dest).last_dc_val[0] = (src).last_dc_val[0], \
+ (dest).last_dc_val[1] = (src).last_dc_val[1], \
+ (dest).last_dc_val[2] = (src).last_dc_val[2], \
+ (dest).last_dc_val[3] = (src).last_dc_val[3])
+#endif
+#endif
+
+
+typedef struct {
+ struct jpeg_entropy_encoder pub; /* public fields */
+
+ savable_state saved; /* Bit buffer & DC state at start of MCU */
+
+ /* These fields are NOT loaded into local working state. */
+ unsigned int restarts_to_go; /* MCUs left in this restart interval */
+ int next_restart_num; /* next restart number to write (0-7) */
+
+ /* Pointers to derived tables (these workspaces have image lifespan) */
+ c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
+ c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
+
+#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */
+ long * dc_count_ptrs[NUM_HUFF_TBLS];
+ long * ac_count_ptrs[NUM_HUFF_TBLS];
+#endif
+} huff_entropy_encoder;
+
+typedef huff_entropy_encoder * huff_entropy_ptr;
+
+/* Working state while writing an MCU.
+ * This struct contains all the fields that are needed by subroutines.
+ */
+
+typedef struct {
+ JOCTET * next_output_byte; /* => next byte to write in buffer */
+ size_t free_in_buffer; /* # of byte spaces remaining in buffer */
+ savable_state cur; /* Current bit buffer & DC state */
+ j_compress_ptr cinfo; /* dump_buffer needs access to this */
+} working_state;
+
+
+/* Forward declarations */
+METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo));
+#ifdef ENTROPY_OPT_SUPPORTED
+METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo));
+#endif
+
+
+/*
+ * Initialize for a Huffman-compressed scan.
+ * If gather_statistics is TRUE, we do not output anything during the scan,
+ * just count the Huffman symbols used and generate Huffman code tables.
+ */
+
+METHODDEF(void)
+start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int ci, dctbl, actbl;
+ jpeg_component_info * compptr;
+
+ if (gather_statistics) {
+#ifdef ENTROPY_OPT_SUPPORTED
+ entropy->pub.encode_mcu = encode_mcu_gather;
+ entropy->pub.finish_pass = finish_pass_gather;
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ entropy->pub.encode_mcu = encode_mcu_huff;
+ entropy->pub.finish_pass = finish_pass_huff;
+ }
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ dctbl = compptr->dc_tbl_no;
+ actbl = compptr->ac_tbl_no;
+ if (gather_statistics) {
+#ifdef ENTROPY_OPT_SUPPORTED
+ /* Check for invalid table indexes */
+ /* (make_c_derived_tbl does this in the other path) */
+ if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
+ if (actbl < 0 || actbl >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
+ /* Allocate and zero the statistics tables */
+ /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
+ if (entropy->dc_count_ptrs[dctbl] == NULL)
+ entropy->dc_count_ptrs[dctbl] = (long *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ 257 * SIZEOF(long));
+ MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long));
+ if (entropy->ac_count_ptrs[actbl] == NULL)
+ entropy->ac_count_ptrs[actbl] = (long *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ 257 * SIZEOF(long));
+ MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long));
+#endif
+ } else {
+ /* Compute derived values for Huffman tables */
+ /* We may do this more than once for a table, but it's not expensive */
+ jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
+ & entropy->dc_derived_tbls[dctbl]);
+ jpeg_make_c_derived_tbl(cinfo, FALSE, actbl,
+ & entropy->ac_derived_tbls[actbl]);
+ }
+ /* Initialize DC predictions to 0 */
+ entropy->saved.last_dc_val[ci] = 0;
+ }
+
+ /* Initialize bit buffer to empty */
+ entropy->saved.put_buffer = 0;
+ entropy->saved.put_bits = 0;
+
+ /* Initialize restart stuff */
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num = 0;
+}
+
+
+/*
+ * Compute the derived values for a Huffman table.
+ * This routine also performs some validation checks on the table.
+ *
+ * Note this is also used by jcphuff.c.
+ */
+
+GLOBAL(void)
+jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
+ c_derived_tbl ** pdtbl)
+{
+ JHUFF_TBL *htbl;
+ c_derived_tbl *dtbl;
+ int p, i, l, lastp, si, maxsymbol;
+ char huffsize[257];
+ unsigned int huffcode[257];
+ unsigned int code;
+
+ /* Note that huffsize[] and huffcode[] are filled in code-length order,
+ * paralleling the order of the symbols themselves in htbl->huffval[].
+ */
+
+ /* Find the input Huffman table */
+ if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+ htbl =
+ isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
+ if (htbl == NULL)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+
+ /* Allocate a workspace if we haven't already done so. */
+ if (*pdtbl == NULL)
+ *pdtbl = (c_derived_tbl *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(c_derived_tbl));
+ dtbl = *pdtbl;
+
+ /* Figure C.1: make table of Huffman code length for each symbol */
+
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ i = (int) htbl->bits[l];
+ if (i < 0 || p + i > 256) /* protect against table overrun */
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ while (i--)
+ huffsize[p++] = (char) l;
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+ /* Figure C.2: generate the codes themselves */
+ /* We also validate that the counts represent a legal Huffman code tree. */
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p]) {
+ while (((int) huffsize[p]) == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ /* code is now 1 more than the last code used for codelength si; but
+ * it must still fit in si bits, since no code is allowed to be all ones.
+ */
+ if (((INT32) code) >= (((INT32) 1) << si))
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ code <<= 1;
+ si++;
+ }
+
+ /* Figure C.3: generate encoding tables */
+ /* These are code and size indexed by symbol value */
+
+ /* Set all codeless symbols to have code length 0;
+ * this lets us detect duplicate VAL entries here, and later
+ * allows emit_bits to detect any attempt to emit such symbols.
+ */
+ MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi));
+
+ /* This is also a convenient place to check for out-of-range
+ * and duplicated VAL entries. We allow 0..255 for AC symbols
+ * but only 0..15 for DC. (We could constrain them further
+ * based on data depth and mode, but this seems enough.)
+ */
+ maxsymbol = isDC ? 15 : 255;
+
+ for (p = 0; p < lastp; p++) {
+ i = htbl->huffval[p];
+ if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ dtbl->ehufco[i] = huffcode[p];
+ dtbl->ehufsi[i] = huffsize[p];
+ }
+
+ if(!jpeg_nbits_table_init) {
+ for(i = 0; i < 65536; i++) {
+ int nbits = 0, temp = i;
+ while (temp) {temp >>= 1; nbits++;}
+ jpeg_nbits_table[i] = nbits;
+ }
+ jpeg_nbits_table_init = 1;
+ }
+}
+
+
+/* Outputting bytes to the file */
+
+/* Emit a byte, taking 'action' if must suspend. */
+#define emit_byte(state,val,action) \
+ { *(state)->next_output_byte++ = (JOCTET) (val); \
+ if (--(state)->free_in_buffer == 0) \
+ if (! dump_buffer(state)) \
+ { action; } }
+
+
+LOCAL(boolean)
+dump_buffer (working_state * state)
+/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
+{
+ struct jpeg_destination_mgr * dest = state->cinfo->dest;
+
+ dest->free_in_buffer = state->free_in_buffer;
+
+ if (! (*dest->empty_output_buffer) (state->cinfo))
+ return FALSE;
+ /* After a successful buffer dump, must reset buffer pointers */
+ state->next_output_byte = dest->next_output_byte;
+ state->free_in_buffer = dest->free_in_buffer;
+ return TRUE;
+}
+
+
+/* Outputting bits to the file */
+
+/* These macros perform the same task as the emit_bits() function in the
+ * original libjpeg code. In addition to reducing overhead by explicitly
+ * inlining the code, additional performance is achieved by taking into
+ * account the size of the bit buffer and waiting until it is almost full
+ * before emptying it. This mostly benefits 64-bit platforms, since 6
+ * bytes can be stored in a 64-bit bit buffer before it has to be emptied.
+ */
+
+#define EMIT_BYTE() { \
+ JOCTET c; \
+ put_bits -= 8; \
+ c = (JOCTET)GETJOCTET(put_buffer >> put_bits); \
+ *buffer++ = c; \
+ if (c == 0xFF) /* need to stuff a zero byte? */ \
+ *buffer++ = 0; \
+ }
+
+#define PUT_BITS(code, size) { \
+ put_bits += size; \
+ put_buffer = (put_buffer << size) | code; \
+}
+
+#define CHECKBUF15() { \
+ if (put_bits > 15) { \
+ EMIT_BYTE() \
+ EMIT_BYTE() \
+ } \
+}
+
+#define CHECKBUF31() { \
+ if (put_bits > 31) { \
+ EMIT_BYTE() \
+ EMIT_BYTE() \
+ EMIT_BYTE() \
+ EMIT_BYTE() \
+ } \
+}
+
+#define CHECKBUF47() { \
+ if (put_bits > 47) { \
+ EMIT_BYTE() \
+ EMIT_BYTE() \
+ EMIT_BYTE() \
+ EMIT_BYTE() \
+ EMIT_BYTE() \
+ EMIT_BYTE() \
+ } \
+}
+
+#if __WORDSIZE==64 || defined(_WIN64)
+
+#define EMIT_BITS(code, size) { \
+ CHECKBUF47() \
+ PUT_BITS(code, size) \
+}
+
+#define EMIT_CODE(code, size) { \
+ temp2 &= (((INT32) 1)<<nbits) - 1; \
+ CHECKBUF31() \
+ PUT_BITS(code, size) \
+ PUT_BITS(temp2, nbits) \
+ }
+
+#else
+
+#define EMIT_BITS(code, size) { \
+ PUT_BITS(code, size) \
+ CHECKBUF15() \
+}
+
+#define EMIT_CODE(code, size) { \
+ temp2 &= (((INT32) 1)<<nbits) - 1; \
+ PUT_BITS(code, size) \
+ CHECKBUF15() \
+ PUT_BITS(temp2, nbits) \
+ CHECKBUF15() \
+ }
+
+#endif
+
+
+#define BUFSIZE (DCTSIZE2 * 2)
+
+#define LOAD_BUFFER() { \
+ if (state->free_in_buffer < BUFSIZE) { \
+ localbuf = 1; \
+ buffer = _buffer; \
+ } \
+ else buffer = state->next_output_byte; \
+ }
+
+#define STORE_BUFFER() { \
+ if (localbuf) { \
+ bytes = buffer - _buffer; \
+ buffer = _buffer; \
+ while (bytes > 0) { \
+ bytestocopy = min(bytes, state->free_in_buffer); \
+ MEMCOPY(state->next_output_byte, buffer, bytestocopy); \
+ state->next_output_byte += bytestocopy; \
+ buffer += bytestocopy; \
+ state->free_in_buffer -= bytestocopy; \
+ if (state->free_in_buffer == 0) \
+ if (! dump_buffer(state)) return FALSE; \
+ bytes -= bytestocopy; \
+ } \
+ } \
+ else { \
+ state->free_in_buffer -= (buffer - state->next_output_byte); \
+ state->next_output_byte = buffer; \
+ } \
+ }
+
+
+LOCAL(boolean)
+flush_bits (working_state * state)
+{
+ JOCTET _buffer[BUFSIZE], *buffer;
+ size_t put_buffer; int put_bits;
+ size_t bytes, bytestocopy; int localbuf = 0;
+
+ put_buffer = state->cur.put_buffer;
+ put_bits = state->cur.put_bits;
+ LOAD_BUFFER()
+
+ /* fill any partial byte with ones */
+ PUT_BITS(0x7F, 7)
+ while (put_bits >= 8) EMIT_BYTE()
+
+ state->cur.put_buffer = 0; /* and reset bit-buffer to empty */
+ state->cur.put_bits = 0;
+ STORE_BUFFER()
+
+ return TRUE;
+}
+
+
+/* Encode a single block's worth of coefficients */
+
+LOCAL(boolean)
+encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
+ c_derived_tbl *dctbl, c_derived_tbl *actbl)
+{
+ int temp, temp2, temp3;
+ int nbits;
+ int r, code, size;
+ JOCTET _buffer[BUFSIZE], *buffer;
+ size_t put_buffer; int put_bits;
+ int code_0xf0 = actbl->ehufco[0xf0], size_0xf0 = actbl->ehufsi[0xf0];
+ size_t bytes, bytestocopy; int localbuf = 0;
+
+ put_buffer = state->cur.put_buffer;
+ put_bits = state->cur.put_bits;
+ LOAD_BUFFER()
+
+ /* Encode the DC coefficient difference per section F.1.2.1 */
+
+ temp = temp2 = block[0] - last_dc_val;
+
+ /* This is a well-known technique for obtaining the absolute value without a
+ * branch. It is derived from an assembly language technique presented in
+ * "How to Optimize for the Pentium Processors", Copyright (c) 1996, 1997 by
+ * Agner Fog.
+ */
+ temp3 = temp >> (CHAR_BIT * sizeof(int) - 1);
+ temp ^= temp3;
+ temp -= temp3;
+
+ /* For a negative input, want temp2 = bitwise complement of abs(input) */
+ /* This code assumes we are on a two's complement machine */
+ temp2 += temp3;
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ nbits = jpeg_nbits_table[temp];
+
+ /* Emit the Huffman-coded symbol for the number of bits */
+ code = dctbl->ehufco[nbits];
+ size = dctbl->ehufsi[nbits];
+ PUT_BITS(code, size)
+ CHECKBUF15()
+
+ /* Mask off any extra bits in code */
+ temp2 &= (((INT32) 1)<<nbits) - 1;
+
+ /* Emit that number of bits of the value, if positive, */
+ /* or the complement of its magnitude, if negative. */
+ PUT_BITS(temp2, nbits)
+ CHECKBUF15()
+
+ /* Encode the AC coefficients per section F.1.2.2 */
+
+ r = 0; /* r = run length of zeros */
+
+/* Manually unroll the k loop to eliminate the counter variable. This
+ * improves performance greatly on systems with a limited number of
+ * registers (such as x86.)
+ */
+#define kloop(jpeg_natural_order_of_k) { \
+ if ((temp = block[jpeg_natural_order_of_k]) == 0) { \
+ r++; \
+ } else { \
+ temp2 = temp; \
+ /* Branch-less absolute value, bitwise complement, etc., same as above */ \
+ temp3 = temp >> (CHAR_BIT * sizeof(int) - 1); \
+ temp ^= temp3; \
+ temp -= temp3; \
+ temp2 += temp3; \
+ nbits = jpeg_nbits_table[temp]; \
+ /* if run length > 15, must emit special run-length-16 codes (0xF0) */ \
+ while (r > 15) { \
+ EMIT_BITS(code_0xf0, size_0xf0) \
+ r -= 16; \
+ } \
+ /* Emit Huffman symbol for run length / number of bits */ \
+ temp3 = (r << 4) + nbits; \
+ code = actbl->ehufco[temp3]; \
+ size = actbl->ehufsi[temp3]; \
+ EMIT_CODE(code, size) \
+ r = 0; \
+ } \
+}
+
+ /* One iteration for each value in jpeg_natural_order[] */
+ kloop(1); kloop(8); kloop(16); kloop(9); kloop(2); kloop(3);
+ kloop(10); kloop(17); kloop(24); kloop(32); kloop(25); kloop(18);
+ kloop(11); kloop(4); kloop(5); kloop(12); kloop(19); kloop(26);
+ kloop(33); kloop(40); kloop(48); kloop(41); kloop(34); kloop(27);
+ kloop(20); kloop(13); kloop(6); kloop(7); kloop(14); kloop(21);
+ kloop(28); kloop(35); kloop(42); kloop(49); kloop(56); kloop(57);
+ kloop(50); kloop(43); kloop(36); kloop(29); kloop(22); kloop(15);
+ kloop(23); kloop(30); kloop(37); kloop(44); kloop(51); kloop(58);
+ kloop(59); kloop(52); kloop(45); kloop(38); kloop(31); kloop(39);
+ kloop(46); kloop(53); kloop(60); kloop(61); kloop(54); kloop(47);
+ kloop(55); kloop(62); kloop(63);
+
+ /* If the last coef(s) were zero, emit an end-of-block code */
+ if (r > 0) {
+ code = actbl->ehufco[0];
+ size = actbl->ehufsi[0];
+ EMIT_BITS(code, size)
+ }
+
+ state->cur.put_buffer = put_buffer;
+ state->cur.put_bits = put_bits;
+ STORE_BUFFER()
+
+ return TRUE;
+}
+
+
+/*
+ * Emit a restart marker & resynchronize predictions.
+ */
+
+LOCAL(boolean)
+emit_restart (working_state * state, int restart_num)
+{
+ int ci;
+
+ if (! flush_bits(state))
+ return FALSE;
+
+ emit_byte(state, 0xFF, return FALSE);
+ emit_byte(state, JPEG_RST0 + restart_num, return FALSE);
+
+ /* Re-initialize DC predictions to 0 */
+ for (ci = 0; ci < state->cinfo->comps_in_scan; ci++)
+ state->cur.last_dc_val[ci] = 0;
+
+ /* The restart counter is not updated until we successfully write the MCU. */
+
+ return TRUE;
+}
+
+
+/*
+ * Encode and output one MCU's worth of Huffman-compressed coefficients.
+ */
+
+METHODDEF(boolean)
+encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ working_state state;
+ int blkn, ci;
+ jpeg_component_info * compptr;
+
+ /* Load up working state */
+ state.next_output_byte = cinfo->dest->next_output_byte;
+ state.free_in_buffer = cinfo->dest->free_in_buffer;
+ ASSIGN_STATE(state.cur, entropy->saved);
+ state.cinfo = cinfo;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! emit_restart(&state, entropy->next_restart_num))
+ return FALSE;
+ }
+
+ /* Encode the MCU data blocks */
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+ if (! encode_one_block(&state,
+ MCU_data[blkn][0], state.cur.last_dc_val[ci],
+ entropy->dc_derived_tbls[compptr->dc_tbl_no],
+ entropy->ac_derived_tbls[compptr->ac_tbl_no]))
+ return FALSE;
+ /* Update last_dc_val */
+ state.cur.last_dc_val[ci] = MCU_data[blkn][0][0];
+ }
+
+ /* Completed MCU, so update state */
+ cinfo->dest->next_output_byte = state.next_output_byte;
+ cinfo->dest->free_in_buffer = state.free_in_buffer;
+ ASSIGN_STATE(entropy->saved, state.cur);
+
+ /* Update restart-interval state too */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Finish up at the end of a Huffman-compressed scan.
+ */
+
+METHODDEF(void)
+finish_pass_huff (j_compress_ptr cinfo)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ working_state state;
+
+ /* Load up working state ... flush_bits needs it */
+ state.next_output_byte = cinfo->dest->next_output_byte;
+ state.free_in_buffer = cinfo->dest->free_in_buffer;
+ ASSIGN_STATE(state.cur, entropy->saved);
+ state.cinfo = cinfo;
+
+ /* Flush out the last data */
+ if (! flush_bits(&state))
+ ERREXIT(cinfo, JERR_CANT_SUSPEND);
+
+ /* Update state */
+ cinfo->dest->next_output_byte = state.next_output_byte;
+ cinfo->dest->free_in_buffer = state.free_in_buffer;
+ ASSIGN_STATE(entropy->saved, state.cur);
+}
+
+
+/*
+ * Huffman coding optimization.
+ *
+ * We first scan the supplied data and count the number of uses of each symbol
+ * that is to be Huffman-coded. (This process MUST agree with the code above.)
+ * Then we build a Huffman coding tree for the observed counts.
+ * Symbols which are not needed at all for the particular image are not
+ * assigned any code, which saves space in the DHT marker as well as in
+ * the compressed data.
+ */
+
+#ifdef ENTROPY_OPT_SUPPORTED
+
+
+/* Process a single block's worth of coefficients */
+
+LOCAL(void)
+htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
+ long dc_counts[], long ac_counts[])
+{
+ register int temp;
+ register int nbits;
+ register int k, r;
+
+ /* Encode the DC coefficient difference per section F.1.2.1 */
+
+ temp = block[0] - last_dc_val;
+ if (temp < 0)
+ temp = -temp;
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ nbits = 0;
+ while (temp) {
+ nbits++;
+ temp >>= 1;
+ }
+ /* Check for out-of-range coefficient values.
+ * Since we're encoding a difference, the range limit is twice as much.
+ */
+ if (nbits > MAX_COEF_BITS+1)
+ ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+
+ /* Count the Huffman symbol for the number of bits */
+ dc_counts[nbits]++;
+
+ /* Encode the AC coefficients per section F.1.2.2 */
+
+ r = 0; /* r = run length of zeros */
+
+ for (k = 1; k < DCTSIZE2; k++) {
+ if ((temp = block[jpeg_natural_order[k]]) == 0) {
+ r++;
+ } else {
+ /* if run length > 15, must emit special run-length-16 codes (0xF0) */
+ while (r > 15) {
+ ac_counts[0xF0]++;
+ r -= 16;
+ }
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ if (temp < 0)
+ temp = -temp;
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ nbits = 1; /* there must be at least one 1 bit */
+ while ((temp >>= 1))
+ nbits++;
+ /* Check for out-of-range coefficient values */
+ if (nbits > MAX_COEF_BITS)
+ ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+
+ /* Count Huffman symbol for run length / number of bits */
+ ac_counts[(r << 4) + nbits]++;
+
+ r = 0;
+ }
+ }
+
+ /* If the last coef(s) were zero, emit an end-of-block code */
+ if (r > 0)
+ ac_counts[0]++;
+}
+
+
+/*
+ * Trial-encode one MCU's worth of Huffman-compressed coefficients.
+ * No data is actually output, so no suspension return is possible.
+ */
+
+METHODDEF(boolean)
+encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int blkn, ci;
+ jpeg_component_info * compptr;
+
+ /* Take care of restart intervals if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ /* Re-initialize DC predictions to 0 */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+ entropy->saved.last_dc_val[ci] = 0;
+ /* Update restart state */
+ entropy->restarts_to_go = cinfo->restart_interval;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+ htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci],
+ entropy->dc_count_ptrs[compptr->dc_tbl_no],
+ entropy->ac_count_ptrs[compptr->ac_tbl_no]);
+ entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0];
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Generate the best Huffman code table for the given counts, fill htbl.
+ * Note this is also used by jcphuff.c.
+ *
+ * The JPEG standard requires that no symbol be assigned a codeword of all
+ * one bits (so that padding bits added at the end of a compressed segment
+ * can't look like a valid code). Because of the canonical ordering of
+ * codewords, this just means that there must be an unused slot in the
+ * longest codeword length category. Section K.2 of the JPEG spec suggests
+ * reserving such a slot by pretending that symbol 256 is a valid symbol
+ * with count 1. In theory that's not optimal; giving it count zero but
+ * including it in the symbol set anyway should give a better Huffman code.
+ * But the theoretically better code actually seems to come out worse in
+ * practice, because it produces more all-ones bytes (which incur stuffed
+ * zero bytes in the final file). In any case the difference is tiny.
+ *
+ * The JPEG standard requires Huffman codes to be no more than 16 bits long.
+ * If some symbols have a very small but nonzero probability, the Huffman tree
+ * must be adjusted to meet the code length restriction. We currently use
+ * the adjustment method suggested in JPEG section K.2. This method is *not*
+ * optimal; it may not choose the best possible limited-length code. But
+ * typically only very-low-frequency symbols will be given less-than-optimal
+ * lengths, so the code is almost optimal. Experimental comparisons against
+ * an optimal limited-length-code algorithm indicate that the difference is
+ * microscopic --- usually less than a hundredth of a percent of total size.
+ * So the extra complexity of an optimal algorithm doesn't seem worthwhile.
+ */
+
+GLOBAL(void)
+jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
+{
+#define MAX_CLEN 32 /* assumed maximum initial code length */
+ UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */
+ int codesize[257]; /* codesize[k] = code length of symbol k */
+ int others[257]; /* next symbol in current branch of tree */
+ int c1, c2;
+ int p, i, j;
+ long v;
+
+ /* This algorithm is explained in section K.2 of the JPEG standard */
+
+ MEMZERO(bits, SIZEOF(bits));
+ MEMZERO(codesize, SIZEOF(codesize));
+ for (i = 0; i < 257; i++)
+ others[i] = -1; /* init links to empty */
+
+ freq[256] = 1; /* make sure 256 has a nonzero count */
+ /* Including the pseudo-symbol 256 in the Huffman procedure guarantees
+ * that no real symbol is given code-value of all ones, because 256
+ * will be placed last in the largest codeword category.
+ */
+
+ /* Huffman's basic algorithm to assign optimal code lengths to symbols */
+
+ for (;;) {
+ /* Find the smallest nonzero frequency, set c1 = its symbol */
+ /* In case of ties, take the larger symbol number */
+ c1 = -1;
+ v = 1000000000L;
+ for (i = 0; i <= 256; i++) {
+ if (freq[i] && freq[i] <= v) {
+ v = freq[i];
+ c1 = i;
+ }
+ }
+
+ /* Find the next smallest nonzero frequency, set c2 = its symbol */
+ /* In case of ties, take the larger symbol number */
+ c2 = -1;
+ v = 1000000000L;
+ for (i = 0; i <= 256; i++) {
+ if (freq[i] && freq[i] <= v && i != c1) {
+ v = freq[i];
+ c2 = i;
+ }
+ }
+
+ /* Done if we've merged everything into one frequency */
+ if (c2 < 0)
+ break;
+
+ /* Else merge the two counts/trees */
+ freq[c1] += freq[c2];
+ freq[c2] = 0;
+
+ /* Increment the codesize of everything in c1's tree branch */
+ codesize[c1]++;
+ while (others[c1] >= 0) {
+ c1 = others[c1];
+ codesize[c1]++;
+ }
+
+ others[c1] = c2; /* chain c2 onto c1's tree branch */
+
+ /* Increment the codesize of everything in c2's tree branch */
+ codesize[c2]++;
+ while (others[c2] >= 0) {
+ c2 = others[c2];
+ codesize[c2]++;
+ }
+ }
+
+ /* Now count the number of symbols of each code length */
+ for (i = 0; i <= 256; i++) {
+ if (codesize[i]) {
+ /* The JPEG standard seems to think that this can't happen, */
+ /* but I'm paranoid... */
+ if (codesize[i] > MAX_CLEN)
+ ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
+
+ bits[codesize[i]]++;
+ }
+ }
+
+ /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
+ * Huffman procedure assigned any such lengths, we must adjust the coding.
+ * Here is what the JPEG spec says about how this next bit works:
+ * Since symbols are paired for the longest Huffman code, the symbols are
+ * removed from this length category two at a time. The prefix for the pair
+ * (which is one bit shorter) is allocated to one of the pair; then,
+ * skipping the BITS entry for that prefix length, a code word from the next
+ * shortest nonzero BITS entry is converted into a prefix for two code words
+ * one bit longer.
+ */
+
+ for (i = MAX_CLEN; i > 16; i--) {
+ while (bits[i] > 0) {
+ j = i - 2; /* find length of new prefix to be used */
+ while (bits[j] == 0)
+ j--;
+
+ bits[i] -= 2; /* remove two symbols */
+ bits[i-1]++; /* one goes in this length */
+ bits[j+1] += 2; /* two new symbols in this length */
+ bits[j]--; /* symbol of this length is now a prefix */
+ }
+ }
+
+ /* Remove the count for the pseudo-symbol 256 from the largest codelength */
+ while (bits[i] == 0) /* find largest codelength still in use */
+ i--;
+ bits[i]--;
+
+ /* Return final symbol counts (only for lengths 0..16) */
+ MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
+
+ /* Return a list of the symbols sorted by code length */
+ /* It's not real clear to me why we don't need to consider the codelength
+ * changes made above, but the JPEG spec seems to think this works.
+ */
+ p = 0;
+ for (i = 1; i <= MAX_CLEN; i++) {
+ for (j = 0; j <= 255; j++) {
+ if (codesize[j] == i) {
+ htbl->huffval[p] = (UINT8) j;
+ p++;
+ }
+ }
+ }
+
+ /* Set sent_table FALSE so updated table will be written to JPEG file. */
+ htbl->sent_table = FALSE;
+}
+
+
+/*
+ * Finish up a statistics-gathering pass and create the new Huffman tables.
+ */
+
+METHODDEF(void)
+finish_pass_gather (j_compress_ptr cinfo)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int ci, dctbl, actbl;
+ jpeg_component_info * compptr;
+ JHUFF_TBL **htblptr;
+ boolean did_dc[NUM_HUFF_TBLS];
+ boolean did_ac[NUM_HUFF_TBLS];
+
+ /* It's important not to apply jpeg_gen_optimal_table more than once
+ * per table, because it clobbers the input frequency counts!
+ */
+ MEMZERO(did_dc, SIZEOF(did_dc));
+ MEMZERO(did_ac, SIZEOF(did_ac));
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ dctbl = compptr->dc_tbl_no;
+ actbl = compptr->ac_tbl_no;
+ if (! did_dc[dctbl]) {
+ htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl];
+ if (*htblptr == NULL)
+ *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+ jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]);
+ did_dc[dctbl] = TRUE;
+ }
+ if (! did_ac[actbl]) {
+ htblptr = & cinfo->ac_huff_tbl_ptrs[actbl];
+ if (*htblptr == NULL)
+ *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+ jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]);
+ did_ac[actbl] = TRUE;
+ }
+ }
+}
+
+
+#endif /* ENTROPY_OPT_SUPPORTED */
+
+
+/*
+ * Module initialization routine for Huffman entropy encoding.
+ */
+
+GLOBAL(void)
+jinit_huff_encoder (j_compress_ptr cinfo)
+{
+ huff_entropy_ptr entropy;
+ int i;
+
+ entropy = (huff_entropy_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(huff_entropy_encoder));
+ cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
+ entropy->pub.start_pass = start_pass_huff;
+
+ /* Mark tables unallocated */
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
+#ifdef ENTROPY_OPT_SUPPORTED
+ entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL;
+#endif
+ }
+}
diff --git a/src/libjpeg-turbo/jchuff.h b/src/libjpeg-turbo/jchuff.h
new file mode 100644
index 0000000..a9599fc
--- /dev/null
+++ b/src/libjpeg-turbo/jchuff.h
@@ -0,0 +1,47 @@
+/*
+ * jchuff.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains declarations for Huffman entropy encoding routines
+ * that are shared between the sequential encoder (jchuff.c) and the
+ * progressive encoder (jcphuff.c). No other modules need to see these.
+ */
+
+/* The legal range of a DCT coefficient is
+ * -1024 .. +1023 for 8-bit data;
+ * -16384 .. +16383 for 12-bit data.
+ * Hence the magnitude should always fit in 10 or 14 bits respectively.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MAX_COEF_BITS 10
+#else
+#define MAX_COEF_BITS 14
+#endif
+
+/* Derived data constructed for each Huffman table */
+
+typedef struct {
+ unsigned int ehufco[256]; /* code for each symbol */
+ char ehufsi[256]; /* length of code for each symbol */
+ /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
+} c_derived_tbl;
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_make_c_derived_tbl jMkCDerived
+#define jpeg_gen_optimal_table jGenOptTbl
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+/* Expand a Huffman table definition into the derived format */
+EXTERN(void) jpeg_make_c_derived_tbl
+ JPP((j_compress_ptr cinfo, boolean isDC, int tblno,
+ c_derived_tbl ** pdtbl));
+
+/* Generate an optimal table definition given the specified counts */
+EXTERN(void) jpeg_gen_optimal_table
+ JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));
diff --git a/src/libjpeg-turbo/jcinit.c b/src/libjpeg-turbo/jcinit.c
new file mode 100644
index 0000000..de0ade2
--- /dev/null
+++ b/src/libjpeg-turbo/jcinit.c
@@ -0,0 +1,76 @@
+/*
+ * jcinit.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains initialization logic for the JPEG compressor.
+ * This routine is in charge of selecting the modules to be executed and
+ * making an initialization call to each one.
+ *
+ * Logically, this code belongs in jcmaster.c. It's split out because
+ * linking this routine implies linking the entire compression library.
+ * For a transcoding-only application, we want to be able to use jcmaster.c
+ * without linking in the whole library.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Master selection of compression modules.
+ * This is done once at the start of processing an image. We determine
+ * which modules will be used and give them appropriate initialization calls.
+ */
+
+GLOBAL(void)
+jinit_compress_master (j_compress_ptr cinfo)
+{
+ /* Initialize master control (includes parameter checking/processing) */
+ jinit_c_master_control(cinfo, FALSE /* full compression */);
+
+ /* Preprocessing */
+ if (! cinfo->raw_data_in) {
+ jinit_color_converter(cinfo);
+ jinit_downsampler(cinfo);
+ jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
+ }
+ /* Forward DCT */
+ jinit_forward_dct(cinfo);
+ /* Entropy encoding: either Huffman or arithmetic coding. */
+ if (cinfo->arith_code) {
+#ifdef C_ARITH_CODING_SUPPORTED
+ jinit_arith_encoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+#endif
+ } else {
+ if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+ jinit_phuff_encoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else
+ jinit_huff_encoder(cinfo);
+ }
+
+ /* Need a full-image coefficient buffer in any multi-pass mode. */
+ jinit_c_coef_controller(cinfo,
+ (boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
+ jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
+
+ jinit_marker_writer(cinfo);
+
+ /* We can now tell the memory manager to allocate virtual arrays. */
+ (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+ /* Write the datastream header (SOI) immediately.
+ * Frame and scan headers are postponed till later.
+ * This lets application insert special markers after the SOI.
+ */
+ (*cinfo->marker->write_file_header) (cinfo);
+}
diff --git a/src/libjpeg-turbo/jcmainct.c b/src/libjpeg-turbo/jcmainct.c
new file mode 100644
index 0000000..bd0051a
--- /dev/null
+++ b/src/libjpeg-turbo/jcmainct.c
@@ -0,0 +1,293 @@
+/*
+ * jcmainct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the main buffer controller for compression.
+ * The main buffer lies between the pre-processor and the JPEG
+ * compressor proper; it holds downsampled data in the JPEG colorspace.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Note: currently, there is no operating mode in which a full-image buffer
+ * is needed at this step. If there were, that mode could not be used with
+ * "raw data" input, since this module is bypassed in that case. However,
+ * we've left the code here for possible use in special applications.
+ */
+#undef FULL_MAIN_BUFFER_SUPPORTED
+
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_c_main_controller pub; /* public fields */
+
+ JDIMENSION cur_iMCU_row; /* number of current iMCU row */
+ JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */
+ boolean suspended; /* remember if we suspended output */
+ J_BUF_MODE pass_mode; /* current operating mode */
+
+ /* If using just a strip buffer, this points to the entire set of buffers
+ * (we allocate one for each component). In the full-image case, this
+ * points to the currently accessible strips of the virtual arrays.
+ */
+ JSAMPARRAY buffer[MAX_COMPONENTS];
+
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+ /* If using full-image storage, this array holds pointers to virtual-array
+ * control blocks for each component. Unused if not full-image storage.
+ */
+ jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
+#endif
+} my_main_controller;
+
+typedef my_main_controller * my_main_ptr;
+
+
+/* Forward declarations */
+METHODDEF(void) process_data_simple_main
+ JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
+ JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+METHODDEF(void) process_data_buffer_main
+ JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
+ JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
+#endif
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
+
+ /* Do nothing in raw-data mode. */
+ if (cinfo->raw_data_in)
+ return;
+
+ main_ptr->cur_iMCU_row = 0; /* initialize counters */
+ main_ptr->rowgroup_ctr = 0;
+ main_ptr->suspended = FALSE;
+ main_ptr->pass_mode = pass_mode; /* save mode for use by process_data */
+
+ switch (pass_mode) {
+ case JBUF_PASS_THRU:
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+ if (main_ptr->whole_image[0] != NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif
+ main_ptr->pub.process_data = process_data_simple_main;
+ break;
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+ case JBUF_SAVE_SOURCE:
+ case JBUF_CRANK_DEST:
+ case JBUF_SAVE_AND_PASS:
+ if (main_ptr->whole_image[0] == NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ main_ptr->pub.process_data = process_data_buffer_main;
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ break;
+ }
+}
+
+
+/*
+ * Process some data.
+ * This routine handles the simple pass-through mode,
+ * where we have only a strip buffer.
+ */
+
+METHODDEF(void)
+process_data_simple_main (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail)
+{
+ my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
+
+ while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
+ /* Read input data if we haven't filled the main buffer yet */
+ if (main_ptr->rowgroup_ctr < DCTSIZE)
+ (*cinfo->prep->pre_process_data) (cinfo,
+ input_buf, in_row_ctr, in_rows_avail,
+ main_ptr->buffer, &main_ptr->rowgroup_ctr,
+ (JDIMENSION) DCTSIZE);
+
+ /* If we don't have a full iMCU row buffered, return to application for
+ * more data. Note that preprocessor will always pad to fill the iMCU row
+ * at the bottom of the image.
+ */
+ if (main_ptr->rowgroup_ctr != DCTSIZE)
+ return;
+
+ /* Send the completed row to the compressor */
+ if (! (*cinfo->coef->compress_data) (cinfo, main_ptr->buffer)) {
+ /* If compressor did not consume the whole row, then we must need to
+ * suspend processing and return to the application. In this situation
+ * we pretend we didn't yet consume the last input row; otherwise, if
+ * it happened to be the last row of the image, the application would
+ * think we were done.
+ */
+ if (! main_ptr->suspended) {
+ (*in_row_ctr)--;
+ main_ptr->suspended = TRUE;
+ }
+ return;
+ }
+ /* We did finish the row. Undo our little suspension hack if a previous
+ * call suspended; then mark the main buffer empty.
+ */
+ if (main_ptr->suspended) {
+ (*in_row_ctr)++;
+ main_ptr->suspended = FALSE;
+ }
+ main_ptr->rowgroup_ctr = 0;
+ main_ptr->cur_iMCU_row++;
+ }
+}
+
+
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+
+/*
+ * Process some data.
+ * This routine handles all of the modes that use a full-size buffer.
+ */
+
+METHODDEF(void)
+process_data_buffer_main (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail)
+{
+ my_main_ptr main = (my_main_ptr) cinfo->main;
+ int ci;
+ jpeg_component_info *compptr;
+ boolean writing = (main_ptr->pass_mode != JBUF_CRANK_DEST);
+
+ while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
+ /* Realign the virtual buffers if at the start of an iMCU row. */
+ if (main_ptr->rowgroup_ctr == 0) {
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ main_ptr->buffer[ci] = (*cinfo->mem->access_virt_sarray)
+ ((j_common_ptr) cinfo, main_ptr->whole_image[ci],
+ main_ptr->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
+ (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
+ }
+ /* In a read pass, pretend we just read some source data. */
+ if (! writing) {
+ *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
+ main_ptr->rowgroup_ctr = DCTSIZE;
+ }
+ }
+
+ /* If a write pass, read input data until the current iMCU row is full. */
+ /* Note: preprocessor will pad if necessary to fill the last iMCU row. */
+ if (writing) {
+ (*cinfo->prep->pre_process_data) (cinfo,
+ input_buf, in_row_ctr, in_rows_avail,
+ main_ptr->buffer, &main_ptr->rowgroup_ctr,
+ (JDIMENSION) DCTSIZE);
+ /* Return to application if we need more data to fill the iMCU row. */
+ if (main_ptr->rowgroup_ctr < DCTSIZE)
+ return;
+ }
+
+ /* Emit data, unless this is a sink-only pass. */
+ if (main_ptr->pass_mode != JBUF_SAVE_SOURCE) {
+ if (! (*cinfo->coef->compress_data) (cinfo, main_ptr->buffer)) {
+ /* If compressor did not consume the whole row, then we must need to
+ * suspend processing and return to the application. In this situation
+ * we pretend we didn't yet consume the last input row; otherwise, if
+ * it happened to be the last row of the image, the application would
+ * think we were done.
+ */
+ if (! main_ptr->suspended) {
+ (*in_row_ctr)--;
+ main_ptr->suspended = TRUE;
+ }
+ return;
+ }
+ /* We did finish the row. Undo our little suspension hack if a previous
+ * call suspended; then mark the main buffer empty.
+ */
+ if (main_ptr->suspended) {
+ (*in_row_ctr)++;
+ main_ptr->suspended = FALSE;
+ }
+ }
+
+ /* If get here, we are done with this iMCU row. Mark buffer empty. */
+ main_ptr->rowgroup_ctr = 0;
+ main_ptr->cur_iMCU_row++;
+ }
+}
+
+#endif /* FULL_MAIN_BUFFER_SUPPORTED */
+
+
+/*
+ * Initialize main buffer controller.
+ */
+
+GLOBAL(void)
+jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
+{
+ my_main_ptr main_ptr;
+ int ci;
+ jpeg_component_info *compptr;
+
+ main_ptr = (my_main_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_main_controller));
+ cinfo->main = (struct jpeg_c_main_controller *) main_ptr;
+ main_ptr->pub.start_pass = start_pass_main;
+
+ /* We don't need to create a buffer in raw-data mode. */
+ if (cinfo->raw_data_in)
+ return;
+
+ /* Create the buffer. It holds downsampled data, so each component
+ * may be of a different size.
+ */
+ if (need_full_buffer) {
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+ /* Allocate a full-image virtual array for each component */
+ /* Note we pad the bottom to a multiple of the iMCU height */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ main_ptr->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
+ compptr->width_in_blocks * DCTSIZE,
+ (JDIMENSION) jround_up((long) compptr->height_in_blocks,
+ (long) compptr->v_samp_factor) * DCTSIZE,
+ (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
+ }
+#else
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif
+ } else {
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+ main_ptr->whole_image[0] = NULL; /* flag for no virtual arrays */
+#endif
+ /* Allocate a strip buffer for each component */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ main_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ compptr->width_in_blocks * DCTSIZE,
+ (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
+ }
+ }
+}
diff --git a/src/libjpeg-turbo/jcmarker.c b/src/libjpeg-turbo/jcmarker.c
new file mode 100644
index 0000000..b1c1e45
--- /dev/null
+++ b/src/libjpeg-turbo/jcmarker.c
@@ -0,0 +1,666 @@
+/*
+ * jcmarker.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * Copyright (C) 2010, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains routines to write JPEG datastream markers.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jpegcomp.h"
+
+
+typedef enum { /* JPEG marker codes */
+ M_SOF0 = 0xc0,
+ M_SOF1 = 0xc1,
+ M_SOF2 = 0xc2,
+ M_SOF3 = 0xc3,
+
+ M_SOF5 = 0xc5,
+ M_SOF6 = 0xc6,
+ M_SOF7 = 0xc7,
+
+ M_JPG = 0xc8,
+ M_SOF9 = 0xc9,
+ M_SOF10 = 0xca,
+ M_SOF11 = 0xcb,
+
+ M_SOF13 = 0xcd,
+ M_SOF14 = 0xce,
+ M_SOF15 = 0xcf,
+
+ M_DHT = 0xc4,
+
+ M_DAC = 0xcc,
+
+ M_RST0 = 0xd0,
+ M_RST1 = 0xd1,
+ M_RST2 = 0xd2,
+ M_RST3 = 0xd3,
+ M_RST4 = 0xd4,
+ M_RST5 = 0xd5,
+ M_RST6 = 0xd6,
+ M_RST7 = 0xd7,
+
+ M_SOI = 0xd8,
+ M_EOI = 0xd9,
+ M_SOS = 0xda,
+ M_DQT = 0xdb,
+ M_DNL = 0xdc,
+ M_DRI = 0xdd,
+ M_DHP = 0xde,
+ M_EXP = 0xdf,
+
+ M_APP0 = 0xe0,
+ M_APP1 = 0xe1,
+ M_APP2 = 0xe2,
+ M_APP3 = 0xe3,
+ M_APP4 = 0xe4,
+ M_APP5 = 0xe5,
+ M_APP6 = 0xe6,
+ M_APP7 = 0xe7,
+ M_APP8 = 0xe8,
+ M_APP9 = 0xe9,
+ M_APP10 = 0xea,
+ M_APP11 = 0xeb,
+ M_APP12 = 0xec,
+ M_APP13 = 0xed,
+ M_APP14 = 0xee,
+ M_APP15 = 0xef,
+
+ M_JPG0 = 0xf0,
+ M_JPG13 = 0xfd,
+ M_COM = 0xfe,
+
+ M_TEM = 0x01,
+
+ M_ERROR = 0x100
+} JPEG_MARKER;
+
+
+/* Private state */
+
+typedef struct {
+ struct jpeg_marker_writer pub; /* public fields */
+
+ unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */
+} my_marker_writer;
+
+typedef my_marker_writer * my_marker_ptr;
+
+
+/*
+ * Basic output routines.
+ *
+ * Note that we do not support suspension while writing a marker.
+ * Therefore, an application using suspension must ensure that there is
+ * enough buffer space for the initial markers (typ. 600-700 bytes) before
+ * calling jpeg_start_compress, and enough space to write the trailing EOI
+ * (a few bytes) before calling jpeg_finish_compress. Multipass compression
+ * modes are not supported at all with suspension, so those two are the only
+ * points where markers will be written.
+ */
+
+LOCAL(void)
+emit_byte (j_compress_ptr cinfo, int val)
+/* Emit a byte */
+{
+ struct jpeg_destination_mgr * dest = cinfo->dest;
+
+ *(dest->next_output_byte)++ = (JOCTET) val;
+ if (--dest->free_in_buffer == 0) {
+ if (! (*dest->empty_output_buffer) (cinfo))
+ ERREXIT(cinfo, JERR_CANT_SUSPEND);
+ }
+}
+
+
+LOCAL(void)
+emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
+/* Emit a marker code */
+{
+ emit_byte(cinfo, 0xFF);
+ emit_byte(cinfo, (int) mark);
+}
+
+
+LOCAL(void)
+emit_2bytes (j_compress_ptr cinfo, int value)
+/* Emit a 2-byte integer; these are always MSB first in JPEG files */
+{
+ emit_byte(cinfo, (value >> 8) & 0xFF);
+ emit_byte(cinfo, value & 0xFF);
+}
+
+
+/*
+ * Routines to write specific marker types.
+ */
+
+LOCAL(int)
+emit_dqt (j_compress_ptr cinfo, int index)
+/* Emit a DQT marker */
+/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
+{
+ JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index];
+ int prec;
+ int i;
+
+ if (qtbl == NULL)
+ ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
+
+ prec = 0;
+ for (i = 0; i < DCTSIZE2; i++) {
+ if (qtbl->quantval[i] > 255)
+ prec = 1;
+ }
+
+ if (! qtbl->sent_table) {
+ emit_marker(cinfo, M_DQT);
+
+ emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
+
+ emit_byte(cinfo, index + (prec<<4));
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ /* The table entries must be emitted in zigzag order. */
+ unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
+ if (prec)
+ emit_byte(cinfo, (int) (qval >> 8));
+ emit_byte(cinfo, (int) (qval & 0xFF));
+ }
+
+ qtbl->sent_table = TRUE;
+ }
+
+ return prec;
+}
+
+
+LOCAL(void)
+emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
+/* Emit a DHT marker */
+{
+ JHUFF_TBL * htbl;
+ int length, i;
+
+ if (is_ac) {
+ htbl = cinfo->ac_huff_tbl_ptrs[index];
+ index += 0x10; /* output index has AC bit set */
+ } else {
+ htbl = cinfo->dc_huff_tbl_ptrs[index];
+ }
+
+ if (htbl == NULL)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index);
+
+ if (! htbl->sent_table) {
+ emit_marker(cinfo, M_DHT);
+
+ length = 0;
+ for (i = 1; i <= 16; i++)
+ length += htbl->bits[i];
+
+ emit_2bytes(cinfo, length + 2 + 1 + 16);
+ emit_byte(cinfo, index);
+
+ for (i = 1; i <= 16; i++)
+ emit_byte(cinfo, htbl->bits[i]);
+
+ for (i = 0; i < length; i++)
+ emit_byte(cinfo, htbl->huffval[i]);
+
+ htbl->sent_table = TRUE;
+ }
+}
+
+
+LOCAL(void)
+emit_dac (j_compress_ptr cinfo)
+/* Emit a DAC marker */
+/* Since the useful info is so small, we want to emit all the tables in */
+/* one DAC marker. Therefore this routine does its own scan of the table. */
+{
+#ifdef C_ARITH_CODING_SUPPORTED
+ char dc_in_use[NUM_ARITH_TBLS];
+ char ac_in_use[NUM_ARITH_TBLS];
+ int length, i;
+ jpeg_component_info *compptr;
+
+ for (i = 0; i < NUM_ARITH_TBLS; i++)
+ dc_in_use[i] = ac_in_use[i] = 0;
+
+ for (i = 0; i < cinfo->comps_in_scan; i++) {
+ compptr = cinfo->cur_comp_info[i];
+ dc_in_use[compptr->dc_tbl_no] = 1;
+ ac_in_use[compptr->ac_tbl_no] = 1;
+ }
+
+ length = 0;
+ for (i = 0; i < NUM_ARITH_TBLS; i++)
+ length += dc_in_use[i] + ac_in_use[i];
+
+ emit_marker(cinfo, M_DAC);
+
+ emit_2bytes(cinfo, length*2 + 2);
+
+ for (i = 0; i < NUM_ARITH_TBLS; i++) {
+ if (dc_in_use[i]) {
+ emit_byte(cinfo, i);
+ emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
+ }
+ if (ac_in_use[i]) {
+ emit_byte(cinfo, i + 0x10);
+ emit_byte(cinfo, cinfo->arith_ac_K[i]);
+ }
+ }
+#endif /* C_ARITH_CODING_SUPPORTED */
+}
+
+
+LOCAL(void)
+emit_dri (j_compress_ptr cinfo)
+/* Emit a DRI marker */
+{
+ emit_marker(cinfo, M_DRI);
+
+ emit_2bytes(cinfo, 4); /* fixed length */
+
+ emit_2bytes(cinfo, (int) cinfo->restart_interval);
+}
+
+
+LOCAL(void)
+emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
+/* Emit a SOF marker */
+{
+ int ci;
+ jpeg_component_info *compptr;
+
+ emit_marker(cinfo, code);
+
+ emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
+
+ /* Make sure image isn't bigger than SOF field can handle */
+ if ((long) cinfo->_jpeg_height > 65535L ||
+ (long) cinfo->_jpeg_width > 65535L)
+ ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
+
+ emit_byte(cinfo, cinfo->data_precision);
+ emit_2bytes(cinfo, (int) cinfo->_jpeg_height);
+ emit_2bytes(cinfo, (int) cinfo->_jpeg_width);
+
+ emit_byte(cinfo, cinfo->num_components);
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ emit_byte(cinfo, compptr->component_id);
+ emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor);
+ emit_byte(cinfo, compptr->quant_tbl_no);
+ }
+}
+
+
+LOCAL(void)
+emit_sos (j_compress_ptr cinfo)
+/* Emit a SOS marker */
+{
+ int i, td, ta;
+ jpeg_component_info *compptr;
+
+ emit_marker(cinfo, M_SOS);
+
+ emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
+
+ emit_byte(cinfo, cinfo->comps_in_scan);
+
+ for (i = 0; i < cinfo->comps_in_scan; i++) {
+ compptr = cinfo->cur_comp_info[i];
+ emit_byte(cinfo, compptr->component_id);
+ td = compptr->dc_tbl_no;
+ ta = compptr->ac_tbl_no;
+ if (cinfo->progressive_mode) {
+ /* Progressive mode: only DC or only AC tables are used in one scan;
+ * furthermore, Huffman coding of DC refinement uses no table at all.
+ * We emit 0 for unused field(s); this is recommended by the P&M text
+ * but does not seem to be specified in the standard.
+ */
+ if (cinfo->Ss == 0) {
+ ta = 0; /* DC scan */
+ if (cinfo->Ah != 0 && !cinfo->arith_code)
+ td = 0; /* no DC table either */
+ } else {
+ td = 0; /* AC scan */
+ }
+ }
+ emit_byte(cinfo, (td << 4) + ta);
+ }
+
+ emit_byte(cinfo, cinfo->Ss);
+ emit_byte(cinfo, cinfo->Se);
+ emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al);
+}
+
+
+LOCAL(void)
+emit_jfif_app0 (j_compress_ptr cinfo)
+/* Emit a JFIF-compliant APP0 marker */
+{
+ /*
+ * Length of APP0 block (2 bytes)
+ * Block ID (4 bytes - ASCII "JFIF")
+ * Zero byte (1 byte to terminate the ID string)
+ * Version Major, Minor (2 bytes - major first)
+ * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
+ * Xdpu (2 bytes - dots per unit horizontal)
+ * Ydpu (2 bytes - dots per unit vertical)
+ * Thumbnail X size (1 byte)
+ * Thumbnail Y size (1 byte)
+ */
+
+ emit_marker(cinfo, M_APP0);
+
+ emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
+
+ emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */
+ emit_byte(cinfo, 0x46);
+ emit_byte(cinfo, 0x49);
+ emit_byte(cinfo, 0x46);
+ emit_byte(cinfo, 0);
+ emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
+ emit_byte(cinfo, cinfo->JFIF_minor_version);
+ emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
+ emit_2bytes(cinfo, (int) cinfo->X_density);
+ emit_2bytes(cinfo, (int) cinfo->Y_density);
+ emit_byte(cinfo, 0); /* No thumbnail image */
+ emit_byte(cinfo, 0);
+}
+
+
+LOCAL(void)
+emit_adobe_app14 (j_compress_ptr cinfo)
+/* Emit an Adobe APP14 marker */
+{
+ /*
+ * Length of APP14 block (2 bytes)
+ * Block ID (5 bytes - ASCII "Adobe")
+ * Version Number (2 bytes - currently 100)
+ * Flags0 (2 bytes - currently 0)
+ * Flags1 (2 bytes - currently 0)
+ * Color transform (1 byte)
+ *
+ * Although Adobe TN 5116 mentions Version = 101, all the Adobe files
+ * now in circulation seem to use Version = 100, so that's what we write.
+ *
+ * We write the color transform byte as 1 if the JPEG color space is
+ * YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with
+ * whether the encoder performed a transformation, which is pretty useless.
+ */
+
+ emit_marker(cinfo, M_APP14);
+
+ emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */
+
+ emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */
+ emit_byte(cinfo, 0x64);
+ emit_byte(cinfo, 0x6F);
+ emit_byte(cinfo, 0x62);
+ emit_byte(cinfo, 0x65);
+ emit_2bytes(cinfo, 100); /* Version */
+ emit_2bytes(cinfo, 0); /* Flags0 */
+ emit_2bytes(cinfo, 0); /* Flags1 */
+ switch (cinfo->jpeg_color_space) {
+ case JCS_YCbCr:
+ emit_byte(cinfo, 1); /* Color transform = 1 */
+ break;
+ case JCS_YCCK:
+ emit_byte(cinfo, 2); /* Color transform = 2 */
+ break;
+ default:
+ emit_byte(cinfo, 0); /* Color transform = 0 */
+ break;
+ }
+}
+
+
+/*
+ * These routines allow writing an arbitrary marker with parameters.
+ * The only intended use is to emit COM or APPn markers after calling
+ * write_file_header and before calling write_frame_header.
+ * Other uses are not guaranteed to produce desirable results.
+ * Counting the parameter bytes properly is the caller's responsibility.
+ */
+
+METHODDEF(void)
+write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
+/* Emit an arbitrary marker header */
+{
+ if (datalen > (unsigned int) 65533) /* safety check */
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ emit_marker(cinfo, (JPEG_MARKER) marker);
+
+ emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */
+}
+
+METHODDEF(void)
+write_marker_byte (j_compress_ptr cinfo, int val)
+/* Emit one byte of marker parameters following write_marker_header */
+{
+ emit_byte(cinfo, val);
+}
+
+
+/*
+ * Write datastream header.
+ * This consists of an SOI and optional APPn markers.
+ * We recommend use of the JFIF marker, but not the Adobe marker,
+ * when using YCbCr or grayscale data. The JFIF marker should NOT
+ * be used for any other JPEG colorspace. The Adobe marker is helpful
+ * to distinguish RGB, CMYK, and YCCK colorspaces.
+ * Note that an application can write additional header markers after
+ * jpeg_start_compress returns.
+ */
+
+METHODDEF(void)
+write_file_header (j_compress_ptr cinfo)
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
+ emit_marker(cinfo, M_SOI); /* first the SOI */
+
+ /* SOI is defined to reset restart interval to 0 */
+ marker->last_restart_interval = 0;
+
+ if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
+ emit_jfif_app0(cinfo);
+ if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
+ emit_adobe_app14(cinfo);
+}
+
+
+/*
+ * Write frame header.
+ * This consists of DQT and SOFn markers.
+ * Note that we do not emit the SOF until we have emitted the DQT(s).
+ * This avoids compatibility problems with incorrect implementations that
+ * try to error-check the quant table numbers as soon as they see the SOF.
+ */
+
+METHODDEF(void)
+write_frame_header (j_compress_ptr cinfo)
+{
+ int ci, prec;
+ boolean is_baseline;
+ jpeg_component_info *compptr;
+
+ /* Emit DQT for each quantization table.
+ * Note that emit_dqt() suppresses any duplicate tables.
+ */
+ prec = 0;
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ prec += emit_dqt(cinfo, compptr->quant_tbl_no);
+ }
+ /* now prec is nonzero iff there are any 16-bit quant tables. */
+
+ /* Check for a non-baseline specification.
+ * Note we assume that Huffman table numbers won't be changed later.
+ */
+ if (cinfo->arith_code || cinfo->progressive_mode ||
+ cinfo->data_precision != 8) {
+ is_baseline = FALSE;
+ } else {
+ is_baseline = TRUE;
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1)
+ is_baseline = FALSE;
+ }
+ if (prec && is_baseline) {
+ is_baseline = FALSE;
+ /* If it's baseline except for quantizer size, warn the user */
+ TRACEMS(cinfo, 0, JTRC_16BIT_TABLES);
+ }
+ }
+
+ /* Emit the proper SOF marker */
+ if (cinfo->arith_code) {
+ emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */
+ } else {
+ if (cinfo->progressive_mode)
+ emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */
+ else if (is_baseline)
+ emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */
+ else
+ emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */
+ }
+}
+
+
+/*
+ * Write scan header.
+ * This consists of DHT or DAC markers, optional DRI, and SOS.
+ * Compressed data will be written following the SOS.
+ */
+
+METHODDEF(void)
+write_scan_header (j_compress_ptr cinfo)
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+ int i;
+ jpeg_component_info *compptr;
+
+ if (cinfo->arith_code) {
+ /* Emit arith conditioning info. We may have some duplication
+ * if the file has multiple scans, but it's so small it's hardly
+ * worth worrying about.
+ */
+ emit_dac(cinfo);
+ } else {
+ /* Emit Huffman tables.
+ * Note that emit_dht() suppresses any duplicate tables.
+ */
+ for (i = 0; i < cinfo->comps_in_scan; i++) {
+ compptr = cinfo->cur_comp_info[i];
+ if (cinfo->progressive_mode) {
+ /* Progressive mode: only DC or only AC tables are used in one scan */
+ if (cinfo->Ss == 0) {
+ if (cinfo->Ah == 0) /* DC needs no table for refinement scan */
+ emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
+ } else {
+ emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
+ }
+ } else {
+ /* Sequential mode: need both DC and AC tables */
+ emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
+ emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
+ }
+ }
+ }
+
+ /* Emit DRI if required --- note that DRI value could change for each scan.
+ * We avoid wasting space with unnecessary DRIs, however.
+ */
+ if (cinfo->restart_interval != marker->last_restart_interval) {
+ emit_dri(cinfo);
+ marker->last_restart_interval = cinfo->restart_interval;
+ }
+
+ emit_sos(cinfo);
+}
+
+
+/*
+ * Write datastream trailer.
+ */
+
+METHODDEF(void)
+write_file_trailer (j_compress_ptr cinfo)
+{
+ emit_marker(cinfo, M_EOI);
+}
+
+
+/*
+ * Write an abbreviated table-specification datastream.
+ * This consists of SOI, DQT and DHT tables, and EOI.
+ * Any table that is defined and not marked sent_table = TRUE will be
+ * emitted. Note that all tables will be marked sent_table = TRUE at exit.
+ */
+
+METHODDEF(void)
+write_tables_only (j_compress_ptr cinfo)
+{
+ int i;
+
+ emit_marker(cinfo, M_SOI);
+
+ for (i = 0; i < NUM_QUANT_TBLS; i++) {
+ if (cinfo->quant_tbl_ptrs[i] != NULL)
+ (void) emit_dqt(cinfo, i);
+ }
+
+ if (! cinfo->arith_code) {
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ if (cinfo->dc_huff_tbl_ptrs[i] != NULL)
+ emit_dht(cinfo, i, FALSE);
+ if (cinfo->ac_huff_tbl_ptrs[i] != NULL)
+ emit_dht(cinfo, i, TRUE);
+ }
+ }
+
+ emit_marker(cinfo, M_EOI);
+}
+
+
+/*
+ * Initialize the marker writer module.
+ */
+
+GLOBAL(void)
+jinit_marker_writer (j_compress_ptr cinfo)
+{
+ my_marker_ptr marker;
+
+ /* Create the subobject */
+ marker = (my_marker_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_marker_writer));
+ cinfo->marker = (struct jpeg_marker_writer *) marker;
+ /* Initialize method pointers */
+ marker->pub.write_file_header = write_file_header;
+ marker->pub.write_frame_header = write_frame_header;
+ marker->pub.write_scan_header = write_scan_header;
+ marker->pub.write_file_trailer = write_file_trailer;
+ marker->pub.write_tables_only = write_tables_only;
+ marker->pub.write_marker_header = write_marker_header;
+ marker->pub.write_marker_byte = write_marker_byte;
+ /* Initialize private state */
+ marker->last_restart_interval = 0;
+}
diff --git a/src/libjpeg-turbo/jcmaster.c b/src/libjpeg-turbo/jcmaster.c
new file mode 100644
index 0000000..3ca346c
--- /dev/null
+++ b/src/libjpeg-turbo/jcmaster.c
@@ -0,0 +1,624 @@
+/*
+ * jcmaster.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Modified 2003-2010 by Guido Vollbeding.
+ * Copyright (C) 2010, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains master control logic for the JPEG compressor.
+ * These routines are concerned with parameter validation, initial setup,
+ * and inter-pass control (determining the number of passes and the work
+ * to be done in each pass).
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jpegcomp.h"
+
+
+/* Private state */
+
+typedef enum {
+ main_pass, /* input data, also do first output step */
+ huff_opt_pass, /* Huffman code optimization pass */
+ output_pass /* data output pass */
+} c_pass_type;
+
+typedef struct {
+ struct jpeg_comp_master pub; /* public fields */
+
+ c_pass_type pass_type; /* the type of the current pass */
+
+ int pass_number; /* # of passes completed */
+ int total_passes; /* total # of passes needed */
+
+ int scan_number; /* current index in scan_info[] */
+} my_comp_master;
+
+typedef my_comp_master * my_master_ptr;
+
+
+/*
+ * Support routines that do various essential calculations.
+ */
+
+#if JPEG_LIB_VERSION >= 70
+/*
+ * Compute JPEG image dimensions and related values.
+ * NOTE: this is exported for possible use by application.
+ * Hence it mustn't do anything that can't be done twice.
+ */
+
+GLOBAL(void)
+jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo)
+/* Do computations that are needed before master selection phase */
+{
+ /* Hardwire it to "no scaling" */
+ cinfo->jpeg_width = cinfo->image_width;
+ cinfo->jpeg_height = cinfo->image_height;
+ cinfo->min_DCT_h_scaled_size = DCTSIZE;
+ cinfo->min_DCT_v_scaled_size = DCTSIZE;
+}
+#endif
+
+
+LOCAL(void)
+initial_setup (j_compress_ptr cinfo, boolean transcode_only)
+/* Do computations that are needed before master selection phase */
+{
+ int ci;
+ jpeg_component_info *compptr;
+ long samplesperrow;
+ JDIMENSION jd_samplesperrow;
+
+#if JPEG_LIB_VERSION >= 70
+#if JPEG_LIB_VERSION >= 80
+ if (!transcode_only)
+#endif
+ jpeg_calc_jpeg_dimensions(cinfo);
+#endif
+
+ /* Sanity check on image dimensions */
+ if (cinfo->_jpeg_height <= 0 || cinfo->_jpeg_width <= 0
+ || cinfo->num_components <= 0 || cinfo->input_components <= 0)
+ ERREXIT(cinfo, JERR_EMPTY_IMAGE);
+
+ /* Make sure image isn't bigger than I can handle */
+ if ((long) cinfo->_jpeg_height > (long) JPEG_MAX_DIMENSION ||
+ (long) cinfo->_jpeg_width > (long) JPEG_MAX_DIMENSION)
+ ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
+
+ /* Width of an input scanline must be representable as JDIMENSION. */
+ samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components;
+ jd_samplesperrow = (JDIMENSION) samplesperrow;
+ if ((long) jd_samplesperrow != samplesperrow)
+ ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+
+ /* For now, precision must match compiled-in value... */
+ if (cinfo->data_precision != BITS_IN_JSAMPLE)
+ ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
+
+ /* Check that number of components won't exceed internal array sizes */
+ if (cinfo->num_components > MAX_COMPONENTS)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+ MAX_COMPONENTS);
+
+ /* Compute maximum sampling factors; check factor validity */
+ cinfo->max_h_samp_factor = 1;
+ cinfo->max_v_samp_factor = 1;
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
+ compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
+ ERREXIT(cinfo, JERR_BAD_SAMPLING);
+ cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
+ compptr->h_samp_factor);
+ cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
+ compptr->v_samp_factor);
+ }
+
+ /* Compute dimensions of components */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Fill in the correct component_index value; don't rely on application */
+ compptr->component_index = ci;
+ /* For compression, we never do DCT scaling. */
+#if JPEG_LIB_VERSION >= 70
+ compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = DCTSIZE;
+#else
+ compptr->DCT_scaled_size = DCTSIZE;
+#endif
+ /* Size in DCT blocks */
+ compptr->width_in_blocks = (JDIMENSION)
+ jdiv_round_up((long) cinfo->_jpeg_width * (long) compptr->h_samp_factor,
+ (long) (cinfo->max_h_samp_factor * DCTSIZE));
+ compptr->height_in_blocks = (JDIMENSION)
+ jdiv_round_up((long) cinfo->_jpeg_height * (long) compptr->v_samp_factor,
+ (long) (cinfo->max_v_samp_factor * DCTSIZE));
+ /* Size in samples */
+ compptr->downsampled_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->_jpeg_width * (long) compptr->h_samp_factor,
+ (long) cinfo->max_h_samp_factor);
+ compptr->downsampled_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->_jpeg_height * (long) compptr->v_samp_factor,
+ (long) cinfo->max_v_samp_factor);
+ /* Mark component needed (this flag isn't actually used for compression) */
+ compptr->component_needed = TRUE;
+ }
+
+ /* Compute number of fully interleaved MCU rows (number of times that
+ * main controller will call coefficient controller).
+ */
+ cinfo->total_iMCU_rows = (JDIMENSION)
+ jdiv_round_up((long) cinfo->_jpeg_height,
+ (long) (cinfo->max_v_samp_factor*DCTSIZE));
+}
+
+
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+
+LOCAL(void)
+validate_script (j_compress_ptr cinfo)
+/* Verify that the scan script in cinfo->scan_info[] is valid; also
+ * determine whether it uses progressive JPEG, and set cinfo->progressive_mode.
+ */
+{
+ const jpeg_scan_info * scanptr;
+ int scanno, ncomps, ci, coefi, thisi;
+ int Ss, Se, Ah, Al;
+ boolean component_sent[MAX_COMPONENTS];
+#ifdef C_PROGRESSIVE_SUPPORTED
+ int * last_bitpos_ptr;
+ int last_bitpos[MAX_COMPONENTS][DCTSIZE2];
+ /* -1 until that coefficient has been seen; then last Al for it */
+#endif
+
+ if (cinfo->num_scans <= 0)
+ ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
+
+ /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1;
+ * for progressive JPEG, no scan can have this.
+ */
+ scanptr = cinfo->scan_info;
+ if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+ cinfo->progressive_mode = TRUE;
+ last_bitpos_ptr = & last_bitpos[0][0];
+ for (ci = 0; ci < cinfo->num_components; ci++)
+ for (coefi = 0; coefi < DCTSIZE2; coefi++)
+ *last_bitpos_ptr++ = -1;
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ cinfo->progressive_mode = FALSE;
+ for (ci = 0; ci < cinfo->num_components; ci++)
+ component_sent[ci] = FALSE;
+ }
+
+ for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) {
+ /* Validate component indexes */
+ ncomps = scanptr->comps_in_scan;
+ if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN);
+ for (ci = 0; ci < ncomps; ci++) {
+ thisi = scanptr->component_index[ci];
+ if (thisi < 0 || thisi >= cinfo->num_components)
+ ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
+ /* Components must appear in SOF order within each scan */
+ if (ci > 0 && thisi <= scanptr->component_index[ci-1])
+ ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
+ }
+ /* Validate progression parameters */
+ Ss = scanptr->Ss;
+ Se = scanptr->Se;
+ Ah = scanptr->Ah;
+ Al = scanptr->Al;
+ if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+ /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
+ * seems wrong: the upper bound ought to depend on data precision.
+ * Perhaps they really meant 0..N+1 for N-bit precision.
+ * Here we allow 0..10 for 8-bit data; Al larger than 10 results in
+ * out-of-range reconstructed DC values during the first DC scan,
+ * which might cause problems for some decoders.
+ */
+#if BITS_IN_JSAMPLE == 8
+#define MAX_AH_AL 10
+#else
+#define MAX_AH_AL 13
+#endif
+ if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
+ Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ if (Ss == 0) {
+ if (Se != 0) /* DC and AC together not OK */
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ } else {
+ if (ncomps != 1) /* AC scans must be for only one component */
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ }
+ for (ci = 0; ci < ncomps; ci++) {
+ last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0];
+ if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ for (coefi = Ss; coefi <= Se; coefi++) {
+ if (last_bitpos_ptr[coefi] < 0) {
+ /* first scan of this coefficient */
+ if (Ah != 0)
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ } else {
+ /* not first scan */
+ if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1)
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ }
+ last_bitpos_ptr[coefi] = Al;
+ }
+ }
+#endif
+ } else {
+ /* For sequential JPEG, all progression parameters must be these: */
+ if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0)
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ /* Make sure components are not sent twice */
+ for (ci = 0; ci < ncomps; ci++) {
+ thisi = scanptr->component_index[ci];
+ if (component_sent[thisi])
+ ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
+ component_sent[thisi] = TRUE;
+ }
+ }
+ }
+
+ /* Now verify that everything got sent. */
+ if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+ /* For progressive mode, we only check that at least some DC data
+ * got sent for each component; the spec does not require that all bits
+ * of all coefficients be transmitted. Would it be wiser to enforce
+ * transmission of all coefficient bits??
+ */
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ if (last_bitpos[ci][0] < 0)
+ ERREXIT(cinfo, JERR_MISSING_DATA);
+ }
+#endif
+ } else {
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ if (! component_sent[ci])
+ ERREXIT(cinfo, JERR_MISSING_DATA);
+ }
+ }
+}
+
+#endif /* C_MULTISCAN_FILES_SUPPORTED */
+
+
+LOCAL(void)
+select_scan_parameters (j_compress_ptr cinfo)
+/* Set up the scan parameters for the current scan */
+{
+ int ci;
+
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+ if (cinfo->scan_info != NULL) {
+ /* Prepare for current scan --- the script is already validated */
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+ const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number;
+
+ cinfo->comps_in_scan = scanptr->comps_in_scan;
+ for (ci = 0; ci < scanptr->comps_in_scan; ci++) {
+ cinfo->cur_comp_info[ci] =
+ &cinfo->comp_info[scanptr->component_index[ci]];
+ }
+ cinfo->Ss = scanptr->Ss;
+ cinfo->Se = scanptr->Se;
+ cinfo->Ah = scanptr->Ah;
+ cinfo->Al = scanptr->Al;
+ }
+ else
+#endif
+ {
+ /* Prepare for single sequential-JPEG scan containing all components */
+ if (cinfo->num_components > MAX_COMPS_IN_SCAN)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+ MAX_COMPS_IN_SCAN);
+ cinfo->comps_in_scan = cinfo->num_components;
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
+ }
+ cinfo->Ss = 0;
+ cinfo->Se = DCTSIZE2-1;
+ cinfo->Ah = 0;
+ cinfo->Al = 0;
+ }
+}
+
+
+LOCAL(void)
+per_scan_setup (j_compress_ptr cinfo)
+/* Do computations that are needed before processing a JPEG scan */
+/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */
+{
+ int ci, mcublks, tmp;
+ jpeg_component_info *compptr;
+
+ if (cinfo->comps_in_scan == 1) {
+
+ /* Noninterleaved (single-component) scan */
+ compptr = cinfo->cur_comp_info[0];
+
+ /* Overall image size in MCUs */
+ cinfo->MCUs_per_row = compptr->width_in_blocks;
+ cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
+
+ /* For noninterleaved scan, always one block per MCU */
+ compptr->MCU_width = 1;
+ compptr->MCU_height = 1;
+ compptr->MCU_blocks = 1;
+ compptr->MCU_sample_width = DCTSIZE;
+ compptr->last_col_width = 1;
+ /* For noninterleaved scans, it is convenient to define last_row_height
+ * as the number of block rows present in the last iMCU row.
+ */
+ tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+ if (tmp == 0) tmp = compptr->v_samp_factor;
+ compptr->last_row_height = tmp;
+
+ /* Prepare array describing MCU composition */
+ cinfo->blocks_in_MCU = 1;
+ cinfo->MCU_membership[0] = 0;
+
+ } else {
+
+ /* Interleaved (multi-component) scan */
+ if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
+ MAX_COMPS_IN_SCAN);
+
+ /* Overall image size in MCUs */
+ cinfo->MCUs_per_row = (JDIMENSION)
+ jdiv_round_up((long) cinfo->_jpeg_width,
+ (long) (cinfo->max_h_samp_factor*DCTSIZE));
+ cinfo->MCU_rows_in_scan = (JDIMENSION)
+ jdiv_round_up((long) cinfo->_jpeg_height,
+ (long) (cinfo->max_v_samp_factor*DCTSIZE));
+
+ cinfo->blocks_in_MCU = 0;
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* Sampling factors give # of blocks of component in each MCU */
+ compptr->MCU_width = compptr->h_samp_factor;
+ compptr->MCU_height = compptr->v_samp_factor;
+ compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
+ compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE;
+ /* Figure number of non-dummy blocks in last MCU column & row */
+ tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
+ if (tmp == 0) tmp = compptr->MCU_width;
+ compptr->last_col_width = tmp;
+ tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
+ if (tmp == 0) tmp = compptr->MCU_height;
+ compptr->last_row_height = tmp;
+ /* Prepare array describing MCU composition */
+ mcublks = compptr->MCU_blocks;
+ if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU)
+ ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
+ while (mcublks-- > 0) {
+ cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
+ }
+ }
+
+ }
+
+ /* Convert restart specified in rows to actual MCU count. */
+ /* Note that count must fit in 16 bits, so we provide limiting. */
+ if (cinfo->restart_in_rows > 0) {
+ long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row;
+ cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L);
+ }
+}
+
+
+/*
+ * Per-pass setup.
+ * This is called at the beginning of each pass. We determine which modules
+ * will be active during this pass and give them appropriate start_pass calls.
+ * We also set is_last_pass to indicate whether any more passes will be
+ * required.
+ */
+
+METHODDEF(void)
+prepare_for_pass (j_compress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+
+ switch (master->pass_type) {
+ case main_pass:
+ /* Initial pass: will collect input data, and do either Huffman
+ * optimization or data output for the first scan.
+ */
+ select_scan_parameters(cinfo);
+ per_scan_setup(cinfo);
+ if (! cinfo->raw_data_in) {
+ (*cinfo->cconvert->start_pass) (cinfo);
+ (*cinfo->downsample->start_pass) (cinfo);
+ (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU);
+ }
+ (*cinfo->fdct->start_pass) (cinfo);
+ (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding);
+ (*cinfo->coef->start_pass) (cinfo,
+ (master->total_passes > 1 ?
+ JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
+ (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
+ if (cinfo->optimize_coding) {
+ /* No immediate data output; postpone writing frame/scan headers */
+ master->pub.call_pass_startup = FALSE;
+ } else {
+ /* Will write frame/scan headers at first jpeg_write_scanlines call */
+ master->pub.call_pass_startup = TRUE;
+ }
+ break;
+#ifdef ENTROPY_OPT_SUPPORTED
+ case huff_opt_pass:
+ /* Do Huffman optimization for a scan after the first one. */
+ select_scan_parameters(cinfo);
+ per_scan_setup(cinfo);
+ if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) {
+ (*cinfo->entropy->start_pass) (cinfo, TRUE);
+ (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
+ master->pub.call_pass_startup = FALSE;
+ break;
+ }
+ /* Special case: Huffman DC refinement scans need no Huffman table
+ * and therefore we can skip the optimization pass for them.
+ */
+ master->pass_type = output_pass;
+ master->pass_number++;
+ /*FALLTHROUGH*/
+#endif
+ case output_pass:
+ /* Do a data-output pass. */
+ /* We need not repeat per-scan setup if prior optimization pass did it. */
+ if (! cinfo->optimize_coding) {
+ select_scan_parameters(cinfo);
+ per_scan_setup(cinfo);
+ }
+ (*cinfo->entropy->start_pass) (cinfo, FALSE);
+ (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
+ /* We emit frame/scan headers now */
+ if (master->scan_number == 0)
+ (*cinfo->marker->write_frame_header) (cinfo);
+ (*cinfo->marker->write_scan_header) (cinfo);
+ master->pub.call_pass_startup = FALSE;
+ break;
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ }
+
+ master->pub.is_last_pass = (master->pass_number == master->total_passes-1);
+
+ /* Set up progress monitor's pass info if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->completed_passes = master->pass_number;
+ cinfo->progress->total_passes = master->total_passes;
+ }
+}
+
+
+/*
+ * Special start-of-pass hook.
+ * This is called by jpeg_write_scanlines if call_pass_startup is TRUE.
+ * In single-pass processing, we need this hook because we don't want to
+ * write frame/scan headers during jpeg_start_compress; we want to let the
+ * application write COM markers etc. between jpeg_start_compress and the
+ * jpeg_write_scanlines loop.
+ * In multi-pass processing, this routine is not used.
+ */
+
+METHODDEF(void)
+pass_startup (j_compress_ptr cinfo)
+{
+ cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */
+
+ (*cinfo->marker->write_frame_header) (cinfo);
+ (*cinfo->marker->write_scan_header) (cinfo);
+}
+
+
+/*
+ * Finish up at end of pass.
+ */
+
+METHODDEF(void)
+finish_pass_master (j_compress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+
+ /* The entropy coder always needs an end-of-pass call,
+ * either to analyze statistics or to flush its output buffer.
+ */
+ (*cinfo->entropy->finish_pass) (cinfo);
+
+ /* Update state for next pass */
+ switch (master->pass_type) {
+ case main_pass:
+ /* next pass is either output of scan 0 (after optimization)
+ * or output of scan 1 (if no optimization).
+ */
+ master->pass_type = output_pass;
+ if (! cinfo->optimize_coding)
+ master->scan_number++;
+ break;
+ case huff_opt_pass:
+ /* next pass is always output of current scan */
+ master->pass_type = output_pass;
+ break;
+ case output_pass:
+ /* next pass is either optimization or output of next scan */
+ if (cinfo->optimize_coding)
+ master->pass_type = huff_opt_pass;
+ master->scan_number++;
+ break;
+ }
+
+ master->pass_number++;
+}
+
+
+/*
+ * Initialize master compression control.
+ */
+
+GLOBAL(void)
+jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
+{
+ my_master_ptr master;
+
+ master = (my_master_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_comp_master));
+ cinfo->master = (struct jpeg_comp_master *) master;
+ master->pub.prepare_for_pass = prepare_for_pass;
+ master->pub.pass_startup = pass_startup;
+ master->pub.finish_pass = finish_pass_master;
+ master->pub.is_last_pass = FALSE;
+
+ /* Validate parameters, determine derived values */
+ initial_setup(cinfo, transcode_only);
+
+ if (cinfo->scan_info != NULL) {
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+ validate_script(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ cinfo->progressive_mode = FALSE;
+ cinfo->num_scans = 1;
+ }
+
+ if (cinfo->progressive_mode) /* TEMPORARY HACK ??? */
+ cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */
+
+ /* Initialize my private state */
+ if (transcode_only) {
+ /* no main pass in transcoding */
+ if (cinfo->optimize_coding)
+ master->pass_type = huff_opt_pass;
+ else
+ master->pass_type = output_pass;
+ } else {
+ /* for normal compression, first pass is always this type: */
+ master->pass_type = main_pass;
+ }
+ master->scan_number = 0;
+ master->pass_number = 0;
+ if (cinfo->optimize_coding)
+ master->total_passes = cinfo->num_scans * 2;
+ else
+ master->total_passes = cinfo->num_scans;
+}
diff --git a/src/libjpeg-turbo/jcomapi.c b/src/libjpeg-turbo/jcomapi.c
new file mode 100644
index 0000000..9b1fa75
--- /dev/null
+++ b/src/libjpeg-turbo/jcomapi.c
@@ -0,0 +1,106 @@
+/*
+ * jcomapi.c
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains application interface routines that are used for both
+ * compression and decompression.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Abort processing of a JPEG compression or decompression operation,
+ * but don't destroy the object itself.
+ *
+ * For this, we merely clean up all the nonpermanent memory pools.
+ * Note that temp files (virtual arrays) are not allowed to belong to
+ * the permanent pool, so we will be able to close all temp files here.
+ * Closing a data source or destination, if necessary, is the application's
+ * responsibility.
+ */
+
+GLOBAL(void)
+jpeg_abort (j_common_ptr cinfo)
+{
+ int pool;
+
+ /* Do nothing if called on a not-initialized or destroyed JPEG object. */
+ if (cinfo->mem == NULL)
+ return;
+
+ /* Releasing pools in reverse order might help avoid fragmentation
+ * with some (brain-damaged) malloc libraries.
+ */
+ for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) {
+ (*cinfo->mem->free_pool) (cinfo, pool);
+ }
+
+ /* Reset overall state for possible reuse of object */
+ if (cinfo->is_decompressor) {
+ cinfo->global_state = DSTATE_START;
+ /* Try to keep application from accessing now-deleted marker list.
+ * A bit kludgy to do it here, but this is the most central place.
+ */
+ ((j_decompress_ptr) cinfo)->marker_list = NULL;
+ } else {
+ cinfo->global_state = CSTATE_START;
+ }
+}
+
+
+/*
+ * Destruction of a JPEG object.
+ *
+ * Everything gets deallocated except the master jpeg_compress_struct itself
+ * and the error manager struct. Both of these are supplied by the application
+ * and must be freed, if necessary, by the application. (Often they are on
+ * the stack and so don't need to be freed anyway.)
+ * Closing a data source or destination, if necessary, is the application's
+ * responsibility.
+ */
+
+GLOBAL(void)
+jpeg_destroy (j_common_ptr cinfo)
+{
+ /* We need only tell the memory manager to release everything. */
+ /* NB: mem pointer is NULL if memory mgr failed to initialize. */
+ if (cinfo->mem != NULL)
+ (*cinfo->mem->self_destruct) (cinfo);
+ cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */
+ cinfo->global_state = 0; /* mark it destroyed */
+}
+
+
+/*
+ * Convenience routines for allocating quantization and Huffman tables.
+ * (Would jutils.c be a more reasonable place to put these?)
+ */
+
+GLOBAL(JQUANT_TBL *)
+jpeg_alloc_quant_table (j_common_ptr cinfo)
+{
+ JQUANT_TBL *tbl;
+
+ tbl = (JQUANT_TBL *)
+ (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL));
+ tbl->sent_table = FALSE; /* make sure this is false in any new table */
+ return tbl;
+}
+
+
+GLOBAL(JHUFF_TBL *)
+jpeg_alloc_huff_table (j_common_ptr cinfo)
+{
+ JHUFF_TBL *tbl;
+
+ tbl = (JHUFF_TBL *)
+ (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL));
+ tbl->sent_table = FALSE; /* make sure this is false in any new table */
+ return tbl;
+}
diff --git a/src/libjpeg-turbo/jconfig.h b/src/libjpeg-turbo/jconfig.h
new file mode 100644
index 0000000..4cd0fa0
--- /dev/null
+++ b/src/libjpeg-turbo/jconfig.h
@@ -0,0 +1,58 @@
+/* jconfig.h. Generated from jconfig.h.in by configure. */
+/* Version ID for the JPEG library.
+ * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
+ */
+#define JPEG_LIB_VERSION 62
+
+/* libjpeg-turbo version */
+#define LIBJPEG_TURBO_VERSION 1.2.0
+
+/* Support arithmetic encoding */
+#define C_ARITH_CODING_SUPPORTED 1
+
+/* Support arithmetic decoding */
+#define D_ARITH_CODING_SUPPORTED 1
+
+/* Compiler supports function prototypes. */
+#define HAVE_PROTOTYPES 1
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Compiler supports 'unsigned char'. */
+#define HAVE_UNSIGNED_CHAR 1
+
+/* Compiler supports 'unsigned short'. */
+#define HAVE_UNSIGNED_SHORT 1
+
+/* Compiler does not support pointers to unspecified structures. */
+/* #undef INCOMPLETE_TYPES_BROKEN */
+
+/* Compiler has <strings.h> rather than standard <string.h>. */
+/* #undef NEED_BSD_STRINGS */
+
+/* Linker requires that global names be unique in first 15 characters. */
+/* #undef NEED_SHORT_EXTERNAL_NAMES */
+
+/* Need to include <sys/types.h> in order to obtain size_t. */
+#define NEED_SYS_TYPES_H 1
+
+/* Broken compiler shifts signed values as an unsigned shift. */
+/* #undef RIGHT_SHIFT_IS_UNSIGNED */
+
+/* Use accelerated SIMD routines. */
+#define WITH_SIMD 1
+
+/* Define to 1 if type `char' is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+/* # undef __CHAR_UNSIGNED__ */
+#endif
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/src/libjpeg-turbo/jcparam.c b/src/libjpeg-turbo/jcparam.c
new file mode 100644
index 0000000..557fdc9
--- /dev/null
+++ b/src/libjpeg-turbo/jcparam.c
@@ -0,0 +1,649 @@
+/*
+ * jcparam.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * Modified 2003-2008 by Guido Vollbeding.
+ * Copyright (C) 2009-2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains optional default-setting code for the JPEG compressor.
+ * Applications do not have to use this file, but those that don't use it
+ * must know a lot more about the innards of the JPEG code.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Quantization table setup routines
+ */
+
+GLOBAL(void)
+jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
+ const unsigned int *basic_table,
+ int scale_factor, boolean force_baseline)
+/* Define a quantization table equal to the basic_table times
+ * a scale factor (given as a percentage).
+ * If force_baseline is TRUE, the computed quantization table entries
+ * are limited to 1..255 for JPEG baseline compatibility.
+ */
+{
+ JQUANT_TBL ** qtblptr;
+ int i;
+ long temp;
+
+ /* Safety check to ensure start_compress not called yet. */
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS)
+ ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl);
+
+ qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
+
+ if (*qtblptr == NULL)
+ *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo);
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
+ /* limit the values to the valid range */
+ if (temp <= 0L) temp = 1L;
+ if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */
+ if (force_baseline && temp > 255L)
+ temp = 255L; /* limit to baseline range if requested */
+ (*qtblptr)->quantval[i] = (UINT16) temp;
+ }
+
+ /* Initialize sent_table FALSE so table will be written to JPEG file. */
+ (*qtblptr)->sent_table = FALSE;
+}
+
+
+/* These are the sample quantization tables given in JPEG spec section K.1.
+ * The spec says that the values given produce "good" quality, and
+ * when divided by 2, "very good" quality.
+ */
+static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
+ 16, 11, 10, 16, 24, 40, 51, 61,
+ 12, 12, 14, 19, 26, 58, 60, 55,
+ 14, 13, 16, 24, 40, 57, 69, 56,
+ 14, 17, 22, 29, 51, 87, 80, 62,
+ 18, 22, 37, 56, 68, 109, 103, 77,
+ 24, 35, 55, 64, 81, 104, 113, 92,
+ 49, 64, 78, 87, 103, 121, 120, 101,
+ 72, 92, 95, 98, 112, 100, 103, 99
+};
+static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
+ 17, 18, 24, 47, 99, 99, 99, 99,
+ 18, 21, 26, 66, 99, 99, 99, 99,
+ 24, 26, 56, 99, 99, 99, 99, 99,
+ 47, 66, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99
+};
+
+
+#if JPEG_LIB_VERSION >= 70
+GLOBAL(void)
+jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
+/* Set or change the 'quality' (quantization) setting, using default tables
+ * and straight percentage-scaling quality scales.
+ * This entry point allows different scalings for luminance and chrominance.
+ */
+{
+ /* Set up two quantization tables using the specified scaling */
+ jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
+ cinfo->q_scale_factor[0], force_baseline);
+ jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
+ cinfo->q_scale_factor[1], force_baseline);
+}
+#endif
+
+
+GLOBAL(void)
+jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
+ boolean force_baseline)
+/* Set or change the 'quality' (quantization) setting, using default tables
+ * and a straight percentage-scaling quality scale. In most cases it's better
+ * to use jpeg_set_quality (below); this entry point is provided for
+ * applications that insist on a linear percentage scaling.
+ */
+{
+ /* Set up two quantization tables using the specified scaling */
+ jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
+ scale_factor, force_baseline);
+ jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
+ scale_factor, force_baseline);
+}
+
+
+GLOBAL(int)
+jpeg_quality_scaling (int quality)
+/* Convert a user-specified quality rating to a percentage scaling factor
+ * for an underlying quantization table, using our recommended scaling curve.
+ * The input 'quality' factor should be 0 (terrible) to 100 (very good).
+ */
+{
+ /* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */
+ if (quality <= 0) quality = 1;
+ if (quality > 100) quality = 100;
+
+ /* The basic table is used as-is (scaling 100) for a quality of 50.
+ * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
+ * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table
+ * to make all the table entries 1 (hence, minimum quantization loss).
+ * Qualities 1..50 are converted to scaling percentage 5000/Q.
+ */
+ if (quality < 50)
+ quality = 5000 / quality;
+ else
+ quality = 200 - quality*2;
+
+ return quality;
+}
+
+
+GLOBAL(void)
+jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
+/* Set or change the 'quality' (quantization) setting, using default tables.
+ * This is the standard quality-adjusting entry point for typical user
+ * interfaces; only those who want detailed control over quantization tables
+ * would use the preceding three routines directly.
+ */
+{
+ /* Convert user 0-100 rating to percentage scaling */
+ quality = jpeg_quality_scaling(quality);
+
+ /* Set up standard quality tables */
+ jpeg_set_linear_quality(cinfo, quality, force_baseline);
+}
+
+
+/*
+ * Huffman table setup routines
+ */
+
+LOCAL(void)
+add_huff_table (j_compress_ptr cinfo,
+ JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
+/* Define a Huffman table */
+{
+ int nsymbols, len;
+
+ if (*htblptr == NULL)
+ *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+
+ /* Copy the number-of-symbols-of-each-code-length counts */
+ MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
+
+ /* Validate the counts. We do this here mainly so we can copy the right
+ * number of symbols from the val[] array, without risking marching off
+ * the end of memory. jchuff.c will do a more thorough test later.
+ */
+ nsymbols = 0;
+ for (len = 1; len <= 16; len++)
+ nsymbols += bits[len];
+ if (nsymbols < 1 || nsymbols > 256)
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+
+ MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
+
+ /* Initialize sent_table FALSE so table will be written to JPEG file. */
+ (*htblptr)->sent_table = FALSE;
+}
+
+
+LOCAL(void)
+std_huff_tables (j_compress_ptr cinfo)
+/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
+/* IMPORTANT: these are only valid for 8-bit data precision! */
+{
+ static const UINT8 bits_dc_luminance[17] =
+ { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
+ static const UINT8 val_dc_luminance[] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+ static const UINT8 bits_dc_chrominance[17] =
+ { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
+ static const UINT8 val_dc_chrominance[] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+ static const UINT8 bits_ac_luminance[17] =
+ { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
+ static const UINT8 val_ac_luminance[] =
+ { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+ 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa };
+
+ static const UINT8 bits_ac_chrominance[17] =
+ { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
+ static const UINT8 val_ac_chrominance[] =
+ { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+ 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+ 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+ 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+ 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+ 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+ 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+ 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+ 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+ 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+ 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+ 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa };
+
+ add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
+ bits_dc_luminance, val_dc_luminance);
+ add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
+ bits_ac_luminance, val_ac_luminance);
+ add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
+ bits_dc_chrominance, val_dc_chrominance);
+ add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
+ bits_ac_chrominance, val_ac_chrominance);
+}
+
+
+/*
+ * Default parameter setup for compression.
+ *
+ * Applications that don't choose to use this routine must do their
+ * own setup of all these parameters. Alternately, you can call this
+ * to establish defaults and then alter parameters selectively. This
+ * is the recommended approach since, if we add any new parameters,
+ * your code will still work (they'll be set to reasonable defaults).
+ */
+
+GLOBAL(void)
+jpeg_set_defaults (j_compress_ptr cinfo)
+{
+ int i;
+
+ /* Safety check to ensure start_compress not called yet. */
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ /* Allocate comp_info array large enough for maximum component count.
+ * Array is made permanent in case application wants to compress
+ * multiple images at same param settings.
+ */
+ if (cinfo->comp_info == NULL)
+ cinfo->comp_info = (jpeg_component_info *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ MAX_COMPONENTS * SIZEOF(jpeg_component_info));
+
+ /* Initialize everything not dependent on the color space */
+
+#if JPEG_LIB_VERSION >= 70
+ cinfo->scale_num = 1; /* 1:1 scaling */
+ cinfo->scale_denom = 1;
+#endif
+ cinfo->data_precision = BITS_IN_JSAMPLE;
+ /* Set up two quantization tables using default quality of 75 */
+ jpeg_set_quality(cinfo, 75, TRUE);
+ /* Set up two Huffman tables */
+ std_huff_tables(cinfo);
+
+ /* Initialize default arithmetic coding conditioning */
+ for (i = 0; i < NUM_ARITH_TBLS; i++) {
+ cinfo->arith_dc_L[i] = 0;
+ cinfo->arith_dc_U[i] = 1;
+ cinfo->arith_ac_K[i] = 5;
+ }
+
+ /* Default is no multiple-scan output */
+ cinfo->scan_info = NULL;
+ cinfo->num_scans = 0;
+
+ /* Expect normal source image, not raw downsampled data */
+ cinfo->raw_data_in = FALSE;
+
+ /* Use Huffman coding, not arithmetic coding, by default */
+ cinfo->arith_code = FALSE;
+
+ /* By default, don't do extra passes to optimize entropy coding */
+ cinfo->optimize_coding = FALSE;
+ /* The standard Huffman tables are only valid for 8-bit data precision.
+ * If the precision is higher, force optimization on so that usable
+ * tables will be computed. This test can be removed if default tables
+ * are supplied that are valid for the desired precision.
+ */
+ if (cinfo->data_precision > 8)
+ cinfo->optimize_coding = TRUE;
+
+ /* By default, use the simpler non-cosited sampling alignment */
+ cinfo->CCIR601_sampling = FALSE;
+
+#if JPEG_LIB_VERSION >= 70
+ /* By default, apply fancy downsampling */
+ cinfo->do_fancy_downsampling = TRUE;
+#endif
+
+ /* No input smoothing */
+ cinfo->smoothing_factor = 0;
+
+ /* DCT algorithm preference */
+ cinfo->dct_method = JDCT_DEFAULT;
+
+ /* No restart markers */
+ cinfo->restart_interval = 0;
+ cinfo->restart_in_rows = 0;
+
+ /* Fill in default JFIF marker parameters. Note that whether the marker
+ * will actually be written is determined by jpeg_set_colorspace.
+ *
+ * By default, the library emits JFIF version code 1.01.
+ * An application that wants to emit JFIF 1.02 extension markers should set
+ * JFIF_minor_version to 2. We could probably get away with just defaulting
+ * to 1.02, but there may still be some decoders in use that will complain
+ * about that; saying 1.01 should minimize compatibility problems.
+ */
+ cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */
+ cinfo->JFIF_minor_version = 1;
+ cinfo->density_unit = 0; /* Pixel size is unknown by default */
+ cinfo->X_density = 1; /* Pixel aspect ratio is square by default */
+ cinfo->Y_density = 1;
+
+ /* Choose JPEG colorspace based on input space, set defaults accordingly */
+
+ jpeg_default_colorspace(cinfo);
+}
+
+
+/*
+ * Select an appropriate JPEG colorspace for in_color_space.
+ */
+
+GLOBAL(void)
+jpeg_default_colorspace (j_compress_ptr cinfo)
+{
+ switch (cinfo->in_color_space) {
+ case JCS_GRAYSCALE:
+ jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
+ break;
+ case JCS_RGB:
+ case JCS_EXT_RGB:
+ case JCS_EXT_RGBX:
+ case JCS_EXT_BGR:
+ case JCS_EXT_BGRX:
+ case JCS_EXT_XBGR:
+ case JCS_EXT_XRGB:
+ case JCS_EXT_RGBA:
+ case JCS_EXT_BGRA:
+ case JCS_EXT_ABGR:
+ case JCS_EXT_ARGB:
+ jpeg_set_colorspace(cinfo, JCS_YCbCr);
+ break;
+ case JCS_YCbCr:
+ jpeg_set_colorspace(cinfo, JCS_YCbCr);
+ break;
+ case JCS_CMYK:
+ jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */
+ break;
+ case JCS_YCCK:
+ jpeg_set_colorspace(cinfo, JCS_YCCK);
+ break;
+ case JCS_UNKNOWN:
+ jpeg_set_colorspace(cinfo, JCS_UNKNOWN);
+ break;
+ default:
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ }
+}
+
+
+/*
+ * Set the JPEG colorspace, and choose colorspace-dependent default values.
+ */
+
+GLOBAL(void)
+jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
+{
+ jpeg_component_info * compptr;
+ int ci;
+
+#define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl) \
+ (compptr = &cinfo->comp_info[index], \
+ compptr->component_id = (id), \
+ compptr->h_samp_factor = (hsamp), \
+ compptr->v_samp_factor = (vsamp), \
+ compptr->quant_tbl_no = (quant), \
+ compptr->dc_tbl_no = (dctbl), \
+ compptr->ac_tbl_no = (actbl) )
+
+ /* Safety check to ensure start_compress not called yet. */
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ /* For all colorspaces, we use Q and Huff tables 0 for luminance components,
+ * tables 1 for chrominance components.
+ */
+
+ cinfo->jpeg_color_space = colorspace;
+
+ cinfo->write_JFIF_header = FALSE; /* No marker for non-JFIF colorspaces */
+ cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */
+
+ switch (colorspace) {
+ case JCS_GRAYSCALE:
+ cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
+ cinfo->num_components = 1;
+ /* JFIF specifies component ID 1 */
+ SET_COMP(0, 1, 1,1, 0, 0,0);
+ break;
+ case JCS_RGB:
+ cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */
+ cinfo->num_components = 3;
+ SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0);
+ SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0);
+ SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0);
+ break;
+ case JCS_YCbCr:
+ cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
+ cinfo->num_components = 3;
+ /* JFIF specifies component IDs 1,2,3 */
+ /* We default to 2x2 subsamples of chrominance */
+ SET_COMP(0, 1, 2,2, 0, 0,0);
+ SET_COMP(1, 2, 1,1, 1, 1,1);
+ SET_COMP(2, 3, 1,1, 1, 1,1);
+ break;
+ case JCS_CMYK:
+ cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */
+ cinfo->num_components = 4;
+ SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0);
+ SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0);
+ SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0);
+ SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0);
+ break;
+ case JCS_YCCK:
+ cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */
+ cinfo->num_components = 4;
+ SET_COMP(0, 1, 2,2, 0, 0,0);
+ SET_COMP(1, 2, 1,1, 1, 1,1);
+ SET_COMP(2, 3, 1,1, 1, 1,1);
+ SET_COMP(3, 4, 2,2, 0, 0,0);
+ break;
+ case JCS_UNKNOWN:
+ cinfo->num_components = cinfo->input_components;
+ if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+ MAX_COMPONENTS);
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ SET_COMP(ci, ci, 1,1, 0, 0,0);
+ }
+ break;
+ default:
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ }
+}
+
+
+#ifdef C_PROGRESSIVE_SUPPORTED
+
+LOCAL(jpeg_scan_info *)
+fill_a_scan (jpeg_scan_info * scanptr, int ci,
+ int Ss, int Se, int Ah, int Al)
+/* Support routine: generate one scan for specified component */
+{
+ scanptr->comps_in_scan = 1;
+ scanptr->component_index[0] = ci;
+ scanptr->Ss = Ss;
+ scanptr->Se = Se;
+ scanptr->Ah = Ah;
+ scanptr->Al = Al;
+ scanptr++;
+ return scanptr;
+}
+
+LOCAL(jpeg_scan_info *)
+fill_scans (jpeg_scan_info * scanptr, int ncomps,
+ int Ss, int Se, int Ah, int Al)
+/* Support routine: generate one scan for each component */
+{
+ int ci;
+
+ for (ci = 0; ci < ncomps; ci++) {
+ scanptr->comps_in_scan = 1;
+ scanptr->component_index[0] = ci;
+ scanptr->Ss = Ss;
+ scanptr->Se = Se;
+ scanptr->Ah = Ah;
+ scanptr->Al = Al;
+ scanptr++;
+ }
+ return scanptr;
+}
+
+LOCAL(jpeg_scan_info *)
+fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al)
+/* Support routine: generate interleaved DC scan if possible, else N scans */
+{
+ int ci;
+
+ if (ncomps <= MAX_COMPS_IN_SCAN) {
+ /* Single interleaved DC scan */
+ scanptr->comps_in_scan = ncomps;
+ for (ci = 0; ci < ncomps; ci++)
+ scanptr->component_index[ci] = ci;
+ scanptr->Ss = scanptr->Se = 0;
+ scanptr->Ah = Ah;
+ scanptr->Al = Al;
+ scanptr++;
+ } else {
+ /* Noninterleaved DC scan for each component */
+ scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al);
+ }
+ return scanptr;
+}
+
+
+/*
+ * Create a recommended progressive-JPEG script.
+ * cinfo->num_components and cinfo->jpeg_color_space must be correct.
+ */
+
+GLOBAL(void)
+jpeg_simple_progression (j_compress_ptr cinfo)
+{
+ int ncomps = cinfo->num_components;
+ int nscans;
+ jpeg_scan_info * scanptr;
+
+ /* Safety check to ensure start_compress not called yet. */
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ /* Figure space needed for script. Calculation must match code below! */
+ if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
+ /* Custom script for YCbCr color images. */
+ nscans = 10;
+ } else {
+ /* All-purpose script for other color spaces. */
+ if (ncomps > MAX_COMPS_IN_SCAN)
+ nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */
+ else
+ nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */
+ }
+
+ /* Allocate space for script.
+ * We need to put it in the permanent pool in case the application performs
+ * multiple compressions without changing the settings. To avoid a memory
+ * leak if jpeg_simple_progression is called repeatedly for the same JPEG
+ * object, we try to re-use previously allocated space, and we allocate
+ * enough space to handle YCbCr even if initially asked for grayscale.
+ */
+ if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
+ cinfo->script_space_size = MAX(nscans, 10);
+ cinfo->script_space = (jpeg_scan_info *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ cinfo->script_space_size * SIZEOF(jpeg_scan_info));
+ }
+ scanptr = cinfo->script_space;
+ cinfo->scan_info = scanptr;
+ cinfo->num_scans = nscans;
+
+ if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
+ /* Custom script for YCbCr color images. */
+ /* Initial DC scan */
+ scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
+ /* Initial AC scan: get some luma data out in a hurry */
+ scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2);
+ /* Chroma data is too small to be worth expending many scans on */
+ scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1);
+ scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1);
+ /* Complete spectral selection for luma AC */
+ scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2);
+ /* Refine next bit of luma AC */
+ scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1);
+ /* Finish DC successive approximation */
+ scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
+ /* Finish AC successive approximation */
+ scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0);
+ scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0);
+ /* Luma bottom bit comes last since it's usually largest scan */
+ scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0);
+ } else {
+ /* All-purpose script for other color spaces. */
+ /* Successive approximation first pass */
+ scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
+ scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2);
+ scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2);
+ /* Successive approximation second pass */
+ scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1);
+ /* Successive approximation final pass */
+ scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
+ scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0);
+ }
+}
+
+#endif /* C_PROGRESSIVE_SUPPORTED */
diff --git a/src/libjpeg-turbo/jcphuff.c b/src/libjpeg-turbo/jcphuff.c
new file mode 100644
index 0000000..3102871
--- /dev/null
+++ b/src/libjpeg-turbo/jcphuff.c
@@ -0,0 +1,831 @@
+/*
+ * jcphuff.c
+ *
+ * Copyright (C) 1995-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains Huffman entropy encoding routines for progressive JPEG.
+ *
+ * We do not support output suspension in this module, since the library
+ * currently does not allow multiple-scan files to be written with output
+ * suspension.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jchuff.h" /* Declarations shared with jchuff.c */
+
+#ifdef C_PROGRESSIVE_SUPPORTED
+
+/* Expanded entropy encoder object for progressive Huffman encoding. */
+
+typedef struct {
+ struct jpeg_entropy_encoder pub; /* public fields */
+
+ /* Mode flag: TRUE for optimization, FALSE for actual data output */
+ boolean gather_statistics;
+
+ /* Bit-level coding status.
+ * next_output_byte/free_in_buffer are local copies of cinfo->dest fields.
+ */
+ JOCTET * next_output_byte; /* => next byte to write in buffer */
+ size_t free_in_buffer; /* # of byte spaces remaining in buffer */
+ INT32 put_buffer; /* current bit-accumulation buffer */
+ int put_bits; /* # of bits now in it */
+ j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */
+
+ /* Coding status for DC components */
+ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+
+ /* Coding status for AC components */
+ int ac_tbl_no; /* the table number of the single component */
+ unsigned int EOBRUN; /* run length of EOBs */
+ unsigned int BE; /* # of buffered correction bits before MCU */
+ char * bit_buffer; /* buffer for correction bits (1 per char) */
+ /* packing correction bits tightly would save some space but cost time... */
+
+ unsigned int restarts_to_go; /* MCUs left in this restart interval */
+ int next_restart_num; /* next restart number to write (0-7) */
+
+ /* Pointers to derived tables (these workspaces have image lifespan).
+ * Since any one scan codes only DC or only AC, we only need one set
+ * of tables, not one for DC and one for AC.
+ */
+ c_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
+
+ /* Statistics tables for optimization; again, one set is enough */
+ long * count_ptrs[NUM_HUFF_TBLS];
+} phuff_entropy_encoder;
+
+typedef phuff_entropy_encoder * phuff_entropy_ptr;
+
+/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit
+ * buffer can hold. Larger sizes may slightly improve compression, but
+ * 1000 is already well into the realm of overkill.
+ * The minimum safe size is 64 bits.
+ */
+
+#define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */
+
+/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
+ * We assume that int right shift is unsigned if INT32 right shift is,
+ * which should be safe.
+ */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define ISHIFT_TEMPS int ishift_temp;
+#define IRIGHT_SHIFT(x,shft) \
+ ((ishift_temp = (x)) < 0 ? \
+ (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
+ (ishift_temp >> (shft)))
+#else
+#define ISHIFT_TEMPS
+#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
+#endif
+
+/* Forward declarations */
+METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo));
+METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo));
+
+
+/*
+ * Initialize for a Huffman-compressed scan using progressive JPEG.
+ */
+
+METHODDEF(void)
+start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ boolean is_DC_band;
+ int ci, tbl;
+ jpeg_component_info * compptr;
+
+ entropy->cinfo = cinfo;
+ entropy->gather_statistics = gather_statistics;
+
+ is_DC_band = (cinfo->Ss == 0);
+
+ /* We assume jcmaster.c already validated the scan parameters. */
+
+ /* Select execution routines */
+ if (cinfo->Ah == 0) {
+ if (is_DC_band)
+ entropy->pub.encode_mcu = encode_mcu_DC_first;
+ else
+ entropy->pub.encode_mcu = encode_mcu_AC_first;
+ } else {
+ if (is_DC_band)
+ entropy->pub.encode_mcu = encode_mcu_DC_refine;
+ else {
+ entropy->pub.encode_mcu = encode_mcu_AC_refine;
+ /* AC refinement needs a correction bit buffer */
+ if (entropy->bit_buffer == NULL)
+ entropy->bit_buffer = (char *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ MAX_CORR_BITS * SIZEOF(char));
+ }
+ }
+ if (gather_statistics)
+ entropy->pub.finish_pass = finish_pass_gather_phuff;
+ else
+ entropy->pub.finish_pass = finish_pass_phuff;
+
+ /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1
+ * for AC coefficients.
+ */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* Initialize DC predictions to 0 */
+ entropy->last_dc_val[ci] = 0;
+ /* Get table index */
+ if (is_DC_band) {
+ if (cinfo->Ah != 0) /* DC refinement needs no table */
+ continue;
+ tbl = compptr->dc_tbl_no;
+ } else {
+ entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;
+ }
+ if (gather_statistics) {
+ /* Check for invalid table index */
+ /* (make_c_derived_tbl does this in the other path) */
+ if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
+ /* Allocate and zero the statistics tables */
+ /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
+ if (entropy->count_ptrs[tbl] == NULL)
+ entropy->count_ptrs[tbl] = (long *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ 257 * SIZEOF(long));
+ MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
+ } else {
+ /* Compute derived values for Huffman table */
+ /* We may do this more than once for a table, but it's not expensive */
+ jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,
+ & entropy->derived_tbls[tbl]);
+ }
+ }
+
+ /* Initialize AC stuff */
+ entropy->EOBRUN = 0;
+ entropy->BE = 0;
+
+ /* Initialize bit buffer to empty */
+ entropy->put_buffer = 0;
+ entropy->put_bits = 0;
+
+ /* Initialize restart stuff */
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num = 0;
+}
+
+
+/* Outputting bytes to the file.
+ * NB: these must be called only when actually outputting,
+ * that is, entropy->gather_statistics == FALSE.
+ */
+
+/* Emit a byte */
+#define emit_byte(entropy,val) \
+ { *(entropy)->next_output_byte++ = (JOCTET) (val); \
+ if (--(entropy)->free_in_buffer == 0) \
+ dump_buffer(entropy); }
+
+
+LOCAL(void)
+dump_buffer (phuff_entropy_ptr entropy)
+/* Empty the output buffer; we do not support suspension in this module. */
+{
+ struct jpeg_destination_mgr * dest = entropy->cinfo->dest;
+
+ if (! (*dest->empty_output_buffer) (entropy->cinfo))
+ ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND);
+ /* After a successful buffer dump, must reset buffer pointers */
+ entropy->next_output_byte = dest->next_output_byte;
+ entropy->free_in_buffer = dest->free_in_buffer;
+}
+
+
+/* Outputting bits to the file */
+
+/* Only the right 24 bits of put_buffer are used; the valid bits are
+ * left-justified in this part. At most 16 bits can be passed to emit_bits
+ * in one call, and we never retain more than 7 bits in put_buffer
+ * between calls, so 24 bits are sufficient.
+ */
+
+LOCAL(void)
+emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
+/* Emit some bits, unless we are in gather mode */
+{
+ /* This routine is heavily used, so it's worth coding tightly. */
+ register INT32 put_buffer = (INT32) code;
+ register int put_bits = entropy->put_bits;
+
+ /* if size is 0, caller used an invalid Huffman table entry */
+ if (size == 0)
+ ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
+
+ if (entropy->gather_statistics)
+ return; /* do nothing if we're only getting stats */
+
+ put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
+
+ put_bits += size; /* new number of bits in buffer */
+
+ put_buffer <<= 24 - put_bits; /* align incoming bits */
+
+ put_buffer |= entropy->put_buffer; /* and merge with old buffer contents */
+
+ while (put_bits >= 8) {
+ int c = (int) ((put_buffer >> 16) & 0xFF);
+
+ emit_byte(entropy, c);
+ if (c == 0xFF) { /* need to stuff a zero byte? */
+ emit_byte(entropy, 0);
+ }
+ put_buffer <<= 8;
+ put_bits -= 8;
+ }
+
+ entropy->put_buffer = put_buffer; /* update variables */
+ entropy->put_bits = put_bits;
+}
+
+
+LOCAL(void)
+flush_bits (phuff_entropy_ptr entropy)
+{
+ emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */
+ entropy->put_buffer = 0; /* and reset bit-buffer to empty */
+ entropy->put_bits = 0;
+}
+
+
+/*
+ * Emit (or just count) a Huffman symbol.
+ */
+
+LOCAL(void)
+emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
+{
+ if (entropy->gather_statistics)
+ entropy->count_ptrs[tbl_no][symbol]++;
+ else {
+ c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];
+ emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
+ }
+}
+
+
+/*
+ * Emit bits from a correction bit buffer.
+ */
+
+LOCAL(void)
+emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,
+ unsigned int nbits)
+{
+ if (entropy->gather_statistics)
+ return; /* no real work */
+
+ while (nbits > 0) {
+ emit_bits(entropy, (unsigned int) (*bufstart), 1);
+ bufstart++;
+ nbits--;
+ }
+}
+
+
+/*
+ * Emit any pending EOBRUN symbol.
+ */
+
+LOCAL(void)
+emit_eobrun (phuff_entropy_ptr entropy)
+{
+ register int temp, nbits;
+
+ if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */
+ temp = entropy->EOBRUN;
+ nbits = 0;
+ while ((temp >>= 1))
+ nbits++;
+ /* safety check: shouldn't happen given limited correction-bit buffer */
+ if (nbits > 14)
+ ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
+
+ emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
+ if (nbits)
+ emit_bits(entropy, entropy->EOBRUN, nbits);
+
+ entropy->EOBRUN = 0;
+
+ /* Emit any buffered correction bits */
+ emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE);
+ entropy->BE = 0;
+ }
+}
+
+
+/*
+ * Emit a restart marker & resynchronize predictions.
+ */
+
+LOCAL(void)
+emit_restart (phuff_entropy_ptr entropy, int restart_num)
+{
+ int ci;
+
+ emit_eobrun(entropy);
+
+ if (! entropy->gather_statistics) {
+ flush_bits(entropy);
+ emit_byte(entropy, 0xFF);
+ emit_byte(entropy, JPEG_RST0 + restart_num);
+ }
+
+ if (entropy->cinfo->Ss == 0) {
+ /* Re-initialize DC predictions to 0 */
+ for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++)
+ entropy->last_dc_val[ci] = 0;
+ } else {
+ /* Re-initialize all AC-related fields to 0 */
+ entropy->EOBRUN = 0;
+ entropy->BE = 0;
+ }
+}
+
+
+/*
+ * MCU encoding for DC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ register int temp, temp2;
+ register int nbits;
+ int blkn, ci;
+ int Al = cinfo->Al;
+ JBLOCKROW block;
+ jpeg_component_info * compptr;
+ ISHIFT_TEMPS
+
+ entropy->next_output_byte = cinfo->dest->next_output_byte;
+ entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval)
+ if (entropy->restarts_to_go == 0)
+ emit_restart(entropy, entropy->next_restart_num);
+
+ /* Encode the MCU data blocks */
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+
+ /* Compute the DC value after the required point transform by Al.
+ * This is simply an arithmetic right shift.
+ */
+ temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);
+
+ /* DC differences are figured on the point-transformed values. */
+ temp = temp2 - entropy->last_dc_val[ci];
+ entropy->last_dc_val[ci] = temp2;
+
+ /* Encode the DC coefficient difference per section G.1.2.1 */
+ temp2 = temp;
+ if (temp < 0) {
+ temp = -temp; /* temp is abs value of input */
+ /* For a negative input, want temp2 = bitwise complement of abs(input) */
+ /* This code assumes we are on a two's complement machine */
+ temp2--;
+ }
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ nbits = 0;
+ while (temp) {
+ nbits++;
+ temp >>= 1;
+ }
+ /* Check for out-of-range coefficient values.
+ * Since we're encoding a difference, the range limit is twice as much.
+ */
+ if (nbits > MAX_COEF_BITS+1)
+ ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+
+ /* Count/emit the Huffman-coded symbol for the number of bits */
+ emit_symbol(entropy, compptr->dc_tbl_no, nbits);
+
+ /* Emit that number of bits of the value, if positive, */
+ /* or the complement of its magnitude, if negative. */
+ if (nbits) /* emit_bits rejects calls with size 0 */
+ emit_bits(entropy, (unsigned int) temp2, nbits);
+ }
+
+ cinfo->dest->next_output_byte = entropy->next_output_byte;
+ cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+ /* Update restart-interval state too */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU encoding for AC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ register int temp, temp2;
+ register int nbits;
+ register int r, k;
+ int Se = cinfo->Se;
+ int Al = cinfo->Al;
+ JBLOCKROW block;
+
+ entropy->next_output_byte = cinfo->dest->next_output_byte;
+ entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval)
+ if (entropy->restarts_to_go == 0)
+ emit_restart(entropy, entropy->next_restart_num);
+
+ /* Encode the MCU data block */
+ block = MCU_data[0];
+
+ /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */
+
+ r = 0; /* r = run length of zeros */
+
+ for (k = cinfo->Ss; k <= Se; k++) {
+ if ((temp = (*block)[jpeg_natural_order[k]]) == 0) {
+ r++;
+ continue;
+ }
+ /* We must apply the point transform by Al. For AC coefficients this
+ * is an integer division with rounding towards 0. To do this portably
+ * in C, we shift after obtaining the absolute value; so the code is
+ * interwoven with finding the abs value (temp) and output bits (temp2).
+ */
+ if (temp < 0) {
+ temp = -temp; /* temp is abs value of input */
+ temp >>= Al; /* apply the point transform */
+ /* For a negative coef, want temp2 = bitwise complement of abs(coef) */
+ temp2 = ~temp;
+ } else {
+ temp >>= Al; /* apply the point transform */
+ temp2 = temp;
+ }
+ /* Watch out for case that nonzero coef is zero after point transform */
+ if (temp == 0) {
+ r++;
+ continue;
+ }
+
+ /* Emit any pending EOBRUN */
+ if (entropy->EOBRUN > 0)
+ emit_eobrun(entropy);
+ /* if run length > 15, must emit special run-length-16 codes (0xF0) */
+ while (r > 15) {
+ emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
+ r -= 16;
+ }
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ nbits = 1; /* there must be at least one 1 bit */
+ while ((temp >>= 1))
+ nbits++;
+ /* Check for out-of-range coefficient values */
+ if (nbits > MAX_COEF_BITS)
+ ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+
+ /* Count/emit Huffman symbol for run length / number of bits */
+ emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
+
+ /* Emit that number of bits of the value, if positive, */
+ /* or the complement of its magnitude, if negative. */
+ emit_bits(entropy, (unsigned int) temp2, nbits);
+
+ r = 0; /* reset zero run length */
+ }
+
+ if (r > 0) { /* If there are trailing zeroes, */
+ entropy->EOBRUN++; /* count an EOB */
+ if (entropy->EOBRUN == 0x7FFF)
+ emit_eobrun(entropy); /* force it out to avoid overflow */
+ }
+
+ cinfo->dest->next_output_byte = entropy->next_output_byte;
+ cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+ /* Update restart-interval state too */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU encoding for DC successive approximation refinement scan.
+ * Note: we assume such scans can be multi-component, although the spec
+ * is not very clear on the point.
+ */
+
+METHODDEF(boolean)
+encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ register int temp;
+ int blkn;
+ int Al = cinfo->Al;
+ JBLOCKROW block;
+
+ entropy->next_output_byte = cinfo->dest->next_output_byte;
+ entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval)
+ if (entropy->restarts_to_go == 0)
+ emit_restart(entropy, entropy->next_restart_num);
+
+ /* Encode the MCU data blocks */
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+
+ /* We simply emit the Al'th bit of the DC coefficient value. */
+ temp = (*block)[0];
+ emit_bits(entropy, (unsigned int) (temp >> Al), 1);
+ }
+
+ cinfo->dest->next_output_byte = entropy->next_output_byte;
+ cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+ /* Update restart-interval state too */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU encoding for AC successive approximation refinement scan.
+ */
+
+METHODDEF(boolean)
+encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ register int temp;
+ register int r, k;
+ int EOB;
+ char *BR_buffer;
+ unsigned int BR;
+ int Se = cinfo->Se;
+ int Al = cinfo->Al;
+ JBLOCKROW block;
+ int absvalues[DCTSIZE2];
+
+ entropy->next_output_byte = cinfo->dest->next_output_byte;
+ entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval)
+ if (entropy->restarts_to_go == 0)
+ emit_restart(entropy, entropy->next_restart_num);
+
+ /* Encode the MCU data block */
+ block = MCU_data[0];
+
+ /* It is convenient to make a pre-pass to determine the transformed
+ * coefficients' absolute values and the EOB position.
+ */
+ EOB = 0;
+ for (k = cinfo->Ss; k <= Se; k++) {
+ temp = (*block)[jpeg_natural_order[k]];
+ /* We must apply the point transform by Al. For AC coefficients this
+ * is an integer division with rounding towards 0. To do this portably
+ * in C, we shift after obtaining the absolute value.
+ */
+ if (temp < 0)
+ temp = -temp; /* temp is abs value of input */
+ temp >>= Al; /* apply the point transform */
+ absvalues[k] = temp; /* save abs value for main pass */
+ if (temp == 1)
+ EOB = k; /* EOB = index of last newly-nonzero coef */
+ }
+
+ /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */
+
+ r = 0; /* r = run length of zeros */
+ BR = 0; /* BR = count of buffered bits added now */
+ BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */
+
+ for (k = cinfo->Ss; k <= Se; k++) {
+ if ((temp = absvalues[k]) == 0) {
+ r++;
+ continue;
+ }
+
+ /* Emit any required ZRLs, but not if they can be folded into EOB */
+ while (r > 15 && k <= EOB) {
+ /* emit any pending EOBRUN and the BE correction bits */
+ emit_eobrun(entropy);
+ /* Emit ZRL */
+ emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
+ r -= 16;
+ /* Emit buffered correction bits that must be associated with ZRL */
+ emit_buffered_bits(entropy, BR_buffer, BR);
+ BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
+ BR = 0;
+ }
+
+ /* If the coef was previously nonzero, it only needs a correction bit.
+ * NOTE: a straight translation of the spec's figure G.7 would suggest
+ * that we also need to test r > 15. But if r > 15, we can only get here
+ * if k > EOB, which implies that this coefficient is not 1.
+ */
+ if (temp > 1) {
+ /* The correction bit is the next bit of the absolute value. */
+ BR_buffer[BR++] = (char) (temp & 1);
+ continue;
+ }
+
+ /* Emit any pending EOBRUN and the BE correction bits */
+ emit_eobrun(entropy);
+
+ /* Count/emit Huffman symbol for run length / number of bits */
+ emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1);
+
+ /* Emit output bit for newly-nonzero coef */
+ temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1;
+ emit_bits(entropy, (unsigned int) temp, 1);
+
+ /* Emit buffered correction bits that must be associated with this code */
+ emit_buffered_bits(entropy, BR_buffer, BR);
+ BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
+ BR = 0;
+ r = 0; /* reset zero run length */
+ }
+
+ if (r > 0 || BR > 0) { /* If there are trailing zeroes, */
+ entropy->EOBRUN++; /* count an EOB */
+ entropy->BE += BR; /* concat my correction bits to older ones */
+ /* We force out the EOB if we risk either:
+ * 1. overflow of the EOB counter;
+ * 2. overflow of the correction bit buffer during the next MCU.
+ */
+ if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1))
+ emit_eobrun(entropy);
+ }
+
+ cinfo->dest->next_output_byte = entropy->next_output_byte;
+ cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+ /* Update restart-interval state too */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Finish up at the end of a Huffman-compressed progressive scan.
+ */
+
+METHODDEF(void)
+finish_pass_phuff (j_compress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+
+ entropy->next_output_byte = cinfo->dest->next_output_byte;
+ entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+ /* Flush out any buffered data */
+ emit_eobrun(entropy);
+ flush_bits(entropy);
+
+ cinfo->dest->next_output_byte = entropy->next_output_byte;
+ cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+}
+
+
+/*
+ * Finish up a statistics-gathering pass and create the new Huffman tables.
+ */
+
+METHODDEF(void)
+finish_pass_gather_phuff (j_compress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ boolean is_DC_band;
+ int ci, tbl;
+ jpeg_component_info * compptr;
+ JHUFF_TBL **htblptr;
+ boolean did[NUM_HUFF_TBLS];
+
+ /* Flush out buffered data (all we care about is counting the EOB symbol) */
+ emit_eobrun(entropy);
+
+ is_DC_band = (cinfo->Ss == 0);
+
+ /* It's important not to apply jpeg_gen_optimal_table more than once
+ * per table, because it clobbers the input frequency counts!
+ */
+ MEMZERO(did, SIZEOF(did));
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ if (is_DC_band) {
+ if (cinfo->Ah != 0) /* DC refinement needs no table */
+ continue;
+ tbl = compptr->dc_tbl_no;
+ } else {
+ tbl = compptr->ac_tbl_no;
+ }
+ if (! did[tbl]) {
+ if (is_DC_band)
+ htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
+ else
+ htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
+ if (*htblptr == NULL)
+ *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+ jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]);
+ did[tbl] = TRUE;
+ }
+ }
+}
+
+
+/*
+ * Module initialization routine for progressive Huffman entropy encoding.
+ */
+
+GLOBAL(void)
+jinit_phuff_encoder (j_compress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy;
+ int i;
+
+ entropy = (phuff_entropy_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(phuff_entropy_encoder));
+ cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
+ entropy->pub.start_pass = start_pass_phuff;
+
+ /* Mark tables unallocated */
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ entropy->derived_tbls[i] = NULL;
+ entropy->count_ptrs[i] = NULL;
+ }
+ entropy->bit_buffer = NULL; /* needed only in AC refinement scan */
+}
+
+#endif /* C_PROGRESSIVE_SUPPORTED */
diff --git a/src/libjpeg-turbo/jcprepct.c b/src/libjpeg-turbo/jcprepct.c
new file mode 100644
index 0000000..fa93333
--- /dev/null
+++ b/src/libjpeg-turbo/jcprepct.c
@@ -0,0 +1,354 @@
+/*
+ * jcprepct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the compression preprocessing controller.
+ * This controller manages the color conversion, downsampling,
+ * and edge expansion steps.
+ *
+ * Most of the complexity here is associated with buffering input rows
+ * as required by the downsampler. See the comments at the head of
+ * jcsample.c for the downsampler's needs.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* At present, jcsample.c can request context rows only for smoothing.
+ * In the future, we might also need context rows for CCIR601 sampling
+ * or other more-complex downsampling procedures. The code to support
+ * context rows should be compiled only if needed.
+ */
+#ifdef INPUT_SMOOTHING_SUPPORTED
+#define CONTEXT_ROWS_SUPPORTED
+#endif
+
+
+/*
+ * For the simple (no-context-row) case, we just need to buffer one
+ * row group's worth of pixels for the downsampling step. At the bottom of
+ * the image, we pad to a full row group by replicating the last pixel row.
+ * The downsampler's last output row is then replicated if needed to pad
+ * out to a full iMCU row.
+ *
+ * When providing context rows, we must buffer three row groups' worth of
+ * pixels. Three row groups are physically allocated, but the row pointer
+ * arrays are made five row groups high, with the extra pointers above and
+ * below "wrapping around" to point to the last and first real row groups.
+ * This allows the downsampler to access the proper context rows.
+ * At the top and bottom of the image, we create dummy context rows by
+ * copying the first or last real pixel row. This copying could be avoided
+ * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
+ * trouble on the compression side.
+ */
+
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_c_prep_controller pub; /* public fields */
+
+ /* Downsampling input buffer. This buffer holds color-converted data
+ * until we have enough to do a downsample step.
+ */
+ JSAMPARRAY color_buf[MAX_COMPONENTS];
+
+ JDIMENSION rows_to_go; /* counts rows remaining in source image */
+ int next_buf_row; /* index of next row to store in color_buf */
+
+#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */
+ int this_row_group; /* starting row index of group to process */
+ int next_buf_stop; /* downsample when we reach this index */
+#endif
+} my_prep_controller;
+
+typedef my_prep_controller * my_prep_ptr;
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+
+ if (pass_mode != JBUF_PASS_THRU)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+ /* Initialize total-height counter for detecting bottom of image */
+ prep->rows_to_go = cinfo->image_height;
+ /* Mark the conversion buffer empty */
+ prep->next_buf_row = 0;
+#ifdef CONTEXT_ROWS_SUPPORTED
+ /* Preset additional state variables for context mode.
+ * These aren't used in non-context mode, so we needn't test which mode.
+ */
+ prep->this_row_group = 0;
+ /* Set next_buf_stop to stop after two row groups have been read in. */
+ prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
+#endif
+}
+
+
+/*
+ * Expand an image vertically from height input_rows to height output_rows,
+ * by duplicating the bottom row.
+ */
+
+LOCAL(void)
+expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
+ int input_rows, int output_rows)
+{
+ register int row;
+
+ for (row = input_rows; row < output_rows; row++) {
+ jcopy_sample_rows(image_data, input_rows-1, image_data, row,
+ 1, num_cols);
+ }
+}
+
+
+/*
+ * Process some data in the simple no-context case.
+ *
+ * Preprocessor output data is counted in "row groups". A row group
+ * is defined to be v_samp_factor sample rows of each component.
+ * Downsampling will produce this much data from each max_v_samp_factor
+ * input rows.
+ */
+
+METHODDEF(void)
+pre_process_data (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail,
+ JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
+ JDIMENSION out_row_groups_avail)
+{
+ my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+ int numrows, ci;
+ JDIMENSION inrows;
+ jpeg_component_info * compptr;
+
+ while (*in_row_ctr < in_rows_avail &&
+ *out_row_group_ctr < out_row_groups_avail) {
+ /* Do color conversion to fill the conversion buffer. */
+ inrows = in_rows_avail - *in_row_ctr;
+ numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
+ numrows = (int) MIN((JDIMENSION) numrows, inrows);
+ (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
+ prep->color_buf,
+ (JDIMENSION) prep->next_buf_row,
+ numrows);
+ *in_row_ctr += numrows;
+ prep->next_buf_row += numrows;
+ prep->rows_to_go -= numrows;
+ /* If at bottom of image, pad to fill the conversion buffer. */
+ if (prep->rows_to_go == 0 &&
+ prep->next_buf_row < cinfo->max_v_samp_factor) {
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
+ prep->next_buf_row, cinfo->max_v_samp_factor);
+ }
+ prep->next_buf_row = cinfo->max_v_samp_factor;
+ }
+ /* If we've filled the conversion buffer, empty it. */
+ if (prep->next_buf_row == cinfo->max_v_samp_factor) {
+ (*cinfo->downsample->downsample) (cinfo,
+ prep->color_buf, (JDIMENSION) 0,
+ output_buf, *out_row_group_ctr);
+ prep->next_buf_row = 0;
+ (*out_row_group_ctr)++;
+ }
+ /* If at bottom of image, pad the output to a full iMCU height.
+ * Note we assume the caller is providing a one-iMCU-height output buffer!
+ */
+ if (prep->rows_to_go == 0 &&
+ *out_row_group_ctr < out_row_groups_avail) {
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ expand_bottom_edge(output_buf[ci],
+ compptr->width_in_blocks * DCTSIZE,
+ (int) (*out_row_group_ctr * compptr->v_samp_factor),
+ (int) (out_row_groups_avail * compptr->v_samp_factor));
+ }
+ *out_row_group_ctr = out_row_groups_avail;
+ break; /* can exit outer loop without test */
+ }
+ }
+}
+
+
+#ifdef CONTEXT_ROWS_SUPPORTED
+
+/*
+ * Process some data in the context case.
+ */
+
+METHODDEF(void)
+pre_process_context (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail,
+ JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
+ JDIMENSION out_row_groups_avail)
+{
+ my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+ int numrows, ci;
+ int buf_height = cinfo->max_v_samp_factor * 3;
+ JDIMENSION inrows;
+
+ while (*out_row_group_ctr < out_row_groups_avail) {
+ if (*in_row_ctr < in_rows_avail) {
+ /* Do color conversion to fill the conversion buffer. */
+ inrows = in_rows_avail - *in_row_ctr;
+ numrows = prep->next_buf_stop - prep->next_buf_row;
+ numrows = (int) MIN((JDIMENSION) numrows, inrows);
+ (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
+ prep->color_buf,
+ (JDIMENSION) prep->next_buf_row,
+ numrows);
+ /* Pad at top of image, if first time through */
+ if (prep->rows_to_go == cinfo->image_height) {
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ int row;
+ for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
+ jcopy_sample_rows(prep->color_buf[ci], 0,
+ prep->color_buf[ci], -row,
+ 1, cinfo->image_width);
+ }
+ }
+ }
+ *in_row_ctr += numrows;
+ prep->next_buf_row += numrows;
+ prep->rows_to_go -= numrows;
+ } else {
+ /* Return for more data, unless we are at the bottom of the image. */
+ if (prep->rows_to_go != 0)
+ break;
+ /* When at bottom of image, pad to fill the conversion buffer. */
+ if (prep->next_buf_row < prep->next_buf_stop) {
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
+ prep->next_buf_row, prep->next_buf_stop);
+ }
+ prep->next_buf_row = prep->next_buf_stop;
+ }
+ }
+ /* If we've gotten enough data, downsample a row group. */
+ if (prep->next_buf_row == prep->next_buf_stop) {
+ (*cinfo->downsample->downsample) (cinfo,
+ prep->color_buf,
+ (JDIMENSION) prep->this_row_group,
+ output_buf, *out_row_group_ctr);
+ (*out_row_group_ctr)++;
+ /* Advance pointers with wraparound as necessary. */
+ prep->this_row_group += cinfo->max_v_samp_factor;
+ if (prep->this_row_group >= buf_height)
+ prep->this_row_group = 0;
+ if (prep->next_buf_row >= buf_height)
+ prep->next_buf_row = 0;
+ prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
+ }
+ }
+}
+
+
+/*
+ * Create the wrapped-around downsampling input buffer needed for context mode.
+ */
+
+LOCAL(void)
+create_context_buffer (j_compress_ptr cinfo)
+{
+ my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+ int rgroup_height = cinfo->max_v_samp_factor;
+ int ci, i;
+ jpeg_component_info * compptr;
+ JSAMPARRAY true_buffer, fake_buffer;
+
+ /* Grab enough space for fake row pointers for all the components;
+ * we need five row groups' worth of pointers for each component.
+ */
+ fake_buffer = (JSAMPARRAY)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (cinfo->num_components * 5 * rgroup_height) *
+ SIZEOF(JSAMPROW));
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Allocate the actual buffer space (3 row groups) for this component.
+ * We make the buffer wide enough to allow the downsampler to edge-expand
+ * horizontally within the buffer, if it so chooses.
+ */
+ true_buffer = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
+ cinfo->max_h_samp_factor) / compptr->h_samp_factor),
+ (JDIMENSION) (3 * rgroup_height));
+ /* Copy true buffer row pointers into the middle of the fake row array */
+ MEMCOPY(fake_buffer + rgroup_height, true_buffer,
+ 3 * rgroup_height * SIZEOF(JSAMPROW));
+ /* Fill in the above and below wraparound pointers */
+ for (i = 0; i < rgroup_height; i++) {
+ fake_buffer[i] = true_buffer[2 * rgroup_height + i];
+ fake_buffer[4 * rgroup_height + i] = true_buffer[i];
+ }
+ prep->color_buf[ci] = fake_buffer + rgroup_height;
+ fake_buffer += 5 * rgroup_height; /* point to space for next component */
+ }
+}
+
+#endif /* CONTEXT_ROWS_SUPPORTED */
+
+
+/*
+ * Initialize preprocessing controller.
+ */
+
+GLOBAL(void)
+jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
+{
+ my_prep_ptr prep;
+ int ci;
+ jpeg_component_info * compptr;
+
+ if (need_full_buffer) /* safety check */
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+ prep = (my_prep_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_prep_controller));
+ cinfo->prep = (struct jpeg_c_prep_controller *) prep;
+ prep->pub.start_pass = start_pass_prep;
+
+ /* Allocate the color conversion buffer.
+ * We make the buffer wide enough to allow the downsampler to edge-expand
+ * horizontally within the buffer, if it so chooses.
+ */
+ if (cinfo->downsample->need_context_rows) {
+ /* Set up to provide context rows */
+#ifdef CONTEXT_ROWS_SUPPORTED
+ prep->pub.pre_process_data = pre_process_context;
+ create_context_buffer(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ /* No context, just make it tall enough for one row group */
+ prep->pub.pre_process_data = pre_process_data;
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
+ cinfo->max_h_samp_factor) / compptr->h_samp_factor),
+ (JDIMENSION) cinfo->max_v_samp_factor);
+ }
+ }
+}
diff --git a/src/libjpeg-turbo/jcsample.c b/src/libjpeg-turbo/jcsample.c
new file mode 100644
index 0000000..eea376f
--- /dev/null
+++ b/src/libjpeg-turbo/jcsample.c
@@ -0,0 +1,527 @@
+/*
+ * jcsample.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains downsampling routines.
+ *
+ * Downsampling input data is counted in "row groups". A row group
+ * is defined to be max_v_samp_factor pixel rows of each component,
+ * from which the downsampler produces v_samp_factor sample rows.
+ * A single row group is processed in each call to the downsampler module.
+ *
+ * The downsampler is responsible for edge-expansion of its output data
+ * to fill an integral number of DCT blocks horizontally. The source buffer
+ * may be modified if it is helpful for this purpose (the source buffer is
+ * allocated wide enough to correspond to the desired output width).
+ * The caller (the prep controller) is responsible for vertical padding.
+ *
+ * The downsampler may request "context rows" by setting need_context_rows
+ * during startup. In this case, the input arrays will contain at least
+ * one row group's worth of pixels above and below the passed-in data;
+ * the caller will create dummy rows at image top and bottom by replicating
+ * the first or last real pixel row.
+ *
+ * An excellent reference for image resampling is
+ * Digital Image Warping, George Wolberg, 1990.
+ * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
+ *
+ * The downsampling algorithm used here is a simple average of the source
+ * pixels covered by the output pixel. The hi-falutin sampling literature
+ * refers to this as a "box filter". In general the characteristics of a box
+ * filter are not very good, but for the specific cases we normally use (1:1
+ * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not
+ * nearly so bad. If you intend to use other sampling ratios, you'd be well
+ * advised to improve this code.
+ *
+ * A simple input-smoothing capability is provided. This is mainly intended
+ * for cleaning up color-dithered GIF input files (if you find it inadequate,
+ * we suggest using an external filtering program such as pnmconvol). When
+ * enabled, each input pixel P is replaced by a weighted sum of itself and its
+ * eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF,
+ * where SF = (smoothing_factor / 1024).
+ * Currently, smoothing is only supported for 2h2v sampling factors.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jsimd.h"
+
+
+/* Pointer to routine to downsample a single component */
+typedef JMETHOD(void, downsample1_ptr,
+ (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data));
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_downsampler pub; /* public fields */
+
+ /* Downsampling method pointers, one per component */
+ downsample1_ptr methods[MAX_COMPONENTS];
+} my_downsampler;
+
+typedef my_downsampler * my_downsample_ptr;
+
+
+/*
+ * Initialize for a downsampling pass.
+ */
+
+METHODDEF(void)
+start_pass_downsample (j_compress_ptr cinfo)
+{
+ /* no work for now */
+}
+
+
+/*
+ * Expand a component horizontally from width input_cols to width output_cols,
+ * by duplicating the rightmost samples.
+ */
+
+LOCAL(void)
+expand_right_edge (JSAMPARRAY image_data, int num_rows,
+ JDIMENSION input_cols, JDIMENSION output_cols)
+{
+ register JSAMPROW ptr;
+ register JSAMPLE pixval;
+ register int count;
+ int row;
+ int numcols = (int) (output_cols - input_cols);
+
+ if (numcols > 0) {
+ for (row = 0; row < num_rows; row++) {
+ ptr = image_data[row] + input_cols;
+ pixval = ptr[-1]; /* don't need GETJSAMPLE() here */
+ for (count = numcols; count > 0; count--)
+ *ptr++ = pixval;
+ }
+ }
+}
+
+
+/*
+ * Do downsampling for a whole row group (all components).
+ *
+ * In this version we simply downsample each component independently.
+ */
+
+METHODDEF(void)
+sep_downsample (j_compress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_index,
+ JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)
+{
+ my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample;
+ int ci;
+ jpeg_component_info * compptr;
+ JSAMPARRAY in_ptr, out_ptr;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ in_ptr = input_buf[ci] + in_row_index;
+ out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor);
+ (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr);
+ }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * One row group is processed per call.
+ * This version handles arbitrary integral sampling ratios, without smoothing.
+ * Note that this version is not actually used for customary sampling ratios.
+ */
+
+METHODDEF(void)
+int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
+ JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */
+ JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+ JSAMPROW inptr, outptr;
+ INT32 outvalue;
+
+ h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
+ v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
+ numpix = h_expand * v_expand;
+ numpix2 = numpix/2;
+
+ /* Expand input data enough to let all the output samples be generated
+ * by the standard loop. Special-casing padded output would be more
+ * efficient.
+ */
+ expand_right_edge(input_data, cinfo->max_v_samp_factor,
+ cinfo->image_width, output_cols * h_expand);
+
+ inrow = 0;
+ for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+ outptr = output_data[outrow];
+ for (outcol = 0, outcol_h = 0; outcol < output_cols;
+ outcol++, outcol_h += h_expand) {
+ outvalue = 0;
+ for (v = 0; v < v_expand; v++) {
+ inptr = input_data[inrow+v] + outcol_h;
+ for (h = 0; h < h_expand; h++) {
+ outvalue += (INT32) GETJSAMPLE(*inptr++);
+ }
+ }
+ *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
+ }
+ inrow += v_expand;
+ }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the special case of a full-size component,
+ * without smoothing.
+ */
+
+METHODDEF(void)
+fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ /* Copy the data */
+ jcopy_sample_rows(input_data, 0, output_data, 0,
+ cinfo->max_v_samp_factor, cinfo->image_width);
+ /* Edge-expand */
+ expand_right_edge(output_data, cinfo->max_v_samp_factor,
+ cinfo->image_width, compptr->width_in_blocks * DCTSIZE);
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the common case of 2:1 horizontal and 1:1 vertical,
+ * without smoothing.
+ *
+ * A note about the "bias" calculations: when rounding fractional values to
+ * integer, we do not want to always round 0.5 up to the next integer.
+ * If we did that, we'd introduce a noticeable bias towards larger values.
+ * Instead, this code is arranged so that 0.5 will be rounded up or down at
+ * alternate pixel locations (a simple ordered dither pattern).
+ */
+
+METHODDEF(void)
+h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ int outrow;
+ JDIMENSION outcol;
+ JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+ register JSAMPROW inptr, outptr;
+ register int bias;
+
+ /* Expand input data enough to let all the output samples be generated
+ * by the standard loop. Special-casing padded output would be more
+ * efficient.
+ */
+ expand_right_edge(input_data, cinfo->max_v_samp_factor,
+ cinfo->image_width, output_cols * 2);
+
+ for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+ outptr = output_data[outrow];
+ inptr = input_data[outrow];
+ bias = 0; /* bias = 0,1,0,1,... for successive samples */
+ for (outcol = 0; outcol < output_cols; outcol++) {
+ *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])
+ + bias) >> 1);
+ bias ^= 1; /* 0=>1, 1=>0 */
+ inptr += 2;
+ }
+ }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
+ * without smoothing.
+ */
+
+METHODDEF(void)
+h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ int inrow, outrow;
+ JDIMENSION outcol;
+ JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+ register JSAMPROW inptr0, inptr1, outptr;
+ register int bias;
+
+ /* Expand input data enough to let all the output samples be generated
+ * by the standard loop. Special-casing padded output would be more
+ * efficient.
+ */
+ expand_right_edge(input_data, cinfo->max_v_samp_factor,
+ cinfo->image_width, output_cols * 2);
+
+ inrow = 0;
+ for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+ outptr = output_data[outrow];
+ inptr0 = input_data[inrow];
+ inptr1 = input_data[inrow+1];
+ bias = 1; /* bias = 1,2,1,2,... for successive samples */
+ for (outcol = 0; outcol < output_cols; outcol++) {
+ *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+ GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1])
+ + bias) >> 2);
+ bias ^= 3; /* 1=>2, 2=>1 */
+ inptr0 += 2; inptr1 += 2;
+ }
+ inrow += 2;
+ }
+}
+
+
+#ifdef INPUT_SMOOTHING_SUPPORTED
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
+ * with smoothing. One row of context is required.
+ */
+
+METHODDEF(void)
+h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ int inrow, outrow;
+ JDIMENSION colctr;
+ JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+ register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
+ INT32 membersum, neighsum, memberscale, neighscale;
+
+ /* Expand input data enough to let all the output samples be generated
+ * by the standard loop. Special-casing padded output would be more
+ * efficient.
+ */
+ expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
+ cinfo->image_width, output_cols * 2);
+
+ /* We don't bother to form the individual "smoothed" input pixel values;
+ * we can directly compute the output which is the average of the four
+ * smoothed values. Each of the four member pixels contributes a fraction
+ * (1-8*SF) to its own smoothed image and a fraction SF to each of the three
+ * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
+ * output. The four corner-adjacent neighbor pixels contribute a fraction
+ * SF to just one smoothed pixel, or SF/4 to the final output; while the
+ * eight edge-adjacent neighbors contribute SF to each of two smoothed
+ * pixels, or SF/2 overall. In order to use integer arithmetic, these
+ * factors are scaled by 2^16 = 65536.
+ * Also recall that SF = smoothing_factor / 1024.
+ */
+
+ memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
+ neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */
+
+ inrow = 0;
+ for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+ outptr = output_data[outrow];
+ inptr0 = input_data[inrow];
+ inptr1 = input_data[inrow+1];
+ above_ptr = input_data[inrow-1];
+ below_ptr = input_data[inrow+2];
+
+ /* Special case for first column: pretend column -1 is same as column 0 */
+ membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+ GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
+ neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
+ GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
+ GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
+ GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
+ neighsum += neighsum;
+ neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
+ GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
+ membersum = membersum * memberscale + neighsum * neighscale;
+ *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+ inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
+
+ for (colctr = output_cols - 2; colctr > 0; colctr--) {
+ /* sum of pixels directly mapped to this output element */
+ membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+ GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
+ /* sum of edge-neighbor pixels */
+ neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
+ GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
+ GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
+ GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
+ /* The edge-neighbors count twice as much as corner-neighbors */
+ neighsum += neighsum;
+ /* Add in the corner-neighbors */
+ neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
+ GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
+ /* form final output scaled up by 2^16 */
+ membersum = membersum * memberscale + neighsum * neighscale;
+ /* round, descale and output it */
+ *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+ inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
+ }
+
+ /* Special case for last column */
+ membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+ GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
+ neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
+ GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
+ GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
+ GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
+ neighsum += neighsum;
+ neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
+ GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
+ membersum = membersum * memberscale + neighsum * neighscale;
+ *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
+
+ inrow += 2;
+ }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the special case of a full-size component,
+ * with smoothing. One row of context is required.
+ */
+
+METHODDEF(void)
+fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ int outrow;
+ JDIMENSION colctr;
+ JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+ register JSAMPROW inptr, above_ptr, below_ptr, outptr;
+ INT32 membersum, neighsum, memberscale, neighscale;
+ int colsum, lastcolsum, nextcolsum;
+
+ /* Expand input data enough to let all the output samples be generated
+ * by the standard loop. Special-casing padded output would be more
+ * efficient.
+ */
+ expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
+ cinfo->image_width, output_cols);
+
+ /* Each of the eight neighbor pixels contributes a fraction SF to the
+ * smoothed pixel, while the main pixel contributes (1-8*SF). In order
+ * to use integer arithmetic, these factors are multiplied by 2^16 = 65536.
+ * Also recall that SF = smoothing_factor / 1024.
+ */
+
+ memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
+ neighscale = cinfo->smoothing_factor * 64; /* scaled SF */
+
+ for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+ outptr = output_data[outrow];
+ inptr = input_data[outrow];
+ above_ptr = input_data[outrow-1];
+ below_ptr = input_data[outrow+1];
+
+ /* Special case for first column */
+ colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
+ GETJSAMPLE(*inptr);
+ membersum = GETJSAMPLE(*inptr++);
+ nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
+ GETJSAMPLE(*inptr);
+ neighsum = colsum + (colsum - membersum) + nextcolsum;
+ membersum = membersum * memberscale + neighsum * neighscale;
+ *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+ lastcolsum = colsum; colsum = nextcolsum;
+
+ for (colctr = output_cols - 2; colctr > 0; colctr--) {
+ membersum = GETJSAMPLE(*inptr++);
+ above_ptr++; below_ptr++;
+ nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
+ GETJSAMPLE(*inptr);
+ neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
+ membersum = membersum * memberscale + neighsum * neighscale;
+ *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+ lastcolsum = colsum; colsum = nextcolsum;
+ }
+
+ /* Special case for last column */
+ membersum = GETJSAMPLE(*inptr);
+ neighsum = lastcolsum + (colsum - membersum) + colsum;
+ membersum = membersum * memberscale + neighsum * neighscale;
+ *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
+
+ }
+}
+
+#endif /* INPUT_SMOOTHING_SUPPORTED */
+
+
+/*
+ * Module initialization routine for downsampling.
+ * Note that we must select a routine for each component.
+ */
+
+GLOBAL(void)
+jinit_downsampler (j_compress_ptr cinfo)
+{
+ my_downsample_ptr downsample;
+ int ci;
+ jpeg_component_info * compptr;
+ boolean smoothok = TRUE;
+
+ downsample = (my_downsample_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_downsampler));
+ cinfo->downsample = (struct jpeg_downsampler *) downsample;
+ downsample->pub.start_pass = start_pass_downsample;
+ downsample->pub.downsample = sep_downsample;
+ downsample->pub.need_context_rows = FALSE;
+
+ if (cinfo->CCIR601_sampling)
+ ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
+
+ /* Verify we can handle the sampling factors, and set up method pointers */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
+ compptr->v_samp_factor == cinfo->max_v_samp_factor) {
+#ifdef INPUT_SMOOTHING_SUPPORTED
+ if (cinfo->smoothing_factor) {
+ downsample->methods[ci] = fullsize_smooth_downsample;
+ downsample->pub.need_context_rows = TRUE;
+ } else
+#endif
+ downsample->methods[ci] = fullsize_downsample;
+ } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
+ compptr->v_samp_factor == cinfo->max_v_samp_factor) {
+ smoothok = FALSE;
+ if (jsimd_can_h2v1_downsample())
+ downsample->methods[ci] = jsimd_h2v1_downsample;
+ else
+ downsample->methods[ci] = h2v1_downsample;
+ } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
+ compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
+#ifdef INPUT_SMOOTHING_SUPPORTED
+ if (cinfo->smoothing_factor) {
+ downsample->methods[ci] = h2v2_smooth_downsample;
+ downsample->pub.need_context_rows = TRUE;
+ } else
+#endif
+ if (jsimd_can_h2v2_downsample())
+ downsample->methods[ci] = jsimd_h2v2_downsample;
+ else
+ downsample->methods[ci] = h2v2_downsample;
+ } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
+ (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
+ smoothok = FALSE;
+ downsample->methods[ci] = int_downsample;
+ } else
+ ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
+ }
+
+#ifdef INPUT_SMOOTHING_SUPPORTED
+ if (cinfo->smoothing_factor && !smoothok)
+ TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL);
+#endif
+}
diff --git a/src/libjpeg-turbo/jctrans.c b/src/libjpeg-turbo/jctrans.c
new file mode 100644
index 0000000..916e872
--- /dev/null
+++ b/src/libjpeg-turbo/jctrans.c
@@ -0,0 +1,399 @@
+/*
+ * jctrans.c
+ *
+ * Copyright (C) 1995-1998, Thomas G. Lane.
+ * Modified 2000-2009 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains library routines for transcoding compression,
+ * that is, writing raw DCT coefficient arrays to an output JPEG file.
+ * The routines in jcapimin.c will also be needed by a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Forward declarations */
+LOCAL(void) transencode_master_selection
+ JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
+LOCAL(void) transencode_coef_controller
+ JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
+
+
+/*
+ * Compression initialization for writing raw-coefficient data.
+ * Before calling this, all parameters and a data destination must be set up.
+ * Call jpeg_finish_compress() to actually write the data.
+ *
+ * The number of passed virtual arrays must match cinfo->num_components.
+ * Note that the virtual arrays need not be filled or even realized at
+ * the time write_coefficients is called; indeed, if the virtual arrays
+ * were requested from this compression object's memory manager, they
+ * typically will be realized during this routine and filled afterwards.
+ */
+
+GLOBAL(void)
+jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
+{
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ /* Mark all tables to be written */
+ jpeg_suppress_tables(cinfo, FALSE);
+ /* (Re)initialize error mgr and destination modules */
+ (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+ (*cinfo->dest->init_destination) (cinfo);
+ /* Perform master selection of active modules */
+ transencode_master_selection(cinfo, coef_arrays);
+ /* Wait for jpeg_finish_compress() call */
+ cinfo->next_scanline = 0; /* so jpeg_write_marker works */
+ cinfo->global_state = CSTATE_WRCOEFS;
+}
+
+
+/*
+ * Initialize the compression object with default parameters,
+ * then copy from the source object all parameters needed for lossless
+ * transcoding. Parameters that can be varied without loss (such as
+ * scan script and Huffman optimization) are left in their default states.
+ */
+
+GLOBAL(void)
+jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
+ j_compress_ptr dstinfo)
+{
+ JQUANT_TBL ** qtblptr;
+ jpeg_component_info *incomp, *outcomp;
+ JQUANT_TBL *c_quant, *slot_quant;
+ int tblno, ci, coefi;
+
+ /* Safety check to ensure start_compress not called yet. */
+ if (dstinfo->global_state != CSTATE_START)
+ ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
+ /* Copy fundamental image dimensions */
+ dstinfo->image_width = srcinfo->image_width;
+ dstinfo->image_height = srcinfo->image_height;
+ dstinfo->input_components = srcinfo->num_components;
+ dstinfo->in_color_space = srcinfo->jpeg_color_space;
+#if JPEG_LIB_VERSION >= 70
+ dstinfo->jpeg_width = srcinfo->output_width;
+ dstinfo->jpeg_height = srcinfo->output_height;
+ dstinfo->min_DCT_h_scaled_size = srcinfo->min_DCT_h_scaled_size;
+ dstinfo->min_DCT_v_scaled_size = srcinfo->min_DCT_v_scaled_size;
+#endif
+ /* Initialize all parameters to default values */
+ jpeg_set_defaults(dstinfo);
+ /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
+ * Fix it to get the right header markers for the image colorspace.
+ */
+ jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
+ dstinfo->data_precision = srcinfo->data_precision;
+ dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
+ /* Copy the source's quantization tables. */
+ for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
+ if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
+ qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
+ if (*qtblptr == NULL)
+ *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
+ MEMCOPY((*qtblptr)->quantval,
+ srcinfo->quant_tbl_ptrs[tblno]->quantval,
+ SIZEOF((*qtblptr)->quantval));
+ (*qtblptr)->sent_table = FALSE;
+ }
+ }
+ /* Copy the source's per-component info.
+ * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
+ */
+ dstinfo->num_components = srcinfo->num_components;
+ if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
+ ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
+ MAX_COMPONENTS);
+ for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
+ ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
+ outcomp->component_id = incomp->component_id;
+ outcomp->h_samp_factor = incomp->h_samp_factor;
+ outcomp->v_samp_factor = incomp->v_samp_factor;
+ outcomp->quant_tbl_no = incomp->quant_tbl_no;
+ /* Make sure saved quantization table for component matches the qtable
+ * slot. If not, the input file re-used this qtable slot.
+ * IJG encoder currently cannot duplicate this.
+ */
+ tblno = outcomp->quant_tbl_no;
+ if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
+ srcinfo->quant_tbl_ptrs[tblno] == NULL)
+ ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
+ slot_quant = srcinfo->quant_tbl_ptrs[tblno];
+ c_quant = incomp->quant_table;
+ if (c_quant != NULL) {
+ for (coefi = 0; coefi < DCTSIZE2; coefi++) {
+ if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
+ ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
+ }
+ }
+ /* Note: we do not copy the source's Huffman table assignments;
+ * instead we rely on jpeg_set_colorspace to have made a suitable choice.
+ */
+ }
+ /* Also copy JFIF version and resolution information, if available.
+ * Strictly speaking this isn't "critical" info, but it's nearly
+ * always appropriate to copy it if available. In particular,
+ * if the application chooses to copy JFIF 1.02 extension markers from
+ * the source file, we need to copy the version to make sure we don't
+ * emit a file that has 1.02 extensions but a claimed version of 1.01.
+ * We will *not*, however, copy version info from mislabeled "2.01" files.
+ */
+ if (srcinfo->saw_JFIF_marker) {
+ if (srcinfo->JFIF_major_version == 1) {
+ dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
+ dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
+ }
+ dstinfo->density_unit = srcinfo->density_unit;
+ dstinfo->X_density = srcinfo->X_density;
+ dstinfo->Y_density = srcinfo->Y_density;
+ }
+}
+
+
+/*
+ * Master selection of compression modules for transcoding.
+ * This substitutes for jcinit.c's initialization of the full compressor.
+ */
+
+LOCAL(void)
+transencode_master_selection (j_compress_ptr cinfo,
+ jvirt_barray_ptr * coef_arrays)
+{
+ /* Although we don't actually use input_components for transcoding,
+ * jcmaster.c's initial_setup will complain if input_components is 0.
+ */
+ cinfo->input_components = 1;
+ /* Initialize master control (includes parameter checking/processing) */
+ jinit_c_master_control(cinfo, TRUE /* transcode only */);
+
+ /* Entropy encoding: either Huffman or arithmetic coding. */
+ if (cinfo->arith_code) {
+#ifdef C_ARITH_CODING_SUPPORTED
+ jinit_arith_encoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+#endif
+ } else {
+ if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+ jinit_phuff_encoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else
+ jinit_huff_encoder(cinfo);
+ }
+
+ /* We need a special coefficient buffer controller. */
+ transencode_coef_controller(cinfo, coef_arrays);
+
+ jinit_marker_writer(cinfo);
+
+ /* We can now tell the memory manager to allocate virtual arrays. */
+ (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+ /* Write the datastream header (SOI, JFIF) immediately.
+ * Frame and scan headers are postponed till later.
+ * This lets application insert special markers after the SOI.
+ */
+ (*cinfo->marker->write_file_header) (cinfo);
+}
+
+
+/*
+ * The rest of this file is a special implementation of the coefficient
+ * buffer controller. This is similar to jccoefct.c, but it handles only
+ * output from presupplied virtual arrays. Furthermore, we generate any
+ * dummy padding blocks on-the-fly rather than expecting them to be present
+ * in the arrays.
+ */
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_c_coef_controller pub; /* public fields */
+
+ JDIMENSION iMCU_row_num; /* iMCU row # within image */
+ JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
+ int MCU_vert_offset; /* counts MCU rows within iMCU row */
+ int MCU_rows_per_iMCU_row; /* number of such rows needed */
+
+ /* Virtual block array for each component. */
+ jvirt_barray_ptr * whole_image;
+
+ /* Workspace for constructing dummy blocks at right/bottom edges. */
+ JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
+} my_coef_controller;
+
+typedef my_coef_controller * my_coef_ptr;
+
+
+LOCAL(void)
+start_iMCU_row (j_compress_ptr cinfo)
+/* Reset within-iMCU-row counters for a new row */
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ /* In an interleaved scan, an MCU row is the same as an iMCU row.
+ * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
+ * But at the bottom of the image, process only what's left.
+ */
+ if (cinfo->comps_in_scan > 1) {
+ coef->MCU_rows_per_iMCU_row = 1;
+ } else {
+ if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
+ else
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
+ }
+
+ coef->mcu_ctr = 0;
+ coef->MCU_vert_offset = 0;
+}
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ if (pass_mode != JBUF_CRANK_DEST)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+ coef->iMCU_row_num = 0;
+ start_iMCU_row(cinfo);
+}
+
+
+/*
+ * Process some data.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the scan.
+ * The data is obtained from the virtual arrays and fed to the entropy coder.
+ * Returns TRUE if the iMCU row is completed, FALSE if suspended.
+ *
+ * NB: input_buf is ignored; it is likely to be a NULL pointer.
+ */
+
+METHODDEF(boolean)
+compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION MCU_col_num; /* index of current MCU within row */
+ JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ int blkn, ci, xindex, yindex, yoffset, blockcnt;
+ JDIMENSION start_col;
+ JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
+ JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
+ JBLOCKROW buffer_ptr;
+ jpeg_component_info *compptr;
+
+ /* Align the virtual buffers for the components used in this scan. */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ buffer[ci] = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
+ coef->iMCU_row_num * compptr->v_samp_factor,
+ (JDIMENSION) compptr->v_samp_factor, FALSE);
+ }
+
+ /* Loop to process one whole iMCU row */
+ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+ yoffset++) {
+ for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
+ MCU_col_num++) {
+ /* Construct list of pointers to DCT blocks belonging to this MCU */
+ blkn = 0; /* index of current DCT block within MCU */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ start_col = MCU_col_num * compptr->MCU_width;
+ blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
+ : compptr->last_col_width;
+ for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+ if (coef->iMCU_row_num < last_iMCU_row ||
+ yindex+yoffset < compptr->last_row_height) {
+ /* Fill in pointers to real blocks in this row */
+ buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
+ for (xindex = 0; xindex < blockcnt; xindex++)
+ MCU_buffer[blkn++] = buffer_ptr++;
+ } else {
+ /* At bottom of image, need a whole row of dummy blocks */
+ xindex = 0;
+ }
+ /* Fill in any dummy blocks needed in this row.
+ * Dummy blocks are filled in the same way as in jccoefct.c:
+ * all zeroes in the AC entries, DC entries equal to previous
+ * block's DC value. The init routine has already zeroed the
+ * AC entries, so we need only set the DC entries correctly.
+ */
+ for (; xindex < compptr->MCU_width; xindex++) {
+ MCU_buffer[blkn] = coef->dummy_buffer[blkn];
+ MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
+ blkn++;
+ }
+ }
+ }
+ /* Try to write the MCU. */
+ if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
+ /* Suspension forced; update state counters and exit */
+ coef->MCU_vert_offset = yoffset;
+ coef->mcu_ctr = MCU_col_num;
+ return FALSE;
+ }
+ }
+ /* Completed an MCU row, but perhaps not an iMCU row */
+ coef->mcu_ctr = 0;
+ }
+ /* Completed the iMCU row, advance counters for next one */
+ coef->iMCU_row_num++;
+ start_iMCU_row(cinfo);
+ return TRUE;
+}
+
+
+/*
+ * Initialize coefficient buffer controller.
+ *
+ * Each passed coefficient array must be the right size for that
+ * coefficient: width_in_blocks wide and height_in_blocks high,
+ * with unitheight at least v_samp_factor.
+ */
+
+LOCAL(void)
+transencode_coef_controller (j_compress_ptr cinfo,
+ jvirt_barray_ptr * coef_arrays)
+{
+ my_coef_ptr coef;
+ JBLOCKROW buffer;
+ int i;
+
+ coef = (my_coef_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_coef_controller));
+ cinfo->coef = (struct jpeg_c_coef_controller *) coef;
+ coef->pub.start_pass = start_pass_coef;
+ coef->pub.compress_data = compress_output;
+
+ /* Save pointer to virtual arrays */
+ coef->whole_image = coef_arrays;
+
+ /* Allocate and pre-zero space for dummy DCT blocks. */
+ buffer = (JBLOCKROW)
+ (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+ jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+ for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
+ coef->dummy_buffer[i] = buffer + i;
+ }
+}
diff --git a/src/libjpeg-turbo/jdapimin.c b/src/libjpeg-turbo/jdapimin.c
new file mode 100644
index 0000000..cadb59f
--- /dev/null
+++ b/src/libjpeg-turbo/jdapimin.c
@@ -0,0 +1,395 @@
+/*
+ * jdapimin.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains application interface code for the decompression half
+ * of the JPEG library. These are the "minimum" API routines that may be
+ * needed in either the normal full-decompression case or the
+ * transcoding-only case.
+ *
+ * Most of the routines intended to be called directly by an application
+ * are in this file or in jdapistd.c. But also see jcomapi.c for routines
+ * shared by compression and decompression, and jdtrans.c for the transcoding
+ * case.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Initialization of a JPEG decompression object.
+ * The error manager must already be set up (in case memory manager fails).
+ */
+
+GLOBAL(void)
+jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
+{
+ int i;
+
+ /* Guard against version mismatches between library and caller. */
+ cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
+ if (version != JPEG_LIB_VERSION)
+ ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
+ if (structsize != SIZEOF(struct jpeg_decompress_struct))
+ ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
+ (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
+
+ /* For debugging purposes, we zero the whole master structure.
+ * But the application has already set the err pointer, and may have set
+ * client_data, so we have to save and restore those fields.
+ * Note: if application hasn't set client_data, tools like Purify may
+ * complain here.
+ */
+ {
+ struct jpeg_error_mgr * err = cinfo->err;
+ void * client_data = cinfo->client_data; /* ignore Purify complaint here */
+ MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
+ cinfo->err = err;
+ cinfo->client_data = client_data;
+ }
+ cinfo->is_decompressor = TRUE;
+
+ /* Initialize a memory manager instance for this object */
+ jinit_memory_mgr((j_common_ptr) cinfo);
+
+ /* Zero out pointers to permanent structures. */
+ cinfo->progress = NULL;
+ cinfo->src = NULL;
+
+ for (i = 0; i < NUM_QUANT_TBLS; i++)
+ cinfo->quant_tbl_ptrs[i] = NULL;
+
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ cinfo->dc_huff_tbl_ptrs[i] = NULL;
+ cinfo->ac_huff_tbl_ptrs[i] = NULL;
+ }
+
+ /* Initialize marker processor so application can override methods
+ * for COM, APPn markers before calling jpeg_read_header.
+ */
+ cinfo->marker_list = NULL;
+ jinit_marker_reader(cinfo);
+
+ /* And initialize the overall input controller. */
+ jinit_input_controller(cinfo);
+
+ /* OK, I'm ready */
+ cinfo->global_state = DSTATE_START;
+}
+
+
+/*
+ * Destruction of a JPEG decompression object
+ */
+
+GLOBAL(void)
+jpeg_destroy_decompress (j_decompress_ptr cinfo)
+{
+ jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Abort processing of a JPEG decompression operation,
+ * but don't destroy the object itself.
+ */
+
+GLOBAL(void)
+jpeg_abort_decompress (j_decompress_ptr cinfo)
+{
+ jpeg_abort((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Set default decompression parameters.
+ */
+
+LOCAL(void)
+default_decompress_parms (j_decompress_ptr cinfo)
+{
+ /* Guess the input colorspace, and set output colorspace accordingly. */
+ /* (Wish JPEG committee had provided a real way to specify this...) */
+ /* Note application may override our guesses. */
+ switch (cinfo->num_components) {
+ case 1:
+ cinfo->jpeg_color_space = JCS_GRAYSCALE;
+ cinfo->out_color_space = JCS_GRAYSCALE;
+ break;
+
+ case 3:
+ if (cinfo->saw_JFIF_marker) {
+ cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
+ } else if (cinfo->saw_Adobe_marker) {
+ switch (cinfo->Adobe_transform) {
+ case 0:
+ cinfo->jpeg_color_space = JCS_RGB;
+ break;
+ case 1:
+ cinfo->jpeg_color_space = JCS_YCbCr;
+ break;
+ default:
+ WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
+ cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
+ break;
+ }
+ } else {
+ /* Saw no special markers, try to guess from the component IDs */
+ int cid0 = cinfo->comp_info[0].component_id;
+ int cid1 = cinfo->comp_info[1].component_id;
+ int cid2 = cinfo->comp_info[2].component_id;
+
+ if (cid0 == 1 && cid1 == 2 && cid2 == 3)
+ cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
+ else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
+ cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
+ else {
+ TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
+ cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
+ }
+ }
+ /* Always guess RGB is proper output colorspace. */
+ cinfo->out_color_space = JCS_RGB;
+ break;
+
+ case 4:
+ if (cinfo->saw_Adobe_marker) {
+ switch (cinfo->Adobe_transform) {
+ case 0:
+ cinfo->jpeg_color_space = JCS_CMYK;
+ break;
+ case 2:
+ cinfo->jpeg_color_space = JCS_YCCK;
+ break;
+ default:
+ WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
+ cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
+ break;
+ }
+ } else {
+ /* No special markers, assume straight CMYK. */
+ cinfo->jpeg_color_space = JCS_CMYK;
+ }
+ cinfo->out_color_space = JCS_CMYK;
+ break;
+
+ default:
+ cinfo->jpeg_color_space = JCS_UNKNOWN;
+ cinfo->out_color_space = JCS_UNKNOWN;
+ break;
+ }
+
+ /* Set defaults for other decompression parameters. */
+ cinfo->scale_num = 1; /* 1:1 scaling */
+ cinfo->scale_denom = 1;
+ cinfo->output_gamma = 1.0;
+ cinfo->buffered_image = FALSE;
+ cinfo->raw_data_out = FALSE;
+ cinfo->dct_method = JDCT_DEFAULT;
+ cinfo->do_fancy_upsampling = TRUE;
+ cinfo->do_block_smoothing = TRUE;
+ cinfo->quantize_colors = FALSE;
+ /* We set these in case application only sets quantize_colors. */
+ cinfo->dither_mode = JDITHER_FS;
+#ifdef QUANT_2PASS_SUPPORTED
+ cinfo->two_pass_quantize = TRUE;
+#else
+ cinfo->two_pass_quantize = FALSE;
+#endif
+ cinfo->desired_number_of_colors = 256;
+ cinfo->colormap = NULL;
+ /* Initialize for no mode change in buffered-image mode. */
+ cinfo->enable_1pass_quant = FALSE;
+ cinfo->enable_external_quant = FALSE;
+ cinfo->enable_2pass_quant = FALSE;
+}
+
+
+/*
+ * Decompression startup: read start of JPEG datastream to see what's there.
+ * Need only initialize JPEG object and supply a data source before calling.
+ *
+ * This routine will read as far as the first SOS marker (ie, actual start of
+ * compressed data), and will save all tables and parameters in the JPEG
+ * object. It will also initialize the decompression parameters to default
+ * values, and finally return JPEG_HEADER_OK. On return, the application may
+ * adjust the decompression parameters and then call jpeg_start_decompress.
+ * (Or, if the application only wanted to determine the image parameters,
+ * the data need not be decompressed. In that case, call jpeg_abort or
+ * jpeg_destroy to release any temporary space.)
+ * If an abbreviated (tables only) datastream is presented, the routine will
+ * return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then
+ * re-use the JPEG object to read the abbreviated image datastream(s).
+ * It is unnecessary (but OK) to call jpeg_abort in this case.
+ * The JPEG_SUSPENDED return code only occurs if the data source module
+ * requests suspension of the decompressor. In this case the application
+ * should load more source data and then re-call jpeg_read_header to resume
+ * processing.
+ * If a non-suspending data source is used and require_image is TRUE, then the
+ * return code need not be inspected since only JPEG_HEADER_OK is possible.
+ *
+ * This routine is now just a front end to jpeg_consume_input, with some
+ * extra error checking.
+ */
+
+GLOBAL(int)
+jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
+{
+ int retcode;
+
+ if (cinfo->global_state != DSTATE_START &&
+ cinfo->global_state != DSTATE_INHEADER)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ retcode = jpeg_consume_input(cinfo);
+
+ switch (retcode) {
+ case JPEG_REACHED_SOS:
+ retcode = JPEG_HEADER_OK;
+ break;
+ case JPEG_REACHED_EOI:
+ if (require_image) /* Complain if application wanted an image */
+ ERREXIT(cinfo, JERR_NO_IMAGE);
+ /* Reset to start state; it would be safer to require the application to
+ * call jpeg_abort, but we can't change it now for compatibility reasons.
+ * A side effect is to free any temporary memory (there shouldn't be any).
+ */
+ jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
+ retcode = JPEG_HEADER_TABLES_ONLY;
+ break;
+ case JPEG_SUSPENDED:
+ /* no work */
+ break;
+ }
+
+ return retcode;
+}
+
+
+/*
+ * Consume data in advance of what the decompressor requires.
+ * This can be called at any time once the decompressor object has
+ * been created and a data source has been set up.
+ *
+ * This routine is essentially a state machine that handles a couple
+ * of critical state-transition actions, namely initial setup and
+ * transition from header scanning to ready-for-start_decompress.
+ * All the actual input is done via the input controller's consume_input
+ * method.
+ */
+
+GLOBAL(int)
+jpeg_consume_input (j_decompress_ptr cinfo)
+{
+ int retcode = JPEG_SUSPENDED;
+
+ /* NB: every possible DSTATE value should be listed in this switch */
+ switch (cinfo->global_state) {
+ case DSTATE_START:
+ /* Start-of-datastream actions: reset appropriate modules */
+ (*cinfo->inputctl->reset_input_controller) (cinfo);
+ /* Initialize application's data source module */
+ (*cinfo->src->init_source) (cinfo);
+ cinfo->global_state = DSTATE_INHEADER;
+ /*FALLTHROUGH*/
+ case DSTATE_INHEADER:
+ retcode = (*cinfo->inputctl->consume_input) (cinfo);
+ if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
+ /* Set up default parameters based on header data */
+ default_decompress_parms(cinfo);
+ /* Set global state: ready for start_decompress */
+ cinfo->global_state = DSTATE_READY;
+ }
+ break;
+ case DSTATE_READY:
+ /* Can't advance past first SOS until start_decompress is called */
+ retcode = JPEG_REACHED_SOS;
+ break;
+ case DSTATE_PRELOAD:
+ case DSTATE_PRESCAN:
+ case DSTATE_SCANNING:
+ case DSTATE_RAW_OK:
+ case DSTATE_BUFIMAGE:
+ case DSTATE_BUFPOST:
+ case DSTATE_STOPPING:
+ retcode = (*cinfo->inputctl->consume_input) (cinfo);
+ break;
+ default:
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ }
+ return retcode;
+}
+
+
+/*
+ * Have we finished reading the input file?
+ */
+
+GLOBAL(boolean)
+jpeg_input_complete (j_decompress_ptr cinfo)
+{
+ /* Check for valid jpeg object */
+ if (cinfo->global_state < DSTATE_START ||
+ cinfo->global_state > DSTATE_STOPPING)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ return cinfo->inputctl->eoi_reached;
+}
+
+
+/*
+ * Is there more than one scan?
+ */
+
+GLOBAL(boolean)
+jpeg_has_multiple_scans (j_decompress_ptr cinfo)
+{
+ /* Only valid after jpeg_read_header completes */
+ if (cinfo->global_state < DSTATE_READY ||
+ cinfo->global_state > DSTATE_STOPPING)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ return cinfo->inputctl->has_multiple_scans;
+}
+
+
+/*
+ * Finish JPEG decompression.
+ *
+ * This will normally just verify the file trailer and release temp storage.
+ *
+ * Returns FALSE if suspended. The return value need be inspected only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(boolean)
+jpeg_finish_decompress (j_decompress_ptr cinfo)
+{
+ if ((cinfo->global_state == DSTATE_SCANNING ||
+ cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) {
+ /* Terminate final pass of non-buffered mode */
+ if (cinfo->output_scanline < cinfo->output_height)
+ ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
+ (*cinfo->master->finish_output_pass) (cinfo);
+ cinfo->global_state = DSTATE_STOPPING;
+ } else if (cinfo->global_state == DSTATE_BUFIMAGE) {
+ /* Finishing after a buffered-image operation */
+ cinfo->global_state = DSTATE_STOPPING;
+ } else if (cinfo->global_state != DSTATE_STOPPING) {
+ /* STOPPING = repeat call after a suspension, anything else is error */
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ }
+ /* Read until EOI */
+ while (! cinfo->inputctl->eoi_reached) {
+ if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
+ return FALSE; /* Suspend, come back later */
+ }
+ /* Do final cleanup */
+ (*cinfo->src->term_source) (cinfo);
+ /* We can use jpeg_abort to release memory and reset global_state */
+ jpeg_abort((j_common_ptr) cinfo);
+ return TRUE;
+}
diff --git a/src/libjpeg-turbo/jdapistd.c b/src/libjpeg-turbo/jdapistd.c
new file mode 100644
index 0000000..2343da5
--- /dev/null
+++ b/src/libjpeg-turbo/jdapistd.c
@@ -0,0 +1,277 @@
+/*
+ * jdapistd.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 2010, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains application interface code for the decompression half
+ * of the JPEG library. These are the "standard" API routines that are
+ * used in the normal full-decompression case. They are not used by a
+ * transcoding-only application. Note that if an application links in
+ * jpeg_start_decompress, it will end up linking in the entire decompressor.
+ * We thus must separate this file from jdapimin.c to avoid linking the
+ * whole decompression library into a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jpegcomp.h"
+
+
+/* Forward declarations */
+LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
+
+
+/*
+ * Decompression initialization.
+ * jpeg_read_header must be completed before calling this.
+ *
+ * If a multipass operating mode was selected, this will do all but the
+ * last pass, and thus may take a great deal of time.
+ *
+ * Returns FALSE if suspended. The return value need be inspected only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(boolean)
+jpeg_start_decompress (j_decompress_ptr cinfo)
+{
+ if (cinfo->global_state == DSTATE_READY) {
+ /* First call: initialize master control, select active modules */
+ jinit_master_decompress(cinfo);
+ if (cinfo->buffered_image) {
+ /* No more work here; expecting jpeg_start_output next */
+ cinfo->global_state = DSTATE_BUFIMAGE;
+ return TRUE;
+ }
+ cinfo->global_state = DSTATE_PRELOAD;
+ }
+ if (cinfo->global_state == DSTATE_PRELOAD) {
+ /* If file has multiple scans, absorb them all into the coef buffer */
+ if (cinfo->inputctl->has_multiple_scans) {
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+ for (;;) {
+ int retcode;
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL)
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ /* Absorb some more input */
+ retcode = (*cinfo->inputctl->consume_input) (cinfo);
+ if (retcode == JPEG_SUSPENDED)
+ return FALSE;
+ if (retcode == JPEG_REACHED_EOI)
+ break;
+ /* Advance progress counter if appropriate */
+ if (cinfo->progress != NULL &&
+ (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
+ if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
+ /* jdmaster underestimated number of scans; ratchet up one scan */
+ cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
+ }
+ }
+ }
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+ }
+ cinfo->output_scan_number = cinfo->input_scan_number;
+ } else if (cinfo->global_state != DSTATE_PRESCAN)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ /* Perform any dummy output passes, and set up for the final pass */
+ return output_pass_setup(cinfo);
+}
+
+
+/*
+ * Set up for an output pass, and perform any dummy pass(es) needed.
+ * Common subroutine for jpeg_start_decompress and jpeg_start_output.
+ * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
+ * Exit: If done, returns TRUE and sets global_state for proper output mode.
+ * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
+ */
+
+LOCAL(boolean)
+output_pass_setup (j_decompress_ptr cinfo)
+{
+ if (cinfo->global_state != DSTATE_PRESCAN) {
+ /* First call: do pass setup */
+ (*cinfo->master->prepare_for_output_pass) (cinfo);
+ cinfo->output_scanline = 0;
+ cinfo->global_state = DSTATE_PRESCAN;
+ }
+ /* Loop over any required dummy passes */
+ while (cinfo->master->is_dummy_pass) {
+#ifdef QUANT_2PASS_SUPPORTED
+ /* Crank through the dummy pass */
+ while (cinfo->output_scanline < cinfo->output_height) {
+ JDIMENSION last_scanline;
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) cinfo->output_scanline;
+ cinfo->progress->pass_limit = (long) cinfo->output_height;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+ /* Process some data */
+ last_scanline = cinfo->output_scanline;
+ (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
+ &cinfo->output_scanline, (JDIMENSION) 0);
+ if (cinfo->output_scanline == last_scanline)
+ return FALSE; /* No progress made, must suspend */
+ }
+ /* Finish up dummy pass, and set up for another one */
+ (*cinfo->master->finish_output_pass) (cinfo);
+ (*cinfo->master->prepare_for_output_pass) (cinfo);
+ cinfo->output_scanline = 0;
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif /* QUANT_2PASS_SUPPORTED */
+ }
+ /* Ready for application to drive output pass through
+ * jpeg_read_scanlines or jpeg_read_raw_data.
+ */
+ cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
+ return TRUE;
+}
+
+
+/*
+ * Read some scanlines of data from the JPEG decompressor.
+ *
+ * The return value will be the number of lines actually read.
+ * This may be less than the number requested in several cases,
+ * including bottom of image, data source suspension, and operating
+ * modes that emit multiple scanlines at a time.
+ *
+ * Note: we warn about excess calls to jpeg_read_scanlines() since
+ * this likely signals an application programmer error. However,
+ * an oversize buffer (max_lines > scanlines remaining) is not an error.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
+ JDIMENSION max_lines)
+{
+ JDIMENSION row_ctr;
+
+ if (cinfo->global_state != DSTATE_SCANNING)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ if (cinfo->output_scanline >= cinfo->output_height) {
+ WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+ return 0;
+ }
+
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) cinfo->output_scanline;
+ cinfo->progress->pass_limit = (long) cinfo->output_height;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+
+ /* Process some data */
+ row_ctr = 0;
+ (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
+ cinfo->output_scanline += row_ctr;
+ return row_ctr;
+}
+
+
+/*
+ * Alternate entry point to read raw data.
+ * Processes exactly one iMCU row per call, unless suspended.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
+ JDIMENSION max_lines)
+{
+ JDIMENSION lines_per_iMCU_row;
+
+ if (cinfo->global_state != DSTATE_RAW_OK)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ if (cinfo->output_scanline >= cinfo->output_height) {
+ WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+ return 0;
+ }
+
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) cinfo->output_scanline;
+ cinfo->progress->pass_limit = (long) cinfo->output_height;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+
+ /* Verify that at least one iMCU row can be returned. */
+ lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->_min_DCT_scaled_size;
+ if (max_lines < lines_per_iMCU_row)
+ ERREXIT(cinfo, JERR_BUFFER_SIZE);
+
+ /* Decompress directly into user's buffer. */
+ if (! (*cinfo->coef->decompress_data) (cinfo, data))
+ return 0; /* suspension forced, can do nothing more */
+
+ /* OK, we processed one iMCU row. */
+ cinfo->output_scanline += lines_per_iMCU_row;
+ return lines_per_iMCU_row;
+}
+
+
+/* Additional entry points for buffered-image mode. */
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+
+/*
+ * Initialize for an output pass in buffered-image mode.
+ */
+
+GLOBAL(boolean)
+jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
+{
+ if (cinfo->global_state != DSTATE_BUFIMAGE &&
+ cinfo->global_state != DSTATE_PRESCAN)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ /* Limit scan number to valid range */
+ if (scan_number <= 0)
+ scan_number = 1;
+ if (cinfo->inputctl->eoi_reached &&
+ scan_number > cinfo->input_scan_number)
+ scan_number = cinfo->input_scan_number;
+ cinfo->output_scan_number = scan_number;
+ /* Perform any dummy output passes, and set up for the real pass */
+ return output_pass_setup(cinfo);
+}
+
+
+/*
+ * Finish up after an output pass in buffered-image mode.
+ *
+ * Returns FALSE if suspended. The return value need be inspected only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(boolean)
+jpeg_finish_output (j_decompress_ptr cinfo)
+{
+ if ((cinfo->global_state == DSTATE_SCANNING ||
+ cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
+ /* Terminate this pass. */
+ /* We do not require the whole pass to have been completed. */
+ (*cinfo->master->finish_output_pass) (cinfo);
+ cinfo->global_state = DSTATE_BUFPOST;
+ } else if (cinfo->global_state != DSTATE_BUFPOST) {
+ /* BUFPOST = repeat call after a suspension, anything else is error */
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ }
+ /* Read markers looking for SOS or EOI */
+ while (cinfo->input_scan_number <= cinfo->output_scan_number &&
+ ! cinfo->inputctl->eoi_reached) {
+ if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
+ return FALSE; /* Suspend, come back later */
+ }
+ cinfo->global_state = DSTATE_BUFIMAGE;
+ return TRUE;
+}
+
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
diff --git a/src/libjpeg-turbo/jdarith.c b/src/libjpeg-turbo/jdarith.c
new file mode 100644
index 0000000..d556733
--- /dev/null
+++ b/src/libjpeg-turbo/jdarith.c
@@ -0,0 +1,761 @@
+/*
+ * jdarith.c
+ *
+ * Developed 1997-2009 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains portable arithmetic entropy decoding routines for JPEG
+ * (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
+ *
+ * Both sequential and progressive modes are supported in this single module.
+ *
+ * Suspension is not currently supported in this module.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Expanded entropy decoder object for arithmetic decoding. */
+
+typedef struct {
+ struct jpeg_entropy_decoder pub; /* public fields */
+
+ INT32 c; /* C register, base of coding interval + input bit buffer */
+ INT32 a; /* A register, normalized size of coding interval */
+ int ct; /* bit shift counter, # of bits left in bit buffer part of C */
+ /* init: ct = -16 */
+ /* run: ct = 0..7 */
+ /* error: ct = -1 */
+ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+ int dc_context[MAX_COMPS_IN_SCAN]; /* context index for DC conditioning */
+
+ unsigned int restarts_to_go; /* MCUs left in this restart interval */
+
+ /* Pointers to statistics areas (these workspaces have image lifespan) */
+ unsigned char * dc_stats[NUM_ARITH_TBLS];
+ unsigned char * ac_stats[NUM_ARITH_TBLS];
+
+ /* Statistics bin for coding with fixed probability 0.5 */
+ unsigned char fixed_bin[4];
+} arith_entropy_decoder;
+
+typedef arith_entropy_decoder * arith_entropy_ptr;
+
+/* The following two definitions specify the allocation chunk size
+ * for the statistics area.
+ * According to sections F.1.4.4.1.3 and F.1.4.4.2, we need at least
+ * 49 statistics bins for DC, and 245 statistics bins for AC coding.
+ *
+ * We use a compact representation with 1 byte per statistics bin,
+ * thus the numbers directly represent byte sizes.
+ * This 1 byte per statistics bin contains the meaning of the MPS
+ * (more probable symbol) in the highest bit (mask 0x80), and the
+ * index into the probability estimation state machine table
+ * in the lower bits (mask 0x7F).
+ */
+
+#define DC_STAT_BINS 64
+#define AC_STAT_BINS 256
+
+
+LOCAL(int)
+get_byte (j_decompress_ptr cinfo)
+/* Read next input byte; we do not support suspension in this module. */
+{
+ struct jpeg_source_mgr * src = cinfo->src;
+
+ if (src->bytes_in_buffer == 0)
+ if (! (*src->fill_input_buffer) (cinfo))
+ ERREXIT(cinfo, JERR_CANT_SUSPEND);
+ src->bytes_in_buffer--;
+ return GETJOCTET(*src->next_input_byte++);
+}
+
+
+/*
+ * The core arithmetic decoding routine (common in JPEG and JBIG).
+ * This needs to go as fast as possible.
+ * Machine-dependent optimization facilities
+ * are not utilized in this portable implementation.
+ * However, this code should be fairly efficient and
+ * may be a good base for further optimizations anyway.
+ *
+ * Return value is 0 or 1 (binary decision).
+ *
+ * Note: I've changed the handling of the code base & bit
+ * buffer register C compared to other implementations
+ * based on the standards layout & procedures.
+ * While it also contains both the actual base of the
+ * coding interval (16 bits) and the next-bits buffer,
+ * the cut-point between these two parts is floating
+ * (instead of fixed) with the bit shift counter CT.
+ * Thus, we also need only one (variable instead of
+ * fixed size) shift for the LPS/MPS decision, and
+ * we can get away with any renormalization update
+ * of C (except for new data insertion, of course).
+ *
+ * I've also introduced a new scheme for accessing
+ * the probability estimation state machine table,
+ * derived from Markus Kuhn's JBIG implementation.
+ */
+
+LOCAL(int)
+arith_decode (j_decompress_ptr cinfo, unsigned char *st)
+{
+ register arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
+ register unsigned char nl, nm;
+ register INT32 qe, temp;
+ register int sv, data;
+
+ /* Renormalization & data input per section D.2.6 */
+ while (e->a < 0x8000L) {
+ if (--e->ct < 0) {
+ /* Need to fetch next data byte */
+ if (cinfo->unread_marker)
+ data = 0; /* stuff zero data */
+ else {
+ data = get_byte(cinfo); /* read next input byte */
+ if (data == 0xFF) { /* zero stuff or marker code */
+ do data = get_byte(cinfo);
+ while (data == 0xFF); /* swallow extra 0xFF bytes */
+ if (data == 0)
+ data = 0xFF; /* discard stuffed zero byte */
+ else {
+ /* Note: Different from the Huffman decoder, hitting
+ * a marker while processing the compressed data
+ * segment is legal in arithmetic coding.
+ * The convention is to supply zero data
+ * then until decoding is complete.
+ */
+ cinfo->unread_marker = data;
+ data = 0;
+ }
+ }
+ }
+ e->c = (e->c << 8) | data; /* insert data into C register */
+ if ((e->ct += 8) < 0) /* update bit shift counter */
+ /* Need more initial bytes */
+ if (++e->ct == 0)
+ /* Got 2 initial bytes -> re-init A and exit loop */
+ e->a = 0x8000L; /* => e->a = 0x10000L after loop exit */
+ }
+ e->a <<= 1;
+ }
+
+ /* Fetch values from our compact representation of Table D.2:
+ * Qe values and probability estimation state machine
+ */
+ sv = *st;
+ qe = jpeg_aritab[sv & 0x7F]; /* => Qe_Value */
+ nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */
+ nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */
+
+ /* Decode & estimation procedures per sections D.2.4 & D.2.5 */
+ temp = e->a - qe;
+ e->a = temp;
+ temp <<= e->ct;
+ if (e->c >= temp) {
+ e->c -= temp;
+ /* Conditional LPS (less probable symbol) exchange */
+ if (e->a < qe) {
+ e->a = qe;
+ *st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
+ } else {
+ e->a = qe;
+ *st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
+ sv ^= 0x80; /* Exchange LPS/MPS */
+ }
+ } else if (e->a < 0x8000L) {
+ /* Conditional MPS (more probable symbol) exchange */
+ if (e->a < qe) {
+ *st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
+ sv ^= 0x80; /* Exchange LPS/MPS */
+ } else {
+ *st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
+ }
+ }
+
+ return sv >> 7;
+}
+
+
+/*
+ * Check for a restart marker & resynchronize decoder.
+ */
+
+LOCAL(void)
+process_restart (j_decompress_ptr cinfo)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ int ci;
+ jpeg_component_info * compptr;
+
+ /* Advance past the RSTn marker */
+ if (! (*cinfo->marker->read_restart_marker) (cinfo))
+ ERREXIT(cinfo, JERR_CANT_SUSPEND);
+
+ /* Re-initialize statistics areas */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
+ MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
+ /* Reset DC predictions to 0 */
+ entropy->last_dc_val[ci] = 0;
+ entropy->dc_context[ci] = 0;
+ }
+ if (! cinfo->progressive_mode || cinfo->Ss) {
+ MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
+ }
+ }
+
+ /* Reset arithmetic decoding variables */
+ entropy->c = 0;
+ entropy->a = 0;
+ entropy->ct = -16; /* force reading 2 initial bytes to fill C */
+
+ /* Reset restart counter */
+ entropy->restarts_to_go = cinfo->restart_interval;
+}
+
+
+/*
+ * Arithmetic MCU decoding.
+ * Each of these routines decodes and returns one MCU's worth of
+ * arithmetic-compressed coefficients.
+ * The coefficients are reordered from zigzag order into natural array order,
+ * but are not dequantized.
+ *
+ * The i'th block of the MCU is stored into the block pointed to by
+ * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
+ */
+
+/*
+ * MCU decoding for DC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ JBLOCKROW block;
+ unsigned char *st;
+ int blkn, ci, tbl, sign;
+ int v, m;
+
+ /* Process restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ process_restart(cinfo);
+ entropy->restarts_to_go--;
+ }
+
+ if (entropy->ct == -1) return TRUE; /* if error do nothing */
+
+ /* Outer loop handles each block in the MCU */
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+ ci = cinfo->MCU_membership[blkn];
+ tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
+
+ /* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */
+
+ /* Table F.4: Point to statistics bin S0 for DC coefficient coding */
+ st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
+
+ /* Figure F.19: Decode_DC_DIFF */
+ if (arith_decode(cinfo, st) == 0)
+ entropy->dc_context[ci] = 0;
+ else {
+ /* Figure F.21: Decoding nonzero value v */
+ /* Figure F.22: Decoding the sign of v */
+ sign = arith_decode(cinfo, st + 1);
+ st += 2; st += sign;
+ /* Figure F.23: Decoding the magnitude category of v */
+ if ((m = arith_decode(cinfo, st)) != 0) {
+ st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
+ while (arith_decode(cinfo, st)) {
+ if ((m <<= 1) == 0x8000) {
+ WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
+ entropy->ct = -1; /* magnitude overflow */
+ return TRUE;
+ }
+ st += 1;
+ }
+ }
+ /* Section F.1.4.4.1.2: Establish dc_context conditioning category */
+ if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
+ entropy->dc_context[ci] = 0; /* zero diff category */
+ else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
+ entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */
+ else
+ entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */
+ v = m;
+ /* Figure F.24: Decoding the magnitude bit pattern of v */
+ st += 14;
+ while (m >>= 1)
+ if (arith_decode(cinfo, st)) v |= m;
+ v += 1; if (sign) v = -v;
+ entropy->last_dc_val[ci] += v;
+ }
+
+ /* Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) */
+ (*block)[0] = (JCOEF) (entropy->last_dc_val[ci] << cinfo->Al);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU decoding for AC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ JBLOCKROW block;
+ unsigned char *st;
+ int tbl, sign, k;
+ int v, m;
+
+ /* Process restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ process_restart(cinfo);
+ entropy->restarts_to_go--;
+ }
+
+ if (entropy->ct == -1) return TRUE; /* if error do nothing */
+
+ /* There is always only one block per MCU */
+ block = MCU_data[0];
+ tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
+
+ /* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
+
+ /* Figure F.20: Decode_AC_coefficients */
+ for (k = cinfo->Ss; k <= cinfo->Se; k++) {
+ st = entropy->ac_stats[tbl] + 3 * (k - 1);
+ if (arith_decode(cinfo, st)) break; /* EOB flag */
+ while (arith_decode(cinfo, st + 1) == 0) {
+ st += 3; k++;
+ if (k > cinfo->Se) {
+ WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
+ entropy->ct = -1; /* spectral overflow */
+ return TRUE;
+ }
+ }
+ /* Figure F.21: Decoding nonzero value v */
+ /* Figure F.22: Decoding the sign of v */
+ sign = arith_decode(cinfo, entropy->fixed_bin);
+ st += 2;
+ /* Figure F.23: Decoding the magnitude category of v */
+ if ((m = arith_decode(cinfo, st)) != 0) {
+ if (arith_decode(cinfo, st)) {
+ m <<= 1;
+ st = entropy->ac_stats[tbl] +
+ (k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
+ while (arith_decode(cinfo, st)) {
+ if ((m <<= 1) == 0x8000) {
+ WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
+ entropy->ct = -1; /* magnitude overflow */
+ return TRUE;
+ }
+ st += 1;
+ }
+ }
+ }
+ v = m;
+ /* Figure F.24: Decoding the magnitude bit pattern of v */
+ st += 14;
+ while (m >>= 1)
+ if (arith_decode(cinfo, st)) v |= m;
+ v += 1; if (sign) v = -v;
+ /* Scale and output coefficient in natural (dezigzagged) order */
+ (*block)[jpeg_natural_order[k]] = (JCOEF) (v << cinfo->Al);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU decoding for DC successive approximation refinement scan.
+ */
+
+METHODDEF(boolean)
+decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ unsigned char *st;
+ int p1, blkn;
+
+ /* Process restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ process_restart(cinfo);
+ entropy->restarts_to_go--;
+ }
+
+ st = entropy->fixed_bin; /* use fixed probability estimation */
+ p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
+
+ /* Outer loop handles each block in the MCU */
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ /* Encoded data is simply the next bit of the two's-complement DC value */
+ if (arith_decode(cinfo, st))
+ MCU_data[blkn][0][0] |= p1;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU decoding for AC successive approximation refinement scan.
+ */
+
+METHODDEF(boolean)
+decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ JBLOCKROW block;
+ JCOEFPTR thiscoef;
+ unsigned char *st;
+ int tbl, k, kex;
+ int p1, m1;
+
+ /* Process restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ process_restart(cinfo);
+ entropy->restarts_to_go--;
+ }
+
+ if (entropy->ct == -1) return TRUE; /* if error do nothing */
+
+ /* There is always only one block per MCU */
+ block = MCU_data[0];
+ tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
+
+ p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
+ m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
+
+ /* Establish EOBx (previous stage end-of-block) index */
+ for (kex = cinfo->Se; kex > 0; kex--)
+ if ((*block)[jpeg_natural_order[kex]]) break;
+
+ for (k = cinfo->Ss; k <= cinfo->Se; k++) {
+ st = entropy->ac_stats[tbl] + 3 * (k - 1);
+ if (k > kex)
+ if (arith_decode(cinfo, st)) break; /* EOB flag */
+ for (;;) {
+ thiscoef = *block + jpeg_natural_order[k];
+ if (*thiscoef) { /* previously nonzero coef */
+ if (arith_decode(cinfo, st + 2)) {
+ if (*thiscoef < 0)
+ *thiscoef += m1;
+ else
+ *thiscoef += p1;
+ }
+ break;
+ }
+ if (arith_decode(cinfo, st + 1)) { /* newly nonzero coef */
+ if (arith_decode(cinfo, entropy->fixed_bin))
+ *thiscoef = m1;
+ else
+ *thiscoef = p1;
+ break;
+ }
+ st += 3; k++;
+ if (k > cinfo->Se) {
+ WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
+ entropy->ct = -1; /* spectral overflow */
+ return TRUE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Decode one MCU's worth of arithmetic-compressed coefficients.
+ */
+
+METHODDEF(boolean)
+decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ jpeg_component_info * compptr;
+ JBLOCKROW block;
+ unsigned char *st;
+ int blkn, ci, tbl, sign, k;
+ int v, m;
+
+ /* Process restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ process_restart(cinfo);
+ entropy->restarts_to_go--;
+ }
+
+ if (entropy->ct == -1) return TRUE; /* if error do nothing */
+
+ /* Outer loop handles each block in the MCU */
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+
+ /* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */
+
+ tbl = compptr->dc_tbl_no;
+
+ /* Table F.4: Point to statistics bin S0 for DC coefficient coding */
+ st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
+
+ /* Figure F.19: Decode_DC_DIFF */
+ if (arith_decode(cinfo, st) == 0)
+ entropy->dc_context[ci] = 0;
+ else {
+ /* Figure F.21: Decoding nonzero value v */
+ /* Figure F.22: Decoding the sign of v */
+ sign = arith_decode(cinfo, st + 1);
+ st += 2; st += sign;
+ /* Figure F.23: Decoding the magnitude category of v */
+ if ((m = arith_decode(cinfo, st)) != 0) {
+ st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
+ while (arith_decode(cinfo, st)) {
+ if ((m <<= 1) == 0x8000) {
+ WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
+ entropy->ct = -1; /* magnitude overflow */
+ return TRUE;
+ }
+ st += 1;
+ }
+ }
+ /* Section F.1.4.4.1.2: Establish dc_context conditioning category */
+ if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
+ entropy->dc_context[ci] = 0; /* zero diff category */
+ else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
+ entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */
+ else
+ entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */
+ v = m;
+ /* Figure F.24: Decoding the magnitude bit pattern of v */
+ st += 14;
+ while (m >>= 1)
+ if (arith_decode(cinfo, st)) v |= m;
+ v += 1; if (sign) v = -v;
+ entropy->last_dc_val[ci] += v;
+ }
+
+ (*block)[0] = (JCOEF) entropy->last_dc_val[ci];
+
+ /* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
+
+ tbl = compptr->ac_tbl_no;
+
+ /* Figure F.20: Decode_AC_coefficients */
+ for (k = 1; k <= DCTSIZE2 - 1; k++) {
+ st = entropy->ac_stats[tbl] + 3 * (k - 1);
+ if (arith_decode(cinfo, st)) break; /* EOB flag */
+ while (arith_decode(cinfo, st + 1) == 0) {
+ st += 3; k++;
+ if (k > DCTSIZE2 - 1) {
+ WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
+ entropy->ct = -1; /* spectral overflow */
+ return TRUE;
+ }
+ }
+ /* Figure F.21: Decoding nonzero value v */
+ /* Figure F.22: Decoding the sign of v */
+ sign = arith_decode(cinfo, entropy->fixed_bin);
+ st += 2;
+ /* Figure F.23: Decoding the magnitude category of v */
+ if ((m = arith_decode(cinfo, st)) != 0) {
+ if (arith_decode(cinfo, st)) {
+ m <<= 1;
+ st = entropy->ac_stats[tbl] +
+ (k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
+ while (arith_decode(cinfo, st)) {
+ if ((m <<= 1) == 0x8000) {
+ WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
+ entropy->ct = -1; /* magnitude overflow */
+ return TRUE;
+ }
+ st += 1;
+ }
+ }
+ }
+ v = m;
+ /* Figure F.24: Decoding the magnitude bit pattern of v */
+ st += 14;
+ while (m >>= 1)
+ if (arith_decode(cinfo, st)) v |= m;
+ v += 1; if (sign) v = -v;
+ (*block)[jpeg_natural_order[k]] = (JCOEF) v;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Initialize for an arithmetic-compressed scan.
+ */
+
+METHODDEF(void)
+start_pass (j_decompress_ptr cinfo)
+{
+ arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
+ int ci, tbl;
+ jpeg_component_info * compptr;
+
+ if (cinfo->progressive_mode) {
+ /* Validate progressive scan parameters */
+ if (cinfo->Ss == 0) {
+ if (cinfo->Se != 0)
+ goto bad;
+ } else {
+ /* need not check Ss/Se < 0 since they came from unsigned bytes */
+ if (cinfo->Se < cinfo->Ss || cinfo->Se > DCTSIZE2 - 1)
+ goto bad;
+ /* AC scans may have only one component */
+ if (cinfo->comps_in_scan != 1)
+ goto bad;
+ }
+ if (cinfo->Ah != 0) {
+ /* Successive approximation refinement scan: must have Al = Ah-1. */
+ if (cinfo->Ah-1 != cinfo->Al)
+ goto bad;
+ }
+ if (cinfo->Al > 13) { /* need not check for < 0 */
+ bad:
+ ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
+ cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
+ }
+ /* Update progression status, and verify that scan order is legal.
+ * Note that inter-scan inconsistencies are treated as warnings
+ * not fatal errors ... not clear if this is right way to behave.
+ */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ int coefi, cindex = cinfo->cur_comp_info[ci]->component_index;
+ int *coef_bit_ptr = & cinfo->coef_bits[cindex][0];
+ if (cinfo->Ss && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
+ WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
+ for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
+ int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
+ if (cinfo->Ah != expected)
+ WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
+ coef_bit_ptr[coefi] = cinfo->Al;
+ }
+ }
+ /* Select MCU decoding routine */
+ if (cinfo->Ah == 0) {
+ if (cinfo->Ss == 0)
+ entropy->pub.decode_mcu = decode_mcu_DC_first;
+ else
+ entropy->pub.decode_mcu = decode_mcu_AC_first;
+ } else {
+ if (cinfo->Ss == 0)
+ entropy->pub.decode_mcu = decode_mcu_DC_refine;
+ else
+ entropy->pub.decode_mcu = decode_mcu_AC_refine;
+ }
+ } else {
+ /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
+ * This ought to be an error condition, but we make it a warning.
+ */
+ if (cinfo->Ss != 0 || cinfo->Ah != 0 || cinfo->Al != 0 ||
+ (cinfo->Se < DCTSIZE2 && cinfo->Se != DCTSIZE2 - 1))
+ WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
+ /* Select MCU decoding routine */
+ entropy->pub.decode_mcu = decode_mcu;
+ }
+
+ /* Allocate & initialize requested statistics areas */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
+ tbl = compptr->dc_tbl_no;
+ if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
+ ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
+ if (entropy->dc_stats[tbl] == NULL)
+ entropy->dc_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, DC_STAT_BINS);
+ MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
+ /* Initialize DC predictions to 0 */
+ entropy->last_dc_val[ci] = 0;
+ entropy->dc_context[ci] = 0;
+ }
+ if (! cinfo->progressive_mode || cinfo->Ss) {
+ tbl = compptr->ac_tbl_no;
+ if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
+ ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
+ if (entropy->ac_stats[tbl] == NULL)
+ entropy->ac_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS);
+ MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
+ }
+ }
+
+ /* Initialize arithmetic decoding variables */
+ entropy->c = 0;
+ entropy->a = 0;
+ entropy->ct = -16; /* force reading 2 initial bytes to fill C */
+
+ /* Initialize restart counter */
+ entropy->restarts_to_go = cinfo->restart_interval;
+}
+
+
+/*
+ * Module initialization routine for arithmetic entropy decoding.
+ */
+
+GLOBAL(void)
+jinit_arith_decoder (j_decompress_ptr cinfo)
+{
+ arith_entropy_ptr entropy;
+ int i;
+
+ entropy = (arith_entropy_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(arith_entropy_decoder));
+ cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
+ entropy->pub.start_pass = start_pass;
+
+ /* Mark tables unallocated */
+ for (i = 0; i < NUM_ARITH_TBLS; i++) {
+ entropy->dc_stats[i] = NULL;
+ entropy->ac_stats[i] = NULL;
+ }
+
+ /* Initialize index for fixed probability estimation */
+ entropy->fixed_bin[0] = 113;
+
+ if (cinfo->progressive_mode) {
+ /* Create progression status table */
+ int *coef_bit_ptr, ci;
+ cinfo->coef_bits = (int (*)[DCTSIZE2])
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ cinfo->num_components*DCTSIZE2*SIZEOF(int));
+ coef_bit_ptr = & cinfo->coef_bits[0][0];
+ for (ci = 0; ci < cinfo->num_components; ci++)
+ for (i = 0; i < DCTSIZE2; i++)
+ *coef_bit_ptr++ = -1;
+ }
+}
diff --git a/src/libjpeg-turbo/jdatadst-tj.c b/src/libjpeg-turbo/jdatadst-tj.c
new file mode 100644
index 0000000..cb674dc
--- /dev/null
+++ b/src/libjpeg-turbo/jdatadst-tj.c
@@ -0,0 +1,188 @@
+/*
+ * jdatadst.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Modified 2009 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains compression data destination routines for the case of
+ * emitting JPEG data to memory or to a file (or any stdio stream).
+ * While these routines are sufficient for most applications,
+ * some will want to use a different destination manager.
+ * IMPORTANT: we assume that fwrite() will correctly transcribe an array of
+ * JOCTETs into 8-bit-wide elements on external storage. If char is wider
+ * than 8 bits on your machine, you may need to do some tweaking.
+ */
+
+/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jerror.h"
+
+#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
+extern void * malloc JPP((size_t size));
+extern void free JPP((void *ptr));
+#endif
+
+
+#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */
+
+
+/* Expanded data destination object for memory output */
+
+typedef struct {
+ struct jpeg_destination_mgr pub; /* public fields */
+
+ unsigned char ** outbuffer; /* target buffer */
+ unsigned long * outsize;
+ unsigned char * newbuffer; /* newly allocated buffer */
+ JOCTET * buffer; /* start of buffer */
+ size_t bufsize;
+ boolean alloc;
+} my_mem_destination_mgr;
+
+typedef my_mem_destination_mgr * my_mem_dest_ptr;
+
+
+/*
+ * Initialize destination --- called by jpeg_start_compress
+ * before any data is actually written.
+ */
+
+METHODDEF(void)
+init_mem_destination (j_compress_ptr cinfo)
+{
+ /* no work necessary here */
+}
+
+
+/*
+ * Empty the output buffer --- called whenever buffer fills up.
+ *
+ * In typical applications, this should write the entire output buffer
+ * (ignoring the current state of next_output_byte & free_in_buffer),
+ * reset the pointer & count to the start of the buffer, and return TRUE
+ * indicating that the buffer has been dumped.
+ *
+ * In applications that need to be able to suspend compression due to output
+ * overrun, a FALSE return indicates that the buffer cannot be emptied now.
+ * In this situation, the compressor will return to its caller (possibly with
+ * an indication that it has not accepted all the supplied scanlines). The
+ * application should resume compression after it has made more room in the
+ * output buffer. Note that there are substantial restrictions on the use of
+ * suspension --- see the documentation.
+ *
+ * When suspending, the compressor will back up to a convenient restart point
+ * (typically the start of the current MCU). next_output_byte & free_in_buffer
+ * indicate where the restart point will be if the current call returns FALSE.
+ * Data beyond this point will be regenerated after resumption, so do not
+ * write it out when emptying the buffer externally.
+ */
+
+METHODDEF(boolean)
+empty_mem_output_buffer (j_compress_ptr cinfo)
+{
+ size_t nextsize;
+ JOCTET * nextbuffer;
+ my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
+
+ if (!dest->alloc) ERREXIT(cinfo, JERR_BUFFER_SIZE);
+
+ /* Try to allocate new buffer with double size */
+ nextsize = dest->bufsize * 2;
+ nextbuffer = malloc(nextsize);
+
+ if (nextbuffer == NULL)
+ ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
+
+ MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
+
+ if (dest->newbuffer != NULL)
+ free(dest->newbuffer);
+
+ dest->newbuffer = nextbuffer;
+
+ dest->pub.next_output_byte = nextbuffer + dest->bufsize;
+ dest->pub.free_in_buffer = dest->bufsize;
+
+ dest->buffer = nextbuffer;
+ dest->bufsize = nextsize;
+
+ return TRUE;
+}
+
+
+/*
+ * Terminate destination --- called by jpeg_finish_compress
+ * after all data has been written. Usually needs to flush buffer.
+ *
+ * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
+ * application must deal with any cleanup that should happen even
+ * for error exit.
+ */
+
+METHODDEF(void)
+term_mem_destination (j_compress_ptr cinfo)
+{
+ my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
+
+ if(dest->alloc) *dest->outbuffer = dest->buffer;
+ *dest->outsize = (unsigned long)(dest->bufsize - dest->pub.free_in_buffer);
+}
+
+
+/*
+ * Prepare for output to a memory buffer.
+ * The caller may supply an own initial buffer with appropriate size.
+ * Otherwise, or when the actual data output exceeds the given size,
+ * the library adapts the buffer size as necessary.
+ * The standard library functions malloc/free are used for allocating
+ * larger memory, so the buffer is available to the application after
+ * finishing compression, and then the application is responsible for
+ * freeing the requested memory.
+ */
+
+GLOBAL(void)
+jpeg_mem_dest_tj (j_compress_ptr cinfo,
+ unsigned char ** outbuffer, unsigned long * outsize,
+ boolean alloc)
+{
+ my_mem_dest_ptr dest;
+
+ if (outbuffer == NULL || outsize == NULL) /* sanity check */
+ ERREXIT(cinfo, JERR_BUFFER_SIZE);
+
+ /* The destination object is made permanent so that multiple JPEG images
+ * can be written to the same buffer without re-executing jpeg_mem_dest.
+ */
+ if (cinfo->dest == NULL) { /* first time for this JPEG object? */
+ cinfo->dest = (struct jpeg_destination_mgr *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ SIZEOF(my_mem_destination_mgr));
+ dest = (my_mem_dest_ptr) cinfo->dest;
+ dest->newbuffer = NULL;
+ }
+
+ dest = (my_mem_dest_ptr) cinfo->dest;
+ dest->pub.init_destination = init_mem_destination;
+ dest->pub.empty_output_buffer = empty_mem_output_buffer;
+ dest->pub.term_destination = term_mem_destination;
+ dest->outbuffer = outbuffer;
+ dest->outsize = outsize;
+ dest->alloc = alloc;
+
+ if (*outbuffer == NULL || *outsize == 0) {
+ if (alloc) {
+ /* Allocate initial buffer */
+ dest->newbuffer = *outbuffer = malloc(OUTPUT_BUF_SIZE);
+ if (dest->newbuffer == NULL)
+ ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
+ *outsize = OUTPUT_BUF_SIZE;
+ }
+ else ERREXIT(cinfo, JERR_BUFFER_SIZE);
+ }
+
+ dest->pub.next_output_byte = dest->buffer = *outbuffer;
+ dest->pub.free_in_buffer = dest->bufsize = *outsize;
+}
diff --git a/src/libjpeg-turbo/jdatasrc-tj.c b/src/libjpeg-turbo/jdatasrc-tj.c
new file mode 100644
index 0000000..d860a02
--- /dev/null
+++ b/src/libjpeg-turbo/jdatasrc-tj.c
@@ -0,0 +1,182 @@
+/*
+ * jdatasrc.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Modified 2009-2010 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains decompression data source routines for the case of
+ * reading JPEG data from memory or from a file (or any stdio stream).
+ * While these routines are sufficient for most applications,
+ * some will want to use a different source manager.
+ * IMPORTANT: we assume that fread() will correctly transcribe an array of
+ * JOCTETs from 8-bit-wide elements on external storage. If char is wider
+ * than 8 bits on your machine, you may need to do some tweaking.
+ */
+
+/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jerror.h"
+
+
+/*
+ * Initialize source --- called by jpeg_read_header
+ * before any data is actually read.
+ */
+
+METHODDEF(void)
+init_mem_source (j_decompress_ptr cinfo)
+{
+ /* no work necessary here */
+}
+
+
+/*
+ * Fill the input buffer --- called whenever buffer is emptied.
+ *
+ * In typical applications, this should read fresh data into the buffer
+ * (ignoring the current state of next_input_byte & bytes_in_buffer),
+ * reset the pointer & count to the start of the buffer, and return TRUE
+ * indicating that the buffer has been reloaded. It is not necessary to
+ * fill the buffer entirely, only to obtain at least one more byte.
+ *
+ * There is no such thing as an EOF return. If the end of the file has been
+ * reached, the routine has a choice of ERREXIT() or inserting fake data into
+ * the buffer. In most cases, generating a warning message and inserting a
+ * fake EOI marker is the best course of action --- this will allow the
+ * decompressor to output however much of the image is there. However,
+ * the resulting error message is misleading if the real problem is an empty
+ * input file, so we handle that case specially.
+ *
+ * In applications that need to be able to suspend compression due to input
+ * not being available yet, a FALSE return indicates that no more data can be
+ * obtained right now, but more may be forthcoming later. In this situation,
+ * the decompressor will return to its caller (with an indication of the
+ * number of scanlines it has read, if any). The application should resume
+ * decompression after it has loaded more data into the input buffer. Note
+ * that there are substantial restrictions on the use of suspension --- see
+ * the documentation.
+ *
+ * When suspending, the decompressor will back up to a convenient restart point
+ * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
+ * indicate where the restart point will be if the current call returns FALSE.
+ * Data beyond this point must be rescanned after resumption, so move it to
+ * the front of the buffer rather than discarding it.
+ */
+
+METHODDEF(boolean)
+fill_mem_input_buffer (j_decompress_ptr cinfo)
+{
+ static JOCTET mybuffer[4];
+
+ /* The whole JPEG data is expected to reside in the supplied memory
+ * buffer, so any request for more data beyond the given buffer size
+ * is treated as an error.
+ */
+ WARNMS(cinfo, JWRN_JPEG_EOF);
+ /* Insert a fake EOI marker */
+ mybuffer[0] = (JOCTET) 0xFF;
+ mybuffer[1] = (JOCTET) JPEG_EOI;
+
+ cinfo->src->next_input_byte = mybuffer;
+ cinfo->src->bytes_in_buffer = 2;
+
+ return TRUE;
+}
+
+
+/*
+ * Skip data --- used to skip over a potentially large amount of
+ * uninteresting data (such as an APPn marker).
+ *
+ * Writers of suspendable-input applications must note that skip_input_data
+ * is not granted the right to give a suspension return. If the skip extends
+ * beyond the data currently in the buffer, the buffer can be marked empty so
+ * that the next read will cause a fill_input_buffer call that can suspend.
+ * Arranging for additional bytes to be discarded before reloading the input
+ * buffer is the application writer's problem.
+ */
+
+METHODDEF(void)
+skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+{
+ struct jpeg_source_mgr * src = cinfo->src;
+
+ /* Just a dumb implementation for now. Could use fseek() except
+ * it doesn't work on pipes. Not clear that being smart is worth
+ * any trouble anyway --- large skips are infrequent.
+ */
+ if (num_bytes > 0) {
+ while (num_bytes > (long) src->bytes_in_buffer) {
+ num_bytes -= (long) src->bytes_in_buffer;
+ (void) (*src->fill_input_buffer) (cinfo);
+ /* note we assume that fill_input_buffer will never return FALSE,
+ * so suspension need not be handled.
+ */
+ }
+ src->next_input_byte += (size_t) num_bytes;
+ src->bytes_in_buffer -= (size_t) num_bytes;
+ }
+}
+
+
+/*
+ * An additional method that can be provided by data source modules is the
+ * resync_to_restart method for error recovery in the presence of RST markers.
+ * For the moment, this source module just uses the default resync method
+ * provided by the JPEG library. That method assumes that no backtracking
+ * is possible.
+ */
+
+
+/*
+ * Terminate source --- called by jpeg_finish_decompress
+ * after all data has been read. Often a no-op.
+ *
+ * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
+ * application must deal with any cleanup that should happen even
+ * for error exit.
+ */
+
+METHODDEF(void)
+term_source (j_decompress_ptr cinfo)
+{
+ /* no work necessary here */
+}
+
+
+/*
+ * Prepare for input from a supplied memory buffer.
+ * The buffer must contain the whole JPEG data.
+ */
+
+GLOBAL(void)
+jpeg_mem_src_tj (j_decompress_ptr cinfo,
+ unsigned char * inbuffer, unsigned long insize)
+{
+ struct jpeg_source_mgr * src;
+
+ if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */
+ ERREXIT(cinfo, JERR_INPUT_EMPTY);
+
+ /* The source object is made permanent so that a series of JPEG images
+ * can be read from the same buffer by calling jpeg_mem_src only before
+ * the first one.
+ */
+ if (cinfo->src == NULL) { /* first time for this JPEG object? */
+ cinfo->src = (struct jpeg_source_mgr *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ SIZEOF(struct jpeg_source_mgr));
+ }
+
+ src = cinfo->src;
+ src->init_source = init_mem_source;
+ src->fill_input_buffer = fill_mem_input_buffer;
+ src->skip_input_data = skip_input_data;
+ src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
+ src->term_source = term_source;
+ src->bytes_in_buffer = (size_t) insize;
+ src->next_input_byte = (JOCTET *) inbuffer;
+}
diff --git a/src/libjpeg-turbo/jdcoefct.c b/src/libjpeg-turbo/jdcoefct.c
new file mode 100644
index 0000000..48a9fc6
--- /dev/null
+++ b/src/libjpeg-turbo/jdcoefct.c
@@ -0,0 +1,749 @@
+/*
+ * jdcoefct.c
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * Copyright (C) 2010, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the coefficient buffer controller for decompression.
+ * This controller is the top level of the JPEG decompressor proper.
+ * The coefficient buffer lies between entropy decoding and inverse-DCT steps.
+ *
+ * In buffered-image mode, this controller is the interface between
+ * input-oriented processing and output-oriented processing.
+ * Also, the input side (only) is used when reading a file for transcoding.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jpegcomp.h"
+
+/* Block smoothing is only applicable for progressive JPEG, so: */
+#ifndef D_PROGRESSIVE_SUPPORTED
+#undef BLOCK_SMOOTHING_SUPPORTED
+#endif
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_d_coef_controller pub; /* public fields */
+
+ /* These variables keep track of the current location of the input side. */
+ /* cinfo->input_iMCU_row is also used for this. */
+ JDIMENSION MCU_ctr; /* counts MCUs processed in current row */
+ int MCU_vert_offset; /* counts MCU rows within iMCU row */
+ int MCU_rows_per_iMCU_row; /* number of such rows needed */
+
+ /* The output side's location is represented by cinfo->output_iMCU_row. */
+
+ /* In single-pass modes, it's sufficient to buffer just one MCU.
+ * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
+ * and let the entropy decoder write into that workspace each time.
+ * (On 80x86, the workspace is FAR even though it's not really very big;
+ * this is to keep the module interfaces unchanged when a large coefficient
+ * buffer is necessary.)
+ * In multi-pass modes, this array points to the current MCU's blocks
+ * within the virtual arrays; it is used only by the input side.
+ */
+ JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
+
+ /* Temporary workspace for one MCU */
+ JCOEF * workspace;
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+ /* In multi-pass modes, we need a virtual block array for each component. */
+ jvirt_barray_ptr whole_image[MAX_COMPONENTS];
+#endif
+
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+ /* When doing block smoothing, we latch coefficient Al values here */
+ int * coef_bits_latch;
+#define SAVED_COEFS 6 /* we save coef_bits[0..5] */
+#endif
+} my_coef_controller;
+
+typedef my_coef_controller * my_coef_ptr;
+
+/* Forward declarations */
+METHODDEF(int) decompress_onepass
+ JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+METHODDEF(int) decompress_data
+ JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
+#endif
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo));
+METHODDEF(int) decompress_smooth_data
+ JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
+#endif
+
+
+LOCAL(void)
+start_iMCU_row (j_decompress_ptr cinfo)
+/* Reset within-iMCU-row counters for a new row (input side) */
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ /* In an interleaved scan, an MCU row is the same as an iMCU row.
+ * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
+ * But at the bottom of the image, process only what's left.
+ */
+ if (cinfo->comps_in_scan > 1) {
+ coef->MCU_rows_per_iMCU_row = 1;
+ } else {
+ if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
+ else
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
+ }
+
+ coef->MCU_ctr = 0;
+ coef->MCU_vert_offset = 0;
+}
+
+
+/*
+ * Initialize for an input processing pass.
+ */
+
+METHODDEF(void)
+start_input_pass (j_decompress_ptr cinfo)
+{
+ cinfo->input_iMCU_row = 0;
+ start_iMCU_row(cinfo);
+}
+
+
+/*
+ * Initialize for an output processing pass.
+ */
+
+METHODDEF(void)
+start_output_pass (j_decompress_ptr cinfo)
+{
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ /* If multipass, check to see whether to use block smoothing on this pass */
+ if (coef->pub.coef_arrays != NULL) {
+ if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
+ coef->pub.decompress_data = decompress_smooth_data;
+ else
+ coef->pub.decompress_data = decompress_data;
+ }
+#endif
+ cinfo->output_iMCU_row = 0;
+}
+
+
+/*
+ * Decompress and return some data in the single-pass case.
+ * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
+ * Input and output must run in lockstep since we have only a one-MCU buffer.
+ * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
+ *
+ * NB: output_buf contains a plane for each component in image,
+ * which we index according to the component's SOF position.
+ */
+
+METHODDEF(int)
+decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION MCU_col_num; /* index of current MCU within row */
+ JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ int blkn, ci, xindex, yindex, yoffset, useful_width;
+ JSAMPARRAY output_ptr;
+ JDIMENSION start_col, output_col;
+ jpeg_component_info *compptr;
+ inverse_DCT_method_ptr inverse_DCT;
+
+ /* Loop to process as much as one whole iMCU row */
+ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+ yoffset++) {
+ for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
+ MCU_col_num++) {
+ /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */
+ jzero_far((void FAR *) coef->MCU_buffer[0],
+ (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
+ if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
+ /* Suspension forced; update state counters and exit */
+ coef->MCU_vert_offset = yoffset;
+ coef->MCU_ctr = MCU_col_num;
+ return JPEG_SUSPENDED;
+ }
+ /* Determine where data should go in output_buf and do the IDCT thing.
+ * We skip dummy blocks at the right and bottom edges (but blkn gets
+ * incremented past them!). Note the inner loop relies on having
+ * allocated the MCU_buffer[] blocks sequentially.
+ */
+ blkn = 0; /* index of current DCT block within MCU */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* Don't bother to IDCT an uninteresting component. */
+ if (! compptr->component_needed) {
+ blkn += compptr->MCU_blocks;
+ continue;
+ }
+ inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
+ useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
+ : compptr->last_col_width;
+ output_ptr = output_buf[compptr->component_index] +
+ yoffset * compptr->_DCT_scaled_size;
+ start_col = MCU_col_num * compptr->MCU_sample_width;
+ for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+ if (cinfo->input_iMCU_row < last_iMCU_row ||
+ yoffset+yindex < compptr->last_row_height) {
+ output_col = start_col;
+ for (xindex = 0; xindex < useful_width; xindex++) {
+ (*inverse_DCT) (cinfo, compptr,
+ (JCOEFPTR) coef->MCU_buffer[blkn+xindex],
+ output_ptr, output_col);
+ output_col += compptr->_DCT_scaled_size;
+ }
+ }
+ blkn += compptr->MCU_width;
+ output_ptr += compptr->_DCT_scaled_size;
+ }
+ }
+ }
+ /* Completed an MCU row, but perhaps not an iMCU row */
+ coef->MCU_ctr = 0;
+ }
+ /* Completed the iMCU row, advance counters for next one */
+ cinfo->output_iMCU_row++;
+ if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
+ start_iMCU_row(cinfo);
+ return JPEG_ROW_COMPLETED;
+ }
+ /* Completed the scan */
+ (*cinfo->inputctl->finish_input_pass) (cinfo);
+ return JPEG_SCAN_COMPLETED;
+}
+
+
+/*
+ * Dummy consume-input routine for single-pass operation.
+ */
+
+METHODDEF(int)
+dummy_consume_data (j_decompress_ptr cinfo)
+{
+ return JPEG_SUSPENDED; /* Always indicate nothing was done */
+}
+
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+
+/*
+ * Consume input data and store it in the full-image coefficient buffer.
+ * We read as much as one fully interleaved MCU row ("iMCU" row) per call,
+ * ie, v_samp_factor block rows for each component in the scan.
+ * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
+ */
+
+METHODDEF(int)
+consume_data (j_decompress_ptr cinfo)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION MCU_col_num; /* index of current MCU within row */
+ int blkn, ci, xindex, yindex, yoffset;
+ JDIMENSION start_col;
+ JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
+ JBLOCKROW buffer_ptr;
+ jpeg_component_info *compptr;
+
+ /* Align the virtual buffers for the components used in this scan. */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ buffer[ci] = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
+ cinfo->input_iMCU_row * compptr->v_samp_factor,
+ (JDIMENSION) compptr->v_samp_factor, TRUE);
+ /* Note: entropy decoder expects buffer to be zeroed,
+ * but this is handled automatically by the memory manager
+ * because we requested a pre-zeroed array.
+ */
+ }
+
+ /* Loop to process one whole iMCU row */
+ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+ yoffset++) {
+ for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row;
+ MCU_col_num++) {
+ /* Construct list of pointers to DCT blocks belonging to this MCU */
+ blkn = 0; /* index of current DCT block within MCU */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ start_col = MCU_col_num * compptr->MCU_width;
+ for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+ buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
+ for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
+ coef->MCU_buffer[blkn++] = buffer_ptr++;
+ }
+ }
+ }
+ /* Try to fetch the MCU. */
+ if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
+ /* Suspension forced; update state counters and exit */
+ coef->MCU_vert_offset = yoffset;
+ coef->MCU_ctr = MCU_col_num;
+ return JPEG_SUSPENDED;
+ }
+ }
+ /* Completed an MCU row, but perhaps not an iMCU row */
+ coef->MCU_ctr = 0;
+ }
+ /* Completed the iMCU row, advance counters for next one */
+ if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
+ start_iMCU_row(cinfo);
+ return JPEG_ROW_COMPLETED;
+ }
+ /* Completed the scan */
+ (*cinfo->inputctl->finish_input_pass) (cinfo);
+ return JPEG_SCAN_COMPLETED;
+}
+
+
+/*
+ * Decompress and return some data in the multi-pass case.
+ * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
+ * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
+ *
+ * NB: output_buf contains a plane for each component in image.
+ */
+
+METHODDEF(int)
+decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ JDIMENSION block_num;
+ int ci, block_row, block_rows;
+ JBLOCKARRAY buffer;
+ JBLOCKROW buffer_ptr;
+ JSAMPARRAY output_ptr;
+ JDIMENSION output_col;
+ jpeg_component_info *compptr;
+ inverse_DCT_method_ptr inverse_DCT;
+
+ /* Force some input to be done if we are getting ahead of the input. */
+ while (cinfo->input_scan_number < cinfo->output_scan_number ||
+ (cinfo->input_scan_number == cinfo->output_scan_number &&
+ cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
+ if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
+ return JPEG_SUSPENDED;
+ }
+
+ /* OK, output from the virtual arrays. */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Don't bother to IDCT an uninteresting component. */
+ if (! compptr->component_needed)
+ continue;
+ /* Align the virtual buffer for this component. */
+ buffer = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[ci],
+ cinfo->output_iMCU_row * compptr->v_samp_factor,
+ (JDIMENSION) compptr->v_samp_factor, FALSE);
+ /* Count non-dummy DCT block rows in this iMCU row. */
+ if (cinfo->output_iMCU_row < last_iMCU_row)
+ block_rows = compptr->v_samp_factor;
+ else {
+ /* NB: can't use last_row_height here; it is input-side-dependent! */
+ block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+ if (block_rows == 0) block_rows = compptr->v_samp_factor;
+ }
+ inverse_DCT = cinfo->idct->inverse_DCT[ci];
+ output_ptr = output_buf[ci];
+ /* Loop over all DCT blocks to be processed. */
+ for (block_row = 0; block_row < block_rows; block_row++) {
+ buffer_ptr = buffer[block_row];
+ output_col = 0;
+ for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
+ (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
+ output_ptr, output_col);
+ buffer_ptr++;
+ output_col += compptr->_DCT_scaled_size;
+ }
+ output_ptr += compptr->_DCT_scaled_size;
+ }
+ }
+
+ if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
+ return JPEG_ROW_COMPLETED;
+ return JPEG_SCAN_COMPLETED;
+}
+
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+
+
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+
+/*
+ * This code applies interblock smoothing as described by section K.8
+ * of the JPEG standard: the first 5 AC coefficients are estimated from
+ * the DC values of a DCT block and its 8 neighboring blocks.
+ * We apply smoothing only for progressive JPEG decoding, and only if
+ * the coefficients it can estimate are not yet known to full precision.
+ */
+
+/* Natural-order array positions of the first 5 zigzag-order coefficients */
+#define Q01_POS 1
+#define Q10_POS 8
+#define Q20_POS 16
+#define Q11_POS 9
+#define Q02_POS 2
+
+/*
+ * Determine whether block smoothing is applicable and safe.
+ * We also latch the current states of the coef_bits[] entries for the
+ * AC coefficients; otherwise, if the input side of the decompressor
+ * advances into a new scan, we might think the coefficients are known
+ * more accurately than they really are.
+ */
+
+LOCAL(boolean)
+smoothing_ok (j_decompress_ptr cinfo)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ boolean smoothing_useful = FALSE;
+ int ci, coefi;
+ jpeg_component_info *compptr;
+ JQUANT_TBL * qtable;
+ int * coef_bits;
+ int * coef_bits_latch;
+
+ if (! cinfo->progressive_mode || cinfo->coef_bits == NULL)
+ return FALSE;
+
+ /* Allocate latch area if not already done */
+ if (coef->coef_bits_latch == NULL)
+ coef->coef_bits_latch = (int *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ cinfo->num_components *
+ (SAVED_COEFS * SIZEOF(int)));
+ coef_bits_latch = coef->coef_bits_latch;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* All components' quantization values must already be latched. */
+ if ((qtable = compptr->quant_table) == NULL)
+ return FALSE;
+ /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
+ if (qtable->quantval[0] == 0 ||
+ qtable->quantval[Q01_POS] == 0 ||
+ qtable->quantval[Q10_POS] == 0 ||
+ qtable->quantval[Q20_POS] == 0 ||
+ qtable->quantval[Q11_POS] == 0 ||
+ qtable->quantval[Q02_POS] == 0)
+ return FALSE;
+ /* DC values must be at least partly known for all components. */
+ coef_bits = cinfo->coef_bits[ci];
+ if (coef_bits[0] < 0)
+ return FALSE;
+ /* Block smoothing is helpful if some AC coefficients remain inaccurate. */
+ for (coefi = 1; coefi <= 5; coefi++) {
+ coef_bits_latch[coefi] = coef_bits[coefi];
+ if (coef_bits[coefi] != 0)
+ smoothing_useful = TRUE;
+ }
+ coef_bits_latch += SAVED_COEFS;
+ }
+
+ return smoothing_useful;
+}
+
+
+/*
+ * Variant of decompress_data for use when doing block smoothing.
+ */
+
+METHODDEF(int)
+decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ JDIMENSION block_num, last_block_column;
+ int ci, block_row, block_rows, access_rows;
+ JBLOCKARRAY buffer;
+ JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
+ JSAMPARRAY output_ptr;
+ JDIMENSION output_col;
+ jpeg_component_info *compptr;
+ inverse_DCT_method_ptr inverse_DCT;
+ boolean first_row, last_row;
+ JCOEF * workspace;
+ int *coef_bits;
+ JQUANT_TBL *quanttbl;
+ INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
+ int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
+ int Al, pred;
+
+ /* Keep a local variable to avoid looking it up more than once */
+ workspace = coef->workspace;
+
+ /* Force some input to be done if we are getting ahead of the input. */
+ while (cinfo->input_scan_number <= cinfo->output_scan_number &&
+ ! cinfo->inputctl->eoi_reached) {
+ if (cinfo->input_scan_number == cinfo->output_scan_number) {
+ /* If input is working on current scan, we ordinarily want it to
+ * have completed the current row. But if input scan is DC,
+ * we want it to keep one row ahead so that next block row's DC
+ * values are up to date.
+ */
+ JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
+ if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta)
+ break;
+ }
+ if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
+ return JPEG_SUSPENDED;
+ }
+
+ /* OK, output from the virtual arrays. */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Don't bother to IDCT an uninteresting component. */
+ if (! compptr->component_needed)
+ continue;
+ /* Count non-dummy DCT block rows in this iMCU row. */
+ if (cinfo->output_iMCU_row < last_iMCU_row) {
+ block_rows = compptr->v_samp_factor;
+ access_rows = block_rows * 2; /* this and next iMCU row */
+ last_row = FALSE;
+ } else {
+ /* NB: can't use last_row_height here; it is input-side-dependent! */
+ block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+ if (block_rows == 0) block_rows = compptr->v_samp_factor;
+ access_rows = block_rows; /* this iMCU row only */
+ last_row = TRUE;
+ }
+ /* Align the virtual buffer for this component. */
+ if (cinfo->output_iMCU_row > 0) {
+ access_rows += compptr->v_samp_factor; /* prior iMCU row too */
+ buffer = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[ci],
+ (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
+ (JDIMENSION) access_rows, FALSE);
+ buffer += compptr->v_samp_factor; /* point to current iMCU row */
+ first_row = FALSE;
+ } else {
+ buffer = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[ci],
+ (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE);
+ first_row = TRUE;
+ }
+ /* Fetch component-dependent info */
+ coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
+ quanttbl = compptr->quant_table;
+ Q00 = quanttbl->quantval[0];
+ Q01 = quanttbl->quantval[Q01_POS];
+ Q10 = quanttbl->quantval[Q10_POS];
+ Q20 = quanttbl->quantval[Q20_POS];
+ Q11 = quanttbl->quantval[Q11_POS];
+ Q02 = quanttbl->quantval[Q02_POS];
+ inverse_DCT = cinfo->idct->inverse_DCT[ci];
+ output_ptr = output_buf[ci];
+ /* Loop over all DCT blocks to be processed. */
+ for (block_row = 0; block_row < block_rows; block_row++) {
+ buffer_ptr = buffer[block_row];
+ if (first_row && block_row == 0)
+ prev_block_row = buffer_ptr;
+ else
+ prev_block_row = buffer[block_row-1];
+ if (last_row && block_row == block_rows-1)
+ next_block_row = buffer_ptr;
+ else
+ next_block_row = buffer[block_row+1];
+ /* We fetch the surrounding DC values using a sliding-register approach.
+ * Initialize all nine here so as to do the right thing on narrow pics.
+ */
+ DC1 = DC2 = DC3 = (int) prev_block_row[0][0];
+ DC4 = DC5 = DC6 = (int) buffer_ptr[0][0];
+ DC7 = DC8 = DC9 = (int) next_block_row[0][0];
+ output_col = 0;
+ last_block_column = compptr->width_in_blocks - 1;
+ for (block_num = 0; block_num <= last_block_column; block_num++) {
+ /* Fetch current DCT block into workspace so we can modify it. */
+ jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1);
+ /* Update DC values */
+ if (block_num < last_block_column) {
+ DC3 = (int) prev_block_row[1][0];
+ DC6 = (int) buffer_ptr[1][0];
+ DC9 = (int) next_block_row[1][0];
+ }
+ /* Compute coefficient estimates per K.8.
+ * An estimate is applied only if coefficient is still zero,
+ * and is not known to be fully accurate.
+ */
+ /* AC01 */
+ if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) {
+ num = 36 * Q00 * (DC4 - DC6);
+ if (num >= 0) {
+ pred = (int) (((Q01<<7) + num) / (Q01<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ } else {
+ pred = (int) (((Q01<<7) - num) / (Q01<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ pred = -pred;
+ }
+ workspace[1] = (JCOEF) pred;
+ }
+ /* AC10 */
+ if ((Al=coef_bits[2]) != 0 && workspace[8] == 0) {
+ num = 36 * Q00 * (DC2 - DC8);
+ if (num >= 0) {
+ pred = (int) (((Q10<<7) + num) / (Q10<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ } else {
+ pred = (int) (((Q10<<7) - num) / (Q10<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ pred = -pred;
+ }
+ workspace[8] = (JCOEF) pred;
+ }
+ /* AC20 */
+ if ((Al=coef_bits[3]) != 0 && workspace[16] == 0) {
+ num = 9 * Q00 * (DC2 + DC8 - 2*DC5);
+ if (num >= 0) {
+ pred = (int) (((Q20<<7) + num) / (Q20<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ } else {
+ pred = (int) (((Q20<<7) - num) / (Q20<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ pred = -pred;
+ }
+ workspace[16] = (JCOEF) pred;
+ }
+ /* AC11 */
+ if ((Al=coef_bits[4]) != 0 && workspace[9] == 0) {
+ num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
+ if (num >= 0) {
+ pred = (int) (((Q11<<7) + num) / (Q11<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ } else {
+ pred = (int) (((Q11<<7) - num) / (Q11<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ pred = -pred;
+ }
+ workspace[9] = (JCOEF) pred;
+ }
+ /* AC02 */
+ if ((Al=coef_bits[5]) != 0 && workspace[2] == 0) {
+ num = 9 * Q00 * (DC4 + DC6 - 2*DC5);
+ if (num >= 0) {
+ pred = (int) (((Q02<<7) + num) / (Q02<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ } else {
+ pred = (int) (((Q02<<7) - num) / (Q02<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ pred = -pred;
+ }
+ workspace[2] = (JCOEF) pred;
+ }
+ /* OK, do the IDCT */
+ (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) workspace,
+ output_ptr, output_col);
+ /* Advance for next column */
+ DC1 = DC2; DC2 = DC3;
+ DC4 = DC5; DC5 = DC6;
+ DC7 = DC8; DC8 = DC9;
+ buffer_ptr++, prev_block_row++, next_block_row++;
+ output_col += compptr->_DCT_scaled_size;
+ }
+ output_ptr += compptr->_DCT_scaled_size;
+ }
+ }
+
+ if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
+ return JPEG_ROW_COMPLETED;
+ return JPEG_SCAN_COMPLETED;
+}
+
+#endif /* BLOCK_SMOOTHING_SUPPORTED */
+
+
+/*
+ * Initialize coefficient buffer controller.
+ */
+
+GLOBAL(void)
+jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
+{
+ my_coef_ptr coef;
+
+ coef = (my_coef_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_coef_controller));
+ cinfo->coef = (struct jpeg_d_coef_controller *) coef;
+ coef->pub.start_input_pass = start_input_pass;
+ coef->pub.start_output_pass = start_output_pass;
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+ coef->coef_bits_latch = NULL;
+#endif
+
+ /* Create the coefficient buffer. */
+ if (need_full_buffer) {
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+ /* Allocate a full-image virtual array for each component, */
+ /* padded to a multiple of samp_factor DCT blocks in each direction. */
+ /* Note we ask for a pre-zeroed array. */
+ int ci, access_rows;
+ jpeg_component_info *compptr;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ access_rows = compptr->v_samp_factor;
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+ /* If block smoothing could be used, need a bigger window */
+ if (cinfo->progressive_mode)
+ access_rows *= 3;
+#endif
+ coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
+ (JDIMENSION) jround_up((long) compptr->width_in_blocks,
+ (long) compptr->h_samp_factor),
+ (JDIMENSION) jround_up((long) compptr->height_in_blocks,
+ (long) compptr->v_samp_factor),
+ (JDIMENSION) access_rows);
+ }
+ coef->pub.consume_data = consume_data;
+ coef->pub.decompress_data = decompress_data;
+ coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ /* We only need a single-MCU buffer. */
+ JBLOCKROW buffer;
+ int i;
+
+ buffer = (JBLOCKROW)
+ (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+ for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
+ coef->MCU_buffer[i] = buffer + i;
+ }
+ coef->pub.consume_data = dummy_consume_data;
+ coef->pub.decompress_data = decompress_onepass;
+ coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
+ }
+
+ /* Allocate the workspace buffer */
+ coef->workspace = (JCOEF *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(JCOEF) * DCTSIZE2);
+}
diff --git a/src/libjpeg-turbo/jdcolext.c.inc b/src/libjpeg-turbo/jdcolext.c.inc
new file mode 100644
index 0000000..07da949
--- /dev/null
+++ b/src/libjpeg-turbo/jdcolext.c.inc
@@ -0,0 +1,104 @@
+/*
+ * jdcolext.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Copyright (C) 2009, 2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains output colorspace conversion routines.
+ */
+
+
+/* This file is included by jdcolor.c */
+
+
+/*
+ * Convert some rows of samples to the output colorspace.
+ *
+ * Note that we change from noninterleaved, one-plane-per-component format
+ * to interleaved-pixel format. The output buffer is therefore three times
+ * as wide as the input buffer.
+ * A starting row offset is provided only for the input buffer. The caller
+ * can easily adjust the passed output_buf value to accommodate any row
+ * offset required on that side.
+ */
+
+INLINE
+LOCAL(void)
+ycc_rgb_convert_internal (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ register int y, cb, cr;
+ register JSAMPROW outptr;
+ register JSAMPROW inptr0, inptr1, inptr2;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->output_width;
+ /* copy these pointers into registers if possible */
+ register JSAMPLE * range_limit = cinfo->sample_range_limit;
+ register int * Crrtab = cconvert->Cr_r_tab;
+ register int * Cbbtab = cconvert->Cb_b_tab;
+ register INT32 * Crgtab = cconvert->Cr_g_tab;
+ register INT32 * Cbgtab = cconvert->Cb_g_tab;
+ SHIFT_TEMPS
+
+ while (--num_rows >= 0) {
+ inptr0 = input_buf[0][input_row];
+ inptr1 = input_buf[1][input_row];
+ inptr2 = input_buf[2][input_row];
+ input_row++;
+ outptr = *output_buf++;
+ for (col = 0; col < num_cols; col++) {
+ y = GETJSAMPLE(inptr0[col]);
+ cb = GETJSAMPLE(inptr1[col]);
+ cr = GETJSAMPLE(inptr2[col]);
+ /* Range-limiting is essential due to noise introduced by DCT losses. */
+ outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
+ outptr[RGB_GREEN] = range_limit[y +
+ ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
+ SCALEBITS))];
+ outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
+ /* Set unused byte to 0xFF so it can be interpreted as an opaque */
+ /* alpha channel value */
+#ifdef RGB_ALPHA
+ outptr[RGB_ALPHA] = 0xFF;
+#endif
+ outptr += RGB_PIXELSIZE;
+ }
+ }
+}
+
+
+/*
+ * Convert grayscale to RGB: just duplicate the graylevel three times.
+ * This is provided to support applications that don't want to cope
+ * with grayscale as a separate case.
+ */
+
+INLINE
+LOCAL(void)
+gray_rgb_convert_internal (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ register JSAMPROW inptr, outptr;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->output_width;
+
+ while (--num_rows >= 0) {
+ inptr = input_buf[0][input_row++];
+ outptr = *output_buf++;
+ for (col = 0; col < num_cols; col++) {
+ /* We can dispense with GETJSAMPLE() here */
+ outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
+ /* Set unused byte to 0xFF so it can be interpreted as an opaque */
+ /* alpha channel value */
+#ifdef RGB_ALPHA
+ outptr[RGB_ALPHA] = 0xFF;
+#endif
+ outptr += RGB_PIXELSIZE;
+ }
+ }
+}
diff --git a/src/libjpeg-turbo/jdcolor.c b/src/libjpeg-turbo/jdcolor.c
new file mode 100644
index 0000000..66c4520
--- /dev/null
+++ b/src/libjpeg-turbo/jdcolor.c
@@ -0,0 +1,529 @@
+/*
+ * jdcolor.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright (C) 2009, 2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains output colorspace conversion routines.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jsimd.h"
+#include "config.h"
+
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_color_deconverter pub; /* public fields */
+
+ /* Private state for YCC->RGB conversion */
+ int * Cr_r_tab; /* => table for Cr to R conversion */
+ int * Cb_b_tab; /* => table for Cb to B conversion */
+ INT32 * Cr_g_tab; /* => table for Cr to G conversion */
+ INT32 * Cb_g_tab; /* => table for Cb to G conversion */
+} my_color_deconverter;
+
+typedef my_color_deconverter * my_cconvert_ptr;
+
+
+/**************** YCbCr -> RGB conversion: most common case **************/
+
+/*
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ * R = Y + 1.40200 * Cr
+ * G = Y - 0.34414 * Cb - 0.71414 * Cr
+ * B = Y + 1.77200 * Cb
+ * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
+ * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
+ *
+ * To avoid floating-point arithmetic, we represent the fractional constants
+ * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
+ * the products by 2^16, with appropriate rounding, to get the correct answer.
+ * Notice that Y, being an integral input, does not contribute any fraction
+ * so it need not participate in the rounding.
+ *
+ * For even more speed, we avoid doing any multiplications in the inner loop
+ * by precalculating the constants times Cb and Cr for all possible values.
+ * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
+ * for 12-bit samples it is still acceptable. It's not very reasonable for
+ * 16-bit samples, but if you want lossless storage you shouldn't be changing
+ * colorspace anyway.
+ * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
+ * values for the G calculation are left scaled up, since we must add them
+ * together before rounding.
+ */
+
+#define SCALEBITS 16 /* speediest right-shift on some machines */
+#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
+#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
+
+
+/* Include inline routines for colorspace extensions */
+
+#include "jdcolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+
+#define RGB_RED EXT_RGB_RED
+#define RGB_GREEN EXT_RGB_GREEN
+#define RGB_BLUE EXT_RGB_BLUE
+#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extrgb_convert_internal
+#define gray_rgb_convert_internal gray_extrgb_convert_internal
+#include "jdcolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+#define RGB_RED EXT_RGBX_RED
+#define RGB_GREEN EXT_RGBX_GREEN
+#define RGB_BLUE EXT_RGBX_BLUE
+#define RGB_ALPHA 3
+#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extrgbx_convert_internal
+#define gray_rgb_convert_internal gray_extrgbx_convert_internal
+#include "jdcolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+#define RGB_RED EXT_BGR_RED
+#define RGB_GREEN EXT_BGR_GREEN
+#define RGB_BLUE EXT_BGR_BLUE
+#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extbgr_convert_internal
+#define gray_rgb_convert_internal gray_extbgr_convert_internal
+#include "jdcolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+#define RGB_RED EXT_BGRX_RED
+#define RGB_GREEN EXT_BGRX_GREEN
+#define RGB_BLUE EXT_BGRX_BLUE
+#define RGB_ALPHA 3
+#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extbgrx_convert_internal
+#define gray_rgb_convert_internal gray_extbgrx_convert_internal
+#include "jdcolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+#define RGB_RED EXT_XBGR_RED
+#define RGB_GREEN EXT_XBGR_GREEN
+#define RGB_BLUE EXT_XBGR_BLUE
+#define RGB_ALPHA 0
+#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extxbgr_convert_internal
+#define gray_rgb_convert_internal gray_extxbgr_convert_internal
+#include "jdcolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+#define RGB_RED EXT_XRGB_RED
+#define RGB_GREEN EXT_XRGB_GREEN
+#define RGB_BLUE EXT_XRGB_BLUE
+#define RGB_ALPHA 0
+#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
+#define ycc_rgb_convert_internal ycc_extxrgb_convert_internal
+#define gray_rgb_convert_internal gray_extxrgb_convert_internal
+#include "jdcolext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef ycc_rgb_convert_internal
+#undef gray_rgb_convert_internal
+
+
+/*
+ * Initialize tables for YCC->RGB colorspace conversion.
+ */
+
+LOCAL(void)
+build_ycc_rgb_table (j_decompress_ptr cinfo)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ int i;
+ INT32 x;
+ SHIFT_TEMPS
+
+ cconvert->Cr_r_tab = (int *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(int));
+ cconvert->Cb_b_tab = (int *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(int));
+ cconvert->Cr_g_tab = (INT32 *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(INT32));
+ cconvert->Cb_g_tab = (INT32 *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(INT32));
+
+ for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
+ /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
+ /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
+ /* Cr=>R value is nearest int to 1.40200 * x */
+ cconvert->Cr_r_tab[i] = (int)
+ RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
+ /* Cb=>B value is nearest int to 1.77200 * x */
+ cconvert->Cb_b_tab[i] = (int)
+ RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
+ /* Cr=>G value is scaled-up -0.71414 * x */
+ cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
+ /* Cb=>G value is scaled-up -0.34414 * x */
+ /* We also add in ONE_HALF so that need not do it in inner loop */
+ cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
+ }
+}
+
+
+/*
+ * Convert some rows of samples to the output colorspace.
+ */
+
+METHODDEF(void)
+ycc_rgb_convert (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ switch (cinfo->out_color_space) {
+ case JCS_EXT_RGB:
+ ycc_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ case JCS_EXT_RGBX:
+ case JCS_EXT_RGBA:
+ ycc_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ case JCS_EXT_BGR:
+ ycc_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ case JCS_EXT_BGRX:
+ case JCS_EXT_BGRA:
+ ycc_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ case JCS_EXT_XBGR:
+ case JCS_EXT_ABGR:
+ ycc_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ case JCS_EXT_XRGB:
+ case JCS_EXT_ARGB:
+ ycc_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ default:
+ ycc_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ }
+}
+
+
+/**************** Cases other than YCbCr -> RGB **************/
+
+
+/*
+ * Color conversion for no colorspace change: just copy the data,
+ * converting from separate-planes to interleaved representation.
+ */
+
+METHODDEF(void)
+null_convert (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ register JSAMPROW inptr, outptr;
+ register JDIMENSION count;
+ register int num_components = cinfo->num_components;
+ JDIMENSION num_cols = cinfo->output_width;
+ int ci;
+
+ while (--num_rows >= 0) {
+ for (ci = 0; ci < num_components; ci++) {
+ inptr = input_buf[ci][input_row];
+ outptr = output_buf[0] + ci;
+ for (count = num_cols; count > 0; count--) {
+ *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
+ outptr += num_components;
+ }
+ }
+ input_row++;
+ output_buf++;
+ }
+}
+
+
+/*
+ * Color conversion for grayscale: just copy the data.
+ * This also works for YCbCr -> grayscale conversion, in which
+ * we just copy the Y (luminance) component and ignore chrominance.
+ */
+
+METHODDEF(void)
+grayscale_convert (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
+ num_rows, cinfo->output_width);
+}
+
+
+/*
+ * Convert grayscale to RGB
+ */
+
+METHODDEF(void)
+gray_rgb_convert (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ switch (cinfo->out_color_space) {
+ case JCS_EXT_RGB:
+ gray_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ case JCS_EXT_RGBX:
+ case JCS_EXT_RGBA:
+ gray_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ case JCS_EXT_BGR:
+ gray_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ case JCS_EXT_BGRX:
+ case JCS_EXT_BGRA:
+ gray_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ case JCS_EXT_XBGR:
+ case JCS_EXT_ABGR:
+ gray_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ case JCS_EXT_XRGB:
+ case JCS_EXT_ARGB:
+ gray_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ default:
+ gray_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
+ num_rows);
+ break;
+ }
+}
+
+
+/*
+ * Adobe-style YCCK->CMYK conversion.
+ * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
+ * conversion as above, while passing K (black) unchanged.
+ * We assume build_ycc_rgb_table has been called.
+ */
+
+METHODDEF(void)
+ycck_cmyk_convert (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ register int y, cb, cr;
+ register JSAMPROW outptr;
+ register JSAMPROW inptr0, inptr1, inptr2, inptr3;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->output_width;
+ /* copy these pointers into registers if possible */
+ register JSAMPLE * range_limit = cinfo->sample_range_limit;
+ register int * Crrtab = cconvert->Cr_r_tab;
+ register int * Cbbtab = cconvert->Cb_b_tab;
+ register INT32 * Crgtab = cconvert->Cr_g_tab;
+ register INT32 * Cbgtab = cconvert->Cb_g_tab;
+ SHIFT_TEMPS
+
+ while (--num_rows >= 0) {
+ inptr0 = input_buf[0][input_row];
+ inptr1 = input_buf[1][input_row];
+ inptr2 = input_buf[2][input_row];
+ inptr3 = input_buf[3][input_row];
+ input_row++;
+ outptr = *output_buf++;
+ for (col = 0; col < num_cols; col++) {
+ y = GETJSAMPLE(inptr0[col]);
+ cb = GETJSAMPLE(inptr1[col]);
+ cr = GETJSAMPLE(inptr2[col]);
+ /* Range-limiting is essential due to noise introduced by DCT losses. */
+ outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */
+ outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */
+ ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
+ SCALEBITS)))];
+ outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
+ /* K passes through unchanged */
+ outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */
+ outptr += 4;
+ }
+ }
+}
+
+
+/*
+ * Empty method for start_pass.
+ */
+
+METHODDEF(void)
+start_pass_dcolor (j_decompress_ptr cinfo)
+{
+ /* no work needed */
+}
+
+
+/*
+ * Module initialization routine for output colorspace conversion.
+ */
+
+GLOBAL(void)
+jinit_color_deconverter (j_decompress_ptr cinfo)
+{
+ my_cconvert_ptr cconvert;
+ int ci;
+
+ cconvert = (my_cconvert_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_color_deconverter));
+ cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
+ cconvert->pub.start_pass = start_pass_dcolor;
+
+ /* Make sure num_components agrees with jpeg_color_space */
+ switch (cinfo->jpeg_color_space) {
+ case JCS_GRAYSCALE:
+ if (cinfo->num_components != 1)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ break;
+
+ case JCS_RGB:
+ case JCS_YCbCr:
+ if (cinfo->num_components != 3)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ break;
+
+ case JCS_CMYK:
+ case JCS_YCCK:
+ if (cinfo->num_components != 4)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ break;
+
+ default: /* JCS_UNKNOWN can be anything */
+ if (cinfo->num_components < 1)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ break;
+ }
+
+ /* Set out_color_components and conversion method based on requested space.
+ * Also clear the component_needed flags for any unused components,
+ * so that earlier pipeline stages can avoid useless computation.
+ */
+
+ switch (cinfo->out_color_space) {
+ case JCS_GRAYSCALE:
+ cinfo->out_color_components = 1;
+ if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
+ cinfo->jpeg_color_space == JCS_YCbCr) {
+ cconvert->pub.color_convert = grayscale_convert;
+ /* For color->grayscale conversion, only the Y (0) component is needed */
+ for (ci = 1; ci < cinfo->num_components; ci++)
+ cinfo->comp_info[ci].component_needed = FALSE;
+ } else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_RGB:
+ case JCS_EXT_RGB:
+ case JCS_EXT_RGBX:
+ case JCS_EXT_BGR:
+ case JCS_EXT_BGRX:
+ case JCS_EXT_XBGR:
+ case JCS_EXT_XRGB:
+ case JCS_EXT_RGBA:
+ case JCS_EXT_BGRA:
+ case JCS_EXT_ABGR:
+ case JCS_EXT_ARGB:
+ cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
+ if (cinfo->jpeg_color_space == JCS_YCbCr) {
+ if (jsimd_can_ycc_rgb())
+ cconvert->pub.color_convert = jsimd_ycc_rgb_convert;
+ else {
+ cconvert->pub.color_convert = ycc_rgb_convert;
+ build_ycc_rgb_table(cinfo);
+ }
+ } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
+ cconvert->pub.color_convert = gray_rgb_convert;
+ } else if (cinfo->jpeg_color_space == cinfo->out_color_space &&
+ rgb_pixelsize[cinfo->out_color_space] == 3) {
+ cconvert->pub.color_convert = null_convert;
+ } else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_CMYK:
+ cinfo->out_color_components = 4;
+ if (cinfo->jpeg_color_space == JCS_YCCK) {
+ cconvert->pub.color_convert = ycck_cmyk_convert;
+ build_ycc_rgb_table(cinfo);
+ } else if (cinfo->jpeg_color_space == JCS_CMYK) {
+ cconvert->pub.color_convert = null_convert;
+ } else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ default:
+ /* Permit null conversion to same output space */
+ if (cinfo->out_color_space == cinfo->jpeg_color_space) {
+ cinfo->out_color_components = cinfo->num_components;
+ cconvert->pub.color_convert = null_convert;
+ } else /* unsupported non-null conversion */
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+ }
+
+ if (cinfo->quantize_colors)
+ cinfo->output_components = 1; /* single colormapped output component */
+ else
+ cinfo->output_components = cinfo->out_color_components;
+}
diff --git a/src/libjpeg-turbo/jdct.h b/src/libjpeg-turbo/jdct.h
new file mode 100644
index 0000000..7b49a97
--- /dev/null
+++ b/src/libjpeg-turbo/jdct.h
@@ -0,0 +1,184 @@
+/*
+ * jdct.h
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This include file contains common declarations for the forward and
+ * inverse DCT modules. These declarations are private to the DCT managers
+ * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms.
+ * The individual DCT algorithms are kept in separate files to ease
+ * machine-dependent tuning (e.g., assembly coding).
+ */
+
+
+/*
+ * A forward DCT routine is given a pointer to a work area of type DCTELEM[];
+ * the DCT is to be performed in-place in that buffer. Type DCTELEM is int
+ * for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT
+ * implementations use an array of type FAST_FLOAT, instead.)
+ * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
+ * The DCT outputs are returned scaled up by a factor of 8; they therefore
+ * have a range of +-8K for 8-bit data, +-128K for 12-bit data. This
+ * convention improves accuracy in integer implementations and saves some
+ * work in floating-point ones.
+ * Quantization of the output coefficients is done by jcdctmgr.c. This
+ * step requires an unsigned type and also one with twice the bits.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#ifndef WITH_SIMD
+typedef int DCTELEM; /* 16 or 32 bits is fine */
+typedef unsigned int UDCTELEM;
+typedef unsigned long long UDCTELEM2;
+#else
+typedef short DCTELEM; /* prefer 16 bit with SIMD for parellelism */
+typedef unsigned short UDCTELEM;
+typedef unsigned int UDCTELEM2;
+#endif
+#else
+typedef INT32 DCTELEM; /* must have 32 bits */
+typedef UINT32 UDCTELEM;
+typedef unsigned long long UDCTELEM2;
+#endif
+
+
+/*
+ * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
+ * to an output sample array. The routine must dequantize the input data as
+ * well as perform the IDCT; for dequantization, it uses the multiplier table
+ * pointed to by compptr->dct_table. The output data is to be placed into the
+ * sample array starting at a specified column. (Any row offset needed will
+ * be applied to the array pointer before it is passed to the IDCT code.)
+ * Note that the number of samples emitted by the IDCT routine is
+ * DCT_scaled_size * DCT_scaled_size.
+ */
+
+/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
+
+/*
+ * Each IDCT routine has its own ideas about the best dct_table element type.
+ */
+
+typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */
+#if BITS_IN_JSAMPLE == 8
+typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */
+#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */
+#else
+typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */
+#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */
+#endif
+typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
+
+
+/*
+ * Each IDCT routine is responsible for range-limiting its results and
+ * converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could
+ * be quite far out of range if the input data is corrupt, so a bulletproof
+ * range-limiting step is required. We use a mask-and-table-lookup method
+ * to do the combined operations quickly. See the comments with
+ * prepare_range_limit_table (in jdmaster.c) for more info.
+ */
+
+#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE)
+
+#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
+
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_fdct_islow jFDislow
+#define jpeg_fdct_ifast jFDifast
+#define jpeg_fdct_float jFDfloat
+#define jpeg_idct_islow jRDislow
+#define jpeg_idct_ifast jRDifast
+#define jpeg_idct_float jRDfloat
+#define jpeg_idct_4x4 jRD4x4
+#define jpeg_idct_2x2 jRD2x2
+#define jpeg_idct_1x1 jRD1x1
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+/* Extern declarations for the forward and inverse DCT routines. */
+
+EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data));
+EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data));
+EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data));
+
+EXTERN(void) jpeg_idct_islow
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_ifast
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_float
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_4x4
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_2x2
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_1x1
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+
+
+/*
+ * Macros for handling fixed-point arithmetic; these are used by many
+ * but not all of the DCT/IDCT modules.
+ *
+ * All values are expected to be of type INT32.
+ * Fractional constants are scaled left by CONST_BITS bits.
+ * CONST_BITS is defined within each module using these macros,
+ * and may differ from one module to the next.
+ */
+
+#define ONE ((INT32) 1)
+#define CONST_SCALE (ONE << CONST_BITS)
+
+/* Convert a positive real constant to an integer scaled by CONST_SCALE.
+ * Caution: some C compilers fail to reduce "FIX(constant)" at compile time,
+ * thus causing a lot of useless floating-point operations at run time.
+ */
+
+#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
+
+/* Descale and correctly round an INT32 value that's scaled by N bits.
+ * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
+ * the fudge factor is correct for either sign of X.
+ */
+
+#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * This macro is used only when the two inputs will actually be no more than
+ * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
+ * full 32x32 multiply. This provides a useful speedup on many machines.
+ * Unfortunately there is no way to specify a 16x16->32 multiply portably
+ * in C, but some C compilers will do the right thing if you provide the
+ * correct combination of casts.
+ */
+
+#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
+#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const)))
+#endif
+#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */
+#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const)))
+#endif
+
+#ifndef MULTIPLY16C16 /* default definition */
+#define MULTIPLY16C16(var,const) ((var) * (const))
+#endif
+
+/* Same except both inputs are variables. */
+
+#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
+#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2)))
+#endif
+
+#ifndef MULTIPLY16V16 /* default definition */
+#define MULTIPLY16V16(var1,var2) ((var1) * (var2))
+#endif
diff --git a/src/libjpeg-turbo/jddctmgr.c b/src/libjpeg-turbo/jddctmgr.c
new file mode 100644
index 0000000..044e469
--- /dev/null
+++ b/src/libjpeg-turbo/jddctmgr.c
@@ -0,0 +1,288 @@
+/*
+ * jddctmgr.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright (C) 2010, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the inverse-DCT management logic.
+ * This code selects a particular IDCT implementation to be used,
+ * and it performs related housekeeping chores. No code in this file
+ * is executed per IDCT step, only during output pass setup.
+ *
+ * Note that the IDCT routines are responsible for performing coefficient
+ * dequantization as well as the IDCT proper. This module sets up the
+ * dequantization multiplier table needed by the IDCT routine.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+#include "jsimddct.h"
+#include "jpegcomp.h"
+
+
+/*
+ * The decompressor input side (jdinput.c) saves away the appropriate
+ * quantization table for each component at the start of the first scan
+ * involving that component. (This is necessary in order to correctly
+ * decode files that reuse Q-table slots.)
+ * When we are ready to make an output pass, the saved Q-table is converted
+ * to a multiplier table that will actually be used by the IDCT routine.
+ * The multiplier table contents are IDCT-method-dependent. To support
+ * application changes in IDCT method between scans, we can remake the
+ * multiplier tables if necessary.
+ * In buffered-image mode, the first output pass may occur before any data
+ * has been seen for some components, and thus before their Q-tables have
+ * been saved away. To handle this case, multiplier tables are preset
+ * to zeroes; the result of the IDCT will be a neutral gray level.
+ */
+
+
+/* Private subobject for this module */
+
+typedef struct {
+ struct jpeg_inverse_dct pub; /* public fields */
+
+ /* This array contains the IDCT method code that each multiplier table
+ * is currently set up for, or -1 if it's not yet set up.
+ * The actual multiplier tables are pointed to by dct_table in the
+ * per-component comp_info structures.
+ */
+ int cur_method[MAX_COMPONENTS];
+} my_idct_controller;
+
+typedef my_idct_controller * my_idct_ptr;
+
+
+/* Allocated multiplier tables: big enough for any supported variant */
+
+typedef union {
+ ISLOW_MULT_TYPE islow_array[DCTSIZE2];
+#ifdef DCT_IFAST_SUPPORTED
+ IFAST_MULT_TYPE ifast_array[DCTSIZE2];
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+ FLOAT_MULT_TYPE float_array[DCTSIZE2];
+#endif
+} multiplier_table;
+
+
+/* The current scaled-IDCT routines require ISLOW-style multiplier tables,
+ * so be sure to compile that code if either ISLOW or SCALING is requested.
+ */
+#ifdef DCT_ISLOW_SUPPORTED
+#define PROVIDE_ISLOW_TABLES
+#else
+#ifdef IDCT_SCALING_SUPPORTED
+#define PROVIDE_ISLOW_TABLES
+#endif
+#endif
+
+
+/*
+ * Prepare for an output pass.
+ * Here we select the proper IDCT routine for each component and build
+ * a matching multiplier table.
+ */
+
+METHODDEF(void)
+start_pass (j_decompress_ptr cinfo)
+{
+ my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
+ int ci, i;
+ jpeg_component_info *compptr;
+ int method = 0;
+ inverse_DCT_method_ptr method_ptr = NULL;
+ JQUANT_TBL * qtbl;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Select the proper IDCT routine for this component's scaling */
+ switch (compptr->_DCT_scaled_size) {
+#ifdef IDCT_SCALING_SUPPORTED
+ case 1:
+ method_ptr = jpeg_idct_1x1;
+ method = JDCT_ISLOW; /* jidctred uses islow-style table */
+ break;
+ case 2:
+ if (jsimd_can_idct_2x2())
+ method_ptr = jsimd_idct_2x2;
+ else
+ method_ptr = jpeg_idct_2x2;
+ method = JDCT_ISLOW; /* jidctred uses islow-style table */
+ break;
+ case 4:
+ if (jsimd_can_idct_4x4())
+ method_ptr = jsimd_idct_4x4;
+ else
+ method_ptr = jpeg_idct_4x4;
+ method = JDCT_ISLOW; /* jidctred uses islow-style table */
+ break;
+#endif
+ case DCTSIZE:
+ switch (cinfo->dct_method) {
+#ifdef DCT_ISLOW_SUPPORTED
+ case JDCT_ISLOW:
+ if (jsimd_can_idct_islow())
+ method_ptr = jsimd_idct_islow;
+ else
+ method_ptr = jpeg_idct_islow;
+ method = JDCT_ISLOW;
+ break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+ case JDCT_IFAST:
+ if (jsimd_can_idct_ifast())
+ method_ptr = jsimd_idct_ifast;
+ else
+ method_ptr = jpeg_idct_ifast;
+ method = JDCT_IFAST;
+ break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+ case JDCT_FLOAT:
+ if (jsimd_can_idct_float())
+ method_ptr = jsimd_idct_float;
+ else
+ method_ptr = jpeg_idct_float;
+ method = JDCT_FLOAT;
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ break;
+ }
+ break;
+ default:
+ ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->_DCT_scaled_size);
+ break;
+ }
+ idct->pub.inverse_DCT[ci] = method_ptr;
+ /* Create multiplier table from quant table.
+ * However, we can skip this if the component is uninteresting
+ * or if we already built the table. Also, if no quant table
+ * has yet been saved for the component, we leave the
+ * multiplier table all-zero; we'll be reading zeroes from the
+ * coefficient controller's buffer anyway.
+ */
+ if (! compptr->component_needed || idct->cur_method[ci] == method)
+ continue;
+ qtbl = compptr->quant_table;
+ if (qtbl == NULL) /* happens if no data yet for component */
+ continue;
+ idct->cur_method[ci] = method;
+ switch (method) {
+#ifdef PROVIDE_ISLOW_TABLES
+ case JDCT_ISLOW:
+ {
+ /* For LL&M IDCT method, multipliers are equal to raw quantization
+ * coefficients, but are stored as ints to ensure access efficiency.
+ */
+ ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
+ for (i = 0; i < DCTSIZE2; i++) {
+ ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
+ }
+ }
+ break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+ case JDCT_IFAST:
+ {
+ /* For AA&N IDCT method, multipliers are equal to quantization
+ * coefficients scaled by scalefactor[row]*scalefactor[col], where
+ * scalefactor[0] = 1
+ * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
+ * For integer operation, the multiplier table is to be scaled by
+ * IFAST_SCALE_BITS.
+ */
+ IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
+#define CONST_BITS 14
+ static const INT16 aanscales[DCTSIZE2] = {
+ /* precomputed values scaled up by 14 bits */
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
+ 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
+ 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
+ 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
+ 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
+ };
+ SHIFT_TEMPS
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ ifmtbl[i] = (IFAST_MULT_TYPE)
+ DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
+ (INT32) aanscales[i]),
+ CONST_BITS-IFAST_SCALE_BITS);
+ }
+ }
+ break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+ case JDCT_FLOAT:
+ {
+ /* For float AA&N IDCT method, multipliers are equal to quantization
+ * coefficients scaled by scalefactor[row]*scalefactor[col], where
+ * scalefactor[0] = 1
+ * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
+ */
+ FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
+ int row, col;
+ static const double aanscalefactor[DCTSIZE] = {
+ 1.0, 1.387039845, 1.306562965, 1.175875602,
+ 1.0, 0.785694958, 0.541196100, 0.275899379
+ };
+
+ i = 0;
+ for (row = 0; row < DCTSIZE; row++) {
+ for (col = 0; col < DCTSIZE; col++) {
+ fmtbl[i] = (FLOAT_MULT_TYPE)
+ ((double) qtbl->quantval[i] *
+ aanscalefactor[row] * aanscalefactor[col]);
+ i++;
+ }
+ }
+ }
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ break;
+ }
+ }
+}
+
+
+/*
+ * Initialize IDCT manager.
+ */
+
+GLOBAL(void)
+jinit_inverse_dct (j_decompress_ptr cinfo)
+{
+ my_idct_ptr idct;
+ int ci;
+ jpeg_component_info *compptr;
+
+ idct = (my_idct_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_idct_controller));
+ cinfo->idct = (struct jpeg_inverse_dct *) idct;
+ idct->pub.start_pass = start_pass;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Allocate and pre-zero a multiplier table for each component */
+ compptr->dct_table =
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(multiplier_table));
+ MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
+ /* Mark multiplier table not yet set up for any method */
+ idct->cur_method[ci] = -1;
+ }
+}
diff --git a/src/libjpeg-turbo/jdhuff.c b/src/libjpeg-turbo/jdhuff.c
new file mode 100644
index 0000000..f822dba
--- /dev/null
+++ b/src/libjpeg-turbo/jdhuff.c
@@ -0,0 +1,808 @@
+/*
+ * jdhuff.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Copyright (C) 2009-2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains Huffman entropy decoding routines.
+ *
+ * Much of the complexity here has to do with supporting input suspension.
+ * If the data source module demands suspension, we want to be able to back
+ * up to the start of the current MCU. To do this, we copy state variables
+ * into local working storage, and update them back to the permanent
+ * storage only upon successful completion of an MCU.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdhuff.h" /* Declarations shared with jdphuff.c */
+#include "jpegcomp.h"
+
+
+/*
+ * Expanded entropy decoder object for Huffman decoding.
+ *
+ * The savable_state subrecord contains fields that change within an MCU,
+ * but must not be updated permanently until we complete the MCU.
+ */
+
+typedef struct {
+ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+} savable_state;
+
+/* This macro is to work around compilers with missing or broken
+ * structure assignment. You'll need to fix this code if you have
+ * such a compiler and you change MAX_COMPS_IN_SCAN.
+ */
+
+#ifndef NO_STRUCT_ASSIGN
+#define ASSIGN_STATE(dest,src) ((dest) = (src))
+#else
+#if MAX_COMPS_IN_SCAN == 4
+#define ASSIGN_STATE(dest,src) \
+ ((dest).last_dc_val[0] = (src).last_dc_val[0], \
+ (dest).last_dc_val[1] = (src).last_dc_val[1], \
+ (dest).last_dc_val[2] = (src).last_dc_val[2], \
+ (dest).last_dc_val[3] = (src).last_dc_val[3])
+#endif
+#endif
+
+
+typedef struct {
+ struct jpeg_entropy_decoder pub; /* public fields */
+
+ /* These fields are loaded into local variables at start of each MCU.
+ * In case of suspension, we exit WITHOUT updating them.
+ */
+ bitread_perm_state bitstate; /* Bit buffer at start of MCU */
+ savable_state saved; /* Other state at start of MCU */
+
+ /* These fields are NOT loaded into local working state. */
+ unsigned int restarts_to_go; /* MCUs left in this restart interval */
+
+ /* Pointers to derived tables (these workspaces have image lifespan) */
+ d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
+ d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
+
+ /* Precalculated info set up by start_pass for use in decode_mcu: */
+
+ /* Pointers to derived tables to be used for each block within an MCU */
+ d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU];
+ d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU];
+ /* Whether we care about the DC and AC coefficient values for each block */
+ boolean dc_needed[D_MAX_BLOCKS_IN_MCU];
+ boolean ac_needed[D_MAX_BLOCKS_IN_MCU];
+} huff_entropy_decoder;
+
+typedef huff_entropy_decoder * huff_entropy_ptr;
+
+
+/*
+ * Initialize for a Huffman-compressed scan.
+ */
+
+METHODDEF(void)
+start_pass_huff_decoder (j_decompress_ptr cinfo)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int ci, blkn, dctbl, actbl;
+ jpeg_component_info * compptr;
+
+ /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
+ * This ought to be an error condition, but we make it a warning because
+ * there are some baseline files out there with all zeroes in these bytes.
+ */
+ if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 ||
+ cinfo->Ah != 0 || cinfo->Al != 0)
+ WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ dctbl = compptr->dc_tbl_no;
+ actbl = compptr->ac_tbl_no;
+ /* Compute derived values for Huffman tables */
+ /* We may do this more than once for a table, but it's not expensive */
+ jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl,
+ & entropy->dc_derived_tbls[dctbl]);
+ jpeg_make_d_derived_tbl(cinfo, FALSE, actbl,
+ & entropy->ac_derived_tbls[actbl]);
+ /* Initialize DC predictions to 0 */
+ entropy->saved.last_dc_val[ci] = 0;
+ }
+
+ /* Precalculate decoding info for each block in an MCU of this scan */
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+ /* Precalculate which table to use for each block */
+ entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
+ entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
+ /* Decide whether we really care about the coefficient values */
+ if (compptr->component_needed) {
+ entropy->dc_needed[blkn] = TRUE;
+ /* we don't need the ACs if producing a 1/8th-size image */
+ entropy->ac_needed[blkn] = (compptr->_DCT_scaled_size > 1);
+ } else {
+ entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE;
+ }
+ }
+
+ /* Initialize bitread state variables */
+ entropy->bitstate.bits_left = 0;
+ entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
+ entropy->pub.insufficient_data = FALSE;
+
+ /* Initialize restart counter */
+ entropy->restarts_to_go = cinfo->restart_interval;
+}
+
+
+/*
+ * Compute the derived values for a Huffman table.
+ * This routine also performs some validation checks on the table.
+ *
+ * Note this is also used by jdphuff.c.
+ */
+
+GLOBAL(void)
+jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
+ d_derived_tbl ** pdtbl)
+{
+ JHUFF_TBL *htbl;
+ d_derived_tbl *dtbl;
+ int p, i, l, si, numsymbols;
+ int lookbits, ctr;
+ char huffsize[257];
+ unsigned int huffcode[257];
+ unsigned int code;
+
+ /* Note that huffsize[] and huffcode[] are filled in code-length order,
+ * paralleling the order of the symbols themselves in htbl->huffval[].
+ */
+
+ /* Find the input Huffman table */
+ if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+ htbl =
+ isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
+ if (htbl == NULL)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+
+ /* Allocate a workspace if we haven't already done so. */
+ if (*pdtbl == NULL)
+ *pdtbl = (d_derived_tbl *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(d_derived_tbl));
+ dtbl = *pdtbl;
+ dtbl->pub = htbl; /* fill in back link */
+
+ /* Figure C.1: make table of Huffman code length for each symbol */
+
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ i = (int) htbl->bits[l];
+ if (i < 0 || p + i > 256) /* protect against table overrun */
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ while (i--)
+ huffsize[p++] = (char) l;
+ }
+ huffsize[p] = 0;
+ numsymbols = p;
+
+ /* Figure C.2: generate the codes themselves */
+ /* We also validate that the counts represent a legal Huffman code tree. */
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p]) {
+ while (((int) huffsize[p]) == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ /* code is now 1 more than the last code used for codelength si; but
+ * it must still fit in si bits, since no code is allowed to be all ones.
+ */
+ if (((INT32) code) >= (((INT32) 1) << si))
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ code <<= 1;
+ si++;
+ }
+
+ /* Figure F.15: generate decoding tables for bit-sequential decoding */
+
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ if (htbl->bits[l]) {
+ /* valoffset[l] = huffval[] index of 1st symbol of code length l,
+ * minus the minimum code of length l
+ */
+ dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
+ p += htbl->bits[l];
+ dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
+ } else {
+ dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
+ }
+ }
+ dtbl->valoffset[17] = 0;
+ dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */
+
+ /* Compute lookahead tables to speed up decoding.
+ * First we set all the table entries to 0, indicating "too long";
+ * then we iterate through the Huffman codes that are short enough and
+ * fill in all the entries that correspond to bit sequences starting
+ * with that code.
+ */
+
+ for (i = 0; i < (1 << HUFF_LOOKAHEAD); i++)
+ dtbl->lookup[i] = (HUFF_LOOKAHEAD + 1) << HUFF_LOOKAHEAD;
+
+ p = 0;
+ for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
+ for (i = 1; i <= (int) htbl->bits[l]; i++, p++) {
+ /* l = current code's length, p = its index in huffcode[] & huffval[]. */
+ /* Generate left-justified code followed by all possible bit sequences */
+ lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
+ for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
+ dtbl->lookup[lookbits] = (l << HUFF_LOOKAHEAD) | htbl->huffval[p];
+ lookbits++;
+ }
+ }
+ }
+
+ /* Validate symbols as being reasonable.
+ * For AC tables, we make no check, but accept all byte values 0..255.
+ * For DC tables, we require the symbols to be in range 0..15.
+ * (Tighter bounds could be applied depending on the data depth and mode,
+ * but this is sufficient to ensure safe decoding.)
+ */
+ if (isDC) {
+ for (i = 0; i < numsymbols; i++) {
+ int sym = htbl->huffval[i];
+ if (sym < 0 || sym > 15)
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ }
+ }
+}
+
+
+/*
+ * Out-of-line code for bit fetching (shared with jdphuff.c).
+ * See jdhuff.h for info about usage.
+ * Note: current values of get_buffer and bits_left are passed as parameters,
+ * but are returned in the corresponding fields of the state struct.
+ *
+ * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
+ * of get_buffer to be used. (On machines with wider words, an even larger
+ * buffer could be used.) However, on some machines 32-bit shifts are
+ * quite slow and take time proportional to the number of places shifted.
+ * (This is true with most PC compilers, for instance.) In this case it may
+ * be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the
+ * average shift distance at the cost of more calls to jpeg_fill_bit_buffer.
+ */
+
+#ifdef SLOW_SHIFT_32
+#define MIN_GET_BITS 15 /* minimum allowable value */
+#else
+#define MIN_GET_BITS (BIT_BUF_SIZE-7)
+#endif
+
+
+GLOBAL(boolean)
+jpeg_fill_bit_buffer (bitread_working_state * state,
+ register bit_buf_type get_buffer, register int bits_left,
+ int nbits)
+/* Load up the bit buffer to a depth of at least nbits */
+{
+ /* Copy heavily used state fields into locals (hopefully registers) */
+ register const JOCTET * next_input_byte = state->next_input_byte;
+ register size_t bytes_in_buffer = state->bytes_in_buffer;
+ j_decompress_ptr cinfo = state->cinfo;
+
+ /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */
+ /* (It is assumed that no request will be for more than that many bits.) */
+ /* We fail to do so only if we hit a marker or are forced to suspend. */
+
+ if (cinfo->unread_marker == 0) { /* cannot advance past a marker */
+ while (bits_left < MIN_GET_BITS) {
+ register int c;
+
+ /* Attempt to read a byte */
+ if (bytes_in_buffer == 0) {
+ if (! (*cinfo->src->fill_input_buffer) (cinfo))
+ return FALSE;
+ next_input_byte = cinfo->src->next_input_byte;
+ bytes_in_buffer = cinfo->src->bytes_in_buffer;
+ }
+ bytes_in_buffer--;
+ c = GETJOCTET(*next_input_byte++);
+
+ /* If it's 0xFF, check and discard stuffed zero byte */
+ if (c == 0xFF) {
+ /* Loop here to discard any padding FF's on terminating marker,
+ * so that we can save a valid unread_marker value. NOTE: we will
+ * accept multiple FF's followed by a 0 as meaning a single FF data
+ * byte. This data pattern is not valid according to the standard.
+ */
+ do {
+ if (bytes_in_buffer == 0) {
+ if (! (*cinfo->src->fill_input_buffer) (cinfo))
+ return FALSE;
+ next_input_byte = cinfo->src->next_input_byte;
+ bytes_in_buffer = cinfo->src->bytes_in_buffer;
+ }
+ bytes_in_buffer--;
+ c = GETJOCTET(*next_input_byte++);
+ } while (c == 0xFF);
+
+ if (c == 0) {
+ /* Found FF/00, which represents an FF data byte */
+ c = 0xFF;
+ } else {
+ /* Oops, it's actually a marker indicating end of compressed data.
+ * Save the marker code for later use.
+ * Fine point: it might appear that we should save the marker into
+ * bitread working state, not straight into permanent state. But
+ * once we have hit a marker, we cannot need to suspend within the
+ * current MCU, because we will read no more bytes from the data
+ * source. So it is OK to update permanent state right away.
+ */
+ cinfo->unread_marker = c;
+ /* See if we need to insert some fake zero bits. */
+ goto no_more_bytes;
+ }
+ }
+
+ /* OK, load c into get_buffer */
+ get_buffer = (get_buffer << 8) | c;
+ bits_left += 8;
+ } /* end while */
+ } else {
+ no_more_bytes:
+ /* We get here if we've read the marker that terminates the compressed
+ * data segment. There should be enough bits in the buffer register
+ * to satisfy the request; if so, no problem.
+ */
+ if (nbits > bits_left) {
+ /* Uh-oh. Report corrupted data to user and stuff zeroes into
+ * the data stream, so that we can produce some kind of image.
+ * We use a nonvolatile flag to ensure that only one warning message
+ * appears per data segment.
+ */
+ if (! cinfo->entropy->insufficient_data) {
+ WARNMS(cinfo, JWRN_HIT_MARKER);
+ cinfo->entropy->insufficient_data = TRUE;
+ }
+ /* Fill the buffer with zero bits */
+ get_buffer <<= MIN_GET_BITS - bits_left;
+ bits_left = MIN_GET_BITS;
+ }
+ }
+
+ /* Unload the local registers */
+ state->next_input_byte = next_input_byte;
+ state->bytes_in_buffer = bytes_in_buffer;
+ state->get_buffer = get_buffer;
+ state->bits_left = bits_left;
+
+ return TRUE;
+}
+
+
+/* Macro version of the above, which performs much better but does not
+ handle markers. We have to hand off any blocks with markers to the
+ slower routines. */
+
+#define GET_BYTE \
+{ \
+ register int c0, c1; \
+ c0 = GETJOCTET(*buffer++); \
+ c1 = GETJOCTET(*buffer); \
+ /* Pre-execute most common case */ \
+ get_buffer = (get_buffer << 8) | c0; \
+ bits_left += 8; \
+ if (c0 == 0xFF) { \
+ /* Pre-execute case of FF/00, which represents an FF data byte */ \
+ buffer++; \
+ if (c1 != 0) { \
+ /* Oops, it's actually a marker indicating end of compressed data. */ \
+ cinfo->unread_marker = c1; \
+ /* Back out pre-execution and fill the buffer with zero bits */ \
+ buffer -= 2; \
+ get_buffer &= ~0xFF; \
+ } \
+ } \
+}
+
+#if __WORDSIZE == 64 || defined(_WIN64)
+
+/* Pre-fetch 48 bytes, because the holding register is 64-bit */
+#define FILL_BIT_BUFFER_FAST \
+ if (bits_left < 16) { \
+ GET_BYTE GET_BYTE GET_BYTE GET_BYTE GET_BYTE GET_BYTE \
+ }
+
+#else
+
+/* Pre-fetch 16 bytes, because the holding register is 32-bit */
+#define FILL_BIT_BUFFER_FAST \
+ if (bits_left < 16) { \
+ GET_BYTE GET_BYTE \
+ }
+
+#endif
+
+
+/*
+ * Out-of-line code for Huffman code decoding.
+ * See jdhuff.h for info about usage.
+ */
+
+GLOBAL(int)
+jpeg_huff_decode (bitread_working_state * state,
+ register bit_buf_type get_buffer, register int bits_left,
+ d_derived_tbl * htbl, int min_bits)
+{
+ register int l = min_bits;
+ register INT32 code;
+
+ /* HUFF_DECODE has determined that the code is at least min_bits */
+ /* bits long, so fetch that many bits in one swoop. */
+
+ CHECK_BIT_BUFFER(*state, l, return -1);
+ code = GET_BITS(l);
+
+ /* Collect the rest of the Huffman code one bit at a time. */
+ /* This is per Figure F.16 in the JPEG spec. */
+
+ while (code > htbl->maxcode[l]) {
+ code <<= 1;
+ CHECK_BIT_BUFFER(*state, 1, return -1);
+ code |= GET_BITS(1);
+ l++;
+ }
+
+ /* Unload the local registers */
+ state->get_buffer = get_buffer;
+ state->bits_left = bits_left;
+
+ /* With garbage input we may reach the sentinel value l = 17. */
+
+ if (l > 16) {
+ WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE);
+ return 0; /* fake a zero as the safest result */
+ }
+
+ return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ];
+}
+
+
+/*
+ * Figure F.12: extend sign bit.
+ * On some machines, a shift and add will be faster than a table lookup.
+ */
+
+#define AVOID_TABLES
+#ifdef AVOID_TABLES
+
+#define HUFF_EXTEND(x,s) ((x) + ((((x) - (1<<((s)-1))) >> 31) & (((-1)<<(s)) + 1)))
+
+#else
+
+#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
+
+static const int extend_test[16] = /* entry n is 2**(n-1) */
+ { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
+
+static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
+ { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
+ ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
+ ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
+ ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
+
+#endif /* AVOID_TABLES */
+
+
+/*
+ * Check for a restart marker & resynchronize decoder.
+ * Returns FALSE if must suspend.
+ */
+
+LOCAL(boolean)
+process_restart (j_decompress_ptr cinfo)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int ci;
+
+ /* Throw away any unused bits remaining in bit buffer; */
+ /* include any full bytes in next_marker's count of discarded bytes */
+ cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
+ entropy->bitstate.bits_left = 0;
+
+ /* Advance past the RSTn marker */
+ if (! (*cinfo->marker->read_restart_marker) (cinfo))
+ return FALSE;
+
+ /* Re-initialize DC predictions to 0 */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+ entropy->saved.last_dc_val[ci] = 0;
+
+ /* Reset restart counter */
+ entropy->restarts_to_go = cinfo->restart_interval;
+
+ /* Reset out-of-data flag, unless read_restart_marker left us smack up
+ * against a marker. In that case we will end up treating the next data
+ * segment as empty, and we can avoid producing bogus output pixels by
+ * leaving the flag set.
+ */
+ if (cinfo->unread_marker == 0)
+ entropy->pub.insufficient_data = FALSE;
+
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+decode_mcu_slow (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ BITREAD_STATE_VARS;
+ int blkn;
+ savable_state state;
+ /* Outer loop handles each block in the MCU */
+
+ /* Load up working state */
+ BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+ ASSIGN_STATE(state, entropy->saved);
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ JBLOCKROW block = MCU_data[blkn];
+ d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn];
+ d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn];
+ register int s, k, r;
+
+ /* Decode a single block's worth of coefficients */
+
+ /* Section F.2.2.1: decode the DC coefficient difference */
+ HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);
+ if (s) {
+ CHECK_BIT_BUFFER(br_state, s, return FALSE);
+ r = GET_BITS(s);
+ s = HUFF_EXTEND(r, s);
+ }
+
+ if (entropy->dc_needed[blkn]) {
+ /* Convert DC difference to actual value, update last_dc_val */
+ int ci = cinfo->MCU_membership[blkn];
+ s += state.last_dc_val[ci];
+ state.last_dc_val[ci] = s;
+ /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
+ (*block)[0] = (JCOEF) s;
+ }
+
+ if (entropy->ac_needed[blkn]) {
+
+ /* Section F.2.2.2: decode the AC coefficients */
+ /* Since zeroes are skipped, output area must be cleared beforehand */
+ for (k = 1; k < DCTSIZE2; k++) {
+ HUFF_DECODE(s, br_state, actbl, return FALSE, label2);
+
+ r = s >> 4;
+ s &= 15;
+
+ if (s) {
+ k += r;
+ CHECK_BIT_BUFFER(br_state, s, return FALSE);
+ r = GET_BITS(s);
+ s = HUFF_EXTEND(r, s);
+ /* Output coefficient in natural (dezigzagged) order.
+ * Note: the extra entries in jpeg_natural_order[] will save us
+ * if k >= DCTSIZE2, which could happen if the data is corrupted.
+ */
+ (*block)[jpeg_natural_order[k]] = (JCOEF) s;
+ } else {
+ if (r != 15)
+ break;
+ k += 15;
+ }
+ }
+
+ } else {
+
+ /* Section F.2.2.2: decode the AC coefficients */
+ /* In this path we just discard the values */
+ for (k = 1; k < DCTSIZE2; k++) {
+ HUFF_DECODE(s, br_state, actbl, return FALSE, label3);
+
+ r = s >> 4;
+ s &= 15;
+
+ if (s) {
+ k += r;
+ CHECK_BIT_BUFFER(br_state, s, return FALSE);
+ DROP_BITS(s);
+ } else {
+ if (r != 15)
+ break;
+ k += 15;
+ }
+ }
+ }
+ }
+
+ /* Completed MCU, so update state */
+ BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+ ASSIGN_STATE(entropy->saved, state);
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+decode_mcu_fast (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ BITREAD_STATE_VARS;
+ JOCTET *buffer;
+ int blkn;
+ savable_state state;
+ /* Outer loop handles each block in the MCU */
+
+ /* Load up working state */
+ BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+ buffer = (JOCTET *) br_state.next_input_byte;
+ ASSIGN_STATE(state, entropy->saved);
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ JBLOCKROW block = MCU_data[blkn];
+ d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn];
+ d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn];
+ register int s, k, r, l;
+
+ HUFF_DECODE_FAST(s, l, dctbl);
+ if (s) {
+ FILL_BIT_BUFFER_FAST
+ r = GET_BITS(s);
+ s = HUFF_EXTEND(r, s);
+ }
+
+ if (entropy->dc_needed[blkn]) {
+ int ci = cinfo->MCU_membership[blkn];
+ s += state.last_dc_val[ci];
+ state.last_dc_val[ci] = s;
+ (*block)[0] = (JCOEF) s;
+ }
+
+ if (entropy->ac_needed[blkn]) {
+
+ for (k = 1; k < DCTSIZE2; k++) {
+ HUFF_DECODE_FAST(s, l, actbl);
+ r = s >> 4;
+ s &= 15;
+
+ if (s) {
+ k += r;
+ FILL_BIT_BUFFER_FAST
+ r = GET_BITS(s);
+ s = HUFF_EXTEND(r, s);
+ (*block)[jpeg_natural_order[k]] = (JCOEF) s;
+ } else {
+ if (r != 15) break;
+ k += 15;
+ }
+ }
+
+ } else {
+
+ for (k = 1; k < DCTSIZE2; k++) {
+ HUFF_DECODE_FAST(s, l, actbl);
+ r = s >> 4;
+ s &= 15;
+
+ if (s) {
+ k += r;
+ FILL_BIT_BUFFER_FAST
+ DROP_BITS(s);
+ } else {
+ if (r != 15) break;
+ k += 15;
+ }
+ }
+ }
+ }
+
+ if (cinfo->unread_marker != 0) {
+ cinfo->unread_marker = 0;
+ return FALSE;
+ }
+
+ br_state.bytes_in_buffer -= (buffer - br_state.next_input_byte);
+ br_state.next_input_byte = buffer;
+ BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+ ASSIGN_STATE(entropy->saved, state);
+ return TRUE;
+}
+
+
+/*
+ * Decode and return one MCU's worth of Huffman-compressed coefficients.
+ * The coefficients are reordered from zigzag order into natural array order,
+ * but are not dequantized.
+ *
+ * The i'th block of the MCU is stored into the block pointed to by
+ * MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER.
+ * (Wholesale zeroing is usually a little faster than retail...)
+ *
+ * Returns FALSE if data source requested suspension. In that case no
+ * changes have been made to permanent state. (Exception: some output
+ * coefficients may already have been assigned. This is harmless for
+ * this module, since we'll just re-assign them on the next call.)
+ */
+
+#define BUFSIZE (DCTSIZE2 * 2)
+
+METHODDEF(boolean)
+decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int usefast = 1;
+
+ /* Process restart marker if needed; may have to suspend */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! process_restart(cinfo))
+ return FALSE;
+ usefast = 0;
+ }
+
+ if (cinfo->src->bytes_in_buffer < BUFSIZE * (size_t)cinfo->blocks_in_MCU
+ || cinfo->unread_marker != 0)
+ usefast = 0;
+
+ /* If we've run out of data, just leave the MCU set to zeroes.
+ * This way, we return uniform gray for the remainder of the segment.
+ */
+ if (! entropy->pub.insufficient_data) {
+
+ if (usefast) {
+ if (!decode_mcu_fast(cinfo, MCU_data)) goto use_slow;
+ }
+ else {
+ use_slow:
+ if (!decode_mcu_slow(cinfo, MCU_data)) return FALSE;
+ }
+
+ }
+
+ /* Account for restart interval (no-op if not using restarts) */
+ entropy->restarts_to_go--;
+
+ return TRUE;
+}
+
+
+/*
+ * Module initialization routine for Huffman entropy decoding.
+ */
+
+GLOBAL(void)
+jinit_huff_decoder (j_decompress_ptr cinfo)
+{
+ huff_entropy_ptr entropy;
+ int i;
+
+ entropy = (huff_entropy_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(huff_entropy_decoder));
+ cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
+ entropy->pub.start_pass = start_pass_huff_decoder;
+ entropy->pub.decode_mcu = decode_mcu;
+
+ /* Mark tables unallocated */
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
+ }
+}
diff --git a/src/libjpeg-turbo/jdhuff.h b/src/libjpeg-turbo/jdhuff.h
new file mode 100644
index 0000000..96f2dab
--- /dev/null
+++ b/src/libjpeg-turbo/jdhuff.h
@@ -0,0 +1,234 @@
+/*
+ * jdhuff.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Copyright (C) 2010-2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains declarations for Huffman entropy decoding routines
+ * that are shared between the sequential decoder (jdhuff.c) and the
+ * progressive decoder (jdphuff.c). No other modules need to see these.
+ */
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_make_d_derived_tbl jMkDDerived
+#define jpeg_fill_bit_buffer jFilBitBuf
+#define jpeg_huff_decode jHufDecode
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/* Derived data constructed for each Huffman table */
+
+#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
+
+typedef struct {
+ /* Basic tables: (element [0] of each array is unused) */
+ INT32 maxcode[18]; /* largest code of length k (-1 if none) */
+ /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
+ INT32 valoffset[18]; /* huffval[] offset for codes of length k */
+ /* valoffset[k] = huffval[] index of 1st symbol of code length k, less
+ * the smallest code of length k; so given a code of length k, the
+ * corresponding symbol is huffval[code + valoffset[k]]
+ */
+
+ /* Link to public Huffman table (needed only in jpeg_huff_decode) */
+ JHUFF_TBL *pub;
+
+ /* Lookahead table: indexed by the next HUFF_LOOKAHEAD bits of
+ * the input data stream. If the next Huffman code is no more
+ * than HUFF_LOOKAHEAD bits long, we can obtain its length and
+ * the corresponding symbol directly from this tables.
+ *
+ * The lower 8 bits of each table entry contain the number of
+ * bits in the corresponding Huffman code, or HUFF_LOOKAHEAD + 1
+ * if too long. The next 8 bits of each entry contain the
+ * symbol.
+ */
+ int lookup[1<<HUFF_LOOKAHEAD];
+} d_derived_tbl;
+
+/* Expand a Huffman table definition into the derived format */
+EXTERN(void) jpeg_make_d_derived_tbl
+ JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
+ d_derived_tbl ** pdtbl));
+
+
+/*
+ * Fetching the next N bits from the input stream is a time-critical operation
+ * for the Huffman decoders. We implement it with a combination of inline
+ * macros and out-of-line subroutines. Note that N (the number of bits
+ * demanded at one time) never exceeds 15 for JPEG use.
+ *
+ * We read source bytes into get_buffer and dole out bits as needed.
+ * If get_buffer already contains enough bits, they are fetched in-line
+ * by the macros CHECK_BIT_BUFFER and GET_BITS. When there aren't enough
+ * bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer
+ * as full as possible (not just to the number of bits needed; this
+ * prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer).
+ * Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension.
+ * On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains
+ * at least the requested number of bits --- dummy zeroes are inserted if
+ * necessary.
+ */
+
+#if __WORDSIZE == 64 || defined(_WIN64)
+
+typedef size_t bit_buf_type; /* type of bit-extraction buffer */
+#define BIT_BUF_SIZE 64 /* size of buffer in bits */
+
+#else
+
+typedef INT32 bit_buf_type; /* type of bit-extraction buffer */
+#define BIT_BUF_SIZE 32 /* size of buffer in bits */
+
+#endif
+
+/* If long is > 32 bits on your machine, and shifting/masking longs is
+ * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
+ * appropriately should be a win. Unfortunately we can't define the size
+ * with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
+ * because not all machines measure sizeof in 8-bit bytes.
+ */
+
+typedef struct { /* Bitreading state saved across MCUs */
+ bit_buf_type get_buffer; /* current bit-extraction buffer */
+ int bits_left; /* # of unused bits in it */
+} bitread_perm_state;
+
+typedef struct { /* Bitreading working state within an MCU */
+ /* Current data source location */
+ /* We need a copy, rather than munging the original, in case of suspension */
+ const JOCTET * next_input_byte; /* => next byte to read from source */
+ size_t bytes_in_buffer; /* # of bytes remaining in source buffer */
+ /* Bit input buffer --- note these values are kept in register variables,
+ * not in this struct, inside the inner loops.
+ */
+ bit_buf_type get_buffer; /* current bit-extraction buffer */
+ int bits_left; /* # of unused bits in it */
+ /* Pointer needed by jpeg_fill_bit_buffer. */
+ j_decompress_ptr cinfo; /* back link to decompress master record */
+} bitread_working_state;
+
+/* Macros to declare and load/save bitread local variables. */
+#define BITREAD_STATE_VARS \
+ register bit_buf_type get_buffer; \
+ register int bits_left; \
+ bitread_working_state br_state
+
+#define BITREAD_LOAD_STATE(cinfop,permstate) \
+ br_state.cinfo = cinfop; \
+ br_state.next_input_byte = cinfop->src->next_input_byte; \
+ br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
+ get_buffer = permstate.get_buffer; \
+ bits_left = permstate.bits_left;
+
+#define BITREAD_SAVE_STATE(cinfop,permstate) \
+ cinfop->src->next_input_byte = br_state.next_input_byte; \
+ cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
+ permstate.get_buffer = get_buffer; \
+ permstate.bits_left = bits_left
+
+/*
+ * These macros provide the in-line portion of bit fetching.
+ * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer
+ * before using GET_BITS, PEEK_BITS, or DROP_BITS.
+ * The variables get_buffer and bits_left are assumed to be locals,
+ * but the state struct might not be (jpeg_huff_decode needs this).
+ * CHECK_BIT_BUFFER(state,n,action);
+ * Ensure there are N bits in get_buffer; if suspend, take action.
+ * val = GET_BITS(n);
+ * Fetch next N bits.
+ * val = PEEK_BITS(n);
+ * Fetch next N bits without removing them from the buffer.
+ * DROP_BITS(n);
+ * Discard next N bits.
+ * The value N should be a simple variable, not an expression, because it
+ * is evaluated multiple times.
+ */
+
+#define CHECK_BIT_BUFFER(state,nbits,action) \
+ { if (bits_left < (nbits)) { \
+ if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \
+ { action; } \
+ get_buffer = (state).get_buffer; bits_left = (state).bits_left; } }
+
+#define GET_BITS(nbits) \
+ (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1))
+
+#define PEEK_BITS(nbits) \
+ (((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1))
+
+#define DROP_BITS(nbits) \
+ (bits_left -= (nbits))
+
+/* Load up the bit buffer to a depth of at least nbits */
+EXTERN(boolean) jpeg_fill_bit_buffer
+ JPP((bitread_working_state * state, register bit_buf_type get_buffer,
+ register int bits_left, int nbits));
+
+
+/*
+ * Code for extracting next Huffman-coded symbol from input bit stream.
+ * Again, this is time-critical and we make the main paths be macros.
+ *
+ * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
+ * without looping. Usually, more than 95% of the Huffman codes will be 8
+ * or fewer bits long. The few overlength codes are handled with a loop,
+ * which need not be inline code.
+ *
+ * Notes about the HUFF_DECODE macro:
+ * 1. Near the end of the data segment, we may fail to get enough bits
+ * for a lookahead. In that case, we do it the hard way.
+ * 2. If the lookahead table contains no entry, the next code must be
+ * more than HUFF_LOOKAHEAD bits long.
+ * 3. jpeg_huff_decode returns -1 if forced to suspend.
+ */
+
+#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \
+{ register int nb, look; \
+ if (bits_left < HUFF_LOOKAHEAD) { \
+ if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \
+ get_buffer = state.get_buffer; bits_left = state.bits_left; \
+ if (bits_left < HUFF_LOOKAHEAD) { \
+ nb = 1; goto slowlabel; \
+ } \
+ } \
+ look = PEEK_BITS(HUFF_LOOKAHEAD); \
+ if ((nb = (htbl->lookup[look] >> HUFF_LOOKAHEAD)) <= HUFF_LOOKAHEAD) { \
+ DROP_BITS(nb); \
+ result = htbl->lookup[look] & ((1 << HUFF_LOOKAHEAD) - 1); \
+ } else { \
+slowlabel: \
+ if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
+ { failaction; } \
+ get_buffer = state.get_buffer; bits_left = state.bits_left; \
+ } \
+}
+
+#define HUFF_DECODE_FAST(s,nb,htbl) \
+ FILL_BIT_BUFFER_FAST; \
+ s = PEEK_BITS(HUFF_LOOKAHEAD); \
+ s = htbl->lookup[s]; \
+ nb = s >> HUFF_LOOKAHEAD; \
+ /* Pre-execute the common case of nb <= HUFF_LOOKAHEAD */ \
+ DROP_BITS(nb); \
+ s = s & ((1 << HUFF_LOOKAHEAD) - 1); \
+ if (nb > HUFF_LOOKAHEAD) { \
+ /* Equivalent of jpeg_huff_decode() */ \
+ /* Don't use GET_BITS() here because we don't want to modify bits_left */ \
+ s = (get_buffer >> bits_left) & ((1 << (nb)) - 1); \
+ while (s > htbl->maxcode[nb]) { \
+ s <<= 1; \
+ s |= GET_BITS(1); \
+ nb++; \
+ } \
+ s = htbl->pub->huffval[ (int) (s + htbl->valoffset[nb]) & 0xFF ]; \
+ }
+
+/* Out-of-line case for Huffman code fetching */
+EXTERN(int) jpeg_huff_decode
+ JPP((bitread_working_state * state, register bit_buf_type get_buffer,
+ register int bits_left, d_derived_tbl * htbl, int min_bits));
diff --git a/src/libjpeg-turbo/jdinput.c b/src/libjpeg-turbo/jdinput.c
new file mode 100644
index 0000000..9fcd089
--- /dev/null
+++ b/src/libjpeg-turbo/jdinput.c
@@ -0,0 +1,471 @@
+/*
+ * jdinput.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Modified 2002-2009 by Guido Vollbeding.
+ * Copyright (C) 2010, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains input control logic for the JPEG decompressor.
+ * These routines are concerned with controlling the decompressor's input
+ * processing (marker reading and coefficient decoding). The actual input
+ * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jpegcomp.h"
+
+
+/* Private state */
+
+typedef struct {
+ struct jpeg_input_controller pub; /* public fields */
+
+ boolean inheaders; /* TRUE until first SOS is reached */
+} my_input_controller;
+
+typedef my_input_controller * my_inputctl_ptr;
+
+
+/* Forward declarations */
+METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
+
+
+/*
+ * Routines to calculate various quantities related to the size of the image.
+ */
+
+
+#if JPEG_LIB_VERSION >= 80
+/*
+ * Compute output image dimensions and related values.
+ * NOTE: this is exported for possible use by application.
+ * Hence it mustn't do anything that can't be done twice.
+ */
+
+GLOBAL(void)
+jpeg_core_output_dimensions (j_decompress_ptr cinfo)
+/* Do computations that are needed before master selection phase.
+ * This function is used for transcoding and full decompression.
+ */
+{
+#ifdef IDCT_SCALING_SUPPORTED
+ int ci;
+ jpeg_component_info *compptr;
+
+ /* Compute actual output image dimensions and DCT scaling choices. */
+ if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom) {
+ /* Provide 1/block_size scaling */
+ cinfo->output_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width, (long) cinfo->block_size);
+ cinfo->output_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height, (long) cinfo->block_size);
+ cinfo->min_DCT_h_scaled_size = 1;
+ cinfo->min_DCT_v_scaled_size = 1;
+ } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 2) {
+ /* Provide 2/block_size scaling */
+ cinfo->output_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * 2L, (long) cinfo->block_size);
+ cinfo->output_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * 2L, (long) cinfo->block_size);
+ cinfo->min_DCT_h_scaled_size = 2;
+ cinfo->min_DCT_v_scaled_size = 2;
+ } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 4) {
+ /* Provide 4/block_size scaling */
+ cinfo->output_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * 4L, (long) cinfo->block_size);
+ cinfo->output_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * 4L, (long) cinfo->block_size);
+ cinfo->min_DCT_h_scaled_size = 4;
+ cinfo->min_DCT_v_scaled_size = 4;
+ } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 8) {
+ /* Provide 8/block_size scaling */
+ cinfo->output_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * 8L, (long) cinfo->block_size);
+ cinfo->output_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * 8L, (long) cinfo->block_size);
+ cinfo->min_DCT_h_scaled_size = 8;
+ cinfo->min_DCT_v_scaled_size = 8;
+ }
+ /* Recompute dimensions of components */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size;
+ compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size;
+ }
+
+#else /* !IDCT_SCALING_SUPPORTED */
+
+ /* Hardwire it to "no scaling" */
+ cinfo->output_width = cinfo->image_width;
+ cinfo->output_height = cinfo->image_height;
+ /* jdinput.c has already initialized DCT_scaled_size,
+ * and has computed unscaled downsampled_width and downsampled_height.
+ */
+
+#endif /* IDCT_SCALING_SUPPORTED */
+}
+#endif
+
+
+LOCAL(void)
+initial_setup (j_decompress_ptr cinfo)
+/* Called once, when first SOS marker is reached */
+{
+ int ci;
+ jpeg_component_info *compptr;
+
+ /* Make sure image isn't bigger than I can handle */
+ if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
+ (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
+ ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
+
+ /* For now, precision must match compiled-in value... */
+ if (cinfo->data_precision != BITS_IN_JSAMPLE)
+ ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
+
+ /* Check that number of components won't exceed internal array sizes */
+ if (cinfo->num_components > MAX_COMPONENTS)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+ MAX_COMPONENTS);
+
+ /* Compute maximum sampling factors; check factor validity */
+ cinfo->max_h_samp_factor = 1;
+ cinfo->max_v_samp_factor = 1;
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
+ compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
+ ERREXIT(cinfo, JERR_BAD_SAMPLING);
+ cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
+ compptr->h_samp_factor);
+ cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
+ compptr->v_samp_factor);
+ }
+
+#if JPEG_LIB_VERSION >=80
+ cinfo->block_size = DCTSIZE;
+ cinfo->natural_order = jpeg_natural_order;
+ cinfo->lim_Se = DCTSIZE2-1;
+#endif
+
+ /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
+ * In the full decompressor, this will be overridden by jdmaster.c;
+ * but in the transcoder, jdmaster.c is not used, so we must do it here.
+ */
+#if JPEG_LIB_VERSION >= 70
+ cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = DCTSIZE;
+#else
+ cinfo->min_DCT_scaled_size = DCTSIZE;
+#endif
+
+ /* Compute dimensions of components */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+#if JPEG_LIB_VERSION >= 70
+ compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = DCTSIZE;
+#else
+ compptr->DCT_scaled_size = DCTSIZE;
+#endif
+ /* Size in DCT blocks */
+ compptr->width_in_blocks = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
+ (long) (cinfo->max_h_samp_factor * DCTSIZE));
+ compptr->height_in_blocks = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
+ (long) (cinfo->max_v_samp_factor * DCTSIZE));
+ /* downsampled_width and downsampled_height will also be overridden by
+ * jdmaster.c if we are doing full decompression. The transcoder library
+ * doesn't use these values, but the calling application might.
+ */
+ /* Size in samples */
+ compptr->downsampled_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
+ (long) cinfo->max_h_samp_factor);
+ compptr->downsampled_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
+ (long) cinfo->max_v_samp_factor);
+ /* Mark component needed, until color conversion says otherwise */
+ compptr->component_needed = TRUE;
+ /* Mark no quantization table yet saved for component */
+ compptr->quant_table = NULL;
+ }
+
+ /* Compute number of fully interleaved MCU rows. */
+ cinfo->total_iMCU_rows = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height,
+ (long) (cinfo->max_v_samp_factor*DCTSIZE));
+
+ /* Decide whether file contains multiple scans */
+ if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
+ cinfo->inputctl->has_multiple_scans = TRUE;
+ else
+ cinfo->inputctl->has_multiple_scans = FALSE;
+}
+
+
+LOCAL(void)
+per_scan_setup (j_decompress_ptr cinfo)
+/* Do computations that are needed before processing a JPEG scan */
+/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
+{
+ int ci, mcublks, tmp;
+ jpeg_component_info *compptr;
+
+ if (cinfo->comps_in_scan == 1) {
+
+ /* Noninterleaved (single-component) scan */
+ compptr = cinfo->cur_comp_info[0];
+
+ /* Overall image size in MCUs */
+ cinfo->MCUs_per_row = compptr->width_in_blocks;
+ cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
+
+ /* For noninterleaved scan, always one block per MCU */
+ compptr->MCU_width = 1;
+ compptr->MCU_height = 1;
+ compptr->MCU_blocks = 1;
+ compptr->MCU_sample_width = compptr->_DCT_scaled_size;
+ compptr->last_col_width = 1;
+ /* For noninterleaved scans, it is convenient to define last_row_height
+ * as the number of block rows present in the last iMCU row.
+ */
+ tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+ if (tmp == 0) tmp = compptr->v_samp_factor;
+ compptr->last_row_height = tmp;
+
+ /* Prepare array describing MCU composition */
+ cinfo->blocks_in_MCU = 1;
+ cinfo->MCU_membership[0] = 0;
+
+ } else {
+
+ /* Interleaved (multi-component) scan */
+ if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
+ MAX_COMPS_IN_SCAN);
+
+ /* Overall image size in MCUs */
+ cinfo->MCUs_per_row = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width,
+ (long) (cinfo->max_h_samp_factor*DCTSIZE));
+ cinfo->MCU_rows_in_scan = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height,
+ (long) (cinfo->max_v_samp_factor*DCTSIZE));
+
+ cinfo->blocks_in_MCU = 0;
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* Sampling factors give # of blocks of component in each MCU */
+ compptr->MCU_width = compptr->h_samp_factor;
+ compptr->MCU_height = compptr->v_samp_factor;
+ compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
+ compptr->MCU_sample_width = compptr->MCU_width * compptr->_DCT_scaled_size;
+ /* Figure number of non-dummy blocks in last MCU column & row */
+ tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
+ if (tmp == 0) tmp = compptr->MCU_width;
+ compptr->last_col_width = tmp;
+ tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
+ if (tmp == 0) tmp = compptr->MCU_height;
+ compptr->last_row_height = tmp;
+ /* Prepare array describing MCU composition */
+ mcublks = compptr->MCU_blocks;
+ if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
+ ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
+ while (mcublks-- > 0) {
+ cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
+ }
+ }
+
+ }
+}
+
+
+/*
+ * Save away a copy of the Q-table referenced by each component present
+ * in the current scan, unless already saved during a prior scan.
+ *
+ * In a multiple-scan JPEG file, the encoder could assign different components
+ * the same Q-table slot number, but change table definitions between scans
+ * so that each component uses a different Q-table. (The IJG encoder is not
+ * currently capable of doing this, but other encoders might.) Since we want
+ * to be able to dequantize all the components at the end of the file, this
+ * means that we have to save away the table actually used for each component.
+ * We do this by copying the table at the start of the first scan containing
+ * the component.
+ * The JPEG spec prohibits the encoder from changing the contents of a Q-table
+ * slot between scans of a component using that slot. If the encoder does so
+ * anyway, this decoder will simply use the Q-table values that were current
+ * at the start of the first scan for the component.
+ *
+ * The decompressor output side looks only at the saved quant tables,
+ * not at the current Q-table slots.
+ */
+
+LOCAL(void)
+latch_quant_tables (j_decompress_ptr cinfo)
+{
+ int ci, qtblno;
+ jpeg_component_info *compptr;
+ JQUANT_TBL * qtbl;
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* No work if we already saved Q-table for this component */
+ if (compptr->quant_table != NULL)
+ continue;
+ /* Make sure specified quantization table is present */
+ qtblno = compptr->quant_tbl_no;
+ if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
+ cinfo->quant_tbl_ptrs[qtblno] == NULL)
+ ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
+ /* OK, save away the quantization table */
+ qtbl = (JQUANT_TBL *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(JQUANT_TBL));
+ MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
+ compptr->quant_table = qtbl;
+ }
+}
+
+
+/*
+ * Initialize the input modules to read a scan of compressed data.
+ * The first call to this is done by jdmaster.c after initializing
+ * the entire decompressor (during jpeg_start_decompress).
+ * Subsequent calls come from consume_markers, below.
+ */
+
+METHODDEF(void)
+start_input_pass (j_decompress_ptr cinfo)
+{
+ per_scan_setup(cinfo);
+ latch_quant_tables(cinfo);
+ (*cinfo->entropy->start_pass) (cinfo);
+ (*cinfo->coef->start_input_pass) (cinfo);
+ cinfo->inputctl->consume_input = cinfo->coef->consume_data;
+}
+
+
+/*
+ * Finish up after inputting a compressed-data scan.
+ * This is called by the coefficient controller after it's read all
+ * the expected data of the scan.
+ */
+
+METHODDEF(void)
+finish_input_pass (j_decompress_ptr cinfo)
+{
+ cinfo->inputctl->consume_input = consume_markers;
+}
+
+
+/*
+ * Read JPEG markers before, between, or after compressed-data scans.
+ * Change state as necessary when a new scan is reached.
+ * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
+ *
+ * The consume_input method pointer points either here or to the
+ * coefficient controller's consume_data routine, depending on whether
+ * we are reading a compressed data segment or inter-segment markers.
+ */
+
+METHODDEF(int)
+consume_markers (j_decompress_ptr cinfo)
+{
+ my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
+ int val;
+
+ if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
+ return JPEG_REACHED_EOI;
+
+ val = (*cinfo->marker->read_markers) (cinfo);
+
+ switch (val) {
+ case JPEG_REACHED_SOS: /* Found SOS */
+ if (inputctl->inheaders) { /* 1st SOS */
+ initial_setup(cinfo);
+ inputctl->inheaders = FALSE;
+ /* Note: start_input_pass must be called by jdmaster.c
+ * before any more input can be consumed. jdapimin.c is
+ * responsible for enforcing this sequencing.
+ */
+ } else { /* 2nd or later SOS marker */
+ if (! inputctl->pub.has_multiple_scans)
+ ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
+ start_input_pass(cinfo);
+ }
+ break;
+ case JPEG_REACHED_EOI: /* Found EOI */
+ inputctl->pub.eoi_reached = TRUE;
+ if (inputctl->inheaders) { /* Tables-only datastream, apparently */
+ if (cinfo->marker->saw_SOF)
+ ERREXIT(cinfo, JERR_SOF_NO_SOS);
+ } else {
+ /* Prevent infinite loop in coef ctlr's decompress_data routine
+ * if user set output_scan_number larger than number of scans.
+ */
+ if (cinfo->output_scan_number > cinfo->input_scan_number)
+ cinfo->output_scan_number = cinfo->input_scan_number;
+ }
+ break;
+ case JPEG_SUSPENDED:
+ break;
+ }
+
+ return val;
+}
+
+
+/*
+ * Reset state to begin a fresh datastream.
+ */
+
+METHODDEF(void)
+reset_input_controller (j_decompress_ptr cinfo)
+{
+ my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
+
+ inputctl->pub.consume_input = consume_markers;
+ inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
+ inputctl->pub.eoi_reached = FALSE;
+ inputctl->inheaders = TRUE;
+ /* Reset other modules */
+ (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+ (*cinfo->marker->reset_marker_reader) (cinfo);
+ /* Reset progression state -- would be cleaner if entropy decoder did this */
+ cinfo->coef_bits = NULL;
+}
+
+
+/*
+ * Initialize the input controller module.
+ * This is called only once, when the decompression object is created.
+ */
+
+GLOBAL(void)
+jinit_input_controller (j_decompress_ptr cinfo)
+{
+ my_inputctl_ptr inputctl;
+
+ /* Create subobject in permanent pool */
+ inputctl = (my_inputctl_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ SIZEOF(my_input_controller));
+ cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
+ /* Initialize method pointers */
+ inputctl->pub.consume_input = consume_markers;
+ inputctl->pub.reset_input_controller = reset_input_controller;
+ inputctl->pub.start_input_pass = start_input_pass;
+ inputctl->pub.finish_input_pass = finish_input_pass;
+ /* Initialize state: can't use reset_input_controller since we don't
+ * want to try to reset other modules yet.
+ */
+ inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
+ inputctl->pub.eoi_reached = FALSE;
+ inputctl->inheaders = TRUE;
+}
diff --git a/src/libjpeg-turbo/jdmainct.c b/src/libjpeg-turbo/jdmainct.c
new file mode 100644
index 0000000..eb32cae
--- /dev/null
+++ b/src/libjpeg-turbo/jdmainct.c
@@ -0,0 +1,514 @@
+/*
+ * jdmainct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 2010, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the main buffer controller for decompression.
+ * The main buffer lies between the JPEG decompressor proper and the
+ * post-processor; it holds downsampled data in the JPEG colorspace.
+ *
+ * Note that this code is bypassed in raw-data mode, since the application
+ * supplies the equivalent of the main buffer in that case.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jpegcomp.h"
+
+
+/*
+ * In the current system design, the main buffer need never be a full-image
+ * buffer; any full-height buffers will be found inside the coefficient or
+ * postprocessing controllers. Nonetheless, the main controller is not
+ * trivial. Its responsibility is to provide context rows for upsampling/
+ * rescaling, and doing this in an efficient fashion is a bit tricky.
+ *
+ * Postprocessor input data is counted in "row groups". A row group
+ * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
+ * sample rows of each component. (We require DCT_scaled_size values to be
+ * chosen such that these numbers are integers. In practice DCT_scaled_size
+ * values will likely be powers of two, so we actually have the stronger
+ * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
+ * Upsampling will typically produce max_v_samp_factor pixel rows from each
+ * row group (times any additional scale factor that the upsampler is
+ * applying).
+ *
+ * The coefficient controller will deliver data to us one iMCU row at a time;
+ * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or
+ * exactly min_DCT_scaled_size row groups. (This amount of data corresponds
+ * to one row of MCUs when the image is fully interleaved.) Note that the
+ * number of sample rows varies across components, but the number of row
+ * groups does not. Some garbage sample rows may be included in the last iMCU
+ * row at the bottom of the image.
+ *
+ * Depending on the vertical scaling algorithm used, the upsampler may need
+ * access to the sample row(s) above and below its current input row group.
+ * The upsampler is required to set need_context_rows TRUE at global selection
+ * time if so. When need_context_rows is FALSE, this controller can simply
+ * obtain one iMCU row at a time from the coefficient controller and dole it
+ * out as row groups to the postprocessor.
+ *
+ * When need_context_rows is TRUE, this controller guarantees that the buffer
+ * passed to postprocessing contains at least one row group's worth of samples
+ * above and below the row group(s) being processed. Note that the context
+ * rows "above" the first passed row group appear at negative row offsets in
+ * the passed buffer. At the top and bottom of the image, the required
+ * context rows are manufactured by duplicating the first or last real sample
+ * row; this avoids having special cases in the upsampling inner loops.
+ *
+ * The amount of context is fixed at one row group just because that's a
+ * convenient number for this controller to work with. The existing
+ * upsamplers really only need one sample row of context. An upsampler
+ * supporting arbitrary output rescaling might wish for more than one row
+ * group of context when shrinking the image; tough, we don't handle that.
+ * (This is justified by the assumption that downsizing will be handled mostly
+ * by adjusting the DCT_scaled_size values, so that the actual scale factor at
+ * the upsample step needn't be much less than one.)
+ *
+ * To provide the desired context, we have to retain the last two row groups
+ * of one iMCU row while reading in the next iMCU row. (The last row group
+ * can't be processed until we have another row group for its below-context,
+ * and so we have to save the next-to-last group too for its above-context.)
+ * We could do this most simply by copying data around in our buffer, but
+ * that'd be very slow. We can avoid copying any data by creating a rather
+ * strange pointer structure. Here's how it works. We allocate a workspace
+ * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number
+ * of row groups per iMCU row). We create two sets of redundant pointers to
+ * the workspace. Labeling the physical row groups 0 to M+1, the synthesized
+ * pointer lists look like this:
+ * M+1 M-1
+ * master pointer --> 0 master pointer --> 0
+ * 1 1
+ * ... ...
+ * M-3 M-3
+ * M-2 M
+ * M-1 M+1
+ * M M-2
+ * M+1 M-1
+ * 0 0
+ * We read alternate iMCU rows using each master pointer; thus the last two
+ * row groups of the previous iMCU row remain un-overwritten in the workspace.
+ * The pointer lists are set up so that the required context rows appear to
+ * be adjacent to the proper places when we pass the pointer lists to the
+ * upsampler.
+ *
+ * The above pictures describe the normal state of the pointer lists.
+ * At top and bottom of the image, we diddle the pointer lists to duplicate
+ * the first or last sample row as necessary (this is cheaper than copying
+ * sample rows around).
+ *
+ * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that
+ * situation each iMCU row provides only one row group so the buffering logic
+ * must be different (eg, we must read two iMCU rows before we can emit the
+ * first row group). For now, we simply do not support providing context
+ * rows when min_DCT_scaled_size is 1. That combination seems unlikely to
+ * be worth providing --- if someone wants a 1/8th-size preview, they probably
+ * want it quick and dirty, so a context-free upsampler is sufficient.
+ */
+
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_d_main_controller pub; /* public fields */
+
+ /* Pointer to allocated workspace (M or M+2 row groups). */
+ JSAMPARRAY buffer[MAX_COMPONENTS];
+
+ boolean buffer_full; /* Have we gotten an iMCU row from decoder? */
+ JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */
+
+ /* Remaining fields are only used in the context case. */
+
+ /* These are the master pointers to the funny-order pointer lists. */
+ JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */
+
+ int whichptr; /* indicates which pointer set is now in use */
+ int context_state; /* process_data state machine status */
+ JDIMENSION rowgroups_avail; /* row groups available to postprocessor */
+ JDIMENSION iMCU_row_ctr; /* counts iMCU rows to detect image top/bot */
+} my_main_controller;
+
+typedef my_main_controller * my_main_ptr;
+
+/* context_state values: */
+#define CTX_PREPARE_FOR_IMCU 0 /* need to prepare for MCU row */
+#define CTX_PROCESS_IMCU 1 /* feeding iMCU to postprocessor */
+#define CTX_POSTPONED_ROW 2 /* feeding postponed row group */
+
+
+/* Forward declarations */
+METHODDEF(void) process_data_simple_main
+ JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
+ JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
+METHODDEF(void) process_data_context_main
+ JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
+ JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
+#ifdef QUANT_2PASS_SUPPORTED
+METHODDEF(void) process_data_crank_post
+ JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
+ JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
+#endif
+
+
+LOCAL(void)
+alloc_funny_pointers (j_decompress_ptr cinfo)
+/* Allocate space for the funny pointer lists.
+ * This is done only once, not once per pass.
+ */
+{
+ my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
+ int ci, rgroup;
+ int M = cinfo->_min_DCT_scaled_size;
+ jpeg_component_info *compptr;
+ JSAMPARRAY xbuf;
+
+ /* Get top-level space for component array pointers.
+ * We alloc both arrays with one call to save a few cycles.
+ */
+ main_ptr->xbuffer[0] = (JSAMPIMAGE)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));
+ main_ptr->xbuffer[1] = main_ptr->xbuffer[0] + cinfo->num_components;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
+ cinfo->_min_DCT_scaled_size; /* height of a row group of component */
+ /* Get space for pointer lists --- M+4 row groups in each list.
+ * We alloc both pointer lists with one call to save a few cycles.
+ */
+ xbuf = (JSAMPARRAY)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
+ xbuf += rgroup; /* want one row group at negative offsets */
+ main_ptr->xbuffer[0][ci] = xbuf;
+ xbuf += rgroup * (M + 4);
+ main_ptr->xbuffer[1][ci] = xbuf;
+ }
+}
+
+
+LOCAL(void)
+make_funny_pointers (j_decompress_ptr cinfo)
+/* Create the funny pointer lists discussed in the comments above.
+ * The actual workspace is already allocated (in main_ptr->buffer),
+ * and the space for the pointer lists is allocated too.
+ * This routine just fills in the curiously ordered lists.
+ * This will be repeated at the beginning of each pass.
+ */
+{
+ my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
+ int ci, i, rgroup;
+ int M = cinfo->_min_DCT_scaled_size;
+ jpeg_component_info *compptr;
+ JSAMPARRAY buf, xbuf0, xbuf1;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
+ cinfo->_min_DCT_scaled_size; /* height of a row group of component */
+ xbuf0 = main_ptr->xbuffer[0][ci];
+ xbuf1 = main_ptr->xbuffer[1][ci];
+ /* First copy the workspace pointers as-is */
+ buf = main_ptr->buffer[ci];
+ for (i = 0; i < rgroup * (M + 2); i++) {
+ xbuf0[i] = xbuf1[i] = buf[i];
+ }
+ /* In the second list, put the last four row groups in swapped order */
+ for (i = 0; i < rgroup * 2; i++) {
+ xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];
+ xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];
+ }
+ /* The wraparound pointers at top and bottom will be filled later
+ * (see set_wraparound_pointers, below). Initially we want the "above"
+ * pointers to duplicate the first actual data line. This only needs
+ * to happen in xbuffer[0].
+ */
+ for (i = 0; i < rgroup; i++) {
+ xbuf0[i - rgroup] = xbuf0[0];
+ }
+ }
+}
+
+
+LOCAL(void)
+set_wraparound_pointers (j_decompress_ptr cinfo)
+/* Set up the "wraparound" pointers at top and bottom of the pointer lists.
+ * This changes the pointer list state from top-of-image to the normal state.
+ */
+{
+ my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
+ int ci, i, rgroup;
+ int M = cinfo->_min_DCT_scaled_size;
+ jpeg_component_info *compptr;
+ JSAMPARRAY xbuf0, xbuf1;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
+ cinfo->_min_DCT_scaled_size; /* height of a row group of component */
+ xbuf0 = main_ptr->xbuffer[0][ci];
+ xbuf1 = main_ptr->xbuffer[1][ci];
+ for (i = 0; i < rgroup; i++) {
+ xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
+ xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
+ xbuf0[rgroup*(M+2) + i] = xbuf0[i];
+ xbuf1[rgroup*(M+2) + i] = xbuf1[i];
+ }
+ }
+}
+
+
+LOCAL(void)
+set_bottom_pointers (j_decompress_ptr cinfo)
+/* Change the pointer lists to duplicate the last sample row at the bottom
+ * of the image. whichptr indicates which xbuffer holds the final iMCU row.
+ * Also sets rowgroups_avail to indicate number of nondummy row groups in row.
+ */
+{
+ my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
+ int ci, i, rgroup, iMCUheight, rows_left;
+ jpeg_component_info *compptr;
+ JSAMPARRAY xbuf;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Count sample rows in one iMCU row and in one row group */
+ iMCUheight = compptr->v_samp_factor * compptr->_DCT_scaled_size;
+ rgroup = iMCUheight / cinfo->_min_DCT_scaled_size;
+ /* Count nondummy sample rows remaining for this component */
+ rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
+ if (rows_left == 0) rows_left = iMCUheight;
+ /* Count nondummy row groups. Should get same answer for each component,
+ * so we need only do it once.
+ */
+ if (ci == 0) {
+ main_ptr->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
+ }
+ /* Duplicate the last real sample row rgroup*2 times; this pads out the
+ * last partial rowgroup and ensures at least one full rowgroup of context.
+ */
+ xbuf = main_ptr->xbuffer[main_ptr->whichptr][ci];
+ for (i = 0; i < rgroup * 2; i++) {
+ xbuf[rows_left + i] = xbuf[rows_left-1];
+ }
+ }
+}
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
+
+ switch (pass_mode) {
+ case JBUF_PASS_THRU:
+ if (cinfo->upsample->need_context_rows) {
+ main_ptr->pub.process_data = process_data_context_main;
+ make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
+ main_ptr->whichptr = 0; /* Read first iMCU row into xbuffer[0] */
+ main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
+ main_ptr->iMCU_row_ctr = 0;
+ } else {
+ /* Simple case with no context needed */
+ main_ptr->pub.process_data = process_data_simple_main;
+ }
+ main_ptr->buffer_full = FALSE; /* Mark buffer empty */
+ main_ptr->rowgroup_ctr = 0;
+ break;
+#ifdef QUANT_2PASS_SUPPORTED
+ case JBUF_CRANK_DEST:
+ /* For last pass of 2-pass quantization, just crank the postprocessor */
+ main_ptr->pub.process_data = process_data_crank_post;
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ break;
+ }
+}
+
+
+/*
+ * Process some data.
+ * This handles the simple case where no context is required.
+ */
+
+METHODDEF(void)
+process_data_simple_main (j_decompress_ptr cinfo,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
+ JDIMENSION rowgroups_avail;
+
+ /* Read input data if we haven't filled the main buffer yet */
+ if (! main_ptr->buffer_full) {
+ if (! (*cinfo->coef->decompress_data) (cinfo, main_ptr->buffer))
+ return; /* suspension forced, can do nothing more */
+ main_ptr->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
+ }
+
+ /* There are always min_DCT_scaled_size row groups in an iMCU row. */
+ rowgroups_avail = (JDIMENSION) cinfo->_min_DCT_scaled_size;
+ /* Note: at the bottom of the image, we may pass extra garbage row groups
+ * to the postprocessor. The postprocessor has to check for bottom
+ * of image anyway (at row resolution), so no point in us doing it too.
+ */
+
+ /* Feed the postprocessor */
+ (*cinfo->post->post_process_data) (cinfo, main_ptr->buffer,
+ &main_ptr->rowgroup_ctr, rowgroups_avail,
+ output_buf, out_row_ctr, out_rows_avail);
+
+ /* Has postprocessor consumed all the data yet? If so, mark buffer empty */
+ if (main_ptr->rowgroup_ctr >= rowgroups_avail) {
+ main_ptr->buffer_full = FALSE;
+ main_ptr->rowgroup_ctr = 0;
+ }
+}
+
+
+/*
+ * Process some data.
+ * This handles the case where context rows must be provided.
+ */
+
+METHODDEF(void)
+process_data_context_main (j_decompress_ptr cinfo,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
+
+ /* Read input data if we haven't filled the main buffer yet */
+ if (! main_ptr->buffer_full) {
+ if (! (*cinfo->coef->decompress_data) (cinfo,
+ main_ptr->xbuffer[main_ptr->whichptr]))
+ return; /* suspension forced, can do nothing more */
+ main_ptr->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
+ main_ptr->iMCU_row_ctr++; /* count rows received */
+ }
+
+ /* Postprocessor typically will not swallow all the input data it is handed
+ * in one call (due to filling the output buffer first). Must be prepared
+ * to exit and restart. This switch lets us keep track of how far we got.
+ * Note that each case falls through to the next on successful completion.
+ */
+ switch (main_ptr->context_state) {
+ case CTX_POSTPONED_ROW:
+ /* Call postprocessor using previously set pointers for postponed row */
+ (*cinfo->post->post_process_data) (cinfo, main_ptr->xbuffer[main_ptr->whichptr],
+ &main_ptr->rowgroup_ctr, main_ptr->rowgroups_avail,
+ output_buf, out_row_ctr, out_rows_avail);
+ if (main_ptr->rowgroup_ctr < main_ptr->rowgroups_avail)
+ return; /* Need to suspend */
+ main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
+ if (*out_row_ctr >= out_rows_avail)
+ return; /* Postprocessor exactly filled output buf */
+ /*FALLTHROUGH*/
+ case CTX_PREPARE_FOR_IMCU:
+ /* Prepare to process first M-1 row groups of this iMCU row */
+ main_ptr->rowgroup_ctr = 0;
+ main_ptr->rowgroups_avail = (JDIMENSION) (cinfo->_min_DCT_scaled_size - 1);
+ /* Check for bottom of image: if so, tweak pointers to "duplicate"
+ * the last sample row, and adjust rowgroups_avail to ignore padding rows.
+ */
+ if (main_ptr->iMCU_row_ctr == cinfo->total_iMCU_rows)
+ set_bottom_pointers(cinfo);
+ main_ptr->context_state = CTX_PROCESS_IMCU;
+ /*FALLTHROUGH*/
+ case CTX_PROCESS_IMCU:
+ /* Call postprocessor using previously set pointers */
+ (*cinfo->post->post_process_data) (cinfo, main_ptr->xbuffer[main_ptr->whichptr],
+ &main_ptr->rowgroup_ctr, main_ptr->rowgroups_avail,
+ output_buf, out_row_ctr, out_rows_avail);
+ if (main_ptr->rowgroup_ctr < main_ptr->rowgroups_avail)
+ return; /* Need to suspend */
+ /* After the first iMCU, change wraparound pointers to normal state */
+ if (main_ptr->iMCU_row_ctr == 1)
+ set_wraparound_pointers(cinfo);
+ /* Prepare to load new iMCU row using other xbuffer list */
+ main_ptr->whichptr ^= 1; /* 0=>1 or 1=>0 */
+ main_ptr->buffer_full = FALSE;
+ /* Still need to process last row group of this iMCU row, */
+ /* which is saved at index M+1 of the other xbuffer */
+ main_ptr->rowgroup_ctr = (JDIMENSION) (cinfo->_min_DCT_scaled_size + 1);
+ main_ptr->rowgroups_avail = (JDIMENSION) (cinfo->_min_DCT_scaled_size + 2);
+ main_ptr->context_state = CTX_POSTPONED_ROW;
+ }
+}
+
+
+/*
+ * Process some data.
+ * Final pass of two-pass quantization: just call the postprocessor.
+ * Source data will be the postprocessor controller's internal buffer.
+ */
+
+#ifdef QUANT_2PASS_SUPPORTED
+
+METHODDEF(void)
+process_data_crank_post (j_decompress_ptr cinfo,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL,
+ (JDIMENSION *) NULL, (JDIMENSION) 0,
+ output_buf, out_row_ctr, out_rows_avail);
+}
+
+#endif /* QUANT_2PASS_SUPPORTED */
+
+
+/*
+ * Initialize main buffer controller.
+ */
+
+GLOBAL(void)
+jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
+{
+ my_main_ptr main_ptr;
+ int ci, rgroup, ngroups;
+ jpeg_component_info *compptr;
+
+ main_ptr = (my_main_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_main_controller));
+ cinfo->main = (struct jpeg_d_main_controller *) main_ptr;
+ main_ptr->pub.start_pass = start_pass_main;
+
+ if (need_full_buffer) /* shouldn't happen */
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+ /* Allocate the workspace.
+ * ngroups is the number of row groups we need.
+ */
+ if (cinfo->upsample->need_context_rows) {
+ if (cinfo->_min_DCT_scaled_size < 2) /* unsupported, see comments above */
+ ERREXIT(cinfo, JERR_NOTIMPL);
+ alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
+ ngroups = cinfo->_min_DCT_scaled_size + 2;
+ } else {
+ ngroups = cinfo->_min_DCT_scaled_size;
+ }
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
+ cinfo->_min_DCT_scaled_size; /* height of a row group of component */
+ main_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ compptr->width_in_blocks * compptr->_DCT_scaled_size,
+ (JDIMENSION) (rgroup * ngroups));
+ }
+}
diff --git a/src/libjpeg-turbo/jdmarker.c b/src/libjpeg-turbo/jdmarker.c
new file mode 100644
index 0000000..d8dcba9
--- /dev/null
+++ b/src/libjpeg-turbo/jdmarker.c
@@ -0,0 +1,1364 @@
+/*
+ * jdmarker.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * Copyright (C) 2012, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains routines to decode JPEG datastream markers.
+ * Most of the complexity arises from our desire to support input
+ * suspension: if not all of the data for a marker is available,
+ * we must exit back to the application. On resumption, we reprocess
+ * the marker.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+typedef enum { /* JPEG marker codes */
+ M_SOF0 = 0xc0,
+ M_SOF1 = 0xc1,
+ M_SOF2 = 0xc2,
+ M_SOF3 = 0xc3,
+
+ M_SOF5 = 0xc5,
+ M_SOF6 = 0xc6,
+ M_SOF7 = 0xc7,
+
+ M_JPG = 0xc8,
+ M_SOF9 = 0xc9,
+ M_SOF10 = 0xca,
+ M_SOF11 = 0xcb,
+
+ M_SOF13 = 0xcd,
+ M_SOF14 = 0xce,
+ M_SOF15 = 0xcf,
+
+ M_DHT = 0xc4,
+
+ M_DAC = 0xcc,
+
+ M_RST0 = 0xd0,
+ M_RST1 = 0xd1,
+ M_RST2 = 0xd2,
+ M_RST3 = 0xd3,
+ M_RST4 = 0xd4,
+ M_RST5 = 0xd5,
+ M_RST6 = 0xd6,
+ M_RST7 = 0xd7,
+
+ M_SOI = 0xd8,
+ M_EOI = 0xd9,
+ M_SOS = 0xda,
+ M_DQT = 0xdb,
+ M_DNL = 0xdc,
+ M_DRI = 0xdd,
+ M_DHP = 0xde,
+ M_EXP = 0xdf,
+
+ M_APP0 = 0xe0,
+ M_APP1 = 0xe1,
+ M_APP2 = 0xe2,
+ M_APP3 = 0xe3,
+ M_APP4 = 0xe4,
+ M_APP5 = 0xe5,
+ M_APP6 = 0xe6,
+ M_APP7 = 0xe7,
+ M_APP8 = 0xe8,
+ M_APP9 = 0xe9,
+ M_APP10 = 0xea,
+ M_APP11 = 0xeb,
+ M_APP12 = 0xec,
+ M_APP13 = 0xed,
+ M_APP14 = 0xee,
+ M_APP15 = 0xef,
+
+ M_JPG0 = 0xf0,
+ M_JPG13 = 0xfd,
+ M_COM = 0xfe,
+
+ M_TEM = 0x01,
+
+ M_ERROR = 0x100
+} JPEG_MARKER;
+
+
+/* Private state */
+
+typedef struct {
+ struct jpeg_marker_reader pub; /* public fields */
+
+ /* Application-overridable marker processing methods */
+ jpeg_marker_parser_method process_COM;
+ jpeg_marker_parser_method process_APPn[16];
+
+ /* Limit on marker data length to save for each marker type */
+ unsigned int length_limit_COM;
+ unsigned int length_limit_APPn[16];
+
+ /* Status of COM/APPn marker saving */
+ jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */
+ unsigned int bytes_read; /* data bytes read so far in marker */
+ /* Note: cur_marker is not linked into marker_list until it's all read. */
+} my_marker_reader;
+
+typedef my_marker_reader * my_marker_ptr;
+
+
+/*
+ * Macros for fetching data from the data source module.
+ *
+ * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect
+ * the current restart point; we update them only when we have reached a
+ * suitable place to restart if a suspension occurs.
+ */
+
+/* Declare and initialize local copies of input pointer/count */
+#define INPUT_VARS(cinfo) \
+ struct jpeg_source_mgr * datasrc = (cinfo)->src; \
+ const JOCTET * next_input_byte = datasrc->next_input_byte; \
+ size_t bytes_in_buffer = datasrc->bytes_in_buffer
+
+/* Unload the local copies --- do this only at a restart boundary */
+#define INPUT_SYNC(cinfo) \
+ ( datasrc->next_input_byte = next_input_byte, \
+ datasrc->bytes_in_buffer = bytes_in_buffer )
+
+/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */
+#define INPUT_RELOAD(cinfo) \
+ ( next_input_byte = datasrc->next_input_byte, \
+ bytes_in_buffer = datasrc->bytes_in_buffer )
+
+/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
+ * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
+ * but we must reload the local copies after a successful fill.
+ */
+#define MAKE_BYTE_AVAIL(cinfo,action) \
+ if (bytes_in_buffer == 0) { \
+ if (! (*datasrc->fill_input_buffer) (cinfo)) \
+ { action; } \
+ INPUT_RELOAD(cinfo); \
+ }
+
+/* Read a byte into variable V.
+ * If must suspend, take the specified action (typically "return FALSE").
+ */
+#define INPUT_BYTE(cinfo,V,action) \
+ MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
+ bytes_in_buffer--; \
+ V = GETJOCTET(*next_input_byte++); )
+
+/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
+ * V should be declared unsigned int or perhaps INT32.
+ */
+#define INPUT_2BYTES(cinfo,V,action) \
+ MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
+ bytes_in_buffer--; \
+ V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
+ MAKE_BYTE_AVAIL(cinfo,action); \
+ bytes_in_buffer--; \
+ V += GETJOCTET(*next_input_byte++); )
+
+
+/*
+ * Routines to process JPEG markers.
+ *
+ * Entry condition: JPEG marker itself has been read and its code saved
+ * in cinfo->unread_marker; input restart point is just after the marker.
+ *
+ * Exit: if return TRUE, have read and processed any parameters, and have
+ * updated the restart point to point after the parameters.
+ * If return FALSE, was forced to suspend before reaching end of
+ * marker parameters; restart point has not been moved. Same routine
+ * will be called again after application supplies more input data.
+ *
+ * This approach to suspension assumes that all of a marker's parameters
+ * can fit into a single input bufferload. This should hold for "normal"
+ * markers. Some COM/APPn markers might have large parameter segments
+ * that might not fit. If we are simply dropping such a marker, we use
+ * skip_input_data to get past it, and thereby put the problem on the
+ * source manager's shoulders. If we are saving the marker's contents
+ * into memory, we use a slightly different convention: when forced to
+ * suspend, the marker processor updates the restart point to the end of
+ * what it's consumed (ie, the end of the buffer) before returning FALSE.
+ * On resumption, cinfo->unread_marker still contains the marker code,
+ * but the data source will point to the next chunk of marker data.
+ * The marker processor must retain internal state to deal with this.
+ *
+ * Note that we don't bother to avoid duplicate trace messages if a
+ * suspension occurs within marker parameters. Other side effects
+ * require more care.
+ */
+
+
+LOCAL(boolean)
+get_soi (j_decompress_ptr cinfo)
+/* Process an SOI marker */
+{
+ int i;
+
+ TRACEMS(cinfo, 1, JTRC_SOI);
+
+ if (cinfo->marker->saw_SOI)
+ ERREXIT(cinfo, JERR_SOI_DUPLICATE);
+
+ /* Reset all parameters that are defined to be reset by SOI */
+
+ for (i = 0; i < NUM_ARITH_TBLS; i++) {
+ cinfo->arith_dc_L[i] = 0;
+ cinfo->arith_dc_U[i] = 1;
+ cinfo->arith_ac_K[i] = 5;
+ }
+ cinfo->restart_interval = 0;
+
+ /* Set initial assumptions for colorspace etc */
+
+ cinfo->jpeg_color_space = JCS_UNKNOWN;
+ cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
+
+ cinfo->saw_JFIF_marker = FALSE;
+ cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
+ cinfo->JFIF_minor_version = 1;
+ cinfo->density_unit = 0;
+ cinfo->X_density = 1;
+ cinfo->Y_density = 1;
+ cinfo->saw_Adobe_marker = FALSE;
+ cinfo->Adobe_transform = 0;
+
+ cinfo->marker->saw_SOI = TRUE;
+
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
+/* Process a SOFn marker */
+{
+ INT32 length;
+ int c, ci;
+ jpeg_component_info * compptr;
+ INPUT_VARS(cinfo);
+
+ cinfo->progressive_mode = is_prog;
+ cinfo->arith_code = is_arith;
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+
+ INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
+ INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
+ INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
+ INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
+
+ length -= 8;
+
+ TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
+ (int) cinfo->image_width, (int) cinfo->image_height,
+ cinfo->num_components);
+
+ if (cinfo->marker->saw_SOF)
+ ERREXIT(cinfo, JERR_SOF_DUPLICATE);
+
+ /* We don't support files in which the image height is initially specified */
+ /* as 0 and is later redefined by DNL. As long as we have to check that, */
+ /* might as well have a general sanity check. */
+ if (cinfo->image_height <= 0 || cinfo->image_width <= 0
+ || cinfo->num_components <= 0)
+ ERREXIT(cinfo, JERR_EMPTY_IMAGE);
+
+ if (length != (cinfo->num_components * 3))
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ if (cinfo->comp_info == NULL) /* do only once, even if suspend */
+ cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ cinfo->num_components * SIZEOF(jpeg_component_info));
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ compptr->component_index = ci;
+ INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
+ INPUT_BYTE(cinfo, c, return FALSE);
+ compptr->h_samp_factor = (c >> 4) & 15;
+ compptr->v_samp_factor = (c ) & 15;
+ INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
+
+ TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
+ compptr->component_id, compptr->h_samp_factor,
+ compptr->v_samp_factor, compptr->quant_tbl_no);
+ }
+
+ cinfo->marker->saw_SOF = TRUE;
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+get_sos (j_decompress_ptr cinfo)
+/* Process a SOS marker */
+{
+ INT32 length;
+ int i, ci, n, c, cc;
+ jpeg_component_info * compptr;
+ INPUT_VARS(cinfo);
+
+ if (! cinfo->marker->saw_SOF)
+ ERREXIT(cinfo, JERR_SOS_NO_SOF);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+
+ INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
+
+ TRACEMS1(cinfo, 1, JTRC_SOS, n);
+
+ if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ cinfo->comps_in_scan = n;
+
+ /* Collect the component-spec parameters */
+
+ for (i = 0; i < cinfo->num_components; i++)
+ cinfo->cur_comp_info[i] = NULL;
+
+ for (i = 0; i < n; i++) {
+ INPUT_BYTE(cinfo, cc, return FALSE);
+ INPUT_BYTE(cinfo, c, return FALSE);
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ if (cc == compptr->component_id && !cinfo->cur_comp_info[ci])
+ goto id_found;
+ }
+
+ ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
+
+ id_found:
+
+ cinfo->cur_comp_info[i] = compptr;
+ compptr->dc_tbl_no = (c >> 4) & 15;
+ compptr->ac_tbl_no = (c ) & 15;
+
+ TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
+ compptr->dc_tbl_no, compptr->ac_tbl_no);
+ }
+
+ /* Collect the additional scan parameters Ss, Se, Ah/Al. */
+ INPUT_BYTE(cinfo, c, return FALSE);
+ cinfo->Ss = c;
+ INPUT_BYTE(cinfo, c, return FALSE);
+ cinfo->Se = c;
+ INPUT_BYTE(cinfo, c, return FALSE);
+ cinfo->Ah = (c >> 4) & 15;
+ cinfo->Al = (c ) & 15;
+
+ TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
+ cinfo->Ah, cinfo->Al);
+
+ /* Prepare to scan data & restart markers */
+ cinfo->marker->next_restart_num = 0;
+
+ /* Count another SOS marker */
+ cinfo->input_scan_number++;
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+#ifdef D_ARITH_CODING_SUPPORTED
+
+LOCAL(boolean)
+get_dac (j_decompress_ptr cinfo)
+/* Process a DAC marker */
+{
+ INT32 length;
+ int index, val;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+
+ while (length > 0) {
+ INPUT_BYTE(cinfo, index, return FALSE);
+ INPUT_BYTE(cinfo, val, return FALSE);
+
+ length -= 2;
+
+ TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
+
+ if (index < 0 || index >= (2*NUM_ARITH_TBLS))
+ ERREXIT1(cinfo, JERR_DAC_INDEX, index);
+
+ if (index >= NUM_ARITH_TBLS) { /* define AC table */
+ cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
+ } else { /* define DC table */
+ cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
+ cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
+ if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
+ ERREXIT1(cinfo, JERR_DAC_VALUE, val);
+ }
+ }
+
+ if (length != 0)
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+#else /* ! D_ARITH_CODING_SUPPORTED */
+
+#define get_dac(cinfo) skip_variable(cinfo)
+
+#endif /* D_ARITH_CODING_SUPPORTED */
+
+
+LOCAL(boolean)
+get_dht (j_decompress_ptr cinfo)
+/* Process a DHT marker */
+{
+ INT32 length;
+ UINT8 bits[17];
+ UINT8 huffval[256];
+ int i, index, count;
+ JHUFF_TBL **htblptr;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+
+ while (length > 16) {
+ INPUT_BYTE(cinfo, index, return FALSE);
+
+ TRACEMS1(cinfo, 1, JTRC_DHT, index);
+
+ bits[0] = 0;
+ count = 0;
+ for (i = 1; i <= 16; i++) {
+ INPUT_BYTE(cinfo, bits[i], return FALSE);
+ count += bits[i];
+ }
+
+ length -= 1 + 16;
+
+ TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
+ bits[1], bits[2], bits[3], bits[4],
+ bits[5], bits[6], bits[7], bits[8]);
+ TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
+ bits[9], bits[10], bits[11], bits[12],
+ bits[13], bits[14], bits[15], bits[16]);
+
+ /* Here we just do minimal validation of the counts to avoid walking
+ * off the end of our table space. jdhuff.c will check more carefully.
+ */
+ if (count > 256 || ((INT32) count) > length)
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+
+ for (i = 0; i < count; i++)
+ INPUT_BYTE(cinfo, huffval[i], return FALSE);
+
+ length -= count;
+
+ if (index & 0x10) { /* AC table definition */
+ index -= 0x10;
+ htblptr = &cinfo->ac_huff_tbl_ptrs[index];
+ } else { /* DC table definition */
+ htblptr = &cinfo->dc_huff_tbl_ptrs[index];
+ }
+
+ if (index < 0 || index >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_DHT_INDEX, index);
+
+ if (*htblptr == NULL)
+ *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+
+ MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
+ MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
+ }
+
+ if (length != 0)
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+get_dqt (j_decompress_ptr cinfo)
+/* Process a DQT marker */
+{
+ INT32 length;
+ int n, i, prec;
+ unsigned int tmp;
+ JQUANT_TBL *quant_ptr;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+
+ while (length > 0) {
+ INPUT_BYTE(cinfo, n, return FALSE);
+ prec = n >> 4;
+ n &= 0x0F;
+
+ TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
+
+ if (n >= NUM_QUANT_TBLS)
+ ERREXIT1(cinfo, JERR_DQT_INDEX, n);
+
+ if (cinfo->quant_tbl_ptrs[n] == NULL)
+ cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
+ quant_ptr = cinfo->quant_tbl_ptrs[n];
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ if (prec)
+ INPUT_2BYTES(cinfo, tmp, return FALSE);
+ else
+ INPUT_BYTE(cinfo, tmp, return FALSE);
+ /* We convert the zigzag-order table to natural array order. */
+ quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;
+ }
+
+ if (cinfo->err->trace_level >= 2) {
+ for (i = 0; i < DCTSIZE2; i += 8) {
+ TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
+ quant_ptr->quantval[i], quant_ptr->quantval[i+1],
+ quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],
+ quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],
+ quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);
+ }
+ }
+
+ length -= DCTSIZE2+1;
+ if (prec) length -= DCTSIZE2;
+ }
+
+ if (length != 0)
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+get_dri (j_decompress_ptr cinfo)
+/* Process a DRI marker */
+{
+ INT32 length;
+ unsigned int tmp;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+
+ if (length != 4)
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ INPUT_2BYTES(cinfo, tmp, return FALSE);
+
+ TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
+
+ cinfo->restart_interval = tmp;
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+/*
+ * Routines for processing APPn and COM markers.
+ * These are either saved in memory or discarded, per application request.
+ * APP0 and APP14 are specially checked to see if they are
+ * JFIF and Adobe markers, respectively.
+ */
+
+#define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */
+#define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */
+#define APPN_DATA_LEN 14 /* Must be the largest of the above!! */
+
+
+LOCAL(void)
+examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
+ unsigned int datalen, INT32 remaining)
+/* Examine first few bytes from an APP0.
+ * Take appropriate action if it is a JFIF marker.
+ * datalen is # of bytes at data[], remaining is length of rest of marker data.
+ */
+{
+ INT32 totallen = (INT32) datalen + remaining;
+
+ if (datalen >= APP0_DATA_LEN &&
+ GETJOCTET(data[0]) == 0x4A &&
+ GETJOCTET(data[1]) == 0x46 &&
+ GETJOCTET(data[2]) == 0x49 &&
+ GETJOCTET(data[3]) == 0x46 &&
+ GETJOCTET(data[4]) == 0) {
+ /* Found JFIF APP0 marker: save info */
+ cinfo->saw_JFIF_marker = TRUE;
+ cinfo->JFIF_major_version = GETJOCTET(data[5]);
+ cinfo->JFIF_minor_version = GETJOCTET(data[6]);
+ cinfo->density_unit = GETJOCTET(data[7]);
+ cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
+ cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
+ /* Check version.
+ * Major version must be 1, anything else signals an incompatible change.
+ * (We used to treat this as an error, but now it's a nonfatal warning,
+ * because some bozo at Hijaak couldn't read the spec.)
+ * Minor version should be 0..2, but process anyway if newer.
+ */
+ if (cinfo->JFIF_major_version != 1)
+ WARNMS2(cinfo, JWRN_JFIF_MAJOR,
+ cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
+ /* Generate trace messages */
+ TRACEMS5(cinfo, 1, JTRC_JFIF,
+ cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
+ cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
+ /* Validate thumbnail dimensions and issue appropriate messages */
+ if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
+ TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
+ GETJOCTET(data[12]), GETJOCTET(data[13]));
+ totallen -= APP0_DATA_LEN;
+ if (totallen !=
+ ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))
+ TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
+ } else if (datalen >= 6 &&
+ GETJOCTET(data[0]) == 0x4A &&
+ GETJOCTET(data[1]) == 0x46 &&
+ GETJOCTET(data[2]) == 0x58 &&
+ GETJOCTET(data[3]) == 0x58 &&
+ GETJOCTET(data[4]) == 0) {
+ /* Found JFIF "JFXX" extension APP0 marker */
+ /* The library doesn't actually do anything with these,
+ * but we try to produce a helpful trace message.
+ */
+ switch (GETJOCTET(data[5])) {
+ case 0x10:
+ TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
+ break;
+ case 0x11:
+ TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
+ break;
+ case 0x13:
+ TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
+ break;
+ default:
+ TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
+ GETJOCTET(data[5]), (int) totallen);
+ break;
+ }
+ } else {
+ /* Start of APP0 does not match "JFIF" or "JFXX", or too short */
+ TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
+ }
+}
+
+
+LOCAL(void)
+examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,
+ unsigned int datalen, INT32 remaining)
+/* Examine first few bytes from an APP14.
+ * Take appropriate action if it is an Adobe marker.
+ * datalen is # of bytes at data[], remaining is length of rest of marker data.
+ */
+{
+ unsigned int version, flags0, flags1, transform;
+
+ if (datalen >= APP14_DATA_LEN &&
+ GETJOCTET(data[0]) == 0x41 &&
+ GETJOCTET(data[1]) == 0x64 &&
+ GETJOCTET(data[2]) == 0x6F &&
+ GETJOCTET(data[3]) == 0x62 &&
+ GETJOCTET(data[4]) == 0x65) {
+ /* Found Adobe APP14 marker */
+ version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
+ flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
+ flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
+ transform = GETJOCTET(data[11]);
+ TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
+ cinfo->saw_Adobe_marker = TRUE;
+ cinfo->Adobe_transform = (UINT8) transform;
+ } else {
+ /* Start of APP14 does not match "Adobe", or too short */
+ TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
+ }
+}
+
+
+METHODDEF(boolean)
+get_interesting_appn (j_decompress_ptr cinfo)
+/* Process an APP0 or APP14 marker without saving it */
+{
+ INT32 length;
+ JOCTET b[APPN_DATA_LEN];
+ unsigned int i, numtoread;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+
+ /* get the interesting part of the marker data */
+ if (length >= APPN_DATA_LEN)
+ numtoread = APPN_DATA_LEN;
+ else if (length > 0)
+ numtoread = (unsigned int) length;
+ else
+ numtoread = 0;
+ for (i = 0; i < numtoread; i++)
+ INPUT_BYTE(cinfo, b[i], return FALSE);
+ length -= numtoread;
+
+ /* process it */
+ switch (cinfo->unread_marker) {
+ case M_APP0:
+ examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);
+ break;
+ case M_APP14:
+ examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);
+ break;
+ default:
+ /* can't get here unless jpeg_save_markers chooses wrong processor */
+ ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
+ break;
+ }
+
+ /* skip any remaining data -- could be lots */
+ INPUT_SYNC(cinfo);
+ if (length > 0)
+ (*cinfo->src->skip_input_data) (cinfo, (long) length);
+
+ return TRUE;
+}
+
+
+#ifdef SAVE_MARKERS_SUPPORTED
+
+METHODDEF(boolean)
+save_marker (j_decompress_ptr cinfo)
+/* Save an APPn or COM marker into the marker list */
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+ jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
+ unsigned int bytes_read, data_length;
+ JOCTET FAR * data;
+ INT32 length = 0;
+ INPUT_VARS(cinfo);
+
+ if (cur_marker == NULL) {
+ /* begin reading a marker */
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+ if (length >= 0) { /* watch out for bogus length word */
+ /* figure out how much we want to save */
+ unsigned int limit;
+ if (cinfo->unread_marker == (int) M_COM)
+ limit = marker->length_limit_COM;
+ else
+ limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
+ if ((unsigned int) length < limit)
+ limit = (unsigned int) length;
+ /* allocate and initialize the marker item */
+ cur_marker = (jpeg_saved_marker_ptr)
+ (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(struct jpeg_marker_struct) + limit);
+ cur_marker->next = NULL;
+ cur_marker->marker = (UINT8) cinfo->unread_marker;
+ cur_marker->original_length = (unsigned int) length;
+ cur_marker->data_length = limit;
+ /* data area is just beyond the jpeg_marker_struct */
+ data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);
+ marker->cur_marker = cur_marker;
+ marker->bytes_read = 0;
+ bytes_read = 0;
+ data_length = limit;
+ } else {
+ /* deal with bogus length word */
+ bytes_read = data_length = 0;
+ data = NULL;
+ }
+ } else {
+ /* resume reading a marker */
+ bytes_read = marker->bytes_read;
+ data_length = cur_marker->data_length;
+ data = cur_marker->data + bytes_read;
+ }
+
+ while (bytes_read < data_length) {
+ INPUT_SYNC(cinfo); /* move the restart point to here */
+ marker->bytes_read = bytes_read;
+ /* If there's not at least one byte in buffer, suspend */
+ MAKE_BYTE_AVAIL(cinfo, return FALSE);
+ /* Copy bytes with reasonable rapidity */
+ while (bytes_read < data_length && bytes_in_buffer > 0) {
+ *data++ = *next_input_byte++;
+ bytes_in_buffer--;
+ bytes_read++;
+ }
+ }
+
+ /* Done reading what we want to read */
+ if (cur_marker != NULL) { /* will be NULL if bogus length word */
+ /* Add new marker to end of list */
+ if (cinfo->marker_list == NULL) {
+ cinfo->marker_list = cur_marker;
+ } else {
+ jpeg_saved_marker_ptr prev = cinfo->marker_list;
+ while (prev->next != NULL)
+ prev = prev->next;
+ prev->next = cur_marker;
+ }
+ /* Reset pointer & calc remaining data length */
+ data = cur_marker->data;
+ length = cur_marker->original_length - data_length;
+ }
+ /* Reset to initial state for next marker */
+ marker->cur_marker = NULL;
+
+ /* Process the marker if interesting; else just make a generic trace msg */
+ switch (cinfo->unread_marker) {
+ case M_APP0:
+ examine_app0(cinfo, data, data_length, length);
+ break;
+ case M_APP14:
+ examine_app14(cinfo, data, data_length, length);
+ break;
+ default:
+ TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
+ (int) (data_length + length));
+ break;
+ }
+
+ /* skip any remaining data -- could be lots */
+ INPUT_SYNC(cinfo); /* do before skip_input_data */
+ if (length > 0)
+ (*cinfo->src->skip_input_data) (cinfo, (long) length);
+
+ return TRUE;
+}
+
+#endif /* SAVE_MARKERS_SUPPORTED */
+
+
+METHODDEF(boolean)
+skip_variable (j_decompress_ptr cinfo)
+/* Skip over an unknown or uninteresting variable-length marker */
+{
+ INT32 length;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+
+ TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
+
+ INPUT_SYNC(cinfo); /* do before skip_input_data */
+ if (length > 0)
+ (*cinfo->src->skip_input_data) (cinfo, (long) length);
+
+ return TRUE;
+}
+
+
+/*
+ * Find the next JPEG marker, save it in cinfo->unread_marker.
+ * Returns FALSE if had to suspend before reaching a marker;
+ * in that case cinfo->unread_marker is unchanged.
+ *
+ * Note that the result might not be a valid marker code,
+ * but it will never be 0 or FF.
+ */
+
+LOCAL(boolean)
+next_marker (j_decompress_ptr cinfo)
+{
+ int c;
+ INPUT_VARS(cinfo);
+
+ for (;;) {
+ INPUT_BYTE(cinfo, c, return FALSE);
+ /* Skip any non-FF bytes.
+ * This may look a bit inefficient, but it will not occur in a valid file.
+ * We sync after each discarded byte so that a suspending data source
+ * can discard the byte from its buffer.
+ */
+ while (c != 0xFF) {
+ cinfo->marker->discarded_bytes++;
+ INPUT_SYNC(cinfo);
+ INPUT_BYTE(cinfo, c, return FALSE);
+ }
+ /* This loop swallows any duplicate FF bytes. Extra FFs are legal as
+ * pad bytes, so don't count them in discarded_bytes. We assume there
+ * will not be so many consecutive FF bytes as to overflow a suspending
+ * data source's input buffer.
+ */
+ do {
+ INPUT_BYTE(cinfo, c, return FALSE);
+ } while (c == 0xFF);
+ if (c != 0)
+ break; /* found a valid marker, exit loop */
+ /* Reach here if we found a stuffed-zero data sequence (FF/00).
+ * Discard it and loop back to try again.
+ */
+ cinfo->marker->discarded_bytes += 2;
+ INPUT_SYNC(cinfo);
+ }
+
+ if (cinfo->marker->discarded_bytes != 0) {
+ WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
+ cinfo->marker->discarded_bytes = 0;
+ }
+
+ cinfo->unread_marker = c;
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+first_marker (j_decompress_ptr cinfo)
+/* Like next_marker, but used to obtain the initial SOI marker. */
+/* For this marker, we do not allow preceding garbage or fill; otherwise,
+ * we might well scan an entire input file before realizing it ain't JPEG.
+ * If an application wants to process non-JFIF files, it must seek to the
+ * SOI before calling the JPEG library.
+ */
+{
+ int c, c2;
+ INPUT_VARS(cinfo);
+
+ INPUT_BYTE(cinfo, c, return FALSE);
+ INPUT_BYTE(cinfo, c2, return FALSE);
+ if (c != 0xFF || c2 != (int) M_SOI)
+ ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
+
+ cinfo->unread_marker = c2;
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+/*
+ * Read markers until SOS or EOI.
+ *
+ * Returns same codes as are defined for jpeg_consume_input:
+ * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
+ */
+
+METHODDEF(int)
+read_markers (j_decompress_ptr cinfo)
+{
+ /* Outer loop repeats once for each marker. */
+ for (;;) {
+ /* Collect the marker proper, unless we already did. */
+ /* NB: first_marker() enforces the requirement that SOI appear first. */
+ if (cinfo->unread_marker == 0) {
+ if (! cinfo->marker->saw_SOI) {
+ if (! first_marker(cinfo))
+ return JPEG_SUSPENDED;
+ } else {
+ if (! next_marker(cinfo))
+ return JPEG_SUSPENDED;
+ }
+ }
+ /* At this point cinfo->unread_marker contains the marker code and the
+ * input point is just past the marker proper, but before any parameters.
+ * A suspension will cause us to return with this state still true.
+ */
+ switch (cinfo->unread_marker) {
+ case M_SOI:
+ if (! get_soi(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_SOF0: /* Baseline */
+ case M_SOF1: /* Extended sequential, Huffman */
+ if (! get_sof(cinfo, FALSE, FALSE))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_SOF2: /* Progressive, Huffman */
+ if (! get_sof(cinfo, TRUE, FALSE))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_SOF9: /* Extended sequential, arithmetic */
+ if (! get_sof(cinfo, FALSE, TRUE))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_SOF10: /* Progressive, arithmetic */
+ if (! get_sof(cinfo, TRUE, TRUE))
+ return JPEG_SUSPENDED;
+ break;
+
+ /* Currently unsupported SOFn types */
+ case M_SOF3: /* Lossless, Huffman */
+ case M_SOF5: /* Differential sequential, Huffman */
+ case M_SOF6: /* Differential progressive, Huffman */
+ case M_SOF7: /* Differential lossless, Huffman */
+ case M_JPG: /* Reserved for JPEG extensions */
+ case M_SOF11: /* Lossless, arithmetic */
+ case M_SOF13: /* Differential sequential, arithmetic */
+ case M_SOF14: /* Differential progressive, arithmetic */
+ case M_SOF15: /* Differential lossless, arithmetic */
+ ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
+ break;
+
+ case M_SOS:
+ if (! get_sos(cinfo))
+ return JPEG_SUSPENDED;
+ cinfo->unread_marker = 0; /* processed the marker */
+ return JPEG_REACHED_SOS;
+
+ case M_EOI:
+ TRACEMS(cinfo, 1, JTRC_EOI);
+ cinfo->unread_marker = 0; /* processed the marker */
+ return JPEG_REACHED_EOI;
+
+ case M_DAC:
+ if (! get_dac(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_DHT:
+ if (! get_dht(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_DQT:
+ if (! get_dqt(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_DRI:
+ if (! get_dri(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_APP0:
+ case M_APP1:
+ case M_APP2:
+ case M_APP3:
+ case M_APP4:
+ case M_APP5:
+ case M_APP6:
+ case M_APP7:
+ case M_APP8:
+ case M_APP9:
+ case M_APP10:
+ case M_APP11:
+ case M_APP12:
+ case M_APP13:
+ case M_APP14:
+ case M_APP15:
+ if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[
+ cinfo->unread_marker - (int) M_APP0]) (cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_COM:
+ if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_RST0: /* these are all parameterless */
+ case M_RST1:
+ case M_RST2:
+ case M_RST3:
+ case M_RST4:
+ case M_RST5:
+ case M_RST6:
+ case M_RST7:
+ case M_TEM:
+ TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
+ break;
+
+ case M_DNL: /* Ignore DNL ... perhaps the wrong thing */
+ if (! skip_variable(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ default: /* must be DHP, EXP, JPGn, or RESn */
+ /* For now, we treat the reserved markers as fatal errors since they are
+ * likely to be used to signal incompatible JPEG Part 3 extensions.
+ * Once the JPEG 3 version-number marker is well defined, this code
+ * ought to change!
+ */
+ ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
+ break;
+ }
+ /* Successfully processed marker, so reset state variable */
+ cinfo->unread_marker = 0;
+ } /* end loop */
+}
+
+
+/*
+ * Read a restart marker, which is expected to appear next in the datastream;
+ * if the marker is not there, take appropriate recovery action.
+ * Returns FALSE if suspension is required.
+ *
+ * This is called by the entropy decoder after it has read an appropriate
+ * number of MCUs. cinfo->unread_marker may be nonzero if the entropy decoder
+ * has already read a marker from the data source. Under normal conditions
+ * cinfo->unread_marker will be reset to 0 before returning; if not reset,
+ * it holds a marker which the decoder will be unable to read past.
+ */
+
+METHODDEF(boolean)
+read_restart_marker (j_decompress_ptr cinfo)
+{
+ /* Obtain a marker unless we already did. */
+ /* Note that next_marker will complain if it skips any data. */
+ if (cinfo->unread_marker == 0) {
+ if (! next_marker(cinfo))
+ return FALSE;
+ }
+
+ if (cinfo->unread_marker ==
+ ((int) M_RST0 + cinfo->marker->next_restart_num)) {
+ /* Normal case --- swallow the marker and let entropy decoder continue */
+ TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
+ cinfo->unread_marker = 0;
+ } else {
+ /* Uh-oh, the restart markers have been messed up. */
+ /* Let the data source manager determine how to resync. */
+ if (! (*cinfo->src->resync_to_restart) (cinfo,
+ cinfo->marker->next_restart_num))
+ return FALSE;
+ }
+
+ /* Update next-restart state */
+ cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
+
+ return TRUE;
+}
+
+
+/*
+ * This is the default resync_to_restart method for data source managers
+ * to use if they don't have any better approach. Some data source managers
+ * may be able to back up, or may have additional knowledge about the data
+ * which permits a more intelligent recovery strategy; such managers would
+ * presumably supply their own resync method.
+ *
+ * read_restart_marker calls resync_to_restart if it finds a marker other than
+ * the restart marker it was expecting. (This code is *not* used unless
+ * a nonzero restart interval has been declared.) cinfo->unread_marker is
+ * the marker code actually found (might be anything, except 0 or FF).
+ * The desired restart marker number (0..7) is passed as a parameter.
+ * This routine is supposed to apply whatever error recovery strategy seems
+ * appropriate in order to position the input stream to the next data segment.
+ * Note that cinfo->unread_marker is treated as a marker appearing before
+ * the current data-source input point; usually it should be reset to zero
+ * before returning.
+ * Returns FALSE if suspension is required.
+ *
+ * This implementation is substantially constrained by wanting to treat the
+ * input as a data stream; this means we can't back up. Therefore, we have
+ * only the following actions to work with:
+ * 1. Simply discard the marker and let the entropy decoder resume at next
+ * byte of file.
+ * 2. Read forward until we find another marker, discarding intervening
+ * data. (In theory we could look ahead within the current bufferload,
+ * without having to discard data if we don't find the desired marker.
+ * This idea is not implemented here, in part because it makes behavior
+ * dependent on buffer size and chance buffer-boundary positions.)
+ * 3. Leave the marker unread (by failing to zero cinfo->unread_marker).
+ * This will cause the entropy decoder to process an empty data segment,
+ * inserting dummy zeroes, and then we will reprocess the marker.
+ *
+ * #2 is appropriate if we think the desired marker lies ahead, while #3 is
+ * appropriate if the found marker is a future restart marker (indicating
+ * that we have missed the desired restart marker, probably because it got
+ * corrupted).
+ * We apply #2 or #3 if the found marker is a restart marker no more than
+ * two counts behind or ahead of the expected one. We also apply #2 if the
+ * found marker is not a legal JPEG marker code (it's certainly bogus data).
+ * If the found marker is a restart marker more than 2 counts away, we do #1
+ * (too much risk that the marker is erroneous; with luck we will be able to
+ * resync at some future point).
+ * For any valid non-restart JPEG marker, we apply #3. This keeps us from
+ * overrunning the end of a scan. An implementation limited to single-scan
+ * files might find it better to apply #2 for markers other than EOI, since
+ * any other marker would have to be bogus data in that case.
+ */
+
+GLOBAL(boolean)
+jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
+{
+ int marker = cinfo->unread_marker;
+ int action = 1;
+
+ /* Always put up a warning. */
+ WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
+
+ /* Outer loop handles repeated decision after scanning forward. */
+ for (;;) {
+ if (marker < (int) M_SOF0)
+ action = 2; /* invalid marker */
+ else if (marker < (int) M_RST0 || marker > (int) M_RST7)
+ action = 3; /* valid non-restart marker */
+ else {
+ if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||
+ marker == ((int) M_RST0 + ((desired+2) & 7)))
+ action = 3; /* one of the next two expected restarts */
+ else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||
+ marker == ((int) M_RST0 + ((desired-2) & 7)))
+ action = 2; /* a prior restart, so advance */
+ else
+ action = 1; /* desired restart or too far away */
+ }
+ TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
+ switch (action) {
+ case 1:
+ /* Discard marker and let entropy decoder resume processing. */
+ cinfo->unread_marker = 0;
+ return TRUE;
+ case 2:
+ /* Scan to the next marker, and repeat the decision loop. */
+ if (! next_marker(cinfo))
+ return FALSE;
+ marker = cinfo->unread_marker;
+ break;
+ case 3:
+ /* Return without advancing past this marker. */
+ /* Entropy decoder will be forced to process an empty segment. */
+ return TRUE;
+ }
+ } /* end loop */
+}
+
+
+/*
+ * Reset marker processing state to begin a fresh datastream.
+ */
+
+METHODDEF(void)
+reset_marker_reader (j_decompress_ptr cinfo)
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
+ cinfo->comp_info = NULL; /* until allocated by get_sof */
+ cinfo->input_scan_number = 0; /* no SOS seen yet */
+ cinfo->unread_marker = 0; /* no pending marker */
+ marker->pub.saw_SOI = FALSE; /* set internal state too */
+ marker->pub.saw_SOF = FALSE;
+ marker->pub.discarded_bytes = 0;
+ marker->cur_marker = NULL;
+}
+
+
+/*
+ * Initialize the marker reader module.
+ * This is called only once, when the decompression object is created.
+ */
+
+GLOBAL(void)
+jinit_marker_reader (j_decompress_ptr cinfo)
+{
+ my_marker_ptr marker;
+ int i;
+
+ /* Create subobject in permanent pool */
+ marker = (my_marker_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ SIZEOF(my_marker_reader));
+ cinfo->marker = (struct jpeg_marker_reader *) marker;
+ /* Initialize public method pointers */
+ marker->pub.reset_marker_reader = reset_marker_reader;
+ marker->pub.read_markers = read_markers;
+ marker->pub.read_restart_marker = read_restart_marker;
+ /* Initialize COM/APPn processing.
+ * By default, we examine and then discard APP0 and APP14,
+ * but simply discard COM and all other APPn.
+ */
+ marker->process_COM = skip_variable;
+ marker->length_limit_COM = 0;
+ for (i = 0; i < 16; i++) {
+ marker->process_APPn[i] = skip_variable;
+ marker->length_limit_APPn[i] = 0;
+ }
+ marker->process_APPn[0] = get_interesting_appn;
+ marker->process_APPn[14] = get_interesting_appn;
+ /* Reset marker processing state */
+ reset_marker_reader(cinfo);
+}
+
+
+/*
+ * Control saving of COM and APPn markers into marker_list.
+ */
+
+#ifdef SAVE_MARKERS_SUPPORTED
+
+GLOBAL(void)
+jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
+ unsigned int length_limit)
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+ long maxlength;
+ jpeg_marker_parser_method processor;
+
+ /* Length limit mustn't be larger than what we can allocate
+ * (should only be a concern in a 16-bit environment).
+ */
+ maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);
+ if (((long) length_limit) > maxlength)
+ length_limit = (unsigned int) maxlength;
+
+ /* Choose processor routine to use.
+ * APP0/APP14 have special requirements.
+ */
+ if (length_limit) {
+ processor = save_marker;
+ /* If saving APP0/APP14, save at least enough for our internal use. */
+ if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
+ length_limit = APP0_DATA_LEN;
+ else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
+ length_limit = APP14_DATA_LEN;
+ } else {
+ processor = skip_variable;
+ /* If discarding APP0/APP14, use our regular on-the-fly processor. */
+ if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
+ processor = get_interesting_appn;
+ }
+
+ if (marker_code == (int) M_COM) {
+ marker->process_COM = processor;
+ marker->length_limit_COM = length_limit;
+ } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
+ marker->process_APPn[marker_code - (int) M_APP0] = processor;
+ marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
+ } else
+ ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
+}
+
+#endif /* SAVE_MARKERS_SUPPORTED */
+
+
+/*
+ * Install a special processing method for COM or APPn markers.
+ */
+
+GLOBAL(void)
+jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
+ jpeg_marker_parser_method routine)
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
+ if (marker_code == (int) M_COM)
+ marker->process_COM = routine;
+ else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
+ marker->process_APPn[marker_code - (int) M_APP0] = routine;
+ else
+ ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
+}
diff --git a/src/libjpeg-turbo/jdmaster.c b/src/libjpeg-turbo/jdmaster.c
new file mode 100644
index 0000000..c73ec02
--- /dev/null
+++ b/src/libjpeg-turbo/jdmaster.c
@@ -0,0 +1,601 @@
+/*
+ * jdmaster.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Copyright (C) 2009-2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains master control logic for the JPEG decompressor.
+ * These routines are concerned with selecting the modules to be executed
+ * and with determining the number of passes and the work to be done in each
+ * pass.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jpegcomp.h"
+
+
+/* Private state */
+
+typedef struct {
+ struct jpeg_decomp_master pub; /* public fields */
+
+ int pass_number; /* # of passes completed */
+
+ boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */
+
+ /* Saved references to initialized quantizer modules,
+ * in case we need to switch modes.
+ */
+ struct jpeg_color_quantizer * quantizer_1pass;
+ struct jpeg_color_quantizer * quantizer_2pass;
+} my_decomp_master;
+
+typedef my_decomp_master * my_master_ptr;
+
+
+/*
+ * Determine whether merged upsample/color conversion should be used.
+ * CRUCIAL: this must match the actual capabilities of jdmerge.c!
+ */
+
+LOCAL(boolean)
+use_merged_upsample (j_decompress_ptr cinfo)
+{
+#ifdef UPSAMPLE_MERGING_SUPPORTED
+ /* Merging is the equivalent of plain box-filter upsampling */
+ if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
+ return FALSE;
+ /* jdmerge.c only supports YCC=>RGB color conversion */
+ if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
+ (cinfo->out_color_space != JCS_RGB &&
+ cinfo->out_color_space != JCS_EXT_RGB &&
+ cinfo->out_color_space != JCS_EXT_RGBX &&
+ cinfo->out_color_space != JCS_EXT_BGR &&
+ cinfo->out_color_space != JCS_EXT_BGRX &&
+ cinfo->out_color_space != JCS_EXT_XBGR &&
+ cinfo->out_color_space != JCS_EXT_XRGB &&
+ cinfo->out_color_space != JCS_EXT_RGBA &&
+ cinfo->out_color_space != JCS_EXT_BGRA &&
+ cinfo->out_color_space != JCS_EXT_ABGR &&
+ cinfo->out_color_space != JCS_EXT_ARGB) ||
+ cinfo->out_color_components != rgb_pixelsize[cinfo->out_color_space])
+ return FALSE;
+ /* and it only handles 2h1v or 2h2v sampling ratios */
+ if (cinfo->comp_info[0].h_samp_factor != 2 ||
+ cinfo->comp_info[1].h_samp_factor != 1 ||
+ cinfo->comp_info[2].h_samp_factor != 1 ||
+ cinfo->comp_info[0].v_samp_factor > 2 ||
+ cinfo->comp_info[1].v_samp_factor != 1 ||
+ cinfo->comp_info[2].v_samp_factor != 1)
+ return FALSE;
+ /* furthermore, it doesn't work if we've scaled the IDCTs differently */
+ if (cinfo->comp_info[0]._DCT_scaled_size != cinfo->_min_DCT_scaled_size ||
+ cinfo->comp_info[1]._DCT_scaled_size != cinfo->_min_DCT_scaled_size ||
+ cinfo->comp_info[2]._DCT_scaled_size != cinfo->_min_DCT_scaled_size)
+ return FALSE;
+ /* ??? also need to test for upsample-time rescaling, when & if supported */
+ return TRUE; /* by golly, it'll work... */
+#else
+ return FALSE;
+#endif
+}
+
+
+/*
+ * Compute output image dimensions and related values.
+ * NOTE: this is exported for possible use by application.
+ * Hence it mustn't do anything that can't be done twice.
+ * Also note that it may be called before the master module is initialized!
+ */
+
+GLOBAL(void)
+jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
+/* Do computations that are needed before master selection phase */
+{
+#ifdef IDCT_SCALING_SUPPORTED
+ int ci;
+ jpeg_component_info *compptr;
+#endif
+
+ /* Prevent application from calling me at wrong times */
+ if (cinfo->global_state != DSTATE_READY)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+#ifdef IDCT_SCALING_SUPPORTED
+
+ /* Compute actual output image dimensions and DCT scaling choices. */
+ if (cinfo->scale_num * 8 <= cinfo->scale_denom) {
+ /* Provide 1/8 scaling */
+ cinfo->output_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width, 8L);
+ cinfo->output_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height, 8L);
+#if JPEG_LIB_VERSION >= 70
+ cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = 1;
+#else
+ cinfo->min_DCT_scaled_size = 1;
+#endif
+ } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
+ /* Provide 1/4 scaling */
+ cinfo->output_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width, 4L);
+ cinfo->output_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height, 4L);
+#if JPEG_LIB_VERSION >= 70
+ cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = 2;
+#else
+ cinfo->min_DCT_scaled_size = 2;
+#endif
+ } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
+ /* Provide 1/2 scaling */
+ cinfo->output_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width, 2L);
+ cinfo->output_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height, 2L);
+#if JPEG_LIB_VERSION >= 70
+ cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = 4;
+#else
+ cinfo->min_DCT_scaled_size = 4;
+#endif
+ } else {
+ /* Provide 1/1 scaling */
+ cinfo->output_width = cinfo->image_width;
+ cinfo->output_height = cinfo->image_height;
+#if JPEG_LIB_VERSION >= 70
+ cinfo->min_DCT_h_scaled_size = cinfo->min_DCT_v_scaled_size = DCTSIZE;
+#else
+ cinfo->min_DCT_scaled_size = DCTSIZE;
+#endif
+ }
+ /* In selecting the actual DCT scaling for each component, we try to
+ * scale up the chroma components via IDCT scaling rather than upsampling.
+ * This saves time if the upsampler gets to use 1:1 scaling.
+ * Note this code assumes that the supported DCT scalings are powers of 2.
+ */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ int ssize = cinfo->_min_DCT_scaled_size;
+ while (ssize < DCTSIZE &&
+ (compptr->h_samp_factor * ssize * 2 <=
+ cinfo->max_h_samp_factor * cinfo->_min_DCT_scaled_size) &&
+ (compptr->v_samp_factor * ssize * 2 <=
+ cinfo->max_v_samp_factor * cinfo->_min_DCT_scaled_size)) {
+ ssize = ssize * 2;
+ }
+#if JPEG_LIB_VERSION >= 70
+ compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size = ssize;
+#else
+ compptr->DCT_scaled_size = ssize;
+#endif
+ }
+
+ /* Recompute downsampled dimensions of components;
+ * application needs to know these if using raw downsampled data.
+ */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Size in samples, after IDCT scaling */
+ compptr->downsampled_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width *
+ (long) (compptr->h_samp_factor * compptr->_DCT_scaled_size),
+ (long) (cinfo->max_h_samp_factor * DCTSIZE));
+ compptr->downsampled_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height *
+ (long) (compptr->v_samp_factor * compptr->_DCT_scaled_size),
+ (long) (cinfo->max_v_samp_factor * DCTSIZE));
+ }
+
+#else /* !IDCT_SCALING_SUPPORTED */
+
+ /* Hardwire it to "no scaling" */
+ cinfo->output_width = cinfo->image_width;
+ cinfo->output_height = cinfo->image_height;
+ /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
+ * and has computed unscaled downsampled_width and downsampled_height.
+ */
+
+#endif /* IDCT_SCALING_SUPPORTED */
+
+ /* Report number of components in selected colorspace. */
+ /* Probably this should be in the color conversion module... */
+ switch (cinfo->out_color_space) {
+ case JCS_GRAYSCALE:
+ cinfo->out_color_components = 1;
+ break;
+ case JCS_RGB:
+ case JCS_EXT_RGB:
+ case JCS_EXT_RGBX:
+ case JCS_EXT_BGR:
+ case JCS_EXT_BGRX:
+ case JCS_EXT_XBGR:
+ case JCS_EXT_XRGB:
+ case JCS_EXT_RGBA:
+ case JCS_EXT_BGRA:
+ case JCS_EXT_ABGR:
+ case JCS_EXT_ARGB:
+ cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
+ break;
+ case JCS_YCbCr:
+ cinfo->out_color_components = 3;
+ break;
+ case JCS_CMYK:
+ case JCS_YCCK:
+ cinfo->out_color_components = 4;
+ break;
+ default: /* else must be same colorspace as in file */
+ cinfo->out_color_components = cinfo->num_components;
+ break;
+ }
+ cinfo->output_components = (cinfo->quantize_colors ? 1 :
+ cinfo->out_color_components);
+
+ /* See if upsampler will want to emit more than one row at a time */
+ if (use_merged_upsample(cinfo))
+ cinfo->rec_outbuf_height = cinfo->max_v_samp_factor;
+ else
+ cinfo->rec_outbuf_height = 1;
+}
+
+
+/*
+ * Several decompression processes need to range-limit values to the range
+ * 0..MAXJSAMPLE; the input value may fall somewhat outside this range
+ * due to noise introduced by quantization, roundoff error, etc. These
+ * processes are inner loops and need to be as fast as possible. On most
+ * machines, particularly CPUs with pipelines or instruction prefetch,
+ * a (subscript-check-less) C table lookup
+ * x = sample_range_limit[x];
+ * is faster than explicit tests
+ * if (x < 0) x = 0;
+ * else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
+ * These processes all use a common table prepared by the routine below.
+ *
+ * For most steps we can mathematically guarantee that the initial value
+ * of x is within MAXJSAMPLE+1 of the legal range, so a table running from
+ * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial
+ * limiting step (just after the IDCT), a wildly out-of-range value is
+ * possible if the input data is corrupt. To avoid any chance of indexing
+ * off the end of memory and getting a bad-pointer trap, we perform the
+ * post-IDCT limiting thus:
+ * x = range_limit[x & MASK];
+ * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit
+ * samples. Under normal circumstances this is more than enough range and
+ * a correct output will be generated; with bogus input data the mask will
+ * cause wraparound, and we will safely generate a bogus-but-in-range output.
+ * For the post-IDCT step, we want to convert the data from signed to unsigned
+ * representation by adding CENTERJSAMPLE at the same time that we limit it.
+ * So the post-IDCT limiting table ends up looking like this:
+ * CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE,
+ * MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
+ * 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
+ * 0,1,...,CENTERJSAMPLE-1
+ * Negative inputs select values from the upper half of the table after
+ * masking.
+ *
+ * We can save some space by overlapping the start of the post-IDCT table
+ * with the simpler range limiting table. The post-IDCT table begins at
+ * sample_range_limit + CENTERJSAMPLE.
+ *
+ * Note that the table is allocated in near data space on PCs; it's small
+ * enough and used often enough to justify this.
+ */
+
+LOCAL(void)
+prepare_range_limit_table (j_decompress_ptr cinfo)
+/* Allocate and fill in the sample_range_limit table */
+{
+ JSAMPLE * table;
+ int i;
+
+ table = (JSAMPLE *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE));
+ table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */
+ cinfo->sample_range_limit = table;
+ /* First segment of "simple" table: limit[x] = 0 for x < 0 */
+ MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
+ /* Main part of "simple" table: limit[x] = x */
+ for (i = 0; i <= MAXJSAMPLE; i++)
+ table[i] = (JSAMPLE) i;
+ table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */
+ /* End of simple table, rest of first half of post-IDCT table */
+ for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++)
+ table[i] = MAXJSAMPLE;
+ /* Second half of post-IDCT table */
+ MEMZERO(table + (2 * (MAXJSAMPLE+1)),
+ (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
+ MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE),
+ cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE));
+}
+
+
+/*
+ * Master selection of decompression modules.
+ * This is done once at jpeg_start_decompress time. We determine
+ * which modules will be used and give them appropriate initialization calls.
+ * We also initialize the decompressor input side to begin consuming data.
+ *
+ * Since jpeg_read_header has finished, we know what is in the SOF
+ * and (first) SOS markers. We also have all the application parameter
+ * settings.
+ */
+
+LOCAL(void)
+master_selection (j_decompress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+ boolean use_c_buffer;
+ long samplesperrow;
+ JDIMENSION jd_samplesperrow;
+
+ /* Initialize dimensions and other stuff */
+ jpeg_calc_output_dimensions(cinfo);
+ prepare_range_limit_table(cinfo);
+
+ /* Width of an output scanline must be representable as JDIMENSION. */
+ samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components;
+ jd_samplesperrow = (JDIMENSION) samplesperrow;
+ if ((long) jd_samplesperrow != samplesperrow)
+ ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+
+ /* Initialize my private state */
+ master->pass_number = 0;
+ master->using_merged_upsample = use_merged_upsample(cinfo);
+
+ /* Color quantizer selection */
+ master->quantizer_1pass = NULL;
+ master->quantizer_2pass = NULL;
+ /* No mode changes if not using buffered-image mode. */
+ if (! cinfo->quantize_colors || ! cinfo->buffered_image) {
+ cinfo->enable_1pass_quant = FALSE;
+ cinfo->enable_external_quant = FALSE;
+ cinfo->enable_2pass_quant = FALSE;
+ }
+ if (cinfo->quantize_colors) {
+ if (cinfo->raw_data_out)
+ ERREXIT(cinfo, JERR_NOTIMPL);
+ /* 2-pass quantizer only works in 3-component color space. */
+ if (cinfo->out_color_components != 3) {
+ cinfo->enable_1pass_quant = TRUE;
+ cinfo->enable_external_quant = FALSE;
+ cinfo->enable_2pass_quant = FALSE;
+ cinfo->colormap = NULL;
+ } else if (cinfo->colormap != NULL) {
+ cinfo->enable_external_quant = TRUE;
+ } else if (cinfo->two_pass_quantize) {
+ cinfo->enable_2pass_quant = TRUE;
+ } else {
+ cinfo->enable_1pass_quant = TRUE;
+ }
+
+ if (cinfo->enable_1pass_quant) {
+#ifdef QUANT_1PASS_SUPPORTED
+ jinit_1pass_quantizer(cinfo);
+ master->quantizer_1pass = cinfo->cquantize;
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ }
+
+ /* We use the 2-pass code to map to external colormaps. */
+ if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
+#ifdef QUANT_2PASS_SUPPORTED
+ jinit_2pass_quantizer(cinfo);
+ master->quantizer_2pass = cinfo->cquantize;
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ }
+ /* If both quantizers are initialized, the 2-pass one is left active;
+ * this is necessary for starting with quantization to an external map.
+ */
+ }
+
+ /* Post-processing: in particular, color conversion first */
+ if (! cinfo->raw_data_out) {
+ if (master->using_merged_upsample) {
+#ifdef UPSAMPLE_MERGING_SUPPORTED
+ jinit_merged_upsampler(cinfo); /* does color conversion too */
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ jinit_color_deconverter(cinfo);
+ jinit_upsampler(cinfo);
+ }
+ jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
+ }
+ /* Inverse DCT */
+ jinit_inverse_dct(cinfo);
+ /* Entropy decoding: either Huffman or arithmetic coding. */
+ if (cinfo->arith_code) {
+#ifdef D_ARITH_CODING_SUPPORTED
+ jinit_arith_decoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+#endif
+ } else {
+ if (cinfo->progressive_mode) {
+#ifdef D_PROGRESSIVE_SUPPORTED
+ jinit_phuff_decoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else
+ jinit_huff_decoder(cinfo);
+ }
+
+ /* Initialize principal buffer controllers. */
+ use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
+ jinit_d_coef_controller(cinfo, use_c_buffer);
+
+ if (! cinfo->raw_data_out)
+ jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
+
+ /* We can now tell the memory manager to allocate virtual arrays. */
+ (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+ /* Initialize input side of decompressor to consume first scan. */
+ (*cinfo->inputctl->start_input_pass) (cinfo);
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+ /* If jpeg_start_decompress will read the whole file, initialize
+ * progress monitoring appropriately. The input step is counted
+ * as one pass.
+ */
+ if (cinfo->progress != NULL && ! cinfo->buffered_image &&
+ cinfo->inputctl->has_multiple_scans) {
+ int nscans;
+ /* Estimate number of scans to set pass_limit. */
+ if (cinfo->progressive_mode) {
+ /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
+ nscans = 2 + 3 * cinfo->num_components;
+ } else {
+ /* For a nonprogressive multiscan file, estimate 1 scan per component. */
+ nscans = cinfo->num_components;
+ }
+ cinfo->progress->pass_counter = 0L;
+ cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
+ cinfo->progress->completed_passes = 0;
+ cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2);
+ /* Count the input pass as done */
+ master->pass_number++;
+ }
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+}
+
+
+/*
+ * Per-pass setup.
+ * This is called at the beginning of each output pass. We determine which
+ * modules will be active during this pass and give them appropriate
+ * start_pass calls. We also set is_dummy_pass to indicate whether this
+ * is a "real" output pass or a dummy pass for color quantization.
+ * (In the latter case, jdapistd.c will crank the pass to completion.)
+ */
+
+METHODDEF(void)
+prepare_for_output_pass (j_decompress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+
+ if (master->pub.is_dummy_pass) {
+#ifdef QUANT_2PASS_SUPPORTED
+ /* Final pass of 2-pass quantization */
+ master->pub.is_dummy_pass = FALSE;
+ (*cinfo->cquantize->start_pass) (cinfo, FALSE);
+ (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST);
+ (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif /* QUANT_2PASS_SUPPORTED */
+ } else {
+ if (cinfo->quantize_colors && cinfo->colormap == NULL) {
+ /* Select new quantization method */
+ if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) {
+ cinfo->cquantize = master->quantizer_2pass;
+ master->pub.is_dummy_pass = TRUE;
+ } else if (cinfo->enable_1pass_quant) {
+ cinfo->cquantize = master->quantizer_1pass;
+ } else {
+ ERREXIT(cinfo, JERR_MODE_CHANGE);
+ }
+ }
+ (*cinfo->idct->start_pass) (cinfo);
+ (*cinfo->coef->start_output_pass) (cinfo);
+ if (! cinfo->raw_data_out) {
+ if (! master->using_merged_upsample)
+ (*cinfo->cconvert->start_pass) (cinfo);
+ (*cinfo->upsample->start_pass) (cinfo);
+ if (cinfo->quantize_colors)
+ (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass);
+ (*cinfo->post->start_pass) (cinfo,
+ (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
+ (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
+ }
+ }
+
+ /* Set up progress monitor's pass info if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->completed_passes = master->pass_number;
+ cinfo->progress->total_passes = master->pass_number +
+ (master->pub.is_dummy_pass ? 2 : 1);
+ /* In buffered-image mode, we assume one more output pass if EOI not
+ * yet reached, but no more passes if EOI has been reached.
+ */
+ if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) {
+ cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1);
+ }
+ }
+}
+
+
+/*
+ * Finish up at end of an output pass.
+ */
+
+METHODDEF(void)
+finish_output_pass (j_decompress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+
+ if (cinfo->quantize_colors)
+ (*cinfo->cquantize->finish_pass) (cinfo);
+ master->pass_number++;
+}
+
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+
+/*
+ * Switch to a new external colormap between output passes.
+ */
+
+GLOBAL(void)
+jpeg_new_colormap (j_decompress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+
+ /* Prevent application from calling me at wrong times */
+ if (cinfo->global_state != DSTATE_BUFIMAGE)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ if (cinfo->quantize_colors && cinfo->enable_external_quant &&
+ cinfo->colormap != NULL) {
+ /* Select 2-pass quantizer for external colormap use */
+ cinfo->cquantize = master->quantizer_2pass;
+ /* Notify quantizer of colormap change */
+ (*cinfo->cquantize->new_color_map) (cinfo);
+ master->pub.is_dummy_pass = FALSE; /* just in case */
+ } else
+ ERREXIT(cinfo, JERR_MODE_CHANGE);
+}
+
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+
+
+/*
+ * Initialize master decompression control and select active modules.
+ * This is performed at the start of jpeg_start_decompress.
+ */
+
+GLOBAL(void)
+jinit_master_decompress (j_decompress_ptr cinfo)
+{
+ my_master_ptr master;
+
+ master = (my_master_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_decomp_master));
+ cinfo->master = (struct jpeg_decomp_master *) master;
+ master->pub.prepare_for_output_pass = prepare_for_output_pass;
+ master->pub.finish_output_pass = finish_output_pass;
+
+ master->pub.is_dummy_pass = FALSE;
+
+ master_selection(cinfo);
+}
diff --git a/src/libjpeg-turbo/jdmerge.c b/src/libjpeg-turbo/jdmerge.c
new file mode 100644
index 0000000..a8dcb46
--- /dev/null
+++ b/src/libjpeg-turbo/jdmerge.c
@@ -0,0 +1,455 @@
+/*
+ * jdmerge.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright (C) 2009, 2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains code for merged upsampling/color conversion.
+ *
+ * This file combines functions from jdsample.c and jdcolor.c;
+ * read those files first to understand what's going on.
+ *
+ * When the chroma components are to be upsampled by simple replication
+ * (ie, box filtering), we can save some work in color conversion by
+ * calculating all the output pixels corresponding to a pair of chroma
+ * samples at one time. In the conversion equations
+ * R = Y + K1 * Cr
+ * G = Y + K2 * Cb + K3 * Cr
+ * B = Y + K4 * Cb
+ * only the Y term varies among the group of pixels corresponding to a pair
+ * of chroma samples, so the rest of the terms can be calculated just once.
+ * At typical sampling ratios, this eliminates half or three-quarters of the
+ * multiplications needed for color conversion.
+ *
+ * This file currently provides implementations for the following cases:
+ * YCbCr => RGB color conversion only.
+ * Sampling ratios of 2h1v or 2h2v.
+ * No scaling needed at upsample time.
+ * Corner-aligned (non-CCIR601) sampling alignment.
+ * Other special cases could be added, but in most applications these are
+ * the only common cases. (For uncommon cases we fall back on the more
+ * general code in jdsample.c and jdcolor.c.)
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jsimd.h"
+#include "config.h"
+
+#ifdef UPSAMPLE_MERGING_SUPPORTED
+
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_upsampler pub; /* public fields */
+
+ /* Pointer to routine to do actual upsampling/conversion of one row group */
+ JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf));
+
+ /* Private state for YCC->RGB conversion */
+ int * Cr_r_tab; /* => table for Cr to R conversion */
+ int * Cb_b_tab; /* => table for Cb to B conversion */
+ INT32 * Cr_g_tab; /* => table for Cr to G conversion */
+ INT32 * Cb_g_tab; /* => table for Cb to G conversion */
+
+ /* For 2:1 vertical sampling, we produce two output rows at a time.
+ * We need a "spare" row buffer to hold the second output row if the
+ * application provides just a one-row buffer; we also use the spare
+ * to discard the dummy last row if the image height is odd.
+ */
+ JSAMPROW spare_row;
+ boolean spare_full; /* T if spare buffer is occupied */
+
+ JDIMENSION out_row_width; /* samples per output row */
+ JDIMENSION rows_to_go; /* counts rows remaining in image */
+} my_upsampler;
+
+typedef my_upsampler * my_upsample_ptr;
+
+#define SCALEBITS 16 /* speediest right-shift on some machines */
+#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
+#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
+
+
+/* Include inline routines for colorspace extensions */
+
+#include "jdmrgext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+
+#define RGB_RED EXT_RGB_RED
+#define RGB_GREEN EXT_RGB_GREEN
+#define RGB_BLUE EXT_RGB_BLUE
+#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
+#define h2v1_merged_upsample_internal extrgb_h2v1_merged_upsample_internal
+#define h2v2_merged_upsample_internal extrgb_h2v2_merged_upsample_internal
+#include "jdmrgext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef h2v1_merged_upsample_internal
+#undef h2v2_merged_upsample_internal
+
+#define RGB_RED EXT_RGBX_RED
+#define RGB_GREEN EXT_RGBX_GREEN
+#define RGB_BLUE EXT_RGBX_BLUE
+#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
+#define h2v1_merged_upsample_internal extrgbx_h2v1_merged_upsample_internal
+#define h2v2_merged_upsample_internal extrgbx_h2v2_merged_upsample_internal
+#include "jdmrgext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef h2v1_merged_upsample_internal
+#undef h2v2_merged_upsample_internal
+
+#define RGB_RED EXT_BGR_RED
+#define RGB_GREEN EXT_BGR_GREEN
+#define RGB_BLUE EXT_BGR_BLUE
+#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
+#define h2v1_merged_upsample_internal extbgr_h2v1_merged_upsample_internal
+#define h2v2_merged_upsample_internal extbgr_h2v2_merged_upsample_internal
+#include "jdmrgext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef h2v1_merged_upsample_internal
+#undef h2v2_merged_upsample_internal
+
+#define RGB_RED EXT_BGRX_RED
+#define RGB_GREEN EXT_BGRX_GREEN
+#define RGB_BLUE EXT_BGRX_BLUE
+#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
+#define h2v1_merged_upsample_internal extbgrx_h2v1_merged_upsample_internal
+#define h2v2_merged_upsample_internal extbgrx_h2v2_merged_upsample_internal
+#include "jdmrgext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef h2v1_merged_upsample_internal
+#undef h2v2_merged_upsample_internal
+
+#define RGB_RED EXT_XBGR_RED
+#define RGB_GREEN EXT_XBGR_GREEN
+#define RGB_BLUE EXT_XBGR_BLUE
+#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
+#define h2v1_merged_upsample_internal extxbgr_h2v1_merged_upsample_internal
+#define h2v2_merged_upsample_internal extxbgr_h2v2_merged_upsample_internal
+#include "jdmrgext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef h2v1_merged_upsample_internal
+#undef h2v2_merged_upsample_internal
+
+#define RGB_RED EXT_XRGB_RED
+#define RGB_GREEN EXT_XRGB_GREEN
+#define RGB_BLUE EXT_XRGB_BLUE
+#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
+#define h2v1_merged_upsample_internal extxrgb_h2v1_merged_upsample_internal
+#define h2v2_merged_upsample_internal extxrgb_h2v2_merged_upsample_internal
+#include "jdmrgext.c.inc"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef h2v1_merged_upsample_internal
+#undef h2v2_merged_upsample_internal
+
+
+/*
+ * Initialize tables for YCC->RGB colorspace conversion.
+ * This is taken directly from jdcolor.c; see that file for more info.
+ */
+
+LOCAL(void)
+build_ycc_rgb_table (j_decompress_ptr cinfo)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ int i;
+ INT32 x;
+ SHIFT_TEMPS
+
+ upsample->Cr_r_tab = (int *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(int));
+ upsample->Cb_b_tab = (int *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(int));
+ upsample->Cr_g_tab = (INT32 *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(INT32));
+ upsample->Cb_g_tab = (INT32 *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(INT32));
+
+ for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
+ /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
+ /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
+ /* Cr=>R value is nearest int to 1.40200 * x */
+ upsample->Cr_r_tab[i] = (int)
+ RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
+ /* Cb=>B value is nearest int to 1.77200 * x */
+ upsample->Cb_b_tab[i] = (int)
+ RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
+ /* Cr=>G value is scaled-up -0.71414 * x */
+ upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
+ /* Cb=>G value is scaled-up -0.34414 * x */
+ /* We also add in ONE_HALF so that need not do it in inner loop */
+ upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
+ }
+}
+
+
+/*
+ * Initialize for an upsampling pass.
+ */
+
+METHODDEF(void)
+start_pass_merged_upsample (j_decompress_ptr cinfo)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+
+ /* Mark the spare buffer empty */
+ upsample->spare_full = FALSE;
+ /* Initialize total-height counter for detecting bottom of image */
+ upsample->rows_to_go = cinfo->output_height;
+}
+
+
+/*
+ * Control routine to do upsampling (and color conversion).
+ *
+ * The control routine just handles the row buffering considerations.
+ */
+
+METHODDEF(void)
+merged_2v_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+/* 2:1 vertical sampling case: may need a spare row. */
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ JSAMPROW work_ptrs[2];
+ JDIMENSION num_rows; /* number of rows returned to caller */
+
+ if (upsample->spare_full) {
+ /* If we have a spare row saved from a previous cycle, just return it. */
+ jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
+ 1, upsample->out_row_width);
+ num_rows = 1;
+ upsample->spare_full = FALSE;
+ } else {
+ /* Figure number of rows to return to caller. */
+ num_rows = 2;
+ /* Not more than the distance to the end of the image. */
+ if (num_rows > upsample->rows_to_go)
+ num_rows = upsample->rows_to_go;
+ /* And not more than what the client can accept: */
+ out_rows_avail -= *out_row_ctr;
+ if (num_rows > out_rows_avail)
+ num_rows = out_rows_avail;
+ /* Create output pointer array for upsampler. */
+ work_ptrs[0] = output_buf[*out_row_ctr];
+ if (num_rows > 1) {
+ work_ptrs[1] = output_buf[*out_row_ctr + 1];
+ } else {
+ work_ptrs[1] = upsample->spare_row;
+ upsample->spare_full = TRUE;
+ }
+ /* Now do the upsampling. */
+ (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
+ }
+
+ /* Adjust counts */
+ *out_row_ctr += num_rows;
+ upsample->rows_to_go -= num_rows;
+ /* When the buffer is emptied, declare this input row group consumed */
+ if (! upsample->spare_full)
+ (*in_row_group_ctr)++;
+}
+
+
+METHODDEF(void)
+merged_1v_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+/* 1:1 vertical sampling case: much easier, never need a spare row. */
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+
+ /* Just do the upsampling. */
+ (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
+ output_buf + *out_row_ctr);
+ /* Adjust counts */
+ (*out_row_ctr)++;
+ (*in_row_group_ctr)++;
+}
+
+
+/*
+ * These are the routines invoked by the control routines to do
+ * the actual upsampling/conversion. One row group is processed per call.
+ *
+ * Note: since we may be writing directly into application-supplied buffers,
+ * we have to be honest about the output width; we can't assume the buffer
+ * has been rounded up to an even width.
+ */
+
+
+/*
+ * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
+ */
+
+METHODDEF(void)
+h2v1_merged_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+{
+ switch (cinfo->out_color_space) {
+ case JCS_EXT_RGB:
+ extrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ case JCS_EXT_RGBX:
+ case JCS_EXT_RGBA:
+ extrgbx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ case JCS_EXT_BGR:
+ extbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ case JCS_EXT_BGRX:
+ case JCS_EXT_BGRA:
+ extbgrx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ case JCS_EXT_XBGR:
+ case JCS_EXT_ABGR:
+ extxbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ case JCS_EXT_XRGB:
+ case JCS_EXT_ARGB:
+ extxrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ default:
+ h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ }
+}
+
+
+/*
+ * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
+ */
+
+METHODDEF(void)
+h2v2_merged_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+{
+ switch (cinfo->out_color_space) {
+ case JCS_EXT_RGB:
+ extrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ case JCS_EXT_RGBX:
+ case JCS_EXT_RGBA:
+ extrgbx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ case JCS_EXT_BGR:
+ extbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ case JCS_EXT_BGRX:
+ case JCS_EXT_BGRA:
+ extbgrx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ case JCS_EXT_XBGR:
+ case JCS_EXT_ABGR:
+ extxbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ case JCS_EXT_XRGB:
+ case JCS_EXT_ARGB:
+ extxrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ default:
+ h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
+ output_buf);
+ break;
+ }
+}
+
+
+/*
+ * Module initialization routine for merged upsampling/color conversion.
+ *
+ * NB: this is called under the conditions determined by use_merged_upsample()
+ * in jdmaster.c. That routine MUST correspond to the actual capabilities
+ * of this module; no safety checks are made here.
+ */
+
+GLOBAL(void)
+jinit_merged_upsampler (j_decompress_ptr cinfo)
+{
+ my_upsample_ptr upsample;
+
+ upsample = (my_upsample_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_upsampler));
+ cinfo->upsample = (struct jpeg_upsampler *) upsample;
+ upsample->pub.start_pass = start_pass_merged_upsample;
+ upsample->pub.need_context_rows = FALSE;
+
+ upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
+
+ if (cinfo->max_v_samp_factor == 2) {
+ upsample->pub.upsample = merged_2v_upsample;
+ if (jsimd_can_h2v2_merged_upsample())
+ upsample->upmethod = jsimd_h2v2_merged_upsample;
+ else
+ upsample->upmethod = h2v2_merged_upsample;
+ /* Allocate a spare row buffer */
+ upsample->spare_row = (JSAMPROW)
+ (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
+ } else {
+ upsample->pub.upsample = merged_1v_upsample;
+ if (jsimd_can_h2v1_merged_upsample())
+ upsample->upmethod = jsimd_h2v1_merged_upsample;
+ else
+ upsample->upmethod = h2v1_merged_upsample;
+ /* No spare row needed */
+ upsample->spare_row = NULL;
+ }
+
+ build_ycc_rgb_table(cinfo);
+}
+
+#endif /* UPSAMPLE_MERGING_SUPPORTED */
diff --git a/src/libjpeg-turbo/jdmrgext.c.inc b/src/libjpeg-turbo/jdmrgext.c.inc
new file mode 100644
index 0000000..95ddd55
--- /dev/null
+++ b/src/libjpeg-turbo/jdmrgext.c.inc
@@ -0,0 +1,156 @@
+/*
+ * jdmrgext.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains code for merged upsampling/color conversion.
+ */
+
+
+/* This file is included by jdmerge.c */
+
+
+/*
+ * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
+ */
+
+INLINE
+LOCAL(void)
+h2v1_merged_upsample_internal (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ register int y, cred, cgreen, cblue;
+ int cb, cr;
+ register JSAMPROW outptr;
+ JSAMPROW inptr0, inptr1, inptr2;
+ JDIMENSION col;
+ /* copy these pointers into registers if possible */
+ register JSAMPLE * range_limit = cinfo->sample_range_limit;
+ int * Crrtab = upsample->Cr_r_tab;
+ int * Cbbtab = upsample->Cb_b_tab;
+ INT32 * Crgtab = upsample->Cr_g_tab;
+ INT32 * Cbgtab = upsample->Cb_g_tab;
+ SHIFT_TEMPS
+
+ inptr0 = input_buf[0][in_row_group_ctr];
+ inptr1 = input_buf[1][in_row_group_ctr];
+ inptr2 = input_buf[2][in_row_group_ctr];
+ outptr = output_buf[0];
+ /* Loop for each pair of output pixels */
+ for (col = cinfo->output_width >> 1; col > 0; col--) {
+ /* Do the chroma part of the calculation */
+ cb = GETJSAMPLE(*inptr1++);
+ cr = GETJSAMPLE(*inptr2++);
+ cred = Crrtab[cr];
+ cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+ cblue = Cbbtab[cb];
+ /* Fetch 2 Y values and emit 2 pixels */
+ y = GETJSAMPLE(*inptr0++);
+ outptr[RGB_RED] = range_limit[y + cred];
+ outptr[RGB_GREEN] = range_limit[y + cgreen];
+ outptr[RGB_BLUE] = range_limit[y + cblue];
+ outptr += RGB_PIXELSIZE;
+ y = GETJSAMPLE(*inptr0++);
+ outptr[RGB_RED] = range_limit[y + cred];
+ outptr[RGB_GREEN] = range_limit[y + cgreen];
+ outptr[RGB_BLUE] = range_limit[y + cblue];
+ outptr += RGB_PIXELSIZE;
+ }
+ /* If image width is odd, do the last output column separately */
+ if (cinfo->output_width & 1) {
+ cb = GETJSAMPLE(*inptr1);
+ cr = GETJSAMPLE(*inptr2);
+ cred = Crrtab[cr];
+ cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+ cblue = Cbbtab[cb];
+ y = GETJSAMPLE(*inptr0);
+ outptr[RGB_RED] = range_limit[y + cred];
+ outptr[RGB_GREEN] = range_limit[y + cgreen];
+ outptr[RGB_BLUE] = range_limit[y + cblue];
+ }
+}
+
+
+/*
+ * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
+ */
+
+INLINE
+LOCAL(void)
+h2v2_merged_upsample_internal (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ register int y, cred, cgreen, cblue;
+ int cb, cr;
+ register JSAMPROW outptr0, outptr1;
+ JSAMPROW inptr00, inptr01, inptr1, inptr2;
+ JDIMENSION col;
+ /* copy these pointers into registers if possible */
+ register JSAMPLE * range_limit = cinfo->sample_range_limit;
+ int * Crrtab = upsample->Cr_r_tab;
+ int * Cbbtab = upsample->Cb_b_tab;
+ INT32 * Crgtab = upsample->Cr_g_tab;
+ INT32 * Cbgtab = upsample->Cb_g_tab;
+ SHIFT_TEMPS
+
+ inptr00 = input_buf[0][in_row_group_ctr*2];
+ inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
+ inptr1 = input_buf[1][in_row_group_ctr];
+ inptr2 = input_buf[2][in_row_group_ctr];
+ outptr0 = output_buf[0];
+ outptr1 = output_buf[1];
+ /* Loop for each group of output pixels */
+ for (col = cinfo->output_width >> 1; col > 0; col--) {
+ /* Do the chroma part of the calculation */
+ cb = GETJSAMPLE(*inptr1++);
+ cr = GETJSAMPLE(*inptr2++);
+ cred = Crrtab[cr];
+ cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+ cblue = Cbbtab[cb];
+ /* Fetch 4 Y values and emit 4 pixels */
+ y = GETJSAMPLE(*inptr00++);
+ outptr0[RGB_RED] = range_limit[y + cred];
+ outptr0[RGB_GREEN] = range_limit[y + cgreen];
+ outptr0[RGB_BLUE] = range_limit[y + cblue];
+ outptr0 += RGB_PIXELSIZE;
+ y = GETJSAMPLE(*inptr00++);
+ outptr0[RGB_RED] = range_limit[y + cred];
+ outptr0[RGB_GREEN] = range_limit[y + cgreen];
+ outptr0[RGB_BLUE] = range_limit[y + cblue];
+ outptr0 += RGB_PIXELSIZE;
+ y = GETJSAMPLE(*inptr01++);
+ outptr1[RGB_RED] = range_limit[y + cred];
+ outptr1[RGB_GREEN] = range_limit[y + cgreen];
+ outptr1[RGB_BLUE] = range_limit[y + cblue];
+ outptr1 += RGB_PIXELSIZE;
+ y = GETJSAMPLE(*inptr01++);
+ outptr1[RGB_RED] = range_limit[y + cred];
+ outptr1[RGB_GREEN] = range_limit[y + cgreen];
+ outptr1[RGB_BLUE] = range_limit[y + cblue];
+ outptr1 += RGB_PIXELSIZE;
+ }
+ /* If image width is odd, do the last output column separately */
+ if (cinfo->output_width & 1) {
+ cb = GETJSAMPLE(*inptr1);
+ cr = GETJSAMPLE(*inptr2);
+ cred = Crrtab[cr];
+ cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+ cblue = Cbbtab[cb];
+ y = GETJSAMPLE(*inptr00);
+ outptr0[RGB_RED] = range_limit[y + cred];
+ outptr0[RGB_GREEN] = range_limit[y + cgreen];
+ outptr0[RGB_BLUE] = range_limit[y + cblue];
+ y = GETJSAMPLE(*inptr01);
+ outptr1[RGB_RED] = range_limit[y + cred];
+ outptr1[RGB_GREEN] = range_limit[y + cgreen];
+ outptr1[RGB_BLUE] = range_limit[y + cblue];
+ }
+}
diff --git a/src/libjpeg-turbo/jdphuff.c b/src/libjpeg-turbo/jdphuff.c
new file mode 100644
index 0000000..2267809
--- /dev/null
+++ b/src/libjpeg-turbo/jdphuff.c
@@ -0,0 +1,668 @@
+/*
+ * jdphuff.c
+ *
+ * Copyright (C) 1995-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains Huffman entropy decoding routines for progressive JPEG.
+ *
+ * Much of the complexity here has to do with supporting input suspension.
+ * If the data source module demands suspension, we want to be able to back
+ * up to the start of the current MCU. To do this, we copy state variables
+ * into local working storage, and update them back to the permanent
+ * storage only upon successful completion of an MCU.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdhuff.h" /* Declarations shared with jdhuff.c */
+
+
+#ifdef D_PROGRESSIVE_SUPPORTED
+
+/*
+ * Expanded entropy decoder object for progressive Huffman decoding.
+ *
+ * The savable_state subrecord contains fields that change within an MCU,
+ * but must not be updated permanently until we complete the MCU.
+ */
+
+typedef struct {
+ unsigned int EOBRUN; /* remaining EOBs in EOBRUN */
+ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+} savable_state;
+
+/* This macro is to work around compilers with missing or broken
+ * structure assignment. You'll need to fix this code if you have
+ * such a compiler and you change MAX_COMPS_IN_SCAN.
+ */
+
+#ifndef NO_STRUCT_ASSIGN
+#define ASSIGN_STATE(dest,src) ((dest) = (src))
+#else
+#if MAX_COMPS_IN_SCAN == 4
+#define ASSIGN_STATE(dest,src) \
+ ((dest).EOBRUN = (src).EOBRUN, \
+ (dest).last_dc_val[0] = (src).last_dc_val[0], \
+ (dest).last_dc_val[1] = (src).last_dc_val[1], \
+ (dest).last_dc_val[2] = (src).last_dc_val[2], \
+ (dest).last_dc_val[3] = (src).last_dc_val[3])
+#endif
+#endif
+
+
+typedef struct {
+ struct jpeg_entropy_decoder pub; /* public fields */
+
+ /* These fields are loaded into local variables at start of each MCU.
+ * In case of suspension, we exit WITHOUT updating them.
+ */
+ bitread_perm_state bitstate; /* Bit buffer at start of MCU */
+ savable_state saved; /* Other state at start of MCU */
+
+ /* These fields are NOT loaded into local working state. */
+ unsigned int restarts_to_go; /* MCUs left in this restart interval */
+
+ /* Pointers to derived tables (these workspaces have image lifespan) */
+ d_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
+
+ d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */
+} phuff_entropy_decoder;
+
+typedef phuff_entropy_decoder * phuff_entropy_ptr;
+
+/* Forward declarations */
+METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+
+
+/*
+ * Initialize for a Huffman-compressed scan.
+ */
+
+METHODDEF(void)
+start_pass_phuff_decoder (j_decompress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ boolean is_DC_band, bad;
+ int ci, coefi, tbl;
+ int *coef_bit_ptr;
+ jpeg_component_info * compptr;
+
+ is_DC_band = (cinfo->Ss == 0);
+
+ /* Validate scan parameters */
+ bad = FALSE;
+ if (is_DC_band) {
+ if (cinfo->Se != 0)
+ bad = TRUE;
+ } else {
+ /* need not check Ss/Se < 0 since they came from unsigned bytes */
+ if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2)
+ bad = TRUE;
+ /* AC scans may have only one component */
+ if (cinfo->comps_in_scan != 1)
+ bad = TRUE;
+ }
+ if (cinfo->Ah != 0) {
+ /* Successive approximation refinement scan: must have Al = Ah-1. */
+ if (cinfo->Al != cinfo->Ah-1)
+ bad = TRUE;
+ }
+ if (cinfo->Al > 13) /* need not check for < 0 */
+ bad = TRUE;
+ /* Arguably the maximum Al value should be less than 13 for 8-bit precision,
+ * but the spec doesn't say so, and we try to be liberal about what we
+ * accept. Note: large Al values could result in out-of-range DC
+ * coefficients during early scans, leading to bizarre displays due to
+ * overflows in the IDCT math. But we won't crash.
+ */
+ if (bad)
+ ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
+ cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
+ /* Update progression status, and verify that scan order is legal.
+ * Note that inter-scan inconsistencies are treated as warnings
+ * not fatal errors ... not clear if this is right way to behave.
+ */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ int cindex = cinfo->cur_comp_info[ci]->component_index;
+ coef_bit_ptr = & cinfo->coef_bits[cindex][0];
+ if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
+ WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
+ for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
+ int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
+ if (cinfo->Ah != expected)
+ WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
+ coef_bit_ptr[coefi] = cinfo->Al;
+ }
+ }
+
+ /* Select MCU decoding routine */
+ if (cinfo->Ah == 0) {
+ if (is_DC_band)
+ entropy->pub.decode_mcu = decode_mcu_DC_first;
+ else
+ entropy->pub.decode_mcu = decode_mcu_AC_first;
+ } else {
+ if (is_DC_band)
+ entropy->pub.decode_mcu = decode_mcu_DC_refine;
+ else
+ entropy->pub.decode_mcu = decode_mcu_AC_refine;
+ }
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* Make sure requested tables are present, and compute derived tables.
+ * We may build same derived table more than once, but it's not expensive.
+ */
+ if (is_DC_band) {
+ if (cinfo->Ah == 0) { /* DC refinement needs no table */
+ tbl = compptr->dc_tbl_no;
+ jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
+ & entropy->derived_tbls[tbl]);
+ }
+ } else {
+ tbl = compptr->ac_tbl_no;
+ jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
+ & entropy->derived_tbls[tbl]);
+ /* remember the single active table */
+ entropy->ac_derived_tbl = entropy->derived_tbls[tbl];
+ }
+ /* Initialize DC predictions to 0 */
+ entropy->saved.last_dc_val[ci] = 0;
+ }
+
+ /* Initialize bitread state variables */
+ entropy->bitstate.bits_left = 0;
+ entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
+ entropy->pub.insufficient_data = FALSE;
+
+ /* Initialize private state variables */
+ entropy->saved.EOBRUN = 0;
+
+ /* Initialize restart counter */
+ entropy->restarts_to_go = cinfo->restart_interval;
+}
+
+
+/*
+ * Figure F.12: extend sign bit.
+ * On some machines, a shift and add will be faster than a table lookup.
+ */
+
+#ifdef AVOID_TABLES
+
+#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
+
+#else
+
+#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
+
+static const int extend_test[16] = /* entry n is 2**(n-1) */
+ { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
+
+static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
+ { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
+ ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
+ ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
+ ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
+
+#endif /* AVOID_TABLES */
+
+
+/*
+ * Check for a restart marker & resynchronize decoder.
+ * Returns FALSE if must suspend.
+ */
+
+LOCAL(boolean)
+process_restart (j_decompress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ int ci;
+
+ /* Throw away any unused bits remaining in bit buffer; */
+ /* include any full bytes in next_marker's count of discarded bytes */
+ cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
+ entropy->bitstate.bits_left = 0;
+
+ /* Advance past the RSTn marker */
+ if (! (*cinfo->marker->read_restart_marker) (cinfo))
+ return FALSE;
+
+ /* Re-initialize DC predictions to 0 */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+ entropy->saved.last_dc_val[ci] = 0;
+ /* Re-init EOB run count, too */
+ entropy->saved.EOBRUN = 0;
+
+ /* Reset restart counter */
+ entropy->restarts_to_go = cinfo->restart_interval;
+
+ /* Reset out-of-data flag, unless read_restart_marker left us smack up
+ * against a marker. In that case we will end up treating the next data
+ * segment as empty, and we can avoid producing bogus output pixels by
+ * leaving the flag set.
+ */
+ if (cinfo->unread_marker == 0)
+ entropy->pub.insufficient_data = FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * Huffman MCU decoding.
+ * Each of these routines decodes and returns one MCU's worth of
+ * Huffman-compressed coefficients.
+ * The coefficients are reordered from zigzag order into natural array order,
+ * but are not dequantized.
+ *
+ * The i'th block of the MCU is stored into the block pointed to by
+ * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
+ *
+ * We return FALSE if data source requested suspension. In that case no
+ * changes have been made to permanent state. (Exception: some output
+ * coefficients may already have been assigned. This is harmless for
+ * spectral selection, since we'll just re-assign them on the next call.
+ * Successive approximation AC refinement has to be more careful, however.)
+ */
+
+/*
+ * MCU decoding for DC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ int Al = cinfo->Al;
+ register int s, r;
+ int blkn, ci;
+ JBLOCKROW block;
+ BITREAD_STATE_VARS;
+ savable_state state;
+ d_derived_tbl * tbl;
+ jpeg_component_info * compptr;
+
+ /* Process restart marker if needed; may have to suspend */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! process_restart(cinfo))
+ return FALSE;
+ }
+
+ /* If we've run out of data, just leave the MCU set to zeroes.
+ * This way, we return uniform gray for the remainder of the segment.
+ */
+ if (! entropy->pub.insufficient_data) {
+
+ /* Load up working state */
+ BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+ ASSIGN_STATE(state, entropy->saved);
+
+ /* Outer loop handles each block in the MCU */
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+ tbl = entropy->derived_tbls[compptr->dc_tbl_no];
+
+ /* Decode a single block's worth of coefficients */
+
+ /* Section F.2.2.1: decode the DC coefficient difference */
+ HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
+ if (s) {
+ CHECK_BIT_BUFFER(br_state, s, return FALSE);
+ r = GET_BITS(s);
+ s = HUFF_EXTEND(r, s);
+ }
+
+ /* Convert DC difference to actual value, update last_dc_val */
+ s += state.last_dc_val[ci];
+ state.last_dc_val[ci] = s;
+ /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
+ (*block)[0] = (JCOEF) (s << Al);
+ }
+
+ /* Completed MCU, so update state */
+ BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+ ASSIGN_STATE(entropy->saved, state);
+ }
+
+ /* Account for restart interval (no-op if not using restarts) */
+ entropy->restarts_to_go--;
+
+ return TRUE;
+}
+
+
+/*
+ * MCU decoding for AC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ int Se = cinfo->Se;
+ int Al = cinfo->Al;
+ register int s, k, r;
+ unsigned int EOBRUN;
+ JBLOCKROW block;
+ BITREAD_STATE_VARS;
+ d_derived_tbl * tbl;
+
+ /* Process restart marker if needed; may have to suspend */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! process_restart(cinfo))
+ return FALSE;
+ }
+
+ /* If we've run out of data, just leave the MCU set to zeroes.
+ * This way, we return uniform gray for the remainder of the segment.
+ */
+ if (! entropy->pub.insufficient_data) {
+
+ /* Load up working state.
+ * We can avoid loading/saving bitread state if in an EOB run.
+ */
+ EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
+
+ /* There is always only one block per MCU */
+
+ if (EOBRUN > 0) /* if it's a band of zeroes... */
+ EOBRUN--; /* ...process it now (we do nothing) */
+ else {
+ BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+ block = MCU_data[0];
+ tbl = entropy->ac_derived_tbl;
+
+ for (k = cinfo->Ss; k <= Se; k++) {
+ HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
+ r = s >> 4;
+ s &= 15;
+ if (s) {
+ k += r;
+ CHECK_BIT_BUFFER(br_state, s, return FALSE);
+ r = GET_BITS(s);
+ s = HUFF_EXTEND(r, s);
+ /* Scale and output coefficient in natural (dezigzagged) order */
+ (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
+ } else {
+ if (r == 15) { /* ZRL */
+ k += 15; /* skip 15 zeroes in band */
+ } else { /* EOBr, run length is 2^r + appended bits */
+ EOBRUN = 1 << r;
+ if (r) { /* EOBr, r > 0 */
+ CHECK_BIT_BUFFER(br_state, r, return FALSE);
+ r = GET_BITS(r);
+ EOBRUN += r;
+ }
+ EOBRUN--; /* this band is processed at this moment */
+ break; /* force end-of-band */
+ }
+ }
+ }
+
+ BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+ }
+
+ /* Completed MCU, so update state */
+ entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
+ }
+
+ /* Account for restart interval (no-op if not using restarts) */
+ entropy->restarts_to_go--;
+
+ return TRUE;
+}
+
+
+/*
+ * MCU decoding for DC successive approximation refinement scan.
+ * Note: we assume such scans can be multi-component, although the spec
+ * is not very clear on the point.
+ */
+
+METHODDEF(boolean)
+decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
+ int blkn;
+ JBLOCKROW block;
+ BITREAD_STATE_VARS;
+
+ /* Process restart marker if needed; may have to suspend */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! process_restart(cinfo))
+ return FALSE;
+ }
+
+ /* Not worth the cycles to check insufficient_data here,
+ * since we will not change the data anyway if we read zeroes.
+ */
+
+ /* Load up working state */
+ BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+
+ /* Outer loop handles each block in the MCU */
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+
+ /* Encoded data is simply the next bit of the two's-complement DC value */
+ CHECK_BIT_BUFFER(br_state, 1, return FALSE);
+ if (GET_BITS(1))
+ (*block)[0] |= p1;
+ /* Note: since we use |=, repeating the assignment later is safe */
+ }
+
+ /* Completed MCU, so update state */
+ BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+
+ /* Account for restart interval (no-op if not using restarts) */
+ entropy->restarts_to_go--;
+
+ return TRUE;
+}
+
+
+/*
+ * MCU decoding for AC successive approximation refinement scan.
+ */
+
+METHODDEF(boolean)
+decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ int Se = cinfo->Se;
+ int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
+ int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
+ register int s, k, r;
+ unsigned int EOBRUN;
+ JBLOCKROW block;
+ JCOEFPTR thiscoef;
+ BITREAD_STATE_VARS;
+ d_derived_tbl * tbl;
+ int num_newnz;
+ int newnz_pos[DCTSIZE2];
+
+ /* Process restart marker if needed; may have to suspend */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! process_restart(cinfo))
+ return FALSE;
+ }
+
+ /* If we've run out of data, don't modify the MCU.
+ */
+ if (! entropy->pub.insufficient_data) {
+
+ /* Load up working state */
+ BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+ EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
+
+ /* There is always only one block per MCU */
+ block = MCU_data[0];
+ tbl = entropy->ac_derived_tbl;
+
+ /* If we are forced to suspend, we must undo the assignments to any newly
+ * nonzero coefficients in the block, because otherwise we'd get confused
+ * next time about which coefficients were already nonzero.
+ * But we need not undo addition of bits to already-nonzero coefficients;
+ * instead, we can test the current bit to see if we already did it.
+ */
+ num_newnz = 0;
+
+ /* initialize coefficient loop counter to start of band */
+ k = cinfo->Ss;
+
+ if (EOBRUN == 0) {
+ for (; k <= Se; k++) {
+ HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
+ r = s >> 4;
+ s &= 15;
+ if (s) {
+ if (s != 1) /* size of new coef should always be 1 */
+ WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
+ CHECK_BIT_BUFFER(br_state, 1, goto undoit);
+ if (GET_BITS(1))
+ s = p1; /* newly nonzero coef is positive */
+ else
+ s = m1; /* newly nonzero coef is negative */
+ } else {
+ if (r != 15) {
+ EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */
+ if (r) {
+ CHECK_BIT_BUFFER(br_state, r, goto undoit);
+ r = GET_BITS(r);
+ EOBRUN += r;
+ }
+ break; /* rest of block is handled by EOB logic */
+ }
+ /* note s = 0 for processing ZRL */
+ }
+ /* Advance over already-nonzero coefs and r still-zero coefs,
+ * appending correction bits to the nonzeroes. A correction bit is 1
+ * if the absolute value of the coefficient must be increased.
+ */
+ do {
+ thiscoef = *block + jpeg_natural_order[k];
+ if (*thiscoef != 0) {
+ CHECK_BIT_BUFFER(br_state, 1, goto undoit);
+ if (GET_BITS(1)) {
+ if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
+ if (*thiscoef >= 0)
+ *thiscoef += p1;
+ else
+ *thiscoef += m1;
+ }
+ }
+ } else {
+ if (--r < 0)
+ break; /* reached target zero coefficient */
+ }
+ k++;
+ } while (k <= Se);
+ if (s) {
+ int pos = jpeg_natural_order[k];
+ /* Output newly nonzero coefficient */
+ (*block)[pos] = (JCOEF) s;
+ /* Remember its position in case we have to suspend */
+ newnz_pos[num_newnz++] = pos;
+ }
+ }
+ }
+
+ if (EOBRUN > 0) {
+ /* Scan any remaining coefficient positions after the end-of-band
+ * (the last newly nonzero coefficient, if any). Append a correction
+ * bit to each already-nonzero coefficient. A correction bit is 1
+ * if the absolute value of the coefficient must be increased.
+ */
+ for (; k <= Se; k++) {
+ thiscoef = *block + jpeg_natural_order[k];
+ if (*thiscoef != 0) {
+ CHECK_BIT_BUFFER(br_state, 1, goto undoit);
+ if (GET_BITS(1)) {
+ if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
+ if (*thiscoef >= 0)
+ *thiscoef += p1;
+ else
+ *thiscoef += m1;
+ }
+ }
+ }
+ }
+ /* Count one block completed in EOB run */
+ EOBRUN--;
+ }
+
+ /* Completed MCU, so update state */
+ BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+ entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
+ }
+
+ /* Account for restart interval (no-op if not using restarts) */
+ entropy->restarts_to_go--;
+
+ return TRUE;
+
+undoit:
+ /* Re-zero any output coefficients that we made newly nonzero */
+ while (num_newnz > 0)
+ (*block)[newnz_pos[--num_newnz]] = 0;
+
+ return FALSE;
+}
+
+
+/*
+ * Module initialization routine for progressive Huffman entropy decoding.
+ */
+
+GLOBAL(void)
+jinit_phuff_decoder (j_decompress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy;
+ int *coef_bit_ptr;
+ int ci, i;
+
+ entropy = (phuff_entropy_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(phuff_entropy_decoder));
+ cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
+ entropy->pub.start_pass = start_pass_phuff_decoder;
+
+ /* Mark derived tables unallocated */
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ entropy->derived_tbls[i] = NULL;
+ }
+
+ /* Create progression status table */
+ cinfo->coef_bits = (int (*)[DCTSIZE2])
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ cinfo->num_components*DCTSIZE2*SIZEOF(int));
+ coef_bit_ptr = & cinfo->coef_bits[0][0];
+ for (ci = 0; ci < cinfo->num_components; ci++)
+ for (i = 0; i < DCTSIZE2; i++)
+ *coef_bit_ptr++ = -1;
+}
+
+#endif /* D_PROGRESSIVE_SUPPORTED */
diff --git a/src/libjpeg-turbo/jdpostct.c b/src/libjpeg-turbo/jdpostct.c
new file mode 100644
index 0000000..571563d
--- /dev/null
+++ b/src/libjpeg-turbo/jdpostct.c
@@ -0,0 +1,290 @@
+/*
+ * jdpostct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the decompression postprocessing controller.
+ * This controller manages the upsampling, color conversion, and color
+ * quantization/reduction steps; specifically, it controls the buffering
+ * between upsample/color conversion and color quantization/reduction.
+ *
+ * If no color quantization/reduction is required, then this module has no
+ * work to do, and it just hands off to the upsample/color conversion code.
+ * An integrated upsample/convert/quantize process would replace this module
+ * entirely.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_d_post_controller pub; /* public fields */
+
+ /* Color quantization source buffer: this holds output data from
+ * the upsample/color conversion step to be passed to the quantizer.
+ * For two-pass color quantization, we need a full-image buffer;
+ * for one-pass operation, a strip buffer is sufficient.
+ */
+ jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */
+ JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */
+ JDIMENSION strip_height; /* buffer size in rows */
+ /* for two-pass mode only: */
+ JDIMENSION starting_row; /* row # of first row in current strip */
+ JDIMENSION next_row; /* index of next row to fill/empty in strip */
+} my_post_controller;
+
+typedef my_post_controller * my_post_ptr;
+
+
+/* Forward declarations */
+METHODDEF(void) post_process_1pass
+ JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+#ifdef QUANT_2PASS_SUPPORTED
+METHODDEF(void) post_process_prepass
+ JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+METHODDEF(void) post_process_2pass
+ JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+#endif
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_post_ptr post = (my_post_ptr) cinfo->post;
+
+ switch (pass_mode) {
+ case JBUF_PASS_THRU:
+ if (cinfo->quantize_colors) {
+ /* Single-pass processing with color quantization. */
+ post->pub.post_process_data = post_process_1pass;
+ /* We could be doing buffered-image output before starting a 2-pass
+ * color quantization; in that case, jinit_d_post_controller did not
+ * allocate a strip buffer. Use the virtual-array buffer as workspace.
+ */
+ if (post->buffer == NULL) {
+ post->buffer = (*cinfo->mem->access_virt_sarray)
+ ((j_common_ptr) cinfo, post->whole_image,
+ (JDIMENSION) 0, post->strip_height, TRUE);
+ }
+ } else {
+ /* For single-pass processing without color quantization,
+ * I have no work to do; just call the upsampler directly.
+ */
+ post->pub.post_process_data = cinfo->upsample->upsample;
+ }
+ break;
+#ifdef QUANT_2PASS_SUPPORTED
+ case JBUF_SAVE_AND_PASS:
+ /* First pass of 2-pass quantization */
+ if (post->whole_image == NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ post->pub.post_process_data = post_process_prepass;
+ break;
+ case JBUF_CRANK_DEST:
+ /* Second pass of 2-pass quantization */
+ if (post->whole_image == NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ post->pub.post_process_data = post_process_2pass;
+ break;
+#endif /* QUANT_2PASS_SUPPORTED */
+ default:
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ break;
+ }
+ post->starting_row = post->next_row = 0;
+}
+
+
+/*
+ * Process some data in the one-pass (strip buffer) case.
+ * This is used for color precision reduction as well as one-pass quantization.
+ */
+
+METHODDEF(void)
+post_process_1pass (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_post_ptr post = (my_post_ptr) cinfo->post;
+ JDIMENSION num_rows, max_rows;
+
+ /* Fill the buffer, but not more than what we can dump out in one go. */
+ /* Note we rely on the upsampler to detect bottom of image. */
+ max_rows = out_rows_avail - *out_row_ctr;
+ if (max_rows > post->strip_height)
+ max_rows = post->strip_height;
+ num_rows = 0;
+ (*cinfo->upsample->upsample) (cinfo,
+ input_buf, in_row_group_ctr, in_row_groups_avail,
+ post->buffer, &num_rows, max_rows);
+ /* Quantize and emit data. */
+ (*cinfo->cquantize->color_quantize) (cinfo,
+ post->buffer, output_buf + *out_row_ctr, (int) num_rows);
+ *out_row_ctr += num_rows;
+}
+
+
+#ifdef QUANT_2PASS_SUPPORTED
+
+/*
+ * Process some data in the first pass of 2-pass quantization.
+ */
+
+METHODDEF(void)
+post_process_prepass (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_post_ptr post = (my_post_ptr) cinfo->post;
+ JDIMENSION old_next_row, num_rows;
+
+ /* Reposition virtual buffer if at start of strip. */
+ if (post->next_row == 0) {
+ post->buffer = (*cinfo->mem->access_virt_sarray)
+ ((j_common_ptr) cinfo, post->whole_image,
+ post->starting_row, post->strip_height, TRUE);
+ }
+
+ /* Upsample some data (up to a strip height's worth). */
+ old_next_row = post->next_row;
+ (*cinfo->upsample->upsample) (cinfo,
+ input_buf, in_row_group_ctr, in_row_groups_avail,
+ post->buffer, &post->next_row, post->strip_height);
+
+ /* Allow quantizer to scan new data. No data is emitted, */
+ /* but we advance out_row_ctr so outer loop can tell when we're done. */
+ if (post->next_row > old_next_row) {
+ num_rows = post->next_row - old_next_row;
+ (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
+ (JSAMPARRAY) NULL, (int) num_rows);
+ *out_row_ctr += num_rows;
+ }
+
+ /* Advance if we filled the strip. */
+ if (post->next_row >= post->strip_height) {
+ post->starting_row += post->strip_height;
+ post->next_row = 0;
+ }
+}
+
+
+/*
+ * Process some data in the second pass of 2-pass quantization.
+ */
+
+METHODDEF(void)
+post_process_2pass (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_post_ptr post = (my_post_ptr) cinfo->post;
+ JDIMENSION num_rows, max_rows;
+
+ /* Reposition virtual buffer if at start of strip. */
+ if (post->next_row == 0) {
+ post->buffer = (*cinfo->mem->access_virt_sarray)
+ ((j_common_ptr) cinfo, post->whole_image,
+ post->starting_row, post->strip_height, FALSE);
+ }
+
+ /* Determine number of rows to emit. */
+ num_rows = post->strip_height - post->next_row; /* available in strip */
+ max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
+ if (num_rows > max_rows)
+ num_rows = max_rows;
+ /* We have to check bottom of image here, can't depend on upsampler. */
+ max_rows = cinfo->output_height - post->starting_row;
+ if (num_rows > max_rows)
+ num_rows = max_rows;
+
+ /* Quantize and emit data. */
+ (*cinfo->cquantize->color_quantize) (cinfo,
+ post->buffer + post->next_row, output_buf + *out_row_ctr,
+ (int) num_rows);
+ *out_row_ctr += num_rows;
+
+ /* Advance if we filled the strip. */
+ post->next_row += num_rows;
+ if (post->next_row >= post->strip_height) {
+ post->starting_row += post->strip_height;
+ post->next_row = 0;
+ }
+}
+
+#endif /* QUANT_2PASS_SUPPORTED */
+
+
+/*
+ * Initialize postprocessing controller.
+ */
+
+GLOBAL(void)
+jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
+{
+ my_post_ptr post;
+
+ post = (my_post_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_post_controller));
+ cinfo->post = (struct jpeg_d_post_controller *) post;
+ post->pub.start_pass = start_pass_dpost;
+ post->whole_image = NULL; /* flag for no virtual arrays */
+ post->buffer = NULL; /* flag for no strip buffer */
+
+ /* Create the quantization buffer, if needed */
+ if (cinfo->quantize_colors) {
+ /* The buffer strip height is max_v_samp_factor, which is typically
+ * an efficient number of rows for upsampling to return.
+ * (In the presence of output rescaling, we might want to be smarter?)
+ */
+ post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
+ if (need_full_buffer) {
+ /* Two-pass color quantization: need full-image storage. */
+ /* We round up the number of rows to a multiple of the strip height. */
+#ifdef QUANT_2PASS_SUPPORTED
+ post->whole_image = (*cinfo->mem->request_virt_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
+ cinfo->output_width * cinfo->out_color_components,
+ (JDIMENSION) jround_up((long) cinfo->output_height,
+ (long) post->strip_height),
+ post->strip_height);
+#else
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif /* QUANT_2PASS_SUPPORTED */
+ } else {
+ /* One-pass color quantization: just make a strip buffer. */
+ post->buffer = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ cinfo->output_width * cinfo->out_color_components,
+ post->strip_height);
+ }
+ }
+}
diff --git a/src/libjpeg-turbo/jdsample.c b/src/libjpeg-turbo/jdsample.c
new file mode 100644
index 0000000..1864dd6
--- /dev/null
+++ b/src/libjpeg-turbo/jdsample.c
@@ -0,0 +1,496 @@
+/*
+ * jdsample.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright (C) 2010, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains upsampling routines.
+ *
+ * Upsampling input data is counted in "row groups". A row group
+ * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
+ * sample rows of each component. Upsampling will normally produce
+ * max_v_samp_factor pixel rows from each row group (but this could vary
+ * if the upsampler is applying a scale factor of its own).
+ *
+ * An excellent reference for image resampling is
+ * Digital Image Warping, George Wolberg, 1990.
+ * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jsimd.h"
+#include "jpegcomp.h"
+
+
+/* Pointer to routine to upsample a single component */
+typedef JMETHOD(void, upsample1_ptr,
+ (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_upsampler pub; /* public fields */
+
+ /* Color conversion buffer. When using separate upsampling and color
+ * conversion steps, this buffer holds one upsampled row group until it
+ * has been color converted and output.
+ * Note: we do not allocate any storage for component(s) which are full-size,
+ * ie do not need rescaling. The corresponding entry of color_buf[] is
+ * simply set to point to the input data array, thereby avoiding copying.
+ */
+ JSAMPARRAY color_buf[MAX_COMPONENTS];
+
+ /* Per-component upsampling method pointers */
+ upsample1_ptr methods[MAX_COMPONENTS];
+
+ int next_row_out; /* counts rows emitted from color_buf */
+ JDIMENSION rows_to_go; /* counts rows remaining in image */
+
+ /* Height of an input row group for each component. */
+ int rowgroup_height[MAX_COMPONENTS];
+
+ /* These arrays save pixel expansion factors so that int_expand need not
+ * recompute them each time. They are unused for other upsampling methods.
+ */
+ UINT8 h_expand[MAX_COMPONENTS];
+ UINT8 v_expand[MAX_COMPONENTS];
+} my_upsampler;
+
+typedef my_upsampler * my_upsample_ptr;
+
+
+/*
+ * Initialize for an upsampling pass.
+ */
+
+METHODDEF(void)
+start_pass_upsample (j_decompress_ptr cinfo)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+
+ /* Mark the conversion buffer empty */
+ upsample->next_row_out = cinfo->max_v_samp_factor;
+ /* Initialize total-height counter for detecting bottom of image */
+ upsample->rows_to_go = cinfo->output_height;
+}
+
+
+/*
+ * Control routine to do upsampling (and color conversion).
+ *
+ * In this version we upsample each component independently.
+ * We upsample one row group into the conversion buffer, then apply
+ * color conversion a row at a time.
+ */
+
+METHODDEF(void)
+sep_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ int ci;
+ jpeg_component_info * compptr;
+ JDIMENSION num_rows;
+
+ /* Fill the conversion buffer, if it's empty */
+ if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Invoke per-component upsample method. Notice we pass a POINTER
+ * to color_buf[ci], so that fullsize_upsample can change it.
+ */
+ (*upsample->methods[ci]) (cinfo, compptr,
+ input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
+ upsample->color_buf + ci);
+ }
+ upsample->next_row_out = 0;
+ }
+
+ /* Color-convert and emit rows */
+
+ /* How many we have in the buffer: */
+ num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
+ /* Not more than the distance to the end of the image. Need this test
+ * in case the image height is not a multiple of max_v_samp_factor:
+ */
+ if (num_rows > upsample->rows_to_go)
+ num_rows = upsample->rows_to_go;
+ /* And not more than what the client can accept: */
+ out_rows_avail -= *out_row_ctr;
+ if (num_rows > out_rows_avail)
+ num_rows = out_rows_avail;
+
+ (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
+ (JDIMENSION) upsample->next_row_out,
+ output_buf + *out_row_ctr,
+ (int) num_rows);
+
+ /* Adjust counts */
+ *out_row_ctr += num_rows;
+ upsample->rows_to_go -= num_rows;
+ upsample->next_row_out += num_rows;
+ /* When the buffer is emptied, declare this input row group consumed */
+ if (upsample->next_row_out >= cinfo->max_v_samp_factor)
+ (*in_row_group_ctr)++;
+}
+
+
+/*
+ * These are the routines invoked by sep_upsample to upsample pixel values
+ * of a single component. One row group is processed per call.
+ */
+
+
+/*
+ * For full-size components, we just make color_buf[ci] point at the
+ * input buffer, and thus avoid copying any data. Note that this is
+ * safe only because sep_upsample doesn't declare the input row group
+ * "consumed" until we are done color converting and emitting it.
+ */
+
+METHODDEF(void)
+fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ *output_data_ptr = input_data;
+}
+
+
+/*
+ * This is a no-op version used for "uninteresting" components.
+ * These components will not be referenced by color conversion.
+ */
+
+METHODDEF(void)
+noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ *output_data_ptr = NULL; /* safety check */
+}
+
+
+/*
+ * This version handles any integral sampling ratios.
+ * This is not used for typical JPEG files, so it need not be fast.
+ * Nor, for that matter, is it particularly accurate: the algorithm is
+ * simple replication of the input pixel onto the corresponding output
+ * pixels. The hi-falutin sampling literature refers to this as a
+ * "box filter". A box filter tends to introduce visible artifacts,
+ * so if you are actually going to use 3:1 or 4:1 sampling ratios
+ * you would be well advised to improve this code.
+ */
+
+METHODDEF(void)
+int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ JSAMPARRAY output_data = *output_data_ptr;
+ register JSAMPROW inptr, outptr;
+ register JSAMPLE invalue;
+ register int h;
+ JSAMPROW outend;
+ int h_expand, v_expand;
+ int inrow, outrow;
+
+ h_expand = upsample->h_expand[compptr->component_index];
+ v_expand = upsample->v_expand[compptr->component_index];
+
+ inrow = outrow = 0;
+ while (outrow < cinfo->max_v_samp_factor) {
+ /* Generate one output row with proper horizontal expansion */
+ inptr = input_data[inrow];
+ outptr = output_data[outrow];
+ outend = outptr + cinfo->output_width;
+ while (outptr < outend) {
+ invalue = *inptr++; /* don't need GETJSAMPLE() here */
+ for (h = h_expand; h > 0; h--) {
+ *outptr++ = invalue;
+ }
+ }
+ /* Generate any additional output rows by duplicating the first one */
+ if (v_expand > 1) {
+ jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
+ v_expand-1, cinfo->output_width);
+ }
+ inrow++;
+ outrow += v_expand;
+ }
+}
+
+
+/*
+ * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
+ * It's still a box filter.
+ */
+
+METHODDEF(void)
+h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ JSAMPARRAY output_data = *output_data_ptr;
+ register JSAMPROW inptr, outptr;
+ register JSAMPLE invalue;
+ JSAMPROW outend;
+ int inrow;
+
+ for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
+ inptr = input_data[inrow];
+ outptr = output_data[inrow];
+ outend = outptr + cinfo->output_width;
+ while (outptr < outend) {
+ invalue = *inptr++; /* don't need GETJSAMPLE() here */
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ }
+ }
+}
+
+
+/*
+ * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
+ * It's still a box filter.
+ */
+
+METHODDEF(void)
+h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ JSAMPARRAY output_data = *output_data_ptr;
+ register JSAMPROW inptr, outptr;
+ register JSAMPLE invalue;
+ JSAMPROW outend;
+ int inrow, outrow;
+
+ inrow = outrow = 0;
+ while (outrow < cinfo->max_v_samp_factor) {
+ inptr = input_data[inrow];
+ outptr = output_data[outrow];
+ outend = outptr + cinfo->output_width;
+ while (outptr < outend) {
+ invalue = *inptr++; /* don't need GETJSAMPLE() here */
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ }
+ jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
+ 1, cinfo->output_width);
+ inrow++;
+ outrow += 2;
+ }
+}
+
+
+/*
+ * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
+ *
+ * The upsampling algorithm is linear interpolation between pixel centers,
+ * also known as a "triangle filter". This is a good compromise between
+ * speed and visual quality. The centers of the output pixels are 1/4 and 3/4
+ * of the way between input pixel centers.
+ *
+ * A note about the "bias" calculations: when rounding fractional values to
+ * integer, we do not want to always round 0.5 up to the next integer.
+ * If we did that, we'd introduce a noticeable bias towards larger values.
+ * Instead, this code is arranged so that 0.5 will be rounded up or down at
+ * alternate pixel locations (a simple ordered dither pattern).
+ */
+
+METHODDEF(void)
+h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ JSAMPARRAY output_data = *output_data_ptr;
+ register JSAMPROW inptr, outptr;
+ register int invalue;
+ register JDIMENSION colctr;
+ int inrow;
+
+ for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
+ inptr = input_data[inrow];
+ outptr = output_data[inrow];
+ /* Special case for first column */
+ invalue = GETJSAMPLE(*inptr++);
+ *outptr++ = (JSAMPLE) invalue;
+ *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
+
+ for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
+ /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
+ invalue = GETJSAMPLE(*inptr++) * 3;
+ *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
+ *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
+ }
+
+ /* Special case for last column */
+ invalue = GETJSAMPLE(*inptr);
+ *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
+ *outptr++ = (JSAMPLE) invalue;
+ }
+}
+
+
+/*
+ * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
+ * Again a triangle filter; see comments for h2v1 case, above.
+ *
+ * It is OK for us to reference the adjacent input rows because we demanded
+ * context from the main buffer controller (see initialization code).
+ */
+
+METHODDEF(void)
+h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ JSAMPARRAY output_data = *output_data_ptr;
+ register JSAMPROW inptr0, inptr1, outptr;
+#if BITS_IN_JSAMPLE == 8
+ register int thiscolsum, lastcolsum, nextcolsum;
+#else
+ register INT32 thiscolsum, lastcolsum, nextcolsum;
+#endif
+ register JDIMENSION colctr;
+ int inrow, outrow, v;
+
+ inrow = outrow = 0;
+ while (outrow < cinfo->max_v_samp_factor) {
+ for (v = 0; v < 2; v++) {
+ /* inptr0 points to nearest input row, inptr1 points to next nearest */
+ inptr0 = input_data[inrow];
+ if (v == 0) /* next nearest is row above */
+ inptr1 = input_data[inrow-1];
+ else /* next nearest is row below */
+ inptr1 = input_data[inrow+1];
+ outptr = output_data[outrow++];
+
+ /* Special case for first column */
+ thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
+ nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
+ *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
+ *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
+ lastcolsum = thiscolsum; thiscolsum = nextcolsum;
+
+ for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
+ /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
+ /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
+ nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
+ *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
+ *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
+ lastcolsum = thiscolsum; thiscolsum = nextcolsum;
+ }
+
+ /* Special case for last column */
+ *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
+ *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
+ }
+ inrow++;
+ }
+}
+
+
+/*
+ * Module initialization routine for upsampling.
+ */
+
+GLOBAL(void)
+jinit_upsampler (j_decompress_ptr cinfo)
+{
+ my_upsample_ptr upsample;
+ int ci;
+ jpeg_component_info * compptr;
+ boolean need_buffer, do_fancy;
+ int h_in_group, v_in_group, h_out_group, v_out_group;
+
+ upsample = (my_upsample_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_upsampler));
+ cinfo->upsample = (struct jpeg_upsampler *) upsample;
+ upsample->pub.start_pass = start_pass_upsample;
+ upsample->pub.upsample = sep_upsample;
+ upsample->pub.need_context_rows = FALSE; /* until we find out differently */
+
+ if (cinfo->CCIR601_sampling) /* this isn't supported */
+ ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
+
+ /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
+ * so don't ask for it.
+ */
+ do_fancy = cinfo->do_fancy_upsampling && cinfo->_min_DCT_scaled_size > 1;
+
+ /* Verify we can handle the sampling factors, select per-component methods,
+ * and create storage as needed.
+ */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Compute size of an "input group" after IDCT scaling. This many samples
+ * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
+ */
+ h_in_group = (compptr->h_samp_factor * compptr->_DCT_scaled_size) /
+ cinfo->_min_DCT_scaled_size;
+ v_in_group = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
+ cinfo->_min_DCT_scaled_size;
+ h_out_group = cinfo->max_h_samp_factor;
+ v_out_group = cinfo->max_v_samp_factor;
+ upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
+ need_buffer = TRUE;
+ if (! compptr->component_needed) {
+ /* Don't bother to upsample an uninteresting component. */
+ upsample->methods[ci] = noop_upsample;
+ need_buffer = FALSE;
+ } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
+ /* Fullsize components can be processed without any work. */
+ upsample->methods[ci] = fullsize_upsample;
+ need_buffer = FALSE;
+ } else if (h_in_group * 2 == h_out_group &&
+ v_in_group == v_out_group) {
+ /* Special cases for 2h1v upsampling */
+ if (do_fancy && compptr->downsampled_width > 2) {
+ if (jsimd_can_h2v1_fancy_upsample())
+ upsample->methods[ci] = jsimd_h2v1_fancy_upsample;
+ else
+ upsample->methods[ci] = h2v1_fancy_upsample;
+ } else {
+ if (jsimd_can_h2v1_upsample())
+ upsample->methods[ci] = jsimd_h2v1_upsample;
+ else
+ upsample->methods[ci] = h2v1_upsample;
+ }
+ } else if (h_in_group * 2 == h_out_group &&
+ v_in_group * 2 == v_out_group) {
+ /* Special cases for 2h2v upsampling */
+ if (do_fancy && compptr->downsampled_width > 2) {
+ if (jsimd_can_h2v2_fancy_upsample())
+ upsample->methods[ci] = jsimd_h2v2_fancy_upsample;
+ else
+ upsample->methods[ci] = h2v2_fancy_upsample;
+ upsample->pub.need_context_rows = TRUE;
+ } else {
+ if (jsimd_can_h2v2_upsample())
+ upsample->methods[ci] = jsimd_h2v2_upsample;
+ else
+ upsample->methods[ci] = h2v2_upsample;
+ }
+ } else if ((h_out_group % h_in_group) == 0 &&
+ (v_out_group % v_in_group) == 0) {
+ /* Generic integral-factors upsampling method */
+ upsample->methods[ci] = int_upsample;
+ upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
+ upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
+ } else
+ ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
+ if (need_buffer) {
+ upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (JDIMENSION) jround_up((long) cinfo->output_width,
+ (long) cinfo->max_h_samp_factor),
+ (JDIMENSION) cinfo->max_v_samp_factor);
+ }
+ }
+}
diff --git a/src/libjpeg-turbo/jdtrans.c b/src/libjpeg-turbo/jdtrans.c
new file mode 100644
index 0000000..f0cd0ae
--- /dev/null
+++ b/src/libjpeg-turbo/jdtrans.c
@@ -0,0 +1,152 @@
+/*
+ * jdtrans.c
+ *
+ * Copyright (C) 1995-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains library routines for transcoding decompression,
+ * that is, reading raw DCT coefficient arrays from an input JPEG file.
+ * The routines in jdapimin.c will also be needed by a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Forward declarations */
+LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
+
+
+/*
+ * Read the coefficient arrays from a JPEG file.
+ * jpeg_read_header must be completed before calling this.
+ *
+ * The entire image is read into a set of virtual coefficient-block arrays,
+ * one per component. The return value is a pointer to the array of
+ * virtual-array descriptors. These can be manipulated directly via the
+ * JPEG memory manager, or handed off to jpeg_write_coefficients().
+ * To release the memory occupied by the virtual arrays, call
+ * jpeg_finish_decompress() when done with the data.
+ *
+ * An alternative usage is to simply obtain access to the coefficient arrays
+ * during a buffered-image-mode decompression operation. This is allowed
+ * after any jpeg_finish_output() call. The arrays can be accessed until
+ * jpeg_finish_decompress() is called. (Note that any call to the library
+ * may reposition the arrays, so don't rely on access_virt_barray() results
+ * to stay valid across library calls.)
+ *
+ * Returns NULL if suspended. This case need be checked only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(jvirt_barray_ptr *)
+jpeg_read_coefficients (j_decompress_ptr cinfo)
+{
+ if (cinfo->global_state == DSTATE_READY) {
+ /* First call: initialize active modules */
+ transdecode_master_selection(cinfo);
+ cinfo->global_state = DSTATE_RDCOEFS;
+ }
+ if (cinfo->global_state == DSTATE_RDCOEFS) {
+ /* Absorb whole file into the coef buffer */
+ for (;;) {
+ int retcode;
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL)
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ /* Absorb some more input */
+ retcode = (*cinfo->inputctl->consume_input) (cinfo);
+ if (retcode == JPEG_SUSPENDED)
+ return NULL;
+ if (retcode == JPEG_REACHED_EOI)
+ break;
+ /* Advance progress counter if appropriate */
+ if (cinfo->progress != NULL &&
+ (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
+ if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
+ /* startup underestimated number of scans; ratchet up one scan */
+ cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
+ }
+ }
+ }
+ /* Set state so that jpeg_finish_decompress does the right thing */
+ cinfo->global_state = DSTATE_STOPPING;
+ }
+ /* At this point we should be in state DSTATE_STOPPING if being used
+ * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
+ * to the coefficients during a full buffered-image-mode decompression.
+ */
+ if ((cinfo->global_state == DSTATE_STOPPING ||
+ cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
+ return cinfo->coef->coef_arrays;
+ }
+ /* Oops, improper usage */
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ return NULL; /* keep compiler happy */
+}
+
+
+/*
+ * Master selection of decompression modules for transcoding.
+ * This substitutes for jdmaster.c's initialization of the full decompressor.
+ */
+
+LOCAL(void)
+transdecode_master_selection (j_decompress_ptr cinfo)
+{
+ /* This is effectively a buffered-image operation. */
+ cinfo->buffered_image = TRUE;
+
+#if JPEG_LIB_VERSION >= 80
+ /* Compute output image dimensions and related values. */
+ jpeg_core_output_dimensions(cinfo);
+#endif
+
+ /* Entropy decoding: either Huffman or arithmetic coding. */
+ if (cinfo->arith_code) {
+#ifdef D_ARITH_CODING_SUPPORTED
+ jinit_arith_decoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+#endif
+ } else {
+ if (cinfo->progressive_mode) {
+#ifdef D_PROGRESSIVE_SUPPORTED
+ jinit_phuff_decoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else
+ jinit_huff_decoder(cinfo);
+ }
+
+ /* Always get a full-image coefficient buffer. */
+ jinit_d_coef_controller(cinfo, TRUE);
+
+ /* We can now tell the memory manager to allocate virtual arrays. */
+ (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+ /* Initialize input side of decompressor to consume first scan. */
+ (*cinfo->inputctl->start_input_pass) (cinfo);
+
+ /* Initialize progress monitoring. */
+ if (cinfo->progress != NULL) {
+ int nscans;
+ /* Estimate number of scans to set pass_limit. */
+ if (cinfo->progressive_mode) {
+ /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
+ nscans = 2 + 3 * cinfo->num_components;
+ } else if (cinfo->inputctl->has_multiple_scans) {
+ /* For a nonprogressive multiscan file, estimate 1 scan per component. */
+ nscans = cinfo->num_components;
+ } else {
+ nscans = 1;
+ }
+ cinfo->progress->pass_counter = 0L;
+ cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
+ cinfo->progress->completed_passes = 0;
+ cinfo->progress->total_passes = 1;
+ }
+}
diff --git a/src/libjpeg-turbo/jerror.c b/src/libjpeg-turbo/jerror.c
new file mode 100644
index 0000000..3da7be8
--- /dev/null
+++ b/src/libjpeg-turbo/jerror.c
@@ -0,0 +1,252 @@
+/*
+ * jerror.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains simple error-reporting and trace-message routines.
+ * These are suitable for Unix-like systems and others where writing to
+ * stderr is the right thing to do. Many applications will want to replace
+ * some or all of these routines.
+ *
+ * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
+ * you get a Windows-specific hack to display error messages in a dialog box.
+ * It ain't much, but it beats dropping error messages into the bit bucket,
+ * which is what happens to output to stderr under most Windows C compilers.
+ *
+ * These routines are used by both the compression and decompression code.
+ */
+
+/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jversion.h"
+#include "jerror.h"
+
+#ifdef USE_WINDOWS_MESSAGEBOX
+#include <windows.h>
+#endif
+
+#ifndef EXIT_FAILURE /* define exit() codes if not provided */
+#define EXIT_FAILURE 1
+#endif
+
+
+/*
+ * Create the message string table.
+ * We do this from the master message list in jerror.h by re-reading
+ * jerror.h with a suitable definition for macro JMESSAGE.
+ * The message table is made an external symbol just in case any applications
+ * want to refer to it directly.
+ */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_std_message_table jMsgTable
+#endif
+
+#define JMESSAGE(code,string) string ,
+
+const char * const jpeg_std_message_table[] = {
+#include "jerror.h"
+ NULL
+};
+
+
+/*
+ * Error exit handler: must not return to caller.
+ *
+ * Applications may override this if they want to get control back after
+ * an error. Typically one would longjmp somewhere instead of exiting.
+ * The setjmp buffer can be made a private field within an expanded error
+ * handler object. Note that the info needed to generate an error message
+ * is stored in the error object, so you can generate the message now or
+ * later, at your convenience.
+ * You should make sure that the JPEG object is cleaned up (with jpeg_abort
+ * or jpeg_destroy) at some point.
+ */
+
+METHODDEF(void)
+error_exit (j_common_ptr cinfo)
+{
+ /* Always display the message */
+ (*cinfo->err->output_message) (cinfo);
+
+ /* Let the memory manager delete any temp files before we die */
+ jpeg_destroy(cinfo);
+
+ exit(EXIT_FAILURE);
+}
+
+
+/*
+ * Actual output of an error or trace message.
+ * Applications may override this method to send JPEG messages somewhere
+ * other than stderr.
+ *
+ * On Windows, printing to stderr is generally completely useless,
+ * so we provide optional code to produce an error-dialog popup.
+ * Most Windows applications will still prefer to override this routine,
+ * but if they don't, it'll do something at least marginally useful.
+ *
+ * NOTE: to use the library in an environment that doesn't support the
+ * C stdio library, you may have to delete the call to fprintf() entirely,
+ * not just not use this routine.
+ */
+
+METHODDEF(void)
+output_message (j_common_ptr cinfo)
+{
+ char buffer[JMSG_LENGTH_MAX];
+
+ /* Create the message */
+ (*cinfo->err->format_message) (cinfo, buffer);
+
+#ifdef USE_WINDOWS_MESSAGEBOX
+ /* Display it in a message dialog box */
+ MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
+ MB_OK | MB_ICONERROR);
+#else
+ /* Send it to stderr, adding a newline */
+ fprintf(stderr, "%s\n", buffer);
+#endif
+}
+
+
+/*
+ * Decide whether to emit a trace or warning message.
+ * msg_level is one of:
+ * -1: recoverable corrupt-data warning, may want to abort.
+ * 0: important advisory messages (always display to user).
+ * 1: first level of tracing detail.
+ * 2,3,...: successively more detailed tracing messages.
+ * An application might override this method if it wanted to abort on warnings
+ * or change the policy about which messages to display.
+ */
+
+METHODDEF(void)
+emit_message (j_common_ptr cinfo, int msg_level)
+{
+ struct jpeg_error_mgr * err = cinfo->err;
+
+ if (msg_level < 0) {
+ /* It's a warning message. Since corrupt files may generate many warnings,
+ * the policy implemented here is to show only the first warning,
+ * unless trace_level >= 3.
+ */
+ if (err->num_warnings == 0 || err->trace_level >= 3)
+ (*err->output_message) (cinfo);
+ /* Always count warnings in num_warnings. */
+ err->num_warnings++;
+ } else {
+ /* It's a trace message. Show it if trace_level >= msg_level. */
+ if (err->trace_level >= msg_level)
+ (*err->output_message) (cinfo);
+ }
+}
+
+
+/*
+ * Format a message string for the most recent JPEG error or message.
+ * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
+ * characters. Note that no '\n' character is added to the string.
+ * Few applications should need to override this method.
+ */
+
+METHODDEF(void)
+format_message (j_common_ptr cinfo, char * buffer)
+{
+ struct jpeg_error_mgr * err = cinfo->err;
+ int msg_code = err->msg_code;
+ const char * msgtext = NULL;
+ const char * msgptr;
+ char ch;
+ boolean isstring;
+
+ /* Look up message string in proper table */
+ if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
+ msgtext = err->jpeg_message_table[msg_code];
+ } else if (err->addon_message_table != NULL &&
+ msg_code >= err->first_addon_message &&
+ msg_code <= err->last_addon_message) {
+ msgtext = err->addon_message_table[msg_code - err->first_addon_message];
+ }
+
+ /* Defend against bogus message number */
+ if (msgtext == NULL) {
+ err->msg_parm.i[0] = msg_code;
+ msgtext = err->jpeg_message_table[0];
+ }
+
+ /* Check for string parameter, as indicated by %s in the message text */
+ isstring = FALSE;
+ msgptr = msgtext;
+ while ((ch = *msgptr++) != '\0') {
+ if (ch == '%') {
+ if (*msgptr == 's') isstring = TRUE;
+ break;
+ }
+ }
+
+ /* Format the message into the passed buffer */
+ if (isstring)
+ sprintf(buffer, msgtext, err->msg_parm.s);
+ else
+ sprintf(buffer, msgtext,
+ err->msg_parm.i[0], err->msg_parm.i[1],
+ err->msg_parm.i[2], err->msg_parm.i[3],
+ err->msg_parm.i[4], err->msg_parm.i[5],
+ err->msg_parm.i[6], err->msg_parm.i[7]);
+}
+
+
+/*
+ * Reset error state variables at start of a new image.
+ * This is called during compression startup to reset trace/error
+ * processing to default state, without losing any application-specific
+ * method pointers. An application might possibly want to override
+ * this method if it has additional error processing state.
+ */
+
+METHODDEF(void)
+reset_error_mgr (j_common_ptr cinfo)
+{
+ cinfo->err->num_warnings = 0;
+ /* trace_level is not reset since it is an application-supplied parameter */
+ cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */
+}
+
+
+/*
+ * Fill in the standard error-handling methods in a jpeg_error_mgr object.
+ * Typical call is:
+ * struct jpeg_compress_struct cinfo;
+ * struct jpeg_error_mgr err;
+ *
+ * cinfo.err = jpeg_std_error(&err);
+ * after which the application may override some of the methods.
+ */
+
+GLOBAL(struct jpeg_error_mgr *)
+jpeg_std_error (struct jpeg_error_mgr * err)
+{
+ err->error_exit = error_exit;
+ err->emit_message = emit_message;
+ err->output_message = output_message;
+ err->format_message = format_message;
+ err->reset_error_mgr = reset_error_mgr;
+
+ err->trace_level = 0; /* default = no tracing */
+ err->num_warnings = 0; /* no warnings emitted yet */
+ err->msg_code = 0; /* may be useful as a flag for "no error" */
+
+ /* Initialize message table pointers */
+ err->jpeg_message_table = jpeg_std_message_table;
+ err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
+
+ err->addon_message_table = NULL;
+ err->first_addon_message = 0; /* for safety */
+ err->last_addon_message = 0;
+
+ return err;
+}
diff --git a/src/libjpeg-turbo/jerror.h b/src/libjpeg-turbo/jerror.h
new file mode 100644
index 0000000..275086e
--- /dev/null
+++ b/src/libjpeg-turbo/jerror.h
@@ -0,0 +1,314 @@
+/*
+ * jerror.h
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * Modified 1997-2009 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file defines the error and message codes for the JPEG library.
+ * Edit this file to add new codes, or to translate the message strings to
+ * some other language.
+ * A set of error-reporting macros are defined too. Some applications using
+ * the JPEG library may wish to include this file to get the error codes
+ * and/or the macros.
+ */
+
+/*
+ * To define the enum list of message codes, include this file without
+ * defining macro JMESSAGE. To create a message string table, include it
+ * again with a suitable JMESSAGE definition (see jerror.c for an example).
+ */
+#ifndef JMESSAGE
+#ifndef JERROR_H
+/* First time through, define the enum list */
+#define JMAKE_ENUM_LIST
+#else
+/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
+#define JMESSAGE(code,string)
+#endif /* JERROR_H */
+#endif /* JMESSAGE */
+
+#ifdef JMAKE_ENUM_LIST
+
+typedef enum {
+
+#define JMESSAGE(code,string) code ,
+
+#endif /* JMAKE_ENUM_LIST */
+
+JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
+
+/* For maintenance convenience, list is alphabetical by message code name */
+#if JPEG_LIB_VERSION < 70
+JMESSAGE(JERR_ARITH_NOTIMPL,
+ "Sorry, arithmetic coding is not implemented")
+#endif
+JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
+JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
+JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
+JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
+#if JPEG_LIB_VERSION >= 70
+JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request")
+#endif
+JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
+JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
+#if JPEG_LIB_VERSION >= 70
+JMESSAGE(JERR_BAD_DROP_SAMPLING,
+ "Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c")
+#endif
+JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
+JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
+JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
+JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
+JMESSAGE(JERR_BAD_LIB_VERSION,
+ "Wrong JPEG library version: library is %d, caller expects %d")
+JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
+JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
+JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
+JMESSAGE(JERR_BAD_PROGRESSION,
+ "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
+JMESSAGE(JERR_BAD_PROG_SCRIPT,
+ "Invalid progressive parameters at scan script entry %d")
+JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
+JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
+JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
+JMESSAGE(JERR_BAD_STRUCT_SIZE,
+ "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
+JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
+JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
+JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
+JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
+JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
+JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
+JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
+JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
+JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
+JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
+JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
+JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
+JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
+JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
+JMESSAGE(JERR_FILE_READ, "Input file read error")
+JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
+JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
+JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
+JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
+JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
+JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
+JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
+JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
+ "Cannot transcode due to multiple use of quantization table %d")
+JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
+JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
+JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
+JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
+#if JPEG_LIB_VERSION >= 70
+JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined")
+#endif
+JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
+JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
+JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
+JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
+JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
+JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
+JMESSAGE(JERR_QUANT_COMPONENTS,
+ "Cannot quantize more than %d color components")
+JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
+JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
+JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
+JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
+JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
+JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
+JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
+JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
+JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
+JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
+JMESSAGE(JERR_TFILE_WRITE,
+ "Write failed on temporary file --- out of disk space?")
+JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
+JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
+JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
+JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
+JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
+JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
+JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
+JMESSAGE(JMSG_VERSION, JVERSION)
+JMESSAGE(JTRC_16BIT_TABLES,
+ "Caution: quantization tables are too coarse for baseline JPEG")
+JMESSAGE(JTRC_ADOBE,
+ "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
+JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
+JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
+JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
+JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
+JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d")
+JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
+JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
+JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
+JMESSAGE(JTRC_EOI, "End Of Image")
+JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d")
+JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d")
+JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
+ "Warning: thumbnail image size does not match data length %u")
+JMESSAGE(JTRC_JFIF_EXTENSION,
+ "JFIF extension marker: type 0x%02x, length %u")
+JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image")
+JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
+JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
+JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
+JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
+JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
+JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
+JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
+JMESSAGE(JTRC_RST, "RST%d")
+JMESSAGE(JTRC_SMOOTH_NOTIMPL,
+ "Smoothing not supported with nonstandard sampling ratios")
+JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
+JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d")
+JMESSAGE(JTRC_SOI, "Start of Image")
+JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
+JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
+JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
+JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
+JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
+JMESSAGE(JTRC_THUMB_JPEG,
+ "JFIF extension marker: JPEG-compressed thumbnail image, length %u")
+JMESSAGE(JTRC_THUMB_PALETTE,
+ "JFIF extension marker: palette thumbnail image, length %u")
+JMESSAGE(JTRC_THUMB_RGB,
+ "JFIF extension marker: RGB thumbnail image, length %u")
+JMESSAGE(JTRC_UNKNOWN_IDS,
+ "Unrecognized component IDs %d %d %d, assuming YCbCr")
+JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
+JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
+JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
+#if JPEG_LIB_VERSION >= 70
+JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code")
+#endif
+JMESSAGE(JWRN_BOGUS_PROGRESSION,
+ "Inconsistent progression sequence for component %d coefficient %d")
+JMESSAGE(JWRN_EXTRANEOUS_DATA,
+ "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
+JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
+JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
+JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
+JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
+JMESSAGE(JWRN_MUST_RESYNC,
+ "Corrupt JPEG data: found marker 0x%02x instead of RST%d")
+JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
+JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
+#if JPEG_LIB_VERSION < 70
+JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request")
+#if defined(C_ARITH_CODING_SUPPORTED) || defined(D_ARITH_CODING_SUPPORTED)
+JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined")
+JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code")
+#endif
+#endif
+
+#ifdef JMAKE_ENUM_LIST
+
+ JMSG_LASTMSGCODE
+} J_MESSAGE_CODE;
+
+#undef JMAKE_ENUM_LIST
+#endif /* JMAKE_ENUM_LIST */
+
+/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
+#undef JMESSAGE
+
+
+#ifndef JERROR_H
+#define JERROR_H
+
+/* Macros to simplify using the error and trace message stuff */
+/* The first parameter is either type of cinfo pointer */
+
+/* Fatal errors (print message and exit) */
+#define ERREXIT(cinfo,code) \
+ ((cinfo)->err->msg_code = (code), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT1(cinfo,code,p1) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT2(cinfo,code,p1,p2) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT3(cinfo,code,p1,p2,p3) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (cinfo)->err->msg_parm.i[2] = (p3), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (cinfo)->err->msg_parm.i[2] = (p3), \
+ (cinfo)->err->msg_parm.i[3] = (p4), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXITS(cinfo,code,str) \
+ ((cinfo)->err->msg_code = (code), \
+ strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+
+#define MAKESTMT(stuff) do { stuff } while (0)
+
+/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
+#define WARNMS(cinfo,code) \
+ ((cinfo)->err->msg_code = (code), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+#define WARNMS1(cinfo,code,p1) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+#define WARNMS2(cinfo,code,p1,p2) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+
+/* Informational/debugging messages */
+#define TRACEMS(cinfo,lvl,code) \
+ ((cinfo)->err->msg_code = (code), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS1(cinfo,lvl,code,p1) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS2(cinfo,lvl,code,p1,p2) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+ _mp[4] = (p5); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+ _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMSS(cinfo,lvl,code,str) \
+ ((cinfo)->err->msg_code = (code), \
+ strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+
+#endif /* JERROR_H */
diff --git a/src/libjpeg-turbo/jfdctflt.c b/src/libjpeg-turbo/jfdctflt.c
new file mode 100644
index 0000000..79d7a00
--- /dev/null
+++ b/src/libjpeg-turbo/jfdctflt.c
@@ -0,0 +1,168 @@
+/*
+ * jfdctflt.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a floating-point implementation of the
+ * forward DCT (Discrete Cosine Transform).
+ *
+ * This implementation should be more accurate than either of the integer
+ * DCT implementations. However, it may not give the same results on all
+ * machines because of differences in roundoff behavior. Speed will depend
+ * on the hardware's floating point capacity.
+ *
+ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
+ * on each column. Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README). The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs. These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries. The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with a fixed-point
+ * implementation, accuracy is lost due to imprecise representation of the
+ * scaled quantization values. However, that problem does not arise if
+ * we use floating point arithmetic.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_FLOAT_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/*
+ * Perform the forward DCT on one block of samples.
+ */
+
+GLOBAL(void)
+jpeg_fdct_float (FAST_FLOAT * data)
+{
+ FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
+ FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
+ FAST_FLOAT *dataptr;
+ int ctr;
+
+ /* Pass 1: process rows. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[0] + dataptr[7];
+ tmp7 = dataptr[0] - dataptr[7];
+ tmp1 = dataptr[1] + dataptr[6];
+ tmp6 = dataptr[1] - dataptr[6];
+ tmp2 = dataptr[2] + dataptr[5];
+ tmp5 = dataptr[2] - dataptr[5];
+ tmp3 = dataptr[3] + dataptr[4];
+ tmp4 = dataptr[3] - dataptr[4];
+
+ /* Even part */
+
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[0] = tmp10 + tmp11; /* phase 3 */
+ dataptr[4] = tmp10 - tmp11;
+
+ z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
+ dataptr[2] = tmp13 + z1; /* phase 5 */
+ dataptr[6] = tmp13 - z1;
+
+ /* Odd part */
+
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
+ z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
+ z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
+ z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ dataptr[5] = z13 + z2; /* phase 6 */
+ dataptr[3] = z13 - z2;
+ dataptr[1] = z11 + z4;
+ dataptr[7] = z11 - z4;
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ }
+
+ /* Pass 2: process columns. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+ tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+ tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+ tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+ tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+ tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+ tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+ tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+
+ /* Even part */
+
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
+ dataptr[DCTSIZE*4] = tmp10 - tmp11;
+
+ z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
+ dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
+ dataptr[DCTSIZE*6] = tmp13 - z1;
+
+ /* Odd part */
+
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
+ z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
+ z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
+ z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
+ dataptr[DCTSIZE*3] = z13 - z2;
+ dataptr[DCTSIZE*1] = z11 + z4;
+ dataptr[DCTSIZE*7] = z11 - z4;
+
+ dataptr++; /* advance pointer to next column */
+ }
+}
+
+#endif /* DCT_FLOAT_SUPPORTED */
diff --git a/src/libjpeg-turbo/jfdctfst.c b/src/libjpeg-turbo/jfdctfst.c
new file mode 100644
index 0000000..ccb378a
--- /dev/null
+++ b/src/libjpeg-turbo/jfdctfst.c
@@ -0,0 +1,224 @@
+/*
+ * jfdctfst.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a fast, not so accurate integer implementation of the
+ * forward DCT (Discrete Cosine Transform).
+ *
+ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
+ * on each column. Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README). The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs. These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries. The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with fixed-point math,
+ * accuracy is lost due to imprecise representation of the scaled
+ * quantization values. The smaller the quantization table entry, the less
+ * precise the scaled value, so this implementation does worse with high-
+ * quality-setting files than with low-quality ones.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_IFAST_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Scaling decisions are generally the same as in the LL&M algorithm;
+ * see jfdctint.c for more details. However, we choose to descale
+ * (right shift) multiplication products as soon as they are formed,
+ * rather than carrying additional fractional bits into subsequent additions.
+ * This compromises accuracy slightly, but it lets us save a few shifts.
+ * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
+ * everywhere except in the multiplications proper; this saves a good deal
+ * of work on 16-bit-int machines.
+ *
+ * Again to save a few shifts, the intermediate results between pass 1 and
+ * pass 2 are not upscaled, but are represented only to integral precision.
+ *
+ * A final compromise is to represent the multiplicative constants to only
+ * 8 fractional bits, rather than 13. This saves some shifting work on some
+ * machines, and may also reduce the cost of multiplication (since there
+ * are fewer one-bits in the constants).
+ */
+
+#define CONST_BITS 8
+
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 8
+#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */
+#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */
+#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */
+#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */
+#else
+#define FIX_0_382683433 FIX(0.382683433)
+#define FIX_0_541196100 FIX(0.541196100)
+#define FIX_0_707106781 FIX(0.707106781)
+#define FIX_1_306562965 FIX(1.306562965)
+#endif
+
+
+/* We can gain a little more speed, with a further compromise in accuracy,
+ * by omitting the addition in a descaling shift. This yields an incorrectly
+ * rounded result half the time...
+ */
+
+#ifndef USE_ACCURATE_ROUNDING
+#undef DESCALE
+#define DESCALE(x,n) RIGHT_SHIFT(x, n)
+#endif
+
+
+/* Multiply a DCTELEM variable by an INT32 constant, and immediately
+ * descale to yield a DCTELEM result.
+ */
+
+#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
+
+
+/*
+ * Perform the forward DCT on one block of samples.
+ */
+
+GLOBAL(void)
+jpeg_fdct_ifast (DCTELEM * data)
+{
+ DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ DCTELEM tmp10, tmp11, tmp12, tmp13;
+ DCTELEM z1, z2, z3, z4, z5, z11, z13;
+ DCTELEM *dataptr;
+ int ctr;
+ SHIFT_TEMPS
+
+ /* Pass 1: process rows. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[0] + dataptr[7];
+ tmp7 = dataptr[0] - dataptr[7];
+ tmp1 = dataptr[1] + dataptr[6];
+ tmp6 = dataptr[1] - dataptr[6];
+ tmp2 = dataptr[2] + dataptr[5];
+ tmp5 = dataptr[2] - dataptr[5];
+ tmp3 = dataptr[3] + dataptr[4];
+ tmp4 = dataptr[3] - dataptr[4];
+
+ /* Even part */
+
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[0] = tmp10 + tmp11; /* phase 3 */
+ dataptr[4] = tmp10 - tmp11;
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
+ dataptr[2] = tmp13 + z1; /* phase 5 */
+ dataptr[6] = tmp13 - z1;
+
+ /* Odd part */
+
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
+ z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
+ z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
+ z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ dataptr[5] = z13 + z2; /* phase 6 */
+ dataptr[3] = z13 - z2;
+ dataptr[1] = z11 + z4;
+ dataptr[7] = z11 - z4;
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ }
+
+ /* Pass 2: process columns. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+ tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+ tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+ tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+ tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+ tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+ tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+ tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+
+ /* Even part */
+
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
+ dataptr[DCTSIZE*4] = tmp10 - tmp11;
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
+ dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
+ dataptr[DCTSIZE*6] = tmp13 - z1;
+
+ /* Odd part */
+
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
+ z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
+ z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
+ z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
+ dataptr[DCTSIZE*3] = z13 - z2;
+ dataptr[DCTSIZE*1] = z11 + z4;
+ dataptr[DCTSIZE*7] = z11 - z4;
+
+ dataptr++; /* advance pointer to next column */
+ }
+}
+
+#endif /* DCT_IFAST_SUPPORTED */
diff --git a/src/libjpeg-turbo/jfdctint.c b/src/libjpeg-turbo/jfdctint.c
new file mode 100644
index 0000000..0a78b64
--- /dev/null
+++ b/src/libjpeg-turbo/jfdctint.c
@@ -0,0 +1,283 @@
+/*
+ * jfdctint.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a slow-but-accurate integer implementation of the
+ * forward DCT (Discrete Cosine Transform).
+ *
+ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
+ * on each column. Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on an algorithm described in
+ * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
+ * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
+ * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
+ * The primary algorithm described there uses 11 multiplies and 29 adds.
+ * We use their alternate method with 12 multiplies and 32 adds.
+ * The advantage of this method is that no data path contains more than one
+ * multiplication; this allows a very simple and accurate implementation in
+ * scaled fixed-point arithmetic, with a minimal number of shifts.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_ISLOW_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/*
+ * The poop on this scaling stuff is as follows:
+ *
+ * Each 1-D DCT step produces outputs which are a factor of sqrt(N)
+ * larger than the true DCT outputs. The final outputs are therefore
+ * a factor of N larger than desired; since N=8 this can be cured by
+ * a simple right shift at the end of the algorithm. The advantage of
+ * this arrangement is that we save two multiplications per 1-D DCT,
+ * because the y0 and y4 outputs need not be divided by sqrt(N).
+ * In the IJG code, this factor of 8 is removed by the quantization step
+ * (in jcdctmgr.c), NOT in this module.
+ *
+ * We have to do addition and subtraction of the integer inputs, which
+ * is no problem, and multiplication by fractional constants, which is
+ * a problem to do in integer arithmetic. We multiply all the constants
+ * by CONST_SCALE and convert them to integer constants (thus retaining
+ * CONST_BITS bits of precision in the constants). After doing a
+ * multiplication we have to divide the product by CONST_SCALE, with proper
+ * rounding, to produce the correct output. This division can be done
+ * cheaply as a right shift of CONST_BITS bits. We postpone shifting
+ * as long as possible so that partial sums can be added together with
+ * full fractional precision.
+ *
+ * The outputs of the first pass are scaled up by PASS1_BITS bits so that
+ * they are represented to better-than-integral precision. These outputs
+ * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
+ * with the recommended scaling. (For 12-bit sample data, the intermediate
+ * array is INT32 anyway.)
+ *
+ * To avoid overflow of the 32-bit intermediate results in pass 2, we must
+ * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
+ * shows that the values given below are the most effective.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS 13
+#define PASS1_BITS 2
+#else
+#define CONST_BITS 13
+#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 13
+#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
+#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
+#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */
+#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
+#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
+#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */
+#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */
+#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
+#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */
+#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */
+#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
+#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */
+#else
+#define FIX_0_298631336 FIX(0.298631336)
+#define FIX_0_390180644 FIX(0.390180644)
+#define FIX_0_541196100 FIX(0.541196100)
+#define FIX_0_765366865 FIX(0.765366865)
+#define FIX_0_899976223 FIX(0.899976223)
+#define FIX_1_175875602 FIX(1.175875602)
+#define FIX_1_501321110 FIX(1.501321110)
+#define FIX_1_847759065 FIX(1.847759065)
+#define FIX_1_961570560 FIX(1.961570560)
+#define FIX_2_053119869 FIX(2.053119869)
+#define FIX_2_562915447 FIX(2.562915447)
+#define FIX_3_072711026 FIX(3.072711026)
+#endif
+
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * For 8-bit samples with the recommended scaling, all the variable
+ * and constant values involved are no more than 16 bits wide, so a
+ * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
+ * For 12-bit samples, a full 32-bit multiplication will be needed.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
+#else
+#define MULTIPLY(var,const) ((var) * (const))
+#endif
+
+
+/*
+ * Perform the forward DCT on one block of samples.
+ */
+
+GLOBAL(void)
+jpeg_fdct_islow (DCTELEM * data)
+{
+ INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ INT32 tmp10, tmp11, tmp12, tmp13;
+ INT32 z1, z2, z3, z4, z5;
+ DCTELEM *dataptr;
+ int ctr;
+ SHIFT_TEMPS
+
+ /* Pass 1: process rows. */
+ /* Note results are scaled up by sqrt(8) compared to a true DCT; */
+ /* furthermore, we scale the results by 2**PASS1_BITS. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[0] + dataptr[7];
+ tmp7 = dataptr[0] - dataptr[7];
+ tmp1 = dataptr[1] + dataptr[6];
+ tmp6 = dataptr[1] - dataptr[6];
+ tmp2 = dataptr[2] + dataptr[5];
+ tmp5 = dataptr[2] - dataptr[5];
+ tmp3 = dataptr[3] + dataptr[4];
+ tmp4 = dataptr[3] - dataptr[4];
+
+ /* Even part per LL&M figure 1 --- note that published figure is faulty;
+ * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+ */
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
+ dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+ dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+ CONST_BITS-PASS1_BITS);
+ dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+ CONST_BITS-PASS1_BITS);
+
+ /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
+ * cK represents cos(K*pi/16).
+ * i0..i3 in the paper are tmp4..tmp7 here.
+ */
+
+ z1 = tmp4 + tmp7;
+ z2 = tmp5 + tmp6;
+ z3 = tmp4 + tmp6;
+ z4 = tmp5 + tmp7;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+
+ tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
+ dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
+ dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
+ dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ }
+
+ /* Pass 2: process columns.
+ * We remove the PASS1_BITS scaling, but leave the results scaled up
+ * by an overall factor of 8.
+ */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+ tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+ tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+ tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+ tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+ tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+ tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+ tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+
+ /* Even part per LL&M figure 1 --- note that published figure is faulty;
+ * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+ */
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS);
+ dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS);
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+ dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+ CONST_BITS+PASS1_BITS);
+ dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+ CONST_BITS+PASS1_BITS);
+
+ /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
+ * cK represents cos(K*pi/16).
+ * i0..i3 in the paper are tmp4..tmp7 here.
+ */
+
+ z1 = tmp4 + tmp7;
+ z2 = tmp5 + tmp6;
+ z3 = tmp4 + tmp6;
+ z4 = tmp5 + tmp7;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+
+ tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3,
+ CONST_BITS+PASS1_BITS);
+ dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4,
+ CONST_BITS+PASS1_BITS);
+ dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3,
+ CONST_BITS+PASS1_BITS);
+ dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4,
+ CONST_BITS+PASS1_BITS);
+
+ dataptr++; /* advance pointer to next column */
+ }
+}
+
+#endif /* DCT_ISLOW_SUPPORTED */
diff --git a/src/libjpeg-turbo/jidctflt.c b/src/libjpeg-turbo/jidctflt.c
new file mode 100644
index 0000000..0188ce3
--- /dev/null
+++ b/src/libjpeg-turbo/jidctflt.c
@@ -0,0 +1,242 @@
+/*
+ * jidctflt.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a floating-point implementation of the
+ * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
+ * must also perform dequantization of the input coefficients.
+ *
+ * This implementation should be more accurate than either of the integer
+ * IDCT implementations. However, it may not give the same results on all
+ * machines because of differences in roundoff behavior. Speed will depend
+ * on the hardware's floating point capacity.
+ *
+ * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
+ * on each row (or vice versa, but it's more convenient to emit a row at
+ * a time). Direct algorithms are also available, but they are much more
+ * complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README). The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs. These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries. The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with a fixed-point
+ * implementation, accuracy is lost due to imprecise representation of the
+ * scaled quantization values. However, that problem does not arise if
+ * we use floating point arithmetic.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_FLOAT_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce a float result.
+ */
+
+#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval))
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients.
+ */
+
+GLOBAL(void)
+jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
+ FAST_FLOAT z5, z10, z11, z12, z13;
+ JCOEFPTR inptr;
+ FLOAT_MULT_TYPE * quantptr;
+ FAST_FLOAT * wsptr;
+ JSAMPROW outptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ int ctr;
+ FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
+ SHIFT_TEMPS
+
+ /* Pass 1: process columns from input, store into work array. */
+
+ inptr = coef_block;
+ quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table;
+ wsptr = workspace;
+ for (ctr = DCTSIZE; ctr > 0; ctr--) {
+ /* Due to quantization, we will usually find that many of the input
+ * coefficients are zero, especially the AC terms. We can exploit this
+ * by short-circuiting the IDCT calculation for any column in which all
+ * the AC terms are zero. In that case each output is equal to the
+ * DC coefficient (with scale factor as needed).
+ * With typical images and quantization tables, half or more of the
+ * column DCT calculations can be simplified this way.
+ */
+
+ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+ inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+ inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+ inptr[DCTSIZE*7] == 0) {
+ /* AC terms all zero */
+ FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+
+ wsptr[DCTSIZE*0] = dcval;
+ wsptr[DCTSIZE*1] = dcval;
+ wsptr[DCTSIZE*2] = dcval;
+ wsptr[DCTSIZE*3] = dcval;
+ wsptr[DCTSIZE*4] = dcval;
+ wsptr[DCTSIZE*5] = dcval;
+ wsptr[DCTSIZE*6] = dcval;
+ wsptr[DCTSIZE*7] = dcval;
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ continue;
+ }
+
+ /* Even part */
+
+ tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+ tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+ tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
+ tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+ tmp10 = tmp0 + tmp2; /* phase 3 */
+ tmp11 = tmp0 - tmp2;
+
+ tmp13 = tmp1 + tmp3; /* phases 5-3 */
+ tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
+
+ tmp0 = tmp10 + tmp13; /* phase 2 */
+ tmp3 = tmp10 - tmp13;
+ tmp1 = tmp11 + tmp12;
+ tmp2 = tmp11 - tmp12;
+
+ /* Odd part */
+
+ tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+ tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+ tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+ tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+
+ z13 = tmp6 + tmp5; /* phase 6 */
+ z10 = tmp6 - tmp5;
+ z11 = tmp4 + tmp7;
+ z12 = tmp4 - tmp7;
+
+ tmp7 = z11 + z13; /* phase 5 */
+ tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
+
+ z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
+ tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
+ tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
+
+ tmp6 = tmp12 - tmp7; /* phase 2 */
+ tmp5 = tmp11 - tmp6;
+ tmp4 = tmp10 + tmp5;
+
+ wsptr[DCTSIZE*0] = tmp0 + tmp7;
+ wsptr[DCTSIZE*7] = tmp0 - tmp7;
+ wsptr[DCTSIZE*1] = tmp1 + tmp6;
+ wsptr[DCTSIZE*6] = tmp1 - tmp6;
+ wsptr[DCTSIZE*2] = tmp2 + tmp5;
+ wsptr[DCTSIZE*5] = tmp2 - tmp5;
+ wsptr[DCTSIZE*4] = tmp3 + tmp4;
+ wsptr[DCTSIZE*3] = tmp3 - tmp4;
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ }
+
+ /* Pass 2: process rows from work array, store into output array. */
+ /* Note that we must descale the results by a factor of 8 == 2**3. */
+
+ wsptr = workspace;
+ for (ctr = 0; ctr < DCTSIZE; ctr++) {
+ outptr = output_buf[ctr] + output_col;
+ /* Rows of zeroes can be exploited in the same way as we did with columns.
+ * However, the column calculation has created many nonzero AC terms, so
+ * the simplification applies less often (typically 5% to 10% of the time).
+ * And testing floats for zero is relatively expensive, so we don't bother.
+ */
+
+ /* Even part */
+
+ tmp10 = wsptr[0] + wsptr[4];
+ tmp11 = wsptr[0] - wsptr[4];
+
+ tmp13 = wsptr[2] + wsptr[6];
+ tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
+
+ tmp0 = tmp10 + tmp13;
+ tmp3 = tmp10 - tmp13;
+ tmp1 = tmp11 + tmp12;
+ tmp2 = tmp11 - tmp12;
+
+ /* Odd part */
+
+ z13 = wsptr[5] + wsptr[3];
+ z10 = wsptr[5] - wsptr[3];
+ z11 = wsptr[1] + wsptr[7];
+ z12 = wsptr[1] - wsptr[7];
+
+ tmp7 = z11 + z13;
+ tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
+
+ z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
+ tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
+ tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
+
+ tmp6 = tmp12 - tmp7;
+ tmp5 = tmp11 - tmp6;
+ tmp4 = tmp10 + tmp5;
+
+ /* Final output stage: scale down by a factor of 8 and range-limit */
+
+ outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
+ & RANGE_MASK];
+ outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
+ & RANGE_MASK];
+ outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
+ & RANGE_MASK];
+ outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
+ & RANGE_MASK];
+ outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
+ & RANGE_MASK];
+ outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
+ & RANGE_MASK];
+ outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
+ & RANGE_MASK];
+ outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
+ & RANGE_MASK];
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ }
+}
+
+#endif /* DCT_FLOAT_SUPPORTED */
diff --git a/src/libjpeg-turbo/jidctfst.c b/src/libjpeg-turbo/jidctfst.c
new file mode 100644
index 0000000..dba4216
--- /dev/null
+++ b/src/libjpeg-turbo/jidctfst.c
@@ -0,0 +1,368 @@
+/*
+ * jidctfst.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a fast, not so accurate integer implementation of the
+ * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
+ * must also perform dequantization of the input coefficients.
+ *
+ * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
+ * on each row (or vice versa, but it's more convenient to emit a row at
+ * a time). Direct algorithms are also available, but they are much more
+ * complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README). The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs. These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries. The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with fixed-point math,
+ * accuracy is lost due to imprecise representation of the scaled
+ * quantization values. The smaller the quantization table entry, the less
+ * precise the scaled value, so this implementation does worse with high-
+ * quality-setting files than with low-quality ones.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_IFAST_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Scaling decisions are generally the same as in the LL&M algorithm;
+ * see jidctint.c for more details. However, we choose to descale
+ * (right shift) multiplication products as soon as they are formed,
+ * rather than carrying additional fractional bits into subsequent additions.
+ * This compromises accuracy slightly, but it lets us save a few shifts.
+ * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
+ * everywhere except in the multiplications proper; this saves a good deal
+ * of work on 16-bit-int machines.
+ *
+ * The dequantized coefficients are not integers because the AA&N scaling
+ * factors have been incorporated. We represent them scaled up by PASS1_BITS,
+ * so that the first and second IDCT rounds have the same input scaling.
+ * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to
+ * avoid a descaling shift; this compromises accuracy rather drastically
+ * for small quantization table entries, but it saves a lot of shifts.
+ * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway,
+ * so we use a much larger scaling factor to preserve accuracy.
+ *
+ * A final compromise is to represent the multiplicative constants to only
+ * 8 fractional bits, rather than 13. This saves some shifting work on some
+ * machines, and may also reduce the cost of multiplication (since there
+ * are fewer one-bits in the constants).
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS 8
+#define PASS1_BITS 2
+#else
+#define CONST_BITS 8
+#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 8
+#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */
+#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */
+#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */
+#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */
+#else
+#define FIX_1_082392200 FIX(1.082392200)
+#define FIX_1_414213562 FIX(1.414213562)
+#define FIX_1_847759065 FIX(1.847759065)
+#define FIX_2_613125930 FIX(2.613125930)
+#endif
+
+
+/* We can gain a little more speed, with a further compromise in accuracy,
+ * by omitting the addition in a descaling shift. This yields an incorrectly
+ * rounded result half the time...
+ */
+
+#ifndef USE_ACCURATE_ROUNDING
+#undef DESCALE
+#define DESCALE(x,n) RIGHT_SHIFT(x, n)
+#endif
+
+
+/* Multiply a DCTELEM variable by an INT32 constant, and immediately
+ * descale to yield a DCTELEM result.
+ */
+
+#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce a DCTELEM result. For 8-bit data a 16x16->16
+ * multiplication will do. For 12-bit data, the multiplier table is
+ * declared INT32, so a 32-bit multiply will be used.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval))
+#else
+#define DEQUANTIZE(coef,quantval) \
+ DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
+#endif
+
+
+/* Like DESCALE, but applies to a DCTELEM and produces an int.
+ * We assume that int right shift is unsigned if INT32 right shift is.
+ */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define ISHIFT_TEMPS DCTELEM ishift_temp;
+#if BITS_IN_JSAMPLE == 8
+#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */
+#else
+#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */
+#endif
+#define IRIGHT_SHIFT(x,shft) \
+ ((ishift_temp = (x)) < 0 ? \
+ (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
+ (ishift_temp >> (shft)))
+#else
+#define ISHIFT_TEMPS
+#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
+#endif
+
+#ifdef USE_ACCURATE_ROUNDING
+#define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
+#else
+#define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n))
+#endif
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients.
+ */
+
+GLOBAL(void)
+jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ DCTELEM tmp10, tmp11, tmp12, tmp13;
+ DCTELEM z5, z10, z11, z12, z13;
+ JCOEFPTR inptr;
+ IFAST_MULT_TYPE * quantptr;
+ int * wsptr;
+ JSAMPROW outptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ int ctr;
+ int workspace[DCTSIZE2]; /* buffers data between passes */
+ SHIFT_TEMPS /* for DESCALE */
+ ISHIFT_TEMPS /* for IDESCALE */
+
+ /* Pass 1: process columns from input, store into work array. */
+
+ inptr = coef_block;
+ quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
+ wsptr = workspace;
+ for (ctr = DCTSIZE; ctr > 0; ctr--) {
+ /* Due to quantization, we will usually find that many of the input
+ * coefficients are zero, especially the AC terms. We can exploit this
+ * by short-circuiting the IDCT calculation for any column in which all
+ * the AC terms are zero. In that case each output is equal to the
+ * DC coefficient (with scale factor as needed).
+ * With typical images and quantization tables, half or more of the
+ * column DCT calculations can be simplified this way.
+ */
+
+ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+ inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+ inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+ inptr[DCTSIZE*7] == 0) {
+ /* AC terms all zero */
+ int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+
+ wsptr[DCTSIZE*0] = dcval;
+ wsptr[DCTSIZE*1] = dcval;
+ wsptr[DCTSIZE*2] = dcval;
+ wsptr[DCTSIZE*3] = dcval;
+ wsptr[DCTSIZE*4] = dcval;
+ wsptr[DCTSIZE*5] = dcval;
+ wsptr[DCTSIZE*6] = dcval;
+ wsptr[DCTSIZE*7] = dcval;
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ continue;
+ }
+
+ /* Even part */
+
+ tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+ tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+ tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
+ tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+ tmp10 = tmp0 + tmp2; /* phase 3 */
+ tmp11 = tmp0 - tmp2;
+
+ tmp13 = tmp1 + tmp3; /* phases 5-3 */
+ tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
+
+ tmp0 = tmp10 + tmp13; /* phase 2 */
+ tmp3 = tmp10 - tmp13;
+ tmp1 = tmp11 + tmp12;
+ tmp2 = tmp11 - tmp12;
+
+ /* Odd part */
+
+ tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+ tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+ tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+ tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+
+ z13 = tmp6 + tmp5; /* phase 6 */
+ z10 = tmp6 - tmp5;
+ z11 = tmp4 + tmp7;
+ z12 = tmp4 - tmp7;
+
+ tmp7 = z11 + z13; /* phase 5 */
+ tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
+
+ z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
+ tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
+ tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
+
+ tmp6 = tmp12 - tmp7; /* phase 2 */
+ tmp5 = tmp11 - tmp6;
+ tmp4 = tmp10 + tmp5;
+
+ wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
+ wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
+ wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
+ wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
+ wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
+ wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
+ wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
+ wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ }
+
+ /* Pass 2: process rows from work array, store into output array. */
+ /* Note that we must descale the results by a factor of 8 == 2**3, */
+ /* and also undo the PASS1_BITS scaling. */
+
+ wsptr = workspace;
+ for (ctr = 0; ctr < DCTSIZE; ctr++) {
+ outptr = output_buf[ctr] + output_col;
+ /* Rows of zeroes can be exploited in the same way as we did with columns.
+ * However, the column calculation has created many nonzero AC terms, so
+ * the simplification applies less often (typically 5% to 10% of the time).
+ * On machines with very fast multiplication, it's possible that the
+ * test takes more time than it's worth. In that case this section
+ * may be commented out.
+ */
+
+#ifndef NO_ZERO_ROW_TEST
+ if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
+ wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
+ /* AC terms all zero */
+ JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
+ & RANGE_MASK];
+
+ outptr[0] = dcval;
+ outptr[1] = dcval;
+ outptr[2] = dcval;
+ outptr[3] = dcval;
+ outptr[4] = dcval;
+ outptr[5] = dcval;
+ outptr[6] = dcval;
+ outptr[7] = dcval;
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ continue;
+ }
+#endif
+
+ /* Even part */
+
+ tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
+ tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
+
+ tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
+ tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562)
+ - tmp13;
+
+ tmp0 = tmp10 + tmp13;
+ tmp3 = tmp10 - tmp13;
+ tmp1 = tmp11 + tmp12;
+ tmp2 = tmp11 - tmp12;
+
+ /* Odd part */
+
+ z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
+ z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
+ z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
+ z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
+
+ tmp7 = z11 + z13; /* phase 5 */
+ tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
+
+ z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
+ tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
+ tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
+
+ tmp6 = tmp12 - tmp7; /* phase 2 */
+ tmp5 = tmp11 - tmp6;
+ tmp4 = tmp10 + tmp5;
+
+ /* Final output stage: scale down by a factor of 8 and range-limit */
+
+ outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
+ & RANGE_MASK];
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ }
+}
+
+#endif /* DCT_IFAST_SUPPORTED */
diff --git a/src/libjpeg-turbo/jidctint.c b/src/libjpeg-turbo/jidctint.c
new file mode 100644
index 0000000..a72b320
--- /dev/null
+++ b/src/libjpeg-turbo/jidctint.c
@@ -0,0 +1,389 @@
+/*
+ * jidctint.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a slow-but-accurate integer implementation of the
+ * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
+ * must also perform dequantization of the input coefficients.
+ *
+ * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
+ * on each row (or vice versa, but it's more convenient to emit a row at
+ * a time). Direct algorithms are also available, but they are much more
+ * complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on an algorithm described in
+ * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
+ * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
+ * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
+ * The primary algorithm described there uses 11 multiplies and 29 adds.
+ * We use their alternate method with 12 multiplies and 32 adds.
+ * The advantage of this method is that no data path contains more than one
+ * multiplication; this allows a very simple and accurate implementation in
+ * scaled fixed-point arithmetic, with a minimal number of shifts.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_ISLOW_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/*
+ * The poop on this scaling stuff is as follows:
+ *
+ * Each 1-D IDCT step produces outputs which are a factor of sqrt(N)
+ * larger than the true IDCT outputs. The final outputs are therefore
+ * a factor of N larger than desired; since N=8 this can be cured by
+ * a simple right shift at the end of the algorithm. The advantage of
+ * this arrangement is that we save two multiplications per 1-D IDCT,
+ * because the y0 and y4 inputs need not be divided by sqrt(N).
+ *
+ * We have to do addition and subtraction of the integer inputs, which
+ * is no problem, and multiplication by fractional constants, which is
+ * a problem to do in integer arithmetic. We multiply all the constants
+ * by CONST_SCALE and convert them to integer constants (thus retaining
+ * CONST_BITS bits of precision in the constants). After doing a
+ * multiplication we have to divide the product by CONST_SCALE, with proper
+ * rounding, to produce the correct output. This division can be done
+ * cheaply as a right shift of CONST_BITS bits. We postpone shifting
+ * as long as possible so that partial sums can be added together with
+ * full fractional precision.
+ *
+ * The outputs of the first pass are scaled up by PASS1_BITS bits so that
+ * they are represented to better-than-integral precision. These outputs
+ * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
+ * with the recommended scaling. (To scale up 12-bit sample data further, an
+ * intermediate INT32 array would be needed.)
+ *
+ * To avoid overflow of the 32-bit intermediate results in pass 2, we must
+ * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
+ * shows that the values given below are the most effective.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS 13
+#define PASS1_BITS 2
+#else
+#define CONST_BITS 13
+#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 13
+#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
+#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
+#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */
+#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
+#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
+#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */
+#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */
+#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
+#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */
+#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */
+#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
+#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */
+#else
+#define FIX_0_298631336 FIX(0.298631336)
+#define FIX_0_390180644 FIX(0.390180644)
+#define FIX_0_541196100 FIX(0.541196100)
+#define FIX_0_765366865 FIX(0.765366865)
+#define FIX_0_899976223 FIX(0.899976223)
+#define FIX_1_175875602 FIX(1.175875602)
+#define FIX_1_501321110 FIX(1.501321110)
+#define FIX_1_847759065 FIX(1.847759065)
+#define FIX_1_961570560 FIX(1.961570560)
+#define FIX_2_053119869 FIX(2.053119869)
+#define FIX_2_562915447 FIX(2.562915447)
+#define FIX_3_072711026 FIX(3.072711026)
+#endif
+
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * For 8-bit samples with the recommended scaling, all the variable
+ * and constant values involved are no more than 16 bits wide, so a
+ * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
+ * For 12-bit samples, a full 32-bit multiplication will be needed.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
+#else
+#define MULTIPLY(var,const) ((var) * (const))
+#endif
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce an int result. In this module, both inputs and result
+ * are 16 bits or less, so either int or short multiply will work.
+ */
+
+#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients.
+ */
+
+GLOBAL(void)
+jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ INT32 tmp0, tmp1, tmp2, tmp3;
+ INT32 tmp10, tmp11, tmp12, tmp13;
+ INT32 z1, z2, z3, z4, z5;
+ JCOEFPTR inptr;
+ ISLOW_MULT_TYPE * quantptr;
+ int * wsptr;
+ JSAMPROW outptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ int ctr;
+ int workspace[DCTSIZE2]; /* buffers data between passes */
+ SHIFT_TEMPS
+
+ /* Pass 1: process columns from input, store into work array. */
+ /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
+ /* furthermore, we scale the results by 2**PASS1_BITS. */
+
+ inptr = coef_block;
+ quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+ wsptr = workspace;
+ for (ctr = DCTSIZE; ctr > 0; ctr--) {
+ /* Due to quantization, we will usually find that many of the input
+ * coefficients are zero, especially the AC terms. We can exploit this
+ * by short-circuiting the IDCT calculation for any column in which all
+ * the AC terms are zero. In that case each output is equal to the
+ * DC coefficient (with scale factor as needed).
+ * With typical images and quantization tables, half or more of the
+ * column DCT calculations can be simplified this way.
+ */
+
+ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+ inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+ inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+ inptr[DCTSIZE*7] == 0) {
+ /* AC terms all zero */
+ int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
+
+ wsptr[DCTSIZE*0] = dcval;
+ wsptr[DCTSIZE*1] = dcval;
+ wsptr[DCTSIZE*2] = dcval;
+ wsptr[DCTSIZE*3] = dcval;
+ wsptr[DCTSIZE*4] = dcval;
+ wsptr[DCTSIZE*5] = dcval;
+ wsptr[DCTSIZE*6] = dcval;
+ wsptr[DCTSIZE*7] = dcval;
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ continue;
+ }
+
+ /* Even part: reverse the even part of the forward DCT. */
+ /* The rotator is sqrt(2)*c(-6). */
+
+ z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+ z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+ z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
+
+ z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+ z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
+
+ tmp0 = (z2 + z3) << CONST_BITS;
+ tmp1 = (z2 - z3) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ /* Odd part per figure 8; the matrix is unitary and hence its
+ * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
+ */
+
+ tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+ tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+ tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+ tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+
+ z1 = tmp0 + tmp3;
+ z2 = tmp1 + tmp2;
+ z3 = tmp0 + tmp2;
+ z4 = tmp1 + tmp3;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+
+ tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+
+ /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+
+ wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ }
+
+ /* Pass 2: process rows from work array, store into output array. */
+ /* Note that we must descale the results by a factor of 8 == 2**3, */
+ /* and also undo the PASS1_BITS scaling. */
+
+ wsptr = workspace;
+ for (ctr = 0; ctr < DCTSIZE; ctr++) {
+ outptr = output_buf[ctr] + output_col;
+ /* Rows of zeroes can be exploited in the same way as we did with columns.
+ * However, the column calculation has created many nonzero AC terms, so
+ * the simplification applies less often (typically 5% to 10% of the time).
+ * On machines with very fast multiplication, it's possible that the
+ * test takes more time than it's worth. In that case this section
+ * may be commented out.
+ */
+
+#ifndef NO_ZERO_ROW_TEST
+ if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
+ wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
+ /* AC terms all zero */
+ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
+ & RANGE_MASK];
+
+ outptr[0] = dcval;
+ outptr[1] = dcval;
+ outptr[2] = dcval;
+ outptr[3] = dcval;
+ outptr[4] = dcval;
+ outptr[5] = dcval;
+ outptr[6] = dcval;
+ outptr[7] = dcval;
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ continue;
+ }
+#endif
+
+ /* Even part: reverse the even part of the forward DCT. */
+ /* The rotator is sqrt(2)*c(-6). */
+
+ z2 = (INT32) wsptr[2];
+ z3 = (INT32) wsptr[6];
+
+ z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
+
+ tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS;
+ tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ /* Odd part per figure 8; the matrix is unitary and hence its
+ * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
+ */
+
+ tmp0 = (INT32) wsptr[7];
+ tmp1 = (INT32) wsptr[5];
+ tmp2 = (INT32) wsptr[3];
+ tmp3 = (INT32) wsptr[1];
+
+ z1 = tmp0 + tmp3;
+ z2 = tmp1 + tmp2;
+ z3 = tmp0 + tmp2;
+ z4 = tmp1 + tmp3;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+
+ tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+
+ /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+
+ outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ }
+}
+
+#endif /* DCT_ISLOW_SUPPORTED */
diff --git a/src/libjpeg-turbo/jidctred.c b/src/libjpeg-turbo/jidctred.c
new file mode 100644
index 0000000..421f3c7
--- /dev/null
+++ b/src/libjpeg-turbo/jidctred.c
@@ -0,0 +1,398 @@
+/*
+ * jidctred.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains inverse-DCT routines that produce reduced-size output:
+ * either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block.
+ *
+ * The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M)
+ * algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step
+ * with an 8-to-4 step that produces the four averages of two adjacent outputs
+ * (or an 8-to-2 step producing two averages of four outputs, for 2x2 output).
+ * These steps were derived by computing the corresponding values at the end
+ * of the normal LL&M code, then simplifying as much as possible.
+ *
+ * 1x1 is trivial: just take the DC coefficient divided by 8.
+ *
+ * See jidctint.c for additional comments.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef IDCT_SCALING_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Scaling is the same as in jidctint.c. */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS 13
+#define PASS1_BITS 2
+#else
+#define CONST_BITS 13
+#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 13
+#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */
+#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */
+#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */
+#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */
+#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
+#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */
+#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
+#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */
+#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */
+#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */
+#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
+#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */
+#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
+#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */
+#else
+#define FIX_0_211164243 FIX(0.211164243)
+#define FIX_0_509795579 FIX(0.509795579)
+#define FIX_0_601344887 FIX(0.601344887)
+#define FIX_0_720959822 FIX(0.720959822)
+#define FIX_0_765366865 FIX(0.765366865)
+#define FIX_0_850430095 FIX(0.850430095)
+#define FIX_0_899976223 FIX(0.899976223)
+#define FIX_1_061594337 FIX(1.061594337)
+#define FIX_1_272758580 FIX(1.272758580)
+#define FIX_1_451774981 FIX(1.451774981)
+#define FIX_1_847759065 FIX(1.847759065)
+#define FIX_2_172734803 FIX(2.172734803)
+#define FIX_2_562915447 FIX(2.562915447)
+#define FIX_3_624509785 FIX(3.624509785)
+#endif
+
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * For 8-bit samples with the recommended scaling, all the variable
+ * and constant values involved are no more than 16 bits wide, so a
+ * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
+ * For 12-bit samples, a full 32-bit multiplication will be needed.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
+#else
+#define MULTIPLY(var,const) ((var) * (const))
+#endif
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce an int result. In this module, both inputs and result
+ * are 16 bits or less, so either int or short multiply will work.
+ */
+
+#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients,
+ * producing a reduced-size 4x4 output block.
+ */
+
+GLOBAL(void)
+jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ INT32 tmp0, tmp2, tmp10, tmp12;
+ INT32 z1, z2, z3, z4;
+ JCOEFPTR inptr;
+ ISLOW_MULT_TYPE * quantptr;
+ int * wsptr;
+ JSAMPROW outptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ int ctr;
+ int workspace[DCTSIZE*4]; /* buffers data between passes */
+ SHIFT_TEMPS
+
+ /* Pass 1: process columns from input, store into work array. */
+
+ inptr = coef_block;
+ quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+ wsptr = workspace;
+ for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
+ /* Don't bother to process column 4, because second pass won't use it */
+ if (ctr == DCTSIZE-4)
+ continue;
+ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+ inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 &&
+ inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) {
+ /* AC terms all zero; we need not examine term 4 for 4x4 output */
+ int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
+
+ wsptr[DCTSIZE*0] = dcval;
+ wsptr[DCTSIZE*1] = dcval;
+ wsptr[DCTSIZE*2] = dcval;
+ wsptr[DCTSIZE*3] = dcval;
+
+ continue;
+ }
+
+ /* Even part */
+
+ tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+ tmp0 <<= (CONST_BITS+1);
+
+ z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+ z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+ tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);
+
+ tmp10 = tmp0 + tmp2;
+ tmp12 = tmp0 - tmp2;
+
+ /* Odd part */
+
+ z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+ z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+ z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+ z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+
+ tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
+ + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
+ + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
+ + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
+
+ tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
+ + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
+ + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
+ + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
+
+ /* Final output stage */
+
+ wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1);
+ wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1);
+ wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1);
+ wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1);
+ }
+
+ /* Pass 2: process 4 rows from work array, store into output array. */
+
+ wsptr = workspace;
+ for (ctr = 0; ctr < 4; ctr++) {
+ outptr = output_buf[ctr] + output_col;
+ /* It's not clear whether a zero row test is worthwhile here ... */
+
+#ifndef NO_ZERO_ROW_TEST
+ if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
+ wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
+ /* AC terms all zero */
+ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
+ & RANGE_MASK];
+
+ outptr[0] = dcval;
+ outptr[1] = dcval;
+ outptr[2] = dcval;
+ outptr[3] = dcval;
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ continue;
+ }
+#endif
+
+ /* Even part */
+
+ tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1);
+
+ tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065)
+ + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865);
+
+ tmp10 = tmp0 + tmp2;
+ tmp12 = tmp0 - tmp2;
+
+ /* Odd part */
+
+ z1 = (INT32) wsptr[7];
+ z2 = (INT32) wsptr[5];
+ z3 = (INT32) wsptr[3];
+ z4 = (INT32) wsptr[1];
+
+ tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
+ + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
+ + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
+ + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
+
+ tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
+ + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
+ + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
+ + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
+
+ /* Final output stage */
+
+ outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2,
+ CONST_BITS+PASS1_BITS+3+1)
+ & RANGE_MASK];
+ outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2,
+ CONST_BITS+PASS1_BITS+3+1)
+ & RANGE_MASK];
+ outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0,
+ CONST_BITS+PASS1_BITS+3+1)
+ & RANGE_MASK];
+ outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0,
+ CONST_BITS+PASS1_BITS+3+1)
+ & RANGE_MASK];
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ }
+}
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients,
+ * producing a reduced-size 2x2 output block.
+ */
+
+GLOBAL(void)
+jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ INT32 tmp0, tmp10, z1;
+ JCOEFPTR inptr;
+ ISLOW_MULT_TYPE * quantptr;
+ int * wsptr;
+ JSAMPROW outptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ int ctr;
+ int workspace[DCTSIZE*2]; /* buffers data between passes */
+ SHIFT_TEMPS
+
+ /* Pass 1: process columns from input, store into work array. */
+
+ inptr = coef_block;
+ quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+ wsptr = workspace;
+ for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
+ /* Don't bother to process columns 2,4,6 */
+ if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
+ continue;
+ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
+ inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
+ /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
+ int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
+
+ wsptr[DCTSIZE*0] = dcval;
+ wsptr[DCTSIZE*1] = dcval;
+
+ continue;
+ }
+
+ /* Even part */
+
+ z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+ tmp10 = z1 << (CONST_BITS+2);
+
+ /* Odd part */
+
+ z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+ tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */
+ z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+ tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */
+ z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+ tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */
+ z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+ tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
+
+ /* Final output stage */
+
+ wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2);
+ wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2);
+ }
+
+ /* Pass 2: process 2 rows from work array, store into output array. */
+
+ wsptr = workspace;
+ for (ctr = 0; ctr < 2; ctr++) {
+ outptr = output_buf[ctr] + output_col;
+ /* It's not clear whether a zero row test is worthwhile here ... */
+
+#ifndef NO_ZERO_ROW_TEST
+ if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) {
+ /* AC terms all zero */
+ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
+ & RANGE_MASK];
+
+ outptr[0] = dcval;
+ outptr[1] = dcval;
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ continue;
+ }
+#endif
+
+ /* Even part */
+
+ tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2);
+
+ /* Odd part */
+
+ tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */
+ + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */
+ + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */
+ + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
+
+ /* Final output stage */
+
+ outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0,
+ CONST_BITS+PASS1_BITS+3+2)
+ & RANGE_MASK];
+ outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0,
+ CONST_BITS+PASS1_BITS+3+2)
+ & RANGE_MASK];
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ }
+}
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients,
+ * producing a reduced-size 1x1 output block.
+ */
+
+GLOBAL(void)
+jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ int dcval;
+ ISLOW_MULT_TYPE * quantptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ SHIFT_TEMPS
+
+ /* We hardly need an inverse DCT routine for this: just take the
+ * average pixel value, which is one-eighth of the DC coefficient.
+ */
+ quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+ dcval = DEQUANTIZE(coef_block[0], quantptr[0]);
+ dcval = (int) DESCALE((INT32) dcval, 3);
+
+ output_buf[0][output_col] = range_limit[dcval & RANGE_MASK];
+}
+
+#endif /* IDCT_SCALING_SUPPORTED */
diff --git a/src/libjpeg-turbo/jinclude.h b/src/libjpeg-turbo/jinclude.h
new file mode 100644
index 0000000..0a4f151
--- /dev/null
+++ b/src/libjpeg-turbo/jinclude.h
@@ -0,0 +1,91 @@
+/*
+ * jinclude.h
+ *
+ * Copyright (C) 1991-1994, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file exists to provide a single place to fix any problems with
+ * including the wrong system include files. (Common problems are taken
+ * care of by the standard jconfig symbols, but on really weird systems
+ * you may have to edit this file.)
+ *
+ * NOTE: this file is NOT intended to be included by applications using the
+ * JPEG library. Most applications need only include jpeglib.h.
+ */
+
+
+/* Include auto-config file to find out which system include files we need. */
+
+#include "jconfig.h" /* auto configuration options */
+#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */
+
+/*
+ * We need the NULL macro and size_t typedef.
+ * On an ANSI-conforming system it is sufficient to include <stddef.h>.
+ * Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
+ * pull in <sys/types.h> as well.
+ * Note that the core JPEG library does not require <stdio.h>;
+ * only the default error handler and data source/destination modules do.
+ * But we must pull it in because of the references to FILE in jpeglib.h.
+ * You can remove those references if you want to compile without <stdio.h>.
+ */
+
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef NEED_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <stdio.h>
+
+/*
+ * We need memory copying and zeroing functions, plus strncpy().
+ * ANSI and System V implementations declare these in <string.h>.
+ * BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
+ * Some systems may declare memset and memcpy in <memory.h>.
+ *
+ * NOTE: we assume the size parameters to these functions are of type size_t.
+ * Change the casts in these macros if not!
+ */
+
+#ifdef NEED_BSD_STRINGS
+
+#include <strings.h>
+#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size))
+#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size))
+
+#else /* not BSD, assume ANSI/SysV string lib */
+
+#include <string.h>
+#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size))
+#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size))
+
+#endif
+
+/*
+ * In ANSI C, and indeed any rational implementation, size_t is also the
+ * type returned by sizeof(). However, it seems there are some irrational
+ * implementations out there, in which sizeof() returns an int even though
+ * size_t is defined as long or unsigned long. To ensure consistent results
+ * we always use this SIZEOF() macro in place of using sizeof() directly.
+ */
+
+#define SIZEOF(object) ((size_t) sizeof(object))
+
+/*
+ * The modules that use fread() and fwrite() always invoke them through
+ * these macros. On some systems you may need to twiddle the argument casts.
+ * CAUTION: argument order is different from underlying functions!
+ */
+
+#define JFREAD(file,buf,sizeofbuf) \
+ ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
+#define JFWRITE(file,buf,sizeofbuf) \
+ ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
diff --git a/src/libjpeg-turbo/jmemmgr.c b/src/libjpeg-turbo/jmemmgr.c
new file mode 100644
index 0000000..cf32524
--- /dev/null
+++ b/src/libjpeg-turbo/jmemmgr.c
@@ -0,0 +1,1151 @@
+/*
+ * jmemmgr.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the JPEG system-independent memory management
+ * routines. This code is usable across a wide variety of machines; most
+ * of the system dependencies have been isolated in a separate file.
+ * The major functions provided here are:
+ * * pool-based allocation and freeing of memory;
+ * * policy decisions about how to divide available memory among the
+ * virtual arrays;
+ * * control logic for swapping virtual arrays between main memory and
+ * backing storage.
+ * The separate system-dependent file provides the actual backing-storage
+ * access code, and it contains the policy decision about how much total
+ * main memory to use.
+ * This file is system-dependent in the sense that some of its functions
+ * are unnecessary in some systems. For example, if there is enough virtual
+ * memory so that backing storage will never be used, much of the virtual
+ * array control logic could be removed. (Of course, if you have that much
+ * memory then you shouldn't care about a little bit of unused code...)
+ */
+
+#define JPEG_INTERNALS
+#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jmemsys.h" /* import the system-dependent declarations */
+
+#ifndef NO_GETENV
+#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare getenv() */
+extern char * getenv JPP((const char * name));
+#endif
+#endif
+
+
+LOCAL(size_t)
+round_up_pow2 (size_t a, size_t b)
+/* a rounded up to the next multiple of b, i.e. ceil(a/b)*b */
+/* Assumes a >= 0, b > 0, and b is a power of 2 */
+{
+ return ((a + b - 1) & (~(b - 1)));
+}
+
+
+/*
+ * Some important notes:
+ * The allocation routines provided here must never return NULL.
+ * They should exit to error_exit if unsuccessful.
+ *
+ * It's not a good idea to try to merge the sarray and barray routines,
+ * even though they are textually almost the same, because samples are
+ * usually stored as bytes while coefficients are shorts or ints. Thus,
+ * in machines where byte pointers have a different representation from
+ * word pointers, the resulting machine code could not be the same.
+ */
+
+
+/*
+ * Many machines require storage alignment: longs must start on 4-byte
+ * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc()
+ * always returns pointers that are multiples of the worst-case alignment
+ * requirement, and we had better do so too.
+ * There isn't any really portable way to determine the worst-case alignment
+ * requirement. This module assumes that the alignment requirement is
+ * multiples of ALIGN_SIZE.
+ * By default, we define ALIGN_SIZE as sizeof(double). This is necessary on some
+ * workstations (where doubles really do need 8-byte alignment) and will work
+ * fine on nearly everything. If your machine has lesser alignment needs,
+ * you can save a few bytes by making ALIGN_SIZE smaller.
+ * The only place I know of where this will NOT work is certain Macintosh
+ * 680x0 compilers that define double as a 10-byte IEEE extended float.
+ * Doing 10-byte alignment is counterproductive because longwords won't be
+ * aligned well. Put "#define ALIGN_SIZE 4" in jconfig.h if you have
+ * such a compiler.
+ */
+
+#ifndef ALIGN_SIZE /* so can override from jconfig.h */
+#ifndef WITH_SIMD
+#define ALIGN_SIZE SIZEOF(double)
+#else
+#define ALIGN_SIZE 16 /* Most SIMD implementations require this */
+#endif
+#endif
+
+/*
+ * We allocate objects from "pools", where each pool is gotten with a single
+ * request to jpeg_get_small() or jpeg_get_large(). There is no per-object
+ * overhead within a pool, except for alignment padding. Each pool has a
+ * header with a link to the next pool of the same class.
+ * Small and large pool headers are identical except that the latter's
+ * link pointer must be FAR on 80x86 machines.
+ */
+
+typedef struct small_pool_struct * small_pool_ptr;
+
+typedef struct small_pool_struct {
+ small_pool_ptr next; /* next in list of pools */
+ size_t bytes_used; /* how many bytes already used within pool */
+ size_t bytes_left; /* bytes still available in this pool */
+} small_pool_hdr;
+
+typedef struct large_pool_struct FAR * large_pool_ptr;
+
+typedef struct large_pool_struct {
+ large_pool_ptr next; /* next in list of pools */
+ size_t bytes_used; /* how many bytes already used within pool */
+ size_t bytes_left; /* bytes still available in this pool */
+} large_pool_hdr;
+
+/*
+ * Here is the full definition of a memory manager object.
+ */
+
+typedef struct {
+ struct jpeg_memory_mgr pub; /* public fields */
+
+ /* Each pool identifier (lifetime class) names a linked list of pools. */
+ small_pool_ptr small_list[JPOOL_NUMPOOLS];
+ large_pool_ptr large_list[JPOOL_NUMPOOLS];
+
+ /* Since we only have one lifetime class of virtual arrays, only one
+ * linked list is necessary (for each datatype). Note that the virtual
+ * array control blocks being linked together are actually stored somewhere
+ * in the small-pool list.
+ */
+ jvirt_sarray_ptr virt_sarray_list;
+ jvirt_barray_ptr virt_barray_list;
+
+ /* This counts total space obtained from jpeg_get_small/large */
+ size_t total_space_allocated;
+
+ /* alloc_sarray and alloc_barray set this value for use by virtual
+ * array routines.
+ */
+ JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */
+} my_memory_mgr;
+
+typedef my_memory_mgr * my_mem_ptr;
+
+
+/*
+ * The control blocks for virtual arrays.
+ * Note that these blocks are allocated in the "small" pool area.
+ * System-dependent info for the associated backing store (if any) is hidden
+ * inside the backing_store_info struct.
+ */
+
+struct jvirt_sarray_control {
+ JSAMPARRAY mem_buffer; /* => the in-memory buffer */
+ JDIMENSION rows_in_array; /* total virtual array height */
+ JDIMENSION samplesperrow; /* width of array (and of memory buffer) */
+ JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */
+ JDIMENSION rows_in_mem; /* height of memory buffer */
+ JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
+ JDIMENSION cur_start_row; /* first logical row # in the buffer */
+ JDIMENSION first_undef_row; /* row # of first uninitialized row */
+ boolean pre_zero; /* pre-zero mode requested? */
+ boolean dirty; /* do current buffer contents need written? */
+ boolean b_s_open; /* is backing-store data valid? */
+ jvirt_sarray_ptr next; /* link to next virtual sarray control block */
+ backing_store_info b_s_info; /* System-dependent control info */
+};
+
+struct jvirt_barray_control {
+ JBLOCKARRAY mem_buffer; /* => the in-memory buffer */
+ JDIMENSION rows_in_array; /* total virtual array height */
+ JDIMENSION blocksperrow; /* width of array (and of memory buffer) */
+ JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */
+ JDIMENSION rows_in_mem; /* height of memory buffer */
+ JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
+ JDIMENSION cur_start_row; /* first logical row # in the buffer */
+ JDIMENSION first_undef_row; /* row # of first uninitialized row */
+ boolean pre_zero; /* pre-zero mode requested? */
+ boolean dirty; /* do current buffer contents need written? */
+ boolean b_s_open; /* is backing-store data valid? */
+ jvirt_barray_ptr next; /* link to next virtual barray control block */
+ backing_store_info b_s_info; /* System-dependent control info */
+};
+
+
+#ifdef MEM_STATS /* optional extra stuff for statistics */
+
+LOCAL(void)
+print_mem_stats (j_common_ptr cinfo, int pool_id)
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ small_pool_ptr shdr_ptr;
+ large_pool_ptr lhdr_ptr;
+
+ /* Since this is only a debugging stub, we can cheat a little by using
+ * fprintf directly rather than going through the trace message code.
+ * This is helpful because message parm array can't handle longs.
+ */
+ fprintf(stderr, "Freeing pool %d, total space = %ld\n",
+ pool_id, mem->total_space_allocated);
+
+ for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
+ lhdr_ptr = lhdr_ptr->next) {
+ fprintf(stderr, " Large chunk used %ld\n",
+ (long) lhdr_ptr->bytes_used);
+ }
+
+ for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
+ shdr_ptr = shdr_ptr->next) {
+ fprintf(stderr, " Small chunk used %ld free %ld\n",
+ (long) shdr_ptr->bytes_used,
+ (long) shdr_ptr->bytes_left);
+ }
+}
+
+#endif /* MEM_STATS */
+
+
+LOCAL(void)
+out_of_memory (j_common_ptr cinfo, int which)
+/* Report an out-of-memory error and stop execution */
+/* If we compiled MEM_STATS support, report alloc requests before dying */
+{
+#ifdef MEM_STATS
+ cinfo->err->trace_level = 2; /* force self_destruct to report stats */
+#endif
+ ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which);
+}
+
+
+/*
+ * Allocation of "small" objects.
+ *
+ * For these, we use pooled storage. When a new pool must be created,
+ * we try to get enough space for the current request plus a "slop" factor,
+ * where the slop will be the amount of leftover space in the new pool.
+ * The speed vs. space tradeoff is largely determined by the slop values.
+ * A different slop value is provided for each pool class (lifetime),
+ * and we also distinguish the first pool of a class from later ones.
+ * NOTE: the values given work fairly well on both 16- and 32-bit-int
+ * machines, but may be too small if longs are 64 bits or more.
+ *
+ * Since we do not know what alignment malloc() gives us, we have to
+ * allocate ALIGN_SIZE-1 extra space per pool to have room for alignment
+ * adjustment.
+ */
+
+static const size_t first_pool_slop[JPOOL_NUMPOOLS] =
+{
+ 1600, /* first PERMANENT pool */
+ 16000 /* first IMAGE pool */
+};
+
+static const size_t extra_pool_slop[JPOOL_NUMPOOLS] =
+{
+ 0, /* additional PERMANENT pools */
+ 5000 /* additional IMAGE pools */
+};
+
+#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */
+
+
+METHODDEF(void *)
+alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
+/* Allocate a "small" object */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ small_pool_ptr hdr_ptr, prev_hdr_ptr;
+ char * data_ptr;
+ size_t min_request, slop;
+
+ /*
+ * Round up the requested size to a multiple of ALIGN_SIZE in order
+ * to assure alignment for the next object allocated in the same pool
+ * and so that algorithms can straddle outside the proper area up
+ * to the next alignment.
+ */
+ sizeofobject = round_up_pow2(sizeofobject, ALIGN_SIZE);
+
+ /* Check for unsatisfiable request (do now to ensure no overflow below) */
+ if ((SIZEOF(small_pool_hdr) + sizeofobject + ALIGN_SIZE - 1) > MAX_ALLOC_CHUNK)
+ out_of_memory(cinfo, 1); /* request exceeds malloc's ability */
+
+ /* See if space is available in any existing pool */
+ if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
+ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
+ prev_hdr_ptr = NULL;
+ hdr_ptr = mem->small_list[pool_id];
+ while (hdr_ptr != NULL) {
+ if (hdr_ptr->bytes_left >= sizeofobject)
+ break; /* found pool with enough space */
+ prev_hdr_ptr = hdr_ptr;
+ hdr_ptr = hdr_ptr->next;
+ }
+
+ /* Time to make a new pool? */
+ if (hdr_ptr == NULL) {
+ /* min_request is what we need now, slop is what will be leftover */
+ min_request = SIZEOF(small_pool_hdr) + sizeofobject + ALIGN_SIZE - 1;
+ if (prev_hdr_ptr == NULL) /* first pool in class? */
+ slop = first_pool_slop[pool_id];
+ else
+ slop = extra_pool_slop[pool_id];
+ /* Don't ask for more than MAX_ALLOC_CHUNK */
+ if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
+ slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
+ /* Try to get space, if fail reduce slop and try again */
+ for (;;) {
+ hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
+ if (hdr_ptr != NULL)
+ break;
+ slop /= 2;
+ if (slop < MIN_SLOP) /* give up when it gets real small */
+ out_of_memory(cinfo, 2); /* jpeg_get_small failed */
+ }
+ mem->total_space_allocated += min_request + slop;
+ /* Success, initialize the new pool header and add to end of list */
+ hdr_ptr->next = NULL;
+ hdr_ptr->bytes_used = 0;
+ hdr_ptr->bytes_left = sizeofobject + slop;
+ if (prev_hdr_ptr == NULL) /* first pool in class? */
+ mem->small_list[pool_id] = hdr_ptr;
+ else
+ prev_hdr_ptr->next = hdr_ptr;
+ }
+
+ /* OK, allocate the object from the current pool */
+ data_ptr = (char *) hdr_ptr; /* point to first data byte in pool... */
+ data_ptr += SIZEOF(small_pool_hdr); /* ...by skipping the header... */
+ if ((size_t)data_ptr % ALIGN_SIZE) /* ...and adjust for alignment */
+ data_ptr += ALIGN_SIZE - (size_t)data_ptr % ALIGN_SIZE;
+ data_ptr += hdr_ptr->bytes_used; /* point to place for object */
+ hdr_ptr->bytes_used += sizeofobject;
+ hdr_ptr->bytes_left -= sizeofobject;
+
+ return (void *) data_ptr;
+}
+
+
+/*
+ * Allocation of "large" objects.
+ *
+ * The external semantics of these are the same as "small" objects,
+ * except that FAR pointers are used on 80x86. However the pool
+ * management heuristics are quite different. We assume that each
+ * request is large enough that it may as well be passed directly to
+ * jpeg_get_large; the pool management just links everything together
+ * so that we can free it all on demand.
+ * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
+ * structures. The routines that create these structures (see below)
+ * deliberately bunch rows together to ensure a large request size.
+ */
+
+METHODDEF(void FAR *)
+alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
+/* Allocate a "large" object */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ large_pool_ptr hdr_ptr;
+ char FAR * data_ptr;
+
+ /*
+ * Round up the requested size to a multiple of ALIGN_SIZE so that
+ * algorithms can straddle outside the proper area up to the next
+ * alignment.
+ */
+ sizeofobject = round_up_pow2(sizeofobject, ALIGN_SIZE);
+
+ /* Check for unsatisfiable request (do now to ensure no overflow below) */
+ if ((SIZEOF(large_pool_hdr) + sizeofobject + ALIGN_SIZE - 1) > MAX_ALLOC_CHUNK)
+ out_of_memory(cinfo, 3); /* request exceeds malloc's ability */
+
+ /* Always make a new pool */
+ if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
+ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
+
+ hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
+ SIZEOF(large_pool_hdr) +
+ ALIGN_SIZE - 1);
+ if (hdr_ptr == NULL)
+ out_of_memory(cinfo, 4); /* jpeg_get_large failed */
+ mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr) + ALIGN_SIZE - 1;
+
+ /* Success, initialize the new pool header and add to list */
+ hdr_ptr->next = mem->large_list[pool_id];
+ /* We maintain space counts in each pool header for statistical purposes,
+ * even though they are not needed for allocation.
+ */
+ hdr_ptr->bytes_used = sizeofobject;
+ hdr_ptr->bytes_left = 0;
+ mem->large_list[pool_id] = hdr_ptr;
+
+ data_ptr = (char *) hdr_ptr; /* point to first data byte in pool... */
+ data_ptr += SIZEOF(small_pool_hdr); /* ...by skipping the header... */
+ if ((size_t)data_ptr % ALIGN_SIZE) /* ...and adjust for alignment */
+ data_ptr += ALIGN_SIZE - (size_t)data_ptr % ALIGN_SIZE;
+
+ return (void FAR *) data_ptr;
+}
+
+
+/*
+ * Creation of 2-D sample arrays.
+ * The pointers are in near heap, the samples themselves in FAR heap.
+ *
+ * To minimize allocation overhead and to allow I/O of large contiguous
+ * blocks, we allocate the sample rows in groups of as many rows as possible
+ * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
+ * NB: the virtual array control routines, later in this file, know about
+ * this chunking of rows. The rowsperchunk value is left in the mem manager
+ * object so that it can be saved away if this sarray is the workspace for
+ * a virtual array.
+ *
+ * Since we are often upsampling with a factor 2, we align the size (not
+ * the start) to 2 * ALIGN_SIZE so that the upsampling routines don't have
+ * to be as careful about size.
+ */
+
+METHODDEF(JSAMPARRAY)
+alloc_sarray (j_common_ptr cinfo, int pool_id,
+ JDIMENSION samplesperrow, JDIMENSION numrows)
+/* Allocate a 2-D sample array */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ JSAMPARRAY result;
+ JSAMPROW workspace;
+ JDIMENSION rowsperchunk, currow, i;
+ long ltemp;
+
+ /* Make sure each row is properly aligned */
+ if ((ALIGN_SIZE % SIZEOF(JSAMPLE)) != 0)
+ out_of_memory(cinfo, 5); /* safety check */
+ samplesperrow = (JDIMENSION)round_up_pow2(samplesperrow, (2 * ALIGN_SIZE) / SIZEOF(JSAMPLE));
+
+ /* Calculate max # of rows allowed in one allocation chunk */
+ ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
+ ((long) samplesperrow * SIZEOF(JSAMPLE));
+ if (ltemp <= 0)
+ ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+ if (ltemp < (long) numrows)
+ rowsperchunk = (JDIMENSION) ltemp;
+ else
+ rowsperchunk = numrows;
+ mem->last_rowsperchunk = rowsperchunk;
+
+ /* Get space for row pointers (small object) */
+ result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
+ (size_t) (numrows * SIZEOF(JSAMPROW)));
+
+ /* Get the rows themselves (large objects) */
+ currow = 0;
+ while (currow < numrows) {
+ rowsperchunk = MIN(rowsperchunk, numrows - currow);
+ workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
+ (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
+ * SIZEOF(JSAMPLE)));
+ for (i = rowsperchunk; i > 0; i--) {
+ result[currow++] = workspace;
+ workspace += samplesperrow;
+ }
+ }
+
+ return result;
+}
+
+
+/*
+ * Creation of 2-D coefficient-block arrays.
+ * This is essentially the same as the code for sample arrays, above.
+ */
+
+METHODDEF(JBLOCKARRAY)
+alloc_barray (j_common_ptr cinfo, int pool_id,
+ JDIMENSION blocksperrow, JDIMENSION numrows)
+/* Allocate a 2-D coefficient-block array */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ JBLOCKARRAY result;
+ JBLOCKROW workspace;
+ JDIMENSION rowsperchunk, currow, i;
+ long ltemp;
+
+ /* Make sure each row is properly aligned */
+ if ((SIZEOF(JBLOCK) % ALIGN_SIZE) != 0)
+ out_of_memory(cinfo, 6); /* safety check */
+
+ /* Calculate max # of rows allowed in one allocation chunk */
+ ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
+ ((long) blocksperrow * SIZEOF(JBLOCK));
+ if (ltemp <= 0)
+ ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+ if (ltemp < (long) numrows)
+ rowsperchunk = (JDIMENSION) ltemp;
+ else
+ rowsperchunk = numrows;
+ mem->last_rowsperchunk = rowsperchunk;
+
+ /* Get space for row pointers (small object) */
+ result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
+ (size_t) (numrows * SIZEOF(JBLOCKROW)));
+
+ /* Get the rows themselves (large objects) */
+ currow = 0;
+ while (currow < numrows) {
+ rowsperchunk = MIN(rowsperchunk, numrows - currow);
+ workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
+ (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
+ * SIZEOF(JBLOCK)));
+ for (i = rowsperchunk; i > 0; i--) {
+ result[currow++] = workspace;
+ workspace += blocksperrow;
+ }
+ }
+
+ return result;
+}
+
+
+/*
+ * About virtual array management:
+ *
+ * The above "normal" array routines are only used to allocate strip buffers
+ * (as wide as the image, but just a few rows high). Full-image-sized buffers
+ * are handled as "virtual" arrays. The array is still accessed a strip at a
+ * time, but the memory manager must save the whole array for repeated
+ * accesses. The intended implementation is that there is a strip buffer in
+ * memory (as high as is possible given the desired memory limit), plus a
+ * backing file that holds the rest of the array.
+ *
+ * The request_virt_array routines are told the total size of the image and
+ * the maximum number of rows that will be accessed at once. The in-memory
+ * buffer must be at least as large as the maxaccess value.
+ *
+ * The request routines create control blocks but not the in-memory buffers.
+ * That is postponed until realize_virt_arrays is called. At that time the
+ * total amount of space needed is known (approximately, anyway), so free
+ * memory can be divided up fairly.
+ *
+ * The access_virt_array routines are responsible for making a specific strip
+ * area accessible (after reading or writing the backing file, if necessary).
+ * Note that the access routines are told whether the caller intends to modify
+ * the accessed strip; during a read-only pass this saves having to rewrite
+ * data to disk. The access routines are also responsible for pre-zeroing
+ * any newly accessed rows, if pre-zeroing was requested.
+ *
+ * In current usage, the access requests are usually for nonoverlapping
+ * strips; that is, successive access start_row numbers differ by exactly
+ * num_rows = maxaccess. This means we can get good performance with simple
+ * buffer dump/reload logic, by making the in-memory buffer be a multiple
+ * of the access height; then there will never be accesses across bufferload
+ * boundaries. The code will still work with overlapping access requests,
+ * but it doesn't handle bufferload overlaps very efficiently.
+ */
+
+
+METHODDEF(jvirt_sarray_ptr)
+request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
+ JDIMENSION samplesperrow, JDIMENSION numrows,
+ JDIMENSION maxaccess)
+/* Request a virtual 2-D sample array */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ jvirt_sarray_ptr result;
+
+ /* Only IMAGE-lifetime virtual arrays are currently supported */
+ if (pool_id != JPOOL_IMAGE)
+ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
+
+ /* get control block */
+ result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id,
+ SIZEOF(struct jvirt_sarray_control));
+
+ result->mem_buffer = NULL; /* marks array not yet realized */
+ result->rows_in_array = numrows;
+ result->samplesperrow = samplesperrow;
+ result->maxaccess = maxaccess;
+ result->pre_zero = pre_zero;
+ result->b_s_open = FALSE; /* no associated backing-store object */
+ result->next = mem->virt_sarray_list; /* add to list of virtual arrays */
+ mem->virt_sarray_list = result;
+
+ return result;
+}
+
+
+METHODDEF(jvirt_barray_ptr)
+request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
+ JDIMENSION blocksperrow, JDIMENSION numrows,
+ JDIMENSION maxaccess)
+/* Request a virtual 2-D coefficient-block array */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ jvirt_barray_ptr result;
+
+ /* Only IMAGE-lifetime virtual arrays are currently supported */
+ if (pool_id != JPOOL_IMAGE)
+ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
+
+ /* get control block */
+ result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
+ SIZEOF(struct jvirt_barray_control));
+
+ result->mem_buffer = NULL; /* marks array not yet realized */
+ result->rows_in_array = numrows;
+ result->blocksperrow = blocksperrow;
+ result->maxaccess = maxaccess;
+ result->pre_zero = pre_zero;
+ result->b_s_open = FALSE; /* no associated backing-store object */
+ result->next = mem->virt_barray_list; /* add to list of virtual arrays */
+ mem->virt_barray_list = result;
+
+ return result;
+}
+
+
+METHODDEF(void)
+realize_virt_arrays (j_common_ptr cinfo)
+/* Allocate the in-memory buffers for any unrealized virtual arrays */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ size_t space_per_minheight, maximum_space, avail_mem;
+ size_t minheights, max_minheights;
+ jvirt_sarray_ptr sptr;
+ jvirt_barray_ptr bptr;
+
+ /* Compute the minimum space needed (maxaccess rows in each buffer)
+ * and the maximum space needed (full image height in each buffer).
+ * These may be of use to the system-dependent jpeg_mem_available routine.
+ */
+ space_per_minheight = 0;
+ maximum_space = 0;
+ for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
+ if (sptr->mem_buffer == NULL) { /* if not realized yet */
+ space_per_minheight += (long) sptr->maxaccess *
+ (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
+ maximum_space += (long) sptr->rows_in_array *
+ (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
+ }
+ }
+ for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
+ if (bptr->mem_buffer == NULL) { /* if not realized yet */
+ space_per_minheight += (long) bptr->maxaccess *
+ (long) bptr->blocksperrow * SIZEOF(JBLOCK);
+ maximum_space += (long) bptr->rows_in_array *
+ (long) bptr->blocksperrow * SIZEOF(JBLOCK);
+ }
+ }
+
+ if (space_per_minheight <= 0)
+ return; /* no unrealized arrays, no work */
+
+ /* Determine amount of memory to actually use; this is system-dependent. */
+ avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
+ mem->total_space_allocated);
+
+ /* If the maximum space needed is available, make all the buffers full
+ * height; otherwise parcel it out with the same number of minheights
+ * in each buffer.
+ */
+ if (avail_mem >= maximum_space)
+ max_minheights = 1000000000L;
+ else {
+ max_minheights = avail_mem / space_per_minheight;
+ /* If there doesn't seem to be enough space, try to get the minimum
+ * anyway. This allows a "stub" implementation of jpeg_mem_available().
+ */
+ if (max_minheights <= 0)
+ max_minheights = 1;
+ }
+
+ /* Allocate the in-memory buffers and initialize backing store as needed. */
+
+ for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
+ if (sptr->mem_buffer == NULL) { /* if not realized yet */
+ minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L;
+ if (minheights <= max_minheights) {
+ /* This buffer fits in memory */
+ sptr->rows_in_mem = sptr->rows_in_array;
+ } else {
+ /* It doesn't fit in memory, create backing store. */
+ sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess);
+ jpeg_open_backing_store(cinfo, & sptr->b_s_info,
+ (long) sptr->rows_in_array *
+ (long) sptr->samplesperrow *
+ (long) SIZEOF(JSAMPLE));
+ sptr->b_s_open = TRUE;
+ }
+ sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
+ sptr->samplesperrow, sptr->rows_in_mem);
+ sptr->rowsperchunk = mem->last_rowsperchunk;
+ sptr->cur_start_row = 0;
+ sptr->first_undef_row = 0;
+ sptr->dirty = FALSE;
+ }
+ }
+
+ for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
+ if (bptr->mem_buffer == NULL) { /* if not realized yet */
+ minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L;
+ if (minheights <= max_minheights) {
+ /* This buffer fits in memory */
+ bptr->rows_in_mem = bptr->rows_in_array;
+ } else {
+ /* It doesn't fit in memory, create backing store. */
+ bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess);
+ jpeg_open_backing_store(cinfo, & bptr->b_s_info,
+ (long) bptr->rows_in_array *
+ (long) bptr->blocksperrow *
+ (long) SIZEOF(JBLOCK));
+ bptr->b_s_open = TRUE;
+ }
+ bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE,
+ bptr->blocksperrow, bptr->rows_in_mem);
+ bptr->rowsperchunk = mem->last_rowsperchunk;
+ bptr->cur_start_row = 0;
+ bptr->first_undef_row = 0;
+ bptr->dirty = FALSE;
+ }
+ }
+}
+
+
+LOCAL(void)
+do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
+/* Do backing store read or write of a virtual sample array */
+{
+ long bytesperrow, file_offset, byte_count, rows, thisrow, i;
+
+ bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
+ file_offset = ptr->cur_start_row * bytesperrow;
+ /* Loop to read or write each allocation chunk in mem_buffer */
+ for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
+ /* One chunk, but check for short chunk at end of buffer */
+ rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
+ /* Transfer no more than is currently defined */
+ thisrow = (long) ptr->cur_start_row + i;
+ rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
+ /* Transfer no more than fits in file */
+ rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
+ if (rows <= 0) /* this chunk might be past end of file! */
+ break;
+ byte_count = rows * bytesperrow;
+ if (writing)
+ (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
+ (void FAR *) ptr->mem_buffer[i],
+ file_offset, byte_count);
+ else
+ (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
+ (void FAR *) ptr->mem_buffer[i],
+ file_offset, byte_count);
+ file_offset += byte_count;
+ }
+}
+
+
+LOCAL(void)
+do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
+/* Do backing store read or write of a virtual coefficient-block array */
+{
+ long bytesperrow, file_offset, byte_count, rows, thisrow, i;
+
+ bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
+ file_offset = ptr->cur_start_row * bytesperrow;
+ /* Loop to read or write each allocation chunk in mem_buffer */
+ for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
+ /* One chunk, but check for short chunk at end of buffer */
+ rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
+ /* Transfer no more than is currently defined */
+ thisrow = (long) ptr->cur_start_row + i;
+ rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
+ /* Transfer no more than fits in file */
+ rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
+ if (rows <= 0) /* this chunk might be past end of file! */
+ break;
+ byte_count = rows * bytesperrow;
+ if (writing)
+ (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
+ (void FAR *) ptr->mem_buffer[i],
+ file_offset, byte_count);
+ else
+ (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
+ (void FAR *) ptr->mem_buffer[i],
+ file_offset, byte_count);
+ file_offset += byte_count;
+ }
+}
+
+
+METHODDEF(JSAMPARRAY)
+access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
+ JDIMENSION start_row, JDIMENSION num_rows,
+ boolean writable)
+/* Access the part of a virtual sample array starting at start_row */
+/* and extending for num_rows rows. writable is true if */
+/* caller intends to modify the accessed area. */
+{
+ JDIMENSION end_row = start_row + num_rows;
+ JDIMENSION undef_row;
+
+ /* debugging check */
+ if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
+ ptr->mem_buffer == NULL)
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+
+ /* Make the desired part of the virtual array accessible */
+ if (start_row < ptr->cur_start_row ||
+ end_row > ptr->cur_start_row+ptr->rows_in_mem) {
+ if (! ptr->b_s_open)
+ ERREXIT(cinfo, JERR_VIRTUAL_BUG);
+ /* Flush old buffer contents if necessary */
+ if (ptr->dirty) {
+ do_sarray_io(cinfo, ptr, TRUE);
+ ptr->dirty = FALSE;
+ }
+ /* Decide what part of virtual array to access.
+ * Algorithm: if target address > current window, assume forward scan,
+ * load starting at target address. If target address < current window,
+ * assume backward scan, load so that target area is top of window.
+ * Note that when switching from forward write to forward read, will have
+ * start_row = 0, so the limiting case applies and we load from 0 anyway.
+ */
+ if (start_row > ptr->cur_start_row) {
+ ptr->cur_start_row = start_row;
+ } else {
+ /* use long arithmetic here to avoid overflow & unsigned problems */
+ long ltemp;
+
+ ltemp = (long) end_row - (long) ptr->rows_in_mem;
+ if (ltemp < 0)
+ ltemp = 0; /* don't fall off front end of file */
+ ptr->cur_start_row = (JDIMENSION) ltemp;
+ }
+ /* Read in the selected part of the array.
+ * During the initial write pass, we will do no actual read
+ * because the selected part is all undefined.
+ */
+ do_sarray_io(cinfo, ptr, FALSE);
+ }
+ /* Ensure the accessed part of the array is defined; prezero if needed.
+ * To improve locality of access, we only prezero the part of the array
+ * that the caller is about to access, not the entire in-memory array.
+ */
+ if (ptr->first_undef_row < end_row) {
+ if (ptr->first_undef_row < start_row) {
+ if (writable) /* writer skipped over a section of array */
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+ undef_row = start_row; /* but reader is allowed to read ahead */
+ } else {
+ undef_row = ptr->first_undef_row;
+ }
+ if (writable)
+ ptr->first_undef_row = end_row;
+ if (ptr->pre_zero) {
+ size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE);
+ undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
+ end_row -= ptr->cur_start_row;
+ while (undef_row < end_row) {
+ jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
+ undef_row++;
+ }
+ } else {
+ if (! writable) /* reader looking at undefined data */
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+ }
+ }
+ /* Flag the buffer dirty if caller will write in it */
+ if (writable)
+ ptr->dirty = TRUE;
+ /* Return address of proper part of the buffer */
+ return ptr->mem_buffer + (start_row - ptr->cur_start_row);
+}
+
+
+METHODDEF(JBLOCKARRAY)
+access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
+ JDIMENSION start_row, JDIMENSION num_rows,
+ boolean writable)
+/* Access the part of a virtual block array starting at start_row */
+/* and extending for num_rows rows. writable is true if */
+/* caller intends to modify the accessed area. */
+{
+ JDIMENSION end_row = start_row + num_rows;
+ JDIMENSION undef_row;
+
+ /* debugging check */
+ if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
+ ptr->mem_buffer == NULL)
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+
+ /* Make the desired part of the virtual array accessible */
+ if (start_row < ptr->cur_start_row ||
+ end_row > ptr->cur_start_row+ptr->rows_in_mem) {
+ if (! ptr->b_s_open)
+ ERREXIT(cinfo, JERR_VIRTUAL_BUG);
+ /* Flush old buffer contents if necessary */
+ if (ptr->dirty) {
+ do_barray_io(cinfo, ptr, TRUE);
+ ptr->dirty = FALSE;
+ }
+ /* Decide what part of virtual array to access.
+ * Algorithm: if target address > current window, assume forward scan,
+ * load starting at target address. If target address < current window,
+ * assume backward scan, load so that target area is top of window.
+ * Note that when switching from forward write to forward read, will have
+ * start_row = 0, so the limiting case applies and we load from 0 anyway.
+ */
+ if (start_row > ptr->cur_start_row) {
+ ptr->cur_start_row = start_row;
+ } else {
+ /* use long arithmetic here to avoid overflow & unsigned problems */
+ long ltemp;
+
+ ltemp = (long) end_row - (long) ptr->rows_in_mem;
+ if (ltemp < 0)
+ ltemp = 0; /* don't fall off front end of file */
+ ptr->cur_start_row = (JDIMENSION) ltemp;
+ }
+ /* Read in the selected part of the array.
+ * During the initial write pass, we will do no actual read
+ * because the selected part is all undefined.
+ */
+ do_barray_io(cinfo, ptr, FALSE);
+ }
+ /* Ensure the accessed part of the array is defined; prezero if needed.
+ * To improve locality of access, we only prezero the part of the array
+ * that the caller is about to access, not the entire in-memory array.
+ */
+ if (ptr->first_undef_row < end_row) {
+ if (ptr->first_undef_row < start_row) {
+ if (writable) /* writer skipped over a section of array */
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+ undef_row = start_row; /* but reader is allowed to read ahead */
+ } else {
+ undef_row = ptr->first_undef_row;
+ }
+ if (writable)
+ ptr->first_undef_row = end_row;
+ if (ptr->pre_zero) {
+ size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK);
+ undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
+ end_row -= ptr->cur_start_row;
+ while (undef_row < end_row) {
+ jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
+ undef_row++;
+ }
+ } else {
+ if (! writable) /* reader looking at undefined data */
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+ }
+ }
+ /* Flag the buffer dirty if caller will write in it */
+ if (writable)
+ ptr->dirty = TRUE;
+ /* Return address of proper part of the buffer */
+ return ptr->mem_buffer + (start_row - ptr->cur_start_row);
+}
+
+
+/*
+ * Release all objects belonging to a specified pool.
+ */
+
+METHODDEF(void)
+free_pool (j_common_ptr cinfo, int pool_id)
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ small_pool_ptr shdr_ptr;
+ large_pool_ptr lhdr_ptr;
+ size_t space_freed;
+
+ if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
+ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
+
+#ifdef MEM_STATS
+ if (cinfo->err->trace_level > 1)
+ print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */
+#endif
+
+ /* If freeing IMAGE pool, close any virtual arrays first */
+ if (pool_id == JPOOL_IMAGE) {
+ jvirt_sarray_ptr sptr;
+ jvirt_barray_ptr bptr;
+
+ for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
+ if (sptr->b_s_open) { /* there may be no backing store */
+ sptr->b_s_open = FALSE; /* prevent recursive close if error */
+ (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info);
+ }
+ }
+ mem->virt_sarray_list = NULL;
+ for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
+ if (bptr->b_s_open) { /* there may be no backing store */
+ bptr->b_s_open = FALSE; /* prevent recursive close if error */
+ (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info);
+ }
+ }
+ mem->virt_barray_list = NULL;
+ }
+
+ /* Release large objects */
+ lhdr_ptr = mem->large_list[pool_id];
+ mem->large_list[pool_id] = NULL;
+
+ while (lhdr_ptr != NULL) {
+ large_pool_ptr next_lhdr_ptr = lhdr_ptr->next;
+ space_freed = lhdr_ptr->bytes_used +
+ lhdr_ptr->bytes_left +
+ SIZEOF(large_pool_hdr);
+ jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
+ mem->total_space_allocated -= space_freed;
+ lhdr_ptr = next_lhdr_ptr;
+ }
+
+ /* Release small objects */
+ shdr_ptr = mem->small_list[pool_id];
+ mem->small_list[pool_id] = NULL;
+
+ while (shdr_ptr != NULL) {
+ small_pool_ptr next_shdr_ptr = shdr_ptr->next;
+ space_freed = shdr_ptr->bytes_used +
+ shdr_ptr->bytes_left +
+ SIZEOF(small_pool_hdr);
+ jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
+ mem->total_space_allocated -= space_freed;
+ shdr_ptr = next_shdr_ptr;
+ }
+}
+
+
+/*
+ * Close up shop entirely.
+ * Note that this cannot be called unless cinfo->mem is non-NULL.
+ */
+
+METHODDEF(void)
+self_destruct (j_common_ptr cinfo)
+{
+ int pool;
+
+ /* Close all backing store, release all memory.
+ * Releasing pools in reverse order might help avoid fragmentation
+ * with some (brain-damaged) malloc libraries.
+ */
+ for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
+ free_pool(cinfo, pool);
+ }
+
+ /* Release the memory manager control block too. */
+ jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr));
+ cinfo->mem = NULL; /* ensures I will be called only once */
+
+ jpeg_mem_term(cinfo); /* system-dependent cleanup */
+}
+
+
+/*
+ * Memory manager initialization.
+ * When this is called, only the error manager pointer is valid in cinfo!
+ */
+
+GLOBAL(void)
+jinit_memory_mgr (j_common_ptr cinfo)
+{
+ my_mem_ptr mem;
+ long max_to_use;
+ int pool;
+ size_t test_mac;
+
+ cinfo->mem = NULL; /* for safety if init fails */
+
+ /* Check for configuration errors.
+ * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
+ * doesn't reflect any real hardware alignment requirement.
+ * The test is a little tricky: for X>0, X and X-1 have no one-bits
+ * in common if and only if X is a power of 2, ie has only one one-bit.
+ * Some compilers may give an "unreachable code" warning here; ignore it.
+ */
+ if ((ALIGN_SIZE & (ALIGN_SIZE-1)) != 0)
+ ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
+ /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
+ * a multiple of ALIGN_SIZE.
+ * Again, an "unreachable code" warning may be ignored here.
+ * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
+ */
+ test_mac = (size_t) MAX_ALLOC_CHUNK;
+ if ((long) test_mac != MAX_ALLOC_CHUNK ||
+ (MAX_ALLOC_CHUNK % ALIGN_SIZE) != 0)
+ ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
+
+ max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
+
+ /* Attempt to allocate memory manager's control block */
+ mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr));
+
+ if (mem == NULL) {
+ jpeg_mem_term(cinfo); /* system-dependent cleanup */
+ ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
+ }
+
+ /* OK, fill in the method pointers */
+ mem->pub.alloc_small = alloc_small;
+ mem->pub.alloc_large = alloc_large;
+ mem->pub.alloc_sarray = alloc_sarray;
+ mem->pub.alloc_barray = alloc_barray;
+ mem->pub.request_virt_sarray = request_virt_sarray;
+ mem->pub.request_virt_barray = request_virt_barray;
+ mem->pub.realize_virt_arrays = realize_virt_arrays;
+ mem->pub.access_virt_sarray = access_virt_sarray;
+ mem->pub.access_virt_barray = access_virt_barray;
+ mem->pub.free_pool = free_pool;
+ mem->pub.self_destruct = self_destruct;
+
+ /* Make MAX_ALLOC_CHUNK accessible to other modules */
+ mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK;
+
+ /* Initialize working state */
+ mem->pub.max_memory_to_use = max_to_use;
+
+ for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
+ mem->small_list[pool] = NULL;
+ mem->large_list[pool] = NULL;
+ }
+ mem->virt_sarray_list = NULL;
+ mem->virt_barray_list = NULL;
+
+ mem->total_space_allocated = SIZEOF(my_memory_mgr);
+
+ /* Declare ourselves open for business */
+ cinfo->mem = & mem->pub;
+
+ /* Check for an environment variable JPEGMEM; if found, override the
+ * default max_memory setting from jpeg_mem_init. Note that the
+ * surrounding application may again override this value.
+ * If your system doesn't support getenv(), define NO_GETENV to disable
+ * this feature.
+ */
+#ifndef NO_GETENV
+ { char * memenv;
+
+ if ((memenv = getenv("JPEGMEM")) != NULL) {
+ char ch = 'x';
+
+ if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) {
+ if (ch == 'm' || ch == 'M')
+ max_to_use *= 1000L;
+ mem->pub.max_memory_to_use = max_to_use * 1000L;
+ }
+ }
+ }
+#endif
+
+}
diff --git a/src/libjpeg-turbo/jmemnobs.c b/src/libjpeg-turbo/jmemnobs.c
new file mode 100644
index 0000000..34b1895
--- /dev/null
+++ b/src/libjpeg-turbo/jmemnobs.c
@@ -0,0 +1,109 @@
+/*
+ * jmemnobs.c
+ *
+ * Copyright (C) 1992-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file provides a really simple implementation of the system-
+ * dependent portion of the JPEG memory manager. This implementation
+ * assumes that no backing-store files are needed: all required space
+ * can be obtained from malloc().
+ * This is very portable in the sense that it'll compile on almost anything,
+ * but you'd better have lots of main memory (or virtual memory) if you want
+ * to process big images.
+ * Note that the max_memory_to_use option is ignored by this implementation.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jmemsys.h" /* import the system-dependent declarations */
+
+#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
+extern void * malloc JPP((size_t size));
+extern void free JPP((void *ptr));
+#endif
+
+
+/*
+ * Memory allocation and freeing are controlled by the regular library
+ * routines malloc() and free().
+ */
+
+GLOBAL(void *)
+jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
+{
+ return (void *) malloc(sizeofobject);
+}
+
+GLOBAL(void)
+jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
+{
+ free(object);
+}
+
+
+/*
+ * "Large" objects are treated the same as "small" ones.
+ * NB: although we include FAR keywords in the routine declarations,
+ * this file won't actually work in 80x86 small/medium model; at least,
+ * you probably won't be able to process useful-size images in only 64KB.
+ */
+
+GLOBAL(void FAR *)
+jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
+{
+ return (void FAR *) malloc(sizeofobject);
+}
+
+GLOBAL(void)
+jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
+{
+ free(object);
+}
+
+
+/*
+ * This routine computes the total memory space available for allocation.
+ * Here we always say, "we got all you want bud!"
+ */
+
+GLOBAL(size_t)
+jpeg_mem_available (j_common_ptr cinfo, size_t min_bytes_needed,
+ size_t max_bytes_needed, size_t already_allocated)
+{
+ return max_bytes_needed;
+}
+
+
+/*
+ * Backing store (temporary file) management.
+ * Since jpeg_mem_available always promised the moon,
+ * this should never be called and we can just error out.
+ */
+
+GLOBAL(void)
+jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
+ long total_bytes_needed)
+{
+ ERREXIT(cinfo, JERR_NO_BACKING_STORE);
+}
+
+
+/*
+ * These routines take care of any system-dependent initialization and
+ * cleanup required. Here, there isn't any.
+ */
+
+GLOBAL(long)
+jpeg_mem_init (j_common_ptr cinfo)
+{
+ return 0; /* just set max_memory_to_use to 0 */
+}
+
+GLOBAL(void)
+jpeg_mem_term (j_common_ptr cinfo)
+{
+ /* no work */
+}
diff --git a/src/libjpeg-turbo/jmemsys.h b/src/libjpeg-turbo/jmemsys.h
new file mode 100644
index 0000000..b190945
--- /dev/null
+++ b/src/libjpeg-turbo/jmemsys.h
@@ -0,0 +1,198 @@
+/*
+ * jmemsys.h
+ *
+ * Copyright (C) 1992-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This include file defines the interface between the system-independent
+ * and system-dependent portions of the JPEG memory manager. No other
+ * modules need include it. (The system-independent portion is jmemmgr.c;
+ * there are several different versions of the system-dependent portion.)
+ *
+ * This file works as-is for the system-dependent memory managers supplied
+ * in the IJG distribution. You may need to modify it if you write a
+ * custom memory manager. If system-dependent changes are needed in
+ * this file, the best method is to #ifdef them based on a configuration
+ * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR
+ * and USE_MAC_MEMMGR.
+ */
+
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_get_small jGetSmall
+#define jpeg_free_small jFreeSmall
+#define jpeg_get_large jGetLarge
+#define jpeg_free_large jFreeLarge
+#define jpeg_mem_available jMemAvail
+#define jpeg_open_backing_store jOpenBackStore
+#define jpeg_mem_init jMemInit
+#define jpeg_mem_term jMemTerm
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/*
+ * These two functions are used to allocate and release small chunks of
+ * memory. (Typically the total amount requested through jpeg_get_small is
+ * no more than 20K or so; this will be requested in chunks of a few K each.)
+ * Behavior should be the same as for the standard library functions malloc
+ * and free; in particular, jpeg_get_small must return NULL on failure.
+ * On most systems, these ARE malloc and free. jpeg_free_small is passed the
+ * size of the object being freed, just in case it's needed.
+ * On an 80x86 machine using small-data memory model, these manage near heap.
+ */
+
+EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
+EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object,
+ size_t sizeofobject));
+
+/*
+ * These two functions are used to allocate and release large chunks of
+ * memory (up to the total free space designated by jpeg_mem_available).
+ * The interface is the same as above, except that on an 80x86 machine,
+ * far pointers are used. On most other machines these are identical to
+ * the jpeg_get/free_small routines; but we keep them separate anyway,
+ * in case a different allocation strategy is desirable for large chunks.
+ */
+
+EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo,
+ size_t sizeofobject));
+EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
+ size_t sizeofobject));
+
+/*
+ * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
+ * be requested in a single call to jpeg_get_large (and jpeg_get_small for that
+ * matter, but that case should never come into play). This macro is needed
+ * to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
+ * On those machines, we expect that jconfig.h will provide a proper value.
+ * On machines with 32-bit flat address spaces, any large constant may be used.
+ *
+ * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type
+ * size_t and will be a multiple of sizeof(align_type).
+ */
+
+#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */
+#define MAX_ALLOC_CHUNK 1000000000L
+#endif
+
+/*
+ * This routine computes the total space still available for allocation by
+ * jpeg_get_large. If more space than this is needed, backing store will be
+ * used. NOTE: any memory already allocated must not be counted.
+ *
+ * There is a minimum space requirement, corresponding to the minimum
+ * feasible buffer sizes; jmemmgr.c will request that much space even if
+ * jpeg_mem_available returns zero. The maximum space needed, enough to hold
+ * all working storage in memory, is also passed in case it is useful.
+ * Finally, the total space already allocated is passed. If no better
+ * method is available, cinfo->mem->max_memory_to_use - already_allocated
+ * is often a suitable calculation.
+ *
+ * It is OK for jpeg_mem_available to underestimate the space available
+ * (that'll just lead to more backing-store access than is really necessary).
+ * However, an overestimate will lead to failure. Hence it's wise to subtract
+ * a slop factor from the true available space. 5% should be enough.
+ *
+ * On machines with lots of virtual memory, any large constant may be returned.
+ * Conversely, zero may be returned to always use the minimum amount of memory.
+ */
+
+EXTERN(size_t) jpeg_mem_available JPP((j_common_ptr cinfo,
+ size_t min_bytes_needed,
+ size_t max_bytes_needed,
+ size_t already_allocated));
+
+
+/*
+ * This structure holds whatever state is needed to access a single
+ * backing-store object. The read/write/close method pointers are called
+ * by jmemmgr.c to manipulate the backing-store object; all other fields
+ * are private to the system-dependent backing store routines.
+ */
+
+#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
+
+
+#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */
+
+typedef unsigned short XMSH; /* type of extended-memory handles */
+typedef unsigned short EMSH; /* type of expanded-memory handles */
+
+typedef union {
+ short file_handle; /* DOS file handle if it's a temp file */
+ XMSH xms_handle; /* handle if it's a chunk of XMS */
+ EMSH ems_handle; /* handle if it's a chunk of EMS */
+} handle_union;
+
+#endif /* USE_MSDOS_MEMMGR */
+
+#ifdef USE_MAC_MEMMGR /* Mac-specific junk */
+#include <Files.h>
+#endif /* USE_MAC_MEMMGR */
+
+
+typedef struct backing_store_struct * backing_store_ptr;
+
+typedef struct backing_store_struct {
+ /* Methods for reading/writing/closing this backing-store object */
+ JMETHOD(void, read_backing_store, (j_common_ptr cinfo,
+ backing_store_ptr info,
+ void FAR * buffer_address,
+ long file_offset, long byte_count));
+ JMETHOD(void, write_backing_store, (j_common_ptr cinfo,
+ backing_store_ptr info,
+ void FAR * buffer_address,
+ long file_offset, long byte_count));
+ JMETHOD(void, close_backing_store, (j_common_ptr cinfo,
+ backing_store_ptr info));
+
+ /* Private fields for system-dependent backing-store management */
+#ifdef USE_MSDOS_MEMMGR
+ /* For the MS-DOS manager (jmemdos.c), we need: */
+ handle_union handle; /* reference to backing-store storage object */
+ char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
+#else
+#ifdef USE_MAC_MEMMGR
+ /* For the Mac manager (jmemmac.c), we need: */
+ short temp_file; /* file reference number to temp file */
+ FSSpec tempSpec; /* the FSSpec for the temp file */
+ char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
+#else
+ /* For a typical implementation with temp files, we need: */
+ FILE * temp_file; /* stdio reference to temp file */
+ char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
+#endif
+#endif
+} backing_store_info;
+
+
+/*
+ * Initial opening of a backing-store object. This must fill in the
+ * read/write/close pointers in the object. The read/write routines
+ * may take an error exit if the specified maximum file size is exceeded.
+ * (If jpeg_mem_available always returns a large value, this routine can
+ * just take an error exit.)
+ */
+
+EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo,
+ backing_store_ptr info,
+ long total_bytes_needed));
+
+
+/*
+ * These routines take care of any system-dependent initialization and
+ * cleanup required. jpeg_mem_init will be called before anything is
+ * allocated (and, therefore, nothing in cinfo is of use except the error
+ * manager pointer). It should return a suitable default value for
+ * max_memory_to_use; this may subsequently be overridden by the surrounding
+ * application. (Note that max_memory_to_use is only important if
+ * jpeg_mem_available chooses to consult it ... no one else will.)
+ * jpeg_mem_term may assume that all requested memory has been freed and that
+ * all opened backing-store objects have been closed.
+ */
+
+EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo));
+EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo));
diff --git a/src/libjpeg-turbo/jmorecfg.h b/src/libjpeg-turbo/jmorecfg.h
new file mode 100644
index 0000000..f22c4f3
--- /dev/null
+++ b/src/libjpeg-turbo/jmorecfg.h
@@ -0,0 +1,404 @@
+/*
+ * jmorecfg.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Copyright (C) 2009, 2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains additional configuration options that customize the
+ * JPEG software for special applications or support machine-dependent
+ * optimizations. Most users will not need to touch this file.
+ */
+
+
+/*
+ * Define BITS_IN_JSAMPLE as either
+ * 8 for 8-bit sample values (the usual setting)
+ * 12 for 12-bit sample values
+ * Only 8 and 12 are legal data precisions for lossy JPEG according to the
+ * JPEG standard, and the IJG code does not support anything else!
+ * We do not support run-time selection of data precision, sorry.
+ */
+
+#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
+
+
+/*
+ * Maximum number of components (color channels) allowed in JPEG image.
+ * To meet the letter of the JPEG spec, set this to 255. However, darn
+ * few applications need more than 4 channels (maybe 5 for CMYK + alpha
+ * mask). We recommend 10 as a reasonable compromise; use 4 if you are
+ * really short on memory. (Each allowed component costs a hundred or so
+ * bytes of storage, whether actually used in an image or not.)
+ */
+
+#define MAX_COMPONENTS 10 /* maximum number of image components */
+
+
+/*
+ * Basic data types.
+ * You may need to change these if you have a machine with unusual data
+ * type sizes; for example, "char" not 8 bits, "short" not 16 bits,
+ * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
+ * but it had better be at least 16.
+ */
+
+/* Representation of a single sample (pixel element value).
+ * We frequently allocate large arrays of these, so it's important to keep
+ * them small. But if you have memory to burn and access to char or short
+ * arrays is very slow on your hardware, you might want to change these.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+/* JSAMPLE should be the smallest type that will hold the values 0..255.
+ * You can use a signed char by having GETJSAMPLE mask it with 0xFF.
+ */
+
+#ifdef HAVE_UNSIGNED_CHAR
+
+typedef unsigned char JSAMPLE;
+#define GETJSAMPLE(value) ((int) (value))
+
+#else /* not HAVE_UNSIGNED_CHAR */
+
+typedef char JSAMPLE;
+#ifdef __CHAR_UNSIGNED__
+#define GETJSAMPLE(value) ((int) (value))
+#else
+#define GETJSAMPLE(value) ((int) (value) & 0xFF)
+#endif /* __CHAR_UNSIGNED__ */
+
+#endif /* HAVE_UNSIGNED_CHAR */
+
+#define MAXJSAMPLE 255
+#define CENTERJSAMPLE 128
+
+#endif /* BITS_IN_JSAMPLE == 8 */
+
+
+#if BITS_IN_JSAMPLE == 12
+/* JSAMPLE should be the smallest type that will hold the values 0..4095.
+ * On nearly all machines "short" will do nicely.
+ */
+
+typedef short JSAMPLE;
+#define GETJSAMPLE(value) ((int) (value))
+
+#define MAXJSAMPLE 4095
+#define CENTERJSAMPLE 2048
+
+#endif /* BITS_IN_JSAMPLE == 12 */
+
+
+/* Representation of a DCT frequency coefficient.
+ * This should be a signed value of at least 16 bits; "short" is usually OK.
+ * Again, we allocate large arrays of these, but you can change to int
+ * if you have memory to burn and "short" is really slow.
+ */
+
+typedef short JCOEF;
+
+
+/* Compressed datastreams are represented as arrays of JOCTET.
+ * These must be EXACTLY 8 bits wide, at least once they are written to
+ * external storage. Note that when using the stdio data source/destination
+ * managers, this is also the data type passed to fread/fwrite.
+ */
+
+#ifdef HAVE_UNSIGNED_CHAR
+
+typedef unsigned char JOCTET;
+#define GETJOCTET(value) (value)
+
+#else /* not HAVE_UNSIGNED_CHAR */
+
+typedef char JOCTET;
+#ifdef __CHAR_UNSIGNED__
+#define GETJOCTET(value) (value)
+#else
+#define GETJOCTET(value) ((value) & 0xFF)
+#endif /* __CHAR_UNSIGNED__ */
+
+#endif /* HAVE_UNSIGNED_CHAR */
+
+
+/* These typedefs are used for various table entries and so forth.
+ * They must be at least as wide as specified; but making them too big
+ * won't cost a huge amount of memory, so we don't provide special
+ * extraction code like we did for JSAMPLE. (In other words, these
+ * typedefs live at a different point on the speed/space tradeoff curve.)
+ */
+
+/* UINT8 must hold at least the values 0..255. */
+
+#ifdef HAVE_UNSIGNED_CHAR
+typedef unsigned char UINT8;
+#else /* not HAVE_UNSIGNED_CHAR */
+#ifdef __CHAR_UNSIGNED__
+typedef char UINT8;
+#else /* not __CHAR_UNSIGNED__ */
+typedef short UINT8;
+#endif /* __CHAR_UNSIGNED__ */
+#endif /* HAVE_UNSIGNED_CHAR */
+
+/* UINT16 must hold at least the values 0..65535. */
+
+#ifdef HAVE_UNSIGNED_SHORT
+typedef unsigned short UINT16;
+#else /* not HAVE_UNSIGNED_SHORT */
+typedef unsigned int UINT16;
+#endif /* HAVE_UNSIGNED_SHORT */
+
+/* INT16 must hold at least the values -32768..32767. */
+
+#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
+typedef short INT16;
+#endif
+
+/* INT32 must hold at least signed 32-bit values. */
+
+#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
+typedef long INT32;
+#endif
+
+/* Datatype used for image dimensions. The JPEG standard only supports
+ * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
+ * "unsigned int" is sufficient on all machines. However, if you need to
+ * handle larger images and you don't mind deviating from the spec, you
+ * can change this datatype.
+ */
+
+typedef unsigned int JDIMENSION;
+
+#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
+
+
+/* These macros are used in all function definitions and extern declarations.
+ * You could modify them if you need to change function linkage conventions;
+ * in particular, you'll need to do that to make the library a Windows DLL.
+ * Another application is to make all functions global for use with debuggers
+ * or code profilers that require it.
+ */
+
+/* a function called through method pointers: */
+#define METHODDEF(type) static type
+/* a function used only in its module: */
+#define LOCAL(type) static type
+/* a function referenced thru EXTERNs: */
+#define GLOBAL(type) type
+/* a reference to a GLOBAL function: */
+#define EXTERN(type) extern type
+
+
+/* This macro is used to declare a "method", that is, a function pointer.
+ * We want to supply prototype parameters if the compiler can cope.
+ * Note that the arglist parameter must be parenthesized!
+ * Again, you can customize this if you need special linkage keywords.
+ */
+
+#ifdef HAVE_PROTOTYPES
+#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
+#else
+#define JMETHOD(type,methodname,arglist) type (*methodname) ()
+#endif
+
+
+/* Here is the pseudo-keyword for declaring pointers that must be "far"
+ * on 80x86 machines. Most of the specialized coding for 80x86 is handled
+ * by just saying "FAR *" where such a pointer is needed. In a few places
+ * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
+ */
+
+#ifdef NEED_FAR_POINTERS
+#define FAR far
+#else
+#define FAR
+#endif
+
+
+/*
+ * On a few systems, type boolean and/or its values FALSE, TRUE may appear
+ * in standard header files. Or you may have conflicts with application-
+ * specific header files that you want to include together with these files.
+ * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
+ */
+
+#ifndef HAVE_BOOLEAN
+typedef int boolean;
+#endif
+#ifndef FALSE /* in case these macros already exist */
+#define FALSE 0 /* values of boolean */
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+
+/*
+ * The remaining options affect code selection within the JPEG library,
+ * but they don't need to be visible to most applications using the library.
+ * To minimize application namespace pollution, the symbols won't be
+ * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
+ */
+
+#ifdef JPEG_INTERNALS
+#define JPEG_INTERNAL_OPTIONS
+#endif
+
+#ifdef JPEG_INTERNAL_OPTIONS
+
+
+/*
+ * These defines indicate whether to include various optional functions.
+ * Undefining some of these symbols will produce a smaller but less capable
+ * library. Note that you can leave certain source files out of the
+ * compilation/linking process if you've #undef'd the corresponding symbols.
+ * (You may HAVE to do that if your compiler doesn't like null source files.)
+ */
+
+/* Capability options common to encoder and decoder: */
+
+#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
+#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */
+#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */
+
+/* Encoder capability options: */
+
+#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
+#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
+#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
+/* Note: if you selected 12-bit data precision, it is dangerous to turn off
+ * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
+ * precision, so jchuff.c normally uses entropy optimization to compute
+ * usable tables for higher precision. If you don't want to do optimization,
+ * you'll have to supply different default Huffman tables.
+ * The exact same statements apply for progressive JPEG: the default tables
+ * don't work for progressive mode. (This may get fixed, however.)
+ */
+#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
+
+/* Decoder capability options: */
+
+#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
+#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
+#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
+#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
+#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
+#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
+#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
+#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
+#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
+
+/* more capability options later, no doubt */
+
+
+/*
+ * Ordering of RGB data in scanlines passed to or from the application.
+ * If your application wants to deal with data in the order B,G,R, just
+ * change these macros. You can also deal with formats such as R,G,B,X
+ * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing
+ * the offsets will also change the order in which colormap data is organized.
+ * RESTRICTIONS:
+ * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
+ * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
+ * useful if you are using JPEG color spaces other than YCbCr or grayscale.
+ * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
+ * is not 3 (they don't understand about dummy color components!). So you
+ * can't use color quantization if you change that value.
+ */
+
+#define RGB_RED 0 /* Offset of Red in an RGB scanline element */
+#define RGB_GREEN 1 /* Offset of Green */
+#define RGB_BLUE 2 /* Offset of Blue */
+#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
+
+#define JPEG_NUMCS 16
+
+#define EXT_RGB_RED 0
+#define EXT_RGB_GREEN 1
+#define EXT_RGB_BLUE 2
+#define EXT_RGB_PIXELSIZE 3
+
+#define EXT_RGBX_RED 0
+#define EXT_RGBX_GREEN 1
+#define EXT_RGBX_BLUE 2
+#define EXT_RGBX_PIXELSIZE 4
+
+#define EXT_BGR_RED 2
+#define EXT_BGR_GREEN 1
+#define EXT_BGR_BLUE 0
+#define EXT_BGR_PIXELSIZE 3
+
+#define EXT_BGRX_RED 2
+#define EXT_BGRX_GREEN 1
+#define EXT_BGRX_BLUE 0
+#define EXT_BGRX_PIXELSIZE 4
+
+#define EXT_XBGR_RED 3
+#define EXT_XBGR_GREEN 2
+#define EXT_XBGR_BLUE 1
+#define EXT_XBGR_PIXELSIZE 4
+
+#define EXT_XRGB_RED 1
+#define EXT_XRGB_GREEN 2
+#define EXT_XRGB_BLUE 3
+#define EXT_XRGB_PIXELSIZE 4
+
+static const int rgb_red[JPEG_NUMCS] = {
+ -1, -1, RGB_RED, -1, -1, -1, EXT_RGB_RED, EXT_RGBX_RED,
+ EXT_BGR_RED, EXT_BGRX_RED, EXT_XBGR_RED, EXT_XRGB_RED,
+ EXT_RGBX_RED, EXT_BGRX_RED, EXT_XBGR_RED, EXT_XRGB_RED
+};
+
+static const int rgb_green[JPEG_NUMCS] = {
+ -1, -1, RGB_GREEN, -1, -1, -1, EXT_RGB_GREEN, EXT_RGBX_GREEN,
+ EXT_BGR_GREEN, EXT_BGRX_GREEN, EXT_XBGR_GREEN, EXT_XRGB_GREEN,
+ EXT_RGBX_GREEN, EXT_BGRX_GREEN, EXT_XBGR_GREEN, EXT_XRGB_GREEN
+};
+
+static const int rgb_blue[JPEG_NUMCS] = {
+ -1, -1, RGB_BLUE, -1, -1, -1, EXT_RGB_BLUE, EXT_RGBX_BLUE,
+ EXT_BGR_BLUE, EXT_BGRX_BLUE, EXT_XBGR_BLUE, EXT_XRGB_BLUE,
+ EXT_RGBX_BLUE, EXT_BGRX_BLUE, EXT_XBGR_BLUE, EXT_XRGB_BLUE
+};
+
+static const int rgb_pixelsize[JPEG_NUMCS] = {
+ -1, -1, RGB_PIXELSIZE, -1, -1, -1, EXT_RGB_PIXELSIZE, EXT_RGBX_PIXELSIZE,
+ EXT_BGR_PIXELSIZE, EXT_BGRX_PIXELSIZE, EXT_XBGR_PIXELSIZE, EXT_XRGB_PIXELSIZE,
+ EXT_RGBX_PIXELSIZE, EXT_BGRX_PIXELSIZE, EXT_XBGR_PIXELSIZE, EXT_XRGB_PIXELSIZE
+};
+
+/* Definitions for speed-related optimizations. */
+
+/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
+ * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
+ * as short on such a machine. MULTIPLIER must be at least 16 bits wide.
+ */
+
+#ifndef MULTIPLIER
+#ifndef WITH_SIMD
+#define MULTIPLIER int /* type for fastest integer multiply */
+#else
+#define MULTIPLIER short /* prefer 16-bit with SIMD for parellelism */
+#endif
+#endif
+
+
+/* FAST_FLOAT should be either float or double, whichever is done faster
+ * by your compiler. (Note that this type is only used in the floating point
+ * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
+ * Typically, float is faster in ANSI C compilers, while double is faster in
+ * pre-ANSI compilers (because they insist on converting to double anyway).
+ * The code below therefore chooses float if we have ANSI-style prototypes.
+ */
+
+#ifndef FAST_FLOAT
+#ifdef HAVE_PROTOTYPES
+#define FAST_FLOAT float
+#else
+#define FAST_FLOAT double
+#endif
+#endif
+
+#endif /* JPEG_INTERNAL_OPTIONS */
diff --git a/src/libjpeg-turbo/jpegcomp.h b/src/libjpeg-turbo/jpegcomp.h
new file mode 100644
index 0000000..1b9e0a4
--- /dev/null
+++ b/src/libjpeg-turbo/jpegcomp.h
@@ -0,0 +1,26 @@
+/*
+ * jpegcomp.h
+ *
+ * Copyright (C) 2010, D. R. Commander
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * JPEG compatibility macros
+ * These declarations are considered internal to the JPEG library; most
+ * applications using the library shouldn't need to include this file.
+ */
+
+#if JPEG_LIB_VERSION >= 70
+#define _DCT_scaled_size DCT_h_scaled_size
+#define _min_DCT_scaled_size min_DCT_h_scaled_size
+#define _min_DCT_h_scaled_size min_DCT_h_scaled_size
+#define _min_DCT_v_scaled_size min_DCT_v_scaled_size
+#define _jpeg_width jpeg_width
+#define _jpeg_height jpeg_height
+#else
+#define _DCT_scaled_size DCT_scaled_size
+#define _min_DCT_scaled_size min_DCT_scaled_size
+#define _min_DCT_h_scaled_size min_DCT_scaled_size
+#define _min_DCT_v_scaled_size min_DCT_scaled_size
+#define _jpeg_width image_width
+#define _jpeg_height image_height
+#endif
diff --git a/src/libjpeg-turbo/jpegint.h b/src/libjpeg-turbo/jpegint.h
new file mode 100644
index 0000000..7871748
--- /dev/null
+++ b/src/libjpeg-turbo/jpegint.h
@@ -0,0 +1,401 @@
+/*
+ * jpegint.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Modified 1997-2009 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file provides common declarations for the various JPEG modules.
+ * These declarations are considered internal to the JPEG library; most
+ * applications using the library shouldn't need to include this file.
+ */
+
+
+/* Declarations for both compression & decompression */
+
+typedef enum { /* Operating modes for buffer controllers */
+ JBUF_PASS_THRU, /* Plain stripwise operation */
+ /* Remaining modes require a full-image buffer to have been created */
+ JBUF_SAVE_SOURCE, /* Run source subobject only, save output */
+ JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */
+ JBUF_SAVE_AND_PASS /* Run both subobjects, save output */
+} J_BUF_MODE;
+
+/* Values of global_state field (jdapi.c has some dependencies on ordering!) */
+#define CSTATE_START 100 /* after create_compress */
+#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */
+#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */
+#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */
+#define DSTATE_START 200 /* after create_decompress */
+#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */
+#define DSTATE_READY 202 /* found SOS, ready for start_decompress */
+#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/
+#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */
+#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */
+#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */
+#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */
+#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */
+#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */
+#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */
+
+
+/* Declarations for compression modules */
+
+/* Master control module */
+struct jpeg_comp_master {
+ JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo));
+ JMETHOD(void, pass_startup, (j_compress_ptr cinfo));
+ JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
+
+ /* State variables made visible to other modules */
+ boolean call_pass_startup; /* True if pass_startup must be called */
+ boolean is_last_pass; /* True during last pass */
+};
+
+/* Main buffer control (downsampled-data buffer) */
+struct jpeg_c_main_controller {
+ JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
+ JMETHOD(void, process_data, (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail));
+};
+
+/* Compression preprocessing (downsampling input buffer control) */
+struct jpeg_c_prep_controller {
+ JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
+ JMETHOD(void, pre_process_data, (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf,
+ JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail,
+ JSAMPIMAGE output_buf,
+ JDIMENSION *out_row_group_ctr,
+ JDIMENSION out_row_groups_avail));
+};
+
+/* Coefficient buffer control */
+struct jpeg_c_coef_controller {
+ JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
+ JMETHOD(boolean, compress_data, (j_compress_ptr cinfo,
+ JSAMPIMAGE input_buf));
+};
+
+/* Colorspace conversion */
+struct jpeg_color_converter {
+ JMETHOD(void, start_pass, (j_compress_ptr cinfo));
+ JMETHOD(void, color_convert, (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+};
+
+/* Downsampling */
+struct jpeg_downsampler {
+ JMETHOD(void, start_pass, (j_compress_ptr cinfo));
+ JMETHOD(void, downsample, (j_compress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_index,
+ JSAMPIMAGE output_buf,
+ JDIMENSION out_row_group_index));
+
+ boolean need_context_rows; /* TRUE if need rows above & below */
+};
+
+/* Forward DCT (also controls coefficient quantization) */
+struct jpeg_forward_dct {
+ JMETHOD(void, start_pass, (j_compress_ptr cinfo));
+ /* perhaps this should be an array??? */
+ JMETHOD(void, forward_DCT, (j_compress_ptr cinfo,
+ jpeg_component_info * compptr,
+ JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
+ JDIMENSION start_row, JDIMENSION start_col,
+ JDIMENSION num_blocks));
+};
+
+/* Entropy encoding */
+struct jpeg_entropy_encoder {
+ JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics));
+ JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data));
+ JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
+};
+
+/* Marker writing */
+struct jpeg_marker_writer {
+ JMETHOD(void, write_file_header, (j_compress_ptr cinfo));
+ JMETHOD(void, write_frame_header, (j_compress_ptr cinfo));
+ JMETHOD(void, write_scan_header, (j_compress_ptr cinfo));
+ JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
+ JMETHOD(void, write_tables_only, (j_compress_ptr cinfo));
+ /* These routines are exported to allow insertion of extra markers */
+ /* Probably only COM and APPn markers should be written this way */
+ JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
+ unsigned int datalen));
+ JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
+};
+
+
+/* Declarations for decompression modules */
+
+/* Master control module */
+struct jpeg_decomp_master {
+ JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
+ JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
+
+ /* State variables made visible to other modules */
+ boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */
+};
+
+/* Input control module */
+struct jpeg_input_controller {
+ JMETHOD(int, consume_input, (j_decompress_ptr cinfo));
+ JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo));
+ JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
+ JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo));
+
+ /* State variables made visible to other modules */
+ boolean has_multiple_scans; /* True if file has multiple scans */
+ boolean eoi_reached; /* True when EOI has been consumed */
+};
+
+/* Main buffer control (downsampled-data buffer) */
+struct jpeg_d_main_controller {
+ JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
+ JMETHOD(void, process_data, (j_decompress_ptr cinfo,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+};
+
+/* Coefficient buffer control */
+struct jpeg_d_coef_controller {
+ JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
+ JMETHOD(int, consume_data, (j_decompress_ptr cinfo));
+ JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo));
+ JMETHOD(int, decompress_data, (j_decompress_ptr cinfo,
+ JSAMPIMAGE output_buf));
+ /* Pointer to array of coefficient virtual arrays, or NULL if none */
+ jvirt_barray_ptr *coef_arrays;
+};
+
+/* Decompression postprocessing (color quantization buffer control) */
+struct jpeg_d_post_controller {
+ JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
+ JMETHOD(void, post_process_data, (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf,
+ JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf,
+ JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+};
+
+/* Marker reading & parsing */
+struct jpeg_marker_reader {
+ JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo));
+ /* Read markers until SOS or EOI.
+ * Returns same codes as are defined for jpeg_consume_input:
+ * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
+ */
+ JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
+ /* Read a restart marker --- exported for use by entropy decoder only */
+ jpeg_marker_parser_method read_restart_marker;
+
+ /* State of marker reader --- nominally internal, but applications
+ * supplying COM or APPn handlers might like to know the state.
+ */
+ boolean saw_SOI; /* found SOI? */
+ boolean saw_SOF; /* found SOF? */
+ int next_restart_num; /* next restart number expected (0-7) */
+ unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */
+};
+
+/* Entropy decoding */
+struct jpeg_entropy_decoder {
+ JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
+ JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+
+ /* This is here to share code between baseline and progressive decoders; */
+ /* other modules probably should not use it */
+ boolean insufficient_data; /* set TRUE after emitting warning */
+};
+
+/* Inverse DCT (also performs dequantization) */
+typedef JMETHOD(void, inverse_DCT_method_ptr,
+ (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col));
+
+struct jpeg_inverse_dct {
+ JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
+ /* It is useful to allow each component to have a separate IDCT method. */
+ inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
+};
+
+/* Upsampling (note that upsampler must also call color converter) */
+struct jpeg_upsampler {
+ JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
+ JMETHOD(void, upsample, (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf,
+ JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf,
+ JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+
+ boolean need_context_rows; /* TRUE if need rows above & below */
+};
+
+/* Colorspace conversion */
+struct jpeg_color_deconverter {
+ JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
+ JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+};
+
+/* Color quantization or color precision reduction */
+struct jpeg_color_quantizer {
+ JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan));
+ JMETHOD(void, color_quantize, (j_decompress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPARRAY output_buf,
+ int num_rows));
+ JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
+ JMETHOD(void, new_color_map, (j_decompress_ptr cinfo));
+};
+
+
+/* Miscellaneous useful macros */
+
+#undef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#undef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+
+/* We assume that right shift corresponds to signed division by 2 with
+ * rounding towards minus infinity. This is correct for typical "arithmetic
+ * shift" instructions that shift in copies of the sign bit. But some
+ * C compilers implement >> with an unsigned shift. For these machines you
+ * must define RIGHT_SHIFT_IS_UNSIGNED.
+ * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
+ * It is only applied with constant shift counts. SHIFT_TEMPS must be
+ * included in the variables of any routine using RIGHT_SHIFT.
+ */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define SHIFT_TEMPS INT32 shift_temp;
+#define RIGHT_SHIFT(x,shft) \
+ ((shift_temp = (x)) < 0 ? \
+ (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
+ (shift_temp >> (shft)))
+#else
+#define SHIFT_TEMPS
+#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
+#endif
+
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jinit_compress_master jICompress
+#define jinit_c_master_control jICMaster
+#define jinit_c_main_controller jICMainC
+#define jinit_c_prep_controller jICPrepC
+#define jinit_c_coef_controller jICCoefC
+#define jinit_color_converter jICColor
+#define jinit_downsampler jIDownsampler
+#define jinit_forward_dct jIFDCT
+#define jinit_huff_encoder jIHEncoder
+#define jinit_phuff_encoder jIPHEncoder
+#define jinit_arith_encoder jIAEncoder
+#define jinit_marker_writer jIMWriter
+#define jinit_master_decompress jIDMaster
+#define jinit_d_main_controller jIDMainC
+#define jinit_d_coef_controller jIDCoefC
+#define jinit_d_post_controller jIDPostC
+#define jinit_input_controller jIInCtlr
+#define jinit_marker_reader jIMReader
+#define jinit_huff_decoder jIHDecoder
+#define jinit_phuff_decoder jIPHDecoder
+#define jinit_arith_decoder jIADecoder
+#define jinit_inverse_dct jIIDCT
+#define jinit_upsampler jIUpsampler
+#define jinit_color_deconverter jIDColor
+#define jinit_1pass_quantizer jI1Quant
+#define jinit_2pass_quantizer jI2Quant
+#define jinit_merged_upsampler jIMUpsampler
+#define jinit_memory_mgr jIMemMgr
+#define jdiv_round_up jDivRound
+#define jround_up jRound
+#define jcopy_sample_rows jCopySamples
+#define jcopy_block_row jCopyBlocks
+#define jzero_far jZeroFar
+#define jpeg_zigzag_order jZIGTable
+#define jpeg_natural_order jZAGTable
+#define jpeg_aritab jAriTab
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/* Compression module initialization routines */
+EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
+ boolean transcode_only));
+EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_arith_encoder JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
+/* Decompression module initialization routines */
+EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_arith_decoder JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
+/* Memory manager initialization */
+EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
+
+/* Utility routines in jutils.c */
+EXTERN(long) jdiv_round_up JPP((long a, long b));
+EXTERN(long) jround_up JPP((long a, long b));
+EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
+ JSAMPARRAY output_array, int dest_row,
+ int num_rows, JDIMENSION num_cols));
+EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
+ JDIMENSION num_blocks));
+EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
+/* Constant tables in jutils.c */
+#if 0 /* This table is not actually needed in v6a */
+extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
+#endif
+extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
+
+/* Arithmetic coding probability estimation tables in jaricom.c */
+extern const INT32 jpeg_aritab[];
+
+/* Suppress undefined-structure complaints if necessary. */
+
+#ifdef INCOMPLETE_TYPES_BROKEN
+#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */
+struct jvirt_sarray_control { long dummy; };
+struct jvirt_barray_control { long dummy; };
+#endif
+#endif /* INCOMPLETE_TYPES_BROKEN */
diff --git a/src/libjpeg-turbo/jpeglib.h b/src/libjpeg-turbo/jpeglib.h
new file mode 100644
index 0000000..d19a3ef
--- /dev/null
+++ b/src/libjpeg-turbo/jpeglib.h
@@ -0,0 +1,1213 @@
+/*
+ * jpeglib.h
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * Modified 2002-2009 by Guido Vollbeding.
+ * Copyright (C) 2009-2011, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file defines the application interface for the JPEG library.
+ * Most applications using the library need only include this file,
+ * and perhaps jerror.h if they want to know the exact error codes.
+ */
+
+#ifndef JPEGLIB_H
+#define JPEGLIB_H
+
+/*
+ * First we include the configuration files that record how this
+ * installation of the JPEG library is set up. jconfig.h can be
+ * generated automatically for many systems. jmorecfg.h contains
+ * manual configuration options that most people need not worry about.
+ */
+
+#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */
+#include "jconfig.h" /* widely used configuration options */
+#endif
+#include "jmorecfg.h" /* seldom changed options */
+
+
+#ifdef __cplusplus
+#ifndef DONT_USE_EXTERN_C
+extern "C" {
+#endif
+#endif
+
+
+/* Various constants determining the sizes of things.
+ * All of these are specified by the JPEG standard, so don't change them
+ * if you want to be compatible.
+ */
+
+#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
+#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
+#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */
+#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */
+#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */
+#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */
+#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */
+/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard;
+ * the PostScript DCT filter can emit files with many more than 10 blocks/MCU.
+ * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU
+ * to handle it. We even let you do this from the jconfig.h file. However,
+ * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe
+ * sometimes emits noncompliant files doesn't mean you should too.
+ */
+#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */
+#ifndef D_MAX_BLOCKS_IN_MCU
+#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */
+#endif
+
+
+/* Data structures for images (arrays of samples and of DCT coefficients).
+ * On 80x86 machines, the image arrays are too big for near pointers,
+ * but the pointer arrays can fit in near memory.
+ */
+
+typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */
+typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */
+typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */
+
+typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */
+typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */
+typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */
+typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */
+
+typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */
+
+
+/* Types for JPEG compression parameters and working tables. */
+
+
+/* DCT coefficient quantization tables. */
+
+typedef struct {
+ /* This array gives the coefficient quantizers in natural array order
+ * (not the zigzag order in which they are stored in a JPEG DQT marker).
+ * CAUTION: IJG versions prior to v6a kept this array in zigzag order.
+ */
+ UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */
+ /* This field is used only during compression. It's initialized FALSE when
+ * the table is created, and set TRUE when it's been output to the file.
+ * You could suppress output of a table by setting this to TRUE.
+ * (See jpeg_suppress_tables for an example.)
+ */
+ boolean sent_table; /* TRUE when table has been output */
+} JQUANT_TBL;
+
+
+/* Huffman coding tables. */
+
+typedef struct {
+ /* These two fields directly represent the contents of a JPEG DHT marker */
+ UINT8 bits[17]; /* bits[k] = # of symbols with codes of */
+ /* length k bits; bits[0] is unused */
+ UINT8 huffval[256]; /* The symbols, in order of incr code length */
+ /* This field is used only during compression. It's initialized FALSE when
+ * the table is created, and set TRUE when it's been output to the file.
+ * You could suppress output of a table by setting this to TRUE.
+ * (See jpeg_suppress_tables for an example.)
+ */
+ boolean sent_table; /* TRUE when table has been output */
+} JHUFF_TBL;
+
+
+/* Basic info about one component (color channel). */
+
+typedef struct {
+ /* These values are fixed over the whole image. */
+ /* For compression, they must be supplied by parameter setup; */
+ /* for decompression, they are read from the SOF marker. */
+ int component_id; /* identifier for this component (0..255) */
+ int component_index; /* its index in SOF or cinfo->comp_info[] */
+ int h_samp_factor; /* horizontal sampling factor (1..4) */
+ int v_samp_factor; /* vertical sampling factor (1..4) */
+ int quant_tbl_no; /* quantization table selector (0..3) */
+ /* These values may vary between scans. */
+ /* For compression, they must be supplied by parameter setup; */
+ /* for decompression, they are read from the SOS marker. */
+ /* The decompressor output side may not use these variables. */
+ int dc_tbl_no; /* DC entropy table selector (0..3) */
+ int ac_tbl_no; /* AC entropy table selector (0..3) */
+
+ /* Remaining fields should be treated as private by applications. */
+
+ /* These values are computed during compression or decompression startup: */
+ /* Component's size in DCT blocks.
+ * Any dummy blocks added to complete an MCU are not counted; therefore
+ * these values do not depend on whether a scan is interleaved or not.
+ */
+ JDIMENSION width_in_blocks;
+ JDIMENSION height_in_blocks;
+ /* Size of a DCT block in samples. Always DCTSIZE for compression.
+ * For decompression this is the size of the output from one DCT block,
+ * reflecting any scaling we choose to apply during the IDCT step.
+ * Values of 1,2,4,8 are likely to be supported. Note that different
+ * components may receive different IDCT scalings.
+ */
+#if JPEG_LIB_VERSION >= 70
+ int DCT_h_scaled_size;
+ int DCT_v_scaled_size;
+#else
+ int DCT_scaled_size;
+#endif
+ /* The downsampled dimensions are the component's actual, unpadded number
+ * of samples at the main buffer (preprocessing/compression interface), thus
+ * downsampled_width = ceil(image_width * Hi/Hmax)
+ * and similarly for height. For decompression, IDCT scaling is included, so
+ * downsampled_width = ceil(image_width * Hi/Hmax * DCT_[h_]scaled_size/DCTSIZE)
+ */
+ JDIMENSION downsampled_width; /* actual width in samples */
+ JDIMENSION downsampled_height; /* actual height in samples */
+ /* This flag is used only for decompression. In cases where some of the
+ * components will be ignored (eg grayscale output from YCbCr image),
+ * we can skip most computations for the unused components.
+ */
+ boolean component_needed; /* do we need the value of this component? */
+
+ /* These values are computed before starting a scan of the component. */
+ /* The decompressor output side may not use these variables. */
+ int MCU_width; /* number of blocks per MCU, horizontally */
+ int MCU_height; /* number of blocks per MCU, vertically */
+ int MCU_blocks; /* MCU_width * MCU_height */
+ int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_[h_]scaled_size */
+ int last_col_width; /* # of non-dummy blocks across in last MCU */
+ int last_row_height; /* # of non-dummy blocks down in last MCU */
+
+ /* Saved quantization table for component; NULL if none yet saved.
+ * See jdinput.c comments about the need for this information.
+ * This field is currently used only for decompression.
+ */
+ JQUANT_TBL * quant_table;
+
+ /* Private per-component storage for DCT or IDCT subsystem. */
+ void * dct_table;
+} jpeg_component_info;
+
+
+/* The script for encoding a multiple-scan file is an array of these: */
+
+typedef struct {
+ int comps_in_scan; /* number of components encoded in this scan */
+ int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
+ int Ss, Se; /* progressive JPEG spectral selection parms */
+ int Ah, Al; /* progressive JPEG successive approx. parms */
+} jpeg_scan_info;
+
+/* The decompressor can save APPn and COM markers in a list of these: */
+
+typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr;
+
+struct jpeg_marker_struct {
+ jpeg_saved_marker_ptr next; /* next in list, or NULL */
+ UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */
+ unsigned int original_length; /* # bytes of data in the file */
+ unsigned int data_length; /* # bytes of data saved at data[] */
+ JOCTET FAR * data; /* the data contained in the marker */
+ /* the marker length word is not counted in data_length or original_length */
+};
+
+/* Known color spaces. */
+
+#define JCS_EXTENSIONS 1
+#define JCS_ALPHA_EXTENSIONS 1
+
+typedef enum {
+ JCS_UNKNOWN, /* error/unspecified */
+ JCS_GRAYSCALE, /* monochrome */
+ JCS_RGB, /* red/green/blue as specified by the RGB_RED, RGB_GREEN,
+ RGB_BLUE, and RGB_PIXELSIZE macros */
+ JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
+ JCS_CMYK, /* C/M/Y/K */
+ JCS_YCCK, /* Y/Cb/Cr/K */
+ JCS_EXT_RGB, /* red/green/blue */
+ JCS_EXT_RGBX, /* red/green/blue/x */
+ JCS_EXT_BGR, /* blue/green/red */
+ JCS_EXT_BGRX, /* blue/green/red/x */
+ JCS_EXT_XBGR, /* x/blue/green/red */
+ JCS_EXT_XRGB, /* x/red/green/blue */
+ /* When out_color_space it set to JCS_EXT_RGBX, JCS_EXT_BGRX,
+ JCS_EXT_XBGR, or JCS_EXT_XRGB during decompression, the X byte is
+ undefined, and in order to ensure the best performance,
+ libjpeg-turbo can set that byte to whatever value it wishes. Use
+ the following colorspace constants to ensure that the X byte is set
+ to 0xFF, so that it can be interpreted as an opaque alpha
+ channel. */
+ JCS_EXT_RGBA, /* red/green/blue/alpha */
+ JCS_EXT_BGRA, /* blue/green/red/alpha */
+ JCS_EXT_ABGR, /* alpha/blue/green/red */
+ JCS_EXT_ARGB /* alpha/red/green/blue */
+} J_COLOR_SPACE;
+
+/* DCT/IDCT algorithm options. */
+
+typedef enum {
+ JDCT_ISLOW, /* slow but accurate integer algorithm */
+ JDCT_IFAST, /* faster, less accurate integer method */
+ JDCT_FLOAT /* floating-point: accurate, fast on fast HW */
+} J_DCT_METHOD;
+
+#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */
+#define JDCT_DEFAULT JDCT_ISLOW
+#endif
+#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */
+#define JDCT_FASTEST JDCT_IFAST
+#endif
+
+/* Dithering options for decompression. */
+
+typedef enum {
+ JDITHER_NONE, /* no dithering */
+ JDITHER_ORDERED, /* simple ordered dither */
+ JDITHER_FS /* Floyd-Steinberg error diffusion dither */
+} J_DITHER_MODE;
+
+
+/* Common fields between JPEG compression and decompression master structs. */
+
+#define jpeg_common_fields \
+ struct jpeg_error_mgr * err; /* Error handler module */\
+ struct jpeg_memory_mgr * mem; /* Memory manager module */\
+ struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
+ void * client_data; /* Available for use by application */\
+ boolean is_decompressor; /* So common code can tell which is which */\
+ int global_state /* For checking call sequence validity */
+
+/* Routines that are to be used by both halves of the library are declared
+ * to receive a pointer to this structure. There are no actual instances of
+ * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
+ */
+struct jpeg_common_struct {
+ jpeg_common_fields; /* Fields common to both master struct types */
+ /* Additional fields follow in an actual jpeg_compress_struct or
+ * jpeg_decompress_struct. All three structs must agree on these
+ * initial fields! (This would be a lot cleaner in C++.)
+ */
+};
+
+typedef struct jpeg_common_struct * j_common_ptr;
+typedef struct jpeg_compress_struct * j_compress_ptr;
+typedef struct jpeg_decompress_struct * j_decompress_ptr;
+
+
+/* Master record for a compression instance */
+
+struct jpeg_compress_struct {
+ jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */
+
+ /* Destination for compressed data */
+ struct jpeg_destination_mgr * dest;
+
+ /* Description of source image --- these fields must be filled in by
+ * outer application before starting compression. in_color_space must
+ * be correct before you can even call jpeg_set_defaults().
+ */
+
+ JDIMENSION image_width; /* input image width */
+ JDIMENSION image_height; /* input image height */
+ int input_components; /* # of color components in input image */
+ J_COLOR_SPACE in_color_space; /* colorspace of input image */
+
+ double input_gamma; /* image gamma of input image */
+
+ /* Compression parameters --- these fields must be set before calling
+ * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to
+ * initialize everything to reasonable defaults, then changing anything
+ * the application specifically wants to change. That way you won't get
+ * burnt when new parameters are added. Also note that there are several
+ * helper routines to simplify changing parameters.
+ */
+
+#if JPEG_LIB_VERSION >= 70
+ unsigned int scale_num, scale_denom; /* fraction by which to scale image */
+
+ JDIMENSION jpeg_width; /* scaled JPEG image width */
+ JDIMENSION jpeg_height; /* scaled JPEG image height */
+ /* Dimensions of actual JPEG image that will be written to file,
+ * derived from input dimensions by scaling factors above.
+ * These fields are computed by jpeg_start_compress().
+ * You can also use jpeg_calc_jpeg_dimensions() to determine these values
+ * in advance of calling jpeg_start_compress().
+ */
+#endif
+
+ int data_precision; /* bits of precision in image data */
+
+ int num_components; /* # of color components in JPEG image */
+ J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
+
+ jpeg_component_info * comp_info;
+ /* comp_info[i] describes component that appears i'th in SOF */
+
+ JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
+#if JPEG_LIB_VERSION >= 70
+ int q_scale_factor[NUM_QUANT_TBLS];
+#endif
+ /* ptrs to coefficient quantization tables, or NULL if not defined,
+ * and corresponding scale factors (percentage, initialized 100).
+ */
+
+ JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ /* ptrs to Huffman coding tables, or NULL if not defined */
+
+ UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
+ UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
+ UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
+
+ int num_scans; /* # of entries in scan_info array */
+ const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */
+ /* The default value of scan_info is NULL, which causes a single-scan
+ * sequential JPEG file to be emitted. To create a multi-scan file,
+ * set num_scans and scan_info to point to an array of scan definitions.
+ */
+
+ boolean raw_data_in; /* TRUE=caller supplies downsampled data */
+ boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
+ boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
+ boolean CCIR601_sampling; /* TRUE=first samples are cosited */
+#if JPEG_LIB_VERSION >= 70
+ boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */
+#endif
+ int smoothing_factor; /* 1..100, or 0 for no input smoothing */
+ J_DCT_METHOD dct_method; /* DCT algorithm selector */
+
+ /* The restart interval can be specified in absolute MCUs by setting
+ * restart_interval, or in MCU rows by setting restart_in_rows
+ * (in which case the correct restart_interval will be figured
+ * for each scan).
+ */
+ unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */
+ int restart_in_rows; /* if > 0, MCU rows per restart interval */
+
+ /* Parameters controlling emission of special markers. */
+
+ boolean write_JFIF_header; /* should a JFIF marker be written? */
+ UINT8 JFIF_major_version; /* What to write for the JFIF version number */
+ UINT8 JFIF_minor_version;
+ /* These three values are not used by the JPEG code, merely copied */
+ /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */
+ /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */
+ /* ratio is defined by X_density/Y_density even when density_unit=0. */
+ UINT8 density_unit; /* JFIF code for pixel size units */
+ UINT16 X_density; /* Horizontal pixel density */
+ UINT16 Y_density; /* Vertical pixel density */
+ boolean write_Adobe_marker; /* should an Adobe marker be written? */
+
+ /* State variable: index of next scanline to be written to
+ * jpeg_write_scanlines(). Application may use this to control its
+ * processing loop, e.g., "while (next_scanline < image_height)".
+ */
+
+ JDIMENSION next_scanline; /* 0 .. image_height-1 */
+
+ /* Remaining fields are known throughout compressor, but generally
+ * should not be touched by a surrounding application.
+ */
+
+ /*
+ * These fields are computed during compression startup
+ */
+ boolean progressive_mode; /* TRUE if scan script uses progressive mode */
+ int max_h_samp_factor; /* largest h_samp_factor */
+ int max_v_samp_factor; /* largest v_samp_factor */
+
+#if JPEG_LIB_VERSION >= 70
+ int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
+ int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
+#endif
+
+ JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */
+ /* The coefficient controller receives data in units of MCU rows as defined
+ * for fully interleaved scans (whether the JPEG file is interleaved or not).
+ * There are v_samp_factor * DCTSIZE sample rows of each component in an
+ * "iMCU" (interleaved MCU) row.
+ */
+
+ /*
+ * These fields are valid during any one scan.
+ * They describe the components and MCUs actually appearing in the scan.
+ */
+ int comps_in_scan; /* # of JPEG components in this scan */
+ jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
+ /* *cur_comp_info[i] describes component that appears i'th in SOS */
+
+ JDIMENSION MCUs_per_row; /* # of MCUs across the image */
+ JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
+
+ int blocks_in_MCU; /* # of DCT blocks per MCU */
+ int MCU_membership[C_MAX_BLOCKS_IN_MCU];
+ /* MCU_membership[i] is index in cur_comp_info of component owning */
+ /* i'th block in an MCU */
+
+ int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
+
+#if JPEG_LIB_VERSION >= 80
+ int block_size; /* the basic DCT block size: 1..16 */
+ const int * natural_order; /* natural-order position array */
+ int lim_Se; /* min( Se, DCTSIZE2-1 ) */
+#endif
+
+ /*
+ * Links to compression subobjects (methods and private variables of modules)
+ */
+ struct jpeg_comp_master * master;
+ struct jpeg_c_main_controller * main;
+ struct jpeg_c_prep_controller * prep;
+ struct jpeg_c_coef_controller * coef;
+ struct jpeg_marker_writer * marker;
+ struct jpeg_color_converter * cconvert;
+ struct jpeg_downsampler * downsample;
+ struct jpeg_forward_dct * fdct;
+ struct jpeg_entropy_encoder * entropy;
+ jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */
+ int script_space_size;
+};
+
+
+/* Master record for a decompression instance */
+
+struct jpeg_decompress_struct {
+ jpeg_common_fields; /* Fields shared with jpeg_compress_struct */
+
+ /* Source of compressed data */
+ struct jpeg_source_mgr * src;
+
+ /* Basic description of image --- filled in by jpeg_read_header(). */
+ /* Application may inspect these values to decide how to process image. */
+
+ JDIMENSION image_width; /* nominal image width (from SOF marker) */
+ JDIMENSION image_height; /* nominal image height */
+ int num_components; /* # of color components in JPEG image */
+ J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
+
+ /* Decompression processing parameters --- these fields must be set before
+ * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes
+ * them to default values.
+ */
+
+ J_COLOR_SPACE out_color_space; /* colorspace for output */
+
+ unsigned int scale_num, scale_denom; /* fraction by which to scale image */
+
+ double output_gamma; /* image gamma wanted in output */
+
+ boolean buffered_image; /* TRUE=multiple output passes */
+ boolean raw_data_out; /* TRUE=downsampled data wanted */
+
+ J_DCT_METHOD dct_method; /* IDCT algorithm selector */
+ boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */
+ boolean do_block_smoothing; /* TRUE=apply interblock smoothing */
+
+ boolean quantize_colors; /* TRUE=colormapped output wanted */
+ /* the following are ignored if not quantize_colors: */
+ J_DITHER_MODE dither_mode; /* type of color dithering to use */
+ boolean two_pass_quantize; /* TRUE=use two-pass color quantization */
+ int desired_number_of_colors; /* max # colors to use in created colormap */
+ /* these are significant only in buffered-image mode: */
+ boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */
+ boolean enable_external_quant;/* enable future use of external colormap */
+ boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */
+
+ /* Description of actual output image that will be returned to application.
+ * These fields are computed by jpeg_start_decompress().
+ * You can also use jpeg_calc_output_dimensions() to determine these values
+ * in advance of calling jpeg_start_decompress().
+ */
+
+ JDIMENSION output_width; /* scaled image width */
+ JDIMENSION output_height; /* scaled image height */
+ int out_color_components; /* # of color components in out_color_space */
+ int output_components; /* # of color components returned */
+ /* output_components is 1 (a colormap index) when quantizing colors;
+ * otherwise it equals out_color_components.
+ */
+ int rec_outbuf_height; /* min recommended height of scanline buffer */
+ /* If the buffer passed to jpeg_read_scanlines() is less than this many rows
+ * high, space and time will be wasted due to unnecessary data copying.
+ * Usually rec_outbuf_height will be 1 or 2, at most 4.
+ */
+
+ /* When quantizing colors, the output colormap is described by these fields.
+ * The application can supply a colormap by setting colormap non-NULL before
+ * calling jpeg_start_decompress; otherwise a colormap is created during
+ * jpeg_start_decompress or jpeg_start_output.
+ * The map has out_color_components rows and actual_number_of_colors columns.
+ */
+ int actual_number_of_colors; /* number of entries in use */
+ JSAMPARRAY colormap; /* The color map as a 2-D pixel array */
+
+ /* State variables: these variables indicate the progress of decompression.
+ * The application may examine these but must not modify them.
+ */
+
+ /* Row index of next scanline to be read from jpeg_read_scanlines().
+ * Application may use this to control its processing loop, e.g.,
+ * "while (output_scanline < output_height)".
+ */
+ JDIMENSION output_scanline; /* 0 .. output_height-1 */
+
+ /* Current input scan number and number of iMCU rows completed in scan.
+ * These indicate the progress of the decompressor input side.
+ */
+ int input_scan_number; /* Number of SOS markers seen so far */
+ JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */
+
+ /* The "output scan number" is the notional scan being displayed by the
+ * output side. The decompressor will not allow output scan/row number
+ * to get ahead of input scan/row, but it can fall arbitrarily far behind.
+ */
+ int output_scan_number; /* Nominal scan number being displayed */
+ JDIMENSION output_iMCU_row; /* Number of iMCU rows read */
+
+ /* Current progression status. coef_bits[c][i] indicates the precision
+ * with which component c's DCT coefficient i (in zigzag order) is known.
+ * It is -1 when no data has yet been received, otherwise it is the point
+ * transform (shift) value for the most recent scan of the coefficient
+ * (thus, 0 at completion of the progression).
+ * This pointer is NULL when reading a non-progressive file.
+ */
+ int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */
+
+ /* Internal JPEG parameters --- the application usually need not look at
+ * these fields. Note that the decompressor output side may not use
+ * any parameters that can change between scans.
+ */
+
+ /* Quantization and Huffman tables are carried forward across input
+ * datastreams when processing abbreviated JPEG datastreams.
+ */
+
+ JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
+ /* ptrs to coefficient quantization tables, or NULL if not defined */
+
+ JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ /* ptrs to Huffman coding tables, or NULL if not defined */
+
+ /* These parameters are never carried across datastreams, since they
+ * are given in SOF/SOS markers or defined to be reset by SOI.
+ */
+
+ int data_precision; /* bits of precision in image data */
+
+ jpeg_component_info * comp_info;
+ /* comp_info[i] describes component that appears i'th in SOF */
+
+#if JPEG_LIB_VERSION >= 80
+ boolean is_baseline; /* TRUE if Baseline SOF0 encountered */
+#endif
+ boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */
+ boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
+
+ UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
+ UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
+ UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
+
+ unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */
+
+ /* These fields record data obtained from optional markers recognized by
+ * the JPEG library.
+ */
+ boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */
+ /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
+ UINT8 JFIF_major_version; /* JFIF version number */
+ UINT8 JFIF_minor_version;
+ UINT8 density_unit; /* JFIF code for pixel size units */
+ UINT16 X_density; /* Horizontal pixel density */
+ UINT16 Y_density; /* Vertical pixel density */
+ boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */
+ UINT8 Adobe_transform; /* Color transform code from Adobe marker */
+
+ boolean CCIR601_sampling; /* TRUE=first samples are cosited */
+
+ /* Aside from the specific data retained from APPn markers known to the
+ * library, the uninterpreted contents of any or all APPn and COM markers
+ * can be saved in a list for examination by the application.
+ */
+ jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */
+
+ /* Remaining fields are known throughout decompressor, but generally
+ * should not be touched by a surrounding application.
+ */
+
+ /*
+ * These fields are computed during decompression startup
+ */
+ int max_h_samp_factor; /* largest h_samp_factor */
+ int max_v_samp_factor; /* largest v_samp_factor */
+
+#if JPEG_LIB_VERSION >= 70
+ int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
+ int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
+#else
+ int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */
+#endif
+
+ JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */
+ /* The coefficient controller's input and output progress is measured in
+ * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows
+ * in fully interleaved JPEG scans, but are used whether the scan is
+ * interleaved or not. We define an iMCU row as v_samp_factor DCT block
+ * rows of each component. Therefore, the IDCT output contains
+ * v_samp_factor*DCT_[v_]scaled_size sample rows of a component per iMCU row.
+ */
+
+ JSAMPLE * sample_range_limit; /* table for fast range-limiting */
+
+ /*
+ * These fields are valid during any one scan.
+ * They describe the components and MCUs actually appearing in the scan.
+ * Note that the decompressor output side must not use these fields.
+ */
+ int comps_in_scan; /* # of JPEG components in this scan */
+ jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
+ /* *cur_comp_info[i] describes component that appears i'th in SOS */
+
+ JDIMENSION MCUs_per_row; /* # of MCUs across the image */
+ JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
+
+ int blocks_in_MCU; /* # of DCT blocks per MCU */
+ int MCU_membership[D_MAX_BLOCKS_IN_MCU];
+ /* MCU_membership[i] is index in cur_comp_info of component owning */
+ /* i'th block in an MCU */
+
+ int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
+
+#if JPEG_LIB_VERSION >= 80
+ /* These fields are derived from Se of first SOS marker.
+ */
+ int block_size; /* the basic DCT block size: 1..16 */
+ const int * natural_order; /* natural-order position array for entropy decode */
+ int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */
+#endif
+
+ /* This field is shared between entropy decoder and marker parser.
+ * It is either zero or the code of a JPEG marker that has been
+ * read from the data source, but has not yet been processed.
+ */
+ int unread_marker;
+
+ /*
+ * Links to decompression subobjects (methods, private variables of modules)
+ */
+ struct jpeg_decomp_master * master;
+ struct jpeg_d_main_controller * main;
+ struct jpeg_d_coef_controller * coef;
+ struct jpeg_d_post_controller * post;
+ struct jpeg_input_controller * inputctl;
+ struct jpeg_marker_reader * marker;
+ struct jpeg_entropy_decoder * entropy;
+ struct jpeg_inverse_dct * idct;
+ struct jpeg_upsampler * upsample;
+ struct jpeg_color_deconverter * cconvert;
+ struct jpeg_color_quantizer * cquantize;
+};
+
+
+/* "Object" declarations for JPEG modules that may be supplied or called
+ * directly by the surrounding application.
+ * As with all objects in the JPEG library, these structs only define the
+ * publicly visible methods and state variables of a module. Additional
+ * private fields may exist after the public ones.
+ */
+
+
+/* Error handler object */
+
+struct jpeg_error_mgr {
+ /* Error exit handler: does not return to caller */
+ JMETHOD(void, error_exit, (j_common_ptr cinfo));
+ /* Conditionally emit a trace or warning message */
+ JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
+ /* Routine that actually outputs a trace or error message */
+ JMETHOD(void, output_message, (j_common_ptr cinfo));
+ /* Format a message string for the most recent JPEG error or message */
+ JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer));
+#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */
+ /* Reset error state variables at start of a new image */
+ JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo));
+
+ /* The message ID code and any parameters are saved here.
+ * A message can have one string parameter or up to 8 int parameters.
+ */
+ int msg_code;
+#define JMSG_STR_PARM_MAX 80
+ union {
+ int i[8];
+ char s[JMSG_STR_PARM_MAX];
+ } msg_parm;
+
+ /* Standard state variables for error facility */
+
+ int trace_level; /* max msg_level that will be displayed */
+
+ /* For recoverable corrupt-data errors, we emit a warning message,
+ * but keep going unless emit_message chooses to abort. emit_message
+ * should count warnings in num_warnings. The surrounding application
+ * can check for bad data by seeing if num_warnings is nonzero at the
+ * end of processing.
+ */
+ long num_warnings; /* number of corrupt-data warnings */
+
+ /* These fields point to the table(s) of error message strings.
+ * An application can change the table pointer to switch to a different
+ * message list (typically, to change the language in which errors are
+ * reported). Some applications may wish to add additional error codes
+ * that will be handled by the JPEG library error mechanism; the second
+ * table pointer is used for this purpose.
+ *
+ * First table includes all errors generated by JPEG library itself.
+ * Error code 0 is reserved for a "no such error string" message.
+ */
+ const char * const * jpeg_message_table; /* Library errors */
+ int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */
+ /* Second table can be added by application (see cjpeg/djpeg for example).
+ * It contains strings numbered first_addon_message..last_addon_message.
+ */
+ const char * const * addon_message_table; /* Non-library errors */
+ int first_addon_message; /* code for first string in addon table */
+ int last_addon_message; /* code for last string in addon table */
+};
+
+
+/* Progress monitor object */
+
+struct jpeg_progress_mgr {
+ JMETHOD(void, progress_monitor, (j_common_ptr cinfo));
+
+ long pass_counter; /* work units completed in this pass */
+ long pass_limit; /* total number of work units in this pass */
+ int completed_passes; /* passes completed so far */
+ int total_passes; /* total number of passes expected */
+};
+
+
+/* Data destination object for compression */
+
+struct jpeg_destination_mgr {
+ JOCTET * next_output_byte; /* => next byte to write in buffer */
+ size_t free_in_buffer; /* # of byte spaces remaining in buffer */
+
+ JMETHOD(void, init_destination, (j_compress_ptr cinfo));
+ JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo));
+ JMETHOD(void, term_destination, (j_compress_ptr cinfo));
+};
+
+
+/* Data source object for decompression */
+
+struct jpeg_source_mgr {
+ const JOCTET * next_input_byte; /* => next byte to read from buffer */
+ size_t bytes_in_buffer; /* # of bytes remaining in buffer */
+
+ JMETHOD(void, init_source, (j_decompress_ptr cinfo));
+ JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo));
+ JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes));
+ JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired));
+ JMETHOD(void, term_source, (j_decompress_ptr cinfo));
+};
+
+
+/* Memory manager object.
+ * Allocates "small" objects (a few K total), "large" objects (tens of K),
+ * and "really big" objects (virtual arrays with backing store if needed).
+ * The memory manager does not allow individual objects to be freed; rather,
+ * each created object is assigned to a pool, and whole pools can be freed
+ * at once. This is faster and more convenient than remembering exactly what
+ * to free, especially where malloc()/free() are not too speedy.
+ * NB: alloc routines never return NULL. They exit to error_exit if not
+ * successful.
+ */
+
+#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */
+#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */
+#define JPOOL_NUMPOOLS 2
+
+typedef struct jvirt_sarray_control * jvirt_sarray_ptr;
+typedef struct jvirt_barray_control * jvirt_barray_ptr;
+
+
+struct jpeg_memory_mgr {
+ /* Method pointers */
+ JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id,
+ size_t sizeofobject));
+ JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id,
+ size_t sizeofobject));
+ JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id,
+ JDIMENSION samplesperrow,
+ JDIMENSION numrows));
+ JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id,
+ JDIMENSION blocksperrow,
+ JDIMENSION numrows));
+ JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo,
+ int pool_id,
+ boolean pre_zero,
+ JDIMENSION samplesperrow,
+ JDIMENSION numrows,
+ JDIMENSION maxaccess));
+ JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo,
+ int pool_id,
+ boolean pre_zero,
+ JDIMENSION blocksperrow,
+ JDIMENSION numrows,
+ JDIMENSION maxaccess));
+ JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo));
+ JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo,
+ jvirt_sarray_ptr ptr,
+ JDIMENSION start_row,
+ JDIMENSION num_rows,
+ boolean writable));
+ JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo,
+ jvirt_barray_ptr ptr,
+ JDIMENSION start_row,
+ JDIMENSION num_rows,
+ boolean writable));
+ JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id));
+ JMETHOD(void, self_destruct, (j_common_ptr cinfo));
+
+ /* Limit on memory allocation for this JPEG object. (Note that this is
+ * merely advisory, not a guaranteed maximum; it only affects the space
+ * used for virtual-array buffers.) May be changed by outer application
+ * after creating the JPEG object.
+ */
+ long max_memory_to_use;
+
+ /* Maximum allocation request accepted by alloc_large. */
+ long max_alloc_chunk;
+};
+
+
+/* Routine signature for application-supplied marker processing methods.
+ * Need not pass marker code since it is stored in cinfo->unread_marker.
+ */
+typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
+
+
+/* Declarations for routines called by application.
+ * The JPP macro hides prototype parameters from compilers that can't cope.
+ * Note JPP requires double parentheses.
+ */
+
+#ifdef HAVE_PROTOTYPES
+#define JPP(arglist) arglist
+#else
+#define JPP(arglist) ()
+#endif
+
+
+/* Short forms of external names for systems with brain-damaged linkers.
+ * We shorten external names to be unique in the first six letters, which
+ * is good enough for all known systems.
+ * (If your compiler itself needs names to be unique in less than 15
+ * characters, you are out of luck. Get a better compiler.)
+ */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_std_error jStdError
+#define jpeg_CreateCompress jCreaCompress
+#define jpeg_CreateDecompress jCreaDecompress
+#define jpeg_destroy_compress jDestCompress
+#define jpeg_destroy_decompress jDestDecompress
+#define jpeg_stdio_dest jStdDest
+#define jpeg_stdio_src jStdSrc
+#if JPEG_LIB_VERSION >= 80
+#define jpeg_mem_dest jMemDest
+#define jpeg_mem_src jMemSrc
+#endif
+#define jpeg_set_defaults jSetDefaults
+#define jpeg_set_colorspace jSetColorspace
+#define jpeg_default_colorspace jDefColorspace
+#define jpeg_set_quality jSetQuality
+#define jpeg_set_linear_quality jSetLQuality
+#if JPEG_LIB_VERSION >= 70
+#define jpeg_default_qtables jDefQTables
+#endif
+#define jpeg_add_quant_table jAddQuantTable
+#define jpeg_quality_scaling jQualityScaling
+#define jpeg_simple_progression jSimProgress
+#define jpeg_suppress_tables jSuppressTables
+#define jpeg_alloc_quant_table jAlcQTable
+#define jpeg_alloc_huff_table jAlcHTable
+#define jpeg_start_compress jStrtCompress
+#define jpeg_write_scanlines jWrtScanlines
+#define jpeg_finish_compress jFinCompress
+#if JPEG_LIB_VERSION >= 70
+#define jpeg_calc_jpeg_dimensions jCjpegDimensions
+#endif
+#define jpeg_write_raw_data jWrtRawData
+#define jpeg_write_marker jWrtMarker
+#define jpeg_write_m_header jWrtMHeader
+#define jpeg_write_m_byte jWrtMByte
+#define jpeg_write_tables jWrtTables
+#define jpeg_read_header jReadHeader
+#define jpeg_start_decompress jStrtDecompress
+#define jpeg_read_scanlines jReadScanlines
+#define jpeg_finish_decompress jFinDecompress
+#define jpeg_read_raw_data jReadRawData
+#define jpeg_has_multiple_scans jHasMultScn
+#define jpeg_start_output jStrtOutput
+#define jpeg_finish_output jFinOutput
+#define jpeg_input_complete jInComplete
+#define jpeg_new_colormap jNewCMap
+#define jpeg_consume_input jConsumeInput
+#if JPEG_LIB_VERSION >= 80
+#define jpeg_core_output_dimensions jCoreDimensions
+#endif
+#define jpeg_calc_output_dimensions jCalcDimensions
+#define jpeg_save_markers jSaveMarkers
+#define jpeg_set_marker_processor jSetMarker
+#define jpeg_read_coefficients jReadCoefs
+#define jpeg_write_coefficients jWrtCoefs
+#define jpeg_copy_critical_parameters jCopyCrit
+#define jpeg_abort_compress jAbrtCompress
+#define jpeg_abort_decompress jAbrtDecompress
+#define jpeg_abort jAbort
+#define jpeg_destroy jDestroy
+#define jpeg_resync_to_restart jResyncRestart
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/* Default error-management setup */
+EXTERN(struct jpeg_error_mgr *) jpeg_std_error
+ JPP((struct jpeg_error_mgr * err));
+
+/* Initialization of JPEG compression objects.
+ * jpeg_create_compress() and jpeg_create_decompress() are the exported
+ * names that applications should call. These expand to calls on
+ * jpeg_CreateCompress and jpeg_CreateDecompress with additional information
+ * passed for version mismatch checking.
+ * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.
+ */
+#define jpeg_create_compress(cinfo) \
+ jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
+ (size_t) sizeof(struct jpeg_compress_struct))
+#define jpeg_create_decompress(cinfo) \
+ jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
+ (size_t) sizeof(struct jpeg_decompress_struct))
+EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo,
+ int version, size_t structsize));
+EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo,
+ int version, size_t structsize));
+/* Destruction of JPEG compression objects */
+EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
+
+/* Standard data source and destination managers: stdio streams. */
+/* Caller is responsible for opening the file before and closing after. */
+EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
+EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
+
+#if JPEG_LIB_VERSION >= 80
+/* Data source and destination managers: memory buffers. */
+EXTERN(void) jpeg_mem_dest JPP((j_compress_ptr cinfo,
+ unsigned char ** outbuffer,
+ unsigned long * outsize));
+EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo,
+ unsigned char * inbuffer,
+ unsigned long insize));
+#endif
+
+/* Default parameter setup for compression */
+EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
+/* Compression parameter setup aids */
+EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo,
+ J_COLOR_SPACE colorspace));
+EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
+ boolean force_baseline));
+EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
+ int scale_factor,
+ boolean force_baseline));
+#if JPEG_LIB_VERSION >= 70
+EXTERN(void) jpeg_default_qtables JPP((j_compress_ptr cinfo,
+ boolean force_baseline));
+#endif
+EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
+ const unsigned int *basic_table,
+ int scale_factor,
+ boolean force_baseline));
+EXTERN(int) jpeg_quality_scaling JPP((int quality));
+EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
+ boolean suppress));
+EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
+EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
+
+/* Main entry points for compression */
+EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
+ boolean write_all_tables));
+EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
+ JSAMPARRAY scanlines,
+ JDIMENSION num_lines));
+EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo));
+
+#if JPEG_LIB_VERSION >= 70
+/* Precalculate JPEG dimensions for current compression parameters. */
+EXTERN(void) jpeg_calc_jpeg_dimensions JPP((j_compress_ptr cinfo));
+#endif
+
+/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
+EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo,
+ JSAMPIMAGE data,
+ JDIMENSION num_lines));
+
+/* Write a special marker. See libjpeg.txt concerning safe usage. */
+EXTERN(void) jpeg_write_marker
+ JPP((j_compress_ptr cinfo, int marker,
+ const JOCTET * dataptr, unsigned int datalen));
+/* Same, but piecemeal. */
+EXTERN(void) jpeg_write_m_header
+ JPP((j_compress_ptr cinfo, int marker, unsigned int datalen));
+EXTERN(void) jpeg_write_m_byte
+ JPP((j_compress_ptr cinfo, int val));
+
+/* Alternate compression function: just write an abbreviated table file */
+EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
+
+/* Decompression startup: read start of JPEG datastream to see what's there */
+EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo,
+ boolean require_image));
+/* Return value is one of: */
+#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */
+#define JPEG_HEADER_OK 1 /* Found valid image datastream */
+#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */
+/* If you pass require_image = TRUE (normal case), you need not check for
+ * a TABLES_ONLY return code; an abbreviated file will cause an error exit.
+ * JPEG_SUSPENDED is only possible if you use a data source module that can
+ * give a suspension return (the stdio source module doesn't).
+ */
+
+/* Main entry points for decompression */
+EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo));
+EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo,
+ JSAMPARRAY scanlines,
+ JDIMENSION max_lines));
+EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
+
+/* Replaces jpeg_read_scanlines when reading raw downsampled data. */
+EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE data,
+ JDIMENSION max_lines));
+
+/* Additional entry points for buffered-image mode. */
+EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo));
+EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo,
+ int scan_number));
+EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo));
+EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo));
+EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo));
+EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
+/* Return value is one of: */
+/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */
+#define JPEG_REACHED_SOS 1 /* Reached start of new scan */
+#define JPEG_REACHED_EOI 2 /* Reached end of image */
+#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */
+#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */
+
+/* Precalculate output dimensions for current decompression parameters. */
+#if JPEG_LIB_VERSION >= 80
+EXTERN(void) jpeg_core_output_dimensions JPP((j_decompress_ptr cinfo));
+#endif
+EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
+
+/* Control saving of COM and APPn markers into marker_list. */
+EXTERN(void) jpeg_save_markers
+ JPP((j_decompress_ptr cinfo, int marker_code,
+ unsigned int length_limit));
+
+/* Install a special processing method for COM or APPn markers. */
+EXTERN(void) jpeg_set_marker_processor
+ JPP((j_decompress_ptr cinfo, int marker_code,
+ jpeg_marker_parser_method routine));
+
+/* Read or write raw DCT coefficients --- useful for lossless transcoding. */
+EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo));
+EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo,
+ jvirt_barray_ptr * coef_arrays));
+EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo,
+ j_compress_ptr dstinfo));
+
+/* If you choose to abort compression or decompression before completing
+ * jpeg_finish_(de)compress, then you need to clean up to release memory,
+ * temporary files, etc. You can just call jpeg_destroy_(de)compress
+ * if you're done with the JPEG object, but if you want to clean it up and
+ * reuse it, call this:
+ */
+EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo));
+
+/* Generic versions of jpeg_abort and jpeg_destroy that work on either
+ * flavor of JPEG object. These may be more convenient in some places.
+ */
+EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
+EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
+
+/* Default restart-marker-resync procedure for use by data source modules */
+EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
+ int desired));
+
+
+/* These marker codes are exported since applications and data source modules
+ * are likely to want to use them.
+ */
+
+#define JPEG_RST0 0xD0 /* RST0 marker code */
+#define JPEG_EOI 0xD9 /* EOI marker code */
+#define JPEG_APP0 0xE0 /* APP0 marker code */
+#define JPEG_COM 0xFE /* COM marker code */
+
+
+/* If we have a brain-damaged compiler that emits warnings (or worse, errors)
+ * for structure definitions that are never filled in, keep it quiet by
+ * supplying dummy definitions for the various substructures.
+ */
+
+#ifdef INCOMPLETE_TYPES_BROKEN
+#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */
+struct jvirt_sarray_control { long dummy; };
+struct jvirt_barray_control { long dummy; };
+struct jpeg_comp_master { long dummy; };
+struct jpeg_c_main_controller { long dummy; };
+struct jpeg_c_prep_controller { long dummy; };
+struct jpeg_c_coef_controller { long dummy; };
+struct jpeg_marker_writer { long dummy; };
+struct jpeg_color_converter { long dummy; };
+struct jpeg_downsampler { long dummy; };
+struct jpeg_forward_dct { long dummy; };
+struct jpeg_entropy_encoder { long dummy; };
+struct jpeg_decomp_master { long dummy; };
+struct jpeg_d_main_controller { long dummy; };
+struct jpeg_d_coef_controller { long dummy; };
+struct jpeg_d_post_controller { long dummy; };
+struct jpeg_input_controller { long dummy; };
+struct jpeg_marker_reader { long dummy; };
+struct jpeg_entropy_decoder { long dummy; };
+struct jpeg_inverse_dct { long dummy; };
+struct jpeg_upsampler { long dummy; };
+struct jpeg_color_deconverter { long dummy; };
+struct jpeg_color_quantizer { long dummy; };
+#endif /* JPEG_INTERNALS */
+#endif /* INCOMPLETE_TYPES_BROKEN */
+
+
+/*
+ * The JPEG library modules define JPEG_INTERNALS before including this file.
+ * The internal structure declarations are read only when that is true.
+ * Applications using the library should not include jpegint.h, but may wish
+ * to include jerror.h.
+ */
+
+#ifdef JPEG_INTERNALS
+#include "jpegint.h" /* fetch private declarations */
+#include "jerror.h" /* fetch error codes too */
+#endif
+
+#ifdef __cplusplus
+#ifndef DONT_USE_EXTERN_C
+}
+#endif
+#endif
+
+#endif /* JPEGLIB_H */
diff --git a/src/libjpeg-turbo/jquant1.c b/src/libjpeg-turbo/jquant1.c
new file mode 100644
index 0000000..362bb1e
--- /dev/null
+++ b/src/libjpeg-turbo/jquant1.c
@@ -0,0 +1,860 @@
+/*
+ * jquant1.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 2009, D. R. Commander
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains 1-pass color quantization (color mapping) routines.
+ * These routines provide mapping to a fixed color map using equally spaced
+ * color values. Optional Floyd-Steinberg or ordered dithering is available.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+#ifdef QUANT_1PASS_SUPPORTED
+
+
+/*
+ * The main purpose of 1-pass quantization is to provide a fast, if not very
+ * high quality, colormapped output capability. A 2-pass quantizer usually
+ * gives better visual quality; however, for quantized grayscale output this
+ * quantizer is perfectly adequate. Dithering is highly recommended with this
+ * quantizer, though you can turn it off if you really want to.
+ *
+ * In 1-pass quantization the colormap must be chosen in advance of seeing the
+ * image. We use a map consisting of all combinations of Ncolors[i] color
+ * values for the i'th component. The Ncolors[] values are chosen so that
+ * their product, the total number of colors, is no more than that requested.
+ * (In most cases, the product will be somewhat less.)
+ *
+ * Since the colormap is orthogonal, the representative value for each color
+ * component can be determined without considering the other components;
+ * then these indexes can be combined into a colormap index by a standard
+ * N-dimensional-array-subscript calculation. Most of the arithmetic involved
+ * can be precalculated and stored in the lookup table colorindex[].
+ * colorindex[i][j] maps pixel value j in component i to the nearest
+ * representative value (grid plane) for that component; this index is
+ * multiplied by the array stride for component i, so that the
+ * index of the colormap entry closest to a given pixel value is just
+ * sum( colorindex[component-number][pixel-component-value] )
+ * Aside from being fast, this scheme allows for variable spacing between
+ * representative values with no additional lookup cost.
+ *
+ * If gamma correction has been applied in color conversion, it might be wise
+ * to adjust the color grid spacing so that the representative colors are
+ * equidistant in linear space. At this writing, gamma correction is not
+ * implemented by jdcolor, so nothing is done here.
+ */
+
+
+/* Declarations for ordered dithering.
+ *
+ * We use a standard 16x16 ordered dither array. The basic concept of ordered
+ * dithering is described in many references, for instance Dale Schumacher's
+ * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991).
+ * In place of Schumacher's comparisons against a "threshold" value, we add a
+ * "dither" value to the input pixel and then round the result to the nearest
+ * output value. The dither value is equivalent to (0.5 - threshold) times
+ * the distance between output values. For ordered dithering, we assume that
+ * the output colors are equally spaced; if not, results will probably be
+ * worse, since the dither may be too much or too little at a given point.
+ *
+ * The normal calculation would be to form pixel value + dither, range-limit
+ * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual.
+ * We can skip the separate range-limiting step by extending the colorindex
+ * table in both directions.
+ */
+
+#define ODITHER_SIZE 16 /* dimension of dither matrix */
+/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */
+#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */
+#define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */
+
+typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE];
+typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE];
+
+static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = {
+ /* Bayer's order-4 dither array. Generated by the code given in
+ * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I.
+ * The values in this array must range from 0 to ODITHER_CELLS-1.
+ */
+ { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
+ { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
+ { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
+ { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
+ { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
+ { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
+ { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
+ { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
+ { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
+ { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
+ { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
+ { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
+ { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
+ { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
+ { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
+ { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
+};
+
+
+/* Declarations for Floyd-Steinberg dithering.
+ *
+ * Errors are accumulated into the array fserrors[], at a resolution of
+ * 1/16th of a pixel count. The error at a given pixel is propagated
+ * to its not-yet-processed neighbors using the standard F-S fractions,
+ * ... (here) 7/16
+ * 3/16 5/16 1/16
+ * We work left-to-right on even rows, right-to-left on odd rows.
+ *
+ * We can get away with a single array (holding one row's worth of errors)
+ * by using it to store the current row's errors at pixel columns not yet
+ * processed, but the next row's errors at columns already processed. We
+ * need only a few extra variables to hold the errors immediately around the
+ * current column. (If we are lucky, those variables are in registers, but
+ * even if not, they're probably cheaper to access than array elements are.)
+ *
+ * The fserrors[] array is indexed [component#][position].
+ * We provide (#columns + 2) entries per component; the extra entry at each
+ * end saves us from special-casing the first and last pixels.
+ *
+ * Note: on a wide image, we might not have enough room in a PC's near data
+ * segment to hold the error array; so it is allocated with alloc_large.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+typedef INT16 FSERROR; /* 16 bits should be enough */
+typedef int LOCFSERROR; /* use 'int' for calculation temps */
+#else
+typedef INT32 FSERROR; /* may need more than 16 bits */
+typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */
+#endif
+
+typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
+
+
+/* Private subobject */
+
+#define MAX_Q_COMPS 4 /* max components I can handle */
+
+typedef struct {
+ struct jpeg_color_quantizer pub; /* public fields */
+
+ /* Initially allocated colormap is saved here */
+ JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */
+ int sv_actual; /* number of entries in use */
+
+ JSAMPARRAY colorindex; /* Precomputed mapping for speed */
+ /* colorindex[i][j] = index of color closest to pixel value j in component i,
+ * premultiplied as described above. Since colormap indexes must fit into
+ * JSAMPLEs, the entries of this array will too.
+ */
+ boolean is_padded; /* is the colorindex padded for odither? */
+
+ int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */
+
+ /* Variables for ordered dithering */
+ int row_index; /* cur row's vertical index in dither matrix */
+ ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */
+
+ /* Variables for Floyd-Steinberg dithering */
+ FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */
+ boolean on_odd_row; /* flag to remember which row we are on */
+} my_cquantizer;
+
+typedef my_cquantizer * my_cquantize_ptr;
+
+
+/*
+ * Policy-making subroutines for create_colormap and create_colorindex.
+ * These routines determine the colormap to be used. The rest of the module
+ * only assumes that the colormap is orthogonal.
+ *
+ * * select_ncolors decides how to divvy up the available colors
+ * among the components.
+ * * output_value defines the set of representative values for a component.
+ * * largest_input_value defines the mapping from input values to
+ * representative values for a component.
+ * Note that the latter two routines may impose different policies for
+ * different components, though this is not currently done.
+ */
+
+
+LOCAL(int)
+select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
+/* Determine allocation of desired colors to components, */
+/* and fill in Ncolors[] array to indicate choice. */
+/* Return value is total number of colors (product of Ncolors[] values). */
+{
+ int nc = cinfo->out_color_components; /* number of color components */
+ int max_colors = cinfo->desired_number_of_colors;
+ int total_colors, iroot, i, j;
+ boolean changed;
+ long temp;
+ int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
+ RGB_order[0] = rgb_green[cinfo->out_color_space];
+ RGB_order[1] = rgb_red[cinfo->out_color_space];
+ RGB_order[2] = rgb_blue[cinfo->out_color_space];
+
+ /* We can allocate at least the nc'th root of max_colors per component. */
+ /* Compute floor(nc'th root of max_colors). */
+ iroot = 1;
+ do {
+ iroot++;
+ temp = iroot; /* set temp = iroot ** nc */
+ for (i = 1; i < nc; i++)
+ temp *= iroot;
+ } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */
+ iroot--; /* now iroot = floor(root) */
+
+ /* Must have at least 2 color values per component */
+ if (iroot < 2)
+ ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp);
+
+ /* Initialize to iroot color values for each component */
+ total_colors = 1;
+ for (i = 0; i < nc; i++) {
+ Ncolors[i] = iroot;
+ total_colors *= iroot;
+ }
+ /* We may be able to increment the count for one or more components without
+ * exceeding max_colors, though we know not all can be incremented.
+ * Sometimes, the first component can be incremented more than once!
+ * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.)
+ * In RGB colorspace, try to increment G first, then R, then B.
+ */
+ do {
+ changed = FALSE;
+ for (i = 0; i < nc; i++) {
+ j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i);
+ /* calculate new total_colors if Ncolors[j] is incremented */
+ temp = total_colors / Ncolors[j];
+ temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */
+ if (temp > (long) max_colors)
+ break; /* won't fit, done with this pass */
+ Ncolors[j]++; /* OK, apply the increment */
+ total_colors = (int) temp;
+ changed = TRUE;
+ }
+ } while (changed);
+
+ return total_colors;
+}
+
+
+LOCAL(int)
+output_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
+/* Return j'th output value, where j will range from 0 to maxj */
+/* The output values must fall in 0..MAXJSAMPLE in increasing order */
+{
+ /* We always provide values 0 and MAXJSAMPLE for each component;
+ * any additional values are equally spaced between these limits.
+ * (Forcing the upper and lower values to the limits ensures that
+ * dithering can't produce a color outside the selected gamut.)
+ */
+ return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj);
+}
+
+
+LOCAL(int)
+largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
+/* Return largest input value that should map to j'th output value */
+/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
+{
+ /* Breakpoints are halfway between values returned by output_value */
+ return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj));
+}
+
+
+/*
+ * Create the colormap.
+ */
+
+LOCAL(void)
+create_colormap (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ JSAMPARRAY colormap; /* Created colormap */
+ int total_colors; /* Number of distinct output colors */
+ int i,j,k, nci, blksize, blkdist, ptr, val;
+
+ /* Select number of colors for each component */
+ total_colors = select_ncolors(cinfo, cquantize->Ncolors);
+
+ /* Report selected color counts */
+ if (cinfo->out_color_components == 3)
+ TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS,
+ total_colors, cquantize->Ncolors[0],
+ cquantize->Ncolors[1], cquantize->Ncolors[2]);
+ else
+ TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors);
+
+ /* Allocate and fill in the colormap. */
+ /* The colors are ordered in the map in standard row-major order, */
+ /* i.e. rightmost (highest-indexed) color changes most rapidly. */
+
+ colormap = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components);
+
+ /* blksize is number of adjacent repeated entries for a component */
+ /* blkdist is distance between groups of identical entries for a component */
+ blkdist = total_colors;
+
+ for (i = 0; i < cinfo->out_color_components; i++) {
+ /* fill in colormap entries for i'th color component */
+ nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
+ blksize = blkdist / nci;
+ for (j = 0; j < nci; j++) {
+ /* Compute j'th output value (out of nci) for component */
+ val = output_value(cinfo, i, j, nci-1);
+ /* Fill in all colormap entries that have this value of this component */
+ for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
+ /* fill in blksize entries beginning at ptr */
+ for (k = 0; k < blksize; k++)
+ colormap[i][ptr+k] = (JSAMPLE) val;
+ }
+ }
+ blkdist = blksize; /* blksize of this color is blkdist of next */
+ }
+
+ /* Save the colormap in private storage,
+ * where it will survive color quantization mode changes.
+ */
+ cquantize->sv_colormap = colormap;
+ cquantize->sv_actual = total_colors;
+}
+
+
+/*
+ * Create the color index table.
+ */
+
+LOCAL(void)
+create_colorindex (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ JSAMPROW indexptr;
+ int i,j,k, nci, blksize, val, pad;
+
+ /* For ordered dither, we pad the color index tables by MAXJSAMPLE in
+ * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
+ * This is not necessary in the other dithering modes. However, we
+ * flag whether it was done in case user changes dithering mode.
+ */
+ if (cinfo->dither_mode == JDITHER_ORDERED) {
+ pad = MAXJSAMPLE*2;
+ cquantize->is_padded = TRUE;
+ } else {
+ pad = 0;
+ cquantize->is_padded = FALSE;
+ }
+
+ cquantize->colorindex = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (JDIMENSION) (MAXJSAMPLE+1 + pad),
+ (JDIMENSION) cinfo->out_color_components);
+
+ /* blksize is number of adjacent repeated entries for a component */
+ blksize = cquantize->sv_actual;
+
+ for (i = 0; i < cinfo->out_color_components; i++) {
+ /* fill in colorindex entries for i'th color component */
+ nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
+ blksize = blksize / nci;
+
+ /* adjust colorindex pointers to provide padding at negative indexes. */
+ if (pad)
+ cquantize->colorindex[i] += MAXJSAMPLE;
+
+ /* in loop, val = index of current output value, */
+ /* and k = largest j that maps to current val */
+ indexptr = cquantize->colorindex[i];
+ val = 0;
+ k = largest_input_value(cinfo, i, 0, nci-1);
+ for (j = 0; j <= MAXJSAMPLE; j++) {
+ while (j > k) /* advance val if past boundary */
+ k = largest_input_value(cinfo, i, ++val, nci-1);
+ /* premultiply so that no multiplication needed in main processing */
+ indexptr[j] = (JSAMPLE) (val * blksize);
+ }
+ /* Pad at both ends if necessary */
+ if (pad)
+ for (j = 1; j <= MAXJSAMPLE; j++) {
+ indexptr[-j] = indexptr[0];
+ indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE];
+ }
+ }
+}
+
+
+/*
+ * Create an ordered-dither array for a component having ncolors
+ * distinct output values.
+ */
+
+LOCAL(ODITHER_MATRIX_PTR)
+make_odither_array (j_decompress_ptr cinfo, int ncolors)
+{
+ ODITHER_MATRIX_PTR odither;
+ int j,k;
+ INT32 num,den;
+
+ odither = (ODITHER_MATRIX_PTR)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(ODITHER_MATRIX));
+ /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
+ * Hence the dither value for the matrix cell with fill order f
+ * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
+ * On 16-bit-int machine, be careful to avoid overflow.
+ */
+ den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1));
+ for (j = 0; j < ODITHER_SIZE; j++) {
+ for (k = 0; k < ODITHER_SIZE; k++) {
+ num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k])))
+ * MAXJSAMPLE;
+ /* Ensure round towards zero despite C's lack of consistency
+ * about rounding negative values in integer division...
+ */
+ odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den);
+ }
+ }
+ return odither;
+}
+
+
+/*
+ * Create the ordered-dither tables.
+ * Components having the same number of representative colors may
+ * share a dither table.
+ */
+
+LOCAL(void)
+create_odither_tables (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ ODITHER_MATRIX_PTR odither;
+ int i, j, nci;
+
+ for (i = 0; i < cinfo->out_color_components; i++) {
+ nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
+ odither = NULL; /* search for matching prior component */
+ for (j = 0; j < i; j++) {
+ if (nci == cquantize->Ncolors[j]) {
+ odither = cquantize->odither[j];
+ break;
+ }
+ }
+ if (odither == NULL) /* need a new table? */
+ odither = make_odither_array(cinfo, nci);
+ cquantize->odither[i] = odither;
+ }
+}
+
+
+/*
+ * Map some rows of pixels to the output colormapped representation.
+ */
+
+METHODDEF(void)
+color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+/* General case, no dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ JSAMPARRAY colorindex = cquantize->colorindex;
+ register int pixcode, ci;
+ register JSAMPROW ptrin, ptrout;
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+ register int nc = cinfo->out_color_components;
+
+ for (row = 0; row < num_rows; row++) {
+ ptrin = input_buf[row];
+ ptrout = output_buf[row];
+ for (col = width; col > 0; col--) {
+ pixcode = 0;
+ for (ci = 0; ci < nc; ci++) {
+ pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]);
+ }
+ *ptrout++ = (JSAMPLE) pixcode;
+ }
+ }
+}
+
+
+METHODDEF(void)
+color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+/* Fast path for out_color_components==3, no dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ register int pixcode;
+ register JSAMPROW ptrin, ptrout;
+ JSAMPROW colorindex0 = cquantize->colorindex[0];
+ JSAMPROW colorindex1 = cquantize->colorindex[1];
+ JSAMPROW colorindex2 = cquantize->colorindex[2];
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+
+ for (row = 0; row < num_rows; row++) {
+ ptrin = input_buf[row];
+ ptrout = output_buf[row];
+ for (col = width; col > 0; col--) {
+ pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]);
+ pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]);
+ pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]);
+ *ptrout++ = (JSAMPLE) pixcode;
+ }
+ }
+}
+
+
+METHODDEF(void)
+quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+/* General case, with ordered dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ register JSAMPROW input_ptr;
+ register JSAMPROW output_ptr;
+ JSAMPROW colorindex_ci;
+ int * dither; /* points to active row of dither matrix */
+ int row_index, col_index; /* current indexes into dither matrix */
+ int nc = cinfo->out_color_components;
+ int ci;
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+
+ for (row = 0; row < num_rows; row++) {
+ /* Initialize output values to 0 so can process components separately */
+ jzero_far((void FAR *) output_buf[row],
+ (size_t) (width * SIZEOF(JSAMPLE)));
+ row_index = cquantize->row_index;
+ for (ci = 0; ci < nc; ci++) {
+ input_ptr = input_buf[row] + ci;
+ output_ptr = output_buf[row];
+ colorindex_ci = cquantize->colorindex[ci];
+ dither = cquantize->odither[ci][row_index];
+ col_index = 0;
+
+ for (col = width; col > 0; col--) {
+ /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
+ * select output value, accumulate into output code for this pixel.
+ * Range-limiting need not be done explicitly, as we have extended
+ * the colorindex table to produce the right answers for out-of-range
+ * inputs. The maximum dither is +- MAXJSAMPLE; this sets the
+ * required amount of padding.
+ */
+ *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]];
+ input_ptr += nc;
+ output_ptr++;
+ col_index = (col_index + 1) & ODITHER_MASK;
+ }
+ }
+ /* Advance row index for next row */
+ row_index = (row_index + 1) & ODITHER_MASK;
+ cquantize->row_index = row_index;
+ }
+}
+
+
+METHODDEF(void)
+quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+/* Fast path for out_color_components==3, with ordered dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ register int pixcode;
+ register JSAMPROW input_ptr;
+ register JSAMPROW output_ptr;
+ JSAMPROW colorindex0 = cquantize->colorindex[0];
+ JSAMPROW colorindex1 = cquantize->colorindex[1];
+ JSAMPROW colorindex2 = cquantize->colorindex[2];
+ int * dither0; /* points to active row of dither matrix */
+ int * dither1;
+ int * dither2;
+ int row_index, col_index; /* current indexes into dither matrix */
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+
+ for (row = 0; row < num_rows; row++) {
+ row_index = cquantize->row_index;
+ input_ptr = input_buf[row];
+ output_ptr = output_buf[row];
+ dither0 = cquantize->odither[0][row_index];
+ dither1 = cquantize->odither[1][row_index];
+ dither2 = cquantize->odither[2][row_index];
+ col_index = 0;
+
+ for (col = width; col > 0; col--) {
+ pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) +
+ dither0[col_index]]);
+ pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) +
+ dither1[col_index]]);
+ pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) +
+ dither2[col_index]]);
+ *output_ptr++ = (JSAMPLE) pixcode;
+ col_index = (col_index + 1) & ODITHER_MASK;
+ }
+ row_index = (row_index + 1) & ODITHER_MASK;
+ cquantize->row_index = row_index;
+ }
+}
+
+
+METHODDEF(void)
+quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+/* General case, with Floyd-Steinberg dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ register LOCFSERROR cur; /* current error or pixel value */
+ LOCFSERROR belowerr; /* error for pixel below cur */
+ LOCFSERROR bpreverr; /* error for below/prev col */
+ LOCFSERROR bnexterr; /* error for below/next col */
+ LOCFSERROR delta;
+ register FSERRPTR errorptr; /* => fserrors[] at column before current */
+ register JSAMPROW input_ptr;
+ register JSAMPROW output_ptr;
+ JSAMPROW colorindex_ci;
+ JSAMPROW colormap_ci;
+ int pixcode;
+ int nc = cinfo->out_color_components;
+ int dir; /* 1 for left-to-right, -1 for right-to-left */
+ int dirnc; /* dir * nc */
+ int ci;
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+ JSAMPLE *range_limit = cinfo->sample_range_limit;
+ SHIFT_TEMPS
+
+ for (row = 0; row < num_rows; row++) {
+ /* Initialize output values to 0 so can process components separately */
+ jzero_far((void FAR *) output_buf[row],
+ (size_t) (width * SIZEOF(JSAMPLE)));
+ for (ci = 0; ci < nc; ci++) {
+ input_ptr = input_buf[row] + ci;
+ output_ptr = output_buf[row];
+ if (cquantize->on_odd_row) {
+ /* work right to left in this row */
+ input_ptr += (width-1) * nc; /* so point to rightmost pixel */
+ output_ptr += width-1;
+ dir = -1;
+ dirnc = -nc;
+ errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */
+ } else {
+ /* work left to right in this row */
+ dir = 1;
+ dirnc = nc;
+ errorptr = cquantize->fserrors[ci]; /* => entry before first column */
+ }
+ colorindex_ci = cquantize->colorindex[ci];
+ colormap_ci = cquantize->sv_colormap[ci];
+ /* Preset error values: no error propagated to first pixel from left */
+ cur = 0;
+ /* and no error propagated to row below yet */
+ belowerr = bpreverr = 0;
+
+ for (col = width; col > 0; col--) {
+ /* cur holds the error propagated from the previous pixel on the
+ * current line. Add the error propagated from the previous line
+ * to form the complete error correction term for this pixel, and
+ * round the error term (which is expressed * 16) to an integer.
+ * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
+ * for either sign of the error value.
+ * Note: errorptr points to *previous* column's array entry.
+ */
+ cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4);
+ /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
+ * The maximum error is +- MAXJSAMPLE; this sets the required size
+ * of the range_limit array.
+ */
+ cur += GETJSAMPLE(*input_ptr);
+ cur = GETJSAMPLE(range_limit[cur]);
+ /* Select output value, accumulate into output code for this pixel */
+ pixcode = GETJSAMPLE(colorindex_ci[cur]);
+ *output_ptr += (JSAMPLE) pixcode;
+ /* Compute actual representation error at this pixel */
+ /* Note: we can do this even though we don't have the final */
+ /* pixel code, because the colormap is orthogonal. */
+ cur -= GETJSAMPLE(colormap_ci[pixcode]);
+ /* Compute error fractions to be propagated to adjacent pixels.
+ * Add these into the running sums, and simultaneously shift the
+ * next-line error sums left by 1 column.
+ */
+ bnexterr = cur;
+ delta = cur * 2;
+ cur += delta; /* form error * 3 */
+ errorptr[0] = (FSERROR) (bpreverr + cur);
+ cur += delta; /* form error * 5 */
+ bpreverr = belowerr + cur;
+ belowerr = bnexterr;
+ cur += delta; /* form error * 7 */
+ /* At this point cur contains the 7/16 error value to be propagated
+ * to the next pixel on the current line, and all the errors for the
+ * next line have been shifted over. We are therefore ready to move on.
+ */
+ input_ptr += dirnc; /* advance input ptr to next column */
+ output_ptr += dir; /* advance output ptr to next column */
+ errorptr += dir; /* advance errorptr to current column */
+ }
+ /* Post-loop cleanup: we must unload the final error value into the
+ * final fserrors[] entry. Note we need not unload belowerr because
+ * it is for the dummy column before or after the actual array.
+ */
+ errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */
+ }
+ cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE);
+ }
+}
+
+
+/*
+ * Allocate workspace for Floyd-Steinberg errors.
+ */
+
+LOCAL(void)
+alloc_fs_workspace (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ size_t arraysize;
+ int i;
+
+ arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
+ for (i = 0; i < cinfo->out_color_components; i++) {
+ cquantize->fserrors[i] = (FSERRPTR)
+ (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
+ }
+}
+
+
+/*
+ * Initialize for one-pass color quantization.
+ */
+
+METHODDEF(void)
+start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ size_t arraysize;
+ int i;
+
+ /* Install my colormap. */
+ cinfo->colormap = cquantize->sv_colormap;
+ cinfo->actual_number_of_colors = cquantize->sv_actual;
+
+ /* Initialize for desired dithering mode. */
+ switch (cinfo->dither_mode) {
+ case JDITHER_NONE:
+ if (cinfo->out_color_components == 3)
+ cquantize->pub.color_quantize = color_quantize3;
+ else
+ cquantize->pub.color_quantize = color_quantize;
+ break;
+ case JDITHER_ORDERED:
+ if (cinfo->out_color_components == 3)
+ cquantize->pub.color_quantize = quantize3_ord_dither;
+ else
+ cquantize->pub.color_quantize = quantize_ord_dither;
+ cquantize->row_index = 0; /* initialize state for ordered dither */
+ /* If user changed to ordered dither from another mode,
+ * we must recreate the color index table with padding.
+ * This will cost extra space, but probably isn't very likely.
+ */
+ if (! cquantize->is_padded)
+ create_colorindex(cinfo);
+ /* Create ordered-dither tables if we didn't already. */
+ if (cquantize->odither[0] == NULL)
+ create_odither_tables(cinfo);
+ break;
+ case JDITHER_FS:
+ cquantize->pub.color_quantize = quantize_fs_dither;
+ cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */
+ /* Allocate Floyd-Steinberg workspace if didn't already. */
+ if (cquantize->fserrors[0] == NULL)
+ alloc_fs_workspace(cinfo);
+ /* Initialize the propagated errors to zero. */
+ arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
+ for (i = 0; i < cinfo->out_color_components; i++)
+ jzero_far((void FAR *) cquantize->fserrors[i], arraysize);
+ break;
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ break;
+ }
+}
+
+
+/*
+ * Finish up at the end of the pass.
+ */
+
+METHODDEF(void)
+finish_pass_1_quant (j_decompress_ptr cinfo)
+{
+ /* no work in 1-pass case */
+}
+
+
+/*
+ * Switch to a new external colormap between output passes.
+ * Shouldn't get to this module!
+ */
+
+METHODDEF(void)
+new_color_map_1_quant (j_decompress_ptr cinfo)
+{
+ ERREXIT(cinfo, JERR_MODE_CHANGE);
+}
+
+
+/*
+ * Module initialization routine for 1-pass color quantization.
+ */
+
+GLOBAL(void)
+jinit_1pass_quantizer (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize;
+
+ cquantize = (my_cquantize_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_cquantizer));
+ cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
+ cquantize->pub.start_pass = start_pass_1_quant;
+ cquantize->pub.finish_pass = finish_pass_1_quant;
+ cquantize->pub.new_color_map = new_color_map_1_quant;
+ cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */
+ cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */
+
+ /* Make sure my internal arrays won't overflow */
+ if (cinfo->out_color_components > MAX_Q_COMPS)
+ ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS);
+ /* Make sure colormap indexes can be represented by JSAMPLEs */
+ if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1))
+ ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1);
+
+ /* Create the colormap and color index table. */
+ create_colormap(cinfo);
+ create_colorindex(cinfo);
+
+ /* Allocate Floyd-Steinberg workspace now if requested.
+ * We do this now since it is FAR storage and may affect the memory
+ * manager's space calculations. If the user changes to FS dither
+ * mode in a later pass, we will allocate the space then, and will
+ * possibly overrun the max_memory_to_use setting.
+ */
+ if (cinfo->dither_mode == JDITHER_FS)
+ alloc_fs_workspace(cinfo);
+}
+
+#endif /* QUANT_1PASS_SUPPORTED */
diff --git a/src/libjpeg-turbo/jquant2.c b/src/libjpeg-turbo/jquant2.c
new file mode 100644
index 0000000..da964f7
--- /dev/null
+++ b/src/libjpeg-turbo/jquant2.c
@@ -0,0 +1,1293 @@
+/*
+ * jquant2.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 2009, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains 2-pass color quantization (color mapping) routines.
+ * These routines provide selection of a custom color map for an image,
+ * followed by mapping of the image to that color map, with optional
+ * Floyd-Steinberg dithering.
+ * It is also possible to use just the second pass to map to an arbitrary
+ * externally-given color map.
+ *
+ * Note: ordered dithering is not supported, since there isn't any fast
+ * way to compute intercolor distances; it's unclear that ordered dither's
+ * fundamental assumptions even hold with an irregularly spaced color map.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+#ifdef QUANT_2PASS_SUPPORTED
+
+
+/*
+ * This module implements the well-known Heckbert paradigm for color
+ * quantization. Most of the ideas used here can be traced back to
+ * Heckbert's seminal paper
+ * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display",
+ * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304.
+ *
+ * In the first pass over the image, we accumulate a histogram showing the
+ * usage count of each possible color. To keep the histogram to a reasonable
+ * size, we reduce the precision of the input; typical practice is to retain
+ * 5 or 6 bits per color, so that 8 or 4 different input values are counted
+ * in the same histogram cell.
+ *
+ * Next, the color-selection step begins with a box representing the whole
+ * color space, and repeatedly splits the "largest" remaining box until we
+ * have as many boxes as desired colors. Then the mean color in each
+ * remaining box becomes one of the possible output colors.
+ *
+ * The second pass over the image maps each input pixel to the closest output
+ * color (optionally after applying a Floyd-Steinberg dithering correction).
+ * This mapping is logically trivial, but making it go fast enough requires
+ * considerable care.
+ *
+ * Heckbert-style quantizers vary a good deal in their policies for choosing
+ * the "largest" box and deciding where to cut it. The particular policies
+ * used here have proved out well in experimental comparisons, but better ones
+ * may yet be found.
+ *
+ * In earlier versions of the IJG code, this module quantized in YCbCr color
+ * space, processing the raw upsampled data without a color conversion step.
+ * This allowed the color conversion math to be done only once per colormap
+ * entry, not once per pixel. However, that optimization precluded other
+ * useful optimizations (such as merging color conversion with upsampling)
+ * and it also interfered with desired capabilities such as quantizing to an
+ * externally-supplied colormap. We have therefore abandoned that approach.
+ * The present code works in the post-conversion color space, typically RGB.
+ *
+ * To improve the visual quality of the results, we actually work in scaled
+ * RGB space, giving G distances more weight than R, and R in turn more than
+ * B. To do everything in integer math, we must use integer scale factors.
+ * The 2/3/1 scale factors used here correspond loosely to the relative
+ * weights of the colors in the NTSC grayscale equation.
+ * If you want to use this code to quantize a non-RGB color space, you'll
+ * probably need to change these scale factors.
+ */
+
+#define R_SCALE 2 /* scale R distances by this much */
+#define G_SCALE 3 /* scale G distances by this much */
+#define B_SCALE 1 /* and B by this much */
+
+static const int c_scales[3]={R_SCALE, G_SCALE, B_SCALE};
+#define C0_SCALE c_scales[rgb_red[cinfo->out_color_space]]
+#define C1_SCALE c_scales[rgb_green[cinfo->out_color_space]]
+#define C2_SCALE c_scales[rgb_blue[cinfo->out_color_space]]
+
+/*
+ * First we have the histogram data structure and routines for creating it.
+ *
+ * The number of bits of precision can be adjusted by changing these symbols.
+ * We recommend keeping 6 bits for G and 5 each for R and B.
+ * If you have plenty of memory and cycles, 6 bits all around gives marginally
+ * better results; if you are short of memory, 5 bits all around will save
+ * some space but degrade the results.
+ * To maintain a fully accurate histogram, we'd need to allocate a "long"
+ * (preferably unsigned long) for each cell. In practice this is overkill;
+ * we can get by with 16 bits per cell. Few of the cell counts will overflow,
+ * and clamping those that do overflow to the maximum value will give close-
+ * enough results. This reduces the recommended histogram size from 256Kb
+ * to 128Kb, which is a useful savings on PC-class machines.
+ * (In the second pass the histogram space is re-used for pixel mapping data;
+ * in that capacity, each cell must be able to store zero to the number of
+ * desired colors. 16 bits/cell is plenty for that too.)
+ * Since the JPEG code is intended to run in small memory model on 80x86
+ * machines, we can't just allocate the histogram in one chunk. Instead
+ * of a true 3-D array, we use a row of pointers to 2-D arrays. Each
+ * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and
+ * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that
+ * on 80x86 machines, the pointer row is in near memory but the actual
+ * arrays are in far memory (same arrangement as we use for image arrays).
+ */
+
+#define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */
+
+/* These will do the right thing for either R,G,B or B,G,R color order,
+ * but you may not like the results for other color orders.
+ */
+#define HIST_C0_BITS 5 /* bits of precision in R/B histogram */
+#define HIST_C1_BITS 6 /* bits of precision in G histogram */
+#define HIST_C2_BITS 5 /* bits of precision in B/R histogram */
+
+/* Number of elements along histogram axes. */
+#define HIST_C0_ELEMS (1<<HIST_C0_BITS)
+#define HIST_C1_ELEMS (1<<HIST_C1_BITS)
+#define HIST_C2_ELEMS (1<<HIST_C2_BITS)
+
+/* These are the amounts to shift an input value to get a histogram index. */
+#define C0_SHIFT (BITS_IN_JSAMPLE-HIST_C0_BITS)
+#define C1_SHIFT (BITS_IN_JSAMPLE-HIST_C1_BITS)
+#define C2_SHIFT (BITS_IN_JSAMPLE-HIST_C2_BITS)
+
+
+typedef UINT16 histcell; /* histogram cell; prefer an unsigned type */
+
+typedef histcell FAR * histptr; /* for pointers to histogram cells */
+
+typedef histcell hist1d[HIST_C2_ELEMS]; /* typedefs for the array */
+typedef hist1d FAR * hist2d; /* type for the 2nd-level pointers */
+typedef hist2d * hist3d; /* type for top-level pointer */
+
+
+/* Declarations for Floyd-Steinberg dithering.
+ *
+ * Errors are accumulated into the array fserrors[], at a resolution of
+ * 1/16th of a pixel count. The error at a given pixel is propagated
+ * to its not-yet-processed neighbors using the standard F-S fractions,
+ * ... (here) 7/16
+ * 3/16 5/16 1/16
+ * We work left-to-right on even rows, right-to-left on odd rows.
+ *
+ * We can get away with a single array (holding one row's worth of errors)
+ * by using it to store the current row's errors at pixel columns not yet
+ * processed, but the next row's errors at columns already processed. We
+ * need only a few extra variables to hold the errors immediately around the
+ * current column. (If we are lucky, those variables are in registers, but
+ * even if not, they're probably cheaper to access than array elements are.)
+ *
+ * The fserrors[] array has (#columns + 2) entries; the extra entry at
+ * each end saves us from special-casing the first and last pixels.
+ * Each entry is three values long, one value for each color component.
+ *
+ * Note: on a wide image, we might not have enough room in a PC's near data
+ * segment to hold the error array; so it is allocated with alloc_large.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+typedef INT16 FSERROR; /* 16 bits should be enough */
+typedef int LOCFSERROR; /* use 'int' for calculation temps */
+#else
+typedef INT32 FSERROR; /* may need more than 16 bits */
+typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */
+#endif
+
+typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
+
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_color_quantizer pub; /* public fields */
+
+ /* Space for the eventually created colormap is stashed here */
+ JSAMPARRAY sv_colormap; /* colormap allocated at init time */
+ int desired; /* desired # of colors = size of colormap */
+
+ /* Variables for accumulating image statistics */
+ hist3d histogram; /* pointer to the histogram */
+
+ boolean needs_zeroed; /* TRUE if next pass must zero histogram */
+
+ /* Variables for Floyd-Steinberg dithering */
+ FSERRPTR fserrors; /* accumulated errors */
+ boolean on_odd_row; /* flag to remember which row we are on */
+ int * error_limiter; /* table for clamping the applied error */
+} my_cquantizer;
+
+typedef my_cquantizer * my_cquantize_ptr;
+
+
+/*
+ * Prescan some rows of pixels.
+ * In this module the prescan simply updates the histogram, which has been
+ * initialized to zeroes by start_pass.
+ * An output_buf parameter is required by the method signature, but no data
+ * is actually output (in fact the buffer controller is probably passing a
+ * NULL pointer).
+ */
+
+METHODDEF(void)
+prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ register JSAMPROW ptr;
+ register histptr histp;
+ register hist3d histogram = cquantize->histogram;
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+
+ for (row = 0; row < num_rows; row++) {
+ ptr = input_buf[row];
+ for (col = width; col > 0; col--) {
+ /* get pixel value and index into the histogram */
+ histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT]
+ [GETJSAMPLE(ptr[1]) >> C1_SHIFT]
+ [GETJSAMPLE(ptr[2]) >> C2_SHIFT];
+ /* increment, check for overflow and undo increment if so. */
+ if (++(*histp) <= 0)
+ (*histp)--;
+ ptr += 3;
+ }
+ }
+}
+
+
+/*
+ * Next we have the really interesting routines: selection of a colormap
+ * given the completed histogram.
+ * These routines work with a list of "boxes", each representing a rectangular
+ * subset of the input color space (to histogram precision).
+ */
+
+typedef struct {
+ /* The bounds of the box (inclusive); expressed as histogram indexes */
+ int c0min, c0max;
+ int c1min, c1max;
+ int c2min, c2max;
+ /* The volume (actually 2-norm) of the box */
+ INT32 volume;
+ /* The number of nonzero histogram cells within this box */
+ long colorcount;
+} box;
+
+typedef box * boxptr;
+
+
+LOCAL(boxptr)
+find_biggest_color_pop (boxptr boxlist, int numboxes)
+/* Find the splittable box with the largest color population */
+/* Returns NULL if no splittable boxes remain */
+{
+ register boxptr boxp;
+ register int i;
+ register long maxc = 0;
+ boxptr which = NULL;
+
+ for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
+ if (boxp->colorcount > maxc && boxp->volume > 0) {
+ which = boxp;
+ maxc = boxp->colorcount;
+ }
+ }
+ return which;
+}
+
+
+LOCAL(boxptr)
+find_biggest_volume (boxptr boxlist, int numboxes)
+/* Find the splittable box with the largest (scaled) volume */
+/* Returns NULL if no splittable boxes remain */
+{
+ register boxptr boxp;
+ register int i;
+ register INT32 maxv = 0;
+ boxptr which = NULL;
+
+ for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
+ if (boxp->volume > maxv) {
+ which = boxp;
+ maxv = boxp->volume;
+ }
+ }
+ return which;
+}
+
+
+LOCAL(void)
+update_box (j_decompress_ptr cinfo, boxptr boxp)
+/* Shrink the min/max bounds of a box to enclose only nonzero elements, */
+/* and recompute its volume and population */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ histptr histp;
+ int c0,c1,c2;
+ int c0min,c0max,c1min,c1max,c2min,c2max;
+ INT32 dist0,dist1,dist2;
+ long ccount;
+
+ c0min = boxp->c0min; c0max = boxp->c0max;
+ c1min = boxp->c1min; c1max = boxp->c1max;
+ c2min = boxp->c2min; c2max = boxp->c2max;
+
+ if (c0max > c0min)
+ for (c0 = c0min; c0 <= c0max; c0++)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c0min = c0min = c0;
+ goto have_c0min;
+ }
+ }
+ have_c0min:
+ if (c0max > c0min)
+ for (c0 = c0max; c0 >= c0min; c0--)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c0max = c0max = c0;
+ goto have_c0max;
+ }
+ }
+ have_c0max:
+ if (c1max > c1min)
+ for (c1 = c1min; c1 <= c1max; c1++)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c1min = c1min = c1;
+ goto have_c1min;
+ }
+ }
+ have_c1min:
+ if (c1max > c1min)
+ for (c1 = c1max; c1 >= c1min; c1--)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c1max = c1max = c1;
+ goto have_c1max;
+ }
+ }
+ have_c1max:
+ if (c2max > c2min)
+ for (c2 = c2min; c2 <= c2max; c2++)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1min][c2];
+ for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
+ if (*histp != 0) {
+ boxp->c2min = c2min = c2;
+ goto have_c2min;
+ }
+ }
+ have_c2min:
+ if (c2max > c2min)
+ for (c2 = c2max; c2 >= c2min; c2--)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1min][c2];
+ for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
+ if (*histp != 0) {
+ boxp->c2max = c2max = c2;
+ goto have_c2max;
+ }
+ }
+ have_c2max:
+
+ /* Update box volume.
+ * We use 2-norm rather than real volume here; this biases the method
+ * against making long narrow boxes, and it has the side benefit that
+ * a box is splittable iff norm > 0.
+ * Since the differences are expressed in histogram-cell units,
+ * we have to shift back to JSAMPLE units to get consistent distances;
+ * after which, we scale according to the selected distance scale factors.
+ */
+ dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
+ dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
+ dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
+ boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
+
+ /* Now scan remaining volume of box and compute population */
+ ccount = 0;
+ for (c0 = c0min; c0 <= c0max; c0++)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++, histp++)
+ if (*histp != 0) {
+ ccount++;
+ }
+ }
+ boxp->colorcount = ccount;
+}
+
+
+LOCAL(int)
+median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
+ int desired_colors)
+/* Repeatedly select and split the largest box until we have enough boxes */
+{
+ int n,lb;
+ int c0,c1,c2,cmax;
+ register boxptr b1,b2;
+
+ while (numboxes < desired_colors) {
+ /* Select box to split.
+ * Current algorithm: by population for first half, then by volume.
+ */
+ if (numboxes*2 <= desired_colors) {
+ b1 = find_biggest_color_pop(boxlist, numboxes);
+ } else {
+ b1 = find_biggest_volume(boxlist, numboxes);
+ }
+ if (b1 == NULL) /* no splittable boxes left! */
+ break;
+ b2 = &boxlist[numboxes]; /* where new box will go */
+ /* Copy the color bounds to the new box. */
+ b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max;
+ b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min;
+ /* Choose which axis to split the box on.
+ * Current algorithm: longest scaled axis.
+ * See notes in update_box about scaling distances.
+ */
+ c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
+ c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
+ c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
+ /* We want to break any ties in favor of green, then red, blue last.
+ * This code does the right thing for R,G,B or B,G,R color orders only.
+ */
+ if (rgb_red[cinfo->out_color_space] == 0) {
+ cmax = c1; n = 1;
+ if (c0 > cmax) { cmax = c0; n = 0; }
+ if (c2 > cmax) { n = 2; }
+ }
+ else {
+ cmax = c1; n = 1;
+ if (c2 > cmax) { cmax = c2; n = 2; }
+ if (c0 > cmax) { n = 0; }
+ }
+ /* Choose split point along selected axis, and update box bounds.
+ * Current algorithm: split at halfway point.
+ * (Since the box has been shrunk to minimum volume,
+ * any split will produce two nonempty subboxes.)
+ * Note that lb value is max for lower box, so must be < old max.
+ */
+ switch (n) {
+ case 0:
+ lb = (b1->c0max + b1->c0min) / 2;
+ b1->c0max = lb;
+ b2->c0min = lb+1;
+ break;
+ case 1:
+ lb = (b1->c1max + b1->c1min) / 2;
+ b1->c1max = lb;
+ b2->c1min = lb+1;
+ break;
+ case 2:
+ lb = (b1->c2max + b1->c2min) / 2;
+ b1->c2max = lb;
+ b2->c2min = lb+1;
+ break;
+ }
+ /* Update stats for boxes */
+ update_box(cinfo, b1);
+ update_box(cinfo, b2);
+ numboxes++;
+ }
+ return numboxes;
+}
+
+
+LOCAL(void)
+compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
+/* Compute representative color for a box, put it in colormap[icolor] */
+{
+ /* Current algorithm: mean weighted by pixels (not colors) */
+ /* Note it is important to get the rounding correct! */
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ histptr histp;
+ int c0,c1,c2;
+ int c0min,c0max,c1min,c1max,c2min,c2max;
+ long count;
+ long total = 0;
+ long c0total = 0;
+ long c1total = 0;
+ long c2total = 0;
+
+ c0min = boxp->c0min; c0max = boxp->c0max;
+ c1min = boxp->c1min; c1max = boxp->c1max;
+ c2min = boxp->c2min; c2max = boxp->c2max;
+
+ for (c0 = c0min; c0 <= c0max; c0++)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++) {
+ if ((count = *histp++) != 0) {
+ total += count;
+ c0total += ((c0 << C0_SHIFT) + ((1<<C0_SHIFT)>>1)) * count;
+ c1total += ((c1 << C1_SHIFT) + ((1<<C1_SHIFT)>>1)) * count;
+ c2total += ((c2 << C2_SHIFT) + ((1<<C2_SHIFT)>>1)) * count;
+ }
+ }
+ }
+
+ cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
+ cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
+ cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
+}
+
+
+LOCAL(void)
+select_colors (j_decompress_ptr cinfo, int desired_colors)
+/* Master routine for color selection */
+{
+ boxptr boxlist;
+ int numboxes;
+ int i;
+
+ /* Allocate workspace for box list */
+ boxlist = (boxptr) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box));
+ /* Initialize one box containing whole space */
+ numboxes = 1;
+ boxlist[0].c0min = 0;
+ boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT;
+ boxlist[0].c1min = 0;
+ boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT;
+ boxlist[0].c2min = 0;
+ boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT;
+ /* Shrink it to actually-used volume and set its statistics */
+ update_box(cinfo, & boxlist[0]);
+ /* Perform median-cut to produce final box list */
+ numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors);
+ /* Compute the representative color for each box, fill colormap */
+ for (i = 0; i < numboxes; i++)
+ compute_color(cinfo, & boxlist[i], i);
+ cinfo->actual_number_of_colors = numboxes;
+ TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes);
+}
+
+
+/*
+ * These routines are concerned with the time-critical task of mapping input
+ * colors to the nearest color in the selected colormap.
+ *
+ * We re-use the histogram space as an "inverse color map", essentially a
+ * cache for the results of nearest-color searches. All colors within a
+ * histogram cell will be mapped to the same colormap entry, namely the one
+ * closest to the cell's center. This may not be quite the closest entry to
+ * the actual input color, but it's almost as good. A zero in the cache
+ * indicates we haven't found the nearest color for that cell yet; the array
+ * is cleared to zeroes before starting the mapping pass. When we find the
+ * nearest color for a cell, its colormap index plus one is recorded in the
+ * cache for future use. The pass2 scanning routines call fill_inverse_cmap
+ * when they need to use an unfilled entry in the cache.
+ *
+ * Our method of efficiently finding nearest colors is based on the "locally
+ * sorted search" idea described by Heckbert and on the incremental distance
+ * calculation described by Spencer W. Thomas in chapter III.1 of Graphics
+ * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that
+ * the distances from a given colormap entry to each cell of the histogram can
+ * be computed quickly using an incremental method: the differences between
+ * distances to adjacent cells themselves differ by a constant. This allows a
+ * fairly fast implementation of the "brute force" approach of computing the
+ * distance from every colormap entry to every histogram cell. Unfortunately,
+ * it needs a work array to hold the best-distance-so-far for each histogram
+ * cell (because the inner loop has to be over cells, not colormap entries).
+ * The work array elements have to be INT32s, so the work array would need
+ * 256Kb at our recommended precision. This is not feasible in DOS machines.
+ *
+ * To get around these problems, we apply Thomas' method to compute the
+ * nearest colors for only the cells within a small subbox of the histogram.
+ * The work array need be only as big as the subbox, so the memory usage
+ * problem is solved. Furthermore, we need not fill subboxes that are never
+ * referenced in pass2; many images use only part of the color gamut, so a
+ * fair amount of work is saved. An additional advantage of this
+ * approach is that we can apply Heckbert's locality criterion to quickly
+ * eliminate colormap entries that are far away from the subbox; typically
+ * three-fourths of the colormap entries are rejected by Heckbert's criterion,
+ * and we need not compute their distances to individual cells in the subbox.
+ * The speed of this approach is heavily influenced by the subbox size: too
+ * small means too much overhead, too big loses because Heckbert's criterion
+ * can't eliminate as many colormap entries. Empirically the best subbox
+ * size seems to be about 1/512th of the histogram (1/8th in each direction).
+ *
+ * Thomas' article also describes a refined method which is asymptotically
+ * faster than the brute-force method, but it is also far more complex and
+ * cannot efficiently be applied to small subboxes. It is therefore not
+ * useful for programs intended to be portable to DOS machines. On machines
+ * with plenty of memory, filling the whole histogram in one shot with Thomas'
+ * refined method might be faster than the present code --- but then again,
+ * it might not be any faster, and it's certainly more complicated.
+ */
+
+
+/* log2(histogram cells in update box) for each axis; this can be adjusted */
+#define BOX_C0_LOG (HIST_C0_BITS-3)
+#define BOX_C1_LOG (HIST_C1_BITS-3)
+#define BOX_C2_LOG (HIST_C2_BITS-3)
+
+#define BOX_C0_ELEMS (1<<BOX_C0_LOG) /* # of hist cells in update box */
+#define BOX_C1_ELEMS (1<<BOX_C1_LOG)
+#define BOX_C2_ELEMS (1<<BOX_C2_LOG)
+
+#define BOX_C0_SHIFT (C0_SHIFT + BOX_C0_LOG)
+#define BOX_C1_SHIFT (C1_SHIFT + BOX_C1_LOG)
+#define BOX_C2_SHIFT (C2_SHIFT + BOX_C2_LOG)
+
+
+/*
+ * The next three routines implement inverse colormap filling. They could
+ * all be folded into one big routine, but splitting them up this way saves
+ * some stack space (the mindist[] and bestdist[] arrays need not coexist)
+ * and may allow some compilers to produce better code by registerizing more
+ * inner-loop variables.
+ */
+
+LOCAL(int)
+find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
+ JSAMPLE colorlist[])
+/* Locate the colormap entries close enough to an update box to be candidates
+ * for the nearest entry to some cell(s) in the update box. The update box
+ * is specified by the center coordinates of its first cell. The number of
+ * candidate colormap entries is returned, and their colormap indexes are
+ * placed in colorlist[].
+ * This routine uses Heckbert's "locally sorted search" criterion to select
+ * the colors that need further consideration.
+ */
+{
+ int numcolors = cinfo->actual_number_of_colors;
+ int maxc0, maxc1, maxc2;
+ int centerc0, centerc1, centerc2;
+ int i, x, ncolors;
+ INT32 minmaxdist, min_dist, max_dist, tdist;
+ INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */
+
+ /* Compute true coordinates of update box's upper corner and center.
+ * Actually we compute the coordinates of the center of the upper-corner
+ * histogram cell, which are the upper bounds of the volume we care about.
+ * Note that since ">>" rounds down, the "center" values may be closer to
+ * min than to max; hence comparisons to them must be "<=", not "<".
+ */
+ maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
+ centerc0 = (minc0 + maxc0) >> 1;
+ maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
+ centerc1 = (minc1 + maxc1) >> 1;
+ maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
+ centerc2 = (minc2 + maxc2) >> 1;
+
+ /* For each color in colormap, find:
+ * 1. its minimum squared-distance to any point in the update box
+ * (zero if color is within update box);
+ * 2. its maximum squared-distance to any point in the update box.
+ * Both of these can be found by considering only the corners of the box.
+ * We save the minimum distance for each color in mindist[];
+ * only the smallest maximum distance is of interest.
+ */
+ minmaxdist = 0x7FFFFFFFL;
+
+ for (i = 0; i < numcolors; i++) {
+ /* We compute the squared-c0-distance term, then add in the other two. */
+ x = GETJSAMPLE(cinfo->colormap[0][i]);
+ if (x < minc0) {
+ tdist = (x - minc0) * C0_SCALE;
+ min_dist = tdist*tdist;
+ tdist = (x - maxc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ } else if (x > maxc0) {
+ tdist = (x - maxc0) * C0_SCALE;
+ min_dist = tdist*tdist;
+ tdist = (x - minc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ } else {
+ /* within cell range so no contribution to min_dist */
+ min_dist = 0;
+ if (x <= centerc0) {
+ tdist = (x - maxc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ } else {
+ tdist = (x - minc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ }
+ }
+
+ x = GETJSAMPLE(cinfo->colormap[1][i]);
+ if (x < minc1) {
+ tdist = (x - minc1) * C1_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - maxc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ } else if (x > maxc1) {
+ tdist = (x - maxc1) * C1_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - minc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ /* within cell range so no contribution to min_dist */
+ if (x <= centerc1) {
+ tdist = (x - maxc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ tdist = (x - minc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ }
+ }
+
+ x = GETJSAMPLE(cinfo->colormap[2][i]);
+ if (x < minc2) {
+ tdist = (x - minc2) * C2_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - maxc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ } else if (x > maxc2) {
+ tdist = (x - maxc2) * C2_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - minc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ /* within cell range so no contribution to min_dist */
+ if (x <= centerc2) {
+ tdist = (x - maxc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ tdist = (x - minc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ }
+ }
+
+ mindist[i] = min_dist; /* save away the results */
+ if (max_dist < minmaxdist)
+ minmaxdist = max_dist;
+ }
+
+ /* Now we know that no cell in the update box is more than minmaxdist
+ * away from some colormap entry. Therefore, only colors that are
+ * within minmaxdist of some part of the box need be considered.
+ */
+ ncolors = 0;
+ for (i = 0; i < numcolors; i++) {
+ if (mindist[i] <= minmaxdist)
+ colorlist[ncolors++] = (JSAMPLE) i;
+ }
+ return ncolors;
+}
+
+
+LOCAL(void)
+find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
+ int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
+/* Find the closest colormap entry for each cell in the update box,
+ * given the list of candidate colors prepared by find_nearby_colors.
+ * Return the indexes of the closest entries in the bestcolor[] array.
+ * This routine uses Thomas' incremental distance calculation method to
+ * find the distance from a colormap entry to successive cells in the box.
+ */
+{
+ int ic0, ic1, ic2;
+ int i, icolor;
+ register INT32 * bptr; /* pointer into bestdist[] array */
+ JSAMPLE * cptr; /* pointer into bestcolor[] array */
+ INT32 dist0, dist1; /* initial distance values */
+ register INT32 dist2; /* current distance in inner loop */
+ INT32 xx0, xx1; /* distance increments */
+ register INT32 xx2;
+ INT32 inc0, inc1, inc2; /* initial values for increments */
+ /* This array holds the distance to the nearest-so-far color for each cell */
+ INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
+
+ /* Initialize best-distance for each cell of the update box */
+ bptr = bestdist;
+ for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--)
+ *bptr++ = 0x7FFFFFFFL;
+
+ /* For each color selected by find_nearby_colors,
+ * compute its distance to the center of each cell in the box.
+ * If that's less than best-so-far, update best distance and color number.
+ */
+
+ /* Nominal steps between cell centers ("x" in Thomas article) */
+#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE)
+#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE)
+#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE)
+
+ for (i = 0; i < numcolors; i++) {
+ icolor = GETJSAMPLE(colorlist[i]);
+ /* Compute (square of) distance from minc0/c1/c2 to this color */
+ inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE;
+ dist0 = inc0*inc0;
+ inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE;
+ dist0 += inc1*inc1;
+ inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE;
+ dist0 += inc2*inc2;
+ /* Form the initial difference increments */
+ inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
+ inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
+ inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
+ /* Now loop over all cells in box, updating distance per Thomas method */
+ bptr = bestdist;
+ cptr = bestcolor;
+ xx0 = inc0;
+ for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) {
+ dist1 = dist0;
+ xx1 = inc1;
+ for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) {
+ dist2 = dist1;
+ xx2 = inc2;
+ for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) {
+ if (dist2 < *bptr) {
+ *bptr = dist2;
+ *cptr = (JSAMPLE) icolor;
+ }
+ dist2 += xx2;
+ xx2 += 2 * STEP_C2 * STEP_C2;
+ bptr++;
+ cptr++;
+ }
+ dist1 += xx1;
+ xx1 += 2 * STEP_C1 * STEP_C1;
+ }
+ dist0 += xx0;
+ xx0 += 2 * STEP_C0 * STEP_C0;
+ }
+ }
+}
+
+
+LOCAL(void)
+fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2)
+/* Fill the inverse-colormap entries in the update box that contains */
+/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */
+/* we can fill as many others as we wish.) */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ int minc0, minc1, minc2; /* lower left corner of update box */
+ int ic0, ic1, ic2;
+ register JSAMPLE * cptr; /* pointer into bestcolor[] array */
+ register histptr cachep; /* pointer into main cache array */
+ /* This array lists the candidate colormap indexes. */
+ JSAMPLE colorlist[MAXNUMCOLORS];
+ int numcolors; /* number of candidate colors */
+ /* This array holds the actually closest colormap index for each cell. */
+ JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
+
+ /* Convert cell coordinates to update box ID */
+ c0 >>= BOX_C0_LOG;
+ c1 >>= BOX_C1_LOG;
+ c2 >>= BOX_C2_LOG;
+
+ /* Compute true coordinates of update box's origin corner.
+ * Actually we compute the coordinates of the center of the corner
+ * histogram cell, which are the lower bounds of the volume we care about.
+ */
+ minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
+ minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
+ minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
+
+ /* Determine which colormap entries are close enough to be candidates
+ * for the nearest entry to some cell in the update box.
+ */
+ numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist);
+
+ /* Determine the actually nearest colors. */
+ find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist,
+ bestcolor);
+
+ /* Save the best color numbers (plus 1) in the main cache array */
+ c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */
+ c1 <<= BOX_C1_LOG;
+ c2 <<= BOX_C2_LOG;
+ cptr = bestcolor;
+ for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) {
+ for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
+ cachep = & histogram[c0+ic0][c1+ic1][c2];
+ for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
+ *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1);
+ }
+ }
+ }
+}
+
+
+/*
+ * Map some rows of pixels to the output colormapped representation.
+ */
+
+METHODDEF(void)
+pass2_no_dither (j_decompress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
+/* This version performs no dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ register JSAMPROW inptr, outptr;
+ register histptr cachep;
+ register int c0, c1, c2;
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+
+ for (row = 0; row < num_rows; row++) {
+ inptr = input_buf[row];
+ outptr = output_buf[row];
+ for (col = width; col > 0; col--) {
+ /* get pixel value and index into the cache */
+ c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT;
+ c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT;
+ c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT;
+ cachep = & histogram[c0][c1][c2];
+ /* If we have not seen this color before, find nearest colormap entry */
+ /* and update the cache */
+ if (*cachep == 0)
+ fill_inverse_cmap(cinfo, c0,c1,c2);
+ /* Now emit the colormap index for this cell */
+ *outptr++ = (JSAMPLE) (*cachep - 1);
+ }
+ }
+}
+
+
+METHODDEF(void)
+pass2_fs_dither (j_decompress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
+/* This version performs Floyd-Steinberg dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */
+ LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */
+ LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */
+ register FSERRPTR errorptr; /* => fserrors[] at column before current */
+ JSAMPROW inptr; /* => current input pixel */
+ JSAMPROW outptr; /* => current output pixel */
+ histptr cachep;
+ int dir; /* +1 or -1 depending on direction */
+ int dir3; /* 3*dir, for advancing inptr & errorptr */
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+ JSAMPLE *range_limit = cinfo->sample_range_limit;
+ int *error_limit = cquantize->error_limiter;
+ JSAMPROW colormap0 = cinfo->colormap[0];
+ JSAMPROW colormap1 = cinfo->colormap[1];
+ JSAMPROW colormap2 = cinfo->colormap[2];
+ SHIFT_TEMPS
+
+ for (row = 0; row < num_rows; row++) {
+ inptr = input_buf[row];
+ outptr = output_buf[row];
+ if (cquantize->on_odd_row) {
+ /* work right to left in this row */
+ inptr += (width-1) * 3; /* so point to rightmost pixel */
+ outptr += width-1;
+ dir = -1;
+ dir3 = -3;
+ errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */
+ cquantize->on_odd_row = FALSE; /* flip for next time */
+ } else {
+ /* work left to right in this row */
+ dir = 1;
+ dir3 = 3;
+ errorptr = cquantize->fserrors; /* => entry before first real column */
+ cquantize->on_odd_row = TRUE; /* flip for next time */
+ }
+ /* Preset error values: no error propagated to first pixel from left */
+ cur0 = cur1 = cur2 = 0;
+ /* and no error propagated to row below yet */
+ belowerr0 = belowerr1 = belowerr2 = 0;
+ bpreverr0 = bpreverr1 = bpreverr2 = 0;
+
+ for (col = width; col > 0; col--) {
+ /* curN holds the error propagated from the previous pixel on the
+ * current line. Add the error propagated from the previous line
+ * to form the complete error correction term for this pixel, and
+ * round the error term (which is expressed * 16) to an integer.
+ * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
+ * for either sign of the error value.
+ * Note: errorptr points to *previous* column's array entry.
+ */
+ cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4);
+ cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4);
+ cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4);
+ /* Limit the error using transfer function set by init_error_limit.
+ * See comments with init_error_limit for rationale.
+ */
+ cur0 = error_limit[cur0];
+ cur1 = error_limit[cur1];
+ cur2 = error_limit[cur2];
+ /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
+ * The maximum error is +- MAXJSAMPLE (or less with error limiting);
+ * this sets the required size of the range_limit array.
+ */
+ cur0 += GETJSAMPLE(inptr[0]);
+ cur1 += GETJSAMPLE(inptr[1]);
+ cur2 += GETJSAMPLE(inptr[2]);
+ cur0 = GETJSAMPLE(range_limit[cur0]);
+ cur1 = GETJSAMPLE(range_limit[cur1]);
+ cur2 = GETJSAMPLE(range_limit[cur2]);
+ /* Index into the cache with adjusted pixel value */
+ cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT];
+ /* If we have not seen this color before, find nearest colormap */
+ /* entry and update the cache */
+ if (*cachep == 0)
+ fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT);
+ /* Now emit the colormap index for this cell */
+ { register int pixcode = *cachep - 1;
+ *outptr = (JSAMPLE) pixcode;
+ /* Compute representation error for this pixel */
+ cur0 -= GETJSAMPLE(colormap0[pixcode]);
+ cur1 -= GETJSAMPLE(colormap1[pixcode]);
+ cur2 -= GETJSAMPLE(colormap2[pixcode]);
+ }
+ /* Compute error fractions to be propagated to adjacent pixels.
+ * Add these into the running sums, and simultaneously shift the
+ * next-line error sums left by 1 column.
+ */
+ { register LOCFSERROR bnexterr, delta;
+
+ bnexterr = cur0; /* Process component 0 */
+ delta = cur0 * 2;
+ cur0 += delta; /* form error * 3 */
+ errorptr[0] = (FSERROR) (bpreverr0 + cur0);
+ cur0 += delta; /* form error * 5 */
+ bpreverr0 = belowerr0 + cur0;
+ belowerr0 = bnexterr;
+ cur0 += delta; /* form error * 7 */
+ bnexterr = cur1; /* Process component 1 */
+ delta = cur1 * 2;
+ cur1 += delta; /* form error * 3 */
+ errorptr[1] = (FSERROR) (bpreverr1 + cur1);
+ cur1 += delta; /* form error * 5 */
+ bpreverr1 = belowerr1 + cur1;
+ belowerr1 = bnexterr;
+ cur1 += delta; /* form error * 7 */
+ bnexterr = cur2; /* Process component 2 */
+ delta = cur2 * 2;
+ cur2 += delta; /* form error * 3 */
+ errorptr[2] = (FSERROR) (bpreverr2 + cur2);
+ cur2 += delta; /* form error * 5 */
+ bpreverr2 = belowerr2 + cur2;
+ belowerr2 = bnexterr;
+ cur2 += delta; /* form error * 7 */
+ }
+ /* At this point curN contains the 7/16 error value to be propagated
+ * to the next pixel on the current line, and all the errors for the
+ * next line have been shifted over. We are therefore ready to move on.
+ */
+ inptr += dir3; /* Advance pixel pointers to next column */
+ outptr += dir;
+ errorptr += dir3; /* advance errorptr to current column */
+ }
+ /* Post-loop cleanup: we must unload the final error values into the
+ * final fserrors[] entry. Note we need not unload belowerrN because
+ * it is for the dummy column before or after the actual array.
+ */
+ errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */
+ errorptr[1] = (FSERROR) bpreverr1;
+ errorptr[2] = (FSERROR) bpreverr2;
+ }
+}
+
+
+/*
+ * Initialize the error-limiting transfer function (lookup table).
+ * The raw F-S error computation can potentially compute error values of up to
+ * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be
+ * much less, otherwise obviously wrong pixels will be created. (Typical
+ * effects include weird fringes at color-area boundaries, isolated bright
+ * pixels in a dark area, etc.) The standard advice for avoiding this problem
+ * is to ensure that the "corners" of the color cube are allocated as output
+ * colors; then repeated errors in the same direction cannot cause cascading
+ * error buildup. However, that only prevents the error from getting
+ * completely out of hand; Aaron Giles reports that error limiting improves
+ * the results even with corner colors allocated.
+ * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty
+ * well, but the smoother transfer function used below is even better. Thanks
+ * to Aaron Giles for this idea.
+ */
+
+LOCAL(void)
+init_error_limit (j_decompress_ptr cinfo)
+/* Allocate and fill in the error_limiter table */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ int * table;
+ int in, out;
+
+ table = (int *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int));
+ table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */
+ cquantize->error_limiter = table;
+
+#define STEPSIZE ((MAXJSAMPLE+1)/16)
+ /* Map errors 1:1 up to +- MAXJSAMPLE/16 */
+ out = 0;
+ for (in = 0; in < STEPSIZE; in++, out++) {
+ table[in] = out; table[-in] = -out;
+ }
+ /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */
+ for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) {
+ table[in] = out; table[-in] = -out;
+ }
+ /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */
+ for (; in <= MAXJSAMPLE; in++) {
+ table[in] = out; table[-in] = -out;
+ }
+#undef STEPSIZE
+}
+
+
+/*
+ * Finish up at the end of each pass.
+ */
+
+METHODDEF(void)
+finish_pass1 (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+
+ /* Select the representative colors and fill in cinfo->colormap */
+ cinfo->colormap = cquantize->sv_colormap;
+ select_colors(cinfo, cquantize->desired);
+ /* Force next pass to zero the color index table */
+ cquantize->needs_zeroed = TRUE;
+}
+
+
+METHODDEF(void)
+finish_pass2 (j_decompress_ptr cinfo)
+{
+ /* no work */
+}
+
+
+/*
+ * Initialize for each processing pass.
+ */
+
+METHODDEF(void)
+start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ int i;
+
+ /* Only F-S dithering or no dithering is supported. */
+ /* If user asks for ordered dither, give him F-S. */
+ if (cinfo->dither_mode != JDITHER_NONE)
+ cinfo->dither_mode = JDITHER_FS;
+
+ if (is_pre_scan) {
+ /* Set up method pointers */
+ cquantize->pub.color_quantize = prescan_quantize;
+ cquantize->pub.finish_pass = finish_pass1;
+ cquantize->needs_zeroed = TRUE; /* Always zero histogram */
+ } else {
+ /* Set up method pointers */
+ if (cinfo->dither_mode == JDITHER_FS)
+ cquantize->pub.color_quantize = pass2_fs_dither;
+ else
+ cquantize->pub.color_quantize = pass2_no_dither;
+ cquantize->pub.finish_pass = finish_pass2;
+
+ /* Make sure color count is acceptable */
+ i = cinfo->actual_number_of_colors;
+ if (i < 1)
+ ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1);
+ if (i > MAXNUMCOLORS)
+ ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
+
+ if (cinfo->dither_mode == JDITHER_FS) {
+ size_t arraysize = (size_t) ((cinfo->output_width + 2) *
+ (3 * SIZEOF(FSERROR)));
+ /* Allocate Floyd-Steinberg workspace if we didn't already. */
+ if (cquantize->fserrors == NULL)
+ cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
+ /* Initialize the propagated errors to zero. */
+ jzero_far((void FAR *) cquantize->fserrors, arraysize);
+ /* Make the error-limit table if we didn't already. */
+ if (cquantize->error_limiter == NULL)
+ init_error_limit(cinfo);
+ cquantize->on_odd_row = FALSE;
+ }
+
+ }
+ /* Zero the histogram or inverse color map, if necessary */
+ if (cquantize->needs_zeroed) {
+ for (i = 0; i < HIST_C0_ELEMS; i++) {
+ jzero_far((void FAR *) histogram[i],
+ HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
+ }
+ cquantize->needs_zeroed = FALSE;
+ }
+}
+
+
+/*
+ * Switch to a new external colormap between output passes.
+ */
+
+METHODDEF(void)
+new_color_map_2_quant (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+
+ /* Reset the inverse color map */
+ cquantize->needs_zeroed = TRUE;
+}
+
+
+/*
+ * Module initialization routine for 2-pass color quantization.
+ */
+
+GLOBAL(void)
+jinit_2pass_quantizer (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize;
+ int i;
+
+ cquantize = (my_cquantize_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_cquantizer));
+ cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
+ cquantize->pub.start_pass = start_pass_2_quant;
+ cquantize->pub.new_color_map = new_color_map_2_quant;
+ cquantize->fserrors = NULL; /* flag optional arrays not allocated */
+ cquantize->error_limiter = NULL;
+
+ /* Make sure jdmaster didn't give me a case I can't handle */
+ if (cinfo->out_color_components != 3)
+ ERREXIT(cinfo, JERR_NOTIMPL);
+
+ /* Allocate the histogram/inverse colormap storage */
+ cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d));
+ for (i = 0; i < HIST_C0_ELEMS; i++) {
+ cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
+ }
+ cquantize->needs_zeroed = TRUE; /* histogram is garbage now */
+
+ /* Allocate storage for the completed colormap, if required.
+ * We do this now since it is FAR storage and may affect
+ * the memory manager's space calculations.
+ */
+ if (cinfo->enable_2pass_quant) {
+ /* Make sure color count is acceptable */
+ int desired = cinfo->desired_number_of_colors;
+ /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
+ if (desired < 8)
+ ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8);
+ /* Make sure colormap indexes can be represented by JSAMPLEs */
+ if (desired > MAXNUMCOLORS)
+ ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
+ cquantize->sv_colormap = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3);
+ cquantize->desired = desired;
+ } else
+ cquantize->sv_colormap = NULL;
+
+ /* Only F-S dithering or no dithering is supported. */
+ /* If user asks for ordered dither, give him F-S. */
+ if (cinfo->dither_mode != JDITHER_NONE)
+ cinfo->dither_mode = JDITHER_FS;
+
+ /* Allocate Floyd-Steinberg workspace if necessary.
+ * This isn't really needed until pass 2, but again it is FAR storage.
+ * Although we will cope with a later change in dither_mode,
+ * we do not promise to honor max_memory_to_use if dither_mode changes.
+ */
+ if (cinfo->dither_mode == JDITHER_FS) {
+ cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR))));
+ /* Might as well create the error-limiting table too. */
+ init_error_limit(cinfo);
+ }
+}
+
+#endif /* QUANT_2PASS_SUPPORTED */
diff --git a/src/libjpeg-turbo/jsimd.h b/src/libjpeg-turbo/jsimd.h
new file mode 100644
index 0000000..3fa2c43
--- /dev/null
+++ b/src/libjpeg-turbo/jsimd.h
@@ -0,0 +1,98 @@
+/*
+ * jsimd.h
+ *
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright 2011 D. R. Commander
+ *
+ * Based on the x86 SIMD extension for IJG JPEG library,
+ * Copyright (C) 1999-2006, MIYASAKA Masaru.
+ * For conditions of distribution and use, see copyright notice in jsimdext.inc
+ *
+ */
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jsimd_can_rgb_ycc jSCanRgbYcc
+#define jsimd_can_rgb_gray jSCanRgbGry
+#define jsimd_can_ycc_rgb jSCanYccRgb
+#define jsimd_rgb_ycc_convert jSRgbYccConv
+#define jsimd_rgb_gray_convert jSRgbGryConv
+#define jsimd_ycc_rgb_convert jSYccRgbConv
+#define jsimd_can_h2v2_downsample jSCanH2V2Down
+#define jsimd_can_h2v1_downsample jSCanH2V1Down
+#define jsimd_h2v2_downsample jSH2V2Down
+#define jsimd_h2v1_downsample jSH2V1Down
+#define jsimd_can_h2v2_upsample jSCanH2V2Up
+#define jsimd_can_h2v1_upsample jSCanH2V1Up
+#define jsimd_h2v2_upsample jSH2V2Up
+#define jsimd_h2v1_upsample jSH2V1Up
+#define jsimd_can_h2v2_fancy_upsample jSCanH2V2FUp
+#define jsimd_can_h2v1_fancy_upsample jSCanH2V1FUp
+#define jsimd_h2v2_fancy_upsample jSH2V2FUp
+#define jsimd_h2v1_fancy_upsample jSH2V1FUp
+#define jsimd_can_h2v2_merged_upsample jSCanH2V2MUp
+#define jsimd_can_h2v1_merged_upsample jSCanH2V1MUp
+#define jsimd_h2v2_merged_upsample jSH2V2MUp
+#define jsimd_h2v1_merged_upsample jSH2V1MUp
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+EXTERN(int) jsimd_can_rgb_ycc JPP((void));
+EXTERN(int) jsimd_can_rgb_gray JPP((void));
+EXTERN(int) jsimd_can_ycc_rgb JPP((void));
+
+EXTERN(void) jsimd_rgb_ycc_convert
+ JPP((j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_rgb_gray_convert
+ JPP((j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_ycc_rgb_convert
+ JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+
+EXTERN(int) jsimd_can_h2v2_downsample JPP((void));
+EXTERN(int) jsimd_can_h2v1_downsample JPP((void));
+
+EXTERN(void) jsimd_h2v2_downsample
+ JPP((j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data));
+EXTERN(void) jsimd_h2v1_downsample
+ JPP((j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data));
+
+EXTERN(int) jsimd_can_h2v2_upsample JPP((void));
+EXTERN(int) jsimd_can_h2v1_upsample JPP((void));
+
+EXTERN(void) jsimd_h2v2_upsample
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+EXTERN(void) jsimd_h2v1_upsample
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+
+EXTERN(int) jsimd_can_h2v2_fancy_upsample JPP((void));
+EXTERN(int) jsimd_can_h2v1_fancy_upsample JPP((void));
+
+EXTERN(void) jsimd_h2v2_fancy_upsample
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+EXTERN(void) jsimd_h2v1_fancy_upsample
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+
+EXTERN(int) jsimd_can_h2v2_merged_upsample JPP((void));
+EXTERN(int) jsimd_can_h2v1_merged_upsample JPP((void));
+
+EXTERN(void) jsimd_h2v2_merged_upsample
+ JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_merged_upsample
+ JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf));
+
diff --git a/src/libjpeg-turbo/jsimddct.h b/src/libjpeg-turbo/jsimddct.h
new file mode 100644
index 0000000..a1c7440
--- /dev/null
+++ b/src/libjpeg-turbo/jsimddct.h
@@ -0,0 +1,102 @@
+/*
+ * jsimddct.h
+ *
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ *
+ * Based on the x86 SIMD extension for IJG JPEG library,
+ * Copyright (C) 1999-2006, MIYASAKA Masaru.
+ * For conditions of distribution and use, see copyright notice in jsimdext.inc
+ *
+ */
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jsimd_can_convsamp jSCanConv
+#define jsimd_can_convsamp_float jSCanConvF
+#define jsimd_convsamp jSConv
+#define jsimd_convsamp_float jSConvF
+#define jsimd_can_fdct_islow jSCanFDCTIS
+#define jsimd_can_fdct_ifast jSCanFDCTIF
+#define jsimd_can_fdct_float jSCanFDCTFl
+#define jsimd_fdct_islow jSFDCTIS
+#define jsimd_fdct_ifast jSFDCTIF
+#define jsimd_fdct_float jSFDCTFl
+#define jsimd_can_quantize jSCanQuant
+#define jsimd_can_quantize_float jSCanQuantF
+#define jsimd_quantize jSQuant
+#define jsimd_quantize_float jSQuantF
+#define jsimd_can_idct_2x2 jSCanIDCT22
+#define jsimd_can_idct_4x4 jSCanIDCT44
+#define jsimd_idct_2x2 jSIDCT22
+#define jsimd_idct_4x4 jSIDCT44
+#define jsimd_can_idct_islow jSCanIDCTIS
+#define jsimd_can_idct_ifast jSCanIDCTIF
+#define jsimd_can_idct_float jSCanIDCTFl
+#define jsimd_idct_islow jSIDCTIS
+#define jsimd_idct_ifast jSIDCTIF
+#define jsimd_idct_float jSIDCTFl
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+EXTERN(int) jsimd_can_convsamp JPP((void));
+EXTERN(int) jsimd_can_convsamp_float JPP((void));
+
+EXTERN(void) jsimd_convsamp JPP((JSAMPARRAY sample_data,
+ JDIMENSION start_col,
+ DCTELEM * workspace));
+EXTERN(void) jsimd_convsamp_float JPP((JSAMPARRAY sample_data,
+ JDIMENSION start_col,
+ FAST_FLOAT * workspace));
+
+EXTERN(int) jsimd_can_fdct_islow JPP((void));
+EXTERN(int) jsimd_can_fdct_ifast JPP((void));
+EXTERN(int) jsimd_can_fdct_float JPP((void));
+
+EXTERN(void) jsimd_fdct_islow JPP((DCTELEM * data));
+EXTERN(void) jsimd_fdct_ifast JPP((DCTELEM * data));
+EXTERN(void) jsimd_fdct_float JPP((FAST_FLOAT * data));
+
+EXTERN(int) jsimd_can_quantize JPP((void));
+EXTERN(int) jsimd_can_quantize_float JPP((void));
+
+EXTERN(void) jsimd_quantize JPP((JCOEFPTR coef_block,
+ DCTELEM * divisors,
+ DCTELEM * workspace));
+EXTERN(void) jsimd_quantize_float JPP((JCOEFPTR coef_block,
+ FAST_FLOAT * divisors,
+ FAST_FLOAT * workspace));
+
+EXTERN(int) jsimd_can_idct_2x2 JPP((void));
+EXTERN(int) jsimd_can_idct_4x4 JPP((void));
+
+EXTERN(void) jsimd_idct_2x2 JPP((j_decompress_ptr cinfo,
+ jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+EXTERN(void) jsimd_idct_4x4 JPP((j_decompress_ptr cinfo,
+ jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+
+EXTERN(int) jsimd_can_idct_islow JPP((void));
+EXTERN(int) jsimd_can_idct_ifast JPP((void));
+EXTERN(int) jsimd_can_idct_float JPP((void));
+
+EXTERN(void) jsimd_idct_islow JPP((j_decompress_ptr cinfo,
+ jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+EXTERN(void) jsimd_idct_ifast JPP((j_decompress_ptr cinfo,
+ jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+EXTERN(void) jsimd_idct_float JPP((j_decompress_ptr cinfo,
+ jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+
diff --git a/src/libjpeg-turbo/jutils.c b/src/libjpeg-turbo/jutils.c
new file mode 100644
index 0000000..d18a955
--- /dev/null
+++ b/src/libjpeg-turbo/jutils.c
@@ -0,0 +1,179 @@
+/*
+ * jutils.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains tables and miscellaneous utility routines needed
+ * for both compression and decompression.
+ * Note we prefix all global names with "j" to minimize conflicts with
+ * a surrounding application.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
+ * of a DCT block read in natural order (left to right, top to bottom).
+ */
+
+#if 0 /* This table is not actually needed in v6a */
+
+const int jpeg_zigzag_order[DCTSIZE2] = {
+ 0, 1, 5, 6, 14, 15, 27, 28,
+ 2, 4, 7, 13, 16, 26, 29, 42,
+ 3, 8, 12, 17, 25, 30, 41, 43,
+ 9, 11, 18, 24, 31, 40, 44, 53,
+ 10, 19, 23, 32, 39, 45, 52, 54,
+ 20, 22, 33, 38, 46, 51, 55, 60,
+ 21, 34, 37, 47, 50, 56, 59, 61,
+ 35, 36, 48, 49, 57, 58, 62, 63
+};
+
+#endif
+
+/*
+ * jpeg_natural_order[i] is the natural-order position of the i'th element
+ * of zigzag order.
+ *
+ * When reading corrupted data, the Huffman decoders could attempt
+ * to reference an entry beyond the end of this array (if the decoded
+ * zero run length reaches past the end of the block). To prevent
+ * wild stores without adding an inner-loop test, we put some extra
+ * "63"s after the real entries. This will cause the extra coefficient
+ * to be stored in location 63 of the block, not somewhere random.
+ * The worst case would be a run-length of 15, which means we need 16
+ * fake entries.
+ */
+
+const int jpeg_natural_order[DCTSIZE2+16] = {
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
+ 63, 63, 63, 63, 63, 63, 63, 63
+};
+
+
+/*
+ * Arithmetic utilities
+ */
+
+GLOBAL(long)
+jdiv_round_up (long a, long b)
+/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
+/* Assumes a >= 0, b > 0 */
+{
+ return (a + b - 1L) / b;
+}
+
+
+GLOBAL(long)
+jround_up (long a, long b)
+/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
+/* Assumes a >= 0, b > 0 */
+{
+ a += b - 1L;
+ return a - (a % b);
+}
+
+
+/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
+ * and coefficient-block arrays. This won't work on 80x86 because the arrays
+ * are FAR and we're assuming a small-pointer memory model. However, some
+ * DOS compilers provide far-pointer versions of memcpy() and memset() even
+ * in the small-model libraries. These will be used if USE_FMEM is defined.
+ * Otherwise, the routines below do it the hard way. (The performance cost
+ * is not all that great, because these routines aren't very heavily used.)
+ */
+
+#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */
+#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size)
+#define FMEMZERO(target,size) MEMZERO(target,size)
+#else /* 80x86 case, define if we can */
+#ifdef USE_FMEM
+#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
+#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size))
+#endif
+#endif
+
+
+GLOBAL(void)
+jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
+ JSAMPARRAY output_array, int dest_row,
+ int num_rows, JDIMENSION num_cols)
+/* Copy some rows of samples from one place to another.
+ * num_rows rows are copied from input_array[source_row++]
+ * to output_array[dest_row++]; these areas may overlap for duplication.
+ * The source and destination arrays must be at least as wide as num_cols.
+ */
+{
+ register JSAMPROW inptr, outptr;
+#ifdef FMEMCOPY
+ register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
+#else
+ register JDIMENSION count;
+#endif
+ register int row;
+
+ input_array += source_row;
+ output_array += dest_row;
+
+ for (row = num_rows; row > 0; row--) {
+ inptr = *input_array++;
+ outptr = *output_array++;
+#ifdef FMEMCOPY
+ FMEMCOPY(outptr, inptr, count);
+#else
+ for (count = num_cols; count > 0; count--)
+ *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */
+#endif
+ }
+}
+
+
+GLOBAL(void)
+jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
+ JDIMENSION num_blocks)
+/* Copy a row of coefficient blocks from one place to another. */
+{
+#ifdef FMEMCOPY
+ FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
+#else
+ register JCOEFPTR inptr, outptr;
+ register long count;
+
+ inptr = (JCOEFPTR) input_row;
+ outptr = (JCOEFPTR) output_row;
+ for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
+ *outptr++ = *inptr++;
+ }
+#endif
+}
+
+
+GLOBAL(void)
+jzero_far (void FAR * target, size_t bytestozero)
+/* Zero out a chunk of FAR memory. */
+/* This might be sample-array data, block-array data, or alloc_large data. */
+{
+#ifdef FMEMZERO
+ FMEMZERO(target, bytestozero);
+#else
+ register char FAR * ptr = (char FAR *) target;
+ register size_t count;
+
+ for (count = bytestozero; count > 0; count--) {
+ *ptr++ = 0;
+ }
+#endif
+}
diff --git a/src/libjpeg-turbo/jversion.h b/src/libjpeg-turbo/jversion.h
new file mode 100644
index 0000000..71d7b91
--- /dev/null
+++ b/src/libjpeg-turbo/jversion.h
@@ -0,0 +1,31 @@
+/*
+ * jversion.h
+ *
+ * Copyright (C) 1991-2010, Thomas G. Lane, Guido Vollbeding.
+ * Copyright (C) 2010, 2012, D. R. Commander.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains software version identification.
+ */
+
+
+#if JPEG_LIB_VERSION >= 80
+
+#define JVERSION "8b 16-May-2010"
+
+#elif JPEG_LIB_VERSION >= 70
+
+#define JVERSION "7 27-Jun-2009"
+
+#else
+
+#define JVERSION "6b 27-Mar-1998"
+
+#endif
+
+#define JCOPYRIGHT "Copyright (C) 1991-2010 Thomas G. Lane, Guido Vollbeding\n" \
+ "Copyright (C) 1999-2006 MIYASAKA Masaru\n" \
+ "Copyright (C) 2009 Pierre Ossman for Cendio AB\n" \
+ "Copyright (C) 2009-2012 D. R. Commander\n" \
+ "Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)"
diff --git a/src/libjpeg-turbo/simd/jsimd.h b/src/libjpeg-turbo/simd/jsimd.h
new file mode 100644
index 0000000..6ee99cc
--- /dev/null
+++ b/src/libjpeg-turbo/simd/jsimd.h
@@ -0,0 +1,666 @@
+/*
+ * simd/jsimd.h
+ *
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright 2011 D. R. Commander
+ *
+ * Based on the x86 SIMD extension for IJG JPEG library,
+ * Copyright (C) 1999-2006, MIYASAKA Masaru.
+ * For conditions of distribution and use, see copyright notice in jsimdext.inc
+ *
+ */
+
+/* Bitmask for supported acceleration methods */
+
+#define JSIMD_NONE 0x00
+#define JSIMD_MMX 0x01
+#define JSIMD_3DNOW 0x02
+#define JSIMD_SSE 0x04
+#define JSIMD_SSE2 0x08
+#define JSIMD_ARM_NEON 0x10
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_simd_cpu_support jSiCpuSupport
+#define jsimd_rgb_ycc_convert_mmx jSRGBYCCM
+#define jsimd_extrgb_ycc_convert_mmx jSEXTRGBYCCM
+#define jsimd_extrgbx_ycc_convert_mmx jSEXTRGBXYCCM
+#define jsimd_extbgr_ycc_convert_mmx jSEXTBGRYCCM
+#define jsimd_extbgrx_ycc_convert_mmx jSEXTBGRXYCCM
+#define jsimd_extxbgr_ycc_convert_mmx jSEXTXBGRYCCM
+#define jsimd_extxrgb_ycc_convert_mmx jSEXTXRGBYCCM
+#define jsimd_rgb_gray_convert_mmx jSRGBGRYM
+#define jsimd_extrgb_gray_convert_mmx jSEXTRGBGRYM
+#define jsimd_extrgbx_gray_convert_mmx jSEXTRGBXGRYM
+#define jsimd_extbgr_gray_convert_mmx jSEXTBGRGRYM
+#define jsimd_extbgrx_gray_convert_mmx jSEXTBGRXGRYM
+#define jsimd_extxbgr_gray_convert_mmx jSEXTXBGRGRYM
+#define jsimd_extxrgb_gray_convert_mmx jSEXTXRGBGRYM
+#define jsimd_ycc_rgb_convert_mmx jSYCCRGBM
+#define jsimd_ycc_extrgb_convert_mmx jSYCCEXTRGBM
+#define jsimd_ycc_extrgbx_convert_mmx jSYCCEXTRGBXM
+#define jsimd_ycc_extbgr_convert_mmx jSYCCEXTBGRM
+#define jsimd_ycc_extbgrx_convert_mmx jSYCCEXTBGRXM
+#define jsimd_ycc_extxbgr_convert_mmx jSYCCEXTXBGRM
+#define jsimd_ycc_extxrgb_convert_mmx jSYCCEXTXRGBM
+#define jconst_rgb_ycc_convert_sse2 jSCRGBYCCS2
+#define jsimd_rgb_ycc_convert_sse2 jSRGBYCCS2
+#define jsimd_extrgb_ycc_convert_sse2 jSEXTRGBYCCS2
+#define jsimd_extrgbx_ycc_convert_sse2 jSEXTRGBXYCCS2
+#define jsimd_extbgr_ycc_convert_sse2 jSEXTBGRYCCS2
+#define jsimd_extbgrx_ycc_convert_sse2 jSEXTBGRXYCCS2
+#define jsimd_extxbgr_ycc_convert_sse2 jSEXTXBGRYCCS2
+#define jsimd_extxrgb_ycc_convert_sse2 jSEXTXRGBYCCS2
+#define jconst_rgb_gray_convert_sse2 jSCRGBGRYS2
+#define jsimd_rgb_gray_convert_sse2 jSRGBGRYS2
+#define jsimd_extrgb_gray_convert_sse2 jSEXTRGBGRYS2
+#define jsimd_extrgbx_gray_convert_sse2 jSEXTRGBXGRYS2
+#define jsimd_extbgr_gray_convert_sse2 jSEXTBGRGRYS2
+#define jsimd_extbgrx_gray_convert_sse2 jSEXTBGRXGRYS2
+#define jsimd_extxbgr_gray_convert_sse2 jSEXTXBGRGRYS2
+#define jsimd_extxrgb_gray_convert_sse2 jSEXTXRGBGRYS2
+#define jconst_ycc_rgb_convert_sse2 jSCYCCRGBS2
+#define jsimd_ycc_rgb_convert_sse2 jSYCCRGBS2
+#define jsimd_ycc_extrgb_convert_sse2 jSYCCEXTRGBS2
+#define jsimd_ycc_extrgbx_convert_sse2 jSYCCEXTRGBXS2
+#define jsimd_ycc_extbgr_convert_sse2 jSYCCEXTBGRS2
+#define jsimd_ycc_extbgrx_convert_sse2 jSYCCEXTBGRXS2
+#define jsimd_ycc_extxbgr_convert_sse2 jSYCCEXTXBGRS2
+#define jsimd_ycc_extxrgb_convert_sse2 jSYCCEXTXRGBS2
+#define jsimd_h2v2_downsample_mmx jSDnH2V2M
+#define jsimd_h2v1_downsample_mmx jSDnH2V1M
+#define jsimd_h2v2_downsample_sse2 jSDnH2V2S2
+#define jsimd_h2v1_downsample_sse2 jSDnH2V1S2
+#define jsimd_h2v2_upsample_mmx jSUpH2V2M
+#define jsimd_h2v1_upsample_mmx jSUpH2V1M
+#define jsimd_h2v2_fancy_upsample_mmx jSFUpH2V2M
+#define jsimd_h2v1_fancy_upsample_mmx jSFUpH2V1M
+#define jsimd_h2v2_merged_upsample_mmx jSMUpH2V2M
+#define jsimd_h2v2_extrgb_merged_upsample_mmx jSMUpH2V2EXTRGBM
+#define jsimd_h2v2_extrgbx_merged_upsample_mmx jSMUpH2V2EXTRGBXM
+#define jsimd_h2v2_extbgr_merged_upsample_mmx jSMUpH2V2EXTBGRM
+#define jsimd_h2v2_extbgrx_merged_upsample_mmx jSMUpH2V2EXTBGRXM
+#define jsimd_h2v2_extxbgr_merged_upsample_mmx jSMUpH2V2EXTXBGRM
+#define jsimd_h2v2_extxrgb_merged_upsample_mmx jSMUpH2V2EXTXRGBM
+#define jsimd_h2v1_merged_upsample_mmx jSMUpH2V1M
+#define jsimd_h2v1_extrgb_merged_upsample_mmx jSMUpH2V1EXTRGBM
+#define jsimd_h2v1_extrgbx_merged_upsample_mmx jSMUpH2V1EXTRGBXM
+#define jsimd_h2v1_extbgr_merged_upsample_mmx jSMUpH2V1EXTBGRM
+#define jsimd_h2v1_extbgrx_merged_upsample_mmx jSMUpH2V1EXTBGRXM
+#define jsimd_h2v1_extxbgr_merged_upsample_mmx jSMUpH2V1EXTXBGRM
+#define jsimd_h2v1_extxrgb_merged_upsample_mmx jSMUpH2V1EXTXRGBM
+#define jsimd_h2v2_upsample_sse2 jSUpH2V2S2
+#define jsimd_h2v1_upsample_sse2 jSUpH2V1S2
+#define jconst_fancy_upsample_sse2 jSCFUpS2
+#define jsimd_h2v2_fancy_upsample_sse2 jSFUpH2V2S2
+#define jsimd_h2v1_fancy_upsample_sse2 jSFUpH2V1S2
+#define jconst_merged_upsample_sse2 jSCMUpS2
+#define jsimd_h2v2_merged_upsample_sse2 jSMUpH2V2S2
+#define jsimd_h2v2_extrgb_merged_upsample_sse2 jSMUpH2V2EXTRGBS2
+#define jsimd_h2v2_extrgbx_merged_upsample_sse2 jSMUpH2V2EXTRGBXS2
+#define jsimd_h2v2_extbgr_merged_upsample_sse2 jSMUpH2V2EXTBGRS2
+#define jsimd_h2v2_extbgrx_merged_upsample_sse2 jSMUpH2V2EXTBGRXS2
+#define jsimd_h2v2_extxbgr_merged_upsample_sse2 jSMUpH2V2EXTXBGRS2
+#define jsimd_h2v2_extxrgb_merged_upsample_sse2 jSMUpH2V2EXTXRGBS2
+#define jsimd_h2v1_merged_upsample_sse2 jSMUpH2V1S2
+#define jsimd_h2v1_extrgb_merged_upsample_sse2 jSMUpH2V1EXTRGBS2
+#define jsimd_h2v1_extrgbx_merged_upsample_sse2 jSMUpH2V1EXTRGBXS2
+#define jsimd_h2v1_extbgr_merged_upsample_sse2 jSMUpH2V1EXTBGRS2
+#define jsimd_h2v1_extbgrx_merged_upsample_sse2 jSMUpH2V1EXTBGRXS2
+#define jsimd_h2v1_extxbgr_merged_upsample_sse2 jSMUpH2V1EXTXBGRS2
+#define jsimd_h2v1_extxrgb_merged_upsample_sse2 jSMUpH2V1EXTXRGBS2
+#define jsimd_convsamp_mmx jSConvM
+#define jsimd_convsamp_sse2 jSConvS2
+#define jsimd_convsamp_float_3dnow jSConvF3D
+#define jsimd_convsamp_float_sse jSConvFS
+#define jsimd_convsamp_float_sse2 jSConvFS2
+#define jsimd_fdct_islow_mmx jSFDMIS
+#define jsimd_fdct_ifast_mmx jSFDMIF
+#define jconst_fdct_islow_sse2 jSCFDS2IS
+#define jsimd_fdct_islow_sse2 jSFDS2IS
+#define jconst_fdct_ifast_sse2 jSCFDS2IF
+#define jsimd_fdct_ifast_sse2 jSFDS2IF
+#define jsimd_fdct_float_3dnow jSFD3DF
+#define jconst_fdct_float_sse jSCFDSF
+#define jsimd_fdct_float_sse jSFDSF
+#define jsimd_quantize_mmx jSQuantM
+#define jsimd_quantize_sse2 jSQuantS2
+#define jsimd_quantize_float_3dnow jSQuantF3D
+#define jsimd_quantize_float_sse jSQuantFS
+#define jsimd_quantize_float_sse2 jSQuantFS2
+#define jsimd_idct_2x2_mmx jSIDM22
+#define jsimd_idct_4x4_mmx jSIDM44
+#define jconst_idct_red_sse2 jSCIDS2R
+#define jsimd_idct_2x2_sse2 jSIDS222
+#define jsimd_idct_4x4_sse2 jSIDS244
+#define jsimd_idct_islow_mmx jSIDMIS
+#define jsimd_idct_ifast_mmx jSIDMIF
+#define jconst_idct_islow_sse2 jSCIDS2IS
+#define jsimd_idct_islow_sse2 jSIDS2IS
+#define jconst_idct_ifast_sse2 jSCIDS2IF
+#define jsimd_idct_ifast_sse2 jSIDS2IF
+#define jsimd_idct_float_3dnow jSID3DF
+#define jconst_fdct_float_sse jSCIDSF
+#define jsimd_idct_float_sse jSIDSF
+#define jconst_fdct_float_sse2 jSCIDS2F
+#define jsimd_idct_float_sse2 jSIDS2F
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+/* SIMD Ext: retrieve SIMD/CPU information */
+EXTERN(unsigned int) jpeg_simd_cpu_support JPP((void));
+
+/* SIMD Color Space Conversion */
+EXTERN(void) jsimd_rgb_ycc_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extrgb_ycc_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extrgbx_ycc_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extbgr_ycc_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extbgrx_ycc_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extxbgr_ycc_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extxrgb_ycc_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+
+EXTERN(void) jsimd_rgb_gray_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extrgb_gray_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extrgbx_gray_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extbgr_gray_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extbgrx_gray_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extxbgr_gray_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extxrgb_gray_convert_mmx
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+
+EXTERN(void) jsimd_ycc_rgb_convert_mmx
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extrgb_convert_mmx
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extrgbx_convert_mmx
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extbgr_convert_mmx
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extbgrx_convert_mmx
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extxbgr_convert_mmx
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extxrgb_convert_mmx
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+
+extern const int jconst_rgb_ycc_convert_sse2[];
+EXTERN(void) jsimd_rgb_ycc_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extrgb_ycc_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extrgbx_ycc_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extbgr_ycc_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extbgrx_ycc_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extxbgr_ycc_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extxrgb_ycc_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+
+extern const int jconst_rgb_gray_convert_sse2[];
+EXTERN(void) jsimd_rgb_gray_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extrgb_gray_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extrgbx_gray_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extbgr_gray_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extbgrx_gray_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extxbgr_gray_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extxrgb_gray_convert_sse2
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+
+extern const int jconst_ycc_rgb_convert_sse2[];
+EXTERN(void) jsimd_ycc_rgb_convert_sse2
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extrgb_convert_sse2
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extrgbx_convert_sse2
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extbgr_convert_sse2
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extbgrx_convert_sse2
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extxbgr_convert_sse2
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extxrgb_convert_sse2
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+
+EXTERN(void) jsimd_rgb_ycc_convert_neon
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extrgb_ycc_convert_neon
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extrgbx_ycc_convert_neon
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extbgr_ycc_convert_neon
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extbgrx_ycc_convert_neon
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extxbgr_ycc_convert_neon
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+EXTERN(void) jsimd_extxrgb_ycc_convert_neon
+ JPP((JDIMENSION img_width,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+
+EXTERN(void) jsimd_ycc_rgb_convert_neon
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extrgb_convert_neon
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extrgbx_convert_neon
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extbgr_convert_neon
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extbgrx_convert_neon
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extxbgr_convert_neon
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+EXTERN(void) jsimd_ycc_extxrgb_convert_neon
+ JPP((JDIMENSION out_width,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+
+/* SIMD Downsample */
+EXTERN(void) jsimd_h2v2_downsample_mmx
+ JPP((JDIMENSION image_width, int max_v_samp_factor,
+ JDIMENSION v_samp_factor, JDIMENSION width_blocks,
+ JSAMPARRAY input_data, JSAMPARRAY output_data));
+EXTERN(void) jsimd_h2v1_downsample_mmx
+ JPP((JDIMENSION image_width, int max_v_samp_factor,
+ JDIMENSION v_samp_factor, JDIMENSION width_blocks,
+ JSAMPARRAY input_data, JSAMPARRAY output_data));
+
+EXTERN(void) jsimd_h2v2_downsample_sse2
+ JPP((JDIMENSION image_width, int max_v_samp_factor,
+ JDIMENSION v_samp_factor, JDIMENSION width_blocks,
+ JSAMPARRAY input_data, JSAMPARRAY output_data));
+EXTERN(void) jsimd_h2v1_downsample_sse2
+ JPP((JDIMENSION image_width, int max_v_samp_factor,
+ JDIMENSION v_samp_factor, JDIMENSION width_blocks,
+ JSAMPARRAY input_data, JSAMPARRAY output_data));
+
+/* SIMD Upsample */
+EXTERN(void) jsimd_h2v2_upsample_mmx
+ JPP((int max_v_samp_factor, JDIMENSION output_width,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+EXTERN(void) jsimd_h2v1_upsample_mmx
+ JPP((int max_v_samp_factor, JDIMENSION output_width,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+
+EXTERN(void) jsimd_h2v2_fancy_upsample_mmx
+ JPP((int max_v_samp_factor, JDIMENSION downsampled_width,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+EXTERN(void) jsimd_h2v1_fancy_upsample_mmx
+ JPP((int max_v_samp_factor, JDIMENSION downsampled_width,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+
+EXTERN(void) jsimd_h2v2_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extrgb_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extrgbx_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extbgr_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extbgrx_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extxbgr_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extxrgb_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extrgb_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extrgbx_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extbgr_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extbgrx_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extxbgr_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extxrgb_merged_upsample_mmx
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+
+EXTERN(void) jsimd_h2v2_upsample_sse2
+ JPP((int max_v_samp_factor, JDIMENSION output_width,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+EXTERN(void) jsimd_h2v1_upsample_sse2
+ JPP((int max_v_samp_factor, JDIMENSION output_width,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+
+extern const int jconst_fancy_upsample_sse2[];
+EXTERN(void) jsimd_h2v2_fancy_upsample_sse2
+ JPP((int max_v_samp_factor, JDIMENSION downsampled_width,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+EXTERN(void) jsimd_h2v1_fancy_upsample_sse2
+ JPP((int max_v_samp_factor, JDIMENSION downsampled_width,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+
+extern const int jconst_merged_upsample_sse2[];
+EXTERN(void) jsimd_h2v2_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extrgb_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extrgbx_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extbgr_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extbgrx_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extxbgr_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v2_extxrgb_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extrgb_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extrgbx_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extbgr_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extbgrx_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extxbgr_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+EXTERN(void) jsimd_h2v1_extxrgb_merged_upsample_sse2
+ JPP((JDIMENSION output_width, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf));
+
+/* SIMD Sample Conversion */
+EXTERN(void) jsimd_convsamp_mmx JPP((JSAMPARRAY sample_data,
+ JDIMENSION start_col,
+ DCTELEM * workspace));
+
+EXTERN(void) jsimd_convsamp_sse2 JPP((JSAMPARRAY sample_data,
+ JDIMENSION start_col,
+ DCTELEM * workspace));
+
+EXTERN(void) jsimd_convsamp_neon JPP((JSAMPARRAY sample_data,
+ JDIMENSION start_col,
+ DCTELEM * workspace));
+
+EXTERN(void) jsimd_convsamp_float_3dnow JPP((JSAMPARRAY sample_data,
+ JDIMENSION start_col,
+ FAST_FLOAT * workspace));
+
+EXTERN(void) jsimd_convsamp_float_sse JPP((JSAMPARRAY sample_data,
+ JDIMENSION start_col,
+ FAST_FLOAT * workspace));
+
+EXTERN(void) jsimd_convsamp_float_sse2 JPP((JSAMPARRAY sample_data,
+ JDIMENSION start_col,
+ FAST_FLOAT * workspace));
+
+/* SIMD Forward DCT */
+EXTERN(void) jsimd_fdct_islow_mmx JPP((DCTELEM * data));
+EXTERN(void) jsimd_fdct_ifast_mmx JPP((DCTELEM * data));
+
+extern const int jconst_fdct_ifast_sse2[];
+EXTERN(void) jsimd_fdct_islow_sse2 JPP((DCTELEM * data));
+extern const int jconst_fdct_islow_sse2[];
+EXTERN(void) jsimd_fdct_ifast_sse2 JPP((DCTELEM * data));
+
+EXTERN(void) jsimd_fdct_ifast_neon JPP((DCTELEM * data));
+
+EXTERN(void) jsimd_fdct_float_3dnow JPP((FAST_FLOAT * data));
+
+extern const int jconst_fdct_float_sse[];
+EXTERN(void) jsimd_fdct_float_sse JPP((FAST_FLOAT * data));
+
+/* SIMD Quantization */
+EXTERN(void) jsimd_quantize_mmx JPP((JCOEFPTR coef_block,
+ DCTELEM * divisors,
+ DCTELEM * workspace));
+
+EXTERN(void) jsimd_quantize_sse2 JPP((JCOEFPTR coef_block,
+ DCTELEM * divisors,
+ DCTELEM * workspace));
+
+EXTERN(void) jsimd_quantize_neon JPP((JCOEFPTR coef_block,
+ DCTELEM * divisors,
+ DCTELEM * workspace));
+
+EXTERN(void) jsimd_quantize_float_3dnow JPP((JCOEFPTR coef_block,
+ FAST_FLOAT * divisors,
+ FAST_FLOAT * workspace));
+
+EXTERN(void) jsimd_quantize_float_sse JPP((JCOEFPTR coef_block,
+ FAST_FLOAT * divisors,
+ FAST_FLOAT * workspace));
+
+EXTERN(void) jsimd_quantize_float_sse2 JPP((JCOEFPTR coef_block,
+ FAST_FLOAT * divisors,
+ FAST_FLOAT * workspace));
+
+/* SIMD Reduced Inverse DCT */
+EXTERN(void) jsimd_idct_2x2_mmx JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+EXTERN(void) jsimd_idct_4x4_mmx JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+
+extern const int jconst_idct_red_sse2[];
+EXTERN(void) jsimd_idct_2x2_sse2 JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+EXTERN(void) jsimd_idct_4x4_sse2 JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+
+EXTERN(void) jsimd_idct_2x2_neon JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+EXTERN(void) jsimd_idct_4x4_neon JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+
+/* SIMD Inverse DCT */
+EXTERN(void) jsimd_idct_islow_mmx JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+EXTERN(void) jsimd_idct_ifast_mmx JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+
+extern const int jconst_idct_islow_sse2[];
+EXTERN(void) jsimd_idct_islow_sse2 JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+extern const int jconst_idct_ifast_sse2[];
+EXTERN(void) jsimd_idct_ifast_sse2 JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+
+EXTERN(void) jsimd_idct_islow_neon JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+EXTERN(void) jsimd_idct_ifast_neon JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+
+EXTERN(void) jsimd_idct_float_3dnow JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+
+extern const int jconst_idct_float_sse[];
+EXTERN(void) jsimd_idct_float_sse JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+
+extern const int jconst_idct_float_sse2[];
+EXTERN(void) jsimd_idct_float_sse2 JPP((void * dct_table,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf,
+ JDIMENSION output_col));
+
diff --git a/src/libjpeg-turbo/simd/jsimd_arm.c b/src/libjpeg-turbo/simd/jsimd_arm.c
new file mode 100644
index 0000000..af0c2c8
--- /dev/null
+++ b/src/libjpeg-turbo/simd/jsimd_arm.c
@@ -0,0 +1,670 @@
+/*
+ * jsimd_arm.c
+ *
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright 2009-2011 D. R. Commander
+ *
+ * Based on the x86 SIMD extension for IJG JPEG library,
+ * Copyright (C) 1999-2006, MIYASAKA Masaru.
+ * For conditions of distribution and use, see copyright notice in jsimdext.inc
+ *
+ * This file contains the interface between the "normal" portions
+ * of the library and the SIMD implementations when running on
+ * ARM architecture.
+ *
+ * Based on the stubs from 'jsimd_none.c'
+ */
+
+#define JPEG_INTERNALS
+#include "../jinclude.h"
+#include "../jpeglib.h"
+#include "../jsimd.h"
+#include "../jdct.h"
+#include "../jsimddct.h"
+#include "jsimd.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+static unsigned int simd_support = ~0;
+
+#if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
+
+#define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024)
+
+LOCAL(int)
+check_feature (char *buffer, char *feature)
+{
+ char *p;
+ if (*feature == 0)
+ return 0;
+ if (strncmp(buffer, "Features", 8) != 0)
+ return 0;
+ buffer += 8;
+ while (isspace(*buffer))
+ buffer++;
+
+ /* Check if 'feature' is present in the buffer as a separate word */
+ while ((p = strstr(buffer, feature))) {
+ if (p > buffer && !isspace(*(p - 1))) {
+ buffer++;
+ continue;
+ }
+ p += strlen(feature);
+ if (*p != 0 && !isspace(*p)) {
+ buffer++;
+ continue;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+LOCAL(int)
+parse_proc_cpuinfo (int bufsize)
+{
+ char *buffer = (char *)malloc(bufsize);
+ FILE *fd;
+ simd_support = 0;
+
+ if (!buffer)
+ return 0;
+
+ fd = fopen("/proc/cpuinfo", "r");
+ if (fd) {
+ while (fgets(buffer, bufsize, fd)) {
+ if (!strchr(buffer, '\n') && !feof(fd)) {
+ /* "impossible" happened - insufficient size of the buffer! */
+ fclose(fd);
+ free(buffer);
+ return 0;
+ }
+ if (check_feature(buffer, "neon"))
+ simd_support |= JSIMD_ARM_NEON;
+ }
+ fclose(fd);
+ }
+ free(buffer);
+ return 1;
+}
+
+#endif
+
+/*
+ * Check what SIMD accelerations are supported.
+ *
+ * FIXME: This code is racy under a multi-threaded environment.
+ */
+LOCAL(void)
+init_simd (void)
+{
+ char *env = NULL;
+#if !defined(__ARM_NEON__) && defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
+ int bufsize = 1024; /* an initial guess for the line buffer size limit */
+#endif
+
+ if (simd_support != ~0U)
+ return;
+
+ simd_support = 0;
+
+#if defined(__ARM_NEON__)
+ simd_support |= JSIMD_ARM_NEON;
+#elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
+ /* We still have a chance to use NEON regardless of globally used
+ * -mcpu/-mfpu options passed to gcc by performing runtime detection via
+ * /proc/cpuinfo parsing on linux/android */
+ while (!parse_proc_cpuinfo(bufsize)) {
+ bufsize *= 2;
+ if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
+ break;
+ }
+#endif
+
+ /* Force different settings through environment variables */
+ env = getenv("JSIMD_FORCE_ARM_NEON");
+ if ((env != NULL) && (strcmp(env, "1") == 0))
+ simd_support &= JSIMD_ARM_NEON;
+ env = getenv("JSIMD_FORCE_NO_SIMD");
+ if ((env != NULL) && (strcmp(env, "1") == 0))
+ simd_support = 0;
+}
+
+GLOBAL(int)
+jsimd_can_rgb_ycc (void)
+{
+ init_simd();
+
+ /* The code is optimised for these values only */
+ if (BITS_IN_JSAMPLE != 8)
+ return 0;
+ if (sizeof(JDIMENSION) != 4)
+ return 0;
+ if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
+ return 0;
+
+ if (simd_support & JSIMD_ARM_NEON)
+ return 1;
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_rgb_gray (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_ycc_rgb (void)
+{
+ init_simd();
+
+ /* The code is optimised for these values only */
+ if (BITS_IN_JSAMPLE != 8)
+ return 0;
+ if (sizeof(JDIMENSION) != 4)
+ return 0;
+ if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
+ return 0;
+ if (simd_support & JSIMD_ARM_NEON)
+ return 1;
+
+ return 0;
+}
+
+GLOBAL(void)
+jsimd_rgb_ycc_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ void (*neonfct)(JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
+
+ switch(cinfo->in_color_space)
+ {
+ case JCS_EXT_RGB:
+ neonfct=jsimd_extrgb_ycc_convert_neon;
+ break;
+ case JCS_EXT_RGBX:
+ case JCS_EXT_RGBA:
+ neonfct=jsimd_extrgbx_ycc_convert_neon;
+ break;
+ case JCS_EXT_BGR:
+ neonfct=jsimd_extbgr_ycc_convert_neon;
+ break;
+ case JCS_EXT_BGRX:
+ case JCS_EXT_BGRA:
+ neonfct=jsimd_extbgrx_ycc_convert_neon;
+ break;
+ case JCS_EXT_XBGR:
+ case JCS_EXT_ABGR:
+ neonfct=jsimd_extxbgr_ycc_convert_neon;
+ break;
+ case JCS_EXT_XRGB:
+ case JCS_EXT_ARGB:
+ neonfct=jsimd_extxrgb_ycc_convert_neon;
+ break;
+ default:
+ neonfct=jsimd_extrgb_ycc_convert_neon;
+ break;
+ }
+
+ if (simd_support & JSIMD_ARM_NEON)
+ neonfct(cinfo->image_width, input_buf,
+ output_buf, output_row, num_rows);
+}
+
+GLOBAL(void)
+jsimd_rgb_gray_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+}
+
+GLOBAL(void)
+jsimd_ycc_rgb_convert (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ void (*neonfct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
+
+ switch(cinfo->out_color_space)
+ {
+ case JCS_EXT_RGB:
+ neonfct=jsimd_ycc_extrgb_convert_neon;
+ break;
+ case JCS_EXT_RGBX:
+ case JCS_EXT_RGBA:
+ neonfct=jsimd_ycc_extrgbx_convert_neon;
+ break;
+ case JCS_EXT_BGR:
+ neonfct=jsimd_ycc_extbgr_convert_neon;
+ break;
+ case JCS_EXT_BGRX:
+ case JCS_EXT_BGRA:
+ neonfct=jsimd_ycc_extbgrx_convert_neon;
+ break;
+ case JCS_EXT_XBGR:
+ case JCS_EXT_ABGR:
+ neonfct=jsimd_ycc_extxbgr_convert_neon;
+ break;
+ case JCS_EXT_XRGB:
+ case JCS_EXT_ARGB:
+ neonfct=jsimd_ycc_extxrgb_convert_neon;
+ break;
+ default:
+ neonfct=jsimd_ycc_extrgb_convert_neon;
+ break;
+ }
+
+ if (simd_support & JSIMD_ARM_NEON)
+ neonfct(cinfo->output_width, input_buf,
+ input_row, output_buf, num_rows);
+}
+
+GLOBAL(int)
+jsimd_can_h2v2_downsample (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_h2v1_downsample (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(void)
+jsimd_h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+}
+
+GLOBAL(void)
+jsimd_h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+}
+
+GLOBAL(int)
+jsimd_can_h2v2_upsample (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_h2v1_upsample (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(void)
+jsimd_h2v2_upsample (j_decompress_ptr cinfo,
+ jpeg_component_info * compptr,
+ JSAMPARRAY input_data,
+ JSAMPARRAY * output_data_ptr)
+{
+}
+
+GLOBAL(void)
+jsimd_h2v1_upsample (j_decompress_ptr cinfo,
+ jpeg_component_info * compptr,
+ JSAMPARRAY input_data,
+ JSAMPARRAY * output_data_ptr)
+{
+}
+
+GLOBAL(int)
+jsimd_can_h2v2_fancy_upsample (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_h2v1_fancy_upsample (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(void)
+jsimd_h2v2_fancy_upsample (j_decompress_ptr cinfo,
+ jpeg_component_info * compptr,
+ JSAMPARRAY input_data,
+ JSAMPARRAY * output_data_ptr)
+{
+}
+
+GLOBAL(void)
+jsimd_h2v1_fancy_upsample (j_decompress_ptr cinfo,
+ jpeg_component_info * compptr,
+ JSAMPARRAY input_data,
+ JSAMPARRAY * output_data_ptr)
+{
+}
+
+GLOBAL(int)
+jsimd_can_h2v2_merged_upsample (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_h2v1_merged_upsample (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(void)
+jsimd_h2v2_merged_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+{
+}
+
+GLOBAL(void)
+jsimd_h2v1_merged_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+{
+}
+
+GLOBAL(int)
+jsimd_can_convsamp (void)
+{
+ init_simd();
+
+ /* The code is optimised for these values only */
+ if (DCTSIZE != 8)
+ return 0;
+ if (BITS_IN_JSAMPLE != 8)
+ return 0;
+ if (sizeof(JDIMENSION) != 4)
+ return 0;
+ if (sizeof(DCTELEM) != 2)
+ return 0;
+
+ if (simd_support & JSIMD_ARM_NEON)
+ return 1;
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_convsamp_float (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(void)
+jsimd_convsamp (JSAMPARRAY sample_data, JDIMENSION start_col,
+ DCTELEM * workspace)
+{
+ if (simd_support & JSIMD_ARM_NEON)
+ jsimd_convsamp_neon(sample_data, start_col, workspace);
+}
+
+GLOBAL(void)
+jsimd_convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col,
+ FAST_FLOAT * workspace)
+{
+}
+
+GLOBAL(int)
+jsimd_can_fdct_islow (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_fdct_ifast (void)
+{
+ init_simd();
+
+ /* The code is optimised for these values only */
+ if (DCTSIZE != 8)
+ return 0;
+ if (sizeof(DCTELEM) != 2)
+ return 0;
+
+ if (simd_support & JSIMD_ARM_NEON)
+ return 1;
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_fdct_float (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(void)
+jsimd_fdct_islow (DCTELEM * data)
+{
+}
+
+GLOBAL(void)
+jsimd_fdct_ifast (DCTELEM * data)
+{
+ if (simd_support & JSIMD_ARM_NEON)
+ jsimd_fdct_ifast_neon(data);
+}
+
+GLOBAL(void)
+jsimd_fdct_float (FAST_FLOAT * data)
+{
+}
+
+GLOBAL(int)
+jsimd_can_quantize (void)
+{
+ init_simd();
+
+ /* The code is optimised for these values only */
+ if (DCTSIZE != 8)
+ return 0;
+ if (sizeof(JCOEF) != 2)
+ return 0;
+ if (sizeof(DCTELEM) != 2)
+ return 0;
+
+ if (simd_support & JSIMD_ARM_NEON)
+ return 1;
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_quantize_float (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(void)
+jsimd_quantize (JCOEFPTR coef_block, DCTELEM * divisors,
+ DCTELEM * workspace)
+{
+ if (simd_support & JSIMD_ARM_NEON)
+ jsimd_quantize_neon(coef_block, divisors, workspace);
+}
+
+GLOBAL(void)
+jsimd_quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors,
+ FAST_FLOAT * workspace)
+{
+}
+
+GLOBAL(int)
+jsimd_can_idct_2x2 (void)
+{
+ init_simd();
+
+ /* The code is optimised for these values only */
+ if (DCTSIZE != 8)
+ return 0;
+ if (sizeof(JCOEF) != 2)
+ return 0;
+ if (BITS_IN_JSAMPLE != 8)
+ return 0;
+ if (sizeof(JDIMENSION) != 4)
+ return 0;
+ if (sizeof(ISLOW_MULT_TYPE) != 2)
+ return 0;
+
+ if ((simd_support & JSIMD_ARM_NEON))
+ return 1;
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_idct_4x4 (void)
+{
+ init_simd();
+
+ /* The code is optimised for these values only */
+ if (DCTSIZE != 8)
+ return 0;
+ if (sizeof(JCOEF) != 2)
+ return 0;
+ if (BITS_IN_JSAMPLE != 8)
+ return 0;
+ if (sizeof(JDIMENSION) != 4)
+ return 0;
+ if (sizeof(ISLOW_MULT_TYPE) != 2)
+ return 0;
+
+ if ((simd_support & JSIMD_ARM_NEON))
+ return 1;
+
+ return 0;
+}
+
+GLOBAL(void)
+jsimd_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf,
+ JDIMENSION output_col)
+{
+ if ((simd_support & JSIMD_ARM_NEON))
+ jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf, output_col);
+}
+
+GLOBAL(void)
+jsimd_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf,
+ JDIMENSION output_col)
+{
+ if ((simd_support & JSIMD_ARM_NEON))
+ jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf, output_col);
+}
+
+GLOBAL(int)
+jsimd_can_idct_islow (void)
+{
+ init_simd();
+
+ /* The code is optimised for these values only */
+ if (DCTSIZE != 8)
+ return 0;
+ if (sizeof(JCOEF) != 2)
+ return 0;
+ if (BITS_IN_JSAMPLE != 8)
+ return 0;
+ if (sizeof(JDIMENSION) != 4)
+ return 0;
+ if (sizeof(ISLOW_MULT_TYPE) != 2)
+ return 0;
+
+ if (simd_support & JSIMD_ARM_NEON)
+ return 1;
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_idct_ifast (void)
+{
+ init_simd();
+
+ /* The code is optimised for these values only */
+ if (DCTSIZE != 8)
+ return 0;
+ if (sizeof(JCOEF) != 2)
+ return 0;
+ if (BITS_IN_JSAMPLE != 8)
+ return 0;
+ if (sizeof(JDIMENSION) != 4)
+ return 0;
+ if (sizeof(IFAST_MULT_TYPE) != 2)
+ return 0;
+ if (IFAST_SCALE_BITS != 2)
+ return 0;
+
+ if ((simd_support & JSIMD_ARM_NEON))
+ return 1;
+
+ return 0;
+}
+
+GLOBAL(int)
+jsimd_can_idct_float (void)
+{
+ init_simd();
+
+ return 0;
+}
+
+GLOBAL(void)
+jsimd_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf,
+ JDIMENSION output_col)
+{
+ if ((simd_support & JSIMD_ARM_NEON))
+ jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf, output_col);
+}
+
+GLOBAL(void)
+jsimd_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf,
+ JDIMENSION output_col)
+{
+ if ((simd_support & JSIMD_ARM_NEON))
+ jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf, output_col);
+}
+
+GLOBAL(void)
+jsimd_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf,
+ JDIMENSION output_col)
+{
+}
+
diff --git a/src/libjpeg-turbo/simd/jsimd_arm_neon.S b/src/libjpeg-turbo/simd/jsimd_arm_neon.S
new file mode 100644
index 0000000..b2f9c2a
--- /dev/null
+++ b/src/libjpeg-turbo/simd/jsimd_arm_neon.S
@@ -0,0 +1,2159 @@
+/*
+ * ARM NEON optimizations for libjpeg-turbo
+ *
+ * Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * Author: Siarhei Siamashka <siarhei.siamashka@nokia.com>
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
+#endif
+
+.text
+.fpu neon
+.arch armv7a
+.object_arch armv4
+.arm
+
+
+#define RESPECT_STRICT_ALIGNMENT 1
+
+/*****************************************************************************/
+
+/* Supplementary macro for setting function attributes */
+.macro asm_function fname
+#ifdef __APPLE__
+ .func _\fname
+ .globl _\fname
+_\fname:
+#else
+ .func \fname
+ .global \fname
+#ifdef __ELF__
+ .hidden \fname
+ .type \fname, %function
+#endif
+\fname:
+#endif
+.endm
+
+/* Transpose a block of 4x4 coefficients in four 64-bit registers */
+.macro transpose_4x4 x0, x1, x2, x3
+ vtrn.16 \x0, \x1
+ vtrn.16 \x2, \x3
+ vtrn.32 \x0, \x2
+ vtrn.32 \x1, \x3
+.endm
+
+#define CENTERJSAMPLE 128
+
+/*****************************************************************************/
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients.
+ *
+ * GLOBAL(void)
+ * jsimd_idct_islow_neon (void * dct_table, JCOEFPTR coef_block,
+ * JSAMPARRAY output_buf, JDIMENSION output_col)
+ */
+
+#define FIX_0_298631336 (2446)
+#define FIX_0_390180644 (3196)
+#define FIX_0_541196100 (4433)
+#define FIX_0_765366865 (6270)
+#define FIX_0_899976223 (7373)
+#define FIX_1_175875602 (9633)
+#define FIX_1_501321110 (12299)
+#define FIX_1_847759065 (15137)
+#define FIX_1_961570560 (16069)
+#define FIX_2_053119869 (16819)
+#define FIX_2_562915447 (20995)
+#define FIX_3_072711026 (25172)
+
+#define FIX_1_175875602_MINUS_1_961570560 (FIX_1_175875602 - FIX_1_961570560)
+#define FIX_1_175875602_MINUS_0_390180644 (FIX_1_175875602 - FIX_0_390180644)
+#define FIX_0_541196100_MINUS_1_847759065 (FIX_0_541196100 - FIX_1_847759065)
+#define FIX_3_072711026_MINUS_2_562915447 (FIX_3_072711026 - FIX_2_562915447)
+#define FIX_0_298631336_MINUS_0_899976223 (FIX_0_298631336 - FIX_0_899976223)
+#define FIX_1_501321110_MINUS_0_899976223 (FIX_1_501321110 - FIX_0_899976223)
+#define FIX_2_053119869_MINUS_2_562915447 (FIX_2_053119869 - FIX_2_562915447)
+#define FIX_0_541196100_PLUS_0_765366865 (FIX_0_541196100 + FIX_0_765366865)
+
+/*
+ * Reference SIMD-friendly 1-D ISLOW iDCT C implementation.
+ * Uses some ideas from the comments in 'simd/jiss2int-64.asm'
+ */
+#define REF_1D_IDCT(xrow0, xrow1, xrow2, xrow3, xrow4, xrow5, xrow6, xrow7) \
+{ \
+ DCTELEM row0, row1, row2, row3, row4, row5, row6, row7; \
+ INT32 q1, q2, q3, q4, q5, q6, q7; \
+ INT32 tmp11_plus_tmp2, tmp11_minus_tmp2; \
+ \
+ /* 1-D iDCT input data */ \
+ row0 = xrow0; \
+ row1 = xrow1; \
+ row2 = xrow2; \
+ row3 = xrow3; \
+ row4 = xrow4; \
+ row5 = xrow5; \
+ row6 = xrow6; \
+ row7 = xrow7; \
+ \
+ q5 = row7 + row3; \
+ q4 = row5 + row1; \
+ q6 = MULTIPLY(q5, FIX_1_175875602_MINUS_1_961570560) + \
+ MULTIPLY(q4, FIX_1_175875602); \
+ q7 = MULTIPLY(q5, FIX_1_175875602) + \
+ MULTIPLY(q4, FIX_1_175875602_MINUS_0_390180644); \
+ q2 = MULTIPLY(row2, FIX_0_541196100) + \
+ MULTIPLY(row6, FIX_0_541196100_MINUS_1_847759065); \
+ q4 = q6; \
+ q3 = ((INT32) row0 - (INT32) row4) << 13; \
+ q6 += MULTIPLY(row5, -FIX_2_562915447) + \
+ MULTIPLY(row3, FIX_3_072711026_MINUS_2_562915447); \
+ /* now we can use q1 (reloadable constants have been used up) */ \
+ q1 = q3 + q2; \
+ q4 += MULTIPLY(row7, FIX_0_298631336_MINUS_0_899976223) + \
+ MULTIPLY(row1, -FIX_0_899976223); \
+ q5 = q7; \
+ q1 = q1 + q6; \
+ q7 += MULTIPLY(row7, -FIX_0_899976223) + \
+ MULTIPLY(row1, FIX_1_501321110_MINUS_0_899976223); \
+ \
+ /* (tmp11 + tmp2) has been calculated (out_row1 before descale) */ \
+ tmp11_plus_tmp2 = q1; \
+ row1 = 0; \
+ \
+ q1 = q1 - q6; \
+ q5 += MULTIPLY(row5, FIX_2_053119869_MINUS_2_562915447) + \
+ MULTIPLY(row3, -FIX_2_562915447); \
+ q1 = q1 - q6; \
+ q6 = MULTIPLY(row2, FIX_0_541196100_PLUS_0_765366865) + \
+ MULTIPLY(row6, FIX_0_541196100); \
+ q3 = q3 - q2; \
+ \
+ /* (tmp11 - tmp2) has been calculated (out_row6 before descale) */ \
+ tmp11_minus_tmp2 = q1; \
+ \
+ q1 = ((INT32) row0 + (INT32) row4) << 13; \
+ q2 = q1 + q6; \
+ q1 = q1 - q6; \
+ \
+ /* pick up the results */ \
+ tmp0 = q4; \
+ tmp1 = q5; \
+ tmp2 = (tmp11_plus_tmp2 - tmp11_minus_tmp2) / 2; \
+ tmp3 = q7; \
+ tmp10 = q2; \
+ tmp11 = (tmp11_plus_tmp2 + tmp11_minus_tmp2) / 2; \
+ tmp12 = q3; \
+ tmp13 = q1; \
+}
+
+#define XFIX_0_899976223 d0[0]
+#define XFIX_0_541196100 d0[1]
+#define XFIX_2_562915447 d0[2]
+#define XFIX_0_298631336_MINUS_0_899976223 d0[3]
+#define XFIX_1_501321110_MINUS_0_899976223 d1[0]
+#define XFIX_2_053119869_MINUS_2_562915447 d1[1]
+#define XFIX_0_541196100_PLUS_0_765366865 d1[2]
+#define XFIX_1_175875602 d1[3]
+#define XFIX_1_175875602_MINUS_0_390180644 d2[0]
+#define XFIX_0_541196100_MINUS_1_847759065 d2[1]
+#define XFIX_3_072711026_MINUS_2_562915447 d2[2]
+#define XFIX_1_175875602_MINUS_1_961570560 d2[3]
+
+.balign 16
+jsimd_idct_islow_neon_consts:
+ .short FIX_0_899976223 /* d0[0] */
+ .short FIX_0_541196100 /* d0[1] */
+ .short FIX_2_562915447 /* d0[2] */
+ .short FIX_0_298631336_MINUS_0_899976223 /* d0[3] */
+ .short FIX_1_501321110_MINUS_0_899976223 /* d1[0] */
+ .short FIX_2_053119869_MINUS_2_562915447 /* d1[1] */
+ .short FIX_0_541196100_PLUS_0_765366865 /* d1[2] */
+ .short FIX_1_175875602 /* d1[3] */
+ /* reloadable constants */
+ .short FIX_1_175875602_MINUS_0_390180644 /* d2[0] */
+ .short FIX_0_541196100_MINUS_1_847759065 /* d2[1] */
+ .short FIX_3_072711026_MINUS_2_562915447 /* d2[2] */
+ .short FIX_1_175875602_MINUS_1_961570560 /* d2[3] */
+
+asm_function jsimd_idct_islow_neon
+
+ DCT_TABLE .req r0
+ COEF_BLOCK .req r1
+ OUTPUT_BUF .req r2
+ OUTPUT_COL .req r3
+ TMP1 .req r0
+ TMP2 .req r1
+ TMP3 .req r2
+ TMP4 .req ip
+
+ ROW0L .req d16
+ ROW0R .req d17
+ ROW1L .req d18
+ ROW1R .req d19
+ ROW2L .req d20
+ ROW2R .req d21
+ ROW3L .req d22
+ ROW3R .req d23
+ ROW4L .req d24
+ ROW4R .req d25
+ ROW5L .req d26
+ ROW5R .req d27
+ ROW6L .req d28
+ ROW6R .req d29
+ ROW7L .req d30
+ ROW7R .req d31
+
+ /* Load and dequantize coefficients into NEON registers
+ * with the following allocation:
+ * 0 1 2 3 | 4 5 6 7
+ * ---------+--------
+ * 0 | d16 | d17 ( q8 )
+ * 1 | d18 | d19 ( q9 )
+ * 2 | d20 | d21 ( q10 )
+ * 3 | d22 | d23 ( q11 )
+ * 4 | d24 | d25 ( q12 )
+ * 5 | d26 | d27 ( q13 )
+ * 6 | d28 | d29 ( q14 )
+ * 7 | d30 | d31 ( q15 )
+ */
+ adr ip, jsimd_idct_islow_neon_consts
+ vld1.16 {d16, d17, d18, d19}, [COEF_BLOCK, :128]!
+ vld1.16 {d0, d1, d2, d3}, [DCT_TABLE, :128]!
+ vld1.16 {d20, d21, d22, d23}, [COEF_BLOCK, :128]!
+ vmul.s16 q8, q8, q0
+ vld1.16 {d4, d5, d6, d7}, [DCT_TABLE, :128]!
+ vmul.s16 q9, q9, q1
+ vld1.16 {d24, d25, d26, d27}, [COEF_BLOCK, :128]!
+ vmul.s16 q10, q10, q2
+ vld1.16 {d0, d1, d2, d3}, [DCT_TABLE, :128]!
+ vmul.s16 q11, q11, q3
+ vld1.16 {d28, d29, d30, d31}, [COEF_BLOCK, :128]
+ vmul.s16 q12, q12, q0
+ vld1.16 {d4, d5, d6, d7}, [DCT_TABLE, :128]!
+ vmul.s16 q14, q14, q2
+ vmul.s16 q13, q13, q1
+ vld1.16 {d0, d1, d2, d3}, [ip, :128] /* load constants */
+ add ip, ip, #16
+ vmul.s16 q15, q15, q3
+ vpush {d8-d15} /* save NEON registers */
+ /* 1-D IDCT, pass 1, left 4x8 half */
+ vadd.s16 d4, ROW7L, ROW3L
+ vadd.s16 d5, ROW5L, ROW1L
+ vmull.s16 q6, d4, XFIX_1_175875602_MINUS_1_961570560
+ vmlal.s16 q6, d5, XFIX_1_175875602
+ vmull.s16 q7, d4, XFIX_1_175875602
+ /* Check for the zero coefficients in the right 4x8 half */
+ push {r4, r5}
+ vmlal.s16 q7, d5, XFIX_1_175875602_MINUS_0_390180644
+ vsubl.s16 q3, ROW0L, ROW4L
+ ldrd r4, [COEF_BLOCK, #(-96 + 2 * (4 + 1 * 8))]
+ vmull.s16 q2, ROW2L, XFIX_0_541196100
+ vmlal.s16 q2, ROW6L, XFIX_0_541196100_MINUS_1_847759065
+ orr r0, r4, r5
+ vmov q4, q6
+ vmlsl.s16 q6, ROW5L, XFIX_2_562915447
+ ldrd r4, [COEF_BLOCK, #(-96 + 2 * (4 + 2 * 8))]
+ vmlal.s16 q6, ROW3L, XFIX_3_072711026_MINUS_2_562915447
+ vshl.s32 q3, q3, #13
+ orr r0, r0, r4
+ vmlsl.s16 q4, ROW1L, XFIX_0_899976223
+ orr r0, r0, r5
+ vadd.s32 q1, q3, q2
+ ldrd r4, [COEF_BLOCK, #(-96 + 2 * (4 + 3 * 8))]
+ vmov q5, q7
+ vadd.s32 q1, q1, q6
+ orr r0, r0, r4
+ vmlsl.s16 q7, ROW7L, XFIX_0_899976223
+ orr r0, r0, r5
+ vmlal.s16 q7, ROW1L, XFIX_1_501321110_MINUS_0_899976223
+ vrshrn.s32 ROW1L, q1, #11
+ ldrd r4, [COEF_BLOCK, #(-96 + 2 * (4 + 4 * 8))]
+ vsub.s32 q1, q1, q6
+ vmlal.s16 q5, ROW5L, XFIX_2_053119869_MINUS_2_562915447
+ orr r0, r0, r4
+ vmlsl.s16 q5, ROW3L, XFIX_2_562915447
+ orr r0, r0, r5
+ vsub.s32 q1, q1, q6
+ vmull.s16 q6, ROW2L, XFIX_0_541196100_PLUS_0_765366865
+ ldrd r4, [COEF_BLOCK, #(-96 + 2 * (4 + 5 * 8))]
+ vmlal.s16 q6, ROW6L, XFIX_0_541196100
+ vsub.s32 q3, q3, q2
+ orr r0, r0, r4
+ vrshrn.s32 ROW6L, q1, #11
+ orr r0, r0, r5
+ vadd.s32 q1, q3, q5
+ ldrd r4, [COEF_BLOCK, #(-96 + 2 * (4 + 6 * 8))]
+ vsub.s32 q3, q3, q5
+ vaddl.s16 q5, ROW0L, ROW4L
+ orr r0, r0, r4
+ vrshrn.s32 ROW2L, q1, #11
+ orr r0, r0, r5
+ vrshrn.s32 ROW5L, q3, #11
+ ldrd r4, [COEF_BLOCK, #(-96 + 2 * (4 + 7 * 8))]
+ vshl.s32 q5, q5, #13
+ vmlal.s16 q4, ROW7L, XFIX_0_298631336_MINUS_0_899976223
+ orr r0, r0, r4
+ vadd.s32 q2, q5, q6
+ orrs r0, r0, r5
+ vsub.s32 q1, q5, q6
+ vadd.s32 q6, q2, q7
+ ldrd r4, [COEF_BLOCK, #(-96 + 2 * (4 + 0 * 8))]
+ vsub.s32 q2, q2, q7
+ vadd.s32 q5, q1, q4
+ orr r0, r4, r5
+ vsub.s32 q3, q1, q4
+ pop {r4, r5}
+ vrshrn.s32 ROW7L, q2, #11
+ vrshrn.s32 ROW3L, q5, #11
+ vrshrn.s32 ROW0L, q6, #11
+ vrshrn.s32 ROW4L, q3, #11
+
+ beq 3f /* Go to do some special handling for the sparse right 4x8 half */
+
+ /* 1-D IDCT, pass 1, right 4x8 half */
+ vld1.s16 {d2}, [ip, :64] /* reload constants */
+ vadd.s16 d10, ROW7R, ROW3R
+ vadd.s16 d8, ROW5R, ROW1R
+ /* Transpose left 4x8 half */
+ vtrn.16 ROW6L, ROW7L
+ vmull.s16 q6, d10, XFIX_1_175875602_MINUS_1_961570560
+ vmlal.s16 q6, d8, XFIX_1_175875602
+ vtrn.16 ROW2L, ROW3L
+ vmull.s16 q7, d10, XFIX_1_175875602
+ vmlal.s16 q7, d8, XFIX_1_175875602_MINUS_0_390180644
+ vtrn.16 ROW0L, ROW1L
+ vsubl.s16 q3, ROW0R, ROW4R
+ vmull.s16 q2, ROW2R, XFIX_0_541196100
+ vmlal.s16 q2, ROW6R, XFIX_0_541196100_MINUS_1_847759065
+ vtrn.16 ROW4L, ROW5L
+ vmov q4, q6
+ vmlsl.s16 q6, ROW5R, XFIX_2_562915447
+ vmlal.s16 q6, ROW3R, XFIX_3_072711026_MINUS_2_562915447
+ vtrn.32 ROW1L, ROW3L
+ vshl.s32 q3, q3, #13
+ vmlsl.s16 q4, ROW1R, XFIX_0_899976223
+ vtrn.32 ROW4L, ROW6L
+ vadd.s32 q1, q3, q2
+ vmov q5, q7
+ vadd.s32 q1, q1, q6
+ vtrn.32 ROW0L, ROW2L
+ vmlsl.s16 q7, ROW7R, XFIX_0_899976223
+ vmlal.s16 q7, ROW1R, XFIX_1_501321110_MINUS_0_899976223
+ vrshrn.s32 ROW1R, q1, #11
+ vtrn.32 ROW5L, ROW7L
+ vsub.s32 q1, q1, q6
+ vmlal.s16 q5, ROW5R, XFIX_2_053119869_MINUS_2_562915447
+ vmlsl.s16 q5, ROW3R, XFIX_2_562915447
+ vsub.s32 q1, q1, q6
+ vmull.s16 q6, ROW2R, XFIX_0_541196100_PLUS_0_765366865
+ vmlal.s16 q6, ROW6R, XFIX_0_541196100
+ vsub.s32 q3, q3, q2
+ vrshrn.s32 ROW6R, q1, #11
+ vadd.s32 q1, q3, q5
+ vsub.s32 q3, q3, q5
+ vaddl.s16 q5, ROW0R, ROW4R
+ vrshrn.s32 ROW2R, q1, #11
+ vrshrn.s32 ROW5R, q3, #11
+ vshl.s32 q5, q5, #13
+ vmlal.s16 q4, ROW7R, XFIX_0_298631336_MINUS_0_899976223
+ vadd.s32 q2, q5, q6
+ vsub.s32 q1, q5, q6
+ vadd.s32 q6, q2, q7
+ vsub.s32 q2, q2, q7
+ vadd.s32 q5, q1, q4
+ vsub.s32 q3, q1, q4
+ vrshrn.s32 ROW7R, q2, #11
+ vrshrn.s32 ROW3R, q5, #11
+ vrshrn.s32 ROW0R, q6, #11
+ vrshrn.s32 ROW4R, q3, #11
+ /* Transpose right 4x8 half */
+ vtrn.16 ROW6R, ROW7R
+ vtrn.16 ROW2R, ROW3R
+ vtrn.16 ROW0R, ROW1R
+ vtrn.16 ROW4R, ROW5R
+ vtrn.32 ROW1R, ROW3R
+ vtrn.32 ROW4R, ROW6R
+ vtrn.32 ROW0R, ROW2R
+ vtrn.32 ROW5R, ROW7R
+
+1: /* 1-D IDCT, pass 2 (normal variant), left 4x8 half */
+ vld1.s16 {d2}, [ip, :64] /* reload constants */
+ vmull.s16 q6, ROW1R, XFIX_1_175875602 /* ROW5L <-> ROW1R */
+ vmlal.s16 q6, ROW1L, XFIX_1_175875602
+ vmlal.s16 q6, ROW3R, XFIX_1_175875602_MINUS_1_961570560 /* ROW7L <-> ROW3R */
+ vmlal.s16 q6, ROW3L, XFIX_1_175875602_MINUS_1_961570560
+ vmull.s16 q7, ROW3R, XFIX_1_175875602 /* ROW7L <-> ROW3R */
+ vmlal.s16 q7, ROW3L, XFIX_1_175875602
+ vmlal.s16 q7, ROW1R, XFIX_1_175875602_MINUS_0_390180644 /* ROW5L <-> ROW1R */
+ vmlal.s16 q7, ROW1L, XFIX_1_175875602_MINUS_0_390180644
+ vsubl.s16 q3, ROW0L, ROW0R /* ROW4L <-> ROW0R */
+ vmull.s16 q2, ROW2L, XFIX_0_541196100
+ vmlal.s16 q2, ROW2R, XFIX_0_541196100_MINUS_1_847759065 /* ROW6L <-> ROW2R */
+ vmov q4, q6
+ vmlsl.s16 q6, ROW1R, XFIX_2_562915447 /* ROW5L <-> ROW1R */
+ vmlal.s16 q6, ROW3L, XFIX_3_072711026_MINUS_2_562915447
+ vshl.s32 q3, q3, #13
+ vmlsl.s16 q4, ROW1L, XFIX_0_899976223
+ vadd.s32 q1, q3, q2
+ vmov q5, q7
+ vadd.s32 q1, q1, q6
+ vmlsl.s16 q7, ROW3R, XFIX_0_899976223 /* ROW7L <-> ROW3R */
+ vmlal.s16 q7, ROW1L, XFIX_1_501321110_MINUS_0_899976223
+ vshrn.s32 ROW1L, q1, #16
+ vsub.s32 q1, q1, q6
+ vmlal.s16 q5, ROW1R, XFIX_2_053119869_MINUS_2_562915447 /* ROW5L <-> ROW1R */
+ vmlsl.s16 q5, ROW3L, XFIX_2_562915447
+ vsub.s32 q1, q1, q6
+ vmull.s16 q6, ROW2L, XFIX_0_541196100_PLUS_0_765366865
+ vmlal.s16 q6, ROW2R, XFIX_0_541196100 /* ROW6L <-> ROW2R */
+ vsub.s32 q3, q3, q2
+ vshrn.s32 ROW2R, q1, #16 /* ROW6L <-> ROW2R */
+ vadd.s32 q1, q3, q5
+ vsub.s32 q3, q3, q5
+ vaddl.s16 q5, ROW0L, ROW0R /* ROW4L <-> ROW0R */
+ vshrn.s32 ROW2L, q1, #16
+ vshrn.s32 ROW1R, q3, #16 /* ROW5L <-> ROW1R */
+ vshl.s32 q5, q5, #13
+ vmlal.s16 q4, ROW3R, XFIX_0_298631336_MINUS_0_899976223 /* ROW7L <-> ROW3R */
+ vadd.s32 q2, q5, q6
+ vsub.s32 q1, q5, q6
+ vadd.s32 q6, q2, q7
+ vsub.s32 q2, q2, q7
+ vadd.s32 q5, q1, q4
+ vsub.s32 q3, q1, q4
+ vshrn.s32 ROW3R, q2, #16 /* ROW7L <-> ROW3R */
+ vshrn.s32 ROW3L, q5, #16
+ vshrn.s32 ROW0L, q6, #16
+ vshrn.s32 ROW0R, q3, #16 /* ROW4L <-> ROW0R */
+ /* 1-D IDCT, pass 2, right 4x8 half */
+ vld1.s16 {d2}, [ip, :64] /* reload constants */
+ vmull.s16 q6, ROW5R, XFIX_1_175875602
+ vmlal.s16 q6, ROW5L, XFIX_1_175875602 /* ROW5L <-> ROW1R */
+ vmlal.s16 q6, ROW7R, XFIX_1_175875602_MINUS_1_961570560
+ vmlal.s16 q6, ROW7L, XFIX_1_175875602_MINUS_1_961570560 /* ROW7L <-> ROW3R */
+ vmull.s16 q7, ROW7R, XFIX_1_175875602
+ vmlal.s16 q7, ROW7L, XFIX_1_175875602 /* ROW7L <-> ROW3R */
+ vmlal.s16 q7, ROW5R, XFIX_1_175875602_MINUS_0_390180644
+ vmlal.s16 q7, ROW5L, XFIX_1_175875602_MINUS_0_390180644 /* ROW5L <-> ROW1R */
+ vsubl.s16 q3, ROW4L, ROW4R /* ROW4L <-> ROW0R */
+ vmull.s16 q2, ROW6L, XFIX_0_541196100 /* ROW6L <-> ROW2R */
+ vmlal.s16 q2, ROW6R, XFIX_0_541196100_MINUS_1_847759065
+ vmov q4, q6
+ vmlsl.s16 q6, ROW5R, XFIX_2_562915447
+ vmlal.s16 q6, ROW7L, XFIX_3_072711026_MINUS_2_562915447 /* ROW7L <-> ROW3R */
+ vshl.s32 q3, q3, #13
+ vmlsl.s16 q4, ROW5L, XFIX_0_899976223 /* ROW5L <-> ROW1R */
+ vadd.s32 q1, q3, q2
+ vmov q5, q7
+ vadd.s32 q1, q1, q6
+ vmlsl.s16 q7, ROW7R, XFIX_0_899976223
+ vmlal.s16 q7, ROW5L, XFIX_1_501321110_MINUS_0_899976223 /* ROW5L <-> ROW1R */
+ vshrn.s32 ROW5L, q1, #16 /* ROW5L <-> ROW1R */
+ vsub.s32 q1, q1, q6
+ vmlal.s16 q5, ROW5R, XFIX_2_053119869_MINUS_2_562915447
+ vmlsl.s16 q5, ROW7L, XFIX_2_562915447 /* ROW7L <-> ROW3R */
+ vsub.s32 q1, q1, q6
+ vmull.s16 q6, ROW6L, XFIX_0_541196100_PLUS_0_765366865 /* ROW6L <-> ROW2R */
+ vmlal.s16 q6, ROW6R, XFIX_0_541196100
+ vsub.s32 q3, q3, q2
+ vshrn.s32 ROW6R, q1, #16
+ vadd.s32 q1, q3, q5
+ vsub.s32 q3, q3, q5
+ vaddl.s16 q5, ROW4L, ROW4R /* ROW4L <-> ROW0R */
+ vshrn.s32 ROW6L, q1, #16 /* ROW6L <-> ROW2R */
+ vshrn.s32 ROW5R, q3, #16
+ vshl.s32 q5, q5, #13
+ vmlal.s16 q4, ROW7R, XFIX_0_298631336_MINUS_0_899976223
+ vadd.s32 q2, q5, q6
+ vsub.s32 q1, q5, q6
+ vadd.s32 q6, q2, q7
+ vsub.s32 q2, q2, q7
+ vadd.s32 q5, q1, q4
+ vsub.s32 q3, q1, q4
+ vshrn.s32 ROW7R, q2, #16
+ vshrn.s32 ROW7L, q5, #16 /* ROW7L <-> ROW3R */
+ vshrn.s32 ROW4L, q6, #16 /* ROW4L <-> ROW0R */
+ vshrn.s32 ROW4R, q3, #16
+
+2: /* Descale to 8-bit and range limit */
+ vqrshrn.s16 d16, q8, #2
+ vqrshrn.s16 d17, q9, #2
+ vqrshrn.s16 d18, q10, #2
+ vqrshrn.s16 d19, q11, #2
+ vpop {d8-d15} /* restore NEON registers */
+ vqrshrn.s16 d20, q12, #2
+ /* Transpose the final 8-bit samples and do signed->unsigned conversion */
+ vtrn.16 q8, q9
+ vqrshrn.s16 d21, q13, #2
+ vqrshrn.s16 d22, q14, #2
+ vmov.u8 q0, #(CENTERJSAMPLE)
+ vqrshrn.s16 d23, q15, #2
+ vtrn.8 d16, d17
+ vtrn.8 d18, d19
+ vadd.u8 q8, q8, q0
+ vadd.u8 q9, q9, q0
+ vtrn.16 q10, q11
+ /* Store results to the output buffer */
+ ldmia OUTPUT_BUF!, {TMP1, TMP2}
+ add TMP1, TMP1, OUTPUT_COL
+ add TMP2, TMP2, OUTPUT_COL
+ vst1.8 {d16}, [TMP1]
+ vtrn.8 d20, d21
+ vst1.8 {d17}, [TMP2]
+ ldmia OUTPUT_BUF!, {TMP1, TMP2}
+ add TMP1, TMP1, OUTPUT_COL
+ add TMP2, TMP2, OUTPUT_COL
+ vst1.8 {d18}, [TMP1]
+ vadd.u8 q10, q10, q0
+ vst1.8 {d19}, [TMP2]
+ ldmia OUTPUT_BUF, {TMP1, TMP2, TMP3, TMP4}
+ add TMP1, TMP1, OUTPUT_COL
+ add TMP2, TMP2, OUTPUT_COL
+ add TMP3, TMP3, OUTPUT_COL
+ add TMP4, TMP4, OUTPUT_COL
+ vtrn.8 d22, d23
+ vst1.8 {d20}, [TMP1]
+ vadd.u8 q11, q11, q0
+ vst1.8 {d21}, [TMP2]
+ vst1.8 {d22}, [TMP3]
+ vst1.8 {d23}, [TMP4]
+ bx lr
+
+3: /* Left 4x8 half is done, right 4x8 half contains mostly zeros */
+
+ /* Transpose left 4x8 half */
+ vtrn.16 ROW6L, ROW7L
+ vtrn.16 ROW2L, ROW3L
+ vtrn.16 ROW0L, ROW1L
+ vtrn.16 ROW4L, ROW5L
+ vshl.s16 ROW0R, ROW0R, #2 /* PASS1_BITS */
+ vtrn.32 ROW1L, ROW3L
+ vtrn.32 ROW4L, ROW6L
+ vtrn.32 ROW0L, ROW2L
+ vtrn.32 ROW5L, ROW7L
+
+ cmp r0, #0
+ beq 4f /* Right 4x8 half has all zeros, go to 'sparse' second pass */
+
+ /* Only row 0 is non-zero for the right 4x8 half */
+ vdup.s16 ROW1R, ROW0R[1]
+ vdup.s16 ROW2R, ROW0R[2]
+ vdup.s16 ROW3R, ROW0R[3]
+ vdup.s16 ROW4R, ROW0R[0]
+ vdup.s16 ROW5R, ROW0R[1]
+ vdup.s16 ROW6R, ROW0R[2]
+ vdup.s16 ROW7R, ROW0R[3]
+ vdup.s16 ROW0R, ROW0R[0]
+ b 1b /* Go to 'normal' second pass */
+
+4: /* 1-D IDCT, pass 2 (sparse variant with zero rows 4-7), left 4x8 half */
+ vld1.s16 {d2}, [ip, :64] /* reload constants */
+ vmull.s16 q6, ROW1L, XFIX_1_175875602
+ vmlal.s16 q6, ROW3L, XFIX_1_175875602_MINUS_1_961570560
+ vmull.s16 q7, ROW3L, XFIX_1_175875602
+ vmlal.s16 q7, ROW1L, XFIX_1_175875602_MINUS_0_390180644
+ vmull.s16 q2, ROW2L, XFIX_0_541196100
+ vshll.s16 q3, ROW0L, #13
+ vmov q4, q6
+ vmlal.s16 q6, ROW3L, XFIX_3_072711026_MINUS_2_562915447
+ vmlsl.s16 q4, ROW1L, XFIX_0_899976223
+ vadd.s32 q1, q3, q2
+ vmov q5, q7
+ vmlal.s16 q7, ROW1L, XFIX_1_501321110_MINUS_0_899976223
+ vadd.s32 q1, q1, q6
+ vadd.s32 q6, q6, q6
+ vmlsl.s16 q5, ROW3L, XFIX_2_562915447
+ vshrn.s32 ROW1L, q1, #16
+ vsub.s32 q1, q1, q6
+ vmull.s16 q6, ROW2L, XFIX_0_541196100_PLUS_0_765366865
+ vsub.s32 q3, q3, q2
+ vshrn.s32 ROW2R, q1, #16 /* ROW6L <-> ROW2R */
+ vadd.s32 q1, q3, q5
+ vsub.s32 q3, q3, q5
+ vshll.s16 q5, ROW0L, #13
+ vshrn.s32 ROW2L, q1, #16
+ vshrn.s32 ROW1R, q3, #16 /* ROW5L <-> ROW1R */
+ vadd.s32 q2, q5, q6
+ vsub.s32 q1, q5, q6
+ vadd.s32 q6, q2, q7
+ vsub.s32 q2, q2, q7
+ vadd.s32 q5, q1, q4
+ vsub.s32 q3, q1, q4
+ vshrn.s32 ROW3R, q2, #16 /* ROW7L <-> ROW3R */
+ vshrn.s32 ROW3L, q5, #16
+ vshrn.s32 ROW0L, q6, #16
+ vshrn.s32 ROW0R, q3, #16 /* ROW4L <-> ROW0R */
+ /* 1-D IDCT, pass 2 (sparse variant with zero rows 4-7), right 4x8 half */
+ vld1.s16 {d2}, [ip, :64] /* reload constants */
+ vmull.s16 q6, ROW5L, XFIX_1_175875602
+ vmlal.s16 q6, ROW7L, XFIX_1_175875602_MINUS_1_961570560
+ vmull.s16 q7, ROW7L, XFIX_1_175875602
+ vmlal.s16 q7, ROW5L, XFIX_1_175875602_MINUS_0_390180644
+ vmull.s16 q2, ROW6L, XFIX_0_541196100
+ vshll.s16 q3, ROW4L, #13
+ vmov q4, q6
+ vmlal.s16 q6, ROW7L, XFIX_3_072711026_MINUS_2_562915447
+ vmlsl.s16 q4, ROW5L, XFIX_0_899976223
+ vadd.s32 q1, q3, q2
+ vmov q5, q7
+ vmlal.s16 q7, ROW5L, XFIX_1_501321110_MINUS_0_899976223
+ vadd.s32 q1, q1, q6
+ vadd.s32 q6, q6, q6
+ vmlsl.s16 q5, ROW7L, XFIX_2_562915447
+ vshrn.s32 ROW5L, q1, #16 /* ROW5L <-> ROW1R */
+ vsub.s32 q1, q1, q6
+ vmull.s16 q6, ROW6L, XFIX_0_541196100_PLUS_0_765366865
+ vsub.s32 q3, q3, q2
+ vshrn.s32 ROW6R, q1, #16
+ vadd.s32 q1, q3, q5
+ vsub.s32 q3, q3, q5
+ vshll.s16 q5, ROW4L, #13
+ vshrn.s32 ROW6L, q1, #16 /* ROW6L <-> ROW2R */
+ vshrn.s32 ROW5R, q3, #16
+ vadd.s32 q2, q5, q6
+ vsub.s32 q1, q5, q6
+ vadd.s32 q6, q2, q7
+ vsub.s32 q2, q2, q7
+ vadd.s32 q5, q1, q4
+ vsub.s32 q3, q1, q4
+ vshrn.s32 ROW7R, q2, #16
+ vshrn.s32 ROW7L, q5, #16 /* ROW7L <-> ROW3R */
+ vshrn.s32 ROW4L, q6, #16 /* ROW4L <-> ROW0R */
+ vshrn.s32 ROW4R, q3, #16
+ b 2b /* Go to epilogue */
+
+ .unreq DCT_TABLE
+ .unreq COEF_BLOCK
+ .unreq OUTPUT_BUF
+ .unreq OUTPUT_COL
+ .unreq TMP1
+ .unreq TMP2
+ .unreq TMP3
+ .unreq TMP4
+
+ .unreq ROW0L
+ .unreq ROW0R
+ .unreq ROW1L
+ .unreq ROW1R
+ .unreq ROW2L
+ .unreq ROW2R
+ .unreq ROW3L
+ .unreq ROW3R
+ .unreq ROW4L
+ .unreq ROW4R
+ .unreq ROW5L
+ .unreq ROW5R
+ .unreq ROW6L
+ .unreq ROW6R
+ .unreq ROW7L
+ .unreq ROW7R
+.endfunc
+
+/*****************************************************************************/
+
+/*
+ * jsimd_idct_ifast_neon
+ *
+ * This function contains a fast, not so accurate integer implementation of
+ * the inverse DCT (Discrete Cosine Transform). It uses the same calculations
+ * and produces exactly the same output as IJG's original 'jpeg_idct_ifast'
+ * function from jidctfst.c
+ *
+ * Normally 1-D AAN DCT needs 5 multiplications and 29 additions.
+ * But in ARM NEON case some extra additions are required because VQDMULH
+ * instruction can't handle the constants larger than 1. So the expressions
+ * like "x * 1.082392200" have to be converted to "x * 0.082392200 + x",
+ * which introduces an extra addition. Overall, there are 6 extra additions
+ * per 1-D IDCT pass, totalling to 5 VQDMULH and 35 VADD/VSUB instructions.
+ */
+
+#define XFIX_1_082392200 d0[0]
+#define XFIX_1_414213562 d0[1]
+#define XFIX_1_847759065 d0[2]
+#define XFIX_2_613125930 d0[3]
+
+.balign 16
+jsimd_idct_ifast_neon_consts:
+ .short (277 * 128 - 256 * 128) /* XFIX_1_082392200 */
+ .short (362 * 128 - 256 * 128) /* XFIX_1_414213562 */
+ .short (473 * 128 - 256 * 128) /* XFIX_1_847759065 */
+ .short (669 * 128 - 512 * 128) /* XFIX_2_613125930 */
+
+asm_function jsimd_idct_ifast_neon
+
+ DCT_TABLE .req r0
+ COEF_BLOCK .req r1
+ OUTPUT_BUF .req r2
+ OUTPUT_COL .req r3
+ TMP1 .req r0
+ TMP2 .req r1
+ TMP3 .req r2
+ TMP4 .req ip
+
+ /* Load and dequantize coefficients into NEON registers
+ * with the following allocation:
+ * 0 1 2 3 | 4 5 6 7
+ * ---------+--------
+ * 0 | d16 | d17 ( q8 )
+ * 1 | d18 | d19 ( q9 )
+ * 2 | d20 | d21 ( q10 )
+ * 3 | d22 | d23 ( q11 )
+ * 4 | d24 | d25 ( q12 )
+ * 5 | d26 | d27 ( q13 )
+ * 6 | d28 | d29 ( q14 )
+ * 7 | d30 | d31 ( q15 )
+ */
+ adr ip, jsimd_idct_ifast_neon_consts
+ vld1.16 {d16, d17, d18, d19}, [COEF_BLOCK, :128]!
+ vld1.16 {d0, d1, d2, d3}, [DCT_TABLE, :128]!
+ vld1.16 {d20, d21, d22, d23}, [COEF_BLOCK, :128]!
+ vmul.s16 q8, q8, q0
+ vld1.16 {d4, d5, d6, d7}, [DCT_TABLE, :128]!
+ vmul.s16 q9, q9, q1
+ vld1.16 {d24, d25, d26, d27}, [COEF_BLOCK, :128]!
+ vmul.s16 q10, q10, q2
+ vld1.16 {d0, d1, d2, d3}, [DCT_TABLE, :128]!
+ vmul.s16 q11, q11, q3
+ vld1.16 {d28, d29, d30, d31}, [COEF_BLOCK, :128]
+ vmul.s16 q12, q12, q0
+ vld1.16 {d4, d5, d6, d7}, [DCT_TABLE, :128]!
+ vmul.s16 q14, q14, q2
+ vmul.s16 q13, q13, q1
+ vld1.16 {d0}, [ip, :64] /* load constants */
+ vmul.s16 q15, q15, q3
+ vpush {d8-d13} /* save NEON registers */
+ /* 1-D IDCT, pass 1 */
+ vsub.s16 q2, q10, q14
+ vadd.s16 q14, q10, q14
+ vsub.s16 q1, q11, q13
+ vadd.s16 q13, q11, q13
+ vsub.s16 q5, q9, q15
+ vadd.s16 q15, q9, q15
+ vqdmulh.s16 q4, q2, XFIX_1_414213562
+ vqdmulh.s16 q6, q1, XFIX_2_613125930
+ vadd.s16 q3, q1, q1
+ vsub.s16 q1, q5, q1
+ vadd.s16 q10, q2, q4
+ vqdmulh.s16 q4, q1, XFIX_1_847759065
+ vsub.s16 q2, q15, q13
+ vadd.s16 q3, q3, q6
+ vqdmulh.s16 q6, q2, XFIX_1_414213562
+ vadd.s16 q1, q1, q4
+ vqdmulh.s16 q4, q5, XFIX_1_082392200
+ vsub.s16 q10, q10, q14
+ vadd.s16 q2, q2, q6
+ vsub.s16 q6, q8, q12
+ vadd.s16 q12, q8, q12
+ vadd.s16 q9, q5, q4
+ vadd.s16 q5, q6, q10
+ vsub.s16 q10, q6, q10
+ vadd.s16 q6, q15, q13
+ vadd.s16 q8, q12, q14
+ vsub.s16 q3, q6, q3
+ vsub.s16 q12, q12, q14
+ vsub.s16 q3, q3, q1
+ vsub.s16 q1, q9, q1
+ vadd.s16 q2, q3, q2
+ vsub.s16 q15, q8, q6
+ vadd.s16 q1, q1, q2
+ vadd.s16 q8, q8, q6
+ vadd.s16 q14, q5, q3
+ vsub.s16 q9, q5, q3
+ vsub.s16 q13, q10, q2
+ vadd.s16 q10, q10, q2
+ /* Transpose */
+ vtrn.16 q8, q9
+ vsub.s16 q11, q12, q1
+ vtrn.16 q14, q15
+ vadd.s16 q12, q12, q1
+ vtrn.16 q10, q11
+ vtrn.16 q12, q13
+ vtrn.32 q9, q11
+ vtrn.32 q12, q14
+ vtrn.32 q8, q10
+ vtrn.32 q13, q15
+ vswp d28, d21
+ vswp d26, d19
+ /* 1-D IDCT, pass 2 */
+ vsub.s16 q2, q10, q14
+ vswp d30, d23
+ vadd.s16 q14, q10, q14
+ vswp d24, d17
+ vsub.s16 q1, q11, q13
+ vadd.s16 q13, q11, q13
+ vsub.s16 q5, q9, q15
+ vadd.s16 q15, q9, q15
+ vqdmulh.s16 q4, q2, XFIX_1_414213562
+ vqdmulh.s16 q6, q1, XFIX_2_613125930
+ vadd.s16 q3, q1, q1
+ vsub.s16 q1, q5, q1
+ vadd.s16 q10, q2, q4
+ vqdmulh.s16 q4, q1, XFIX_1_847759065
+ vsub.s16 q2, q15, q13
+ vadd.s16 q3, q3, q6
+ vqdmulh.s16 q6, q2, XFIX_1_414213562
+ vadd.s16 q1, q1, q4
+ vqdmulh.s16 q4, q5, XFIX_1_082392200
+ vsub.s16 q10, q10, q14
+ vadd.s16 q2, q2, q6
+ vsub.s16 q6, q8, q12
+ vadd.s16 q12, q8, q12
+ vadd.s16 q9, q5, q4
+ vadd.s16 q5, q6, q10
+ vsub.s16 q10, q6, q10
+ vadd.s16 q6, q15, q13
+ vadd.s16 q8, q12, q14
+ vsub.s16 q3, q6, q3
+ vsub.s16 q12, q12, q14
+ vsub.s16 q3, q3, q1
+ vsub.s16 q1, q9, q1
+ vadd.s16 q2, q3, q2
+ vsub.s16 q15, q8, q6
+ vadd.s16 q1, q1, q2
+ vadd.s16 q8, q8, q6
+ vadd.s16 q14, q5, q3
+ vsub.s16 q9, q5, q3
+ vsub.s16 q13, q10, q2
+ vpop {d8-d13} /* restore NEON registers */
+ vadd.s16 q10, q10, q2
+ vsub.s16 q11, q12, q1
+ vadd.s16 q12, q12, q1
+ /* Descale to 8-bit and range limit */
+ vmov.u8 q0, #0x80
+ vqshrn.s16 d16, q8, #5
+ vqshrn.s16 d17, q9, #5
+ vqshrn.s16 d18, q10, #5
+ vqshrn.s16 d19, q11, #5
+ vqshrn.s16 d20, q12, #5
+ vqshrn.s16 d21, q13, #5
+ vqshrn.s16 d22, q14, #5
+ vqshrn.s16 d23, q15, #5
+ vadd.u8 q8, q8, q0
+ vadd.u8 q9, q9, q0
+ vadd.u8 q10, q10, q0
+ vadd.u8 q11, q11, q0
+ /* Transpose the final 8-bit samples */
+ vtrn.16 q8, q9
+ vtrn.16 q10, q11
+ vtrn.32 q8, q10
+ vtrn.32 q9, q11
+ vtrn.8 d16, d17
+ vtrn.8 d18, d19
+ /* Store results to the output buffer */
+ ldmia OUTPUT_BUF!, {TMP1, TMP2}
+ add TMP1, TMP1, OUTPUT_COL
+ add TMP2, TMP2, OUTPUT_COL
+ vst1.8 {d16}, [TMP1]
+ vst1.8 {d17}, [TMP2]
+ ldmia OUTPUT_BUF!, {TMP1, TMP2}
+ add TMP1, TMP1, OUTPUT_COL
+ add TMP2, TMP2, OUTPUT_COL
+ vst1.8 {d18}, [TMP1]
+ vtrn.8 d20, d21
+ vst1.8 {d19}, [TMP2]
+ ldmia OUTPUT_BUF, {TMP1, TMP2, TMP3, TMP4}
+ add TMP1, TMP1, OUTPUT_COL
+ add TMP2, TMP2, OUTPUT_COL
+ add TMP3, TMP3, OUTPUT_COL
+ add TMP4, TMP4, OUTPUT_COL
+ vst1.8 {d20}, [TMP1]
+ vtrn.8 d22, d23
+ vst1.8 {d21}, [TMP2]
+ vst1.8 {d22}, [TMP3]
+ vst1.8 {d23}, [TMP4]
+ bx lr
+
+ .unreq DCT_TABLE
+ .unreq COEF_BLOCK
+ .unreq OUTPUT_BUF
+ .unreq OUTPUT_COL
+ .unreq TMP1
+ .unreq TMP2
+ .unreq TMP3
+ .unreq TMP4
+.endfunc
+
+/*****************************************************************************/
+
+/*
+ * jsimd_idct_4x4_neon
+ *
+ * This function contains inverse-DCT code for getting reduced-size
+ * 4x4 pixels output from an 8x8 DCT block. It uses the same calculations
+ * and produces exactly the same output as IJG's original 'jpeg_idct_4x4'
+ * function from jpeg-6b (jidctred.c).
+ *
+ * NOTE: jpeg-8 has an improved implementation of 4x4 inverse-DCT, which
+ * requires much less arithmetic operations and hence should be faster.
+ * The primary purpose of this particular NEON optimized function is
+ * bit exact compatibility with jpeg-6b.
+ *
+ * TODO: a bit better instructions scheduling can be achieved by expanding
+ * idct_helper/transpose_4x4 macros and reordering instructions,
+ * but readability will suffer somewhat.
+ */
+
+#define CONST_BITS 13
+
+#define FIX_0_211164243 (1730) /* FIX(0.211164243) */
+#define FIX_0_509795579 (4176) /* FIX(0.509795579) */
+#define FIX_0_601344887 (4926) /* FIX(0.601344887) */
+#define FIX_0_720959822 (5906) /* FIX(0.720959822) */
+#define FIX_0_765366865 (6270) /* FIX(0.765366865) */
+#define FIX_0_850430095 (6967) /* FIX(0.850430095) */
+#define FIX_0_899976223 (7373) /* FIX(0.899976223) */
+#define FIX_1_061594337 (8697) /* FIX(1.061594337) */
+#define FIX_1_272758580 (10426) /* FIX(1.272758580) */
+#define FIX_1_451774981 (11893) /* FIX(1.451774981) */
+#define FIX_1_847759065 (15137) /* FIX(1.847759065) */
+#define FIX_2_172734803 (17799) /* FIX(2.172734803) */
+#define FIX_2_562915447 (20995) /* FIX(2.562915447) */
+#define FIX_3_624509785 (29692) /* FIX(3.624509785) */
+
+.balign 16
+jsimd_idct_4x4_neon_consts:
+ .short FIX_1_847759065 /* d0[0] */
+ .short -FIX_0_765366865 /* d0[1] */
+ .short -FIX_0_211164243 /* d0[2] */
+ .short FIX_1_451774981 /* d0[3] */
+ .short -FIX_2_172734803 /* d1[0] */
+ .short FIX_1_061594337 /* d1[1] */
+ .short -FIX_0_509795579 /* d1[2] */
+ .short -FIX_0_601344887 /* d1[3] */
+ .short FIX_0_899976223 /* d2[0] */
+ .short FIX_2_562915447 /* d2[1] */
+ .short 1 << (CONST_BITS+1) /* d2[2] */
+ .short 0 /* d2[3] */
+
+.macro idct_helper x4, x6, x8, x10, x12, x14, x16, shift, y26, y27, y28, y29
+ vmull.s16 q14, \x4, d2[2]
+ vmlal.s16 q14, \x8, d0[0]
+ vmlal.s16 q14, \x14, d0[1]
+
+ vmull.s16 q13, \x16, d1[2]
+ vmlal.s16 q13, \x12, d1[3]
+ vmlal.s16 q13, \x10, d2[0]
+ vmlal.s16 q13, \x6, d2[1]
+
+ vmull.s16 q15, \x4, d2[2]
+ vmlsl.s16 q15, \x8, d0[0]
+ vmlsl.s16 q15, \x14, d0[1]
+
+ vmull.s16 q12, \x16, d0[2]
+ vmlal.s16 q12, \x12, d0[3]
+ vmlal.s16 q12, \x10, d1[0]
+ vmlal.s16 q12, \x6, d1[1]
+
+ vadd.s32 q10, q14, q13
+ vsub.s32 q14, q14, q13
+
+.if \shift > 16
+ vrshr.s32 q10, q10, #\shift
+ vrshr.s32 q14, q14, #\shift
+ vmovn.s32 \y26, q10
+ vmovn.s32 \y29, q14
+.else
+ vrshrn.s32 \y26, q10, #\shift
+ vrshrn.s32 \y29, q14, #\shift
+.endif
+
+ vadd.s32 q10, q15, q12
+ vsub.s32 q15, q15, q12
+
+.if \shift > 16
+ vrshr.s32 q10, q10, #\shift
+ vrshr.s32 q15, q15, #\shift
+ vmovn.s32 \y27, q10
+ vmovn.s32 \y28, q15
+.else
+ vrshrn.s32 \y27, q10, #\shift
+ vrshrn.s32 \y28, q15, #\shift
+.endif
+
+.endm
+
+asm_function jsimd_idct_4x4_neon
+
+ DCT_TABLE .req r0
+ COEF_BLOCK .req r1
+ OUTPUT_BUF .req r2
+ OUTPUT_COL .req r3
+ TMP1 .req r0
+ TMP2 .req r1
+ TMP3 .req r2
+ TMP4 .req ip
+
+ vpush {d8-d15}
+
+ /* Load constants (d3 is just used for padding) */
+ adr TMP4, jsimd_idct_4x4_neon_consts
+ vld1.16 {d0, d1, d2, d3}, [TMP4, :128]
+
+ /* Load all COEF_BLOCK into NEON registers with the following allocation:
+ * 0 1 2 3 | 4 5 6 7
+ * ---------+--------
+ * 0 | d4 | d5
+ * 1 | d6 | d7
+ * 2 | d8 | d9
+ * 3 | d10 | d11
+ * 4 | - | -
+ * 5 | d12 | d13
+ * 6 | d14 | d15
+ * 7 | d16 | d17
+ */
+ vld1.16 {d4, d5, d6, d7}, [COEF_BLOCK, :128]!
+ vld1.16 {d8, d9, d10, d11}, [COEF_BLOCK, :128]!
+ add COEF_BLOCK, COEF_BLOCK, #16
+ vld1.16 {d12, d13, d14, d15}, [COEF_BLOCK, :128]!
+ vld1.16 {d16, d17}, [COEF_BLOCK, :128]!
+ /* dequantize */
+ vld1.16 {d18, d19, d20, d21}, [DCT_TABLE, :128]!
+ vmul.s16 q2, q2, q9
+ vld1.16 {d22, d23, d24, d25}, [DCT_TABLE, :128]!
+ vmul.s16 q3, q3, q10
+ vmul.s16 q4, q4, q11
+ add DCT_TABLE, DCT_TABLE, #16
+ vld1.16 {d26, d27, d28, d29}, [DCT_TABLE, :128]!
+ vmul.s16 q5, q5, q12
+ vmul.s16 q6, q6, q13
+ vld1.16 {d30, d31}, [DCT_TABLE, :128]!
+ vmul.s16 q7, q7, q14
+ vmul.s16 q8, q8, q15
+
+ /* Pass 1 */
+ idct_helper d4, d6, d8, d10, d12, d14, d16, 12, d4, d6, d8, d10
+ transpose_4x4 d4, d6, d8, d10
+ idct_helper d5, d7, d9, d11, d13, d15, d17, 12, d5, d7, d9, d11
+ transpose_4x4 d5, d7, d9, d11
+
+ /* Pass 2 */
+ idct_helper d4, d6, d8, d10, d7, d9, d11, 19, d26, d27, d28, d29
+ transpose_4x4 d26, d27, d28, d29
+
+ /* Range limit */
+ vmov.u16 q15, #0x80
+ vadd.s16 q13, q13, q15
+ vadd.s16 q14, q14, q15
+ vqmovun.s16 d26, q13
+ vqmovun.s16 d27, q14
+
+ /* Store results to the output buffer */
+ ldmia OUTPUT_BUF, {TMP1, TMP2, TMP3, TMP4}
+ add TMP1, TMP1, OUTPUT_COL
+ add TMP2, TMP2, OUTPUT_COL
+ add TMP3, TMP3, OUTPUT_COL
+ add TMP4, TMP4, OUTPUT_COL
+
+#if defined(__ARMEL__) && !RESPECT_STRICT_ALIGNMENT
+ /* We can use much less instructions on little endian systems if the
+ * OS kernel is not configured to trap unaligned memory accesses
+ */
+ vst1.32 {d26[0]}, [TMP1]!
+ vst1.32 {d27[0]}, [TMP3]!
+ vst1.32 {d26[1]}, [TMP2]!
+ vst1.32 {d27[1]}, [TMP4]!
+#else
+ vst1.8 {d26[0]}, [TMP1]!
+ vst1.8 {d27[0]}, [TMP3]!
+ vst1.8 {d26[1]}, [TMP1]!
+ vst1.8 {d27[1]}, [TMP3]!
+ vst1.8 {d26[2]}, [TMP1]!
+ vst1.8 {d27[2]}, [TMP3]!
+ vst1.8 {d26[3]}, [TMP1]!
+ vst1.8 {d27[3]}, [TMP3]!
+
+ vst1.8 {d26[4]}, [TMP2]!
+ vst1.8 {d27[4]}, [TMP4]!
+ vst1.8 {d26[5]}, [TMP2]!
+ vst1.8 {d27[5]}, [TMP4]!
+ vst1.8 {d26[6]}, [TMP2]!
+ vst1.8 {d27[6]}, [TMP4]!
+ vst1.8 {d26[7]}, [TMP2]!
+ vst1.8 {d27[7]}, [TMP4]!
+#endif
+
+ vpop {d8-d15}
+ bx lr
+
+ .unreq DCT_TABLE
+ .unreq COEF_BLOCK
+ .unreq OUTPUT_BUF
+ .unreq OUTPUT_COL
+ .unreq TMP1
+ .unreq TMP2
+ .unreq TMP3
+ .unreq TMP4
+.endfunc
+
+.purgem idct_helper
+
+/*****************************************************************************/
+
+/*
+ * jsimd_idct_2x2_neon
+ *
+ * This function contains inverse-DCT code for getting reduced-size
+ * 2x2 pixels output from an 8x8 DCT block. It uses the same calculations
+ * and produces exactly the same output as IJG's original 'jpeg_idct_2x2'
+ * function from jpeg-6b (jidctred.c).
+ *
+ * NOTE: jpeg-8 has an improved implementation of 2x2 inverse-DCT, which
+ * requires much less arithmetic operations and hence should be faster.
+ * The primary purpose of this particular NEON optimized function is
+ * bit exact compatibility with jpeg-6b.
+ */
+
+.balign 8
+jsimd_idct_2x2_neon_consts:
+ .short -FIX_0_720959822 /* d0[0] */
+ .short FIX_0_850430095 /* d0[1] */
+ .short -FIX_1_272758580 /* d0[2] */
+ .short FIX_3_624509785 /* d0[3] */
+
+.macro idct_helper x4, x6, x10, x12, x16, shift, y26, y27
+ vshll.s16 q14, \x4, #15
+ vmull.s16 q13, \x6, d0[3]
+ vmlal.s16 q13, \x10, d0[2]
+ vmlal.s16 q13, \x12, d0[1]
+ vmlal.s16 q13, \x16, d0[0]
+
+ vadd.s32 q10, q14, q13
+ vsub.s32 q14, q14, q13
+
+.if \shift > 16
+ vrshr.s32 q10, q10, #\shift
+ vrshr.s32 q14, q14, #\shift
+ vmovn.s32 \y26, q10
+ vmovn.s32 \y27, q14
+.else
+ vrshrn.s32 \y26, q10, #\shift
+ vrshrn.s32 \y27, q14, #\shift
+.endif
+
+.endm
+
+asm_function jsimd_idct_2x2_neon
+
+ DCT_TABLE .req r0
+ COEF_BLOCK .req r1
+ OUTPUT_BUF .req r2
+ OUTPUT_COL .req r3
+ TMP1 .req r0
+ TMP2 .req ip
+
+ vpush {d8-d15}
+
+ /* Load constants */
+ adr TMP2, jsimd_idct_2x2_neon_consts
+ vld1.16 {d0}, [TMP2, :64]
+
+ /* Load all COEF_BLOCK into NEON registers with the following allocation:
+ * 0 1 2 3 | 4 5 6 7
+ * ---------+--------
+ * 0 | d4 | d5
+ * 1 | d6 | d7
+ * 2 | - | -
+ * 3 | d10 | d11
+ * 4 | - | -
+ * 5 | d12 | d13
+ * 6 | - | -
+ * 7 | d16 | d17
+ */
+ vld1.16 {d4, d5, d6, d7}, [COEF_BLOCK, :128]!
+ add COEF_BLOCK, COEF_BLOCK, #16
+ vld1.16 {d10, d11}, [COEF_BLOCK, :128]!
+ add COEF_BLOCK, COEF_BLOCK, #16
+ vld1.16 {d12, d13}, [COEF_BLOCK, :128]!
+ add COEF_BLOCK, COEF_BLOCK, #16
+ vld1.16 {d16, d17}, [COEF_BLOCK, :128]!
+ /* Dequantize */
+ vld1.16 {d18, d19, d20, d21}, [DCT_TABLE, :128]!
+ vmul.s16 q2, q2, q9
+ vmul.s16 q3, q3, q10
+ add DCT_TABLE, DCT_TABLE, #16
+ vld1.16 {d24, d25}, [DCT_TABLE, :128]!
+ vmul.s16 q5, q5, q12
+ add DCT_TABLE, DCT_TABLE, #16
+ vld1.16 {d26, d27}, [DCT_TABLE, :128]!
+ vmul.s16 q6, q6, q13
+ add DCT_TABLE, DCT_TABLE, #16
+ vld1.16 {d30, d31}, [DCT_TABLE, :128]!
+ vmul.s16 q8, q8, q15
+
+ /* Pass 1 */
+#if 0
+ idct_helper d4, d6, d10, d12, d16, 13, d4, d6
+ transpose_4x4 d4, d6, d8, d10
+ idct_helper d5, d7, d11, d13, d17, 13, d5, d7
+ transpose_4x4 d5, d7, d9, d11
+#else
+ vmull.s16 q13, d6, d0[3]
+ vmlal.s16 q13, d10, d0[2]
+ vmlal.s16 q13, d12, d0[1]
+ vmlal.s16 q13, d16, d0[0]
+ vmull.s16 q12, d7, d0[3]
+ vmlal.s16 q12, d11, d0[2]
+ vmlal.s16 q12, d13, d0[1]
+ vmlal.s16 q12, d17, d0[0]
+ vshll.s16 q14, d4, #15
+ vshll.s16 q15, d5, #15
+ vadd.s32 q10, q14, q13
+ vsub.s32 q14, q14, q13
+ vrshrn.s32 d4, q10, #13
+ vrshrn.s32 d6, q14, #13
+ vadd.s32 q10, q15, q12
+ vsub.s32 q14, q15, q12
+ vrshrn.s32 d5, q10, #13
+ vrshrn.s32 d7, q14, #13
+ vtrn.16 q2, q3
+ vtrn.32 q3, q5
+#endif
+
+ /* Pass 2 */
+ idct_helper d4, d6, d10, d7, d11, 20, d26, d27
+
+ /* Range limit */
+ vmov.u16 q15, #0x80
+ vadd.s16 q13, q13, q15
+ vqmovun.s16 d26, q13
+ vqmovun.s16 d27, q13
+
+ /* Store results to the output buffer */
+ ldmia OUTPUT_BUF, {TMP1, TMP2}
+ add TMP1, TMP1, OUTPUT_COL
+ add TMP2, TMP2, OUTPUT_COL
+
+ vst1.8 {d26[0]}, [TMP1]!
+ vst1.8 {d27[4]}, [TMP1]!
+ vst1.8 {d26[1]}, [TMP2]!
+ vst1.8 {d27[5]}, [TMP2]!
+
+ vpop {d8-d15}
+ bx lr
+
+ .unreq DCT_TABLE
+ .unreq COEF_BLOCK
+ .unreq OUTPUT_BUF
+ .unreq OUTPUT_COL
+ .unreq TMP1
+ .unreq TMP2
+.endfunc
+
+.purgem idct_helper
+
+/*****************************************************************************/
+
+/*
+ * jsimd_ycc_extrgb_convert_neon
+ * jsimd_ycc_extbgr_convert_neon
+ * jsimd_ycc_extrgbx_convert_neon
+ * jsimd_ycc_extbgrx_convert_neon
+ * jsimd_ycc_extxbgr_convert_neon
+ * jsimd_ycc_extxrgb_convert_neon
+ *
+ * Colorspace conversion YCbCr -> RGB
+ */
+
+
+.macro do_load size
+ .if \size == 8
+ vld1.8 {d4}, [U, :64]!
+ vld1.8 {d5}, [V, :64]!
+ vld1.8 {d0}, [Y, :64]!
+ pld [U, #64]
+ pld [V, #64]
+ pld [Y, #64]
+ .elseif \size == 4
+ vld1.8 {d4[0]}, [U]!
+ vld1.8 {d4[1]}, [U]!
+ vld1.8 {d4[2]}, [U]!
+ vld1.8 {d4[3]}, [U]!
+ vld1.8 {d5[0]}, [V]!
+ vld1.8 {d5[1]}, [V]!
+ vld1.8 {d5[2]}, [V]!
+ vld1.8 {d5[3]}, [V]!
+ vld1.8 {d0[0]}, [Y]!
+ vld1.8 {d0[1]}, [Y]!
+ vld1.8 {d0[2]}, [Y]!
+ vld1.8 {d0[3]}, [Y]!
+ .elseif \size == 2
+ vld1.8 {d4[4]}, [U]!
+ vld1.8 {d4[5]}, [U]!
+ vld1.8 {d5[4]}, [V]!
+ vld1.8 {d5[5]}, [V]!
+ vld1.8 {d0[4]}, [Y]!
+ vld1.8 {d0[5]}, [Y]!
+ .elseif \size == 1
+ vld1.8 {d4[6]}, [U]!
+ vld1.8 {d5[6]}, [V]!
+ vld1.8 {d0[6]}, [Y]!
+ .else
+ .error unsupported macroblock size
+ .endif
+.endm
+
+.macro do_store bpp, size
+ .if \bpp == 24
+ .if \size == 8
+ vst3.8 {d10, d11, d12}, [RGB]!
+ .elseif \size == 4
+ vst3.8 {d10[0], d11[0], d12[0]}, [RGB]!
+ vst3.8 {d10[1], d11[1], d12[1]}, [RGB]!
+ vst3.8 {d10[2], d11[2], d12[2]}, [RGB]!
+ vst3.8 {d10[3], d11[3], d12[3]}, [RGB]!
+ .elseif \size == 2
+ vst3.8 {d10[4], d11[4], d12[4]}, [RGB]!
+ vst3.8 {d10[5], d11[5], d12[5]}, [RGB]!
+ .elseif \size == 1
+ vst3.8 {d10[6], d11[6], d12[6]}, [RGB]!
+ .else
+ .error unsupported macroblock size
+ .endif
+ .elseif \bpp == 32
+ .if \size == 8
+ vst4.8 {d10, d11, d12, d13}, [RGB]!
+ .elseif \size == 4
+ vst4.8 {d10[0], d11[0], d12[0], d13[0]}, [RGB]!
+ vst4.8 {d10[1], d11[1], d12[1], d13[1]}, [RGB]!
+ vst4.8 {d10[2], d11[2], d12[2], d13[2]}, [RGB]!
+ vst4.8 {d10[3], d11[3], d12[3], d13[3]}, [RGB]!
+ .elseif \size == 2
+ vst4.8 {d10[4], d11[4], d12[4], d13[4]}, [RGB]!
+ vst4.8 {d10[5], d11[5], d12[5], d13[5]}, [RGB]!
+ .elseif \size == 1
+ vst4.8 {d10[6], d11[6], d12[6], d13[6]}, [RGB]!
+ .else
+ .error unsupported macroblock size
+ .endif
+ .else
+ .error unsupported bpp
+ .endif
+.endm
+
+.macro generate_jsimd_ycc_rgb_convert_neon colorid, bpp, r_offs, g_offs, b_offs
+
+/*
+ * 2 stage pipelined YCbCr->RGB conversion
+ */
+
+.macro do_yuv_to_rgb_stage1
+ vaddw.u8 q3, q1, d4 /* q3 = u - 128 */
+ vaddw.u8 q4, q1, d5 /* q2 = v - 128 */
+ vmull.s16 q10, d6, d1[1] /* multiply by -11277 */
+ vmlal.s16 q10, d8, d1[2] /* multiply by -23401 */
+ vmull.s16 q11, d7, d1[1] /* multiply by -11277 */
+ vmlal.s16 q11, d9, d1[2] /* multiply by -23401 */
+ vmull.s16 q12, d8, d1[0] /* multiply by 22971 */
+ vmull.s16 q13, d9, d1[0] /* multiply by 22971 */
+ vmull.s16 q14, d6, d1[3] /* multiply by 29033 */
+ vmull.s16 q15, d7, d1[3] /* multiply by 29033 */
+.endm
+
+.macro do_yuv_to_rgb_stage2
+ vrshrn.s32 d20, q10, #15
+ vrshrn.s32 d21, q11, #15
+ vrshrn.s32 d24, q12, #14
+ vrshrn.s32 d25, q13, #14
+ vrshrn.s32 d28, q14, #14
+ vrshrn.s32 d29, q15, #14
+ vaddw.u8 q10, q10, d0
+ vaddw.u8 q12, q12, d0
+ vaddw.u8 q14, q14, d0
+ vqmovun.s16 d1\g_offs, q10
+ vqmovun.s16 d1\r_offs, q12
+ vqmovun.s16 d1\b_offs, q14
+.endm
+
+.macro do_yuv_to_rgb_stage2_store_load_stage1
+ vld1.8 {d4}, [U, :64]!
+ vrshrn.s32 d20, q10, #15
+ vrshrn.s32 d21, q11, #15
+ vrshrn.s32 d24, q12, #14
+ vrshrn.s32 d25, q13, #14
+ vrshrn.s32 d28, q14, #14
+ vld1.8 {d5}, [V, :64]!
+ vrshrn.s32 d29, q15, #14
+ vaddw.u8 q10, q10, d0
+ vaddw.u8 q12, q12, d0
+ vaddw.u8 q14, q14, d0
+ vqmovun.s16 d1\g_offs, q10
+ vld1.8 {d0}, [Y, :64]!
+ vqmovun.s16 d1\r_offs, q12
+ pld [U, #64]
+ pld [V, #64]
+ pld [Y, #64]
+ vqmovun.s16 d1\b_offs, q14
+ vaddw.u8 q3, q1, d4 /* q3 = u - 128 */
+ vaddw.u8 q4, q1, d5 /* q2 = v - 128 */
+ do_store \bpp, 8
+ vmull.s16 q10, d6, d1[1] /* multiply by -11277 */
+ vmlal.s16 q10, d8, d1[2] /* multiply by -23401 */
+ vmull.s16 q11, d7, d1[1] /* multiply by -11277 */
+ vmlal.s16 q11, d9, d1[2] /* multiply by -23401 */
+ vmull.s16 q12, d8, d1[0] /* multiply by 22971 */
+ vmull.s16 q13, d9, d1[0] /* multiply by 22971 */
+ vmull.s16 q14, d6, d1[3] /* multiply by 29033 */
+ vmull.s16 q15, d7, d1[3] /* multiply by 29033 */
+.endm
+
+.macro do_yuv_to_rgb
+ do_yuv_to_rgb_stage1
+ do_yuv_to_rgb_stage2
+.endm
+
+/* Apple gas crashes on adrl, work around that by using adr.
+ * But this requires a copy of these constants for each function.
+ */
+
+.balign 16
+jsimd_ycc_\colorid\()_neon_consts:
+ .short 0, 0, 0, 0
+ .short 22971, -11277, -23401, 29033
+ .short -128, -128, -128, -128
+ .short -128, -128, -128, -128
+
+asm_function jsimd_ycc_\colorid\()_convert_neon
+ OUTPUT_WIDTH .req r0
+ INPUT_BUF .req r1
+ INPUT_ROW .req r2
+ OUTPUT_BUF .req r3
+ NUM_ROWS .req r4
+
+ INPUT_BUF0 .req r5
+ INPUT_BUF1 .req r6
+ INPUT_BUF2 .req INPUT_BUF
+
+ RGB .req r7
+ Y .req r8
+ U .req r9
+ V .req r10
+ N .req ip
+
+ /* Load constants to d1, d2, d3 (d0 is just used for padding) */
+ adr ip, jsimd_ycc_\colorid\()_neon_consts
+ vld1.16 {d0, d1, d2, d3}, [ip, :128]
+
+ /* Save ARM registers and handle input arguments */
+ push {r4, r5, r6, r7, r8, r9, r10, lr}
+ ldr NUM_ROWS, [sp, #(4 * 8)]
+ ldr INPUT_BUF0, [INPUT_BUF]
+ ldr INPUT_BUF1, [INPUT_BUF, #4]
+ ldr INPUT_BUF2, [INPUT_BUF, #8]
+ .unreq INPUT_BUF
+
+ /* Save NEON registers */
+ vpush {d8-d15}
+
+ /* Initially set d10, d11, d12, d13 to 0xFF */
+ vmov.u8 q5, #255
+ vmov.u8 q6, #255
+
+ /* Outer loop over scanlines */
+ cmp NUM_ROWS, #1
+ blt 9f
+0:
+ ldr Y, [INPUT_BUF0, INPUT_ROW, lsl #2]
+ ldr U, [INPUT_BUF1, INPUT_ROW, lsl #2]
+ mov N, OUTPUT_WIDTH
+ ldr V, [INPUT_BUF2, INPUT_ROW, lsl #2]
+ add INPUT_ROW, INPUT_ROW, #1
+ ldr RGB, [OUTPUT_BUF], #4
+
+ /* Inner loop over pixels */
+ subs N, N, #8
+ blt 3f
+ do_load 8
+ do_yuv_to_rgb_stage1
+ subs N, N, #8
+ blt 2f
+1:
+ do_yuv_to_rgb_stage2_store_load_stage1
+ subs N, N, #8
+ bge 1b
+2:
+ do_yuv_to_rgb_stage2
+ do_store \bpp, 8
+ tst N, #7
+ beq 8f
+3:
+ tst N, #4
+ beq 3f
+ do_load 4
+3:
+ tst N, #2
+ beq 4f
+ do_load 2
+4:
+ tst N, #1
+ beq 5f
+ do_load 1
+5:
+ do_yuv_to_rgb
+ tst N, #4
+ beq 6f
+ do_store \bpp, 4
+6:
+ tst N, #2
+ beq 7f
+ do_store \bpp, 2
+7:
+ tst N, #1
+ beq 8f
+ do_store \bpp, 1
+8:
+ subs NUM_ROWS, NUM_ROWS, #1
+ bgt 0b
+9:
+ /* Restore all registers and return */
+ vpop {d8-d15}
+ pop {r4, r5, r6, r7, r8, r9, r10, pc}
+
+ .unreq OUTPUT_WIDTH
+ .unreq INPUT_ROW
+ .unreq OUTPUT_BUF
+ .unreq NUM_ROWS
+ .unreq INPUT_BUF0
+ .unreq INPUT_BUF1
+ .unreq INPUT_BUF2
+ .unreq RGB
+ .unreq Y
+ .unreq U
+ .unreq V
+ .unreq N
+.endfunc
+
+.purgem do_yuv_to_rgb
+.purgem do_yuv_to_rgb_stage1
+.purgem do_yuv_to_rgb_stage2
+.purgem do_yuv_to_rgb_stage2_store_load_stage1
+
+.endm
+
+/*--------------------------------- id ----- bpp R G B */
+generate_jsimd_ycc_rgb_convert_neon extrgb, 24, 0, 1, 2
+generate_jsimd_ycc_rgb_convert_neon extbgr, 24, 2, 1, 0
+generate_jsimd_ycc_rgb_convert_neon extrgbx, 32, 0, 1, 2
+generate_jsimd_ycc_rgb_convert_neon extbgrx, 32, 2, 1, 0
+generate_jsimd_ycc_rgb_convert_neon extxbgr, 32, 3, 2, 1
+generate_jsimd_ycc_rgb_convert_neon extxrgb, 32, 1, 2, 3
+
+.purgem do_load
+.purgem do_store
+
+/*****************************************************************************/
+
+/*
+ * jsimd_extrgb_ycc_convert_neon
+ * jsimd_extbgr_ycc_convert_neon
+ * jsimd_extrgbx_ycc_convert_neon
+ * jsimd_extbgrx_ycc_convert_neon
+ * jsimd_extxbgr_ycc_convert_neon
+ * jsimd_extxrgb_ycc_convert_neon
+ *
+ * Colorspace conversion RGB -> YCbCr
+ */
+
+.macro do_store size
+ .if \size == 8
+ vst1.8 {d20}, [Y]!
+ vst1.8 {d21}, [U]!
+ vst1.8 {d22}, [V]!
+ .elseif \size == 4
+ vst1.8 {d20[0]}, [Y]!
+ vst1.8 {d20[1]}, [Y]!
+ vst1.8 {d20[2]}, [Y]!
+ vst1.8 {d20[3]}, [Y]!
+ vst1.8 {d21[0]}, [U]!
+ vst1.8 {d21[1]}, [U]!
+ vst1.8 {d21[2]}, [U]!
+ vst1.8 {d21[3]}, [U]!
+ vst1.8 {d22[0]}, [V]!
+ vst1.8 {d22[1]}, [V]!
+ vst1.8 {d22[2]}, [V]!
+ vst1.8 {d22[3]}, [V]!
+ .elseif \size == 2
+ vst1.8 {d20[4]}, [Y]!
+ vst1.8 {d20[5]}, [Y]!
+ vst1.8 {d21[4]}, [U]!
+ vst1.8 {d21[5]}, [U]!
+ vst1.8 {d22[4]}, [V]!
+ vst1.8 {d22[5]}, [V]!
+ .elseif \size == 1
+ vst1.8 {d20[6]}, [Y]!
+ vst1.8 {d21[6]}, [U]!
+ vst1.8 {d22[6]}, [V]!
+ .else
+ .error unsupported macroblock size
+ .endif
+.endm
+
+.macro do_load bpp, size
+ .if \bpp == 24
+ .if \size == 8
+ vld3.8 {d10, d11, d12}, [RGB]!
+ pld [RGB, #128]
+ .elseif \size == 4
+ vld3.8 {d10[0], d11[0], d12[0]}, [RGB]!
+ vld3.8 {d10[1], d11[1], d12[1]}, [RGB]!
+ vld3.8 {d10[2], d11[2], d12[2]}, [RGB]!
+ vld3.8 {d10[3], d11[3], d12[3]}, [RGB]!
+ .elseif \size == 2
+ vld3.8 {d10[4], d11[4], d12[4]}, [RGB]!
+ vld3.8 {d10[5], d11[5], d12[5]}, [RGB]!
+ .elseif \size == 1
+ vld3.8 {d10[6], d11[6], d12[6]}, [RGB]!
+ .else
+ .error unsupported macroblock size
+ .endif
+ .elseif \bpp == 32
+ .if \size == 8
+ vld4.8 {d10, d11, d12, d13}, [RGB]!
+ pld [RGB, #128]
+ .elseif \size == 4
+ vld4.8 {d10[0], d11[0], d12[0], d13[0]}, [RGB]!
+ vld4.8 {d10[1], d11[1], d12[1], d13[1]}, [RGB]!
+ vld4.8 {d10[2], d11[2], d12[2], d13[2]}, [RGB]!
+ vld4.8 {d10[3], d11[3], d12[3], d13[3]}, [RGB]!
+ .elseif \size == 2
+ vld4.8 {d10[4], d11[4], d12[4], d13[4]}, [RGB]!
+ vld4.8 {d10[5], d11[5], d12[5], d13[5]}, [RGB]!
+ .elseif \size == 1
+ vld4.8 {d10[6], d11[6], d12[6], d13[6]}, [RGB]!
+ .else
+ .error unsupported macroblock size
+ .endif
+ .else
+ .error unsupported bpp
+ .endif
+.endm
+
+.macro generate_jsimd_rgb_ycc_convert_neon colorid, bpp, r_offs, g_offs, b_offs
+
+/*
+ * 2 stage pipelined RGB->YCbCr conversion
+ */
+
+.macro do_rgb_to_yuv_stage1
+ vmovl.u8 q2, d1\r_offs /* r = { d4, d5 } */
+ vmovl.u8 q3, d1\g_offs /* g = { d6, d7 } */
+ vmovl.u8 q4, d1\b_offs /* b = { d8, d9 } */
+ vmull.u16 q7, d4, d0[0]
+ vmlal.u16 q7, d6, d0[1]
+ vmlal.u16 q7, d8, d0[2]
+ vmull.u16 q8, d5, d0[0]
+ vmlal.u16 q8, d7, d0[1]
+ vmlal.u16 q8, d9, d0[2]
+ vrev64.32 q9, q1
+ vrev64.32 q13, q1
+ vmlsl.u16 q9, d4, d0[3]
+ vmlsl.u16 q9, d6, d1[0]
+ vmlal.u16 q9, d8, d1[1]
+ vmlsl.u16 q13, d5, d0[3]
+ vmlsl.u16 q13, d7, d1[0]
+ vmlal.u16 q13, d9, d1[1]
+ vrev64.32 q14, q1
+ vrev64.32 q15, q1
+ vmlal.u16 q14, d4, d1[1]
+ vmlsl.u16 q14, d6, d1[2]
+ vmlsl.u16 q14, d8, d1[3]
+ vmlal.u16 q15, d5, d1[1]
+ vmlsl.u16 q15, d7, d1[2]
+ vmlsl.u16 q15, d9, d1[3]
+.endm
+
+.macro do_rgb_to_yuv_stage2
+ vrshrn.u32 d20, q7, #16
+ vrshrn.u32 d21, q8, #16
+ vshrn.u32 d22, q9, #16
+ vshrn.u32 d23, q13, #16
+ vshrn.u32 d24, q14, #16
+ vshrn.u32 d25, q15, #16
+ vmovn.u16 d20, q10 /* d20 = y */
+ vmovn.u16 d21, q11 /* d21 = u */
+ vmovn.u16 d22, q12 /* d22 = v */
+.endm
+
+.macro do_rgb_to_yuv
+ do_rgb_to_yuv_stage1
+ do_rgb_to_yuv_stage2
+.endm
+
+.macro do_rgb_to_yuv_stage2_store_load_stage1
+ vrshrn.u32 d20, q7, #16
+ vrshrn.u32 d21, q8, #16
+ vshrn.u32 d22, q9, #16
+ vrev64.32 q9, q1
+ vshrn.u32 d23, q13, #16
+ vrev64.32 q13, q1
+ vshrn.u32 d24, q14, #16
+ vshrn.u32 d25, q15, #16
+ do_load \bpp, 8
+ vmovn.u16 d20, q10 /* d20 = y */
+ vmovl.u8 q2, d1\r_offs /* r = { d4, d5 } */
+ vmovn.u16 d21, q11 /* d21 = u */
+ vmovl.u8 q3, d1\g_offs /* g = { d6, d7 } */
+ vmovn.u16 d22, q12 /* d22 = v */
+ vmovl.u8 q4, d1\b_offs /* b = { d8, d9 } */
+ vmull.u16 q7, d4, d0[0]
+ vmlal.u16 q7, d6, d0[1]
+ vmlal.u16 q7, d8, d0[2]
+ vst1.8 {d20}, [Y]!
+ vmull.u16 q8, d5, d0[0]
+ vmlal.u16 q8, d7, d0[1]
+ vmlal.u16 q8, d9, d0[2]
+ vmlsl.u16 q9, d4, d0[3]
+ vmlsl.u16 q9, d6, d1[0]
+ vmlal.u16 q9, d8, d1[1]
+ vst1.8 {d21}, [U]!
+ vmlsl.u16 q13, d5, d0[3]
+ vmlsl.u16 q13, d7, d1[0]
+ vmlal.u16 q13, d9, d1[1]
+ vrev64.32 q14, q1
+ vrev64.32 q15, q1
+ vmlal.u16 q14, d4, d1[1]
+ vmlsl.u16 q14, d6, d1[2]
+ vmlsl.u16 q14, d8, d1[3]
+ vst1.8 {d22}, [V]!
+ vmlal.u16 q15, d5, d1[1]
+ vmlsl.u16 q15, d7, d1[2]
+ vmlsl.u16 q15, d9, d1[3]
+.endm
+
+.balign 16
+jsimd_\colorid\()_ycc_neon_consts:
+ .short 19595, 38470, 7471, 11059
+ .short 21709, 32768, 27439, 5329
+ .short 32767, 128, 32767, 128
+ .short 32767, 128, 32767, 128
+
+asm_function jsimd_\colorid\()_ycc_convert_neon
+ OUTPUT_WIDTH .req r0
+ INPUT_BUF .req r1
+ OUTPUT_BUF .req r2
+ OUTPUT_ROW .req r3
+ NUM_ROWS .req r4
+
+ OUTPUT_BUF0 .req r5
+ OUTPUT_BUF1 .req r6
+ OUTPUT_BUF2 .req OUTPUT_BUF
+
+ RGB .req r7
+ Y .req r8
+ U .req r9
+ V .req r10
+ N .req ip
+
+ /* Load constants to d0, d1, d2, d3 */
+ adr ip, jsimd_\colorid\()_ycc_neon_consts
+ vld1.16 {d0, d1, d2, d3}, [ip, :128]
+
+ /* Save ARM registers and handle input arguments */
+ push {r4, r5, r6, r7, r8, r9, r10, lr}
+ ldr NUM_ROWS, [sp, #(4 * 8)]
+ ldr OUTPUT_BUF0, [OUTPUT_BUF]
+ ldr OUTPUT_BUF1, [OUTPUT_BUF, #4]
+ ldr OUTPUT_BUF2, [OUTPUT_BUF, #8]
+ .unreq OUTPUT_BUF
+
+ /* Save NEON registers */
+ vpush {d8-d15}
+
+ /* Outer loop over scanlines */
+ cmp NUM_ROWS, #1
+ blt 9f
+0:
+ ldr Y, [OUTPUT_BUF0, OUTPUT_ROW, lsl #2]
+ ldr U, [OUTPUT_BUF1, OUTPUT_ROW, lsl #2]
+ mov N, OUTPUT_WIDTH
+ ldr V, [OUTPUT_BUF2, OUTPUT_ROW, lsl #2]
+ add OUTPUT_ROW, OUTPUT_ROW, #1
+ ldr RGB, [INPUT_BUF], #4
+
+ /* Inner loop over pixels */
+ subs N, N, #8
+ blt 3f
+ do_load \bpp, 8
+ do_rgb_to_yuv_stage1
+ subs N, N, #8
+ blt 2f
+1:
+ do_rgb_to_yuv_stage2_store_load_stage1
+ subs N, N, #8
+ bge 1b
+2:
+ do_rgb_to_yuv_stage2
+ do_store 8
+ tst N, #7
+ beq 8f
+3:
+ tst N, #4
+ beq 3f
+ do_load \bpp, 4
+3:
+ tst N, #2
+ beq 4f
+ do_load \bpp, 2
+4:
+ tst N, #1
+ beq 5f
+ do_load \bpp, 1
+5:
+ do_rgb_to_yuv
+ tst N, #4
+ beq 6f
+ do_store 4
+6:
+ tst N, #2
+ beq 7f
+ do_store 2
+7:
+ tst N, #1
+ beq 8f
+ do_store 1
+8:
+ subs NUM_ROWS, NUM_ROWS, #1
+ bgt 0b
+9:
+ /* Restore all registers and return */
+ vpop {d8-d15}
+ pop {r4, r5, r6, r7, r8, r9, r10, pc}
+
+ .unreq OUTPUT_WIDTH
+ .unreq OUTPUT_ROW
+ .unreq INPUT_BUF
+ .unreq NUM_ROWS
+ .unreq OUTPUT_BUF0
+ .unreq OUTPUT_BUF1
+ .unreq OUTPUT_BUF2
+ .unreq RGB
+ .unreq Y
+ .unreq U
+ .unreq V
+ .unreq N
+.endfunc
+
+.purgem do_rgb_to_yuv
+.purgem do_rgb_to_yuv_stage1
+.purgem do_rgb_to_yuv_stage2
+.purgem do_rgb_to_yuv_stage2_store_load_stage1
+
+.endm
+
+/*--------------------------------- id ----- bpp R G B */
+generate_jsimd_rgb_ycc_convert_neon extrgb, 24, 0, 1, 2
+generate_jsimd_rgb_ycc_convert_neon extbgr, 24, 2, 1, 0
+generate_jsimd_rgb_ycc_convert_neon extrgbx, 32, 0, 1, 2
+generate_jsimd_rgb_ycc_convert_neon extbgrx, 32, 2, 1, 0
+generate_jsimd_rgb_ycc_convert_neon extxbgr, 32, 3, 2, 1
+generate_jsimd_rgb_ycc_convert_neon extxrgb, 32, 1, 2, 3
+
+.purgem do_load
+.purgem do_store
+
+/*****************************************************************************/
+
+/*
+ * Load data into workspace, applying unsigned->signed conversion
+ *
+ * TODO: can be combined with 'jsimd_fdct_ifast_neon' to get
+ * rid of VST1.16 instructions
+ */
+
+asm_function jsimd_convsamp_neon
+ SAMPLE_DATA .req r0
+ START_COL .req r1
+ WORKSPACE .req r2
+ TMP1 .req r3
+ TMP2 .req r4
+ TMP3 .req r5
+ TMP4 .req ip
+
+ push {r4, r5}
+ vmov.u8 d0, #128
+
+ ldmia SAMPLE_DATA!, {TMP1, TMP2, TMP3, TMP4}
+ add TMP1, TMP1, START_COL
+ add TMP2, TMP2, START_COL
+ add TMP3, TMP3, START_COL
+ add TMP4, TMP4, START_COL
+ vld1.8 {d16}, [TMP1]
+ vsubl.u8 q8, d16, d0
+ vld1.8 {d18}, [TMP2]
+ vsubl.u8 q9, d18, d0
+ vld1.8 {d20}, [TMP3]
+ vsubl.u8 q10, d20, d0
+ vld1.8 {d22}, [TMP4]
+ ldmia SAMPLE_DATA!, {TMP1, TMP2, TMP3, TMP4}
+ vsubl.u8 q11, d22, d0
+ vst1.16 {d16, d17, d18, d19}, [WORKSPACE, :128]!
+ add TMP1, TMP1, START_COL
+ add TMP2, TMP2, START_COL
+ vst1.16 {d20, d21, d22, d23}, [WORKSPACE, :128]!
+ add TMP3, TMP3, START_COL
+ add TMP4, TMP4, START_COL
+ vld1.8 {d24}, [TMP1]
+ vsubl.u8 q12, d24, d0
+ vld1.8 {d26}, [TMP2]
+ vsubl.u8 q13, d26, d0
+ vld1.8 {d28}, [TMP3]
+ vsubl.u8 q14, d28, d0
+ vld1.8 {d30}, [TMP4]
+ vsubl.u8 q15, d30, d0
+ vst1.16 {d24, d25, d26, d27}, [WORKSPACE, :128]!
+ vst1.16 {d28, d29, d30, d31}, [WORKSPACE, :128]!
+ pop {r4, r5}
+ bx lr
+
+ .unreq SAMPLE_DATA
+ .unreq START_COL
+ .unreq WORKSPACE
+ .unreq TMP1
+ .unreq TMP2
+ .unreq TMP3
+ .unreq TMP4
+.endfunc
+
+/*****************************************************************************/
+
+/*
+ * jsimd_fdct_ifast_neon
+ *
+ * This function contains a fast, not so accurate integer implementation of
+ * the forward DCT (Discrete Cosine Transform). It uses the same calculations
+ * and produces exactly the same output as IJG's original 'jpeg_fdct_ifast'
+ * function from jfdctfst.c
+ *
+ * TODO: can be combined with 'jsimd_convsamp_neon' to get
+ * rid of a bunch of VLD1.16 instructions
+ */
+
+#define XFIX_0_382683433 d0[0]
+#define XFIX_0_541196100 d0[1]
+#define XFIX_0_707106781 d0[2]
+#define XFIX_1_306562965 d0[3]
+
+.balign 16
+jsimd_fdct_ifast_neon_consts:
+ .short (98 * 128) /* XFIX_0_382683433 */
+ .short (139 * 128) /* XFIX_0_541196100 */
+ .short (181 * 128) /* XFIX_0_707106781 */
+ .short (334 * 128 - 256 * 128) /* XFIX_1_306562965 */
+
+asm_function jsimd_fdct_ifast_neon
+
+ DATA .req r0
+ TMP .req ip
+
+ vpush {d8-d15}
+
+ /* Load constants */
+ adr TMP, jsimd_fdct_ifast_neon_consts
+ vld1.16 {d0}, [TMP, :64]
+
+ /* Load all DATA into NEON registers with the following allocation:
+ * 0 1 2 3 | 4 5 6 7
+ * ---------+--------
+ * 0 | d16 | d17 | q8
+ * 1 | d18 | d19 | q9
+ * 2 | d20 | d21 | q10
+ * 3 | d22 | d23 | q11
+ * 4 | d24 | d25 | q12
+ * 5 | d26 | d27 | q13
+ * 6 | d28 | d29 | q14
+ * 7 | d30 | d31 | q15
+ */
+
+ vld1.16 {d16, d17, d18, d19}, [DATA, :128]!
+ vld1.16 {d20, d21, d22, d23}, [DATA, :128]!
+ vld1.16 {d24, d25, d26, d27}, [DATA, :128]!
+ vld1.16 {d28, d29, d30, d31}, [DATA, :128]
+ sub DATA, DATA, #(128 - 32)
+
+ mov TMP, #2
+1:
+ /* Transpose */
+ vtrn.16 q12, q13
+ vtrn.16 q10, q11
+ vtrn.16 q8, q9
+ vtrn.16 q14, q15
+ vtrn.32 q9, q11
+ vtrn.32 q13, q15
+ vtrn.32 q8, q10
+ vtrn.32 q12, q14
+ vswp d30, d23
+ vswp d24, d17
+ vswp d26, d19
+ /* 1-D FDCT */
+ vadd.s16 q2, q11, q12
+ vswp d28, d21
+ vsub.s16 q12, q11, q12
+ vsub.s16 q6, q10, q13
+ vadd.s16 q10, q10, q13
+ vsub.s16 q7, q9, q14
+ vadd.s16 q9, q9, q14
+ vsub.s16 q1, q8, q15
+ vadd.s16 q8, q8, q15
+ vsub.s16 q4, q9, q10
+ vsub.s16 q5, q8, q2
+ vadd.s16 q3, q9, q10
+ vadd.s16 q4, q4, q5
+ vadd.s16 q2, q8, q2
+ vqdmulh.s16 q4, q4, XFIX_0_707106781
+ vadd.s16 q11, q12, q6
+ vadd.s16 q8, q2, q3
+ vsub.s16 q12, q2, q3
+ vadd.s16 q3, q6, q7
+ vadd.s16 q7, q7, q1
+ vqdmulh.s16 q3, q3, XFIX_0_707106781
+ vsub.s16 q6, q11, q7
+ vadd.s16 q10, q5, q4
+ vqdmulh.s16 q6, q6, XFIX_0_382683433
+ vsub.s16 q14, q5, q4
+ vqdmulh.s16 q11, q11, XFIX_0_541196100
+ vqdmulh.s16 q5, q7, XFIX_1_306562965
+ vadd.s16 q4, q1, q3
+ vsub.s16 q3, q1, q3
+ vadd.s16 q7, q7, q6
+ vadd.s16 q11, q11, q6
+ vadd.s16 q7, q7, q5
+ vadd.s16 q13, q3, q11
+ vsub.s16 q11, q3, q11
+ vadd.s16 q9, q4, q7
+ vsub.s16 q15, q4, q7
+ subs TMP, TMP, #1
+ bne 1b
+
+ /* store results */
+ vst1.16 {d16, d17, d18, d19}, [DATA, :128]!
+ vst1.16 {d20, d21, d22, d23}, [DATA, :128]!
+ vst1.16 {d24, d25, d26, d27}, [DATA, :128]!
+ vst1.16 {d28, d29, d30, d31}, [DATA, :128]
+
+ vpop {d8-d15}
+ bx lr
+
+ .unreq DATA
+ .unreq TMP
+.endfunc
+
+/*****************************************************************************/
+
+/*
+ * GLOBAL(void)
+ * jsimd_quantize_neon (JCOEFPTR coef_block, DCTELEM * divisors,
+ * DCTELEM * workspace);
+ *
+ * Note: the code uses 2 stage pipelining in order to improve instructions
+ * scheduling and eliminate stalls (this provides ~15% better
+ * performance for this function on both ARM Cortex-A8 and
+ * ARM Cortex-A9 when compared to the non-pipelined variant).
+ * The instructions which belong to the second stage use different
+ * indentation for better readiability.
+ */
+asm_function jsimd_quantize_neon
+
+ COEF_BLOCK .req r0
+ DIVISORS .req r1
+ WORKSPACE .req r2
+
+ RECIPROCAL .req DIVISORS
+ CORRECTION .req r3
+ SHIFT .req ip
+ LOOP_COUNT .req r4
+
+ vld1.16 {d0, d1, d2, d3}, [WORKSPACE, :128]!
+ vabs.s16 q12, q0
+ add CORRECTION, DIVISORS, #(64 * 2)
+ add SHIFT, DIVISORS, #(64 * 6)
+ vld1.16 {d20, d21, d22, d23}, [CORRECTION, :128]!
+ vabs.s16 q13, q1
+ vld1.16 {d16, d17, d18, d19}, [RECIPROCAL, :128]!
+ vadd.u16 q12, q12, q10 /* add correction */
+ vadd.u16 q13, q13, q11
+ vmull.u16 q10, d24, d16 /* multiply by reciprocal */
+ vmull.u16 q11, d25, d17
+ vmull.u16 q8, d26, d18
+ vmull.u16 q9, d27, d19
+ vld1.16 {d24, d25, d26, d27}, [SHIFT, :128]!
+ vshrn.u32 d20, q10, #16
+ vshrn.u32 d21, q11, #16
+ vshrn.u32 d22, q8, #16
+ vshrn.u32 d23, q9, #16
+ vneg.s16 q12, q12
+ vneg.s16 q13, q13
+ vshr.s16 q2, q0, #15 /* extract sign */
+ vshr.s16 q3, q1, #15
+ vshl.u16 q14, q10, q12 /* shift */
+ vshl.u16 q15, q11, q13
+
+ push {r4, r5}
+ mov LOOP_COUNT, #3
+1:
+ vld1.16 {d0, d1, d2, d3}, [WORKSPACE, :128]!
+ veor.u16 q14, q14, q2 /* restore sign */
+ vabs.s16 q12, q0
+ vld1.16 {d20, d21, d22, d23}, [CORRECTION, :128]!
+ vabs.s16 q13, q1
+ veor.u16 q15, q15, q3
+ vld1.16 {d16, d17, d18, d19}, [RECIPROCAL, :128]!
+ vadd.u16 q12, q12, q10 /* add correction */
+ vadd.u16 q13, q13, q11
+ vmull.u16 q10, d24, d16 /* multiply by reciprocal */
+ vmull.u16 q11, d25, d17
+ vmull.u16 q8, d26, d18
+ vmull.u16 q9, d27, d19
+ vsub.u16 q14, q14, q2
+ vld1.16 {d24, d25, d26, d27}, [SHIFT, :128]!
+ vsub.u16 q15, q15, q3
+ vshrn.u32 d20, q10, #16
+ vshrn.u32 d21, q11, #16
+ vst1.16 {d28, d29, d30, d31}, [COEF_BLOCK, :128]!
+ vshrn.u32 d22, q8, #16
+ vshrn.u32 d23, q9, #16
+ vneg.s16 q12, q12
+ vneg.s16 q13, q13
+ vshr.s16 q2, q0, #15 /* extract sign */
+ vshr.s16 q3, q1, #15
+ vshl.u16 q14, q10, q12 /* shift */
+ vshl.u16 q15, q11, q13
+ subs LOOP_COUNT, LOOP_COUNT, #1
+ bne 1b
+ pop {r4, r5}
+
+ veor.u16 q14, q14, q2 /* restore sign */
+ veor.u16 q15, q15, q3
+ vsub.u16 q14, q14, q2
+ vsub.u16 q15, q15, q3
+ vst1.16 {d28, d29, d30, d31}, [COEF_BLOCK, :128]!
+
+ bx lr /* return */
+
+ .unreq COEF_BLOCK
+ .unreq DIVISORS
+ .unreq WORKSPACE
+ .unreq RECIPROCAL
+ .unreq CORRECTION
+ .unreq SHIFT
+ .unreq LOOP_COUNT
+.endfunc
diff --git a/src/libmatrix/COPYING b/src/libmatrix/COPYING
new file mode 100644
index 0000000..3e4d480
--- /dev/null
+++ b/src/libmatrix/COPYING
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2010 Linaro Limited
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/libmatrix/Makefile b/src/libmatrix/Makefile
new file mode 100644
index 0000000..418311f
--- /dev/null
+++ b/src/libmatrix/Makefile
@@ -0,0 +1,42 @@
+CXXFLAGS = -Wall -Werror -pedantic -O3
+LIBMATRIX = libmatrix.a
+LIBSRCS = mat.cc program.cc log.cc util.cc shader-source.cc
+LIBOBJS = $(LIBSRCS:.cc=.o)
+TESTDIR = test
+LIBMATRIX_TESTS = $(TESTDIR)/libmatrix_test
+TESTSRCS = $(TESTDIR)/options.cc \
+ $(TESTDIR)/const_vec_test.cc \
+ $(TESTDIR)/inverse_test.cc \
+ $(TESTDIR)/transpose_test.cc \
+ $(TESTDIR)/shader_source_test.cc \
+ $(TESTDIR)/util_split_test.cc \
+ $(TESTDIR)/libmatrix_test.cc
+TESTOBJS = $(TESTSRCS:.cc=.o)
+
+# Make sure to build both the library targets and the tests, and generate
+# a make failure if the tests don't pass.
+default: $(LIBMATRIX) $(LIBMATRIX_TESTS) run_tests
+
+# Main library targets here.
+mat.o : mat.cc mat.h vec.h
+program.o: program.cc program.h mat.h vec.h
+log.o: log.cc log.h
+util.o: util.cc util.h
+shader-source.o: shader-source.cc shader-source.h mat.h vec.h util.h
+libmatrix.a : mat.o stack.h program.o log.o util.o shader-source.o
+ $(AR) -r $@ $(LIBOBJS)
+
+# Tests and execution targets here.
+$(TESTDIR)/options.o: $(TESTDIR)/options.cc $(TESTDIR)/libmatrix_test.h
+$(TESTDIR)/libmatrix_test.o: $(TESTDIR)/libmatrix_test.cc $(TESTDIR)/libmatrix_test.h $(TESTDIR)/inverse_test.h $(TESTDIR)/transpose_test.h
+$(TESTDIR)/const_vec_test.o: $(TESTDIR)/const_vec_test.cc $(TESTDIR)/const_vec_test.h $(TESTDIR)/libmatrix_test.h vec.h
+$(TESTDIR)/inverse_test.o: $(TESTDIR)/inverse_test.cc $(TESTDIR)/inverse_test.h $(TESTDIR)/libmatrix_test.h mat.h
+$(TESTDIR)/transpose_test.o: $(TESTDIR)/transpose_test.cc $(TESTDIR)/transpose_test.h $(TESTDIR)/libmatrix_test.h mat.h
+$(TESTDIR)/shader_source_test.o: $(TESTDIR)/shader_source_test.cc $(TESTDIR)/shader_source_test.h $(TESTDIR)/libmatrix_test.h shader-source.h
+$(TESTDIR)/util_split_test.o: $(TESTDIR)/util_split_test.cc $(TESTDIR)/util_split_test.h $(TESTDIR)/libmatrix_test.h util.h
+$(TESTDIR)/libmatrix_test: $(TESTOBJS) libmatrix.a
+ $(CXX) -o $@ $^
+run_tests: $(LIBMATRIX_TESTS)
+ $(LIBMATRIX_TESTS)
+clean :
+ $(RM) $(LIBOBJS) $(TESTOBJS) $(LIBMATRIX) $(LIBMATRIX_TESTS)
diff --git a/src/libmatrix/README b/src/libmatrix/README
new file mode 100644
index 0000000..17229f6
--- /dev/null
+++ b/src/libmatrix/README
@@ -0,0 +1,11 @@
+libmatrix
+=========
+
+A simple C++ template library that provides containers and arithmetic
+operations for vectors, matrices and matrix stacks of 2, 3 and 4 dimensions.
+Additionally, it provides implementations of the more common matrix
+transformations described by the OpenGL programming guide. libmatrix does
+not make any OpenGL calls, it merely replaces a portion of the fixed-function
+vertex processing API that have been removed from newer releases of core OpenGL
+and omitted from OpenGL ES. The goal is simply to provide developers an easier
+point of entry into developing for OpenGL and OpenGL ES.
diff --git a/src/libmatrix/gl-if.h b/src/libmatrix/gl-if.h
new file mode 100644
index 0000000..89b84e9
--- /dev/null
+++ b/src/libmatrix/gl-if.h
@@ -0,0 +1,18 @@
+//
+// Copyright (c) 2012 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#ifndef GL_IF_H_
+#define GL_IF_H_
+// Inclusion abstraction to provide project specific interface headers for
+// whatever flavor of OpenGL(|ES) is appropriate. For core libmatrix, this
+// is GLEW.
+#include "gl-headers.h"
+#endif // GL_IF_H_
diff --git a/src/libmatrix/log.cc b/src/libmatrix/log.cc
new file mode 100644
index 0000000..10603ae
--- /dev/null
+++ b/src/libmatrix/log.cc
@@ -0,0 +1,173 @@
+//
+// Copyright (c) 2010-2012 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#include <unistd.h>
+#include <cstdio>
+#include <cstdarg>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include "log.h"
+
+#ifdef ANDROID
+#include <android/log.h>
+#endif
+
+using std::string;
+
+const string Log::continuation_prefix("\x10");
+string Log::appname_;
+bool Log::do_debug_(false);
+std::ostream* Log::extra_out_(0);
+
+static const string terminal_color_normal("\033[0m");
+static const string terminal_color_red("\033[1;31m");
+static const string terminal_color_cyan("\033[36m");
+static const string terminal_color_yellow("\033[33m");
+static const string empty;
+
+static void
+print_prefixed_message(std::ostream& stream, const string& color, const string& prefix,
+ const string& fmt, va_list ap)
+{
+ va_list aq;
+
+ /* Estimate message size */
+ va_copy(aq, ap);
+ int msg_size = vsnprintf(NULL, 0, fmt.c_str(), aq);
+ va_end(aq);
+
+ /* Create the buffer to hold the message */
+ char *buf = new char[msg_size + 1];
+
+ /* Store the message in the buffer */
+ va_copy(aq, ap);
+ vsnprintf(buf, msg_size + 1, fmt.c_str(), aq);
+ va_end(aq);
+
+ /*
+ * Print the message lines prefixed with the supplied prefix.
+ * If the target stream is a terminal make the prefix colored.
+ */
+ string linePrefix;
+ if (!prefix.empty())
+ {
+ static const string colon(": ");
+ string start_color;
+ string end_color;
+ if (!color.empty())
+ {
+ start_color = color;
+ end_color = terminal_color_normal;
+ }
+ linePrefix = start_color + prefix + end_color + colon;
+ }
+
+ std::string line;
+ std::stringstream ss(buf);
+
+ while(std::getline(ss, line)) {
+ /*
+ * If this line is a continuation of a previous log message
+ * just print the line plainly.
+ */
+ if (line[0] == Log::continuation_prefix[0]) {
+ stream << line.c_str() + 1;
+ }
+ else {
+ /* Normal line, emit the prefix. */
+ stream << linePrefix << line;
+ }
+
+ /* Only emit a newline if the original message has it. */
+ if (!(ss.rdstate() & std::stringstream::eofbit))
+ stream << std::endl;
+ }
+
+ delete[] buf;
+}
+
+
+void
+Log::info(const char *fmt, ...)
+{
+ static const string infoprefix("Info");
+ const string& prefix(do_debug_ ? infoprefix : empty);
+ va_list ap;
+ va_start(ap, fmt);
+
+#ifndef ANDROID
+ static const string& infocolor(isatty(fileno(stdout)) ? terminal_color_cyan : empty);
+ const string& color(do_debug_ ? infocolor : empty);
+ print_prefixed_message(std::cout, color, prefix, fmt, ap);
+#else
+ __android_log_vprint(ANDROID_LOG_INFO, appname_.c_str(), fmt, ap);
+#endif
+
+ if (extra_out_)
+ print_prefixed_message(*extra_out_, empty, prefix, fmt, ap);
+
+ va_end(ap);
+}
+
+void
+Log::debug(const char *fmt, ...)
+{
+ static const string dbgprefix("Debug");
+ if (!do_debug_)
+ return;
+ va_list ap;
+ va_start(ap, fmt);
+
+#ifndef ANDROID
+ static const string& dbgcolor(isatty(fileno(stdout)) ? terminal_color_yellow : empty);
+ print_prefixed_message(std::cout, dbgcolor, dbgprefix, fmt, ap);
+#else
+ __android_log_vprint(ANDROID_LOG_DEBUG, appname_.c_str(), fmt, ap);
+#endif
+
+ if (extra_out_)
+ print_prefixed_message(*extra_out_, empty, dbgprefix, fmt, ap);
+
+ va_end(ap);
+}
+
+void
+Log::error(const char *fmt, ...)
+{
+ static const string errprefix("Error");
+ va_list ap;
+ va_start(ap, fmt);
+
+#ifndef ANDROID
+ static const string& errcolor(isatty(fileno(stderr)) ? terminal_color_red : empty);
+ print_prefixed_message(std::cerr, errcolor, errprefix, fmt, ap);
+#else
+ __android_log_vprint(ANDROID_LOG_ERROR, appname_.c_str(), fmt, ap);
+#endif
+
+ if (extra_out_)
+ print_prefixed_message(*extra_out_, empty, errprefix, fmt, ap);
+
+ va_end(ap);
+}
+
+void
+Log::flush()
+{
+#ifndef ANDROID
+ std::cout.flush();
+ std::cerr.flush();
+#endif
+ if (extra_out_)
+ extra_out_->flush();
+}
diff --git a/src/libmatrix/log.h b/src/libmatrix/log.h
new file mode 100644
index 0000000..9054323
--- /dev/null
+++ b/src/libmatrix/log.h
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2010-2012 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#ifndef LOG_H_
+#define LOG_H_
+
+#include <string>
+#include <iostream>
+
+class Log
+{
+public:
+ static void init(const std::string& appname, bool do_debug = false,
+ std::ostream *extra_out = 0)
+ {
+ appname_ = appname;
+ do_debug_ = do_debug;
+ extra_out_ = extra_out;
+ }
+ // Emit an informational message
+ static void info(const char *fmt, ...);
+ // Emit a debugging message
+ static void debug(const char *fmt, ...);
+ // Emit an error message
+ static void error(const char *fmt, ...);
+ // Explicit flush of the log buffer
+ static void flush();
+ // A prefix constant that informs the logging infrastructure that the log
+ // message is a continuation of a previous log message to be put on the
+ // same line.
+ static const std::string continuation_prefix;
+private:
+ // A constant for identifying the log messages as originating from a
+ // particular application.
+ static std::string appname_;
+ // Indicates whether debug level messages should generate any output
+ static bool do_debug_;
+ // Extra stream to output log messages to
+ static std::ostream *extra_out_;
+};
+
+#endif /* LOG_H_ */
diff --git a/src/libmatrix/mat.cc b/src/libmatrix/mat.cc
new file mode 100644
index 0000000..93ef63c
--- /dev/null
+++ b/src/libmatrix/mat.cc
@@ -0,0 +1,173 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#include <math.h>
+#include "mat.h"
+
+namespace LibMatrix
+{
+namespace Mat4
+{
+
+mat4
+translate(float x, float y, float z)
+{
+ mat4 t;
+ t[0][3] = x;
+ t[1][3] = y;
+ t[2][3] = z;
+ return t;
+}
+
+mat4
+scale(float x, float y, float z)
+{
+ mat4 s;
+ s[0][0] = x;
+ s[1][1] = y;
+ s[2][2] = z;
+ return s;
+}
+
+//
+// As per the OpenGL "red book" definition of rotation, from the appendix
+// on Homogeneous Coordinates and Transformation Matrices, the "upper left"
+// 3x3 portion of the result matrix is formed by:
+//
+// M = uuT + (cos a)(I - uuT) + (sin a)S
+//
+// where u is the normalized input vector, uuT is the outer product of that
+// vector and its transpose, I is the identity matrix and S is the matrix:
+//
+// | 0 -z' y' |
+// | z' 0 -x' |
+// | -y' x' 0 |
+//
+// where x', y' and z' are the elements of u
+//
+mat4
+rotate(float angle, float x, float y, float z)
+{
+ vec3 u(x, y, z);
+ u.normalize();
+ mat3 uuT = outer(u, u);
+ mat3 s;
+ s[0][0] = 0;
+ s[0][1] = -u.z();
+ s[0][2] = u.y();
+ s[1][0] = u.z();
+ s[1][1] = 0;
+ s[1][2] = -u.x();
+ s[2][0] = -u.y();
+ s[2][1] = u.x();
+ s[2][2] = 0;
+ mat3 i;
+ i -= uuT;
+ // degrees to radians
+ float angleRadians(angle * M_PI / 180.0);
+ i *= cos(angleRadians);
+ s *= sin(angleRadians);
+ i += s;
+ mat3 m = uuT + i;
+ mat4 r;
+ r[0][0] = m[0][0];
+ r[0][1] = m[0][1];
+ r[0][2] = m[0][2];
+ r[1][0] = m[1][0];
+ r[1][1] = m[1][1];
+ r[1][2] = m[1][2];
+ r[2][0] = m[2][0];
+ r[2][1] = m[2][1];
+ r[2][2] = m[2][2];
+ return r;
+}
+
+mat4
+frustum(float left, float right, float bottom, float top, float near, float far)
+{
+ float twiceNear(2 * near);
+ float width(right - left);
+ float height(top - bottom);
+ float depth(far - near);
+ mat4 f;
+ f[0][0] = twiceNear / width;
+ f[0][2] = (right + left) / width;
+ f[1][1] = twiceNear / height;
+ f[1][2] = (top + bottom) / height;
+ f[2][2] = -(far + near) / depth;
+ f[2][3] = -(twiceNear * far) / depth;
+ f[3][2] = -1;
+ f[3][3] = 0;
+ return f;
+}
+
+mat4
+ortho(float left, float right, float bottom, float top, float near, float far)
+{
+ float width(right - left);
+ float height(top - bottom);
+ float depth(far - near);
+ mat4 o;
+ o[0][0] = 2 / width;
+ o[0][3] = (right + left) / width;
+ o[1][1] = 2 / height;
+ o[1][3] = (top + bottom) / height;
+ o[2][2] = -2 / depth;
+ o[2][3] = (far + near) / depth;
+ return o;
+}
+
+mat4
+perspective(float fovy, float aspect, float zNear, float zFar)
+{
+ // degrees to radians
+ float fovyRadians(fovy * M_PI / 180.0);
+ // cotangent(x) = 1/tan(x)
+ float f = 1/tan(fovyRadians / 2);
+ float depth(zNear - zFar);
+ mat4 p;
+ p[0][0] = f / aspect;
+ p[1][1] = f;
+ p[2][2] = (zFar + zNear) / depth;
+ p[2][3] = (2 * zFar * zNear) / depth;
+ p[3][2] = -1;
+ p[3][3] = 0;
+ return p;
+}
+
+mat4 lookAt(float eyeX, float eyeY, float eyeZ,
+ float centerX, float centerY, float centerZ,
+ float upX, float upY, float upZ)
+{
+ vec3 f(centerX - eyeX, centerY - eyeY, centerZ - eyeZ);
+ f.normalize();
+ vec3 up(upX, upY, upZ);
+ vec3 s = vec3::cross(f, up);
+ vec3 u = vec3::cross(s, f);
+ s.normalize();
+ u.normalize();
+ mat4 la;
+ la[0][0] = s.x();
+ la[0][1] = s.y();
+ la[0][2] = s.z();
+ la[1][0] = u.x();
+ la[1][1] = u.y();
+ la[1][2] = u.z();
+ la[2][0] = -f.x();
+ la[2][1] = -f.y();
+ la[2][2] = -f.z();
+ la *= translate(-eyeX, -eyeY, -eyeZ);
+ return la;
+}
+
+} // namespace Mat4
+
+} // namespace LibMatrix
diff --git a/src/libmatrix/mat.h b/src/libmatrix/mat.h
new file mode 100644
index 0000000..a55cd45
--- /dev/null
+++ b/src/libmatrix/mat.h
@@ -0,0 +1,1221 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#ifndef MAT_H_
+#define MAT_H_
+#include <stdexcept>
+#include <iostream>
+#include <iomanip>
+#include "vec.h"
+#ifndef USE_EXCEPTIONS
+// If we're not throwing exceptions, we'll need the logger to make sure the
+// caller is informed of errors.
+#include "log.h"
+#endif // USE_EXCEPTIONS
+
+namespace LibMatrix
+{
+// Proxy class for providing the functionality of a doubly-dimensioned array
+// representation of matrices. Each matrix class defines its operator[]
+// to return an ArrayProxy. The ArrayProxy then returns the appropriate item
+// from its operator[].
+template<typename T, unsigned int dimension>
+class ArrayProxy
+{
+public:
+ ArrayProxy(T* data) { data_ = data; }
+ ~ArrayProxy() { data_ = 0; }
+ T& operator[](int index)
+ {
+ return data_[index * dimension];
+ }
+ const T& operator[](int index) const
+ {
+ return data_[index * dimension];
+ }
+private:
+ T* data_;
+};
+
+
+// Programming interfaces to all matrix objects are represented row-centric
+// (i.e. C/C++ style references to the data appear as matrix[row][column]).
+// However, the internal data representation is column-major, so when using
+// the raw data access member to treat the data as a singly-dimensioned array,
+// it does not have to be transposed.
+//
+// A template class for creating, managing and operating on a 2x2 matrix
+// of any type you like (intended for built-in types, but as long as it
+// supports the basic arithmetic and assignment operators, any type should
+// work).
+template<typename T>
+class tmat2
+{
+public:
+ tmat2()
+ {
+ setIdentity();
+ }
+ tmat2(const tmat2& m)
+ {
+ m_[0] = m.m_[0];
+ m_[1] = m.m_[1];
+ m_[2] = m.m_[2];
+ m_[3] = m.m_[3];
+ }
+ tmat2(const T& c0r0, const T& c0r1, const T& c1r0, const T& c1r1)
+ {
+ m_[0] = c0r0;
+ m_[1] = c0r1;
+ m_[2] = c1r0;
+ m_[3] = c1r1;
+ }
+ ~tmat2() {}
+
+ // Reset this to the identity matrix.
+ void setIdentity()
+ {
+ m_[0] = 1;
+ m_[1] = 0;
+ m_[2] = 0;
+ m_[3] = 1;
+ }
+
+ // Transpose this. Return a reference to this.
+ tmat2& transpose()
+ {
+ T tmp_val = m_[1];
+ m_[1] = m_[2];
+ m_[2] = tmp_val;
+ return *this;
+ }
+
+ // Compute the determinant of this and return it.
+ T determinant()
+ {
+ return (m_[0] * m_[3]) - (m_[2] * m_[1]);
+ }
+
+ // Invert this. Return a reference to this.
+ //
+ // NOTE: If this is non-invertible, we will
+ // throw to avoid undefined behavior.
+ tmat2& inverse()
+#ifdef USE_EXCEPTIONS
+ throw(std::runtime_error)
+#endif // USE_EXCEPTIONS
+ {
+ T d(determinant());
+ if (d == static_cast<T>(0))
+ {
+#ifdef USE_EXCEPTIONS
+ throw std::runtime_error("Matrix is noninvertible!!!!");
+#else // !USE_EXCEPTIONS
+ Log::error("Matrix is noninvertible!!!!\n");
+ return *this;
+#endif // USE_EXCEPTIONS
+ }
+ T c0r0(m_[3] / d);
+ T c0r1(-m_[1] / d);
+ T c1r0(-m_[2] / d);
+ T c1r1(m_[0] / d);
+ m_[0] = c0r0;
+ m_[1] = c0r1;
+ m_[2] = c1r0;
+ m_[3] = c1r1;
+ return *this;
+ }
+
+ // Print the elements of the matrix to standard out.
+ // Really only useful for debug and test.
+ void print() const
+ {
+ static const int precision(6);
+ // row 0
+ std::cout << "| ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2];
+ std::cout << " |" << std::endl;
+ // row 1
+ std::cout << "| ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3];
+ std::cout << " |" << std::endl;
+ }
+
+ // Allow raw data access for API calls and the like.
+ // For example, it is valid to pass a tmat2<float> into a call to
+ // the OpenGL command "glUniformMatrix2fv()".
+ operator const T*() const { return &m_[0];}
+
+ // Test if 'rhs' is equal to this.
+ bool operator==(const tmat2& rhs) const
+ {
+ return m_[0] == rhs.m_[0] &&
+ m_[1] == rhs.m_[1] &&
+ m_[2] == rhs.m_[2] &&
+ m_[3] == rhs.m_[3];
+ }
+
+ // Test if 'rhs' is not equal to this.
+ bool operator!=(const tmat2& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ // A direct assignment of 'rhs' to this. Return a reference to this.
+ tmat2& operator=(const tmat2& rhs)
+ {
+ if (this != &rhs)
+ {
+ m_[0] = rhs.m_[0];
+ m_[1] = rhs.m_[1];
+ m_[2] = rhs.m_[2];
+ m_[3] = rhs.m_[3];
+ }
+ return *this;
+ }
+
+ // Add another matrix to this. Return a reference to this.
+ tmat2& operator+=(const tmat2& rhs)
+ {
+ m_[0] += rhs.m_[0];
+ m_[1] += rhs.m_[1];
+ m_[2] += rhs.m_[2];
+ m_[3] += rhs.m_[3];
+ return *this;
+ }
+
+ // Add another matrix to a copy of this. Return the copy.
+ const tmat2 operator+(const tmat2& rhs)
+ {
+ return tmat2(*this) += rhs;
+ }
+
+ // Subtract another matrix from this. Return a reference to this.
+ tmat2& operator-=(const tmat2& rhs)
+ {
+ m_[0] -= rhs.m_[0];
+ m_[1] -= rhs.m_[1];
+ m_[2] -= rhs.m_[2];
+ m_[3] -= rhs.m_[3];
+ return *this;
+ }
+
+ // Subtract another matrix from a copy of this. Return the copy.
+ const tmat2 operator-(const tmat2& rhs)
+ {
+ return tmat2(*this) += rhs;
+ }
+
+ // Multiply this by another matrix. Return a reference to this.
+ tmat2& operator*=(const tmat2& rhs)
+ {
+ T c0r0((m_[0] * rhs.m_[0]) + (m_[2] * rhs.m_[1]));
+ T c0r1((m_[1] * rhs.m_[0]) + (m_[3] * rhs.m_[1]));
+ T c1r0((m_[0] * rhs.m_[2]) + (m_[2] * rhs.m_[3]));
+ T c1r1((m_[1] * rhs.m_[2]) + (m_[3] * rhs.m_[3]));
+ m_[0] = c0r0;
+ m_[1] = c0r1;
+ m_[2] = c1r0;
+ m_[3] = c1r1;
+ return *this;
+ }
+
+ // Multiply a copy of this by another matrix. Return the copy.
+ const tmat2 operator*(const tmat2& rhs)
+ {
+ return tmat2(*this) *= rhs;
+ }
+
+ // Multiply this by a scalar. Return a reference to this.
+ tmat2& operator*=(const T& rhs)
+ {
+ m_[0] *= rhs;
+ m_[1] *= rhs;
+ m_[2] *= rhs;
+ m_[3] *= rhs;
+ return *this;
+ }
+
+ // Multiply a copy of this by a scalar. Return the copy.
+ const tmat2 operator*(const T& rhs)
+ {
+ return tmat2(*this) *= rhs;
+ }
+
+ // Divide this by a scalar. Return a reference to this.
+ tmat2& operator/=(const T& rhs)
+ {
+ m_[0] /= rhs;
+ m_[1] /= rhs;
+ m_[2] /= rhs;
+ m_[3] /= rhs;
+ return *this;
+ }
+
+ // Divide a copy of this by a scalar. Return the copy.
+ const tmat2 operator/(const T& rhs)
+ {
+ return tmat2(*this) /= rhs;
+ }
+
+ // Use an instance of the ArrayProxy class to support double-indexed
+ // references to a matrix (i.e., m[1][1]). See comments above the
+ // ArrayProxy definition for more details.
+ ArrayProxy<T, 2> operator[](int index)
+ {
+ return ArrayProxy<T, 2>(&m_[index]);
+ }
+ const ArrayProxy<T, 2> operator[](int index) const
+ {
+ return ArrayProxy<T, 2>(const_cast<T*>(&m_[index]));
+ }
+
+private:
+ T m_[4];
+};
+
+// Multiply a scalar and a matrix just like the member operator, but allow
+// the scalar to be the left-hand operand.
+template<typename T>
+const tmat2<T> operator*(const T& lhs, const tmat2<T>& rhs)
+{
+ return tmat2<T>(rhs) * lhs;
+}
+
+// Multiply a copy of a vector and a matrix (matrix is right-hand operand).
+// Return the copy.
+template<typename T>
+const tvec2<T> operator*(const tvec2<T>& lhs, const tmat2<T>& rhs)
+{
+ T x((lhs.x() * rhs[0][0]) + (lhs.y() * rhs[1][0]));
+ T y((lhs.x() * rhs[0][1]) + (lhs.y() * rhs[1][1]));
+ return tvec2<T>(x,y);
+}
+
+// Multiply a copy of a vector and a matrix (matrix is left-hand operand).
+// Return the copy.
+template<typename T>
+const tvec2<T> operator*(const tmat2<T>& lhs, const tvec2<T>& rhs)
+{
+ T x((lhs[0][0] * rhs.x()) + (lhs[0][1] * rhs.y()));
+ T y((lhs[1][0] * rhs.x()) + (lhs[1][1] * rhs.y()));
+ return tvec2<T>(x, y);
+}
+
+// Compute the outer product of two vectors. Return the resultant matrix.
+template<typename T>
+const tmat2<T> outer(const tvec2<T>& a, const tvec2<T>& b)
+{
+ tmat2<T> product;
+ product[0][0] = a.x() * b.x();
+ product[0][1] = a.x() * b.y();
+ product[1][0] = a.y() * b.x();
+ product[1][1] = a.y() * b.y();
+ return product;
+}
+
+// A template class for creating, managing and operating on a 3x3 matrix
+// of any type you like (intended for built-in types, but as long as it
+// supports the basic arithmetic and assignment operators, any type should
+// work).
+template<typename T>
+class tmat3
+{
+public:
+ tmat3()
+ {
+ setIdentity();
+ }
+ tmat3(const tmat3& m)
+ {
+ m_[0] = m.m_[0];
+ m_[1] = m.m_[1];
+ m_[2] = m.m_[2];
+ m_[3] = m.m_[3];
+ m_[4] = m.m_[4];
+ m_[5] = m.m_[5];
+ m_[6] = m.m_[6];
+ m_[7] = m.m_[7];
+ m_[8] = m.m_[8];
+ }
+ tmat3(const T& c0r0, const T& c0r1, const T& c0r2,
+ const T& c1r0, const T& c1r1, const T& c1r2,
+ const T& c2r0, const T& c2r1, const T& c2r2)
+ {
+ m_[0] = c0r0;
+ m_[1] = c0r1;
+ m_[2] = c0r2;
+ m_[3] = c1r0;
+ m_[4] = c1r1;
+ m_[5] = c1r2;
+ m_[6] = c2r0;
+ m_[7] = c2r1;
+ m_[8] = c2r2;
+ }
+ ~tmat3() {}
+
+ // Reset this to the identity matrix.
+ void setIdentity()
+ {
+ m_[0] = 1;
+ m_[1] = 0;
+ m_[2] = 0;
+ m_[3] = 0;
+ m_[4] = 1;
+ m_[5] = 0;
+ m_[6] = 0;
+ m_[7] = 0;
+ m_[8] = 1;
+ }
+
+ // Transpose this. Return a reference to this.
+ tmat3& transpose()
+ {
+ T tmp_val = m_[1];
+ m_[1] = m_[3];
+ m_[3] = tmp_val;
+ tmp_val = m_[2];
+ m_[2] = m_[6];
+ m_[6] = tmp_val;
+ tmp_val = m_[5];
+ m_[5] = m_[7];
+ m_[7] = tmp_val;
+ return *this;
+ }
+
+ // Compute the determinant of this and return it.
+ T determinant()
+ {
+ tmat2<T> minor0(m_[4], m_[5], m_[7], m_[8]);
+ tmat2<T> minor3(m_[1], m_[2], m_[7], m_[8]);
+ tmat2<T> minor6(m_[1], m_[2], m_[4], m_[5]);
+ return (m_[0] * minor0.determinant()) -
+ (m_[3] * minor3.determinant()) +
+ (m_[6] * minor6.determinant());
+ }
+
+ // Invert this. Return a reference to this.
+ //
+ // NOTE: If this is non-invertible, we will
+ // throw to avoid undefined behavior.
+ tmat3& inverse()
+#ifdef USE_EXCEPTIONS
+ throw(std::runtime_error)
+#endif // USE_EXCEPTIONS
+ {
+ T d(determinant());
+ if (d == static_cast<T>(0))
+ {
+#ifdef USE_EXCEPTIONS
+ throw std::runtime_error("Matrix is noninvertible!!!!");
+#else // !USE_EXCEPTIONS
+ Log::error("Matrix is noninvertible!!!!\n");
+ return *this;
+#endif // USE_EXCEPTIONS
+ }
+ tmat2<T> minor0(m_[4], m_[5], m_[7], m_[8]);
+ tmat2<T> minor1(m_[7], m_[8], m_[1], m_[2]);
+ tmat2<T> minor2(m_[1], m_[2], m_[4], m_[5]);
+ tmat2<T> minor3(m_[6], m_[8], m_[3], m_[5]);
+ tmat2<T> minor4(m_[0], m_[2], m_[6], m_[8]);
+ tmat2<T> minor5(m_[3], m_[5], m_[0], m_[2]);
+ tmat2<T> minor6(m_[3], m_[4], m_[6], m_[7]);
+ tmat2<T> minor7(m_[6], m_[7], m_[0], m_[1]);
+ tmat2<T> minor8(m_[0], m_[1], m_[3], m_[4]);
+ m_[0] = minor0.determinant() / d;
+ m_[1] = minor1.determinant() / d;
+ m_[2] = minor2.determinant() / d;
+ m_[3] = minor3.determinant() / d;
+ m_[4] = minor4.determinant() / d;
+ m_[5] = minor5.determinant() / d;
+ m_[6] = minor6.determinant() / d;
+ m_[7] = minor7.determinant() / d;
+ m_[8] = minor8.determinant() / d;
+ return *this;
+ }
+
+ // Print the elements of the matrix to standard out.
+ // Really only useful for debug and test.
+ void print() const
+ {
+ static const int precision(6);
+ // row 0
+ std::cout << "| ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[6];
+ std::cout << " |" << std::endl;
+ // row 1
+ std::cout << "| ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[4];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[7];
+ std::cout << " |" << std::endl;
+ // row 2
+ std::cout << "| ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[5];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[8];
+ std::cout << " |" << std::endl;
+ }
+
+ // Allow raw data access for API calls and the like.
+ // For example, it is valid to pass a tmat3<float> into a call to
+ // the OpenGL command "glUniformMatrix3fv()".
+ operator const T*() const { return &m_[0];}
+
+ // Test if 'rhs' is equal to this.
+ bool operator==(const tmat3& rhs) const
+ {
+ return m_[0] == rhs.m_[0] &&
+ m_[1] == rhs.m_[1] &&
+ m_[2] == rhs.m_[2] &&
+ m_[3] == rhs.m_[3] &&
+ m_[4] == rhs.m_[4] &&
+ m_[5] == rhs.m_[5] &&
+ m_[6] == rhs.m_[6] &&
+ m_[7] == rhs.m_[7] &&
+ m_[8] == rhs.m_[8];
+ }
+
+ // Test if 'rhs' is not equal to this.
+ bool operator!=(const tmat3& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ // A direct assignment of 'rhs' to this. Return a reference to this.
+ tmat3& operator=(const tmat3& rhs)
+ {
+ if (this != &rhs)
+ {
+ m_[0] = rhs.m_[0];
+ m_[1] = rhs.m_[1];
+ m_[2] = rhs.m_[2];
+ m_[3] = rhs.m_[3];
+ m_[4] = rhs.m_[4];
+ m_[5] = rhs.m_[5];
+ m_[6] = rhs.m_[6];
+ m_[7] = rhs.m_[7];
+ m_[8] = rhs.m_[8];
+ }
+ return *this;
+ }
+
+ // Add another matrix to this. Return a reference to this.
+ tmat3& operator+=(const tmat3& rhs)
+ {
+ m_[0] += rhs.m_[0];
+ m_[1] += rhs.m_[1];
+ m_[2] += rhs.m_[2];
+ m_[3] += rhs.m_[3];
+ m_[4] += rhs.m_[4];
+ m_[5] += rhs.m_[5];
+ m_[6] += rhs.m_[6];
+ m_[7] += rhs.m_[7];
+ m_[8] += rhs.m_[8];
+ return *this;
+ }
+
+ // Add another matrix to a copy of this. Return the copy.
+ const tmat3 operator+(const tmat3& rhs)
+ {
+ return tmat3(*this) += rhs;
+ }
+
+ // Subtract another matrix from this. Return a reference to this.
+ tmat3& operator-=(const tmat3& rhs)
+ {
+ m_[0] -= rhs.m_[0];
+ m_[1] -= rhs.m_[1];
+ m_[2] -= rhs.m_[2];
+ m_[3] -= rhs.m_[3];
+ m_[4] -= rhs.m_[4];
+ m_[5] -= rhs.m_[5];
+ m_[6] -= rhs.m_[6];
+ m_[7] -= rhs.m_[7];
+ m_[8] -= rhs.m_[8];
+ return *this;
+ }
+
+ // Subtract another matrix from a copy of this. Return the copy.
+ const tmat3 operator-(const tmat3& rhs)
+ {
+ return tmat3(*this) -= rhs;
+ }
+
+ // Multiply this by another matrix. Return a reference to this.
+ tmat3& operator*=(const tmat3& rhs)
+ {
+ T c0r0((m_[0] * rhs.m_[0]) + (m_[3] * rhs.m_[1]) + (m_[6] * rhs.m_[2]));
+ T c0r1((m_[1] * rhs.m_[0]) + (m_[4] * rhs.m_[1]) + (m_[7] * rhs.m_[2]));
+ T c0r2((m_[2] * rhs.m_[0]) + (m_[5] * rhs.m_[1]) + (m_[8] * rhs.m_[2]));
+ T c1r0((m_[0] * rhs.m_[3]) + (m_[3] * rhs.m_[4]) + (m_[6] * rhs.m_[5]));
+ T c1r1((m_[1] * rhs.m_[3]) + (m_[4] * rhs.m_[4]) + (m_[7] * rhs.m_[5]));
+ T c1r2((m_[2] * rhs.m_[3]) + (m_[5] * rhs.m_[4]) + (m_[8] * rhs.m_[5]));
+ T c2r0((m_[0] * rhs.m_[6]) + (m_[3] * rhs.m_[7]) + (m_[6] * rhs.m_[8]));
+ T c2r1((m_[1] * rhs.m_[6]) + (m_[4] * rhs.m_[7]) + (m_[7] * rhs.m_[8]));
+ T c2r2((m_[2] * rhs.m_[6]) + (m_[5] * rhs.m_[7]) + (m_[8] * rhs.m_[8]));
+ m_[0] = c0r0;
+ m_[1] = c0r1;
+ m_[2] = c0r2;
+ m_[3] = c1r0;
+ m_[4] = c1r1;
+ m_[5] = c1r2;
+ m_[6] = c2r0;
+ m_[7] = c2r1;
+ m_[8] = c2r2;
+ return *this;
+ }
+
+ // Multiply a copy of this by another matrix. Return the copy.
+ const tmat3 operator*(const tmat3& rhs)
+ {
+ return tmat3(*this) *= rhs;
+ }
+
+ // Multiply this by a scalar. Return a reference to this.
+ tmat3& operator*=(const T& rhs)
+ {
+ m_[0] *= rhs;
+ m_[1] *= rhs;
+ m_[2] *= rhs;
+ m_[3] *= rhs;
+ m_[4] *= rhs;
+ m_[5] *= rhs;
+ m_[6] *= rhs;
+ m_[7] *= rhs;
+ m_[8] *= rhs;
+ return *this;
+ }
+
+ // Multiply a copy of this by a scalar. Return the copy.
+ const tmat3 operator*(const T& rhs)
+ {
+ return tmat3(*this) *= rhs;
+ }
+
+ // Divide this by a scalar. Return a reference to this.
+ tmat3& operator/=(const T& rhs)
+ {
+ m_[0] /= rhs;
+ m_[1] /= rhs;
+ m_[2] /= rhs;
+ m_[3] /= rhs;
+ m_[4] /= rhs;
+ m_[5] /= rhs;
+ m_[6] /= rhs;
+ m_[7] /= rhs;
+ m_[8] /= rhs;
+ return *this;
+ }
+
+ // Divide a copy of this by a scalar. Return the copy.
+ const tmat3 operator/(const T& rhs)
+ {
+ return tmat3(*this) /= rhs;
+ }
+
+ // Use an instance of the ArrayProxy class to support double-indexed
+ // references to a matrix (i.e., m[1][1]). See comments above the
+ // ArrayProxy definition for more details.
+ ArrayProxy<T, 3> operator[](int index)
+ {
+ return ArrayProxy<T, 3>(&m_[index]);
+ }
+ const ArrayProxy<T, 3> operator[](int index) const
+ {
+ return ArrayProxy<T, 3>(const_cast<T*>(&m_[index]));
+ }
+
+private:
+ T m_[9];
+};
+
+// Multiply a scalar and a matrix just like the member operator, but allow
+// the scalar to be the left-hand operand.
+template<typename T>
+const tmat3<T> operator*(const T& lhs, const tmat3<T>& rhs)
+{
+ return tmat3<T>(rhs) * lhs;
+}
+
+// Multiply a copy of a vector and a matrix (matrix is right-hand operand).
+// Return the copy.
+template<typename T>
+const tvec3<T> operator*(const tvec3<T>& lhs, const tmat3<T>& rhs)
+{
+ T x((lhs.x() * rhs[0][0]) + (lhs.y() * rhs[1][0]) + (lhs.z() * rhs[2][0]));
+ T y((lhs.x() * rhs[0][1]) + (lhs.y() * rhs[1][1]) + (lhs.z() * rhs[2][1]));
+ T z((lhs.x() * rhs[0][2]) + (lhs.y() * rhs[1][2]) + (lhs.z() * rhs[2][2]));
+ return tvec3<T>(x, y, z);
+}
+
+// Multiply a copy of a vector and a matrix (matrix is left-hand operand).
+// Return the copy.
+template<typename T>
+const tvec3<T> operator*(const tmat3<T>& lhs, const tvec3<T>& rhs)
+{
+ T x((lhs[0][0] * rhs.x()) + (lhs[0][1] * rhs.y()) + (lhs[0][2] * rhs.z()));
+ T y((lhs[1][0] * rhs.x()) + (lhs[1][1] * rhs.y()) + (lhs[1][2] * rhs.z()));
+ T z((lhs[2][0] * rhs.x()) + (lhs[2][1] * rhs.y()) + (lhs[2][2] * rhs.z()));
+ return tvec3<T>(x, y, z);
+}
+
+// Compute the outer product of two vectors. Return the resultant matrix.
+template<typename T>
+const tmat3<T> outer(const tvec3<T>& a, const tvec3<T>& b)
+{
+ tmat3<T> product;
+ product[0][0] = a.x() * b.x();
+ product[0][1] = a.x() * b.y();
+ product[0][2] = a.x() * b.z();
+ product[1][0] = a.y() * b.x();
+ product[1][1] = a.y() * b.y();
+ product[1][2] = a.y() * b.z();
+ product[2][0] = a.z() * b.x();
+ product[2][1] = a.z() * b.y();
+ product[2][2] = a.z() * b.z();
+ return product;
+}
+
+// A template class for creating, managing and operating on a 4x4 matrix
+// of any type you like (intended for built-in types, but as long as it
+// supports the basic arithmetic and assignment operators, any type should
+// work).
+template<typename T>
+class tmat4
+{
+public:
+ tmat4()
+ {
+ setIdentity();
+ }
+ tmat4(const tmat4& m)
+ {
+ m_[0] = m.m_[0];
+ m_[1] = m.m_[1];
+ m_[2] = m.m_[2];
+ m_[3] = m.m_[3];
+ m_[4] = m.m_[4];
+ m_[5] = m.m_[5];
+ m_[6] = m.m_[6];
+ m_[7] = m.m_[7];
+ m_[8] = m.m_[8];
+ m_[9] = m.m_[9];
+ m_[10] = m.m_[10];
+ m_[11] = m.m_[11];
+ m_[12] = m.m_[12];
+ m_[13] = m.m_[13];
+ m_[14] = m.m_[14];
+ m_[15] = m.m_[15];
+ }
+ ~tmat4() {}
+
+ // Reset this to the identity matrix.
+ void setIdentity()
+ {
+ m_[0] = 1;
+ m_[1] = 0;
+ m_[2] = 0;
+ m_[3] = 0;
+ m_[4] = 0;
+ m_[5] = 1;
+ m_[6] = 0;
+ m_[7] = 0;
+ m_[8] = 0;
+ m_[9] = 0;
+ m_[10] = 1;
+ m_[11] = 0;
+ m_[12] = 0;
+ m_[13] = 0;
+ m_[14] = 0;
+ m_[15] = 1;
+ }
+
+ // Transpose this. Return a reference to this.
+ tmat4& transpose()
+ {
+ T tmp_val = m_[1];
+ m_[1] = m_[4];
+ m_[4] = tmp_val;
+ tmp_val = m_[2];
+ m_[2] = m_[8];
+ m_[8] = tmp_val;
+ tmp_val = m_[3];
+ m_[3] = m_[12];
+ m_[12] = tmp_val;
+ tmp_val = m_[6];
+ m_[6] = m_[9];
+ m_[9] = tmp_val;
+ tmp_val = m_[7];
+ m_[7] = m_[13];
+ m_[13] = tmp_val;
+ tmp_val = m_[11];
+ m_[11] = m_[14];
+ m_[14] = tmp_val;
+ return *this;
+ }
+
+ // Compute the determinant of this and return it.
+ T determinant()
+ {
+ tmat3<T> minor0(m_[5], m_[6], m_[7], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]);
+ tmat3<T> minor4(m_[1], m_[2], m_[3], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]);
+ tmat3<T> minor8(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[13], m_[14], m_[15]);
+ tmat3<T> minor12(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[9], m_[10], m_[11]);
+ return (m_[0] * minor0.determinant()) -
+ (m_[4] * minor4.determinant()) +
+ (m_[8] * minor8.determinant()) -
+ (m_[12] * minor12.determinant());
+ }
+
+ // Invert this. Return a reference to this.
+ //
+ // NOTE: If this is non-invertible, we will
+ // throw to avoid undefined behavior.
+ tmat4& inverse()
+#ifdef USE_EXCEPTIONS
+ throw(std::runtime_error)
+#endif // USE_EXCEPTIONS
+ {
+ T d(determinant());
+ if (d == static_cast<T>(0))
+ {
+#ifdef USE_EXCEPTIONS
+ throw std::runtime_error("Matrix is noninvertible!!!!");
+#else // !USE_EXCEPTIONS
+ Log::error("Matrix is noninvertible!!!!\n");
+ return *this;
+#endif // USE_EXCEPTIONS
+ }
+ tmat3<T> minor0(m_[5], m_[6], m_[7], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]);
+ tmat3<T> minor1(m_[1], m_[2], m_[3], m_[13], m_[14], m_[15], m_[9], m_[10], m_[11]);
+ tmat3<T> minor2(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[13], m_[14], m_[15]);
+ tmat3<T> minor3(m_[1], m_[2], m_[3], m_[9], m_[10], m_[11], m_[5], m_[6], m_[7]);
+
+ tmat3<T> minor4(m_[4], m_[6], m_[7], m_[12], m_[14], m_[15], m_[8], m_[10], m_[11]);
+ tmat3<T> minor5(m_[0], m_[2], m_[3], m_[8], m_[10], m_[11], m_[12], m_[14], m_[15]);
+ tmat3<T> minor6(m_[0], m_[2], m_[3], m_[12], m_[14], m_[15], m_[4], m_[6], m_[7]);
+ tmat3<T> minor7(m_[0], m_[2], m_[3], m_[4], m_[6], m_[7], m_[8], m_[10], m_[11]);
+
+ tmat3<T> minor8(m_[4], m_[5], m_[7], m_[8], m_[9], m_[11], m_[12], m_[13], m_[15]);
+ tmat3<T> minor9(m_[0], m_[1], m_[3], m_[12], m_[13], m_[15], m_[8], m_[9], m_[11]);
+ tmat3<T> minor10(m_[0], m_[1], m_[3], m_[4], m_[5], m_[7], m_[12], m_[13], m_[15]);
+ tmat3<T> minor11(m_[0], m_[1], m_[3], m_[8], m_[9], m_[11], m_[4], m_[5], m_[7]);
+
+ tmat3<T> minor12(m_[4], m_[5], m_[6], m_[12], m_[13], m_[14], m_[8], m_[9], m_[10]);
+ tmat3<T> minor13(m_[0], m_[1], m_[2], m_[8], m_[9], m_[10], m_[12], m_[13], m_[14]);
+ tmat3<T> minor14(m_[0], m_[1], m_[2], m_[12], m_[13], m_[14], m_[4], m_[5], m_[6]);
+ tmat3<T> minor15(m_[0], m_[1], m_[2], m_[4], m_[5], m_[6], m_[8], m_[9], m_[10]);
+ m_[0] = minor0.determinant() / d;
+ m_[1] = minor1.determinant() / d;
+ m_[2] = minor2.determinant() / d;
+ m_[3] = minor3.determinant() / d;
+ m_[4] = minor4.determinant() / d;
+ m_[5] = minor5.determinant() / d;
+ m_[6] = minor6.determinant() / d;
+ m_[7] = minor7.determinant() / d;
+ m_[8] = minor8.determinant() / d;
+ m_[9] = minor9.determinant() / d;
+ m_[10] = minor10.determinant() / d;
+ m_[11] = minor11.determinant() / d;
+ m_[12] = minor12.determinant() / d;
+ m_[13] = minor13.determinant() / d;
+ m_[14] = minor14.determinant() / d;
+ m_[15] = minor15.determinant() / d;
+ return *this;
+ }
+
+ // Print the elements of the matrix to standard out.
+ // Really only useful for debug and test.
+ void print() const
+ {
+ static const int precision(6);
+ // row 0
+ std::cout << "| ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[4];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[8];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[12];
+ std::cout << " |" << std::endl;
+ // row 1
+ std::cout << "| ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[5];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[9];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[13];
+ std::cout << " |" << std::endl;
+ // row 2
+ std::cout << "| ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[6];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[10];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[14];
+ std::cout << " |" << std::endl;
+ // row 3
+ std::cout << "| ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[7];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[11];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[15];
+ std::cout << " |" << std::endl;
+ }
+
+ // Allow raw data access for API calls and the like.
+ // For example, it is valid to pass a tmat4<float> into a call to
+ // the OpenGL command "glUniformMatrix4fv()".
+ operator const T*() const { return &m_[0];}
+
+ // Test if 'rhs' is equal to this.
+ bool operator==(const tmat4& rhs) const
+ {
+ return m_[0] == rhs.m_[0] &&
+ m_[1] == rhs.m_[1] &&
+ m_[2] == rhs.m_[2] &&
+ m_[3] == rhs.m_[3] &&
+ m_[4] == rhs.m_[4] &&
+ m_[5] == rhs.m_[5] &&
+ m_[6] == rhs.m_[6] &&
+ m_[7] == rhs.m_[7] &&
+ m_[8] == rhs.m_[8] &&
+ m_[9] == rhs.m_[9] &&
+ m_[10] == rhs.m_[10] &&
+ m_[11] == rhs.m_[11] &&
+ m_[12] == rhs.m_[12] &&
+ m_[13] == rhs.m_[13] &&
+ m_[14] == rhs.m_[14] &&
+ m_[15] == rhs.m_[15];
+ }
+
+ // Test if 'rhs' is not equal to this.
+ bool operator!=(const tmat4& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ // A direct assignment of 'rhs' to this. Return a reference to this.
+ tmat4& operator=(const tmat4& rhs)
+ {
+ if (this != &rhs)
+ {
+ m_[0] = rhs.m_[0];
+ m_[1] = rhs.m_[1];
+ m_[2] = rhs.m_[2];
+ m_[3] = rhs.m_[3];
+ m_[4] = rhs.m_[4];
+ m_[5] = rhs.m_[5];
+ m_[6] = rhs.m_[6];
+ m_[7] = rhs.m_[7];
+ m_[8] = rhs.m_[8];
+ m_[9] = rhs.m_[9];
+ m_[10] = rhs.m_[10];
+ m_[11] = rhs.m_[11];
+ m_[12] = rhs.m_[12];
+ m_[13] = rhs.m_[13];
+ m_[14] = rhs.m_[14];
+ m_[15] = rhs.m_[15];
+ }
+ return *this;
+ }
+
+ // Add another matrix to this. Return a reference to this.
+ tmat4& operator+=(const tmat4& rhs)
+ {
+ m_[0] += rhs.m_[0];
+ m_[1] += rhs.m_[1];
+ m_[2] += rhs.m_[2];
+ m_[3] += rhs.m_[3];
+ m_[4] += rhs.m_[4];
+ m_[5] += rhs.m_[5];
+ m_[6] += rhs.m_[6];
+ m_[7] += rhs.m_[7];
+ m_[8] += rhs.m_[8];
+ m_[9] += rhs.m_[9];
+ m_[10] += rhs.m_[10];
+ m_[11] += rhs.m_[11];
+ m_[12] += rhs.m_[12];
+ m_[13] += rhs.m_[13];
+ m_[14] += rhs.m_[14];
+ m_[15] += rhs.m_[15];
+ return *this;
+ }
+
+ // Add another matrix to a copy of this. Return the copy.
+ const tmat4 operator+(const tmat4& rhs)
+ {
+ return tmat4(*this) += rhs;
+ }
+
+ // Subtract another matrix from this. Return a reference to this.
+ tmat4& operator-=(const tmat4& rhs)
+ {
+ m_[0] -= rhs.m_[0];
+ m_[1] -= rhs.m_[1];
+ m_[2] -= rhs.m_[2];
+ m_[3] -= rhs.m_[3];
+ m_[4] -= rhs.m_[4];
+ m_[5] -= rhs.m_[5];
+ m_[6] -= rhs.m_[6];
+ m_[7] -= rhs.m_[7];
+ m_[8] -= rhs.m_[8];
+ m_[9] -= rhs.m_[9];
+ m_[10] -= rhs.m_[10];
+ m_[11] -= rhs.m_[11];
+ m_[12] -= rhs.m_[12];
+ m_[13] -= rhs.m_[13];
+ m_[14] -= rhs.m_[14];
+ m_[15] -= rhs.m_[15];
+ return *this;
+ }
+
+ // Subtract another matrix from a copy of this. Return the copy.
+ const tmat4 operator-(const tmat4& rhs)
+ {
+ return tmat4(*this) -= rhs;
+ }
+
+ // Multiply this by another matrix. Return a reference to this.
+ tmat4& operator*=(const tmat4& rhs)
+ {
+ T c0r0((m_[0] * rhs.m_[0]) + (m_[4] * rhs.m_[1]) + (m_[8] * rhs.m_[2]) + (m_[12] * rhs.m_[3]));
+ T c0r1((m_[1] * rhs.m_[0]) + (m_[5] * rhs.m_[1]) + (m_[9] * rhs.m_[2]) + (m_[13] * rhs.m_[3]));
+ T c0r2((m_[2] * rhs.m_[0]) + (m_[6] * rhs.m_[1]) + (m_[10] * rhs.m_[2]) + (m_[14] * rhs.m_[3]));
+ T c0r3((m_[3] * rhs.m_[0]) + (m_[7] * rhs.m_[1]) + (m_[11] * rhs.m_[2]) + (m_[15] * rhs.m_[3]));
+ T c1r0((m_[0] * rhs.m_[4]) + (m_[4] * rhs.m_[5]) + (m_[8] * rhs.m_[6]) + (m_[12] * rhs.m_[7]));
+ T c1r1((m_[1] * rhs.m_[4]) + (m_[5] * rhs.m_[5]) + (m_[9] * rhs.m_[6]) + (m_[13] * rhs.m_[7]));
+ T c1r2((m_[2] * rhs.m_[4]) + (m_[6] * rhs.m_[5]) + (m_[10] * rhs.m_[6]) + (m_[14] * rhs.m_[7]));
+ T c1r3((m_[3] * rhs.m_[4]) + (m_[7] * rhs.m_[5]) + (m_[11] * rhs.m_[6]) + (m_[15] * rhs.m_[7]));
+ T c2r0((m_[0] * rhs.m_[8]) + (m_[4] * rhs.m_[9]) + (m_[8] * rhs.m_[10]) + (m_[12] * rhs.m_[11]));
+ T c2r1((m_[1] * rhs.m_[8]) + (m_[5] * rhs.m_[9]) + (m_[9] * rhs.m_[10]) + (m_[13] * rhs.m_[11]));
+ T c2r2((m_[2] * rhs.m_[8]) + (m_[6] * rhs.m_[9]) + (m_[10] * rhs.m_[10]) + (m_[14] * rhs.m_[11]));
+ T c2r3((m_[3] * rhs.m_[8]) + (m_[7] * rhs.m_[9]) + (m_[11] * rhs.m_[10]) + (m_[15] * rhs.m_[11]));
+ T c3r0((m_[0] * rhs.m_[12]) + (m_[4] * rhs.m_[13]) + (m_[8] * rhs.m_[14]) + (m_[12] * rhs.m_[15]));
+ T c3r1((m_[1] * rhs.m_[12]) + (m_[5] * rhs.m_[13]) + (m_[9] * rhs.m_[14]) + (m_[13] * rhs.m_[15]));
+ T c3r2((m_[2] * rhs.m_[12]) + (m_[6] * rhs.m_[13]) + (m_[10] * rhs.m_[14]) + (m_[14] * rhs.m_[15]));
+ T c3r3((m_[3] * rhs.m_[12]) + (m_[7] * rhs.m_[13]) + (m_[11] * rhs.m_[14]) + (m_[15] * rhs.m_[15]));
+ m_[0] = c0r0;
+ m_[1] = c0r1;
+ m_[2] = c0r2;
+ m_[3] = c0r3;
+ m_[4] = c1r0;
+ m_[5] = c1r1;
+ m_[6] = c1r2;
+ m_[7] = c1r3;
+ m_[8] = c2r0;
+ m_[9] = c2r1;
+ m_[10] = c2r2;
+ m_[11] = c2r3;
+ m_[12] = c3r0;
+ m_[13] = c3r1;
+ m_[14] = c3r2;
+ m_[15] = c3r3;
+ return *this;
+ }
+
+ // Multiply a copy of this by another matrix. Return the copy.
+ const tmat4 operator*(const tmat4& rhs)
+ {
+ return tmat4(*this) *= rhs;
+ }
+
+ // Multiply this by a scalar. Return a reference to this.
+ tmat4& operator*=(const T& rhs)
+ {
+ m_[0] *= rhs;
+ m_[1] *= rhs;
+ m_[2] *= rhs;
+ m_[3] *= rhs;
+ m_[4] *= rhs;
+ m_[5] *= rhs;
+ m_[6] *= rhs;
+ m_[7] *= rhs;
+ m_[8] *= rhs;
+ m_[9] *= rhs;
+ m_[10] *= rhs;
+ m_[11] *= rhs;
+ m_[12] *= rhs;
+ m_[13] *= rhs;
+ m_[14] *= rhs;
+ m_[15] *= rhs;
+ return *this;
+ }
+
+ // Multiply a copy of this by a scalar. Return the copy.
+ const tmat4 operator*(const T& rhs)
+ {
+ return tmat4(*this) *= rhs;
+ }
+
+ // Divide this by a scalar. Return a reference to this.
+ tmat4& operator/=(const T& rhs)
+ {
+ m_[0] /= rhs;
+ m_[1] /= rhs;
+ m_[2] /= rhs;
+ m_[3] /= rhs;
+ m_[4] /= rhs;
+ m_[5] /= rhs;
+ m_[6] /= rhs;
+ m_[7] /= rhs;
+ m_[8] /= rhs;
+ m_[9] /= rhs;
+ m_[10] /= rhs;
+ m_[11] /= rhs;
+ m_[12] /= rhs;
+ m_[13] /= rhs;
+ m_[14] /= rhs;
+ m_[15] /= rhs;
+ return *this;
+ }
+
+ // Divide a copy of this by a scalar. Return the copy.
+ const tmat4 operator/(const T& rhs)
+ {
+ return tmat4(*this) /= rhs;
+ }
+
+ // Use an instance of the ArrayProxy class to support double-indexed
+ // references to a matrix (i.e., m[1][1]). See comments above the
+ // ArrayProxy definition for more details.
+ ArrayProxy<T, 4> operator[](int index)
+ {
+ return ArrayProxy<T, 4>(&m_[index]);
+ }
+ const ArrayProxy<T, 4> operator[](int index) const
+ {
+ return ArrayProxy<T, 4>(const_cast<T*>(&m_[index]));
+ }
+
+private:
+ T m_[16];
+};
+
+// Multiply a scalar and a matrix just like the member operator, but allow
+// the scalar to be the left-hand operand.
+template<typename T>
+const tmat4<T> operator*(const T& lhs, const tmat4<T>& rhs)
+{
+ return tmat4<T>(rhs) * lhs;
+}
+
+// Multiply a copy of a vector and a matrix (matrix is right-hand operand).
+// Return the copy.
+template<typename T>
+const tvec4<T> operator*(const tvec4<T>& lhs, const tmat4<T>& rhs)
+{
+ T x((lhs.x() * rhs[0][0]) + (lhs.y() * rhs[1][0]) + (lhs.z() * rhs[2][0]) + (lhs.w() * rhs[3][0]));
+ T y((lhs.x() * rhs[0][1]) + (lhs.y() * rhs[1][1]) + (lhs.z() * rhs[2][1]) + (lhs.w() * rhs[3][1]));
+ T z((lhs.x() * rhs[0][2]) + (lhs.y() * rhs[1][2]) + (lhs.z() * rhs[2][2]) + (lhs.w() * rhs[3][2]));
+ T w((lhs.x() * rhs[0][3]) + (lhs.y() * rhs[1][3]) + (lhs.z() * rhs[2][3]) + (lhs.w() * rhs[3][3]));
+ return tvec4<T>(x, y, z, w);
+}
+
+// Multiply a copy of a vector and a matrix (matrix is left-hand operand).
+// Return the copy.
+template<typename T>
+const tvec4<T> operator*(const tmat4<T>& lhs, const tvec4<T>& rhs)
+{
+ T x((lhs[0][0] * rhs.x()) + (lhs[0][1] * rhs.y()) + (lhs[0][2] * rhs.z()) + (lhs[0][3] * rhs.w()));
+ T y((lhs[1][0] * rhs.x()) + (lhs[1][1] * rhs.y()) + (lhs[1][2] * rhs.z()) + (lhs[1][3] * rhs.w()));
+ T z((lhs[2][0] * rhs.x()) + (lhs[2][1] * rhs.y()) + (lhs[2][2] * rhs.z()) + (lhs[2][3] * rhs.w()));
+ T w((lhs[3][0] * rhs.x()) + (lhs[3][1] * rhs.y()) + (lhs[3][2] * rhs.z()) + (lhs[3][3] * rhs.w()));
+ return tvec4<T>(x, y, z, w);
+}
+
+// Compute the outer product of two vectors. Return the resultant matrix.
+template<typename T>
+const tmat4<T> outer(const tvec4<T>& a, const tvec4<T>& b)
+{
+ tmat4<T> product;
+ product[0][0] = a.x() * b.x();
+ product[0][1] = a.x() * b.y();
+ product[0][2] = a.x() * b.z();
+ product[0][3] = a.x() * b.w();
+ product[1][0] = a.y() * b.x();
+ product[1][1] = a.y() * b.y();
+ product[1][2] = a.y() * b.z();
+ product[1][3] = a.y() * b.w();
+ product[2][0] = a.z() * b.x();
+ product[2][1] = a.z() * b.y();
+ product[2][2] = a.z() * b.z();
+ product[2][3] = a.z() * b.w();
+ product[3][0] = a.w() * b.x();
+ product[3][1] = a.w() * b.y();
+ product[3][2] = a.w() * b.z();
+ product[3][3] = a.w() * b.w();
+ return product;
+}
+
+//
+// Convenience typedefs. These are here to present a homogeneous view of these
+// objects with respect to shader source.
+//
+typedef tmat2<float> mat2;
+typedef tmat3<float> mat3;
+typedef tmat4<float> mat4;
+
+typedef tmat2<double> dmat2;
+typedef tmat3<double> dmat3;
+typedef tmat4<double> dmat4;
+
+typedef tmat2<int> imat2;
+typedef tmat3<int> imat3;
+typedef tmat4<int> imat4;
+
+typedef tmat2<unsigned int> umat2;
+typedef tmat3<unsigned int> umat3;
+typedef tmat4<unsigned int> umat4;
+
+typedef tmat2<bool> bmat2;
+typedef tmat3<bool> bmat3;
+typedef tmat4<bool> bmat4;
+
+namespace Mat4
+{
+
+//
+// Some functions to generate transformation matrices that used to be provided
+// by OpenGL.
+//
+mat4 translate(float x, float y, float z);
+mat4 scale(float x, float y, float z);
+mat4 rotate(float angle, float x, float y, float z);
+mat4 frustum(float left, float right, float bottom, float top, float near, float far);
+mat4 ortho(float left, float right, float bottom, float top, float near, float far);
+mat4 perspective(float fovy, float aspect, float zNear, float zFar);
+mat4 lookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ);
+
+} // namespace Mat4
+} // namespace LibMatrix
+#endif // MAT_H_
diff --git a/src/libmatrix/program.cc b/src/libmatrix/program.cc
new file mode 100644
index 0000000..b27298b
--- /dev/null
+++ b/src/libmatrix/program.cc
@@ -0,0 +1,360 @@
+//
+// Copyright (c) 2011-2012 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#include <string>
+#include <vector>
+#include <sstream>
+#include <fstream>
+#include <iostream>
+#include "gl-if.h"
+#include "program.h"
+
+using std::string;
+using LibMatrix::mat4;
+using LibMatrix::mat3;
+using LibMatrix::vec2;
+using LibMatrix::vec3;
+using LibMatrix::vec4;
+
+Shader::Shader(unsigned int type, const string& source) :
+ handle_(0),
+ type_(type),
+ source_(source),
+ ready_(false),
+ valid_(false)
+{
+ // Create our shader and setup the source code.
+ handle_ = glCreateShader(type);
+ if (!handle_)
+ {
+ message_ = string("Failed to create the new shader.");
+ return;
+ }
+ const GLchar* shaderSource = source_.c_str();
+ glShaderSource(handle_, 1, &shaderSource, NULL);
+ GLint param = 0;
+ glGetShaderiv(handle_, GL_SHADER_SOURCE_LENGTH, &param);
+ if (static_cast<unsigned int>(param) != source_.length() + 1)
+ {
+ std::ostringstream o(string("Expected shader source length "));
+ o << source_.length() << ", but got " << param << std::endl;
+ message_ = o.str();
+ return;
+ }
+ valid_ = true;
+}
+
+Shader::~Shader()
+{
+ handle_ = 0;
+ type_ = 0;
+ ready_ = false;
+ valid_ = false;
+}
+
+void
+Shader::compile()
+{
+ // Make sure we have a good shader and haven't already compiled it.
+ if (!valid_ || ready_)
+ {
+ return;
+ }
+ glCompileShader(handle_);
+ GLint param = 0;
+ glGetShaderiv(handle_, GL_COMPILE_STATUS, &param);
+ if (param == GL_FALSE)
+ {
+ glGetShaderiv(handle_, GL_INFO_LOG_LENGTH, &param);
+ GLchar* infoLog = new GLchar[param + 1];
+ glGetShaderInfoLog(handle_, param + 1, NULL, infoLog);
+ message_ = infoLog;
+ delete [] infoLog;
+ return;
+ }
+ ready_ = true;
+}
+
+void
+Shader::attach(unsigned int program)
+{
+ // Shader must be valid and compiled to be attached to a program.
+ if (!valid_ || !ready_)
+ {
+ return;
+ }
+ glAttachShader(program, handle_);
+}
+
+void
+Shader::release()
+{
+ if (handle_)
+ {
+ glDeleteShader(handle_);
+ }
+ handle_ = 0;
+ type_ = 0;
+ ready_ = false;
+ valid_ = false;
+}
+
+Program::Program() :
+ handle_(0),
+ ready_(false),
+ valid_(false)
+{
+}
+
+Program::~Program()
+{
+ // First release all of the shader resources attached to us and clean up
+ // our handle.
+ release();
+}
+
+void
+Program::init()
+{
+ handle_ = glCreateProgram();
+ if (!handle_)
+ {
+ message_ = string("Failed to create the new program");
+ return;
+ }
+
+ valid_ = true;
+}
+
+void
+Program::release()
+{
+ // First delete all of the shader resources attached to us.
+ for (std::vector<Shader>::iterator shaderIt = shaders_.begin(); shaderIt != shaders_.end(); shaderIt++)
+ {
+ shaderIt->release();
+ }
+
+ // Clear out the shader vector so we're ready to reuse it.
+ shaders_.clear();
+
+ // Clear out the error string to make sure we don't return anything stale.
+ message_.clear();
+
+ // Release all of the symbol map resources.
+ for (std::map<string, Symbol*>::iterator symbolIt = symbols_.begin(); symbolIt != symbols_.end(); symbolIt++)
+ {
+ delete (*symbolIt).second;
+ }
+ symbols_.clear();
+
+ if (handle_)
+ {
+ glDeleteProgram(handle_);
+ }
+ handle_ = 0;
+ ready_ = false;
+ valid_ = false;
+}
+void
+Program::addShader(unsigned int type, const string& source)
+{
+ if (!valid_)
+ {
+ return;
+ }
+
+ Shader shader(type, source);
+ if (!shader.valid())
+ {
+ message_ = shader.errorMessage();
+ valid_ = false;
+ return;
+ }
+
+ shader.compile();
+
+ if (!shader.ready())
+ {
+ message_ = shader.errorMessage();
+ valid_ = false;
+ return;
+ }
+
+ shader.attach(handle_);
+ shaders_.push_back(shader);
+ return;
+}
+
+void
+Program::build()
+{
+ if (!valid_ || ready_)
+ {
+ return;
+ }
+
+ if (shaders_.empty())
+ {
+ message_ = string("There are no shaders attached to this program");
+ return;
+ }
+
+ glLinkProgram(handle_);
+ GLint param = 1;
+ glGetProgramiv(handle_, GL_LINK_STATUS, &param);
+ if (param == GL_FALSE)
+ {
+ glGetProgramiv(handle_, GL_INFO_LOG_LENGTH, &param);
+ GLchar* infoLog = new GLchar[param + 1];
+ glGetProgramInfoLog(handle_, param + 1, NULL, infoLog);
+ message_ = infoLog;
+ delete [] infoLog;
+ return;
+ }
+ ready_ = true;
+}
+
+void
+Program::start()
+{
+ if (!valid_ || !ready_)
+ {
+ return;
+ }
+ glUseProgram(handle_);
+}
+
+void
+Program::stop()
+{
+ glUseProgram(0);
+}
+
+
+int
+Program::getUniformLocation(const string& name)
+{
+ GLint location = glGetUniformLocation(handle_, name.c_str());
+ if (location < 0)
+ {
+ message_ = string("Failed to get uniform location for \"") + name +
+ string("\"");
+ }
+ return location;
+}
+
+int
+Program::getAttribIndex(const string& name)
+{
+ GLint index = glGetAttribLocation(handle_, name.c_str());
+ if (index < 0)
+ {
+ message_ = string("Failed to get attribute location for \"") + name +
+ string("\"");
+ }
+ return index;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const mat4& m)
+{
+ if (type_ == Uniform)
+ {
+ // Our matrix representation is column-major, so transpose is false here.
+ glUniformMatrix4fv(location_, 1, GL_FALSE, m);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const mat3& m)
+{
+ if (type_ == Uniform)
+ {
+ // Our matrix representation is column-major, so transpose is false here.
+ glUniformMatrix3fv(location_, 1, GL_FALSE, m);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const vec2& v)
+{
+ if (type_ == Uniform)
+ {
+ glUniform2fv(location_, 1, v);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const vec3& v)
+{
+ if (type_ == Uniform)
+ {
+ glUniform3fv(location_, 1, v);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const vec4& v)
+{
+ if (type_ == Uniform)
+ {
+ glUniform4fv(location_, 1, v);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const float& f)
+{
+ if (type_ == Uniform)
+ {
+ glUniform1f(location_, f);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const int& i)
+{
+ if (type_ == Uniform)
+ {
+ glUniform1i(location_, i);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::operator[](const std::string& name)
+{
+ std::map<std::string, Symbol*>::iterator mapIt = symbols_.find(name);
+ if (mapIt == symbols_.end())
+ {
+ Program::Symbol::SymbolType type(Program::Symbol::Attribute);
+ int location = getAttribIndex(name);
+ if (location < 0)
+ {
+ // No attribute found by that name. Let's try a uniform...
+ type = Program::Symbol::Uniform;
+ location = getUniformLocation(name);
+ if (location < 0)
+ {
+ type = Program::Symbol::None;
+ }
+ }
+ mapIt = symbols_.insert(mapIt, std::make_pair(name, new Symbol(name, location, type)));
+ }
+ return *(*mapIt).second;
+}
diff --git a/src/libmatrix/program.h b/src/libmatrix/program.h
new file mode 100644
index 0000000..b7ba3df
--- /dev/null
+++ b/src/libmatrix/program.h
@@ -0,0 +1,165 @@
+//
+// Copyright (c) 2011-2012 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#ifndef PROGRAM_H_
+#define PROGRAM_H_
+
+#include <string>
+#include <vector>
+#include <map>
+#include "mat.h"
+
+// Simple shader container. Abstracts all of the OpenGL bits, but leaves
+// much of the semantics intact. This is typically only referenced directly
+// by the program object.
+class Shader
+{
+public:
+ Shader() :
+ handle_(0),
+ type_(0),
+ ready_(false),
+ valid_(false) {}
+ Shader(const Shader& shader) :
+ handle_(shader.handle_),
+ type_(shader.type_),
+ source_(shader.source_),
+ message_(shader.message_),
+ ready_(shader.ready_),
+ valid_(shader.valid_) {}
+ Shader(unsigned int type, const std::string& source);
+ ~Shader();
+
+ // Compiles the shader source so that it can be linked into a
+ // program.
+ //
+ // Make sure the shader is "valid" before calling this one.
+ void compile();
+
+ // Attaches a compiled shader to a program in preparation for
+ // linking.
+ //
+ // Make sure the shader is "ready" before calling this one.
+ void attach(unsigned int program);
+
+ // Release any resources associated with this shader back to
+ // OpenGL
+ void release();
+
+ // If "valid" then the shader has successfully been created.
+ // If "ready" then the shader has successfully been compiled.
+ // If either is false, then additional information can be obtained
+ // from the error message.
+ bool valid() const { return valid_; }
+ bool ready() const { return ready_; }
+ const std::string& errorMessage() const { return message_; }
+
+private:
+ unsigned int handle_;
+ unsigned int type_;
+ std::string source_;
+ std::string message_;
+ bool ready_;
+ bool valid_;
+};
+
+// Simple program container. Abstracts all of the OpenGL bits, but leaves
+// much of the semantics intact.
+class Program
+{
+public:
+ Program();
+ ~Program();
+
+ // Initialize the program object for use.
+ void init();
+
+ // Release any resources associated with this program back to
+ // OpenGL
+ void release();
+
+ // Create a new shader of the given type and source, compile it and
+ // attach it to the program.
+ //
+ // Make sure the program is "valid" before calling this one.
+ void addShader(unsigned int type, const std::string& source);
+
+ // Link all of the attached shaders into a runnable program for use
+ // in a rendering operation.
+ //
+ // Make sure the program is "valid" and that at least one shader
+ // has been successfully added before calling this one.
+ void build();
+
+ // Bind the program for use by the rendering context (i.e. actually
+ // run it).
+ //
+ // Make sure the program is "ready" before calling this one.
+ void start();
+
+ // Unbind the program from use by the rendering context (i.e. stop
+ // using it).
+ void stop();
+
+ class Symbol
+ {
+public:
+ enum SymbolType
+ {
+ None,
+ Attribute,
+ Uniform
+ };
+ Symbol(const std::string& name, int location, SymbolType type) :
+ type_(type),
+ location_(location),
+ name_(name) {}
+ int location() const { return location_; }
+ // These members cause data to be bound to program variables, so
+ // the program must be bound for use for these to be effective.
+ Symbol& operator=(const LibMatrix::mat4& m);
+ Symbol& operator=(const LibMatrix::mat3& m);
+ Symbol& operator=(const LibMatrix::vec2& v);
+ Symbol& operator=(const LibMatrix::vec3& v);
+ Symbol& operator=(const LibMatrix::vec4& v);
+ Symbol& operator=(const float& f);
+ Symbol& operator=(const int& i);
+private:
+ Symbol();
+ SymbolType type_;
+ GLint location_;
+ std::string name_;
+ };
+ // Get the handle to a named program input (the location in OpenGL
+ // vernacular). Typically used in conjunction with various VertexAttrib
+ // interfaces. Equality operators are used to load uniform data.
+ Symbol& operator[](const std::string& name);
+
+ // If "valid" then the program has successfully been created.
+ // If "ready" then the program has successfully been built.
+ // If either is false, then additional information can be obtained
+ // from the error message.
+ bool valid() const { return valid_; }
+ bool ready() const { return ready_; }
+ const std::string& errorMessage() const { return message_; }
+
+private:
+ int getAttribIndex(const std::string& name);
+ int getUniformLocation(const std::string& name);
+ unsigned int handle_;
+ std::map<std::string, Symbol*> symbols_;
+ std::vector<Shader> shaders_;
+ std::string message_;
+ bool ready_;
+ bool valid_;
+};
+
+#endif // PROGRAM_H_
diff --git a/src/libmatrix/shader-source.cc b/src/libmatrix/shader-source.cc
new file mode 100644
index 0000000..bf80d21
--- /dev/null
+++ b/src/libmatrix/shader-source.cc
@@ -0,0 +1,615 @@
+//
+// Copyright (c) 2010-2012 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#include <istream>
+#include <memory>
+
+#include "shader-source.h"
+#include "log.h"
+#include "vec.h"
+#include "util.h"
+
+/**
+ * Holds default precision values for all shader types
+ * (even the unknown type, which is hardwired to default precision values)
+ */
+std::vector<ShaderSource::Precision>
+ShaderSource::default_precision_(ShaderSource::ShaderTypeUnknown + 1);
+
+/**
+ * Loads the contents of a file into a string.
+ *
+ * @param filename the name of the file
+ * @param str the string to put the contents of the file into
+ */
+bool
+ShaderSource::load_file(const std::string& filename, std::string& str)
+{
+ std::auto_ptr<std::istream> is_ptr(Util::get_resource(filename));
+ std::istream& inputFile(*is_ptr);
+
+ if (!inputFile)
+ {
+ Log::error("Failed to open \"%s\"\n", filename.c_str());
+ return false;
+ }
+
+ std::string curLine;
+ while (getline(inputFile, curLine))
+ {
+ str += curLine;
+ str += '\n';
+ }
+
+ return true;
+}
+
+
+/**
+ * Appends a string to the shader source.
+ *
+ * @param str the string to append
+ */
+void
+ShaderSource::append(const std::string &str)
+{
+ source_ << str;
+}
+
+/**
+ * Appends the contents of a file to the shader source.
+ *
+ * @param filename the name of the file to append
+ */
+void
+ShaderSource::append_file(const std::string &filename)
+{
+ std::string source;
+ if (load_file(filename, source))
+ source_ << source;
+}
+
+/**
+ * Replaces a string in the source with another string.
+ *
+ * @param remove the string to replace
+ * @param insert the string to replace with
+ */
+void
+ShaderSource::replace(const std::string &remove, const std::string &insert)
+{
+ std::string::size_type pos = 0;
+ std::string str(source_.str());
+
+ while ((pos = str.find(remove, pos)) != std::string::npos) {
+ str.replace(pos, remove.size(), insert);
+ pos++;
+ }
+
+ source_.clear();
+ source_.str(str);
+}
+
+/**
+ * Replaces a string in the source with the contents of a file.
+ *
+ * @param remove the string to replace
+ * @param filename the name of the file to read from
+ */
+void
+ShaderSource::replace_with_file(const std::string &remove, const std::string &filename)
+{
+ std::string source;
+ if (load_file(filename, source))
+ replace(remove, source);
+}
+
+/**
+ * Adds a string (usually containing a constant definition) at
+ * global (per shader) scope.
+ *
+ * The string is placed after any default precision qualifiers.
+ *
+ * @param str the string to add
+ */
+void
+ShaderSource::add_global(const std::string &str)
+{
+ std::string::size_type pos = 0;
+ std::string source(source_.str());
+
+ /* Find the last precision qualifier */
+ pos = source.rfind("precision");
+
+ if (pos != std::string::npos) {
+ /*
+ * Find the next #endif line of a preprocessor block that contains
+ * the precision qualifier.
+ */
+ std::string::size_type pos_if = source.find("#if", pos);
+ std::string::size_type pos_endif = source.find("#endif", pos);
+
+ if (pos_endif != std::string::npos && pos_endif < pos_if)
+ pos = pos_endif;
+
+ /* Go to the next line */
+ pos = source.find("\n", pos);
+ if (pos != std::string::npos)
+ pos++;
+ }
+ else
+ pos = 0;
+
+ source.insert(pos, str);
+
+ source_.clear();
+ source_.str(source);
+}
+
+/**
+ * Adds a string (usually containing a constant definition) at
+ * global (per shader) scope.
+ *
+ * The string is placed after any default precision qualifiers.
+ *
+ * @param function the function to add the string into
+ * @param str the string to add
+ */
+void
+ShaderSource::add_local(const std::string &str, const std::string &function)
+{
+ std::string::size_type pos = 0;
+ std::string source(source_.str());
+
+ /* Find the function */
+ pos = source.find(function);
+ pos = source.find('{', pos);
+
+ /* Go to the next line */
+ pos = source.find("\n", pos);
+ if (pos != std::string::npos)
+ pos++;
+
+ source.insert(pos, str);
+
+ source_.clear();
+ source_.str(source);
+}
+
+/**
+ * Adds a string (usually containing a constant definition) to a shader source
+ *
+ * If the function parameter is empty, the string will be added to global
+ * scope, after any precision definitions.
+ *
+ * @param str the string to add
+ * @param function if not empty, the function to add the string into
+ */
+void
+ShaderSource::add(const std::string &str, const std::string &function)
+{
+ if (!function.empty())
+ add_local(str, function);
+ else
+ add_global(str);
+}
+
+/**
+ * Adds a float constant definition.
+ *
+ * @param name the name of the constant
+ * @param f the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, float f,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const float " << name << " = " << std::fixed << f << ";" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a float array constant definition.
+ *
+ * Note that various GLSL versions (including ES) don't support
+ * array constants.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, std::vector<float> &array,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const float " << name << "[" << array.size() << "] = {" << std::fixed;
+ for(std::vector<float>::const_iterator iter = array.begin();
+ iter != array.end();
+ iter++)
+ {
+ ss << *iter;
+ if (iter + 1 != array.end())
+ ss << ", " << std::endl;
+ }
+
+ ss << "};" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a vec2 constant definition.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, const LibMatrix::vec2 &v,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const vec2 " << name << " = vec2(" << std::fixed;
+ ss << v.x() << ", " << v.y() << ");" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a vec3 constant definition.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, const LibMatrix::vec3 &v,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const vec3 " << name << " = vec3(" << std::fixed;
+ ss << v.x() << ", " << v.y() << ", " << v.z() << ");" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a vec4 constant definition.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, const LibMatrix::vec4 &v,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const vec4 " << name << " = vec4(" << std::fixed;
+ ss << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w() << ");" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a mat3 constant definition.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, const LibMatrix::mat3 &m,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const mat3 " << name << " = mat3(" << std::fixed;
+ ss << m[0][0] << ", " << m[1][0] << ", " << m[2][0] << "," << std::endl;
+ ss << m[0][1] << ", " << m[1][1] << ", " << m[2][1] << "," << std::endl;
+ ss << m[0][2] << ", " << m[1][2] << ", " << m[2][2] << std::endl;
+ ss << ");" << std::endl;
+
+ add(ss.str(), function);
+}
+
+/**
+ * Adds a float array declaration and initialization.
+ *
+ * @param name the name of the array
+ * @param array the array values
+ * @param init_function the function to put the initialization in
+ * @param decl_function if not empty, the function to put the declaration in
+ */
+void
+ShaderSource::add_array(const std::string &name, std::vector<float> &array,
+ const std::string &init_function,
+ const std::string &decl_function)
+{
+ if (init_function.empty() || name.empty())
+ return;
+
+ std::stringstream ss;
+ ss << "float " << name << "[" << array.size() << "];" << std::endl;
+
+ std::string decl(ss.str());
+
+ ss.clear();
+ ss.str("");
+ ss << std::fixed;
+
+ for(std::vector<float>::const_iterator iter = array.begin();
+ iter != array.end();
+ iter++)
+ {
+ ss << name << "[" << iter - array.begin() << "] = " << *iter << ";" << std::endl;
+ }
+
+ add(ss.str(), init_function);
+
+ add(decl, decl_function);
+}
+
+/**
+ * Gets the ShaderType for this ShaderSource.
+ *
+ * If the ShaderType is unknown, an attempt is made to infer
+ * the type from the shader source contents.
+ *
+ * @return the ShaderType
+ */
+ShaderSource::ShaderType
+ShaderSource::type()
+{
+ /* Try to infer the type from the source contents */
+ if (type_ == ShaderSource::ShaderTypeUnknown) {
+ std::string source(source_.str());
+
+ if (source.find("gl_FragColor") != std::string::npos)
+ type_ = ShaderSource::ShaderTypeFragment;
+ else if (source.find("gl_Position") != std::string::npos)
+ type_ = ShaderSource::ShaderTypeVertex;
+ else
+ Log::debug("Cannot infer shader type from contents. Leaving it Unknown.\n");
+ }
+
+ return type_;
+}
+
+/**
+ * Helper function that emits a precision statement.
+ *
+ * @param ss the stringstream to add the statement to
+ * @param val the precision value
+ * @param type_str the variable type to apply the precision value to
+ */
+void
+ShaderSource::emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val,
+ const std::string& type_str)
+{
+ static const char *precision_map[] = {
+ "lowp", "mediump", "highp", NULL
+ };
+
+ if (val == ShaderSource::PrecisionValueHigh) {
+ if (type_ == ShaderSource::ShaderTypeFragment)
+ ss << "#ifdef GL_FRAGMENT_PRECISION_HIGH" << std::endl;
+
+ ss << "precision highp " << type_str << ";" << std::endl;
+
+ if (type_ == ShaderSource::ShaderTypeFragment) {
+ ss << "#else" << std::endl;
+ ss << "precision mediump " << type_str << ";" << std::endl;
+ ss << "#endif" << std::endl;
+ }
+ }
+ else if (val >= 0 && val < ShaderSource::PrecisionValueDefault) {
+ ss << "precision " << precision_map[val] << " ";
+ ss << type_str << ";" << std::endl;
+ }
+
+ /* There is no default precision in the fragment shader, so set it to mediump */
+ if (val == ShaderSource::PrecisionValueDefault
+ && type_str == "float" && type_ == ShaderSource::ShaderTypeFragment)
+ {
+ ss << "precision mediump float;" << std::endl;
+ }
+}
+
+/**
+ * Gets a string containing the complete shader source.
+ *
+ * Precision statements are applied at this point.
+ *
+ * @return the shader source
+ */
+std::string
+ShaderSource::str()
+{
+ /* Decide which precision values to use */
+ ShaderSource::Precision precision;
+
+ /* Ensure we have tried to infer the type from the contents */
+ type();
+
+ if (precision_has_been_set_)
+ precision = precision_;
+ else
+ precision = default_precision(type_);
+
+ /* Create the precision statements */
+ std::stringstream ss;
+
+ emit_precision(ss, precision.int_precision, "int");
+ emit_precision(ss, precision.float_precision, "float");
+ emit_precision(ss, precision.sampler2d_precision, "sampler2D");
+ emit_precision(ss, precision.samplercube_precision, "samplerCube");
+
+ std::string precision_str(ss.str());
+ if (!precision_str.empty()) {
+ precision_str.insert(0, "#ifdef GL_ES\n");
+ precision_str.insert(precision_str.size(), "#endif\n");
+ }
+
+ return precision_str + source_.str();
+}
+
+/**
+ * Sets the precision that will be used for this shader.
+ *
+ * This overrides any default values set with ShaderSource::default_*_precision().
+ *
+ * @param precision the precision to set
+ */
+void
+ShaderSource::precision(const ShaderSource::Precision& precision)
+{
+ precision_ = precision;
+ precision_has_been_set_ = true;
+}
+
+/**
+ * Gets the precision that will be used for this shader.
+ *
+ * @return the precision
+ */
+const ShaderSource::Precision&
+ShaderSource::precision()
+{
+ return precision_;
+}
+
+/**
+ * Sets the default precision that will be used for a shaders type.
+ *
+ * If type is ShaderTypeUnknown the supplied precision is used for all
+ * shader types.
+ *
+ * This can be overriden per ShaderSource object by using ::precision().
+ *
+ * @param precision the default precision to set
+ * @param type the ShaderType to use the precision for
+ */
+void
+ShaderSource::default_precision(const ShaderSource::Precision& precision,
+ ShaderSource::ShaderType type)
+{
+ if (type < 0 || type > ShaderSource::ShaderTypeUnknown)
+ type = ShaderSource::ShaderTypeUnknown;
+
+ if (type == ShaderSource::ShaderTypeUnknown) {
+ for (size_t i = 0; i < ShaderSource::ShaderTypeUnknown; i++)
+ default_precision_[i] = precision;
+ }
+ else {
+ default_precision_[type] = precision;
+ }
+}
+
+/**
+ * Gets the default precision that will be used for a shader type.
+ *
+ * It is valid to use a type of ShaderTypeUnknown. This will always
+ * return a Precision with default values.
+ *
+ * @param type the ShaderType to get the precision of
+ *
+ * @return the precision
+ */
+const ShaderSource::Precision&
+ShaderSource::default_precision(ShaderSource::ShaderType type)
+{
+ if (type < 0 || type > ShaderSource::ShaderTypeUnknown)
+ type = ShaderSource::ShaderTypeUnknown;
+
+ return default_precision_[type];
+}
+
+/****************************************
+ * ShaderSource::Precision constructors *
+ ****************************************/
+
+/**
+ * Creates a ShaderSource::Precision with default precision values.
+ */
+ShaderSource::Precision::Precision() :
+ int_precision(ShaderSource::PrecisionValueDefault),
+ float_precision(ShaderSource::PrecisionValueDefault),
+ sampler2d_precision(ShaderSource::PrecisionValueDefault),
+ samplercube_precision(ShaderSource::PrecisionValueDefault)
+{
+}
+
+/**
+ * Creates a ShaderSource::Precision using the supplied precision values.
+ */
+ShaderSource::Precision::Precision(ShaderSource::PrecisionValue int_p,
+ ShaderSource::PrecisionValue float_p,
+ ShaderSource::PrecisionValue sampler2d_p,
+ ShaderSource::PrecisionValue samplercube_p) :
+ int_precision(int_p), float_precision(float_p),
+ sampler2d_precision(sampler2d_p), samplercube_precision(samplercube_p)
+{
+}
+
+/**
+ * Creates a ShaderSource::Precision from a string representation of
+ * precision values.
+ *
+ * The string format is:
+ * "<int>,<float>,<sampler2d>,<samplercube>"
+ *
+ * Each precision value is one of "high", "medium", "low" or "default".
+ *
+ * @param precision_values the string representation of the precision values
+ */
+ShaderSource::Precision::Precision(const std::string& precision_values) :
+ int_precision(ShaderSource::PrecisionValueDefault),
+ float_precision(ShaderSource::PrecisionValueDefault),
+ sampler2d_precision(ShaderSource::PrecisionValueDefault),
+ samplercube_precision(ShaderSource::PrecisionValueDefault)
+{
+ std::vector<std::string> elems;
+
+ Util::split(precision_values, ',', elems, Util::SplitModeNormal);
+
+ for (size_t i = 0; i < elems.size() && i < 4; i++) {
+ const std::string& pstr(elems[i]);
+ ShaderSource::PrecisionValue pval;
+
+ if (pstr == "high")
+ pval = ShaderSource::PrecisionValueHigh;
+ else if (pstr == "medium")
+ pval = ShaderSource::PrecisionValueMedium;
+ else if (pstr == "low")
+ pval = ShaderSource::PrecisionValueLow;
+ else
+ pval = ShaderSource::PrecisionValueDefault;
+
+ switch(i) {
+ case 0: int_precision = pval; break;
+ case 1: float_precision = pval; break;
+ case 2: sampler2d_precision = pval; break;
+ case 3: samplercube_precision = pval; break;
+ default: break;
+ }
+ }
+}
diff --git a/src/libmatrix/shader-source.h b/src/libmatrix/shader-source.h
new file mode 100644
index 0000000..4dc1d1d
--- /dev/null
+++ b/src/libmatrix/shader-source.h
@@ -0,0 +1,103 @@
+//
+// Copyright (c) 2010-2012 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#include <string>
+#include <sstream>
+#include <vector>
+#include "vec.h"
+#include "mat.h"
+
+/**
+ * Helper class for loading and manipulating shader sources.
+ */
+class ShaderSource
+{
+public:
+ enum ShaderType {
+ ShaderTypeVertex,
+ ShaderTypeFragment,
+ ShaderTypeUnknown
+ };
+
+ ShaderSource(ShaderType type = ShaderTypeUnknown) :
+ precision_has_been_set_(false), type_(type) {}
+ ShaderSource(const std::string &filename, ShaderType type = ShaderTypeUnknown) :
+ precision_has_been_set_(false), type_(type) { append_file(filename); }
+
+ void append(const std::string &str);
+ void append_file(const std::string &filename);
+
+ void replace(const std::string &remove, const std::string &insert);
+ void replace_with_file(const std::string &remove, const std::string &filename);
+
+ void add(const std::string &str, const std::string &function = "");
+
+ void add_const(const std::string &name, float f,
+ const std::string &function = "");
+ void add_const(const std::string &name, std::vector<float> &f,
+ const std::string &function = "");
+ void add_const(const std::string &name, const LibMatrix::vec2 &v,
+ const std::string &function = "");
+ void add_const(const std::string &name, const LibMatrix::vec3 &v,
+ const std::string &function = "");
+ void add_const(const std::string &name, const LibMatrix::vec4 &v,
+ const std::string &function = "");
+ void add_const(const std::string &name, const LibMatrix::mat3 &m,
+ const std::string &function = "");
+
+ void add_array(const std::string &name, std::vector<float> &array,
+ const std::string &init_function,
+ const std::string &decl_function = "");
+
+ ShaderType type();
+ std::string str();
+
+ enum PrecisionValue {
+ PrecisionValueLow,
+ PrecisionValueMedium,
+ PrecisionValueHigh,
+ PrecisionValueDefault
+ };
+
+ struct Precision {
+ Precision();
+ Precision(PrecisionValue int_p, PrecisionValue float_p,
+ PrecisionValue sampler2d_p, PrecisionValue samplercube_p);
+ Precision(const std::string& list);
+
+ PrecisionValue int_precision;
+ PrecisionValue float_precision;
+ PrecisionValue sampler2d_precision;
+ PrecisionValue samplercube_precision;
+ };
+
+ void precision(const Precision& precision);
+ const Precision& precision();
+
+ static void default_precision(const Precision& precision,
+ ShaderType type = ShaderTypeUnknown);
+ static const Precision& default_precision(ShaderType type);
+
+private:
+ void add_global(const std::string &str);
+ void add_local(const std::string &str, const std::string &function);
+ bool load_file(const std::string& filename, std::string& str);
+ void emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val,
+ const std::string& type_str);
+
+ std::stringstream source_;
+ Precision precision_;
+ bool precision_has_been_set_;
+ ShaderType type_;
+
+ static std::vector<Precision> default_precision_;
+};
diff --git a/src/libmatrix/stack.h b/src/libmatrix/stack.h
new file mode 100644
index 0000000..c14cec3
--- /dev/null
+++ b/src/libmatrix/stack.h
@@ -0,0 +1,106 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#ifndef STACK_H_
+#define STACK_H_
+
+#include <vector>
+#include "mat.h"
+
+namespace LibMatrix
+{
+//
+// Simple matrix stack implementation suitable for tracking OpenGL matrix
+// state. Default construction puts an identity matrix on the top of the
+// stack.
+//
+template<typename T>
+class MatrixStack
+{
+public:
+ MatrixStack()
+ {
+ theStack_.push_back(T());
+ }
+ MatrixStack(const T& matrix)
+ {
+ theStack_.push_back(matrix);
+ }
+ ~MatrixStack() {}
+
+ const T& getCurrent() const { return theStack_.back(); }
+
+ void push()
+ {
+ theStack_.push_back(theStack_.back());
+ }
+ void pop()
+ {
+ theStack_.pop_back();
+ }
+ void loadIdentity()
+ {
+ theStack_.back().setIdentity();
+ }
+ T& operator*=(const T& rhs)
+ {
+ T& curMatrix = theStack_.back();
+ curMatrix *= rhs;
+ return curMatrix;
+ }
+ void print() const
+ {
+ const T& curMatrix = theStack_.back();
+ curMatrix.print();
+ }
+ unsigned int getDepth() const { return theStack_.size(); }
+private:
+ std::vector<T> theStack_;
+};
+
+class Stack4 : public MatrixStack<mat4>
+{
+public:
+ void translate(float x, float y, float z)
+ {
+ *this *= Mat4::translate(x, y, z);
+ }
+ void scale(float x, float y, float z)
+ {
+ *this *= Mat4::scale(x, y, z);
+ }
+ void rotate(float angle, float x, float y, float z)
+ {
+ *this *= Mat4::rotate(angle, x, y, z);
+ }
+ void frustum(float left, float right, float bottom, float top, float near, float far)
+ {
+ *this *= Mat4::frustum(left, right, bottom, top, near, far);
+ }
+ void ortho(float left, float right, float bottom, float top, float near, float far)
+ {
+ *this *= Mat4::ortho(left, right, bottom, top, near, far);
+ }
+ void perspective(float fovy, float aspect, float zNear, float zFar)
+ {
+ *this *= Mat4::perspective(fovy, aspect, zNear, zFar);
+ }
+ void lookAt(float eyeX, float eyeY, float eyeZ,
+ float centerX, float centerY, float centerZ,
+ float upX, float upY, float upZ)
+ {
+ *this *= Mat4::lookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
+ }
+};
+
+} // namespace LibMatrix
+
+#endif // STACK_H_
diff --git a/src/libmatrix/test/basic-global-const.vert b/src/libmatrix/test/basic-global-const.vert
new file mode 100644
index 0000000..18dc358
--- /dev/null
+++ b/src/libmatrix/test/basic-global-const.vert
@@ -0,0 +1,15 @@
+const vec4 ConstantColor = vec4(1.000000, 1.000000, 1.000000, 1.000000);
+attribute vec3 position;
+
+uniform mat4 modelview;
+uniform mat4 projection;
+
+varying vec4 color;
+
+void
+main(void)
+{
+ vec4 curVertex = vec4(position, 1.0);
+ gl_Position = projection * modelview * curVertex;
+ color = ConstantColor;
+}
diff --git a/src/libmatrix/test/basic.frag b/src/libmatrix/test/basic.frag
new file mode 100644
index 0000000..1b648db
--- /dev/null
+++ b/src/libmatrix/test/basic.frag
@@ -0,0 +1,7 @@
+varying vec4 color;
+
+void
+main(void)
+{
+ gl_FragColor = color;
+}
diff --git a/src/libmatrix/test/basic.vert b/src/libmatrix/test/basic.vert
new file mode 100644
index 0000000..d93289e
--- /dev/null
+++ b/src/libmatrix/test/basic.vert
@@ -0,0 +1,14 @@
+attribute vec3 position;
+
+uniform mat4 modelview;
+uniform mat4 projection;
+
+varying vec4 color;
+
+void
+main(void)
+{
+ vec4 curVertex = vec4(position, 1.0);
+ gl_Position = projection * modelview * curVertex;
+ color = ConstantColor;
+}
diff --git a/src/libmatrix/test/const_vec_test.cc b/src/libmatrix/test/const_vec_test.cc
new file mode 100644
index 0000000..879d4e6
--- /dev/null
+++ b/src/libmatrix/test/const_vec_test.cc
@@ -0,0 +1,60 @@
+//
+// Copyright (c) 2011 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#include <iostream>
+#include "libmatrix_test.h"
+#include "const_vec_test.h"
+#include "../vec.h"
+
+using LibMatrix::vec2;
+using LibMatrix::vec3;
+using LibMatrix::vec4;
+using std::cout;
+using std::endl;
+
+void
+Vec2TestConstOperator::run(const Options& options)
+{
+ const vec2 a(1.0, 1.0);
+ const vec2 b(2.0, 2.0);
+ vec2 aplusb(a + b);
+ vec2 aminusb(a - b);
+ vec2 atimesb(a * b);
+ vec2 adivb(a / b);
+ const float s(2.5);
+ vec2 stimesb(s * b);
+}
+
+void
+Vec3TestConstOperator::run(const Options& options)
+{
+ const vec3 a(1.0, 1.0, 1.0);
+ const vec3 b(2.0, 2.0, 2.0);
+ vec3 aplusb(a + b);
+ vec3 aminusb(a - b);
+ vec3 atimesb(a * b);
+ vec3 adivb(a / b);
+ const float s(2.5);
+ vec3 stimesb(s * b);
+}
+
+void
+Vec4TestConstOperator::run(const Options& options)
+{
+ const vec4 a(1.0, 1.0, 1.0, 1.0);
+ const vec4 b(2.0, 2.0, 2.0, 2.0);
+ vec4 aplusb(a + b);
+ vec4 aminusb(a - b);
+ vec4 atimesb(a * b);
+ vec4 adivb(a / b);
+ const float s(2.5);
+ vec4 stimesb(s * b);
+}
diff --git a/src/libmatrix/test/const_vec_test.h b/src/libmatrix/test/const_vec_test.h
new file mode 100644
index 0000000..834f4a8
--- /dev/null
+++ b/src/libmatrix/test/const_vec_test.h
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2011 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#ifndef CONST_VEC_TEST_H_
+#define CONST_VEC_TEST_H_
+
+class MatrixTest;
+class Options;
+
+class Vec2TestConstOperator : public MatrixTest
+{
+public:
+ Vec2TestConstOperator() : MatrixTest("vec2::const") {}
+ virtual void run(const Options& options);
+};
+
+class Vec3TestConstOperator : public MatrixTest
+{
+public:
+ Vec3TestConstOperator() : MatrixTest("vec3::const") {}
+ virtual void run(const Options& options);
+};
+
+class Vec4TestConstOperator : public MatrixTest
+{
+public:
+ Vec4TestConstOperator() : MatrixTest("vec4::const") {}
+ virtual void run(const Options& options);
+};
+
+#endif // CONST_VEC_TEST_H_
diff --git a/src/libmatrix/test/inverse_test.cc b/src/libmatrix/test/inverse_test.cc
new file mode 100644
index 0000000..51a8072
--- /dev/null
+++ b/src/libmatrix/test/inverse_test.cc
@@ -0,0 +1,172 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#include <iostream>
+#include "libmatrix_test.h"
+#include "inverse_test.h"
+#include "../mat.h"
+
+using LibMatrix::mat2;
+using LibMatrix::mat3;
+using LibMatrix::mat4;
+using std::cout;
+using std::endl;
+
+void
+MatrixTest2x2Inverse::run(const Options& options)
+{
+ mat2 m;
+
+ if (options.beVerbose())
+ {
+ cout << "Starting with mat2 (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ m[0][1] = -2.5;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Matrix should now have (0, 1) == -2.500000" << endl << endl;
+ m.print();
+ }
+
+ mat2 mi(m);
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Copy of previous matrix (should have (0, 1) == -2.500000)" << endl << endl;
+ mi.print();
+ }
+
+ mi.inverse();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Inverse of copy: " << endl << endl;
+ mi.print();
+ }
+
+ mat2 i = m * mi;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
+ i.print();
+ }
+
+ mat2 ident;
+ if (i == ident)
+ {
+ pass_ = true;
+ }
+}
+
+void
+MatrixTest3x3Inverse::run(const Options& options)
+{
+ mat3 m;
+
+ if (options.beVerbose())
+ {
+ cout << "Starting with mat3 (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ m[1][2] = -2.5;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Matrix should now have (1, 2) == -2.500000" << endl << endl;
+ m.print();
+ }
+
+ mat3 mi(m);
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Copy of previous matrix (should have (1, 2) == -2.500000)" << endl << endl;
+ mi.print();
+ }
+
+ mi.inverse();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Inverse of copy: " << endl << endl;
+ mi.print();
+ }
+
+ mat3 i = m * mi;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
+ i.print();
+ }
+
+ mat3 ident;
+ if (i == ident)
+ {
+ pass_ = true;
+ }
+}
+
+void
+MatrixTest4x4Inverse::run(const Options& options)
+{
+ mat4 m;
+
+ if (options.beVerbose())
+ {
+ cout << "Starting with mat4 (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ m[2][3] = -2.5;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Matrix should now have (2, 3) == -2.500000" << endl << endl;
+ m.print();
+ }
+
+ mat4 mi(m);
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Copy of previous matrix (should have (2, 3) == -2.500000)" << endl << endl;
+ mi.print();
+ }
+
+ mi.inverse();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Inverse of copy: " << endl << endl;
+ mi.print();
+ }
+
+ mat4 i = m * mi;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
+ i.print();
+ }
+
+ mat4 ident;
+ if (i == ident)
+ {
+ pass_ = true;
+ }
+}
+
diff --git a/src/libmatrix/test/inverse_test.h b/src/libmatrix/test/inverse_test.h
new file mode 100644
index 0000000..4c5b584
--- /dev/null
+++ b/src/libmatrix/test/inverse_test.h
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#ifndef INVERSE_TEST_H_
+#define INVERSE_TEST_H_
+
+class MatrixTest;
+class Options;
+
+class MatrixTest2x2Inverse : public MatrixTest
+{
+public:
+ MatrixTest2x2Inverse() : MatrixTest("mat2::inverse") {}
+ virtual void run(const Options& options);
+};
+
+class MatrixTest3x3Inverse : public MatrixTest
+{
+public:
+ MatrixTest3x3Inverse() : MatrixTest("mat3::inverse") {}
+ virtual void run(const Options& options);
+};
+
+class MatrixTest4x4Inverse : public MatrixTest
+{
+public:
+ MatrixTest4x4Inverse() : MatrixTest("mat4::inverse") {}
+ virtual void run(const Options& options);
+};
+
+#endif // INVERSE_TEST_H_
diff --git a/src/libmatrix/test/libmatrix_test.cc b/src/libmatrix/test/libmatrix_test.cc
new file mode 100644
index 0000000..5e4ff12
--- /dev/null
+++ b/src/libmatrix/test/libmatrix_test.cc
@@ -0,0 +1,72 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+// Alexandros Frantzis - Util::split tests
+//
+#include <iostream>
+#include <string>
+#include <vector>
+#include "libmatrix_test.h"
+#include "inverse_test.h"
+#include "transpose_test.h"
+#include "const_vec_test.h"
+#include "shader_source_test.h"
+#include "util_split_test.h"
+
+using std::cerr;
+using std::cout;
+using std::endl;
+
+int
+main(int argc, char** argv)
+{
+ Options testOptions("matrix_test");
+ testOptions.parseArgs(argc, argv);
+ if (testOptions.showHelp())
+ {
+ testOptions.printUsage();
+ return 0;
+ }
+
+ using std::vector;
+ vector<MatrixTest*> testVec;
+ testVec.push_back(new MatrixTest2x2Inverse());
+ testVec.push_back(new MatrixTest3x3Inverse());
+ testVec.push_back(new MatrixTest4x4Inverse());
+ testVec.push_back(new MatrixTest2x2Transpose());
+ testVec.push_back(new MatrixTest3x3Transpose());
+ testVec.push_back(new MatrixTest4x4Transpose());
+ testVec.push_back(new ShaderSourceBasic());
+ testVec.push_back(new UtilSplitTestNormal());
+ testVec.push_back(new UtilSplitTestQuoted());
+
+ for (vector<MatrixTest*>::iterator testIt = testVec.begin();
+ testIt != testVec.end();
+ testIt++)
+ {
+ MatrixTest* curTest = *testIt;
+ if (testOptions.beVerbose())
+ {
+ cout << "Running test " << curTest->name() << endl;
+ }
+ curTest->run(testOptions);
+ if (!curTest->passed())
+ {
+ cerr << curTest->name() << " does not work!" << endl;
+ return 1;
+ }
+ if (testOptions.beVerbose())
+ {
+ cout << curTest->name() << " is okay!" << endl;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/libmatrix/test/libmatrix_test.h b/src/libmatrix/test/libmatrix_test.h
new file mode 100644
index 0000000..4ae0a8a
--- /dev/null
+++ b/src/libmatrix/test/libmatrix_test.h
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#ifndef LIBMATRIX_TEST_H_
+#define LIBMATRIX_TEST_H_
+
+class Options
+{
+ Options();
+ static const std::string verbose_name_;
+ static const std::string help_name_;
+ std::string app_name_;
+ bool show_help_;
+ bool verbose_;
+public:
+ Options(const std::string& app_name) :
+ app_name_(app_name),
+ show_help_(false),
+ verbose_(false) {}
+ ~Options() {}
+ bool beVerbose() const { return verbose_; }
+ bool showHelp() const { return show_help_; }
+ void parseArgs(int argc, char** argv);
+ void printUsage();
+};
+
+class MatrixTest
+{
+ std::string name_;
+protected:
+ bool pass_;
+ MatrixTest();
+public:
+ MatrixTest(const std::string& name) :
+ name_(name),
+ pass_(false) {}
+ ~MatrixTest();
+ const std::string& name() const { return name_; }
+ virtual void run(const Options& options) = 0;
+ const bool passed() const { return pass_; }
+};
+
+#endif // LIBMATRIX_TEST_H_
diff --git a/src/libmatrix/test/options.cc b/src/libmatrix/test/options.cc
new file mode 100644
index 0000000..ec15f3c
--- /dev/null
+++ b/src/libmatrix/test/options.cc
@@ -0,0 +1,76 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#include <iostream>
+#include <iomanip>
+#include <getopt.h>
+#include "libmatrix_test.h"
+
+using std::cout;
+using std::endl;
+
+const std::string Options::verbose_name_("verbose");
+const std::string Options::help_name_("help");
+
+void
+Options::parseArgs(int argc, char** argv)
+{
+ static struct option long_options[] = {
+ {"verbose", 0, 0, 0},
+ {"help", 0, 0, 0},
+ {0, 0, 0, 0}
+ };
+ int option_index(0);
+ int c = getopt_long(argc, argv, "", long_options, &option_index);
+ while (c != -1)
+ {
+ // getopt_long() returns '?' and prints an "unrecognized option" error
+ // to stderr if it does not recognize an option. Just trigger
+ // the help/usage message, stop processing and get out.
+ if (c == '?')
+ {
+ show_help_ = true;
+ break;
+ }
+
+ std::string optname(long_options[option_index].name);
+
+ if (optname == verbose_name_)
+ {
+ verbose_ = true;
+ }
+ else if (optname == help_name_)
+ {
+ show_help_ = true;
+ }
+ c = getopt_long(argc, argv, "",
+ long_options, &option_index);
+ }
+}
+
+
+static void
+emitColumnOne(const std::string& text)
+{
+ cout << std::setw(16) << text;
+}
+
+void
+Options::printUsage()
+{
+ cout << app_name_ << ": directed functional test utility for libmatrix." << endl;
+ cout << "Options:" << endl;
+ emitColumnOne("--verbose");
+ cout << std::setw(0) << " Enable verbose output during test runs." << endl;
+ emitColumnOne("--help");
+ cout << std::setw(0) << " Print this usage text." << endl;
+}
+
diff --git a/src/libmatrix/test/shader_source_test.cc b/src/libmatrix/test/shader_source_test.cc
new file mode 100644
index 0000000..31d0265
--- /dev/null
+++ b/src/libmatrix/test/shader_source_test.cc
@@ -0,0 +1,49 @@
+//
+// Copyright (c) 2012 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#include <string>
+#include "libmatrix_test.h"
+#include "shader_source_test.h"
+#include "../shader-source.h"
+#include "../vec.h"
+
+using std::string;
+using LibMatrix::vec4;
+
+void
+ShaderSourceBasic::run(const Options& options)
+{
+ static const string vtx_shader_filename("test/basic.vert");
+
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource vtx_source2(vtx_shader_filename);
+
+ pass_ = (vtx_source.str() == vtx_source2.str());
+}
+
+void
+ShaderSourceAddConstGlobal::run(const Options& options)
+{
+ // Load the original shader source.
+ static const string src_shader_filename("test/basic.vert");
+ ShaderSource src_shader(src_shader_filename);
+
+ // Add constant at global scope
+ static const vec4 constantColor(1.0, 1.0, 1.0, 1.0);
+ src_shader.add_const("ConstantColor", constantColor);
+
+ // Load the pre-modified shader
+ static const string result_shader_filename("test/basic-global-const.vert");
+ ShaderSource result_shader(result_shader_filename);
+
+ // Compare the output strings to confirm the results.
+ pass_ = (src_shader.str() == result_shader.str());
+}
diff --git a/src/libmatrix/test/shader_source_test.h b/src/libmatrix/test/shader_source_test.h
new file mode 100644
index 0000000..cf49766
--- /dev/null
+++ b/src/libmatrix/test/shader_source_test.h
@@ -0,0 +1,32 @@
+//
+// Copyright (c) 2012 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#ifndef SHADER_SOURCE_TEST_H_
+#define SHADER_SOURCE_TEST_H_
+
+class MatrixTest;
+class Options;
+
+class ShaderSourceBasic : public MatrixTest
+{
+public:
+ ShaderSourceBasic() : MatrixTest("ShaderSource::basic") {}
+ virtual void run(const Options& options);
+};
+
+class ShaderSourceAddConstGlobal : public MatrixTest
+{
+public:
+ ShaderSourceAddConstGlobal() : MatrixTest("ShaderSource::AddConstGlobal") {}
+ virtual void run(const Options& options);
+};
+
+#endif // SHADER_SOURCE_TEST_H
diff --git a/src/libmatrix/test/transpose_test.cc b/src/libmatrix/test/transpose_test.cc
new file mode 100644
index 0000000..574486d
--- /dev/null
+++ b/src/libmatrix/test/transpose_test.cc
@@ -0,0 +1,297 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#include <iostream>
+#include "libmatrix_test.h"
+#include "transpose_test.h"
+#include "../mat.h"
+
+using LibMatrix::mat2;
+using LibMatrix::mat3;
+using LibMatrix::mat4;
+using std::cout;
+using std::endl;
+
+void
+MatrixTest2x2Transpose::run(const Options& options)
+{
+ // First, a simple test to ensure that the transpose of the identity is
+ // the identity.
+ if (options.beVerbose())
+ {
+ cout << endl << "Assertion 1: Transpose of the identity is the identity." << endl << endl;
+ }
+
+ mat2 m;
+
+ if (options.beVerbose())
+ {
+ cout << "Starting with mat2 (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ m.transpose();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Transpose of identity (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ mat2 mi;
+ if (m != mi)
+ {
+ // FAIL! Transpose of the identity is the identity.
+ return;
+ }
+
+ // At this point, we have 2 identity matrices.
+ // Next, set an element in the matrix and transpose twice. We should see
+ // the original matrix (with i,j set).
+ if (options.beVerbose())
+ {
+ cout << endl << "Assertion 2: Transposing a matrix twice yields the original matrix." << endl << endl;
+ }
+
+ m[0][1] = 6.3;
+
+ if (options.beVerbose())
+ {
+ cout << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
+ m.print();
+ }
+
+ mi = m;
+
+ m.transpose().transpose();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
+ m.print();
+ }
+
+ if (m != mi)
+ {
+ // FAIL! Transposing the same matrix twice should yield the original.
+ return;
+ }
+
+ // Next, reset mi back to the identity. Set element element j,i in this
+ // matrix and transpose m. They should now be equal.
+ if (options.beVerbose())
+ {
+ cout << endl << "Assertion 3: Transpose of matrix (i,j) == x is equal to matrix (j,i) == x." << endl << endl;
+ }
+
+ mi.setIdentity();
+ mi[1][0] = 6.3;
+
+ m.transpose();
+
+ if (options.beVerbose())
+ {
+ cout << "Matrix should now have (1, 0) == 6.300000" << endl << endl;
+ m.print();
+ cout << endl;
+ }
+
+ if (m == mi)
+ {
+ pass_ = true;
+ }
+
+ // FAIL! Transposing the same matrix twice should yield the original.
+}
+
+void
+MatrixTest3x3Transpose::run(const Options& options)
+{
+ // First, a simple test to ensure that the transpose of the identity is
+ // the identity.
+ if (options.beVerbose())
+ {
+ cout << endl << "Assertion 1: Transpose of the identity is the identity." << endl << endl;
+ }
+
+ mat3 m;
+
+ if (options.beVerbose())
+ {
+ cout << "Starting with mat2 (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ m.transpose();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Transpose of identity (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ mat3 mi;
+ if (m != mi)
+ {
+ // FAIL! Transpose of the identity is the identity.
+ return;
+ }
+
+ // At this point, we have 2 identity matrices.
+ // Next, set an element in the matrix and transpose twice. We should see
+ // the original matrix (with i,j set).
+ if (options.beVerbose())
+ {
+ cout << endl << "Assertion 2: Transposing a matrix twice yields the original matrix." << endl << endl;
+ }
+
+ m[0][1] = 6.3;
+
+ if (options.beVerbose())
+ {
+ cout << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
+ m.print();
+ }
+
+ mi = m;
+
+ m.transpose().transpose();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
+ m.print();
+ }
+
+ if (m != mi)
+ {
+ // FAIL! Transposing the same matrix twice should yield the original.
+ return;
+ }
+
+ // Next, reset mi back to the identity. Set element element j,i in this
+ // matrix and transpose m. They should now be equal.
+ if (options.beVerbose())
+ {
+ cout << endl << "Assertion 3: Transpose of matrix (i,j) == x is equal to matrix (j,i) == x." << endl << endl;
+ }
+
+ mi.setIdentity();
+ mi[1][0] = 6.3;
+
+ m.transpose();
+
+ if (options.beVerbose())
+ {
+ cout << "Matrix should now have (1, 0) == 6.300000" << endl << endl;
+ m.print();
+ cout << endl;
+ }
+
+ if (m == mi)
+ {
+ pass_ = true;
+ }
+
+ // FAIL! Transposing the same matrix twice should yield the original.
+}
+
+void
+MatrixTest4x4Transpose::run(const Options& options)
+{
+ // First, a simple test to ensure that the transpose of the identity is
+ // the identity.
+ if (options.beVerbose())
+ {
+ cout << endl << "Assertion 1: Transpose of the identity is the identity." << endl << endl;
+ }
+
+ mat4 m;
+
+ if (options.beVerbose())
+ {
+ cout << "Starting with mat2 (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ m.transpose();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Transpose of identity (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ mat4 mi;
+ if (m != mi)
+ {
+ // FAIL! Transpose of the identity is the identity.
+ return;
+ }
+
+ // At this point, we have 2 identity matrices.
+ // Next, set an element in the matrix and transpose twice. We should see
+ // the original matrix (with i,j set).
+ if (options.beVerbose())
+ {
+ cout << endl << "Assertion 2: Transposing a matrix twice yields the original matrix." << endl << endl;
+ }
+
+ m[0][1] = 6.3;
+
+ if (options.beVerbose())
+ {
+ cout << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
+ m.print();
+ }
+
+ mi = m;
+
+ m.transpose().transpose();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
+ m.print();
+ }
+
+ if (m != mi)
+ {
+ // FAIL! Transposing the same matrix twice should yield the original.
+ return;
+ }
+
+ // Next, reset mi back to the identity. Set element element j,i in this
+ // matrix and transpose m. They should now be equal.
+ if (options.beVerbose())
+ {
+ cout << endl << "Assertion 3: Transpose of matrix (i,j) == x is equal to matrix (j,i) == x." << endl << endl;
+ }
+
+ mi.setIdentity();
+ mi[1][0] = 6.3;
+
+ m.transpose();
+
+ if (options.beVerbose())
+ {
+ cout << "Matrix should now have (1, 0) == 6.300000" << endl << endl;
+ m.print();
+ cout << endl;
+ }
+
+ if (m == mi)
+ {
+ pass_ = true;
+ }
+
+ // FAIL! Transposing the same matrix twice should yield the original.
+}
diff --git a/src/libmatrix/test/transpose_test.h b/src/libmatrix/test/transpose_test.h
new file mode 100644
index 0000000..3a4398f
--- /dev/null
+++ b/src/libmatrix/test/transpose_test.h
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#ifndef TRANSPOSE_TEST_H_
+#define TRANSPOSE_TEST_H_
+
+class MatrixTest;
+class Options;
+
+class MatrixTest2x2Transpose : public MatrixTest
+{
+public:
+ MatrixTest2x2Transpose() : MatrixTest("mat2::transpose") {}
+ virtual void run(const Options& options);
+};
+
+class MatrixTest3x3Transpose : public MatrixTest
+{
+public:
+ MatrixTest3x3Transpose() : MatrixTest("mat3::transpose") {}
+ virtual void run(const Options& options);
+};
+
+class MatrixTest4x4Transpose : public MatrixTest
+{
+public:
+ MatrixTest4x4Transpose() : MatrixTest("mat4::transpose") {}
+ virtual void run(const Options& options);
+};
+#endif // TRANSPOSE_TEST_H_
diff --git a/src/libmatrix/test/util_split_test.cc b/src/libmatrix/test/util_split_test.cc
new file mode 100644
index 0000000..4399f77
--- /dev/null
+++ b/src/libmatrix/test/util_split_test.cc
@@ -0,0 +1,180 @@
+//
+// Copyright (c) 2012 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Alexandros Frantzis - original implementation.
+//
+#include <iostream>
+#include <string>
+#include <vector>
+#include "libmatrix_test.h"
+#include "util_split_test.h"
+#include "../util.h"
+
+using std::cout;
+using std::endl;
+using std::string;
+using std::vector;
+
+template <typename T> static bool
+areVectorsEqual(vector<T>& vec1, vector<T>& vec2)
+{
+ if (vec1.size() != vec2.size())
+ return false;
+
+ for (unsigned int i = 0; i < vec1.size(); i++)
+ {
+ if (vec1[i] != vec2[i])
+ return false;
+ }
+
+ return true;
+}
+
+template <typename T> static void
+printVector(vector<T>& vec)
+{
+ cout << "[";
+ for (unsigned int i = 0; i < vec.size(); i++)
+ {
+ cout << '"' << vec[i] << '"';
+ if (i < vec.size() - 1)
+ cout << ", ";
+ }
+ cout << "]";
+}
+
+void
+UtilSplitTestNormal::run(const Options& options)
+{
+ const string test1("abc def ghi");
+ const string test2(" abc: def :ghi ");
+ vector<string> expected1;
+ vector<string> expected2;
+ vector<string> results;
+
+ expected1.push_back("abc");
+ expected1.push_back("def");
+ expected1.push_back("ghi");
+
+ expected2.push_back(" abc");
+ expected2.push_back(" def ");
+ expected2.push_back("ghi ");
+
+ if (options.beVerbose())
+ {
+ cout << "Testing string \"" << test1 << "\"" << endl;
+ }
+
+ Util::split(test1, ' ', results, Util::SplitModeNormal);
+
+ if (options.beVerbose())
+ {
+ cout << "Split result: ";
+ printVector(results);
+ cout << endl << "Expected: ";
+ printVector(expected1);
+ cout << endl;
+ }
+
+ if (!areVectorsEqual(results, expected1))
+ {
+ return;
+ }
+
+ results.clear();
+
+ if (options.beVerbose())
+ {
+ cout << "Testing string \"" << test2 << "\"" << endl;
+ }
+
+ Util::split(test2, ':', results, Util::SplitModeNormal);
+
+ if (options.beVerbose())
+ {
+ cout << "Split result: ";
+ printVector(results);
+ cout << endl << "Expected: ";
+ printVector(expected2);
+ cout << endl;
+ }
+
+ if (!areVectorsEqual(results, expected2))
+ {
+ return;
+ }
+
+ pass_ = true;
+}
+
+void
+UtilSplitTestQuoted::run(const Options& options)
+{
+ const string test1("abc \"def' ghi\" klm\\ nop -b qr:title='123 \"456'");
+ const string test2("abc: def='1:2:3:'ghi : \":jk\"");
+ vector<string> expected1;
+ vector<string> expected2;
+ vector<string> results;
+
+ expected1.push_back("abc");
+ expected1.push_back("def' ghi");
+ expected1.push_back("klm nop");
+ expected1.push_back("-b");
+ expected1.push_back("qr:title=123 \"456");
+
+ expected2.push_back("abc");
+ expected2.push_back(" def=1:2:3:ghi ");
+ expected2.push_back(" :jk");
+
+ if (options.beVerbose())
+ {
+ cout << "Testing string \"" << test1 << "\"" << endl;
+ }
+
+ Util::split(test1, ' ', results, Util::SplitModeQuoted);
+
+ if (options.beVerbose())
+ {
+ cout << "Split result: ";
+ printVector(results);
+ cout << endl << "Expected: ";
+ printVector(expected1);
+ cout << endl;
+ }
+
+ if (!areVectorsEqual(results, expected1))
+ {
+ return;
+ }
+
+ results.clear();
+
+ if (options.beVerbose())
+ {
+ cout << "Testing string \"" << test2 << "\"" << endl;
+ }
+
+ Util::split(test2, ':', results, Util::SplitModeQuoted);
+
+ if (options.beVerbose())
+ {
+ cout << "Split result: ";
+ printVector(results);
+ cout << endl << "Expected: ";
+ printVector(expected2);
+ cout << endl;
+ }
+
+ if (!areVectorsEqual(results, expected2))
+ {
+ return;
+ }
+
+ pass_ = true;
+}
diff --git a/src/libmatrix/test/util_split_test.h b/src/libmatrix/test/util_split_test.h
new file mode 100644
index 0000000..a8023ff
--- /dev/null
+++ b/src/libmatrix/test/util_split_test.h
@@ -0,0 +1,31 @@
+//
+// Copyright (c) 2012 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Alexandros Frantzis - original implementation.
+//
+#ifndef UTIL_SPLIT_TEST_H_
+#define UTIL_SPLIT_TEST_H_
+
+class MatrixTest;
+class Options;
+
+class UtilSplitTestNormal : public MatrixTest
+{
+public:
+ UtilSplitTestNormal() : MatrixTest("Util::split::normal") {}
+ virtual void run(const Options& options);
+};
+
+class UtilSplitTestQuoted : public MatrixTest
+{
+public:
+ UtilSplitTestQuoted() : MatrixTest("Util::split::quoted") {}
+ virtual void run(const Options& options);
+};
+#endif // UTIL_SPLIT_TEST_H_
diff --git a/src/libmatrix/util.cc b/src/libmatrix/util.cc
new file mode 100644
index 0000000..d96f393
--- /dev/null
+++ b/src/libmatrix/util.cc
@@ -0,0 +1,343 @@
+//
+// Copyright (c) 2010-2011 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#include <sstream>
+#include <fstream>
+#include <sys/time.h>
+#ifdef ANDROID
+#include <android/asset_manager.h>
+#else
+#include <dirent.h>
+#endif
+
+#include "log.h"
+#include "util.h"
+
+using std::string;
+using std::vector;
+
+/*
+ * State machine for bash-like quoted string escaping:
+ *
+ * \
+ * -----------> +---------+
+ * | ---------- | Escaped |
+ * | | *,ESC +---------+
+ * | |
+ * | v '
+ * +--------+ ---> +--------------+ -----
+ * | Normal | <--- | SingleQuoted | | *, ESC
+ * +--------+ ' +--------------+ <----
+ * | ^
+ * | |
+ * | | " +--------------+ ----
+ * | ---------- | DoubleQuoted | | *, ESC
+ * -----------> +--------------+ <---
+ * " | ^
+ * \ | | *, ESC
+ * v |
+ * +---------------------+
+ * | DoubleQuotedEscaped |
+ * +---------------------+
+ *
+ * ESC: Mark character as Escaped
+ */
+static void
+fill_escape_vector(const string &str, vector<bool> &esc_vec)
+{
+ enum State {
+ StateNormal,
+ StateEscaped,
+ StateDoubleQuoted,
+ StateDoubleQuotedEscaped,
+ StateSingleQuoted
+ };
+
+ State state = StateNormal;
+
+ for (string::const_iterator iter = str.begin();
+ iter != str.end();
+ iter++)
+ {
+ const char c(*iter);
+ bool esc = false;
+
+ switch (state) {
+ case StateNormal:
+ if (c == '"')
+ state = StateDoubleQuoted;
+ else if (c == '\\')
+ state = StateEscaped;
+ else if (c == '\'')
+ state = StateSingleQuoted;
+ break;
+ case StateEscaped:
+ esc = true;
+ state = StateNormal;
+ break;
+ case StateDoubleQuoted:
+ if (c == '"')
+ state = StateNormal;
+ else if (c == '\\')
+ state = StateDoubleQuotedEscaped;
+ else
+ esc = true;
+ break;
+ case StateDoubleQuotedEscaped:
+ esc = true;
+ state = StateDoubleQuoted;
+ break;
+ case StateSingleQuoted:
+ if (c == '\'')
+ state = StateNormal;
+ else
+ esc = true;
+ default:
+ break;
+ }
+
+ esc_vec.push_back(esc);
+ }
+}
+
+static void
+split_normal(const string& src, char delim, vector<string>& elementVec)
+{
+ std::stringstream ss(src);
+ string item;
+ while(std::getline(ss, item, delim))
+ elementVec.push_back(item);
+}
+
+static void
+split_fuzzy(const string& src, char delim, vector<string>& elementVec)
+{
+ // Fuzzy case: Initialize our delimiter string based upon the caller's plus
+ // a space to allow for more flexibility.
+ string delimiter(" ");
+ delimiter += delim;
+ // Starting index into the string of the first token (by definition, if
+ // we're parsing a string, there is at least one token).
+ string::size_type startPos(0);
+ // string::find_first_of() looks for any character in the string provided,
+ // it is not treated as a sub-string, so regardless of where the space or
+ // comma is or how many there are, the result is the same.
+ string str(src);
+ string::size_type endPos = str.find_first_of(delimiter);
+ while (endPos != string::npos)
+ {
+ // Push back the current element starting at startPos for
+ // (endPos - startPos) characters. std::string takes care of
+ // terminators, etc.
+ elementVec.push_back(string(str, startPos, endPos - startPos));
+ // Index of the next element after any delimiter characters. Same
+ // caveat applies to find_first_not_of() that applies to
+ // find_first_of(); endPos tells it where to start the search.
+ string::size_type nextPos = str.find_first_not_of(delimiter, endPos);
+ // Erase the part of the string we've already parsed.
+ str = str.erase(startPos, nextPos - startPos);
+ // Look for the next delimiter. If there isn't one, we bail out.
+ endPos = str.find_first_of(delimiter);
+ }
+ // Regardless of whether we initially had one element or many, 'str' now
+ // only contains one.
+ elementVec.push_back(str);
+}
+
+static void
+split_quoted(const string& src, char delim, vector<string>& elementVec)
+{
+ std::stringstream ss;
+ vector<bool> escVec;
+
+ /* Mark characters in the string as escaped or not */
+ fill_escape_vector(src, escVec);
+
+ /* Sanity check... */
+ if (src.length() != escVec.size())
+ return;
+
+ for (vector<bool>::const_iterator iter = escVec.begin();
+ iter != escVec.end();
+ iter++)
+ {
+ bool escaped = static_cast<bool>(*iter);
+ char c = src[iter - escVec.begin()];
+
+ /* Output all characters, except unescaped ",\,' */
+ if ((c != '"' && c != '\\' && c != '\'') || escaped) {
+ /* If we reach an unescaped delimiter character, do a split */
+ if (c == delim && !escaped) {
+ elementVec.push_back(ss.str());
+ ss.str("");
+ ss.clear();
+ }
+ else {
+ ss << c;
+ }
+ }
+
+ }
+
+ /* Handle final element, delimited by end of string */
+ const string &finalElement(ss.str());
+ if (!finalElement.empty())
+ elementVec.push_back(finalElement);
+}
+
+void
+Util::split(const string& src, char delim, vector<string>& elementVec,
+ Util::SplitMode mode)
+{
+ // Trivial rejection
+ if (src.empty())
+ {
+ return;
+ }
+
+ switch (mode)
+ {
+ case Util::SplitModeNormal:
+ return split_normal(src, delim, elementVec);
+ case Util::SplitModeFuzzy:
+ return split_fuzzy(src, delim, elementVec);
+ case Util::SplitModeQuoted:
+ return split_quoted(src, delim, elementVec);
+ default:
+ break;
+ }
+}
+
+uint64_t
+Util::get_timestamp_us()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ uint64_t now = static_cast<uint64_t>(tv.tv_sec) * 1000000 +
+ static_cast<double>(tv.tv_usec);
+ return now;
+}
+
+std::string
+Util::appname_from_path(const std::string& path)
+{
+ std::string::size_type slashPos = path.rfind("/");
+ std::string::size_type startPos(0);
+ if (slashPos != std::string::npos)
+ {
+ startPos = slashPos + 1;
+ }
+ return std::string(path, startPos, std::string::npos);
+}
+
+#ifndef ANDROID
+
+std::istream *
+Util::get_resource(const std::string &path)
+{
+ std::ifstream *ifs = new std::ifstream(path.c_str());
+
+ return static_cast<std::istream *>(ifs);
+}
+
+void
+Util::list_files(const std::string& dirName, std::vector<std::string>& fileVec)
+{
+ DIR* dir = opendir(dirName.c_str());
+ if (!dir)
+ {
+ Log::error("Failed to open models directory '%s'\n", dirName.c_str());
+ return;
+ }
+
+ struct dirent* entry = readdir(dir);
+ while (entry)
+ {
+ std::string pathname(dirName + "/");
+ pathname += std::string(entry->d_name);
+ // Skip '.' and '..'
+ if (entry->d_name[0] != '.')
+ {
+ fileVec.push_back(pathname);
+ }
+ entry = readdir(dir);
+ }
+ closedir(dir);
+}
+
+#else
+
+AAssetManager *Util::android_asset_manager = 0;
+
+void
+Util::android_set_asset_manager(AAssetManager *asset_manager)
+{
+ Util::android_asset_manager = asset_manager;
+}
+
+AAssetManager *
+Util::android_get_asset_manager()
+{
+ return Util::android_asset_manager;
+}
+
+std::istream *
+Util::get_resource(const std::string &path)
+{
+ std::string path2(path);
+ /* Remove leading '/' from path name, it confuses the AssetManager */
+ if (path2.size() > 0 && path2[0] == '/')
+ path2.erase(0, 1);
+
+ std::stringstream *ss = new std::stringstream;
+ AAsset *asset = AAssetManager_open(Util::android_asset_manager,
+ path2.c_str(), AASSET_MODE_RANDOM);
+ if (asset) {
+ ss->write(reinterpret_cast<const char *>(AAsset_getBuffer(asset)),
+ AAsset_getLength(asset));
+ Log::debug("Load asset %s\n", path2.c_str());
+ AAsset_close(asset);
+ }
+ else {
+ Log::error("Couldn't load asset %s\n", path2.c_str());
+ }
+
+ return static_cast<std::istream *>(ss);
+}
+
+void
+Util::list_files(const std::string& dirName, std::vector<std::string>& fileVec)
+{
+ AAssetManager *mgr(Util::android_get_asset_manager());
+ std::string dir_name(dirName);
+
+ /* Remove leading '/' from path, it confuses the AssetManager */
+ if (dir_name.size() > 0 && dir_name[0] == '/')
+ dir_name.erase(0, 1);
+
+ AAssetDir* dir = AAssetManager_openDir(mgr, dir_name.c_str());
+ if (!dir)
+ {
+ Log::error("Failed to open models directory '%s'\n", dir_name.c_str());
+ return;
+ }
+
+ const char *filename(0);
+ while ((filename = AAssetDir_getNextFileName(dir)) != 0)
+ {
+ std::string pathname(dir_name + "/");
+ pathname += std::string(filename);
+ fileVec.push_back(pathname);
+ }
+ AAssetDir_close(dir);
+}
+#endif
diff --git a/src/libmatrix/util.h b/src/libmatrix/util.h
new file mode 100644
index 0000000..2b0f0f0
--- /dev/null
+++ b/src/libmatrix/util.h
@@ -0,0 +1,142 @@
+//
+// Copyright (c) 2010-2011 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include <string>
+#include <vector>
+#include <istream>
+#include <sstream>
+#include <stdint.h>
+
+#ifdef ANDROID
+#include <android/asset_manager_jni.h>
+#endif
+
+struct Util {
+ /**
+ * How to perform the split() operation
+ */
+ enum SplitMode {
+ /** Normal split operation */
+ SplitModeNormal,
+ /** Allow for spaces and multiple consecutive occurences of the delimiter */
+ SplitModeFuzzy,
+ /** Take into account bash-like quoting and escaping rules */
+ SplitModeQuoted
+ };
+
+ /**
+ * split() - Splits a string into elements using a provided delimiter
+ *
+ * @s: the string to split
+ * @delim: the delimiter to use
+ * @elems: the string vector to populate
+ * @mode: the SplitMode to use
+ *
+ * Using @delim to determine field boundaries, splits @s into separate
+ * string elements. These elements are returned in the string vector
+ * @elems. As long as @s is non-empty, there will be at least one
+ * element in @elems.
+ */
+ static void split(const std::string& src, char delim,
+ std::vector<std::string>& elems,
+ Util::SplitMode mode);
+ /**
+ * get_timestamp_us() - Returns the current time in microseconds
+ */
+ static uint64_t get_timestamp_us();
+ /**
+ * get_resource() - Gets an input filestream for a given file.
+ *
+ * @path: the path to the file
+ *
+ * Returns a pointer to an input stream, which must be deleted when no
+ * longer in use.
+ */
+ static std::istream *get_resource(const std::string &path);
+ /**
+ * list_files() - Get a list of the files in a given directory.
+ *
+ * @dirName: the directory path to be listed.
+ * @fileVec: the string vector to populate.
+ *
+ * Obtains a list of the files in @dirName, and returns them in the string
+ * vector @fileVec.
+ */
+ static void list_files(const std::string& dirName, std::vector<std::string>& fileVec);
+ /**
+ * dispose_pointer_vector() - cleans up a vector of pointers
+ *
+ * @vec: vector of pointers to objects or plain-old-data
+ *
+ * Iterates across @vec and deletes the data pointed to by each of the
+ * elements. Clears the vector, resetting it for reuse.
+ */
+ template <class T> static void dispose_pointer_vector(std::vector<T*> &vec)
+ {
+ for (typename std::vector<T*>::const_iterator iter = vec.begin();
+ iter != vec.end();
+ iter++)
+ {
+ delete *iter;
+ }
+
+ vec.clear();
+ }
+ /**
+ * toString() - Converts a string to a plain-old-data type.
+ *
+ * @asString: a string representation of plain-old-data.
+ */
+ template<typename T>
+ static T
+ fromString(const std::string& asString)
+ {
+ std::stringstream ss(asString);
+ T retVal = T();
+ ss >> retVal;
+ return retVal;
+ }
+ /**
+ * toString() - Converts a plain-old-data type to a string.
+ *
+ * @t: a simple value to be converted to a string
+ */
+ template<typename T>
+ static std::string
+ toString(const T t)
+ {
+ std::stringstream ss;
+ ss << t;
+ return ss.str();
+ }
+ /**
+ * appname_from_path() - get the name of an executable from an absolute path
+ *
+ * @path: absolute path of the running application (argv[0])
+ *
+ * Returns the last portion of @path (everything after the final '/').
+ */
+ static std::string
+ appname_from_path(const std::string& path);
+
+#ifdef ANDROID
+ static void android_set_asset_manager(AAssetManager *asset_manager);
+ static AAssetManager *android_get_asset_manager(void);
+private:
+ static AAssetManager *android_asset_manager;
+#endif
+};
+
+#endif /* UTIL_H */
diff --git a/src/libmatrix/vec.h b/src/libmatrix/vec.h
new file mode 100644
index 0000000..2680ebc
--- /dev/null
+++ b/src/libmatrix/vec.h
@@ -0,0 +1,716 @@
+//
+// Copyright (c) 2010-2011 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#ifndef VEC_H_
+#define VEC_H_
+
+#include <iostream> // only needed for print() functions...
+#include <math.h>
+
+namespace LibMatrix
+{
+// A template class for creating, managing and operating on a 2-element vector
+// of any type you like (intended for built-in types, but as long as it
+// supports the basic arithmetic and assignment operators, any type should
+// work).
+template<typename T>
+class tvec2
+{
+public:
+ tvec2() :
+ x_(0),
+ y_(0) {}
+ tvec2(const T t) :
+ x_(t),
+ y_(t) {}
+ tvec2(const T x, const T y) :
+ x_(x),
+ y_(y) {}
+ tvec2(const tvec2& v) :
+ x_(v.x_),
+ y_(v.y_) {}
+ ~tvec2() {}
+
+ // Print the elements of the vector to standard out.
+ // Really only useful for debug and test.
+ void print() const
+ {
+ std::cout << "| " << x_ << " " << y_ << " |" << std::endl;
+ }
+
+ // Allow raw data access for API calls and the like.
+ // For example, it is valid to pass a tvec2<float> into a call to
+ // the OpenGL command "glUniform2fv()".
+ operator const T*() const { return &x_;}
+
+ // Get and set access members for the individual elements.
+ const T x() const { return x_; }
+ const T y() const { return y_; }
+
+ void x(const T& val) { x_ = val; }
+ void y(const T& val) { y_ = val; }
+
+ // A direct assignment of 'rhs' to this. Return a reference to this.
+ tvec2& operator=(const tvec2& rhs)
+ {
+ if (this != &rhs)
+ {
+ x_ = rhs.x_;
+ y_ = rhs.y_;
+ }
+ return *this;
+ }
+
+ // Divide this by a scalar. Return a reference to this.
+ tvec2& operator/=(const T& rhs)
+ {
+ x_ /= rhs;
+ y_ /= rhs;
+ return *this;
+ }
+
+ // Divide a copy of this by a scalar. Return the copy.
+ const tvec2 operator/(const T& rhs) const
+ {
+ return tvec2(*this) /= rhs;
+ }
+
+ // Component-wise divide of this by another vector.
+ // Return a reference to this.
+ tvec2& operator/=(const tvec2& rhs)
+ {
+ x_ /= rhs.x_;
+ y_ /= rhs.y_;
+ return *this;
+ }
+
+ // Component-wise divide of a copy of this by another vector.
+ // Return the copy.
+ const tvec2 operator/(const tvec2& rhs) const
+ {
+ return tvec2(*this) /= rhs;
+ }
+
+ // Multiply this by a scalar. Return a reference to this.
+ tvec2& operator*=(const T& rhs)
+ {
+ x_ *= rhs;
+ y_ *= rhs;
+ return *this;
+ }
+
+ // Multiply a copy of this by a scalar. Return the copy.
+ const tvec2 operator*(const T& rhs) const
+ {
+ return tvec2(*this) *= rhs;
+ }
+
+ // Component-wise multiply of this by another vector.
+ // Return a reference to this.
+ tvec2& operator*=(const tvec2& rhs)
+ {
+ x_ *= rhs.x_;
+ y_ *= rhs.y_;
+ return *this;
+ }
+
+ // Component-wise multiply of a copy of this by another vector.
+ // Return the copy.
+ const tvec2 operator*(const tvec2& rhs) const
+ {
+ return tvec2(*this) *= rhs;
+ }
+
+ // Add a scalar to this. Return a reference to this.
+ tvec2& operator+=(const T& rhs)
+ {
+ x_ += rhs;
+ y_ += rhs;
+ return *this;
+ }
+
+ // Add a scalar to a copy of this. Return the copy.
+ const tvec2 operator+(const T& rhs) const
+ {
+ return tvec2(*this) += rhs;
+ }
+
+ // Component-wise addition of another vector to this.
+ // Return a reference to this.
+ tvec2& operator+=(const tvec2& rhs)
+ {
+ x_ += rhs.x_;
+ y_ += rhs.y_;
+ return *this;
+ }
+
+ // Component-wise addition of another vector to a copy of this.
+ // Return the copy.
+ const tvec2 operator+(const tvec2& rhs) const
+ {
+ return tvec2(*this) += rhs;
+ }
+
+ // Subtract a scalar from this. Return a reference to this.
+ tvec2& operator-=(const T& rhs)
+ {
+ x_ -= rhs;
+ y_ -= rhs;
+ return *this;
+ }
+
+ // Subtract a scalar from a copy of this. Return the copy.
+ const tvec2 operator-(const T& rhs) const
+ {
+ return tvec2(*this) -= rhs;
+ }
+
+ // Component-wise subtraction of another vector from this.
+ // Return a reference to this.
+ tvec2& operator-=(const tvec2& rhs)
+ {
+ x_ -= rhs.x_;
+ y_ -= rhs.y_;
+ return *this;
+ }
+
+ // Component-wise subtraction of another vector from a copy of this.
+ // Return the copy.
+ const tvec2 operator-(const tvec2& rhs) const
+ {
+ return tvec2(*this) -= rhs;
+ }
+
+ // Compute the length of this and return it.
+ float length() const
+ {
+ return sqrt(dot(*this, *this));
+ }
+
+ // Make this a unit vector.
+ void normalize()
+ {
+ float l = length();
+ x_ /= l;
+ y_ /= l;
+ }
+
+ // Compute the dot product of two vectors.
+ static T dot(const tvec2& v1, const tvec2& v2)
+ {
+ return (v1.x_ * v2.x_) + (v1.y_ * v2.y_);
+ }
+
+private:
+ T x_;
+ T y_;
+};
+
+// A template class for creating, managing and operating on a 3-element vector
+// of any type you like (intended for built-in types, but as long as it
+// supports the basic arithmetic and assignment operators, any type should
+// work).
+template<typename T>
+class tvec3
+{
+public:
+ tvec3() :
+ x_(0),
+ y_(0),
+ z_(0) {}
+ tvec3(const T t) :
+ x_(t),
+ y_(t),
+ z_(t) {}
+ tvec3(const T x, const T y, const T z) :
+ x_(x),
+ y_(y),
+ z_(z) {}
+ tvec3(const tvec3& v) :
+ x_(v.x_),
+ y_(v.y_),
+ z_(v.z_) {}
+ ~tvec3() {}
+
+ // Print the elements of the vector to standard out.
+ // Really only useful for debug and test.
+ void print() const
+ {
+ std::cout << "| " << x_ << " " << y_ << " " << z_ << " |" << std::endl;
+ }
+
+ // Allow raw data access for API calls and the like.
+ // For example, it is valid to pass a tvec3<float> into a call to
+ // the OpenGL command "glUniform3fv()".
+ operator const T*() const { return &x_;}
+
+ // Get and set access members for the individual elements.
+ const T x() const { return x_; }
+ const T y() const { return y_; }
+ const T z() const { return z_; }
+
+ void x(const T& val) { x_ = val; }
+ void y(const T& val) { y_ = val; }
+ void z(const T& val) { z_ = val; }
+
+ // A direct assignment of 'rhs' to this. Return a reference to this.
+ tvec3& operator=(const tvec3& rhs)
+ {
+ if (this != &rhs)
+ {
+ x_ = rhs.x_;
+ y_ = rhs.y_;
+ z_ = rhs.z_;
+ }
+ return *this;
+ }
+
+ // Divide this by a scalar. Return a reference to this.
+ tvec3& operator/=(const T& rhs)
+ {
+ x_ /= rhs;
+ y_ /= rhs;
+ z_ /= rhs;
+ return *this;
+ }
+
+ // Divide a copy of this by a scalar. Return the copy.
+ const tvec3 operator/(const T& rhs) const
+ {
+ return tvec3(*this) /= rhs;
+ }
+
+ // Component-wise divide of this by another vector.
+ // Return a reference to this.
+ tvec3& operator/=(const tvec3& rhs)
+ {
+ x_ /= rhs.x_;
+ y_ /= rhs.y_;
+ z_ /= rhs.z_;
+ return *this;
+ }
+
+ // Component-wise divide of a copy of this by another vector.
+ // Return the copy.
+ const tvec3 operator/(const tvec3& rhs) const
+ {
+ return tvec3(*this) /= rhs;
+ }
+
+ // Multiply this by a scalar. Return a reference to this.
+ tvec3& operator*=(const T& rhs)
+ {
+ x_ *= rhs;
+ y_ *= rhs;
+ z_ *= rhs;
+ return *this;
+ }
+
+ // Multiply a copy of this by a scalar. Return the copy.
+ const tvec3 operator*(const T& rhs) const
+ {
+ return tvec3(*this) *= rhs;
+ }
+
+ // Component-wise multiply of this by another vector.
+ // Return a reference to this.
+ tvec3& operator*=(const tvec3& rhs)
+ {
+ x_ *= rhs.x_;
+ y_ *= rhs.y_;
+ z_ *= rhs.z_;
+ return *this;
+ }
+
+ // Component-wise multiply of a copy of this by another vector.
+ // Return the copy.
+ const tvec3 operator*(const tvec3& rhs) const
+ {
+ return tvec3(*this) *= rhs;
+ }
+
+ // Add a scalar to this. Return a reference to this.
+ tvec3& operator+=(const T& rhs)
+ {
+ x_ += rhs;
+ y_ += rhs;
+ z_ += rhs;
+ return *this;
+ }
+
+ // Add a scalar to a copy of this. Return the copy.
+ const tvec3 operator+(const T& rhs) const
+ {
+ return tvec3(*this) += rhs;
+ }
+
+ // Component-wise addition of another vector to this.
+ // Return a reference to this.
+ tvec3& operator+=(const tvec3& rhs)
+ {
+ x_ += rhs.x_;
+ y_ += rhs.y_;
+ z_ += rhs.z_;
+ return *this;
+ }
+
+ // Component-wise addition of another vector to a copy of this.
+ // Return the copy.
+ const tvec3 operator+(const tvec3& rhs) const
+ {
+ return tvec3(*this) += rhs;
+ }
+
+ // Subtract a scalar from this. Return a reference to this.
+ tvec3& operator-=(const T& rhs)
+ {
+ x_ -= rhs;
+ y_ -= rhs;
+ z_ -= rhs;
+ return *this;
+ }
+
+ // Subtract a scalar from a copy of this. Return the copy.
+ const tvec3 operator-(const T& rhs) const
+ {
+ return tvec3(*this) -= rhs;
+ }
+
+ // Component-wise subtraction of another vector from this.
+ // Return a reference to this.
+ tvec3& operator-=(const tvec3& rhs)
+ {
+ x_ -= rhs.x_;
+ y_ -= rhs.y_;
+ z_ -= rhs.z_;
+ return *this;
+ }
+
+ // Component-wise subtraction of another vector from a copy of this.
+ // Return the copy.
+ const tvec3 operator-(const tvec3& rhs) const
+ {
+ return tvec3(*this) -= rhs;
+ }
+
+ // Compute the length of this and return it.
+ float length() const
+ {
+ return sqrt(dot(*this, *this));
+ }
+
+ // Make this a unit vector.
+ void normalize()
+ {
+ float l = length();
+ x_ /= l;
+ y_ /= l;
+ z_ /= l;
+ }
+
+ // Compute the dot product of two vectors.
+ static T dot(const tvec3& v1, const tvec3& v2)
+ {
+ return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_);
+ }
+
+ // Compute the cross product of two vectors.
+ static tvec3 cross(const tvec3& u, const tvec3& v)
+ {
+ return tvec3((u.y_ * v.z_) - (u.z_ * v.y_),
+ (u.z_ * v.x_) - (u.x_ * v.z_),
+ (u.x_ * v.y_) - (u.y_ * v.x_));
+ }
+
+private:
+ T x_;
+ T y_;
+ T z_;
+};
+
+// A template class for creating, managing and operating on a 4-element vector
+// of any type you like (intended for built-in types, but as long as it
+// supports the basic arithmetic and assignment operators, any type should
+// work).
+template<typename T>
+class tvec4
+{
+public:
+ tvec4() :
+ x_(0),
+ y_(0),
+ z_(0),
+ w_(0) {}
+ tvec4(const T t) :
+ x_(t),
+ y_(t),
+ z_(t),
+ w_(t) {}
+ tvec4(const T x, const T y, const T z, const T w) :
+ x_(x),
+ y_(y),
+ z_(z),
+ w_(w) {}
+ tvec4(const tvec4& v) :
+ x_(v.x_),
+ y_(v.y_),
+ z_(v.z_),
+ w_(v.w_) {}
+ ~tvec4() {}
+
+ // Print the elements of the vector to standard out.
+ // Really only useful for debug and test.
+ void print() const
+ {
+ std::cout << "| " << x_ << " " << y_ << " " << z_ << " " << w_ << " |" << std::endl;
+ }
+
+ // Allow raw data access for API calls and the like.
+ // For example, it is valid to pass a tvec4<float> into a call to
+ // the OpenGL command "glUniform4fv()".
+ operator const T*() const { return &x_;}
+
+ // Get and set access members for the individual elements.
+ const T x() const { return x_; }
+ const T y() const { return y_; }
+ const T z() const { return z_; }
+ const T w() const { return w_; }
+
+ void x(const T& val) { x_ = val; }
+ void y(const T& val) { y_ = val; }
+ void z(const T& val) { z_ = val; }
+ void w(const T& val) { w_ = val; }
+
+ // A direct assignment of 'rhs' to this. Return a reference to this.
+ tvec4& operator=(const tvec4& rhs)
+ {
+ if (this != &rhs)
+ {
+ x_ = rhs.x_;
+ y_ = rhs.y_;
+ z_ = rhs.z_;
+ w_ = rhs.w_;
+ }
+ return *this;
+ }
+
+ // Divide this by a scalar. Return a reference to this.
+ tvec4& operator/=(const T& rhs)
+ {
+ x_ /= rhs;
+ y_ /= rhs;
+ z_ /= rhs;
+ w_ /= rhs;
+ return *this;
+ }
+
+ // Divide a copy of this by a scalar. Return the copy.
+ const tvec4 operator/(const T& rhs) const
+ {
+ return tvec4(*this) /= rhs;
+ }
+
+ // Component-wise divide of this by another vector.
+ // Return a reference to this.
+ tvec4& operator/=(const tvec4& rhs)
+ {
+ x_ /= rhs.x_;
+ y_ /= rhs.y_;
+ z_ /= rhs.z_;
+ w_ /= rhs.w_;
+ return *this;
+ }
+
+ // Component-wise divide of a copy of this by another vector.
+ // Return the copy.
+ const tvec4 operator/(const tvec4& rhs) const
+ {
+ return tvec4(*this) /= rhs;
+ }
+
+ // Multiply this by a scalar. Return a reference to this.
+ tvec4& operator*=(const T& rhs)
+ {
+ x_ *= rhs;
+ y_ *= rhs;
+ z_ *= rhs;
+ w_ *= rhs;
+ return *this;
+ }
+
+ // Multiply a copy of this by a scalar. Return the copy.
+ const tvec4 operator*(const T& rhs) const
+ {
+ return tvec4(*this) *= rhs;
+ }
+
+ // Component-wise multiply of this by another vector.
+ // Return a reference to this.
+ tvec4& operator*=(const tvec4& rhs)
+ {
+ x_ *= rhs.x_;
+ y_ *= rhs.y_;
+ z_ *= rhs.z_;
+ w_ *= rhs.w_;
+ return *this;
+ }
+
+ // Component-wise multiply of a copy of this by another vector.
+ // Return the copy.
+ const tvec4 operator*(const tvec4& rhs) const
+ {
+ return tvec4(*this) *= rhs;
+ }
+
+ // Add a scalar to this. Return a reference to this.
+ tvec4& operator+=(const T& rhs)
+ {
+ x_ += rhs;
+ y_ += rhs;
+ z_ += rhs;
+ w_ += rhs;
+ return *this;
+ }
+
+ // Add a scalar to a copy of this. Return the copy.
+ const tvec4 operator+(const T& rhs) const
+ {
+ return tvec4(*this) += rhs;
+ }
+
+ // Component-wise addition of another vector to this.
+ // Return a reference to this.
+ tvec4& operator+=(const tvec4& rhs)
+ {
+ x_ += rhs.x_;
+ y_ += rhs.y_;
+ z_ += rhs.z_;
+ w_ += rhs.w_;
+ return *this;
+ }
+
+ // Component-wise addition of another vector to a copy of this.
+ // Return the copy.
+ const tvec4 operator+(const tvec4& rhs) const
+ {
+ return tvec4(*this) += rhs;
+ }
+
+ // Subtract a scalar from this. Return a reference to this.
+ tvec4& operator-=(const T& rhs)
+ {
+ x_ -= rhs;
+ y_ -= rhs;
+ z_ -= rhs;
+ w_ -= rhs;
+ return *this;
+ }
+
+ // Subtract a scalar from a copy of this. Return the copy.
+ const tvec4 operator-(const T& rhs) const
+ {
+ return tvec4(*this) -= rhs;
+ }
+
+ // Component-wise subtraction of another vector from this.
+ // Return a reference to this.
+ tvec4& operator-=(const tvec4& rhs)
+ {
+ x_ -= rhs.x_;
+ y_ -= rhs.y_;
+ z_ -= rhs.z_;
+ w_ -= rhs.w_;
+ return *this;
+ }
+
+ // Component-wise subtraction of another vector from a copy of this.
+ // Return the copy.
+ const tvec4 operator-(const tvec4& rhs) const
+ {
+ return tvec4(*this) -= rhs;
+ }
+
+ // Compute the length of this and return it.
+ float length() const
+ {
+ return sqrt(dot(*this, *this));
+ }
+
+ // Make this a unit vector.
+ void normalize()
+ {
+ float l = length();
+ x_ /= l;
+ y_ /= l;
+ z_ /= l;
+ w_ /= l;
+ }
+
+ // Compute the dot product of two vectors.
+ static T dot(const tvec4& v1, const tvec4& v2)
+ {
+ return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_) + (v1.w_ * v2.w_);
+ }
+
+private:
+ T x_;
+ T y_;
+ T z_;
+ T w_;
+};
+
+//
+// Convenience typedefs. These are here to present a homogeneous view of these
+// objects with respect to shader source.
+//
+typedef tvec2<float> vec2;
+typedef tvec3<float> vec3;
+typedef tvec4<float> vec4;
+
+typedef tvec2<double> dvec2;
+typedef tvec3<double> dvec3;
+typedef tvec4<double> dvec4;
+
+typedef tvec2<int> ivec2;
+typedef tvec3<int> ivec3;
+typedef tvec4<int> ivec4;
+
+typedef tvec2<unsigned int> uvec2;
+typedef tvec3<unsigned int> uvec3;
+typedef tvec4<unsigned int> uvec4;
+
+typedef tvec2<bool> bvec2;
+typedef tvec3<bool> bvec3;
+typedef tvec4<bool> bvec4;
+
+} // namespace LibMatrix
+
+// Global operators to allow for things like defining a new vector in terms of
+// a product of a scalar and a vector
+template<typename T>
+const LibMatrix::tvec2<T> operator*(const T t, const LibMatrix::tvec2<T>& v)
+{
+ return v * t;
+}
+
+template<typename T>
+const LibMatrix::tvec3<T> operator*(const T t, const LibMatrix::tvec3<T>& v)
+{
+ return v * t;
+}
+
+template<typename T>
+const LibMatrix::tvec4<T> operator*(const T t, const LibMatrix::tvec4<T>& v)
+{
+ return v * t;
+}
+
+#endif // VEC_H_
diff --git a/src/libpng/ANNOUNCE b/src/libpng/ANNOUNCE
new file mode 100644
index 0000000..02a24bd
--- /dev/null
+++ b/src/libpng/ANNOUNCE
@@ -0,0 +1,65 @@
+
+Libpng 1.2.46 - July 9, 2011
+
+This is a public release of libpng, intended for use in production codes.
+
+Files available for download:
+
+Source files with LF line endings (for Unix/Linux) and with a
+"configure" script
+
+ libpng-1.2.46.tar.xz (LZMA-compressed, recommended)
+ libpng-1.2.46.tar.gz
+ libpng-1.2.46.tar.bz2
+
+Source files with LF line endings (for Unix/Linux) without the
+"configure" script
+
+ libpng-1.2.46-no-config.tar.xz (LZMA-compressed, recommended)
+ libpng-1.2.46-no-config.tar.gz
+ libpng-1.2.46-no-config.tar.bz2
+
+Source files with CRLF line endings (for Windows), without the
+"configure" script
+
+ lpng1246.zip
+ lpng1246.7z
+ lpng1246.tar.bz2
+
+Project files
+
+ libpng-1.2.46-project-netware.zip
+ libpng-1.2.46-project-wince.zip
+
+Other information:
+
+ libpng-1.2.46-README.txt
+ libpng-1.2.46-KNOWNBUGS.txt
+ libpng-1.2.46-LICENSE.txt
+ libpng-1.2.46-Y2K-compliance.txt
+ libpng-1.2.46-[previous version]-diff.txt
+
+Changes since the last public release (1.2.43):
+
+version 1.2.45 [July 9, 2011]
+
+ Fixed uninitialized memory read in png_format_buffer() (Bug
+ report by Frank Busse, related to CVE-2004-0421).
+ Pass "" instead of '\0' to png_default_error() in png_err(). This mistake
+ was introduced in libpng-1.2.20beta01.
+ Check for up->location !PNG_AFTER_IDAT when writing unknown chunks
+ before IDAT.
+ Ported bugfix in pngrtran.c from 1.5.3: when expanding a paletted image,
+ always expand to RGBA if transparency is present.
+ Check for integer overflow in png_set_rgb_to_gray().
+ Check for sCAL chunk too short.
+ Added CMakeLists.txt, projects/xcode, and pnggccrd.c to EXTRA_DIST in
+ Makefile.am and Makefile.in
+ Udated copyright year to 2011.
+
+Send comments/corrections/commendations to png-mng-implement at lists.sf.net
+(subscription required; visit
+https://lists.sourceforge.net/lists/listinfo/png-mng-implement
+to subscribe) or to glennrp at users.sourceforge.net
+
+Glenn R-P
diff --git a/src/libpng/CMakeLists.txt b/src/libpng/CMakeLists.txt
new file mode 100644
index 0000000..a3ab464
--- /dev/null
+++ b/src/libpng/CMakeLists.txt
@@ -0,0 +1,284 @@
+cmake_minimum_required(VERSION 2.4.3)
+set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
+
+if(UNIX AND NOT DEFINED CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
+ "Choose the type of build, options are:
+ None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used)
+ Debug
+ Release
+ RelWithDebInfo
+ MinSizeRel.")
+endif()
+
+project(libpng C)
+enable_testing()
+
+# Copyright (C) 2007-2010 Glenn Randers-Pehrson
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+set(PNGLIB_MAJOR 1)
+set(PNGLIB_MINOR 2)
+set(PNGLIB_RELEASE 46)
+set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})
+set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})
+
+# needed packages
+find_package(ZLIB REQUIRED)
+include_directories(${ZLIB_INCLUDE_DIR})
+
+if(NOT WIN32)
+ find_library(M_LIBRARY
+ NAMES m
+ PATHS /usr/lib /usr/local/lib
+ )
+ if(NOT M_LIBRARY)
+ message(STATUS
+ "math library 'libm' not found - floating point support disabled")
+ endif()
+else()
+ # not needed on windows
+ set(M_LIBRARY "")
+endif()
+
+# COMMAND LINE OPTIONS
+if(DEFINED PNG_SHARED)
+ option(PNG_SHARED "Build shared lib" ${PNG_SHARED})
+else()
+ option(PNG_SHARED "Build shared lib" ON)
+endif()
+if(DEFINED PNG_STATIC)
+ option(PNG_STATIC "Build static lib" ${PNG_STATIC})
+else()
+ option(PNG_STATIC "Build static lib" ON)
+endif()
+
+if(MINGW)
+ option(PNG_TESTS "Build pngtest" NO)
+else()
+ option(PNG_TESTS "Build pngtest" YES)
+endif()
+
+option(PNG_NO_CONSOLE_IO "FIXME" YES)
+option(PNG_NO_STDIO "FIXME" YES)
+option(PNG_DEBUG "Build with debug output" NO)
+option(PNGARG "FIXME" YES)
+#TODO:
+# PNG_CONSOLE_IO_SUPPORTED
+
+# maybe needs improving, but currently I don't know when we can enable what :)
+set(png_asm_tmp "OFF")
+if(NOT WIN32)
+ find_program(uname_executable NAMES uname PATHS /bin /usr/bin /usr/local/bin)
+ if(uname_executable)
+ exec_program(${uname_executable}
+ ARGS --machine OUTPUT_VARIABLE uname_output)
+ if("uname_output" MATCHES "^.*i[1-9]86.*$")
+ set(png_asm_tmp "ON")
+ else("uname_output" MATCHES "^.*i[1-9]86.*$")
+ set(png_asm_tmp "OFF")
+ endif("uname_output" MATCHES "^.*i[1-9]86.*$")
+ endif(uname_executable)
+else()
+ # this env var is normally only set on win64
+ set(TEXT "ProgramFiles(x86)")
+ if("$ENV{${TEXT}}" STREQUAL "")
+ set(png_asm_tmp "ON")
+ endif("$ENV{${TEXT}}" STREQUAL "")
+endif()
+
+# SET LIBNAME
+set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})
+
+# to distinguish between debug and release lib
+set(CMAKE_DEBUG_POSTFIX "d")
+
+
+# OUR SOURCES
+set(libpng_sources
+ png.h
+ pngconf.h
+ png.c
+ pngerror.c
+ pngget.c
+ pngmem.c
+ pngpread.c
+ pngread.c
+ pngrio.c
+ pngrtran.c
+ pngrutil.c
+ pngset.c
+ pngtrans.c
+ pngwio.c
+ pngwrite.c
+ pngwtran.c
+ pngwutil.c
+)
+set(pngtest_sources
+ pngtest.c
+)
+# SOME NEEDED DEFINITIONS
+
+add_definitions(-DPNG_CONFIGURE_LIBPNG)
+
+if(_AIX)
+ add_definitions(-D_ALL_SOURCE)
+endif(_AIX)
+
+if(MSVC)
+ add_definitions(-DPNG_NO_MODULEDEF -D_CRT_SECURE_NO_DEPRECATE)
+endif(MSVC)
+
+if(PNG_SHARED OR NOT MSVC)
+ #if building msvc static this has NOT to be defined
+ add_definitions(-DZLIB_DLL)
+endif()
+
+add_definitions(-DLIBPNG_NO_MMX)
+add_definitions(-DPNG_NO_MMX_CODE)
+
+
+if(PNG_CONSOLE_IO_SUPPORTED)
+ add_definitions(-DPNG_CONSOLE_IO_SUPPORTED)
+endif()
+
+if(PNG_NO_CONSOLE_IO)
+ add_definitions(-DPNG_NO_CONSOLE_IO)
+endif()
+
+if(PNG_NO_STDIO)
+ add_definitions(-DPNG_NO_STDIO)
+endif()
+
+if(PNG_DEBUG)
+ add_definitions(-DPNG_DEBUG)
+endif()
+
+if(NOT M_LIBRARY AND NOT WIN32)
+ add_definitions(-DPNG_NO_FLOATING_POINT_SUPPORTED)
+endif()
+
+# NOW BUILD OUR TARGET
+include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIR})
+
+if(PNG_SHARED)
+ add_library(${PNG_LIB_NAME} SHARED ${libpng_sources})
+ if(MSVC)
+ # msvc does not append 'lib' - do it here to have consistent name
+ set_target_properties(${PNG_LIB_NAME} PROPERTIES PREFIX "lib")
+ endif()
+ target_link_libraries(${PNG_LIB_NAME} ${ZLIB_LIBRARY} ${M_LIBRARY})
+endif()
+
+if(PNG_STATIC)
+# does not work without changing name
+ set(PNG_LIB_NAME_STATIC ${PNG_LIB_NAME}_static)
+ add_library(${PNG_LIB_NAME_STATIC} STATIC ${libpng_sources})
+ if(MSVC)
+ # msvc does not append 'lib' - do it here to have consistent name
+ set_target_properties(${PNG_LIB_NAME_STATIC} PROPERTIES PREFIX "lib")
+ endif()
+endif()
+
+
+if(PNG_SHARED AND WIN32)
+ set_target_properties(${PNG_LIB_NAME} PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL)
+endif()
+
+if(PNG_TESTS AND PNG_SHARED)
+ # does not work with msvc due to png_lib_ver issue
+ add_executable(pngtest ${pngtest_sources})
+ target_link_libraries(pngtest ${PNG_LIB_NAME})
+ add_test(pngtest pngtest ${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png)
+endif()
+
+
+# CREATE PKGCONFIG FILES
+# we use the same files like ./configure, so we have to set its vars
+set(prefix ${CMAKE_INSTALL_PREFIX})
+set(exec_prefix ${CMAKE_INSTALL_PREFIX})
+set(libdir ${CMAKE_INSTALL_PREFIX}/lib)
+set(includedir ${CMAKE_INSTALL_PREFIX}/include)
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/libpng.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/libpng-config.in
+ ${CMAKE_CURRENT_BINARY_DIR}/libpng-config)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/libpng.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/libpng-config.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config)
+
+# SET UP LINKS
+if(PNG_SHARED)
+ set_target_properties(${PNG_LIB_NAME} PROPERTIES
+# VERSION 0.${PNGLIB_RELEASE}.1.2.46
+ VERSION 0.${PNGLIB_RELEASE}.0
+ SOVERSION 0
+ CLEAN_DIRECT_OUTPUT 1)
+endif()
+if(PNG_STATIC)
+ if(NOT WIN32)
+ # that's uncool on win32 - it overwrites our static import lib...
+ set_target_properties(${PNG_LIB_NAME_STATIC} PROPERTIES
+ OUTPUT_NAME ${PNG_LIB_NAME}
+ CLEAN_DIRECT_OUTPUT 1)
+ endif()
+endif()
+
+# INSTALL
+if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
+ if(PNG_SHARED)
+ install(TARGETS ${PNG_LIB_NAME}
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib)
+ endif()
+ if(PNG_STATIC)
+ install(TARGETS ${PNG_LIB_NAME_STATIC}
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib)
+ endif()
+endif()
+
+if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
+ install(FILES png.h pngconf.h DESTINATION include)
+ install(FILES png.h pngconf.h DESTINATION include/${PNGLIB_NAME})
+endif()
+if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL )
+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config DESTINATION bin)
+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
+ DESTINATION bin)
+endif()
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+ # Install man pages
+ install(FILES libpng.3 libpngpf.3 DESTINATION man/man3)
+ install(FILES png.5 DESTINATION man/man5)
+ # Install pkg-config files
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc
+ DESTINATION lib/pkgconfig)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng-config
+ DESTINATION bin)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc
+ DESTINATION lib/pkgconfig)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
+ DESTINATION bin)
+endif()
+
+# what's with libpng.txt and all the extra files?
+
+
+# UNINSTALL
+# do we need this?
+
+
+# DIST
+# do we need this?
+
+# to create msvc import lib for mingw compiled shared lib
+# pexports libpng.dll > libpng.def
+# lib /def:libpng.def /machine:x86
+
diff --git a/src/libpng/INSTALL b/src/libpng/INSTALL
new file mode 100644
index 0000000..0a5f001
--- /dev/null
+++ b/src/libpng/INSTALL
@@ -0,0 +1,143 @@
+
+Installing libpng version 1.2.46 - July 9, 2011
+
+On Unix/Linux and similar systems, you can simply type
+
+ ./configure [--prefix=/path]
+ make check
+ make install
+
+and ignore the rest of this document.
+
+If configure does not work on your system and you have a reasonably
+up-to-date set of tools, running ./autogen.sh before running ./configure
+may fix the problem. You can also run the individual commands in
+autogen.sh with the --force option, if supported by your version of
+the tools. If you run 'libtoolize --force', though, this will replace
+the distributed, patched, version of ltmain.sh with an unpatched version
+and your shared library builds may fail to produce libraries with the
+correct version numbers.
+
+Instead, you can use one of the custom-built makefiles in the
+"scripts" directory
+
+ cp scripts/makefile.system makefile
+ make test
+ make install
+
+The files that are presently available in the scripts directory
+are listed and described in scripts/README.txt.
+
+Or you can use one of the "projects" in the "projects" directory.
+
+Before installing libpng, you must first install zlib, if it
+is not already on your system. zlib can usually be found
+wherever you got libpng. zlib can be placed in another directory,
+at the same level as libpng.
+
+If you want to use "cmake" (see www.cmake.org), type
+
+ cmake . -DCMAKE_INSTALL_PREFIX=/path
+ make
+ make install
+
+If your system already has a preinstalled zlib you will still need
+to have access to the zlib.h and zconf.h include files that
+correspond to the version of zlib that's installed.
+
+You can rename the directories that you downloaded (they
+might be called "libpng-1.2.46" or "libpng12" and "zlib-1.2.3"
+or "zlib123") so that you have directories called "zlib" and "libpng".
+
+Your directory structure should look like this:
+
+ .. (the parent directory)
+ libpng (this directory)
+ INSTALL (this file)
+ README
+ *.h
+ *.c
+ CMakeLists.txt => "cmake" script
+ configuration files:
+ configure.ac, configure, Makefile.am, Makefile.in,
+ autogen.sh, config.guess, ltmain.sh, missing,
+ aclocal.m4, config.h.in, config.sub,
+ depcomp, install-sh, mkinstalldirs, test-pngtest.sh
+ contrib
+ gregbook
+ pngminim
+ pngminus
+ pngsuite
+ visupng
+ projects
+ cbuilder5 (Borland)
+ visualc6 (msvc)
+ visualc71
+ xcode
+ scripts
+ makefile.*
+ *.def (module definition files)
+ pngtest.png
+ etc.
+ zlib
+ README
+ *.h
+ *.c
+ contrib
+ etc.
+
+If the line endings in the files look funny, you may wish to get the other
+distribution of libpng. It is available in both tar.gz (UNIX style line
+endings) and zip (DOS style line endings) formats.
+
+If you are building libpng with MSVC, you can enter the
+libpng projects\visualc6 or visualc71 directory and follow the instructions
+in README.txt.
+
+Otherwise enter the zlib directory and follow the instructions in zlib/README,
+then come back here and run "configure" or choose the appropriate
+makefile.sys in the scripts directory.
+
+Copy the file (or files) that you need from the
+scripts directory into this directory, for example
+
+ MSDOS example: copy scripts\makefile.msc makefile
+ UNIX example: cp scripts/makefile.std makefile
+
+Read the makefile to see if you need to change any source or
+target directories to match your preferences.
+
+Then read pngconf.h to see if you want to make any configuration
+changes.
+
+Then just run "make" which will create the libpng library in
+this directory and "make test" which will run a quick test that reads
+the "pngtest.png" file and writes a "pngout.png" file that should be
+identical to it. Look for "9782 zero samples" in the output of the
+test. For more confidence, you can run another test by typing
+"pngtest pngnow.png" and looking for "289 zero samples" in the output.
+Also, you can run "pngtest -m contrib/pngsuite/*.png" and compare
+your output with the result shown in contrib/pngsuite/README.
+
+Most of the makefiles will allow you to run "make install" to
+put the library in its final resting place (if you want to
+do that, run "make install" in the zlib directory first if necessary).
+Some also allow you to run "make test-installed" after you have
+run "make install".
+
+If you encounter a compiler error message complaining about the
+lines
+
+ __png.h__ already includes setjmp.h;
+ __dont__ include it again.;
+
+this means you have compiled another module that includes setjmp.h,
+which is hazardous because the two modules might not include exactly
+the same setjmp.h. If you are sure that you know what you are doing
+and that they are exactly the same, then you can comment out or
+delete the two lines. Better yet, use the cexcept interface
+instead, as demonstrated in contrib/visupng of the libpng distribution.
+
+Further information can be found in the README and libpng.txt
+files, in the individual makefiles, in png.h, and the manual pages
+libpng.3 and png.5.
diff --git a/src/libpng/KNOWNBUG b/src/libpng/KNOWNBUG
new file mode 100644
index 0000000..28e83df
--- /dev/null
+++ b/src/libpng/KNOWNBUG
@@ -0,0 +1,22 @@
+
+Known bugs in libpng version 1.2.46
+
+1. February 23, 2006: The custom makefiles don't build libpng with -lz.
+
+ STATUS: This is a subject of debate. The change will probably be made
+ as a part of a major overhaul of the makefiles in libpng version 1.4.0.
+
+2. February 24, 2006: The Makefile generated by the "configure" script
+ fails to install symbolic links
+ libpng12.so => libpng12.so.0.1.2.9betaN
+ that are generated by the custom makefiles.
+
+3. September 4, 2007: There is a report that pngtest crashes on MacOS 10.
+
+ STATUS: workarounds are
+ 1) Compile without optimization (crashes are observed with
+ -arch i386 and -O2 or -O3, using gcc-4.0.1).
+ 2) Compile pngtest.c with PNG_DEBUG defined (the bug goes away if
+ you try to look at it).
+ 3) Ignore the crash. The library itself seems to be OK.
+
diff --git a/src/libpng/LICENSE b/src/libpng/LICENSE
new file mode 100644
index 0000000..0fa9cb7
--- /dev/null
+++ b/src/libpng/LICENSE
@@ -0,0 +1,111 @@
+
+This copy of the libpng notices is provided for your convenience. In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+This code is released under the libpng license.
+
+libpng versions 1.2.6, August 15, 2004, through 1.2.46, July 9, 2011, are
+Copyright (c) 2004, 2006-2009 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.2.5
+with the following individual added to the list of Contributing Authors
+
+ Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+ Simon-Pierre Cadieux
+ Eric S. Raymond
+ Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+ There is no warranty against interference with your enjoyment of the
+ library or against infringement. There is no warranty that our
+ efforts or the library will fulfill any of your particular purposes
+ or needs. This library is provided with all faults, and the entire
+ risk of satisfactory quality, performance, accuracy, and effort is with
+ the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+ Tom Lane
+ Glenn Randers-Pehrson
+ Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+ John Bowler
+ Kevin Bracey
+ Sam Bushell
+ Magnus Holmgren
+ Greg Roelofs
+ Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+ Andreas Dilger
+ Dave Martindale
+ Guy Eric Schalnat
+ Paul Schmidt
+ Tim Wegner
+
+The PNG Reference Library is supplied "AS IS". The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose. The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and must not
+ be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any
+ source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products. If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+ printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+July 9, 2011
diff --git a/src/libpng/README b/src/libpng/README
new file mode 100644
index 0000000..cbff544
--- /dev/null
+++ b/src/libpng/README
@@ -0,0 +1,275 @@
+README for libpng version 1.2.46 - July 9, 2011 (shared library 12.0)
+See the note about version numbers near the top of png.h
+
+See INSTALL for instructions on how to install libpng.
+
+Libpng comes in several distribution formats. Get libpng-*.tar.gz,
+libpng-*.tar.xz, or libpng-*.tar.bz2 if you want UNIX-style line
+endings in the text files, or lpng*.7z or lpng*.zip if you want DOS-style
+line endings. You can get UNIX-style line endings from the *.zip file
+by using "unzip -a" but there seems to be no simple way to recover
+UNIX-style line endings from the *.7z file. The *.tar.xz file is
+recommended for *NIX users instead.
+
+Version 0.89 was the first official release of libpng. Don't let the
+fact that it's the first release fool you. The libpng library has been in
+extensive use and testing since mid-1995. By late 1997 it had
+finally gotten to the stage where there hadn't been significant
+changes to the API in some time, and people have a bad feeling about
+libraries with versions < 1.0. Version 1.0.0 was released in
+March 1998.
+
+****
+Note that some of the changes to the png_info structure render this
+version of the library binary incompatible with libpng-0.89 or
+earlier versions if you are using a shared library. The type of the
+"filler" parameter for png_set_filler() has changed from png_byte to
+png_uint_32, which will affect shared-library applications that use
+this function.
+
+To avoid problems with changes to the internals of png_info_struct,
+new APIs have been made available in 0.95 to avoid direct application
+access to info_ptr. These functions are the png_set_<chunk> and
+png_get_<chunk> functions. These functions should be used when
+accessing/storing the info_struct data, rather than manipulating it
+directly, to avoid such problems in the future.
+
+It is important to note that the APIs do not make current programs
+that access the info struct directly incompatible with the new
+library. However, it is strongly suggested that new programs use
+the new APIs (as shown in example.c and pngtest.c), and older programs
+be converted to the new format, to facilitate upgrades in the future.
+****
+
+Additions since 0.90 include the ability to compile libpng as a
+Windows DLL, and new APIs for accessing data in the info struct.
+Experimental functions include the ability to set weighting and cost
+factors for row filter selection, direct reads of integers from buffers
+on big-endian processors that support misaligned data access, faster
+methods of doing alpha composition, and more accurate 16->8 bit color
+conversion.
+
+The additions since 0.89 include the ability to read from a PNG stream
+which has had some (or all) of the signature bytes read by the calling
+application. This also allows the reading of embedded PNG streams that
+do not have the PNG file signature. As well, it is now possible to set
+the library action on the detection of chunk CRC errors. It is possible
+to set different actions based on whether the CRC error occurred in a
+critical or an ancillary chunk.
+
+The changes made to the library, and bugs fixed are based on discussions
+on the png-mng-implement mailing list and not on material submitted
+privately to Guy, Andreas, or Glenn. They will forward any good
+suggestions to the list.
+
+For a detailed description on using libpng, read libpng.txt. For
+examples of libpng in a program, see example.c and pngtest.c. For usage
+information and restrictions (what little they are) on libpng, see
+png.h. For a description on using zlib (the compression library used by
+libpng) and zlib's restrictions, see zlib.h
+
+I have included a general makefile, as well as several machine and
+compiler specific ones, but you may have to modify one for your own needs.
+
+You should use zlib 1.0.4 or later to run this, but it MAY work with
+versions as old as zlib 0.95. Even so, there are bugs in older zlib
+versions which can cause the output of invalid compression streams for
+some images. You will definitely need zlib 1.0.4 or later if you are
+taking advantage of the MS-DOS "far" structure allocation for the small
+and medium memory models. You should also note that zlib is a
+compression library that is useful for more things than just PNG files.
+You can use zlib as a drop-in replacement for fread() and fwrite() if
+you are so inclined.
+
+zlib should be available at the same place that libpng is, or at
+ftp://ftp.simplesystems.org/pub/png/src/
+
+You may also want a copy of the PNG specification. It is available
+as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find
+these at http://www.libpng.org/pub/png/pngdocs.html
+
+This code is currently being archived at libpng.sf.net in the
+[DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT)
+at GO GRAPHSUP. If you can't find it in any of those places,
+e-mail me, and I'll help you find it.
+
+If you have any code changes, requests, problems, etc., please e-mail
+them to me. Also, I'd appreciate any make files or project files,
+and any modifications you needed to make to get libpng to compile,
+along with a #define variable to tell what compiler/system you are on.
+If you needed to add transformations to libpng, or wish libpng would
+provide the image in a different way, drop me a note (and code, if
+possible), so I can consider supporting the transformation.
+Finally, if you get any warning messages when compiling libpng
+(note: not zlib), and they are easy to fix, I'd appreciate the
+fix. Please mention "libpng" somewhere in the subject line. Thanks.
+
+This release was created and will be supported by myself (of course
+based in a large way on Guy's and Andreas' earlier work), and the PNG
+development group.
+
+Send comments/corrections/commendations to png-mng-implement at lists.sf.net
+(subscription required; visit
+https://lists.sourceforge.net/lists/listinfo/png-mng-implement
+to subscribe) or to glennrp at users.sourceforge.net
+
+You can't reach Guy, the original libpng author, at the addresses
+given in previous versions of this document. He and Andreas will
+read mail addressed to the png-mng-implement list, however.
+
+Please do not send general questions about PNG. Send them to
+the (png-mng-misc at lists.sourceforge.net, subscription required, visit
+https://lists.sourceforge.net/lists/listinfo/png-mng-misc to
+subscribe). On the other hand, please do not send libpng questions to
+that address, send them to me or to the png-mng-implement list. I'll
+get them in the end anyway. If you have a question about something
+in the PNG specification that is related to using libpng, send it
+to me. Send me any questions that start with "I was using libpng,
+and ...". If in doubt, send questions to me. I'll bounce them
+to others, if necessary.
+
+Please do not send suggestions on how to change PNG. We have
+been discussing PNG for twelve years now, and it is official and
+finished. If you have suggestions for libpng, however, I'll
+gladly listen. Even if your suggestion is not used immediately,
+it may be used later.
+
+Files in this distribution:
+
+ ANNOUNCE => Announcement of this version, with recent changes
+ CHANGES => Description of changes between libpng versions
+ KNOWNBUG => List of known bugs and deficiencies
+ LICENSE => License to use and redistribute libpng
+ README => This file
+ TODO => Things not implemented in the current library
+ Y2KINFO => Statement of Y2K compliance
+ example.c => Example code for using libpng functions
+ libpng-*-*-diff.txt => Diff from previous release
+ libpng.3 => manual page for libpng (includes libpng.txt)
+ libpng.txt => Description of libpng and its functions
+ libpngpf.3 => manual page for libpng's private functions
+ png.5 => manual page for the PNG format
+ png.c => Basic interface functions common to library
+ png.h => Library function and interface declarations
+ pngconf.h => System specific library configuration
+ pngerror.c => Error/warning message I/O functions
+ pngget.c => Functions for retrieving info from struct
+ pngmem.c => Memory handling functions
+ pngbar.png => PNG logo, 88x31
+ pngnow.png => PNG logo, 98x31
+ pngpread.c => Progressive reading functions
+ pngread.c => Read data/helper high-level functions
+ pngrio.c => Lowest-level data read I/O functions
+ pngrtran.c => Read data transformation functions
+ pngrutil.c => Read data utility functions
+ pngset.c => Functions for storing data into the info_struct
+ pngtest.c => Library test program
+ pngtest.png => Library test sample image
+ pngtrans.c => Common data transformation functions
+ pngwio.c => Lowest-level write I/O functions
+ pngwrite.c => High-level write functions
+ pngwtran.c => Write data transformations
+ pngwutil.c => Write utility functions
+ contrib => Contributions
+ gregbook => source code for PNG reading and writing, from
+ Greg Roelofs' "PNG: The Definitive Guide",
+ O'Reilly, 1999
+ msvctest => Builds and runs pngtest using a MSVC workspace
+ pngminim => Simple pnm2pngm and png2pnmm programs
+ pngminus => Simple pnm2png and png2pnm programs
+ pngsuite => Test images
+ visupng => Contains a MSVC workspace for VisualPng
+ projects => Contains project files and workspaces for
+ building a DLL
+ beos => Contains a Beos workspace for building libpng
+ c5builder => Contains a Borland workspace for building
+ libpng and zlib
+ netware.txt => Contains instructions for downloading a set
+ of project files for building libpng and
+ zlib on Netware.
+ visualc6 => Contains a Microsoft Visual C++ (MSVC)
+ workspace for building libpng and zlib
+ wince.txt => Contains instructions for downloading a
+ Microsoft Visual C++ (Windows CD Toolkit)
+ workspace for building libpng and zlib on
+ WindowsCE
+ xcode => Contains xcode project files
+ scripts => Directory containing scripts for building libpng:
+ descrip.mms => VMS makefile for MMS or MMK
+ makefile.std => Generic UNIX makefile (cc, creates static
+ libpng.a)
+ makefile.elf => Linux/ELF gcc makefile symbol versioning,
+ creates libpng12.so.0.1.2.46)
+ makefile.linux => Linux/ELF makefile (gcc, creates
+ libpng12.so.0.1.2.46)
+ makefile.gcmmx => Linux/ELF makefile (gcc, creates
+ libpng12.so.0.1.2.46, previously
+ used assembler code tuned for Intel MMX
+ platform)
+ makefile.gcc => Generic makefile (gcc, creates static
+ libpng.a)
+ makefile.knr => Archaic UNIX Makefile that converts files
+ with ansi2knr (Requires ansi2knr.c from
+ ftp://ftp.cs.wisc.edu/ghost)
+ makefile.aix => AIX makefile
+ makefile.cygwin => Cygwin/gcc makefile
+ makefile.darwin => Darwin makefile
+ makefile.dec => DEC Alpha UNIX makefile
+ makefile.freebsd => FreeBSD makefile
+ makefile.hpgcc => HPUX makefile using gcc
+ makefile.hpux => HPUX (10.20 and 11.00) makefile
+ makefile.hp64 => HPUX (10.20 and 11.00) makefile, 64 bit
+ makefile.ibmc => IBM C/C++ version 3.x for Win32 and OS/2
+ (static)
+ makefile.intel => Intel C/C++ version 4.0 and later
+ libpng.icc => Project file, IBM VisualAge/C++ 4.0 or later
+ makefile.netbsd => NetBSD/cc makefile, makes libpng.so.
+ makefile.ne12bsd => NetBSD/cc makefile, makes libpng12.so
+ makefile.openbsd => OpenBSD makefile
+ makefile.sgi => Silicon Graphics IRIX (cc, creates static lib)
+ makefile.sggcc => Silicon Graphics
+ (gcc, creates libpng12.so.0.1.2.46)
+ makefile.sunos => Sun makefile
+ makefile.solaris => Solaris 2.X makefile
+ (gcc, creates libpng12.so.0.1.2.46)
+ makefile.so9 => Solaris 9 makefile
+ (gcc, creates libpng12.so.0.1.2.46)
+ makefile.32sunu => Sun Ultra 32-bit makefile
+ makefile.64sunu => Sun Ultra 64-bit makefile
+ makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc
+ makefile.mips => MIPS makefile
+ makefile.acorn => Acorn makefile
+ makefile.amiga => Amiga makefile
+ smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC
+ compiler (Requires SCOPTIONS, copied from
+ scripts/SCOPTIONS.ppc)
+ makefile.atari => Atari makefile
+ makefile.beos => BEOS makefile for X86
+ makefile.bor => Borland makefile (uses bcc)
+ makefile.bc32 => 32-bit Borland C++ (all modules compiled in C mode)
+ makefile.tc3 => Turbo C 3.0 makefile
+ makefile.dj2 => DJGPP 2 makefile
+ makefile.msc => Microsoft C makefile
+ makefile.vcawin32=> makefile for Microsoft Visual C++ 5.0 and
+ later (previously used assembler code tuned
+ for Intel MMX platform)
+ makefile.vcwin32 => makefile for Microsoft Visual C++ 4.0 and
+ later (does not use assembler code)
+ makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def)
+ pngos2.def => OS/2 module definition file used by makefile.os2
+ makefile.watcom => Watcom 10a+ Makefile, 32-bit flat memory model
+ makevms.com => VMS build script
+ SCOPTIONS.ppc => Used with smakefile.ppc
+
+Good luck, and happy coding.
+
+-Glenn Randers-Pehrson (current maintainer, since 1998)
+ Internet: glennrp at users.sourceforge.net
+
+-Andreas Eric Dilger (former maintainer, 1996-1997)
+ Internet: adilger at enel.ucalgary.ca
+ Web: http://members.shaw.ca/adilger/
+
+-Guy Eric Schalnat (original author and former maintainer, 1995-1996)
+ (formerly of Group 42, Inc)
+ Internet: gschal at infinet.com
diff --git a/src/libpng/TODO b/src/libpng/TODO
new file mode 100644
index 0000000..face765
--- /dev/null
+++ b/src/libpng/TODO
@@ -0,0 +1,25 @@
+TODO - list of things to do for libpng:
+
+Final bug fixes.
+Improve API by hiding the png_struct and png_info structs.
+Finish work on the no-floating-point version (including gamma compensation)
+Better C++ wrapper/full C++ implementation?
+Fix problem with C++ and EXTERN "C".
+cHRM transformation.
+Improve setjmp/longjmp usage or remove it in favor of returning error codes.
+Add "grayscale->palette" transformation and "palette->grayscale" detection.
+Improved dithering.
+Multi-lingual error and warning message support.
+Complete sRGB transformation (presently it simply uses gamma=0.45455).
+Man pages for function calls.
+Better documentation.
+Better filter selection
+ (counting huffman bits/precompression? filter inertia? filter costs?).
+Histogram creation.
+Text conversion between different code pages (Latin-1 -> Mac and DOS).
+Should we always malloc 2^bit_depth PLTE/tRNS/hIST entries for safety?
+Build gamma tables using fixed point (and do away with floating point entirely).
+Use greater precision when changing to linear gamma for compositing against
+ background and doing rgb-to-gray transformation.
+Investigate pre-incremented loop counters and other loop constructions.
+Add interpolated method of handling interlacing.
diff --git a/src/libpng/Y2KINFO b/src/libpng/Y2KINFO
new file mode 100644
index 0000000..0e2a920
--- /dev/null
+++ b/src/libpng/Y2KINFO
@@ -0,0 +1,55 @@
+ Y2K compliance in libpng:
+ =========================
+
+ July 9, 2011
+
+ Since the PNG Development group is an ad-hoc body, we can't make
+ an official declaration.
+
+ This is your unofficial assurance that libpng from version 0.71 and
+ upward through 1.2.46 are Y2K compliant. It is my belief that earlier
+ versions were also Y2K compliant.
+
+ Libpng only has three year fields. One is a 2-byte unsigned integer
+ that will hold years up to 65535. The other two hold the date in text
+ format, and will hold years up to 9999.
+
+ The integer is
+ "png_uint_16 year" in png_time_struct.
+
+ The strings are
+ "png_charp time_buffer" in png_struct and
+ "near_time_buffer", which is a local character string in png.c.
+
+ There are seven time-related functions:
+
+ png_convert_to_rfc_1123() in png.c
+ (formerly png_convert_to_rfc_1152() in error)
+ png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+ png_convert_from_time_t() in pngwrite.c
+ png_get_tIME() in pngget.c
+ png_handle_tIME() in pngrutil.c, called in pngread.c
+ png_set_tIME() in pngset.c
+ png_write_tIME() in pngwutil.c, called in pngwrite.c
+
+ All appear to handle dates properly in a Y2K environment. The
+ png_convert_from_time_t() function calls gmtime() to convert from system
+ clock time, which returns (year - 1900), which we properly convert to
+ the full 4-digit year. There is a possibility that applications using
+ libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+ function, or that they are incorrectly passing only a 2-digit year
+ instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ but this is not under our control. The libpng documentation has always
+ stated that it works with 4-digit years, and the APIs have been
+ documented as such.
+
+ The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
+ integer to hold the year, and can hold years as large as 65535.
+
+ zlib, upon which libpng depends, is also Y2K compliant. It contains
+ no date-related code.
+
+
+ Glenn Randers-Pehrson
+ libpng maintainer
+ PNG Development Group
diff --git a/src/libpng/png.c b/src/libpng/png.c
new file mode 100644
index 0000000..95ea40a
--- /dev/null
+++ b/src/libpng/png.c
@@ -0,0 +1,1100 @@
+
+/* png.c - location for general purpose libpng functions
+ *
+ * Last changed in libpng 1.2.46 [February 25, 2011]
+ * Copyright (c) 1998-2011 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_EXTERN
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef version_1_2_46 Your_png_h_is_not_version_1_2_46;
+
+/* Version information for C files. This had better match the version
+ * string defined in png.h.
+ */
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* png_libpng_ver was changed to a function in version 1.0.5c */
+PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
+
+#ifdef PNG_READ_SUPPORTED
+
+/* png_sig was changed to a function in version 1.0.5c */
+/* Place to hold the signature string for a PNG file. */
+PNG_CONST png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+#endif /* PNG_READ_SUPPORTED */
+
+/* Invoke global declarations for constant strings for known chunk types */
+PNG_IHDR;
+PNG_IDAT;
+PNG_IEND;
+PNG_PLTE;
+PNG_bKGD;
+PNG_cHRM;
+PNG_gAMA;
+PNG_hIST;
+PNG_iCCP;
+PNG_iTXt;
+PNG_oFFs;
+PNG_pCAL;
+PNG_sCAL;
+PNG_pHYs;
+PNG_sBIT;
+PNG_sPLT;
+PNG_sRGB;
+PNG_tEXt;
+PNG_tIME;
+PNG_tRNS;
+PNG_zTXt;
+
+#ifdef PNG_READ_SUPPORTED
+/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+/* Start of interlace block */
+PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+/* Offset to next interlace block */
+PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+/* Start of interlace block in the y direction */
+PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+/* Offset to next interlace block in the y direction */
+PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+/* Height of interlace block. This is not currently used - if you need
+ * it, uncomment it here and in png.h
+PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+*/
+
+/* Mask to determine which pixels are valid in a pass */
+PNG_CONST int FARDATA png_pass_mask[] =
+ {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+
+/* Mask to determine which pixels to overwrite while displaying */
+PNG_CONST int FARDATA png_pass_dsp_mask[]
+ = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+
+#endif /* PNG_READ_SUPPORTED */
+#endif /* PNG_USE_GLOBAL_ARRAYS */
+
+/* Tells libpng that we have already handled the first "num_bytes" bytes
+ * of the PNG file signature. If the PNG data is embedded into another
+ * stream we can set num_bytes = 8 so that libpng will not attempt to read
+ * or write any of the magic bytes before it starts on the IHDR.
+ */
+
+#ifdef PNG_READ_SUPPORTED
+void PNGAPI
+png_set_sig_bytes(png_structp png_ptr, int num_bytes)
+{
+ png_debug(1, "in png_set_sig_bytes");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (num_bytes > 8)
+ png_error(png_ptr, "Too many bytes for PNG signature.");
+
+ png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
+}
+
+/* Checks whether the supplied bytes match the PNG signature. We allow
+ * checking less than the full 8-byte signature so that those apps that
+ * already read the first few bytes of a file to determine the file type
+ * can simply check the remaining bytes for extra assurance. Returns
+ * an integer less than, equal to, or greater than zero if sig is found,
+ * respectively, to be less than, to match, or be greater than the correct
+ * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
+ */
+int PNGAPI
+png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
+{
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+ if (num_to_check > 8)
+ num_to_check = 8;
+ else if (num_to_check < 1)
+ return (-1);
+
+ if (start > 7)
+ return (-1);
+
+ if (start + num_to_check > 8)
+ num_to_check = 8 - start;
+
+ return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
+}
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* (Obsolete) function to check signature bytes. It does not allow one
+ * to check a partial signature. This function might be removed in the
+ * future - use png_sig_cmp(). Returns true (nonzero) if the file is PNG.
+ */
+int PNGAPI
+png_check_sig(png_bytep sig, int num)
+{
+ return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
+}
+#endif
+#endif /* PNG_READ_SUPPORTED */
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Function to allocate memory for zlib and clear it to 0. */
+#ifdef PNG_1_0_X
+voidpf PNGAPI
+#else
+voidpf /* PRIVATE */
+#endif
+png_zalloc(voidpf png_ptr, uInt items, uInt size)
+{
+ png_voidp ptr;
+ png_structp p=(png_structp)png_ptr;
+ png_uint_32 save_flags=p->flags;
+ png_uint_32 num_bytes;
+
+ if (png_ptr == NULL)
+ return (NULL);
+ if (items > PNG_UINT_32_MAX/size)
+ {
+ png_warning (p, "Potential overflow in png_zalloc()");
+ return (NULL);
+ }
+ num_bytes = (png_uint_32)items * size;
+
+ p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
+ ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
+ p->flags=save_flags;
+
+#if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)
+ if (ptr == NULL)
+ return ((voidpf)ptr);
+
+ if (num_bytes > (png_uint_32)0x8000L)
+ {
+ png_memset(ptr, 0, (png_size_t)0x8000L);
+ png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
+ (png_size_t)(num_bytes - (png_uint_32)0x8000L));
+ }
+ else
+ {
+ png_memset(ptr, 0, (png_size_t)num_bytes);
+ }
+#endif
+ return ((voidpf)ptr);
+}
+
+/* Function to free memory for zlib */
+#ifdef PNG_1_0_X
+void PNGAPI
+#else
+void /* PRIVATE */
+#endif
+png_zfree(voidpf png_ptr, voidpf ptr)
+{
+ png_free((png_structp)png_ptr, (png_voidp)ptr);
+}
+
+/* Reset the CRC variable to 32 bits of 1's. Care must be taken
+ * in case CRC is > 32 bits to leave the top bits 0.
+ */
+void /* PRIVATE */
+png_reset_crc(png_structp png_ptr)
+{
+ png_ptr->crc = crc32(0, Z_NULL, 0);
+}
+
+/* Calculate the CRC over a section of data. We can only pass as
+ * much data to this routine as the largest single buffer size. We
+ * also check that this data will actually be used before going to the
+ * trouble of calculating it.
+ */
+void /* PRIVATE */
+png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
+{
+ int need_crc = 1;
+
+ if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+ (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ need_crc = 0;
+ }
+ else /* critical */
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+ need_crc = 0;
+ }
+
+ if (need_crc)
+ png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
+}
+
+/* Allocate the memory for an info_struct for the application. We don't
+ * really need the png_ptr, but it could potentially be useful in the
+ * future. This should be used in favour of malloc(png_sizeof(png_info))
+ * and png_info_init() so that applications that want to use a shared
+ * libpng don't have to be recompiled if png_info changes size.
+ */
+png_infop PNGAPI
+png_create_info_struct(png_structp png_ptr)
+{
+ png_infop info_ptr;
+
+ png_debug(1, "in png_create_info_struct");
+
+ if (png_ptr == NULL)
+ return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
+ png_ptr->malloc_fn, png_ptr->mem_ptr);
+#else
+ info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
+#endif
+ if (info_ptr != NULL)
+ png_info_init_3(&info_ptr, png_sizeof(png_info));
+
+ return (info_ptr);
+}
+
+/* This function frees the memory associated with a single info struct.
+ * Normally, one would use either png_destroy_read_struct() or
+ * png_destroy_write_struct() to free an info struct, but this may be
+ * useful for some applications.
+ */
+void PNGAPI
+png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
+{
+ png_infop info_ptr = NULL;
+
+ png_debug(1, "in png_destroy_info_struct");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (info_ptr_ptr != NULL)
+ info_ptr = *info_ptr_ptr;
+
+ if (info_ptr != NULL)
+ {
+ png_info_destroy(png_ptr, info_ptr);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
+ png_ptr->mem_ptr);
+#else
+ png_destroy_struct((png_voidp)info_ptr);
+#endif
+ *info_ptr_ptr = NULL;
+ }
+}
+
+/* Initialize the info structure. This is now an internal function (0.89)
+ * and applications using it are urged to use png_create_info_struct()
+ * instead.
+ */
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+#undef png_info_init
+void PNGAPI
+png_info_init(png_infop info_ptr)
+{
+ /* We only come here via pre-1.0.12-compiled applications */
+ png_info_init_3(&info_ptr, 0);
+}
+#endif
+
+void PNGAPI
+png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
+{
+ png_infop info_ptr = *ptr_ptr;
+
+ png_debug(1, "in png_info_init_3");
+
+ if (info_ptr == NULL)
+ return;
+
+ if (png_sizeof(png_info) > png_info_struct_size)
+ {
+ png_destroy_struct(info_ptr);
+ info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
+ *ptr_ptr = info_ptr;
+ }
+
+ /* Set everything to 0 */
+ png_memset(info_ptr, 0, png_sizeof(png_info));
+}
+
+#ifdef PNG_FREE_ME_SUPPORTED
+void PNGAPI
+png_data_freer(png_structp png_ptr, png_infop info_ptr,
+ int freer, png_uint_32 mask)
+{
+ png_debug(1, "in png_data_freer");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (freer == PNG_DESTROY_WILL_FREE_DATA)
+ info_ptr->free_me |= mask;
+ else if (freer == PNG_USER_WILL_FREE_DATA)
+ info_ptr->free_me &= ~mask;
+ else
+ png_warning(png_ptr,
+ "Unknown freer parameter in png_data_freer.");
+}
+#endif
+
+void PNGAPI
+png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
+ int num)
+{
+ png_debug(1, "in png_free_data");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+#ifdef PNG_TEXT_SUPPORTED
+ /* Free text item num or (if num == -1) all text items */
+#ifdef PNG_FREE_ME_SUPPORTED
+ if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
+#else
+ if (mask & PNG_FREE_TEXT)
+#endif
+ {
+ if (num != -1)
+ {
+ if (info_ptr->text && info_ptr->text[num].key)
+ {
+ png_free(png_ptr, info_ptr->text[num].key);
+ info_ptr->text[num].key = NULL;
+ }
+ }
+ else
+ {
+ int i;
+ for (i = 0; i < info_ptr->num_text; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
+ png_free(png_ptr, info_ptr->text);
+ info_ptr->text = NULL;
+ info_ptr->num_text=0;
+ }
+ }
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+ /* Free any tRNS entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+ if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
+#else
+ if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
+#endif
+ {
+ png_free(png_ptr, info_ptr->trans);
+ info_ptr->trans = NULL;
+ info_ptr->valid &= ~PNG_INFO_tRNS;
+#ifndef PNG_FREE_ME_SUPPORTED
+ png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
+#endif
+ }
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+ /* Free any sCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+ if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
+#else
+ if (mask & PNG_FREE_SCAL)
+#endif
+ {
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, info_ptr->scal_s_width);
+ png_free(png_ptr, info_ptr->scal_s_height);
+ info_ptr->scal_s_width = NULL;
+ info_ptr->scal_s_height = NULL;
+#endif
+ info_ptr->valid &= ~PNG_INFO_sCAL;
+ }
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+ /* Free any pCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+ if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
+#else
+ if (mask & PNG_FREE_PCAL)
+#endif
+ {
+ png_free(png_ptr, info_ptr->pcal_purpose);
+ png_free(png_ptr, info_ptr->pcal_units);
+ info_ptr->pcal_purpose = NULL;
+ info_ptr->pcal_units = NULL;
+ if (info_ptr->pcal_params != NULL)
+ {
+ int i;
+ for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
+ {
+ png_free(png_ptr, info_ptr->pcal_params[i]);
+ info_ptr->pcal_params[i] = NULL;
+ }
+ png_free(png_ptr, info_ptr->pcal_params);
+ info_ptr->pcal_params = NULL;
+ }
+ info_ptr->valid &= ~PNG_INFO_pCAL;
+ }
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+ /* Free any iCCP entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+ if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
+#else
+ if (mask & PNG_FREE_ICCP)
+#endif
+ {
+ png_free(png_ptr, info_ptr->iccp_name);
+ png_free(png_ptr, info_ptr->iccp_profile);
+ info_ptr->iccp_name = NULL;
+ info_ptr->iccp_profile = NULL;
+ info_ptr->valid &= ~PNG_INFO_iCCP;
+ }
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+ /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
+#ifdef PNG_FREE_ME_SUPPORTED
+ if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
+#else
+ if (mask & PNG_FREE_SPLT)
+#endif
+ {
+ if (num != -1)
+ {
+ if (info_ptr->splt_palettes)
+ {
+ png_free(png_ptr, info_ptr->splt_palettes[num].name);
+ png_free(png_ptr, info_ptr->splt_palettes[num].entries);
+ info_ptr->splt_palettes[num].name = NULL;
+ info_ptr->splt_palettes[num].entries = NULL;
+ }
+ }
+ else
+ {
+ if (info_ptr->splt_palettes_num)
+ {
+ int i;
+ for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
+
+ png_free(png_ptr, info_ptr->splt_palettes);
+ info_ptr->splt_palettes = NULL;
+ info_ptr->splt_palettes_num = 0;
+ }
+ info_ptr->valid &= ~PNG_INFO_sPLT;
+ }
+ }
+#endif
+
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+ if (png_ptr->unknown_chunk.data)
+ {
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
+ }
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
+#else
+ if (mask & PNG_FREE_UNKN)
+#endif
+ {
+ if (num != -1)
+ {
+ if (info_ptr->unknown_chunks)
+ {
+ png_free(png_ptr, info_ptr->unknown_chunks[num].data);
+ info_ptr->unknown_chunks[num].data = NULL;
+ }
+ }
+ else
+ {
+ int i;
+
+ if (info_ptr->unknown_chunks_num)
+ {
+ for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
+
+ png_free(png_ptr, info_ptr->unknown_chunks);
+ info_ptr->unknown_chunks = NULL;
+ info_ptr->unknown_chunks_num = 0;
+ }
+ }
+ }
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+ /* Free any hIST entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+ if ((mask & PNG_FREE_HIST) & info_ptr->free_me)
+#else
+ if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
+#endif
+ {
+ png_free(png_ptr, info_ptr->hist);
+ info_ptr->hist = NULL;
+ info_ptr->valid &= ~PNG_INFO_hIST;
+#ifndef PNG_FREE_ME_SUPPORTED
+ png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
+#endif
+ }
+#endif
+
+ /* Free any PLTE entry that was internally allocated */
+#ifdef PNG_FREE_ME_SUPPORTED
+ if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
+#else
+ if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
+#endif
+ {
+ png_zfree(png_ptr, info_ptr->palette);
+ info_ptr->palette = NULL;
+ info_ptr->valid &= ~PNG_INFO_PLTE;
+#ifndef PNG_FREE_ME_SUPPORTED
+ png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
+#endif
+ info_ptr->num_palette = 0;
+ }
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+ /* Free any image bits attached to the info structure */
+#ifdef PNG_FREE_ME_SUPPORTED
+ if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
+#else
+ if (mask & PNG_FREE_ROWS)
+#endif
+ {
+ if (info_ptr->row_pointers)
+ {
+ int row;
+ for (row = 0; row < (int)info_ptr->height; row++)
+ {
+ png_free(png_ptr, info_ptr->row_pointers[row]);
+ info_ptr->row_pointers[row] = NULL;
+ }
+ png_free(png_ptr, info_ptr->row_pointers);
+ info_ptr->row_pointers = NULL;
+ }
+ info_ptr->valid &= ~PNG_INFO_IDAT;
+ }
+#endif
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ if (num == -1)
+ info_ptr->free_me &= ~mask;
+ else
+ info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
+#endif
+}
+
+/* This is an internal routine to free any memory that the info struct is
+ * pointing to before re-using it or freeing the struct itself. Recall
+ * that png_free() checks for NULL pointers for us.
+ */
+void /* PRIVATE */
+png_info_destroy(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_info_destroy");
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ if (png_ptr->num_chunk_list)
+ {
+ png_free(png_ptr, png_ptr->chunk_list);
+ png_ptr->chunk_list = NULL;
+ png_ptr->num_chunk_list = 0;
+ }
+#endif
+
+ png_info_init_3(&info_ptr, png_sizeof(png_info));
+}
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+/* This function returns a pointer to the io_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy() or png_read_destroy() are called.
+ */
+png_voidp PNGAPI
+png_get_io_ptr(png_structp png_ptr)
+{
+ if (png_ptr == NULL)
+ return (NULL);
+ return (png_ptr->io_ptr);
+}
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+#ifdef PNG_STDIO_SUPPORTED
+/* Initialize the default input/output functions for the PNG file. If you
+ * use your own read or write routines, you can call either png_set_read_fn()
+ * or png_set_write_fn() instead of png_init_io(). If you have defined
+ * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
+ * necessarily available.
+ */
+void PNGAPI
+png_init_io(png_structp png_ptr, png_FILE_p fp)
+{
+ png_debug(1, "in png_init_io");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->io_ptr = (png_voidp)fp;
+}
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+/* Convert the supplied time into an RFC 1123 string suitable for use in
+ * a "Creation Time" or other text-based time string.
+ */
+png_charp PNGAPI
+png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
+{
+ static PNG_CONST char short_months[12][4] =
+ {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+ if (png_ptr == NULL)
+ return (NULL);
+ if (png_ptr->time_buffer == NULL)
+ {
+ png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
+ png_sizeof(char)));
+ }
+
+#ifdef _WIN32_WCE
+ {
+ wchar_t time_buf[29];
+ wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
+ ptime->day % 32, short_months[(ptime->month - 1) % 12],
+ ptime->year, ptime->hour % 24, ptime->minute % 60,
+ ptime->second % 61);
+ WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer,
+ 29, NULL, NULL);
+ }
+#else
+#ifdef USE_FAR_KEYWORD
+ {
+ char near_time_buf[29];
+ png_snprintf6(near_time_buf, 29, "%d %s %d %02d:%02d:%02d +0000",
+ ptime->day % 32, short_months[(ptime->month - 1) % 12],
+ ptime->year, ptime->hour % 24, ptime->minute % 60,
+ ptime->second % 61);
+ png_memcpy(png_ptr->time_buffer, near_time_buf,
+ 29*png_sizeof(char));
+ }
+#else
+ png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000",
+ ptime->day % 32, short_months[(ptime->month - 1) % 12],
+ ptime->year, ptime->hour % 24, ptime->minute % 60,
+ ptime->second % 61);
+#endif
+#endif /* _WIN32_WCE */
+ return ((png_charp)png_ptr->time_buffer);
+}
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+png_charp PNGAPI
+png_get_copyright(png_structp png_ptr)
+{
+ png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
+#ifdef PNG_STRING_COPYRIGHT
+ return PNG_STRING_COPYRIGHT
+#else
+#ifdef __STDC__
+ return ((png_charp) PNG_STRING_NEWLINE \
+ "libpng version 1.2.46 - July 9, 2011" PNG_STRING_NEWLINE \
+ "Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
+ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
+ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
+ PNG_STRING_NEWLINE);
+#else
+ return ((png_charp) "libpng version 1.2.46 - July 9, 2011\
+ Copyright (c) 1998-2011 Glenn Randers-Pehrson\
+ Copyright (c) 1996-1997 Andreas Dilger\
+ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.");
+#endif
+#endif
+}
+
+/* The following return the library version as a short string in the
+ * format 1.0.0 through 99.99.99zz. To get the version of *.h files
+ * used with your application, print out PNG_LIBPNG_VER_STRING, which
+ * is defined in png.h.
+ * Note: now there is no difference between png_get_libpng_ver() and
+ * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
+ * it is guaranteed that png.c uses the correct version of png.h.
+ */
+png_charp PNGAPI
+png_get_libpng_ver(png_structp png_ptr)
+{
+ /* Version of *.c files used when building libpng */
+ png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
+ return ((png_charp) PNG_LIBPNG_VER_STRING);
+}
+
+png_charp PNGAPI
+png_get_header_ver(png_structp png_ptr)
+{
+ /* Version of *.h files used when building libpng */
+ png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
+ return ((png_charp) PNG_LIBPNG_VER_STRING);
+}
+
+png_charp PNGAPI
+png_get_header_version(png_structp png_ptr)
+{
+ /* Returns longer string containing both version and date */
+ png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */
+#ifdef __STDC__
+ return ((png_charp) PNG_HEADER_VERSION_STRING
+#ifndef PNG_READ_SUPPORTED
+ " (NO READ SUPPORT)"
+#endif
+ PNG_STRING_NEWLINE);
+#else
+ return ((png_charp) PNG_HEADER_VERSION_STRING);
+#endif
+}
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+int PNGAPI
+png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
+{
+ /* Check chunk_name and return "keep" value if it's on the list, else 0 */
+ int i;
+ png_bytep p;
+ if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
+ return 0;
+ p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5;
+ for (i = png_ptr->num_chunk_list; i; i--, p -= 5)
+ if (!png_memcmp(chunk_name, p, 4))
+ return ((int)*(p + 4));
+ return 0;
+}
+#endif
+
+/* This function, added to libpng-1.0.6g, is untested. */
+int PNGAPI
+png_reset_zstream(png_structp png_ptr)
+{
+ if (png_ptr == NULL)
+ return Z_STREAM_ERROR;
+ return (inflateReset(&png_ptr->zstream));
+}
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+/* This function was added to libpng-1.0.7 */
+png_uint_32 PNGAPI
+png_access_version_number(void)
+{
+ /* Version of *.c files used when building libpng */
+ return((png_uint_32) PNG_LIBPNG_VER);
+}
+
+
+#if defined(PNG_READ_SUPPORTED) && defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+#ifndef PNG_1_0_X
+/* This function was added to libpng 1.2.0 */
+int PNGAPI
+png_mmx_support(void)
+{
+ /* Obsolete, to be removed from libpng-1.4.0 */
+ return -1;
+}
+#endif /* PNG_1_0_X */
+#endif /* PNG_READ_SUPPORTED && PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+#ifdef PNG_SIZE_T
+/* Added at libpng version 1.2.6 */
+ PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
+png_size_t PNGAPI
+png_convert_size(size_t size)
+{
+ if (size > (png_size_t)-1)
+ PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */
+ return ((png_size_t)size);
+}
+#endif /* PNG_SIZE_T */
+
+/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_CHECK_cHRM_SUPPORTED
+
+/*
+ * Multiply two 32-bit numbers, V1 and V2, using 32-bit
+ * arithmetic, to produce a 64 bit result in the HI/LO words.
+ *
+ * A B
+ * x C D
+ * ------
+ * AD || BD
+ * AC || CB || 0
+ *
+ * where A and B are the high and low 16-bit words of V1,
+ * C and D are the 16-bit words of V2, AD is the product of
+ * A and D, and X || Y is (X << 16) + Y.
+*/
+
+void /* PRIVATE */
+png_64bit_product (long v1, long v2, unsigned long *hi_product,
+ unsigned long *lo_product)
+{
+ int a, b, c, d;
+ long lo, hi, x, y;
+
+ a = (v1 >> 16) & 0xffff;
+ b = v1 & 0xffff;
+ c = (v2 >> 16) & 0xffff;
+ d = v2 & 0xffff;
+
+ lo = b * d; /* BD */
+ x = a * d + c * b; /* AD + CB */
+ y = ((lo >> 16) & 0xffff) + x;
+
+ lo = (lo & 0xffff) | ((y & 0xffff) << 16);
+ hi = (y >> 16) & 0xffff;
+
+ hi += a * c; /* AC */
+
+ *hi_product = (unsigned long)hi;
+ *lo_product = (unsigned long)lo;
+}
+
+int /* PRIVATE */
+png_check_cHRM_fixed(png_structp png_ptr,
+ png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
+ png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
+ png_fixed_point blue_x, png_fixed_point blue_y)
+{
+ int ret = 1;
+ unsigned long xy_hi,xy_lo,yx_hi,yx_lo;
+
+ png_debug(1, "in function png_check_cHRM_fixed");
+
+ if (png_ptr == NULL)
+ return 0;
+
+ if (white_x < 0 || white_y <= 0 ||
+ red_x < 0 || red_y < 0 ||
+ green_x < 0 || green_y < 0 ||
+ blue_x < 0 || blue_y < 0)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set negative chromaticity value");
+ ret = 0;
+ }
+ if (white_x > (png_fixed_point) PNG_UINT_31_MAX ||
+ white_y > (png_fixed_point) PNG_UINT_31_MAX ||
+ red_x > (png_fixed_point) PNG_UINT_31_MAX ||
+ red_y > (png_fixed_point) PNG_UINT_31_MAX ||
+ green_x > (png_fixed_point) PNG_UINT_31_MAX ||
+ green_y > (png_fixed_point) PNG_UINT_31_MAX ||
+ blue_x > (png_fixed_point) PNG_UINT_31_MAX ||
+ blue_y > (png_fixed_point) PNG_UINT_31_MAX )
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set chromaticity value exceeding 21474.83");
+ ret = 0;
+ }
+ if (white_x > 100000L - white_y)
+ {
+ png_warning(png_ptr, "Invalid cHRM white point");
+ ret = 0;
+ }
+ if (red_x > 100000L - red_y)
+ {
+ png_warning(png_ptr, "Invalid cHRM red point");
+ ret = 0;
+ }
+ if (green_x > 100000L - green_y)
+ {
+ png_warning(png_ptr, "Invalid cHRM green point");
+ ret = 0;
+ }
+ if (blue_x > 100000L - blue_y)
+ {
+ png_warning(png_ptr, "Invalid cHRM blue point");
+ ret = 0;
+ }
+
+ png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo);
+ png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo);
+
+ if (xy_hi == yx_hi && xy_lo == yx_lo)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set cHRM RGB triangle with zero area");
+ ret = 0;
+ }
+
+ return ret;
+}
+#endif /* PNG_CHECK_cHRM_SUPPORTED */
+#endif /* PNG_cHRM_SUPPORTED */
+
+void /* PRIVATE */
+png_check_IHDR(png_structp png_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type)
+{
+ int error = 0;
+
+ /* Check for width and height valid values */
+ if (width == 0)
+ {
+ png_warning(png_ptr, "Image width is zero in IHDR");
+ error = 1;
+ }
+
+ if (height == 0)
+ {
+ png_warning(png_ptr, "Image height is zero in IHDR");
+ error = 1;
+ }
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (width > png_ptr->user_width_max || width > PNG_USER_WIDTH_MAX)
+#else
+ if (width > PNG_USER_WIDTH_MAX)
+#endif
+ {
+ png_warning(png_ptr, "Image width exceeds user limit in IHDR");
+ error = 1;
+ }
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (height > png_ptr->user_height_max || height > PNG_USER_HEIGHT_MAX)
+#else
+ if (height > PNG_USER_HEIGHT_MAX)
+#endif
+ {
+ png_warning(png_ptr, "Image height exceeds user limit in IHDR");
+ error = 1;
+ }
+
+ if (width > PNG_UINT_31_MAX)
+ {
+ png_warning(png_ptr, "Invalid image width in IHDR");
+ error = 1;
+ }
+
+ if ( height > PNG_UINT_31_MAX)
+ {
+ png_warning(png_ptr, "Invalid image height in IHDR");
+ error = 1;
+ }
+
+ if ( width > (PNG_UINT_32_MAX
+ >> 3) /* 8-byte RGBA pixels */
+ - 64 /* bigrowbuf hack */
+ - 1 /* filter byte */
+ - 7*8 /* rounding of width to multiple of 8 pixels */
+ - 8) /* extra max_pixel_depth pad */
+ png_warning(png_ptr, "Width is too large for libpng to process pixels");
+
+ /* Check other values */
+ if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
+ bit_depth != 8 && bit_depth != 16)
+ {
+ png_warning(png_ptr, "Invalid bit depth in IHDR");
+ error = 1;
+ }
+
+ if (color_type < 0 || color_type == 1 ||
+ color_type == 5 || color_type > 6)
+ {
+ png_warning(png_ptr, "Invalid color type in IHDR");
+ error = 1;
+ }
+
+ if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
+ ((color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
+ {
+ png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
+ error = 1;
+ }
+
+ if (interlace_type >= PNG_INTERLACE_LAST)
+ {
+ png_warning(png_ptr, "Unknown interlace method in IHDR");
+ error = 1;
+ }
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Unknown compression method in IHDR");
+ error = 1;
+ }
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ /* Accept filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not read a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) &&
+ png_ptr->mng_features_permitted)
+ png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
+
+ if (filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
+ ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
+ (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
+ {
+ png_warning(png_ptr, "Unknown filter method in IHDR");
+ error = 1;
+ }
+
+ if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE)
+ {
+ png_warning(png_ptr, "Invalid filter method in IHDR");
+ error = 1;
+ }
+ }
+
+#else
+ if (filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Unknown filter method in IHDR");
+ error = 1;
+ }
+#endif
+
+ if (error == 1)
+ png_error(png_ptr, "Invalid IHDR data");
+}
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
diff --git a/src/libpng/png.h b/src/libpng/png.h
new file mode 100644
index 0000000..42e7013
--- /dev/null
+++ b/src/libpng/png.h
@@ -0,0 +1,3796 @@
+/* png.h - header file for PNG reference library
+ *
+ * libpng version 1.2.46 - July 9, 2011
+ * Copyright (c) 1998-2011 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license (See LICENSE, below)
+ *
+ * Authors and maintainers:
+ * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
+ * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
+ * libpng versions 0.97, January 1998, through 1.2.46 - July 9, 2011: Glenn
+ * See also "Contributing Authors", below.
+ *
+ * Note about libpng version numbers:
+ *
+ * Due to various miscommunications, unforeseen code incompatibilities
+ * and occasional factors outside the authors' control, version numbering
+ * on the library has not always been consistent and straightforward.
+ * The following table summarizes matters since version 0.89c, which was
+ * the first widely used release:
+ *
+ * source png.h png.h shared-lib
+ * version string int version
+ * ------- ------ ----- ----------
+ * 0.89c "1.0 beta 3" 0.89 89 1.0.89
+ * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90]
+ * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95]
+ * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96]
+ * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97]
+ * 0.97c 0.97 97 2.0.97
+ * 0.98 0.98 98 2.0.98
+ * 0.99 0.99 98 2.0.99
+ * 0.99a-m 0.99 99 2.0.99
+ * 1.00 1.00 100 2.1.0 [100 should be 10000]
+ * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000]
+ * 1.0.1 png.h string is 10001 2.1.0
+ * 1.0.1a-e identical to the 10002 from here on, the shared library
+ * 1.0.2 source version) 10002 is 2.V where V is the source code
+ * 1.0.2a-b 10003 version, except as noted.
+ * 1.0.3 10003
+ * 1.0.3a-d 10004
+ * 1.0.4 10004
+ * 1.0.4a-f 10005
+ * 1.0.5 (+ 2 patches) 10005
+ * 1.0.5a-d 10006
+ * 1.0.5e-r 10100 (not source compatible)
+ * 1.0.5s-v 10006 (not binary compatible)
+ * 1.0.6 (+ 3 patches) 10006 (still binary incompatible)
+ * 1.0.6d-f 10007 (still binary incompatible)
+ * 1.0.6g 10007
+ * 1.0.6h 10007 10.6h (testing xy.z so-numbering)
+ * 1.0.6i 10007 10.6i
+ * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0)
+ * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible)
+ * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible)
+ * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible)
+ * 1.0.7 1 10007 (still compatible)
+ * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4
+ * 1.0.8rc1 1 10008 2.1.0.8rc1
+ * 1.0.8 1 10008 2.1.0.8
+ * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6
+ * 1.0.9rc1 1 10009 2.1.0.9rc1
+ * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10
+ * 1.0.9rc2 1 10009 2.1.0.9rc2
+ * 1.0.9 1 10009 2.1.0.9
+ * 1.0.10beta1 1 10010 2.1.0.10beta1
+ * 1.0.10rc1 1 10010 2.1.0.10rc1
+ * 1.0.10 1 10010 2.1.0.10
+ * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3
+ * 1.0.11rc1 1 10011 2.1.0.11rc1
+ * 1.0.11 1 10011 2.1.0.11
+ * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2
+ * 1.0.12rc1 2 10012 2.1.0.12rc1
+ * 1.0.12 2 10012 2.1.0.12
+ * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned)
+ * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2
+ * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5
+ * 1.2.0rc1 3 10200 3.1.2.0rc1
+ * 1.2.0 3 10200 3.1.2.0
+ * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4
+ * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2
+ * 1.2.1 3 10201 3.1.2.1
+ * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6
+ * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1
+ * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1
+ * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1
+ * 1.0.13 10 10013 10.so.0.1.0.13
+ * 1.2.2 12 10202 12.so.0.1.2.2
+ * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6
+ * 1.2.3 12 10203 12.so.0.1.2.3
+ * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3
+ * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1
+ * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1
+ * 1.0.14 10 10014 10.so.0.1.0.14
+ * 1.2.4 13 10204 12.so.0.1.2.4
+ * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2
+ * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3
+ * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3
+ * 1.0.15 10 10015 10.so.0.1.0.15
+ * 1.2.5 13 10205 12.so.0.1.2.5
+ * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4
+ * 1.0.16 10 10016 10.so.0.1.0.16
+ * 1.2.6 13 10206 12.so.0.1.2.6
+ * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2
+ * 1.0.17rc1 10 10017 10.so.0.1.0.17rc1
+ * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1
+ * 1.0.17 10 10017 10.so.0.1.0.17
+ * 1.2.7 13 10207 12.so.0.1.2.7
+ * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5
+ * 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5
+ * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5
+ * 1.0.18 10 10018 10.so.0.1.0.18
+ * 1.2.8 13 10208 12.so.0.1.2.8
+ * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3
+ * 1.2.9beta4-11 13 10209 12.so.0.9[.0]
+ * 1.2.9rc1 13 10209 12.so.0.9[.0]
+ * 1.2.9 13 10209 12.so.0.9[.0]
+ * 1.2.10beta1-8 13 10210 12.so.0.10[.0]
+ * 1.2.10rc1-3 13 10210 12.so.0.10[.0]
+ * 1.2.10 13 10210 12.so.0.10[.0]
+ * 1.2.11beta1-4 13 10211 12.so.0.11[.0]
+ * 1.0.19rc1-5 10 10019 10.so.0.19[.0]
+ * 1.2.11rc1-5 13 10211 12.so.0.11[.0]
+ * 1.0.19 10 10019 10.so.0.19[.0]
+ * 1.2.11 13 10211 12.so.0.11[.0]
+ * 1.0.20 10 10020 10.so.0.20[.0]
+ * 1.2.12 13 10212 12.so.0.12[.0]
+ * 1.2.13beta1 13 10213 12.so.0.13[.0]
+ * 1.0.21 10 10021 10.so.0.21[.0]
+ * 1.2.13 13 10213 12.so.0.13[.0]
+ * 1.2.14beta1-2 13 10214 12.so.0.14[.0]
+ * 1.0.22rc1 10 10022 10.so.0.22[.0]
+ * 1.2.14rc1 13 10214 12.so.0.14[.0]
+ * 1.0.22 10 10022 10.so.0.22[.0]
+ * 1.2.14 13 10214 12.so.0.14[.0]
+ * 1.2.15beta1-6 13 10215 12.so.0.15[.0]
+ * 1.0.23rc1-5 10 10023 10.so.0.23[.0]
+ * 1.2.15rc1-5 13 10215 12.so.0.15[.0]
+ * 1.0.23 10 10023 10.so.0.23[.0]
+ * 1.2.15 13 10215 12.so.0.15[.0]
+ * 1.2.16beta1-2 13 10216 12.so.0.16[.0]
+ * 1.2.16rc1 13 10216 12.so.0.16[.0]
+ * 1.0.24 10 10024 10.so.0.24[.0]
+ * 1.2.16 13 10216 12.so.0.16[.0]
+ * 1.2.17beta1-2 13 10217 12.so.0.17[.0]
+ * 1.0.25rc1 10 10025 10.so.0.25[.0]
+ * 1.2.17rc1-3 13 10217 12.so.0.17[.0]
+ * 1.0.25 10 10025 10.so.0.25[.0]
+ * 1.2.17 13 10217 12.so.0.17[.0]
+ * 1.0.26 10 10026 10.so.0.26[.0]
+ * 1.2.18 13 10218 12.so.0.18[.0]
+ * 1.2.19beta1-31 13 10219 12.so.0.19[.0]
+ * 1.0.27rc1-6 10 10027 10.so.0.27[.0]
+ * 1.2.19rc1-6 13 10219 12.so.0.19[.0]
+ * 1.0.27 10 10027 10.so.0.27[.0]
+ * 1.2.19 13 10219 12.so.0.19[.0]
+ * 1.2.20beta01-04 13 10220 12.so.0.20[.0]
+ * 1.0.28rc1-6 10 10028 10.so.0.28[.0]
+ * 1.2.20rc1-6 13 10220 12.so.0.20[.0]
+ * 1.0.28 10 10028 10.so.0.28[.0]
+ * 1.2.20 13 10220 12.so.0.20[.0]
+ * 1.2.21beta1-2 13 10221 12.so.0.21[.0]
+ * 1.2.21rc1-3 13 10221 12.so.0.21[.0]
+ * 1.0.29 10 10029 10.so.0.29[.0]
+ * 1.2.21 13 10221 12.so.0.21[.0]
+ * 1.2.22beta1-4 13 10222 12.so.0.22[.0]
+ * 1.0.30rc1 10 10030 10.so.0.30[.0]
+ * 1.2.22rc1 13 10222 12.so.0.22[.0]
+ * 1.0.30 10 10030 10.so.0.30[.0]
+ * 1.2.22 13 10222 12.so.0.22[.0]
+ * 1.2.23beta01-05 13 10223 12.so.0.23[.0]
+ * 1.2.23rc01 13 10223 12.so.0.23[.0]
+ * 1.2.23 13 10223 12.so.0.23[.0]
+ * 1.2.24beta01-02 13 10224 12.so.0.24[.0]
+ * 1.2.24rc01 13 10224 12.so.0.24[.0]
+ * 1.2.24 13 10224 12.so.0.24[.0]
+ * 1.2.25beta01-06 13 10225 12.so.0.25[.0]
+ * 1.2.25rc01-02 13 10225 12.so.0.25[.0]
+ * 1.0.31 10 10031 10.so.0.31[.0]
+ * 1.2.25 13 10225 12.so.0.25[.0]
+ * 1.2.26beta01-06 13 10226 12.so.0.26[.0]
+ * 1.2.26rc01 13 10226 12.so.0.26[.0]
+ * 1.2.26 13 10226 12.so.0.26[.0]
+ * 1.0.32 10 10032 10.so.0.32[.0]
+ * 1.2.27beta01-06 13 10227 12.so.0.27[.0]
+ * 1.2.27rc01 13 10227 12.so.0.27[.0]
+ * 1.0.33 10 10033 10.so.0.33[.0]
+ * 1.2.27 13 10227 12.so.0.27[.0]
+ * 1.0.34 10 10034 10.so.0.34[.0]
+ * 1.2.28 13 10228 12.so.0.28[.0]
+ * 1.2.29beta01-03 13 10229 12.so.0.29[.0]
+ * 1.2.29rc01 13 10229 12.so.0.29[.0]
+ * 1.0.35 10 10035 10.so.0.35[.0]
+ * 1.2.29 13 10229 12.so.0.29[.0]
+ * 1.0.37 10 10037 10.so.0.37[.0]
+ * 1.2.30beta01-04 13 10230 12.so.0.30[.0]
+ * 1.0.38rc01-08 10 10038 10.so.0.38[.0]
+ * 1.2.30rc01-08 13 10230 12.so.0.30[.0]
+ * 1.0.38 10 10038 10.so.0.38[.0]
+ * 1.2.30 13 10230 12.so.0.30[.0]
+ * 1.0.39rc01-03 10 10039 10.so.0.39[.0]
+ * 1.2.31rc01-03 13 10231 12.so.0.31[.0]
+ * 1.0.39 10 10039 10.so.0.39[.0]
+ * 1.2.31 13 10231 12.so.0.31[.0]
+ * 1.2.32beta01-02 13 10232 12.so.0.32[.0]
+ * 1.0.40rc01 10 10040 10.so.0.40[.0]
+ * 1.2.32rc01 13 10232 12.so.0.32[.0]
+ * 1.0.40 10 10040 10.so.0.40[.0]
+ * 1.2.32 13 10232 12.so.0.32[.0]
+ * 1.2.33beta01-02 13 10233 12.so.0.33[.0]
+ * 1.2.33rc01-02 13 10233 12.so.0.33[.0]
+ * 1.0.41rc01 10 10041 10.so.0.41[.0]
+ * 1.2.33 13 10233 12.so.0.33[.0]
+ * 1.0.41 10 10041 10.so.0.41[.0]
+ * 1.2.34beta01-07 13 10234 12.so.0.34[.0]
+ * 1.0.42rc01 10 10042 10.so.0.42[.0]
+ * 1.2.34rc01 13 10234 12.so.0.34[.0]
+ * 1.0.42 10 10042 10.so.0.42[.0]
+ * 1.2.34 13 10234 12.so.0.34[.0]
+ * 1.2.35beta01-03 13 10235 12.so.0.35[.0]
+ * 1.0.43rc01-02 10 10043 10.so.0.43[.0]
+ * 1.2.35rc01-02 13 10235 12.so.0.35[.0]
+ * 1.0.43 10 10043 10.so.0.43[.0]
+ * 1.2.35 13 10235 12.so.0.35[.0]
+ * 1.2.36beta01-05 13 10236 12.so.0.36[.0]
+ * 1.2.36rc01 13 10236 12.so.0.36[.0]
+ * 1.0.44 10 10044 10.so.0.44[.0]
+ * 1.2.36 13 10236 12.so.0.36[.0]
+ * 1.2.37beta01-03 13 10237 12.so.0.37[.0]
+ * 1.2.37rc01 13 10237 12.so.0.37[.0]
+ * 1.2.37 13 10237 12.so.0.37[.0]
+ * 1.0.45 10 10045 12.so.0.45[.0]
+ * 1.0.46 10 10046 10.so.0.46[.0]
+ * 1.2.38beta01 13 10238 12.so.0.38[.0]
+ * 1.2.38rc01-03 13 10238 12.so.0.38[.0]
+ * 1.0.47 10 10047 10.so.0.47[.0]
+ * 1.2.38 13 10238 12.so.0.38[.0]
+ * 1.2.39beta01-05 13 10239 12.so.0.39[.0]
+ * 1.2.39rc01 13 10239 12.so.0.39[.0]
+ * 1.0.48 10 10048 10.so.0.48[.0]
+ * 1.2.39 13 10239 12.so.0.39[.0]
+ * 1.2.40beta01 13 10240 12.so.0.40[.0]
+ * 1.2.40rc01 13 10240 12.so.0.40[.0]
+ * 1.0.49 10 10049 10.so.0.49[.0]
+ * 1.2.40 13 10240 12.so.0.40[.0]
+ * 1.2.41beta01-18 13 10241 12.so.0.41[.0]
+ * 1.0.51rc01 10 10051 10.so.0.51[.0]
+ * 1.2.41rc01-03 13 10241 12.so.0.41[.0]
+ * 1.0.51 10 10051 10.so.0.51[.0]
+ * 1.2.41 13 10241 12.so.0.41[.0]
+ * 1.2.42beta01-02 13 10242 12.so.0.42[.0]
+ * 1.2.42rc01-05 13 10242 12.so.0.42[.0]
+ * 1.0.52 10 10052 10.so.0.52[.0]
+ * 1.2.42 13 10242 12.so.0.42[.0]
+ * 1.2.43beta01-05 13 10243 12.so.0.43[.0]
+ * 1.0.53rc01-02 10 10053 10.so.0.53[.0]
+ * 1.2.43rc01-02 13 10243 12.so.0.43[.0]
+ * 1.0.53 10 10053 10.so.0.53[.0]
+ * 1.2.43 13 10243 12.so.0.43[.0]
+ * 1.2.44beta01-03 13 10244 12.so.0.44[.0]
+ * 1.2.44rc01-03 13 10244 12.so.0.44[.0]
+ * 1.2.44 13 10244 12.so.0.44[.0]
+ * 1.2.45beta01-03 13 10245 12.so.0.45[.0]
+ * 1.0.55rc01 10 10055 10.so.0.55[.0]
+ * 1.2.45rc01 13 10245 12.so.0.45[.0]
+ * 1.0.55 10 10055 10.so.0.55[.0]
+ * 1.2.45 13 10245 12.so.0.45[.0]
+ * 1.2.46rc01-02 13 10246 12.so.0.46[.0]
+ * 1.0.56 10 10056 10.so.0.56[.0]
+ * 1.2.46 13 10246 12.so.0.46[.0]
+ *
+ * Henceforth the source version will match the shared-library major
+ * and minor numbers; the shared-library major version number will be
+ * used for changes in backward compatibility, as it is intended. The
+ * PNG_LIBPNG_VER macro, which is not used within libpng but is available
+ * for applications, is an unsigned integer of the form xyyzz corresponding
+ * to the source version x.y.z (leading zeros in y and z). Beta versions
+ * were given the previous public release number plus a letter, until
+ * version 1.0.6j; from then on they were given the upcoming public
+ * release number plus "betaNN" or "rcNN".
+ *
+ * Binary incompatibility exists only when applications make direct access
+ * to the info_ptr or png_ptr members through png.h, and the compiled
+ * application is loaded with a different version of the library.
+ *
+ * DLLNUM will change each time there are forward or backward changes
+ * in binary compatibility (e.g., when a new feature is added).
+ *
+ * See libpng.txt or libpng.3 for more information. The PNG specification
+ * is available as a W3C Recommendation and as an ISO Specification,
+ * <http://www.w3.org/TR/2003/REC-PNG-20031110/
+ */
+
+/*
+ * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ *
+ * If you modify libpng you may insert additional notices immediately following
+ * this sentence.
+ *
+ * This code is released under the libpng license.
+ *
+ * libpng versions 1.2.6, August 15, 2004, through 1.2.46, July 9, 2011, are
+ * Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.2.5
+ * with the following individual added to the list of Contributing Authors:
+ *
+ * Cosmin Truta
+ *
+ * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
+ * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.0.6
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ * Simon-Pierre Cadieux
+ * Eric S. Raymond
+ * Gilles Vollant
+ *
+ * and with the following additions to the disclaimer:
+ *
+ * There is no warranty against interference with your enjoyment of the
+ * library or against infringement. There is no warranty that our
+ * efforts or the library will fulfill any of your particular purposes
+ * or needs. This library is provided with all faults, and the entire
+ * risk of satisfactory quality, performance, accuracy, and effort is with
+ * the user.
+ *
+ * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+ * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-0.96,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ * Tom Lane
+ * Glenn Randers-Pehrson
+ * Willem van Schaik
+ *
+ * libpng versions 0.89, June 1996, through 0.96, May 1997, are
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Distributed according to the same disclaimer and license as libpng-0.88,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ * John Bowler
+ * Kevin Bracey
+ * Sam Bushell
+ * Magnus Holmgren
+ * Greg Roelofs
+ * Tom Tanner
+ *
+ * libpng versions 0.5, May 1995, through 0.88, January 1996, are
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ *
+ * For the purposes of this copyright and license, "Contributing Authors"
+ * is defined as the following set of individuals:
+ *
+ * Andreas Dilger
+ * Dave Martindale
+ * Guy Eric Schalnat
+ * Paul Schmidt
+ * Tim Wegner
+ *
+ * The PNG Reference Library is supplied "AS IS". The Contributing Authors
+ * and Group 42, Inc. disclaim all warranties, expressed or implied,
+ * including, without limitation, the warranties of merchantability and of
+ * fitness for any purpose. The Contributing Authors and Group 42, Inc.
+ * assume no liability for direct, indirect, incidental, special, exemplary,
+ * or consequential damages, which may result from the use of the PNG
+ * Reference Library, even if advised of the possibility of such damage.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute this
+ * source code, or portions hereof, for any purpose, without fee, subject
+ * to the following restrictions:
+ *
+ * 1. The origin of this source code must not be misrepresented.
+ *
+ * 2. Altered versions must be plainly marked as such and
+ * must not be misrepresented as being the original source.
+ *
+ * 3. This Copyright notice may not be removed or altered from
+ * any source or altered source distribution.
+ *
+ * The Contributing Authors and Group 42, Inc. specifically permit, without
+ * fee, and encourage the use of this source code as a component to
+ * supporting the PNG file format in commercial products. If you use this
+ * source code in a product, acknowledgment is not required but would be
+ * appreciated.
+ */
+
+/*
+ * A "png_get_copyright" function is available, for convenient use in "about"
+ * boxes and the like:
+ *
+ * printf("%s",png_get_copyright(NULL));
+ *
+ * Also, the PNG logo (in PNG format, of course) is supplied in the
+ * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+ */
+
+/*
+ * Libpng is OSI Certified Open Source Software. OSI Certified is a
+ * certification mark of the Open Source Initiative.
+ */
+
+/*
+ * The contributing authors would like to thank all those who helped
+ * with testing, bug fixes, and patience. This wouldn't have been
+ * possible without all of you.
+ *
+ * Thanks to Frank J. T. Wojcik for helping with the documentation.
+ */
+
+/*
+ * Y2K compliance in libpng:
+ * =========================
+ *
+ * July 9, 2011
+ *
+ * Since the PNG Development group is an ad-hoc body, we can't make
+ * an official declaration.
+ *
+ * This is your unofficial assurance that libpng from version 0.71 and
+ * upward through 1.2.46 are Y2K compliant. It is my belief that earlier
+ * versions were also Y2K compliant.
+ *
+ * Libpng only has three year fields. One is a 2-byte unsigned integer
+ * that will hold years up to 65535. The other two hold the date in text
+ * format, and will hold years up to 9999.
+ *
+ * The integer is
+ * "png_uint_16 year" in png_time_struct.
+ *
+ * The strings are
+ * "png_charp time_buffer" in png_struct and
+ * "near_time_buffer", which is a local character string in png.c.
+ *
+ * There are seven time-related functions:
+ * png.c: png_convert_to_rfc_1123() in png.c
+ * (formerly png_convert_to_rfc_1152() in error)
+ * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+ * png_convert_from_time_t() in pngwrite.c
+ * png_get_tIME() in pngget.c
+ * png_handle_tIME() in pngrutil.c, called in pngread.c
+ * png_set_tIME() in pngset.c
+ * png_write_tIME() in pngwutil.c, called in pngwrite.c
+ *
+ * All handle dates properly in a Y2K environment. The
+ * png_convert_from_time_t() function calls gmtime() to convert from system
+ * clock time, which returns (year - 1900), which we properly convert to
+ * the full 4-digit year. There is a possibility that applications using
+ * libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+ * function, or that they are incorrectly passing only a 2-digit year
+ * instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ * but this is not under our control. The libpng documentation has always
+ * stated that it works with 4-digit years, and the APIs have been
+ * documented as such.
+ *
+ * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
+ * integer to hold the year, and can hold years as large as 65535.
+ *
+ * zlib, upon which libpng depends, is also Y2K compliant. It contains
+ * no date-related code.
+ *
+ * Glenn Randers-Pehrson
+ * libpng maintainer
+ * PNG Development Group
+ */
+
+#ifndef PNG_H
+#define PNG_H
+
+/* This is not the place to learn how to use libpng. The file libpng.txt
+ * describes how to use libpng, and the file example.c summarizes it
+ * with some code on which to build. This file is useful for looking
+ * at the actual function definitions and structure components.
+ */
+
+/* Version information for png.h - this should match the version in png.c */
+#define PNG_LIBPNG_VER_STRING "1.2.46"
+#define PNG_HEADER_VERSION_STRING \
+ " libpng version 1.2.46 - July 9, 2011\n"
+
+#define PNG_LIBPNG_VER_SONUM 0
+#define PNG_LIBPNG_VER_DLLNUM 13
+
+/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
+#define PNG_LIBPNG_VER_MAJOR 1
+#define PNG_LIBPNG_VER_MINOR 2
+#define PNG_LIBPNG_VER_RELEASE 46
+/* This should match the numeric part of the final component of
+ * PNG_LIBPNG_VER_STRING, omitting any leading zero:
+ */
+
+#define PNG_LIBPNG_VER_BUILD 0
+
+/* Release Status */
+#define PNG_LIBPNG_BUILD_ALPHA 1
+#define PNG_LIBPNG_BUILD_BETA 2
+#define PNG_LIBPNG_BUILD_RC 3
+#define PNG_LIBPNG_BUILD_STABLE 4
+#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
+
+/* Release-Specific Flags */
+#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with
+ PNG_LIBPNG_BUILD_STABLE only */
+#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
+ PNG_LIBPNG_BUILD_SPECIAL */
+#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
+ PNG_LIBPNG_BUILD_PRIVATE */
+
+#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
+
+/* Careful here. At one time, Guy wanted to use 082, but that would be octal.
+ * We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
+ * version 1.0.0 was mis-numbered 100 instead of 10000). From
+ * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release
+ */
+#define PNG_LIBPNG_VER 10246 /* 1.2.46 */
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* Include the compression library's header */
+#include "zlib.h"
+#endif
+
+/* Include all user configurable info, including optional assembler routines */
+#include "pngconf.h"
+
+/*
+ * Added at libpng-1.2.8 */
+/* Ref MSDN: Private as priority over Special
+ * VS_FF_PRIVATEBUILD File *was not* built using standard release
+ * procedures. If this value is given, the StringFileInfo block must
+ * contain a PrivateBuild string.
+ *
+ * VS_FF_SPECIALBUILD File *was* built by the original company using
+ * standard release procedures but is a variation of the standard
+ * file of the same version number. If this value is given, the
+ * StringFileInfo block must contain a SpecialBuild string.
+ */
+
+#ifdef PNG_USER_PRIVATEBUILD
+# define PNG_LIBPNG_BUILD_TYPE \
+ (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
+#else
+# ifdef PNG_LIBPNG_SPECIALBUILD
+# define PNG_LIBPNG_BUILD_TYPE \
+ (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
+# else
+# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
+# endif
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* This file is arranged in several sections. The first section contains
+ * structure and type definitions. The second section contains the external
+ * library functions, while the third has the internal library functions,
+ * which applications aren't expected to use directly.
+ */
+
+#ifndef PNG_NO_TYPECAST_NULL
+#define int_p_NULL (int *)NULL
+#define png_bytep_NULL (png_bytep)NULL
+#define png_bytepp_NULL (png_bytepp)NULL
+#define png_doublep_NULL (png_doublep)NULL
+#define png_error_ptr_NULL (png_error_ptr)NULL
+#define png_flush_ptr_NULL (png_flush_ptr)NULL
+#define png_free_ptr_NULL (png_free_ptr)NULL
+#define png_infopp_NULL (png_infopp)NULL
+#define png_malloc_ptr_NULL (png_malloc_ptr)NULL
+#define png_read_status_ptr_NULL (png_read_status_ptr)NULL
+#define png_rw_ptr_NULL (png_rw_ptr)NULL
+#define png_structp_NULL (png_structp)NULL
+#define png_uint_16p_NULL (png_uint_16p)NULL
+#define png_voidp_NULL (png_voidp)NULL
+#define png_write_status_ptr_NULL (png_write_status_ptr)NULL
+#else
+#define int_p_NULL NULL
+#define png_bytep_NULL NULL
+#define png_bytepp_NULL NULL
+#define png_doublep_NULL NULL
+#define png_error_ptr_NULL NULL
+#define png_flush_ptr_NULL NULL
+#define png_free_ptr_NULL NULL
+#define png_infopp_NULL NULL
+#define png_malloc_ptr_NULL NULL
+#define png_read_status_ptr_NULL NULL
+#define png_rw_ptr_NULL NULL
+#define png_structp_NULL NULL
+#define png_uint_16p_NULL NULL
+#define png_voidp_NULL NULL
+#define png_write_status_ptr_NULL NULL
+#endif
+
+/* Variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* Version information for C files, stored in png.c. This had better match
+ * the version above.
+ */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (PNG_CONST char) png_libpng_ver[18];
+ /* Need room for 99.99.99beta99z */
+#else
+#define png_libpng_ver png_get_header_ver(NULL)
+#endif
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* This was removed in version 1.0.5c */
+/* Structures to facilitate easy interlacing. See png.c for more details */
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_start[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_inc[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_ystart[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_yinc[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_mask[7];
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_dsp_mask[7];
+/* This isn't currently used. If you need it, see png.c for more details.
+PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_height[7];
+*/
+#endif
+
+#endif /* PNG_NO_EXTERN */
+
+/* Three color definitions. The order of the red, green, and blue, (and the
+ * exact size) is not important, although the size of the fields need to
+ * be png_byte or png_uint_16 (as defined below).
+ */
+typedef struct png_color_struct
+{
+ png_byte red;
+ png_byte green;
+ png_byte blue;
+} png_color;
+typedef png_color FAR * png_colorp;
+typedef png_color FAR * FAR * png_colorpp;
+
+typedef struct png_color_16_struct
+{
+ png_byte index; /* used for palette files */
+ png_uint_16 red; /* for use in red green blue files */
+ png_uint_16 green;
+ png_uint_16 blue;
+ png_uint_16 gray; /* for use in grayscale files */
+} png_color_16;
+typedef png_color_16 FAR * png_color_16p;
+typedef png_color_16 FAR * FAR * png_color_16pp;
+
+typedef struct png_color_8_struct
+{
+ png_byte red; /* for use in red green blue files */
+ png_byte green;
+ png_byte blue;
+ png_byte gray; /* for use in grayscale files */
+ png_byte alpha; /* for alpha channel files */
+} png_color_8;
+typedef png_color_8 FAR * png_color_8p;
+typedef png_color_8 FAR * FAR * png_color_8pp;
+
+/*
+ * The following two structures are used for the in-core representation
+ * of sPLT chunks.
+ */
+typedef struct png_sPLT_entry_struct
+{
+ png_uint_16 red;
+ png_uint_16 green;
+ png_uint_16 blue;
+ png_uint_16 alpha;
+ png_uint_16 frequency;
+} png_sPLT_entry;
+typedef png_sPLT_entry FAR * png_sPLT_entryp;
+typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp;
+
+/* When the depth of the sPLT palette is 8 bits, the color and alpha samples
+ * occupy the LSB of their respective members, and the MSB of each member
+ * is zero-filled. The frequency member always occupies the full 16 bits.
+ */
+
+typedef struct png_sPLT_struct
+{
+ png_charp name; /* palette name */
+ png_byte depth; /* depth of palette samples */
+ png_sPLT_entryp entries; /* palette entries */
+ png_int_32 nentries; /* number of palette entries */
+} png_sPLT_t;
+typedef png_sPLT_t FAR * png_sPLT_tp;
+typedef png_sPLT_t FAR * FAR * png_sPLT_tpp;
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
+ * and whether that contents is compressed or not. The "key" field
+ * points to a regular zero-terminated C string. The "text", "lang", and
+ * "lang_key" fields can be regular C strings, empty strings, or NULL pointers.
+ * However, the * structure returned by png_get_text() will always contain
+ * regular zero-terminated C strings (possibly empty), never NULL pointers,
+ * so they can be safely used in printf() and other string-handling functions.
+ */
+typedef struct png_text_struct
+{
+ int compression; /* compression value:
+ -1: tEXt, none
+ 0: zTXt, deflate
+ 1: iTXt, none
+ 2: iTXt, deflate */
+ png_charp key; /* keyword, 1-79 character description of "text" */
+ png_charp text; /* comment, may be an empty string (ie "")
+ or a NULL pointer */
+ png_size_t text_length; /* length of the text string */
+#ifdef PNG_iTXt_SUPPORTED
+ png_size_t itxt_length; /* length of the itxt string */
+ png_charp lang; /* language code, 0-79 characters
+ or a NULL pointer */
+ png_charp lang_key; /* keyword translated UTF-8 string, 0 or more
+ chars or a NULL pointer */
+#endif
+} png_text;
+typedef png_text FAR * png_textp;
+typedef png_text FAR * FAR * png_textpp;
+#endif
+
+/* Supported compression types for text in PNG files (tEXt, and zTXt).
+ * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed.
+ */
+#define PNG_TEXT_COMPRESSION_NONE_WR -3
+#define PNG_TEXT_COMPRESSION_zTXt_WR -2
+#define PNG_TEXT_COMPRESSION_NONE -1
+#define PNG_TEXT_COMPRESSION_zTXt 0
+#define PNG_ITXT_COMPRESSION_NONE 1
+#define PNG_ITXT_COMPRESSION_zTXt 2
+#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */
+
+/* png_time is a way to hold the time in an machine independent way.
+ * Two conversions are provided, both from time_t and struct tm. There
+ * is no portable way to convert to either of these structures, as far
+ * as I know. If you know of a portable way, send it to me. As a side
+ * note - PNG has always been Year 2000 compliant!
+ */
+typedef struct png_time_struct
+{
+ png_uint_16 year; /* full year, as in, 1995 */
+ png_byte month; /* month of year, 1 - 12 */
+ png_byte day; /* day of month, 1 - 31 */
+ png_byte hour; /* hour of day, 0 - 23 */
+ png_byte minute; /* minute of hour, 0 - 59 */
+ png_byte second; /* second of minute, 0 - 60 (for leap seconds) */
+} png_time;
+typedef png_time FAR * png_timep;
+typedef png_time FAR * FAR * png_timepp;
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \
+ defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+/* png_unknown_chunk is a structure to hold queued chunks for which there is
+ * no specific support. The idea is that we can use this to queue
+ * up private chunks for output even though the library doesn't actually
+ * know about their semantics.
+ */
+#define PNG_CHUNK_NAME_LENGTH 5
+typedef struct png_unknown_chunk_t
+{
+ png_byte name[PNG_CHUNK_NAME_LENGTH];
+ png_byte *data;
+ png_size_t size;
+
+ /* libpng-using applications should NOT directly modify this byte. */
+ png_byte location; /* mode of operation at read time */
+}
+png_unknown_chunk;
+typedef png_unknown_chunk FAR * png_unknown_chunkp;
+typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp;
+#endif
+
+/* png_info is a structure that holds the information in a PNG file so
+ * that the application can find out the characteristics of the image.
+ * If you are reading the file, this structure will tell you what is
+ * in the PNG file. If you are writing the file, fill in the information
+ * you want to put into the PNG file, then call png_write_info().
+ * The names chosen should be very close to the PNG specification, so
+ * consult that document for information about the meaning of each field.
+ *
+ * With libpng < 0.95, it was only possible to directly set and read the
+ * the values in the png_info_struct, which meant that the contents and
+ * order of the values had to remain fixed. With libpng 0.95 and later,
+ * however, there are now functions that abstract the contents of
+ * png_info_struct from the application, so this makes it easier to use
+ * libpng with dynamic libraries, and even makes it possible to use
+ * libraries that don't have all of the libpng ancillary chunk-handing
+ * functionality.
+ *
+ * In any case, the order of the parameters in png_info_struct should NOT
+ * be changed for as long as possible to keep compatibility with applications
+ * that use the old direct-access method with png_info_struct.
+ *
+ * The following members may have allocated storage attached that should be
+ * cleaned up before the structure is discarded: palette, trans, text,
+ * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
+ * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
+ * are automatically freed when the info structure is deallocated, if they were
+ * allocated internally by libpng. This behavior can be changed by means
+ * of the png_data_freer() function.
+ *
+ * More allocation details: all the chunk-reading functions that
+ * change these members go through the corresponding png_set_*
+ * functions. A function to clear these members is available: see
+ * png_free_data(). The png_set_* functions do not depend on being
+ * able to point info structure members to any of the storage they are
+ * passed (they make their own copies), EXCEPT that the png_set_text
+ * functions use the same storage passed to them in the text_ptr or
+ * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
+ * functions do not make their own copies.
+ */
+typedef struct png_info_struct
+{
+ /* The following are necessary for every PNG file */
+ png_uint_32 width PNG_DEPSTRUCT; /* width of image in pixels (from IHDR) */
+ png_uint_32 height PNG_DEPSTRUCT; /* height of image in pixels (from IHDR) */
+ png_uint_32 valid PNG_DEPSTRUCT; /* valid chunk data (see PNG_INFO_ below) */
+ png_uint_32 rowbytes PNG_DEPSTRUCT; /* bytes needed to hold an untransformed row */
+ png_colorp palette PNG_DEPSTRUCT; /* array of color values (valid & PNG_INFO_PLTE) */
+ png_uint_16 num_palette PNG_DEPSTRUCT; /* number of color entries in "palette" (PLTE) */
+ png_uint_16 num_trans PNG_DEPSTRUCT; /* number of transparent palette color (tRNS) */
+ png_byte bit_depth PNG_DEPSTRUCT; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
+ png_byte color_type PNG_DEPSTRUCT; /* see PNG_COLOR_TYPE_ below (from IHDR) */
+ /* The following three should have been named *_method not *_type */
+ png_byte compression_type PNG_DEPSTRUCT; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
+ png_byte filter_type PNG_DEPSTRUCT; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
+ png_byte interlace_type PNG_DEPSTRUCT; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+
+ /* The following is informational only on read, and not used on writes. */
+ png_byte channels PNG_DEPSTRUCT; /* number of data channels per pixel (1, 2, 3, 4) */
+ png_byte pixel_depth PNG_DEPSTRUCT; /* number of bits per pixel */
+ png_byte spare_byte PNG_DEPSTRUCT; /* to align the data, and for future use */
+ png_byte signature[8] PNG_DEPSTRUCT; /* magic bytes read by libpng from start of file */
+
+ /* The rest of the data is optional. If you are reading, check the
+ * valid field to see if the information in these are valid. If you
+ * are writing, set the valid field to those chunks you want written,
+ * and initialize the appropriate fields below.
+ */
+
+#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+ /* The gAMA chunk describes the gamma characteristics of the system
+ * on which the image was created, normally in the range [1.0, 2.5].
+ * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
+ */
+ float gamma PNG_DEPSTRUCT; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+ /* GR-P, 0.96a */
+ /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
+ png_byte srgb_intent PNG_DEPSTRUCT; /* sRGB rendering intent [0, 1, 2, or 3] */
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+ /* The tEXt, and zTXt chunks contain human-readable textual data in
+ * uncompressed, compressed, and optionally compressed forms, respectively.
+ * The data in "text" is an array of pointers to uncompressed,
+ * null-terminated C strings. Each chunk has a keyword that describes the
+ * textual data contained in that chunk. Keywords are not required to be
+ * unique, and the text string may be empty. Any number of text chunks may
+ * be in an image.
+ */
+ int num_text PNG_DEPSTRUCT; /* number of comments read/to write */
+ int max_text PNG_DEPSTRUCT; /* current size of text array */
+ png_textp text PNG_DEPSTRUCT; /* array of comments read/to write */
+#endif /* PNG_TEXT_SUPPORTED */
+
+#ifdef PNG_tIME_SUPPORTED
+ /* The tIME chunk holds the last time the displayed image data was
+ * modified. See the png_time struct for the contents of this struct.
+ */
+ png_time mod_time PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_sBIT_SUPPORTED
+ /* The sBIT chunk specifies the number of significant high-order bits
+ * in the pixel data. Values are in the range [1, bit_depth], and are
+ * only specified for the channels in the pixel data. The contents of
+ * the low-order bits is not specified. Data is valid if
+ * (valid & PNG_INFO_sBIT) is non-zero.
+ */
+ png_color_8 sig_bit PNG_DEPSTRUCT; /* significant bits in color channels */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
+defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* The tRNS chunk supplies transparency data for paletted images and
+ * other image types that don't need a full alpha channel. There are
+ * "num_trans" transparency values for a paletted image, stored in the
+ * same order as the palette colors, starting from index 0. Values
+ * for the data are in the range [0, 255], ranging from fully transparent
+ * to fully opaque, respectively. For non-paletted images, there is a
+ * single color specified that should be treated as fully transparent.
+ * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
+ */
+ png_bytep trans PNG_DEPSTRUCT; /* transparent values for paletted image */
+ png_color_16 trans_values PNG_DEPSTRUCT; /* transparent color for non-palette image */
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* The bKGD chunk gives the suggested image background color if the
+ * display program does not have its own background color and the image
+ * is needs to composited onto a background before display. The colors
+ * in "background" are normally in the same color space/depth as the
+ * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
+ */
+ png_color_16 background PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_oFFs_SUPPORTED
+ /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
+ * and downwards from the top-left corner of the display, page, or other
+ * application-specific co-ordinate space. See the PNG_OFFSET_ defines
+ * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
+ */
+ png_int_32 x_offset PNG_DEPSTRUCT; /* x offset on page */
+ png_int_32 y_offset PNG_DEPSTRUCT; /* y offset on page */
+ png_byte offset_unit_type PNG_DEPSTRUCT; /* offset units type */
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+ /* The pHYs chunk gives the physical pixel density of the image for
+ * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
+ * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
+ */
+ png_uint_32 x_pixels_per_unit PNG_DEPSTRUCT; /* horizontal pixel density */
+ png_uint_32 y_pixels_per_unit PNG_DEPSTRUCT; /* vertical pixel density */
+ png_byte phys_unit_type PNG_DEPSTRUCT; /* resolution type (see PNG_RESOLUTION_ below) */
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+ /* The hIST chunk contains the relative frequency or importance of the
+ * various palette entries, so that a viewer can intelligently select a
+ * reduced-color palette, if required. Data is an array of "num_palette"
+ * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
+ * is non-zero.
+ */
+ png_uint_16p hist PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+ /* The cHRM chunk describes the CIE color characteristics of the monitor
+ * on which the PNG was created. This data allows the viewer to do gamut
+ * mapping of the input image to ensure that the viewer sees the same
+ * colors in the image as the creator. Values are in the range
+ * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero.
+ */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float x_white PNG_DEPSTRUCT;
+ float y_white PNG_DEPSTRUCT;
+ float x_red PNG_DEPSTRUCT;
+ float y_red PNG_DEPSTRUCT;
+ float x_green PNG_DEPSTRUCT;
+ float y_green PNG_DEPSTRUCT;
+ float x_blue PNG_DEPSTRUCT;
+ float y_blue PNG_DEPSTRUCT;
+#endif
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+ /* The pCAL chunk describes a transformation between the stored pixel
+ * values and original physical data values used to create the image.
+ * The integer range [0, 2^bit_depth - 1] maps to the floating-point
+ * range given by [pcal_X0, pcal_X1], and are further transformed by a
+ * (possibly non-linear) transformation function given by "pcal_type"
+ * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_
+ * defines below, and the PNG-Group's PNG extensions document for a
+ * complete description of the transformations and how they should be
+ * implemented, and for a description of the ASCII parameter strings.
+ * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
+ */
+ png_charp pcal_purpose PNG_DEPSTRUCT; /* pCAL chunk description string */
+ png_int_32 pcal_X0 PNG_DEPSTRUCT; /* minimum value */
+ png_int_32 pcal_X1 PNG_DEPSTRUCT; /* maximum value */
+ png_charp pcal_units PNG_DEPSTRUCT; /* Latin-1 string giving physical units */
+ png_charpp pcal_params PNG_DEPSTRUCT; /* ASCII strings containing parameter values */
+ png_byte pcal_type PNG_DEPSTRUCT; /* equation type (see PNG_EQUATION_ below) */
+ png_byte pcal_nparams PNG_DEPSTRUCT; /* number of parameters given in pcal_params */
+#endif
+
+/* New members added in libpng-1.0.6 */
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_uint_32 free_me PNG_DEPSTRUCT; /* flags items libpng is responsible for freeing */
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \
+ defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+ /* Storage for unknown chunks that the library doesn't recognize. */
+ png_unknown_chunkp unknown_chunks PNG_DEPSTRUCT;
+ png_size_t unknown_chunks_num PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+ /* iCCP chunk data. */
+ png_charp iccp_name PNG_DEPSTRUCT; /* profile name */
+ png_charp iccp_profile PNG_DEPSTRUCT; /* International Color Consortium profile data */
+ /* Note to maintainer: should be png_bytep */
+ png_uint_32 iccp_proflen PNG_DEPSTRUCT; /* ICC profile data length */
+ png_byte iccp_compression PNG_DEPSTRUCT; /* Always zero */
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+ /* Data on sPLT chunks (there may be more than one). */
+ png_sPLT_tp splt_palettes PNG_DEPSTRUCT;
+ png_uint_32 splt_palettes_num PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+ /* The sCAL chunk describes the actual physical dimensions of the
+ * subject matter of the graphic. The chunk contains a unit specification
+ * a byte value, and two ASCII strings representing floating-point
+ * values. The values are width and height corresponsing to one pixel
+ * in the image. This external representation is converted to double
+ * here. Data values are valid if (valid & PNG_INFO_sCAL) is non-zero.
+ */
+ png_byte scal_unit PNG_DEPSTRUCT; /* unit of physical scale */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ double scal_pixel_width PNG_DEPSTRUCT; /* width of one pixel */
+ double scal_pixel_height PNG_DEPSTRUCT; /* height of one pixel */
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_charp scal_s_width PNG_DEPSTRUCT; /* string containing height */
+ png_charp scal_s_height PNG_DEPSTRUCT; /* string containing width */
+#endif
+#endif
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+ /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */
+ /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
+ png_bytepp row_pointers PNG_DEPSTRUCT; /* the image bits */
+#endif
+
+#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED)
+ png_fixed_point int_gamma PNG_DEPSTRUCT; /* gamma of image, if (valid & PNG_INFO_gAMA) */
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED)
+ png_fixed_point int_x_white PNG_DEPSTRUCT;
+ png_fixed_point int_y_white PNG_DEPSTRUCT;
+ png_fixed_point int_x_red PNG_DEPSTRUCT;
+ png_fixed_point int_y_red PNG_DEPSTRUCT;
+ png_fixed_point int_x_green PNG_DEPSTRUCT;
+ png_fixed_point int_y_green PNG_DEPSTRUCT;
+ png_fixed_point int_x_blue PNG_DEPSTRUCT;
+ png_fixed_point int_y_blue PNG_DEPSTRUCT;
+#endif
+
+} png_info;
+
+typedef png_info FAR * png_infop;
+typedef png_info FAR * FAR * png_infopp;
+
+/* Maximum positive integer used in PNG is (2^31)-1 */
+#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
+#define PNG_UINT_32_MAX ((png_uint_32)(-1))
+#define PNG_SIZE_MAX ((png_size_t)(-1))
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */
+#define PNG_MAX_UINT PNG_UINT_31_MAX
+#endif
+
+/* These describe the color_type field in png_info. */
+/* color type masks */
+#define PNG_COLOR_MASK_PALETTE 1
+#define PNG_COLOR_MASK_COLOR 2
+#define PNG_COLOR_MASK_ALPHA 4
+
+/* color types. Note that not all combinations are legal */
+#define PNG_COLOR_TYPE_GRAY 0
+#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
+#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
+#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
+#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
+/* aliases */
+#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
+#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA
+
+/* This is for compression type. PNG 1.0-1.2 only define the single type. */
+#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
+#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
+
+/* This is for filter type. PNG 1.0-1.2 only define the single type. */
+#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */
+#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
+#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE
+
+/* These are for the interlacing type. These values should NOT be changed. */
+#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */
+#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */
+#define PNG_INTERLACE_LAST 2 /* Not a valid value */
+
+/* These are for the oFFs chunk. These values should NOT be changed. */
+#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */
+#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */
+#define PNG_OFFSET_LAST 2 /* Not a valid value */
+
+/* These are for the pCAL chunk. These values should NOT be changed. */
+#define PNG_EQUATION_LINEAR 0 /* Linear transformation */
+#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */
+#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */
+#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */
+#define PNG_EQUATION_LAST 4 /* Not a valid value */
+
+/* These are for the sCAL chunk. These values should NOT be changed. */
+#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */
+#define PNG_SCALE_METER 1 /* meters per pixel */
+#define PNG_SCALE_RADIAN 2 /* radians per pixel */
+#define PNG_SCALE_LAST 3 /* Not a valid value */
+
+/* These are for the pHYs chunk. These values should NOT be changed. */
+#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */
+#define PNG_RESOLUTION_METER 1 /* pixels/meter */
+#define PNG_RESOLUTION_LAST 2 /* Not a valid value */
+
+/* These are for the sRGB chunk. These values should NOT be changed. */
+#define PNG_sRGB_INTENT_PERCEPTUAL 0
+#define PNG_sRGB_INTENT_RELATIVE 1
+#define PNG_sRGB_INTENT_SATURATION 2
+#define PNG_sRGB_INTENT_ABSOLUTE 3
+#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */
+
+/* This is for text chunks */
+#define PNG_KEYWORD_MAX_LENGTH 79
+
+/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
+#define PNG_MAX_PALETTE_LENGTH 256
+
+/* These determine if an ancillary chunk's data has been successfully read
+ * from the PNG header, or if the application has filled in the corresponding
+ * data in the info_struct to be written into the output file. The values
+ * of the PNG_INFO_<chunk> defines should NOT be changed.
+ */
+#define PNG_INFO_gAMA 0x0001
+#define PNG_INFO_sBIT 0x0002
+#define PNG_INFO_cHRM 0x0004
+#define PNG_INFO_PLTE 0x0008
+#define PNG_INFO_tRNS 0x0010
+#define PNG_INFO_bKGD 0x0020
+#define PNG_INFO_hIST 0x0040
+#define PNG_INFO_pHYs 0x0080
+#define PNG_INFO_oFFs 0x0100
+#define PNG_INFO_tIME 0x0200
+#define PNG_INFO_pCAL 0x0400
+#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */
+
+/* This is used for the transformation routines, as some of them
+ * change these values for the row. It also should enable using
+ * the routines for other purposes.
+ */
+typedef struct png_row_info_struct
+{
+ png_uint_32 width; /* width of row */
+ png_uint_32 rowbytes; /* number of bytes in row */
+ png_byte color_type; /* color type of row */
+ png_byte bit_depth; /* bit depth of row */
+ png_byte channels; /* number of channels (1, 2, 3, or 4) */
+ png_byte pixel_depth; /* bits per pixel (depth * channels) */
+} png_row_info;
+
+typedef png_row_info FAR * png_row_infop;
+typedef png_row_info FAR * FAR * png_row_infopp;
+
+/* These are the function types for the I/O functions and for the functions
+ * that allow the user to override the default I/O functions with his or her
+ * own. The png_error_ptr type should match that of user-supplied warning
+ * and error functions, while the png_rw_ptr type should match that of the
+ * user read/write data functions.
+ */
+typedef struct png_struct_def png_struct;
+typedef png_struct FAR * png_structp;
+
+typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp));
+typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
+typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp));
+typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32,
+ int));
+typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32,
+ int));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
+ png_uint_32, int));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp,
+ png_row_infop, png_bytep));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp));
+#endif
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp));
+#endif
+
+/* Transform masks for the high-level interface */
+#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */
+#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */
+#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */
+#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */
+#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */
+#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */
+#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */
+#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */
+#define PNG_TRANSFORM_BGR 0x0080 /* read and write */
+#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */
+#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */
+#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */
+#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only, deprecated */
+/* Added to libpng-1.2.34 */
+#define PNG_TRANSFORM_STRIP_FILLER_BEFORE 0x0800 /* write only */
+#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */
+/* Added to libpng-1.2.41 */
+#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */
+
+/* Flags for MNG supported features */
+#define PNG_FLAG_MNG_EMPTY_PLTE 0x01
+#define PNG_FLAG_MNG_FILTER_64 0x04
+#define PNG_ALL_MNG_FEATURES 0x05
+
+typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
+typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp));
+
+/* The structure that holds the information to read and write PNG files.
+ * The only people who need to care about what is inside of this are the
+ * people who will be modifying the library for their own special needs.
+ * It should NOT be accessed directly by an application, except to store
+ * the jmp_buf.
+ */
+
+struct png_struct_def
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf jmpbuf; /* used in png_error */
+#endif
+ png_error_ptr error_fn PNG_DEPSTRUCT; /* function for printing errors and aborting */
+ png_error_ptr warning_fn PNG_DEPSTRUCT; /* function for printing warnings */
+ png_voidp error_ptr PNG_DEPSTRUCT; /* user supplied struct for error functions */
+ png_rw_ptr write_data_fn PNG_DEPSTRUCT; /* function for writing output data */
+ png_rw_ptr read_data_fn PNG_DEPSTRUCT; /* function for reading input data */
+ png_voidp io_ptr PNG_DEPSTRUCT; /* ptr to application struct for I/O functions */
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ png_user_transform_ptr read_user_transform_fn PNG_DEPSTRUCT; /* user read transform */
+#endif
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+ png_user_transform_ptr write_user_transform_fn PNG_DEPSTRUCT; /* user write transform */
+#endif
+
+/* These were added in libpng-1.0.2 */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ png_voidp user_transform_ptr PNG_DEPSTRUCT; /* user supplied struct for user transform */
+ png_byte user_transform_depth PNG_DEPSTRUCT; /* bit depth of user transformed pixels */
+ png_byte user_transform_channels PNG_DEPSTRUCT; /* channels in user transformed pixels */
+#endif
+#endif
+
+ png_uint_32 mode PNG_DEPSTRUCT; /* tells us where we are in the PNG file */
+ png_uint_32 flags PNG_DEPSTRUCT; /* flags indicating various things to libpng */
+ png_uint_32 transformations PNG_DEPSTRUCT; /* which transformations to perform */
+
+ z_stream zstream PNG_DEPSTRUCT; /* pointer to decompression structure (below) */
+ png_bytep zbuf PNG_DEPSTRUCT; /* buffer for zlib */
+ png_size_t zbuf_size PNG_DEPSTRUCT; /* size of zbuf */
+ int zlib_level PNG_DEPSTRUCT; /* holds zlib compression level */
+ int zlib_method PNG_DEPSTRUCT; /* holds zlib compression method */
+ int zlib_window_bits PNG_DEPSTRUCT; /* holds zlib compression window bits */
+ int zlib_mem_level PNG_DEPSTRUCT; /* holds zlib compression memory level */
+ int zlib_strategy PNG_DEPSTRUCT; /* holds zlib compression strategy */
+
+ png_uint_32 width PNG_DEPSTRUCT; /* width of image in pixels */
+ png_uint_32 height PNG_DEPSTRUCT; /* height of image in pixels */
+ png_uint_32 num_rows PNG_DEPSTRUCT; /* number of rows in current pass */
+ png_uint_32 usr_width PNG_DEPSTRUCT; /* width of row at start of write */
+ png_uint_32 rowbytes PNG_DEPSTRUCT; /* size of row in bytes */
+#if 0 /* Replaced with the following in libpng-1.2.43 */
+ png_size_t irowbytes PNG_DEPSTRUCT;
+#endif
+/* Added in libpng-1.2.43 */
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
+ * chunks that can be stored (0 means unlimited).
+ */
+ png_uint_32 user_chunk_cache_max PNG_DEPSTRUCT;
+#endif
+ png_uint_32 iwidth PNG_DEPSTRUCT; /* width of current interlaced row in pixels */
+ png_uint_32 row_number PNG_DEPSTRUCT; /* current row in interlace pass */
+ png_bytep prev_row PNG_DEPSTRUCT; /* buffer to save previous (unfiltered) row */
+ png_bytep row_buf PNG_DEPSTRUCT; /* buffer to save current (unfiltered) row */
+#ifndef PNG_NO_WRITE_FILTER
+ png_bytep sub_row PNG_DEPSTRUCT; /* buffer to save "sub" row when filtering */
+ png_bytep up_row PNG_DEPSTRUCT; /* buffer to save "up" row when filtering */
+ png_bytep avg_row PNG_DEPSTRUCT; /* buffer to save "avg" row when filtering */
+ png_bytep paeth_row PNG_DEPSTRUCT; /* buffer to save "Paeth" row when filtering */
+#endif
+ png_row_info row_info PNG_DEPSTRUCT; /* used for transformation routines */
+
+ png_uint_32 idat_size PNG_DEPSTRUCT; /* current IDAT size for read */
+ png_uint_32 crc PNG_DEPSTRUCT; /* current chunk CRC value */
+ png_colorp palette PNG_DEPSTRUCT; /* palette from the input file */
+ png_uint_16 num_palette PNG_DEPSTRUCT; /* number of color entries in palette */
+ png_uint_16 num_trans PNG_DEPSTRUCT; /* number of transparency values */
+ png_byte chunk_name[5] PNG_DEPSTRUCT; /* null-terminated name of current chunk */
+ png_byte compression PNG_DEPSTRUCT; /* file compression type (always 0) */
+ png_byte filter PNG_DEPSTRUCT; /* file filter type (always 0) */
+ png_byte interlaced PNG_DEPSTRUCT; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+ png_byte pass PNG_DEPSTRUCT; /* current interlace pass (0 - 6) */
+ png_byte do_filter PNG_DEPSTRUCT; /* row filter flags (see PNG_FILTER_ below ) */
+ png_byte color_type PNG_DEPSTRUCT; /* color type of file */
+ png_byte bit_depth PNG_DEPSTRUCT; /* bit depth of file */
+ png_byte usr_bit_depth PNG_DEPSTRUCT; /* bit depth of users row */
+ png_byte pixel_depth PNG_DEPSTRUCT; /* number of bits per pixel */
+ png_byte channels PNG_DEPSTRUCT; /* number of channels in file */
+ png_byte usr_channels PNG_DEPSTRUCT; /* channels at start of write */
+ png_byte sig_bytes PNG_DEPSTRUCT; /* magic bytes read/written from start of file */
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+#ifdef PNG_LEGACY_SUPPORTED
+ png_byte filler PNG_DEPSTRUCT; /* filler byte for pixel expansion */
+#else
+ png_uint_16 filler PNG_DEPSTRUCT; /* filler bytes for pixel expansion */
+#endif
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+ png_byte background_gamma_type PNG_DEPSTRUCT;
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ float background_gamma PNG_DEPSTRUCT;
+# endif
+ png_color_16 background PNG_DEPSTRUCT; /* background color in screen gamma space */
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ png_color_16 background_1 PNG_DEPSTRUCT; /* background normalized to gamma 1.0 */
+#endif
+#endif /* PNG_bKGD_SUPPORTED */
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+ png_flush_ptr output_flush_fn PNG_DEPSTRUCT; /* Function for flushing output */
+ png_uint_32 flush_dist PNG_DEPSTRUCT; /* how many rows apart to flush, 0 - no flush */
+ png_uint_32 flush_rows PNG_DEPSTRUCT; /* number of rows written since last flush */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ int gamma_shift PNG_DEPSTRUCT; /* number of "insignificant" bits 16-bit gamma */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float gamma PNG_DEPSTRUCT; /* file gamma value */
+ float screen_gamma PNG_DEPSTRUCT; /* screen gamma value (display_exponent) */
+#endif
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_bytep gamma_table PNG_DEPSTRUCT; /* gamma table for 8-bit depth files */
+ png_bytep gamma_from_1 PNG_DEPSTRUCT; /* converts from 1.0 to screen */
+ png_bytep gamma_to_1 PNG_DEPSTRUCT; /* converts from file to 1.0 */
+ png_uint_16pp gamma_16_table PNG_DEPSTRUCT; /* gamma table for 16-bit depth files */
+ png_uint_16pp gamma_16_from_1 PNG_DEPSTRUCT; /* converts from 1.0 to screen */
+ png_uint_16pp gamma_16_to_1 PNG_DEPSTRUCT; /* converts from file to 1.0 */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
+ png_color_8 sig_bit PNG_DEPSTRUCT; /* significant bits in each available channel */
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+ png_color_8 shift PNG_DEPSTRUCT; /* shift for significant bit tranformation */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
+ || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_bytep trans PNG_DEPSTRUCT; /* transparency values for paletted files */
+ png_color_16 trans_values PNG_DEPSTRUCT; /* transparency values for non-paletted files */
+#endif
+
+ png_read_status_ptr read_row_fn PNG_DEPSTRUCT; /* called after each row is decoded */
+ png_write_status_ptr write_row_fn PNG_DEPSTRUCT; /* called after each row is encoded */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ png_progressive_info_ptr info_fn PNG_DEPSTRUCT; /* called after header data fully read */
+ png_progressive_row_ptr row_fn PNG_DEPSTRUCT; /* called after each prog. row is decoded */
+ png_progressive_end_ptr end_fn PNG_DEPSTRUCT; /* called after image is complete */
+ png_bytep save_buffer_ptr PNG_DEPSTRUCT; /* current location in save_buffer */
+ png_bytep save_buffer PNG_DEPSTRUCT; /* buffer for previously read data */
+ png_bytep current_buffer_ptr PNG_DEPSTRUCT; /* current location in current_buffer */
+ png_bytep current_buffer PNG_DEPSTRUCT; /* buffer for recently used data */
+ png_uint_32 push_length PNG_DEPSTRUCT; /* size of current input chunk */
+ png_uint_32 skip_length PNG_DEPSTRUCT; /* bytes to skip in input data */
+ png_size_t save_buffer_size PNG_DEPSTRUCT; /* amount of data now in save_buffer */
+ png_size_t save_buffer_max PNG_DEPSTRUCT; /* total size of save_buffer */
+ png_size_t buffer_size PNG_DEPSTRUCT; /* total amount of available input data */
+ png_size_t current_buffer_size PNG_DEPSTRUCT; /* amount of data now in current_buffer */
+ int process_mode PNG_DEPSTRUCT; /* what push library is currently doing */
+ int cur_palette PNG_DEPSTRUCT; /* current push library palette index */
+
+# ifdef PNG_TEXT_SUPPORTED
+ png_size_t current_text_size PNG_DEPSTRUCT; /* current size of text input data */
+ png_size_t current_text_left PNG_DEPSTRUCT; /* how much text left to read in input */
+ png_charp current_text PNG_DEPSTRUCT; /* current text chunk buffer */
+ png_charp current_text_ptr PNG_DEPSTRUCT; /* current location in current_text */
+# endif /* PNG_TEXT_SUPPORTED */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* for the Borland special 64K segment handler */
+ png_bytepp offset_table_ptr PNG_DEPSTRUCT;
+ png_bytep offset_table PNG_DEPSTRUCT;
+ png_uint_16 offset_table_number PNG_DEPSTRUCT;
+ png_uint_16 offset_table_count PNG_DEPSTRUCT;
+ png_uint_16 offset_table_count_free PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+ png_bytep palette_lookup PNG_DEPSTRUCT; /* lookup table for dithering */
+ png_bytep dither_index PNG_DEPSTRUCT; /* index translation for palette files */
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
+ png_uint_16p hist PNG_DEPSTRUCT; /* histogram */
+#endif
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ png_byte heuristic_method PNG_DEPSTRUCT; /* heuristic for row filter selection */
+ png_byte num_prev_filters PNG_DEPSTRUCT; /* number of weights for previous rows */
+ png_bytep prev_filters PNG_DEPSTRUCT; /* filter type(s) of previous row(s) */
+ png_uint_16p filter_weights PNG_DEPSTRUCT; /* weight(s) for previous line(s) */
+ png_uint_16p inv_filter_weights PNG_DEPSTRUCT; /* 1/weight(s) for previous line(s) */
+ png_uint_16p filter_costs PNG_DEPSTRUCT; /* relative filter calculation cost */
+ png_uint_16p inv_filter_costs PNG_DEPSTRUCT; /* 1/relative filter calculation cost */
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+ png_charp time_buffer PNG_DEPSTRUCT; /* String to hold RFC 1123 time text */
+#endif
+
+/* New members added in libpng-1.0.6 */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_uint_32 free_me PNG_DEPSTRUCT; /* flags items libpng is responsible for freeing */
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+ png_voidp user_chunk_ptr PNG_DEPSTRUCT;
+ png_user_chunk_ptr read_user_chunk_fn PNG_DEPSTRUCT; /* user read chunk handler */
+#endif
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ int num_chunk_list PNG_DEPSTRUCT;
+ png_bytep chunk_list PNG_DEPSTRUCT;
+#endif
+
+/* New members added in libpng-1.0.3 */
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ png_byte rgb_to_gray_status PNG_DEPSTRUCT;
+ /* These were changed from png_byte in libpng-1.0.6 */
+ png_uint_16 rgb_to_gray_red_coeff PNG_DEPSTRUCT;
+ png_uint_16 rgb_to_gray_green_coeff PNG_DEPSTRUCT;
+ png_uint_16 rgb_to_gray_blue_coeff PNG_DEPSTRUCT;
+#endif
+
+/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
+#if defined(PNG_MNG_FEATURES_SUPPORTED) || \
+ defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* Changed from png_byte to png_uint_32 at version 1.2.0 */
+#ifdef PNG_1_0_X
+ png_byte mng_features_permitted PNG_DEPSTRUCT;
+#else
+ png_uint_32 mng_features_permitted PNG_DEPSTRUCT;
+#endif /* PNG_1_0_X */
+#endif
+
+/* New member added in libpng-1.0.7 */
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_fixed_point int_gamma PNG_DEPSTRUCT;
+#endif
+
+/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ png_byte filter_type PNG_DEPSTRUCT;
+#endif
+
+#ifdef PNG_1_0_X
+/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */
+ png_uint_32 row_buf_size PNG_DEPSTRUCT;
+#endif
+
+/* New members added in libpng-1.2.0 */
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+# ifndef PNG_1_0_X
+# ifdef PNG_MMX_CODE_SUPPORTED
+ png_byte mmx_bitdepth_threshold PNG_DEPSTRUCT;
+ png_uint_32 mmx_rowbytes_threshold PNG_DEPSTRUCT;
+# endif
+ png_uint_32 asm_flags PNG_DEPSTRUCT;
+# endif
+#endif
+
+/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_voidp mem_ptr PNG_DEPSTRUCT; /* user supplied struct for mem functions */
+ png_malloc_ptr malloc_fn PNG_DEPSTRUCT; /* function for allocating memory */
+ png_free_ptr free_fn PNG_DEPSTRUCT; /* function for freeing memory */
+#endif
+
+/* New member added in libpng-1.0.13 and 1.2.0 */
+ png_bytep big_row_buf PNG_DEPSTRUCT; /* buffer to save current (unfiltered) row */
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+/* The following three members were added at version 1.0.14 and 1.2.4 */
+ png_bytep dither_sort PNG_DEPSTRUCT; /* working sort array */
+ png_bytep index_to_palette PNG_DEPSTRUCT; /* where the original index currently is */
+ /* in the palette */
+ png_bytep palette_to_index PNG_DEPSTRUCT; /* which original index points to this */
+ /* palette color */
+#endif
+
+/* New members added in libpng-1.0.16 and 1.2.6 */
+ png_byte compression_type PNG_DEPSTRUCT;
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ png_uint_32 user_width_max PNG_DEPSTRUCT;
+ png_uint_32 user_height_max PNG_DEPSTRUCT;
+#endif
+
+/* New member added in libpng-1.0.25 and 1.2.17 */
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+ /* Storage for unknown chunk that the library doesn't recognize. */
+ png_unknown_chunk unknown_chunk PNG_DEPSTRUCT;
+#endif
+
+/* New members added in libpng-1.2.26 */
+ png_uint_32 old_big_row_buf_size PNG_DEPSTRUCT;
+ png_uint_32 old_prev_row_size PNG_DEPSTRUCT;
+
+/* New member added in libpng-1.2.30 */
+ png_charp chunkdata PNG_DEPSTRUCT; /* buffer for reading chunk data */
+
+
+};
+
+
+/* This triggers a compiler error in png.c, if png.c and png.h
+ * do not agree upon the version number.
+ */
+typedef png_structp version_1_2_46;
+
+typedef png_struct FAR * FAR * png_structpp;
+
+/* Here are the function definitions most commonly used. This is not
+ * the place to find out how to use libpng. See libpng.txt for the
+ * full explanation, see example.c for the summary. This just provides
+ * a simple one line description of the use of each function.
+ */
+
+/* Returns the version number of the library */
+extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void));
+
+/* Tell lib we have already handled the first <num_bytes> magic bytes.
+ * Handling more than 8 bytes from the beginning of the file is an error.
+ */
+extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr,
+ int num_bytes));
+
+/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
+ * PNG file. Returns zero if the supplied bytes match the 8-byte PNG
+ * signature, and non-zero otherwise. Having num_to_check == 0 or
+ * start > 7 will always fail (ie return non-zero).
+ */
+extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start,
+ png_size_t num_to_check));
+
+/* Simple signature checking function. This is the same as calling
+ * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
+ */
+extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num)) PNG_DEPRECATED;
+
+/* Allocate and initialize png_ptr struct for reading, and any other memory. */
+extern PNG_EXPORT(png_structp,png_create_read_struct)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn)) PNG_ALLOCATED;
+
+/* Allocate and initialize png_ptr struct for writing, and any other memory */
+extern PNG_EXPORT(png_structp,png_create_write_struct)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn)) PNG_ALLOCATED;
+
+#ifdef PNG_WRITE_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size)
+ PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+extern PNG_EXPORT(void,png_set_compression_buffer_size)
+ PNGARG((png_structp png_ptr, png_uint_32 size));
+#endif
+
+/* Reset the compression stream */
+extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
+
+/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
+#ifdef PNG_USER_MEM_SUPPORTED
+extern PNG_EXPORT(png_structp,png_create_read_struct_2)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn)) PNG_ALLOCATED;
+extern PNG_EXPORT(png_structp,png_create_write_struct_2)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn)) PNG_ALLOCATED;
+#endif
+
+/* Write a PNG chunk - size, type, (optional) data, CRC. */
+extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr,
+ png_bytep chunk_name, png_bytep data, png_size_t length));
+
+/* Write the start of a PNG chunk - length and chunk name. */
+extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr,
+ png_bytep chunk_name, png_uint_32 length));
+
+/* Write the data of a PNG chunk started with png_write_chunk_start(). */
+extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr,
+ png_bytep data, png_size_t length));
+
+/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
+extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr));
+
+/* Allocate and initialize the info structure */
+extern PNG_EXPORT(png_infop,png_create_info_struct)
+ PNGARG((png_structp png_ptr)) PNG_ALLOCATED;
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Initialize the info structure (old interface - DEPRECATED) */
+extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr))
+ PNG_DEPRECATED;
+#undef png_info_init
+#define png_info_init(info_ptr) png_info_init_3(&info_ptr,\
+ png_sizeof(png_info));
+#endif
+
+extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr,
+ png_size_t png_info_struct_size));
+
+/* Writes all the PNG information before the image. */
+extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data. */
+extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
+ PNGARG((png_structp png_ptr, png_timep ptime));
+#endif
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+/* Convert from a struct tm to png_time */
+extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
+ struct tm FAR * ttime));
+
+/* Convert from time_t to png_time. Uses gmtime() */
+extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
+ time_t ttime));
+#endif /* PNG_CONVERT_tIME_SUPPORTED */
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
+extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
+#ifndef PNG_1_0_X
+extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp
+ png_ptr));
+#endif
+extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr));
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Deprecated */
+extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp
+ png_ptr)) PNG_DEPRECATED;
+#endif
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Use blue, green, red order for pixels. */
+extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+/* Expand the grayscale to 24-bit RGB if necessary. */
+extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+/* Reduce RGB to grayscale. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr,
+ int error_action, double red, double green ));
+#endif
+extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr,
+ int error_action, png_fixed_point red, png_fixed_point green ));
+extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp
+ png_ptr));
+#endif
+
+extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
+ png_colorp palette));
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
+extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
+ png_uint_32 filler, int flags));
+/* The values of the PNG_FILLER_ defines should NOT be changed */
+#define PNG_FILLER_BEFORE 0
+#define PNG_FILLER_AFTER 1
+/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
+#ifndef PNG_1_0_X
+extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr,
+ png_uint_32 filler, int flags));
+#endif
+#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swap bytes in 16-bit depth files. */
+extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
+extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Swap packing order of pixels in bytes. */
+extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Converts files to legal bit depths. */
+extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
+ png_color_8p true_bits));
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Have the code handle the interlacing. Returns the number of passes. */
+extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+/* Invert monochrome files */
+extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+/* Handle alpha and tRNS by replacing with a background color. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
+ png_color_16p background_color, int background_gamma_code,
+ int need_expand, double background_gamma));
+#endif
+#define PNG_BACKGROUND_GAMMA_UNKNOWN 0
+#define PNG_BACKGROUND_GAMMA_SCREEN 1
+#define PNG_BACKGROUND_GAMMA_FILE 2
+#define PNG_BACKGROUND_GAMMA_UNIQUE 3
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+/* Strip the second byte of information from a 16-bit depth file. */
+extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+/* Turn on dithering, and reduce the palette to the number of colors available. */
+extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
+ png_colorp palette, int num_palette, int maximum_colors,
+ png_uint_16p histogram, int full_dither));
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* Handle gamma correction. Screen_gamma=(display_exponent) */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
+ double screen_gamma, double default_file_gamma));
+#endif
+#endif
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */
+/* Deprecated and will be removed. Use png_permit_mng_features() instead. */
+extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr,
+ int empty_plte_permitted)) PNG_DEPRECATED;
+#endif
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+/* Set how many lines between output flushes - 0 for no flushing */
+extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
+/* Flush the current PNG output buffer */
+extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
+#endif
+
+/* Optional update palette with requested transformations */
+extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
+
+/* Optional call to update the users info structure */
+extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data. */
+extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
+ png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
+#endif
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read a row of data. */
+extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
+ png_bytep row,
+ png_bytep display_row));
+#endif
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read the whole image into memory at once. */
+extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
+ png_bytepp image));
+#endif
+
+/* Write a row of image data */
+extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr,
+ png_bytep row));
+
+/* Write a few rows of image data */
+extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr,
+ png_bytepp row, png_uint_32 num_rows));
+
+/* Write the image data */
+extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
+ png_bytepp image));
+
+/* Writes the end of the PNG file. */
+extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file. */
+extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+#endif
+
+/* Free any memory associated with the png_info_struct */
+extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr,
+ png_infopp info_ptr_ptr));
+
+/* Free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp
+ png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
+
+/* Free all memory used by the read (old method - NOT DLL EXPORTED) */
+extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_infop end_info_ptr)) PNG_DEPRECATED;
+
+/* Free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_write_struct)
+ PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
+
+/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
+extern void png_write_destroy PNGARG((png_structp png_ptr)) PNG_DEPRECATED;
+
+/* Set the libpng method of handling chunk CRC errors */
+extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
+ int crit_action, int ancil_action));
+
+/* Values for png_set_crc_action() to say how to handle CRC errors in
+ * ancillary and critical chunks, and whether to use the data contained
+ * therein. Note that it is impossible to "discard" data in a critical
+ * chunk. For versions prior to 0.90, the action was always error/quit,
+ * whereas in version 0.90 and later, the action for CRC errors in ancillary
+ * chunks is warn/discard. These values should NOT be changed.
+ *
+ * value action:critical action:ancillary
+ */
+#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */
+#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */
+#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */
+#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */
+#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */
+#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */
+
+/* These functions give the user control over the scan-line filtering in
+ * libpng and the compression methods used by zlib. These functions are
+ * mainly useful for testing, as the defaults should work with most users.
+ * Those users who are tight on memory or want faster performance at the
+ * expense of compression can modify them. See the compression library
+ * header file (zlib.h) for an explination of the compression functions.
+ */
+
+/* Set the filtering method(s) used by libpng. Currently, the only valid
+ * value for "method" is 0.
+ */
+extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method,
+ int filters));
+
+/* Flags for png_set_filter() to say which filters to use. The flags
+ * are chosen so that they don't conflict with real filter types
+ * below, in case they are supplied instead of the #defined constants.
+ * These values should NOT be changed.
+ */
+#define PNG_NO_FILTERS 0x00
+#define PNG_FILTER_NONE 0x08
+#define PNG_FILTER_SUB 0x10
+#define PNG_FILTER_UP 0x20
+#define PNG_FILTER_AVG 0x40
+#define PNG_FILTER_PAETH 0x80
+#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
+ PNG_FILTER_AVG | PNG_FILTER_PAETH)
+
+/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
+ * These defines should NOT be changed.
+ */
+#define PNG_FILTER_VALUE_NONE 0
+#define PNG_FILTER_VALUE_SUB 1
+#define PNG_FILTER_VALUE_UP 2
+#define PNG_FILTER_VALUE_AVG 3
+#define PNG_FILTER_VALUE_PAETH 4
+#define PNG_FILTER_VALUE_LAST 5
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */
+/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
+ * defines, either the default (minimum-sum-of-absolute-differences), or
+ * the experimental method (weighted-minimum-sum-of-absolute-differences).
+ *
+ * Weights are factors >= 1.0, indicating how important it is to keep the
+ * filter type consistent between rows. Larger numbers mean the current
+ * filter is that many times as likely to be the same as the "num_weights"
+ * previous filters. This is cumulative for each previous row with a weight.
+ * There needs to be "num_weights" values in "filter_weights", or it can be
+ * NULL if the weights aren't being specified. Weights have no influence on
+ * the selection of the first row filter. Well chosen weights can (in theory)
+ * improve the compression for a given image.
+ *
+ * Costs are factors >= 1.0 indicating the relative decoding costs of a
+ * filter type. Higher costs indicate more decoding expense, and are
+ * therefore less likely to be selected over a filter with lower computational
+ * costs. There needs to be a value in "filter_costs" for each valid filter
+ * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
+ * setting the costs. Costs try to improve the speed of decompression without
+ * unduly increasing the compressed image size.
+ *
+ * A negative weight or cost indicates the default value is to be used, and
+ * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
+ * The default values for both weights and costs are currently 1.0, but may
+ * change if good general weighting/cost heuristics can be found. If both
+ * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
+ * to the UNWEIGHTED method, but with added encoding time/computation.
+ */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
+ int heuristic_method, int num_weights, png_doublep filter_weights,
+ png_doublep filter_costs));
+#endif
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+/* Heuristic used for row filter selection. These defines should NOT be
+ * changed.
+ */
+#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */
+#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */
+#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */
+#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */
+
+/* Set the library compression level. Currently, valid values range from
+ * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
+ * (0 - no compression, 9 - "maximal" compression). Note that tests have
+ * shown that zlib compression levels 3-6 usually perform as well as level 9
+ * for PNG images, and do considerably fewer caclulations. In the future,
+ * these values may not correspond directly to the zlib compression levels.
+ */
+extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr,
+ int level));
+
+extern PNG_EXPORT(void,png_set_compression_mem_level)
+ PNGARG((png_structp png_ptr, int mem_level));
+
+extern PNG_EXPORT(void,png_set_compression_strategy)
+ PNGARG((png_structp png_ptr, int strategy));
+
+extern PNG_EXPORT(void,png_set_compression_window_bits)
+ PNGARG((png_structp png_ptr, int window_bits));
+
+extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr,
+ int method));
+
+/* These next functions are called for input/output, memory, and error
+ * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c,
+ * and call standard C I/O routines such as fread(), fwrite(), and
+ * fprintf(). These functions can be made to use other I/O routines
+ * at run time for those applications that need to handle I/O in a
+ * different manner by calling png_set_???_fn(). See libpng.txt for
+ * more information.
+ */
+
+#ifdef PNG_STDIO_SUPPORTED
+/* Initialize the input/output for the PNG file to the default functions. */
+extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp));
+#endif
+
+/* Replace the (error and abort), and warning functions with user
+ * supplied functions. If no messages are to be printed you must still
+ * write and use replacement functions. The replacement error_fn should
+ * still do a longjmp to the last setjmp location if you are using this
+ * method of error handling. If error_fn or warning_fn is NULL, the
+ * default function will be used.
+ */
+
+extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr,
+ png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
+
+/* Return the user pointer associated with the error functions */
+extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr));
+
+/* Replace the default data output functions with a user supplied one(s).
+ * If buffered output is not used, then output_flush_fn can be set to NULL.
+ * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
+ * output_flush_fn will be ignored (and thus can be NULL).
+ * It is probably a mistake to use NULL for output_flush_fn if
+ * write_data_fn is not also NULL unless you have built libpng with
+ * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's
+ * default flush function, which uses the standard *FILE structure, will
+ * be used.
+ */
+extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr,
+ png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
+
+/* Replace the default data input function with a user supplied one. */
+extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr,
+ png_voidp io_ptr, png_rw_ptr read_data_fn));
+
+/* Return the user pointer associated with the I/O functions */
+extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr));
+
+extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr,
+ png_read_status_ptr read_row_fn));
+
+extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr,
+ png_write_status_ptr write_row_fn));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* Replace the default memory allocation functions with user supplied one(s). */
+extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr,
+ png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+/* Return the user pointer associated with the memory functions */
+extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
+ png_ptr, png_user_transform_ptr read_user_transform_fn));
+#endif
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
+ png_ptr, png_user_transform_ptr write_user_transform_fn));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp
+ png_ptr, png_voidp user_transform_ptr, int user_transform_depth,
+ int user_transform_channels));
+/* Return the user pointer associated with the user transform functions */
+extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr)
+ PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr,
+ png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
+extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp
+ png_ptr));
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+/* Sets the function callbacks for the push reader, and a pointer to a
+ * user-defined structure available to the callback functions.
+ */
+extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr,
+ png_voidp progressive_ptr,
+ png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+ png_progressive_end_ptr end_fn));
+
+/* Returns the user pointer associated with the push read functions */
+extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
+ PNGARG((png_structp png_ptr));
+
+/* Function to be called when data becomes available */
+extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytep buffer, png_size_t buffer_size));
+
+/* Function that combines rows. Not very much different than the
+ * png_combine_row() call. Is this even used?????
+ */
+extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr,
+ png_bytep old_row, png_bytep new_row));
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr,
+ png_uint_32 size)) PNG_ALLOCATED;
+
+#ifdef PNG_1_0_X
+# define png_malloc_warn png_malloc
+#else
+/* Added at libpng version 1.2.4 */
+extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr,
+ png_uint_32 size)) PNG_ALLOCATED;
+#endif
+
+/* Frees a pointer allocated by png_malloc() */
+extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
+
+#ifdef PNG_1_0_X
+/* Function to allocate memory for zlib. */
+extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items,
+ uInt size));
+
+/* Function to free memory for zlib */
+extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr));
+#endif
+
+/* Free data that was allocated internally */
+extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 free_me, int num));
+#ifdef PNG_FREE_ME_SUPPORTED
+/* Reassign responsibility for freeing existing data, whether allocated
+ * by libpng or by the application
+ */
+extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int freer, png_uint_32 mask));
+#endif
+/* Assignments for png_data_freer */
+#define PNG_DESTROY_WILL_FREE_DATA 1
+#define PNG_SET_WILL_FREE_DATA 1
+#define PNG_USER_WILL_FREE_DATA 2
+/* Flags for png_ptr->free_me and info_ptr->free_me */
+#define PNG_FREE_HIST 0x0008
+#define PNG_FREE_ICCP 0x0010
+#define PNG_FREE_SPLT 0x0020
+#define PNG_FREE_ROWS 0x0040
+#define PNG_FREE_PCAL 0x0080
+#define PNG_FREE_SCAL 0x0100
+#define PNG_FREE_UNKN 0x0200
+#define PNG_FREE_LIST 0x0400
+#define PNG_FREE_PLTE 0x1000
+#define PNG_FREE_TRNS 0x2000
+#define PNG_FREE_TEXT 0x4000
+#define PNG_FREE_ALL 0x7fff
+#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+
+#ifdef PNG_USER_MEM_SUPPORTED
+extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr,
+ png_uint_32 size)) PNG_ALLOCATED;
+extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
+ png_voidp ptr));
+#endif
+
+extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
+ png_voidp s1, png_voidp s2, png_uint_32 size)) PNG_DEPRECATED;
+
+extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr,
+ png_voidp s1, int value, png_uint_32 size)) PNG_DEPRECATED;
+
+#if defined(USE_FAR_KEYWORD) /* memory model conversion function */
+extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
+ int check));
+#endif /* USE_FAR_KEYWORD */
+
+#ifndef PNG_NO_ERROR_TEXT
+/* Fatal error in PNG image of libpng - can't continue */
+extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
+ png_const_charp error_message)) PNG_NORETURN;
+
+/* The same, but the chunk name is prepended to the error string. */
+extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr,
+ png_const_charp error_message)) PNG_NORETURN;
+#else
+/* Fatal error in PNG image of libpng - can't continue */
+extern PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr)) PNG_NORETURN;
+#endif
+
+#ifndef PNG_NO_WARNINGS
+/* Non-fatal error in libpng. Can continue, but may have a problem. */
+extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr,
+ png_const_charp warning_message));
+
+#ifdef PNG_READ_SUPPORTED
+/* Non-fatal error in libpng, chunk name is prepended to message. */
+extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr,
+ png_const_charp warning_message));
+#endif /* PNG_READ_SUPPORTED */
+#endif /* PNG_NO_WARNINGS */
+
+/* The png_set_<chunk> functions are for storing values in the png_info_struct.
+ * Similarly, the png_get_<chunk> calls are used to read values from the
+ * png_info_struct, either storing the parameters in the passed variables, or
+ * setting pointers into the png_info_struct where the data is stored. The
+ * png_get_<chunk> functions return a non-zero value if the data was available
+ * in info_ptr, or return zero and do not change any of the parameters if the
+ * data was not available.
+ *
+ * These functions should be used instead of directly accessing png_info
+ * to avoid problems with future changes in the size and internal layout of
+ * png_info_struct.
+ */
+/* Returns "flag" if chunk data is valid in info_ptr. */
+extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr,
+png_infop info_ptr, png_uint_32 flag));
+
+/* Returns number of bytes needed to hold a transformed row. */
+extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+/* Returns row_pointers, which is an array of pointers to scanlines that was
+ * returned from png_read_png().
+ */
+extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+/* Set row_pointers, which is an array of pointers to scanlines for use
+ * by png_write_png().
+ */
+extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytepp row_pointers));
+#endif
+
+/* Returns number of color channels in image. */
+extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Returns image width in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image height in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image bit_depth. */
+extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image color_type. */
+extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image filter_type. */
+extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image interlace_type. */
+extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image compression_type. */
+extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image resolution in pixels per meter, from pHYs chunk data. */
+extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns pixel aspect ratio, computed from pHYs chunk data. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+#endif
+
+/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
+extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
+
+/* Returns pointer to signature string read from PNG header */
+extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_bKGD_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_16p *background));
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_16p background));
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double *white_x, double *white_y, double *red_x,
+ double *red_y, double *green_x, double *green_y, double *blue_x,
+ double *blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point
+ *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+ png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point
+ *int_blue_x, png_fixed_point *int_blue_y));
+#endif
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double white_x, double white_y, double red_x,
+ double red_y, double green_x, double green_y, double blue_x, double blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y,
+ png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+ int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+ png_fixed_point int_blue_y));
+#endif
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double *file_gamma));
+#endif
+extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point *int_file_gamma));
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double file_gamma));
+#endif
+extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point int_file_gamma));
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_16p *hist));
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_16p hist));
+#endif
+
+extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
+ int *bit_depth, int *color_type, int *interlace_method,
+ int *compression_method, int *filter_method));
+
+extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_method, int compression_method,
+ int filter_method));
+
+#ifdef PNG_oFFs_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
+ int *unit_type));
+#endif
+
+#ifdef PNG_oFFs_SUPPORTED
+extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y,
+ int unit_type));
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
+ int *type, int *nparams, png_charp *units, png_charpp *params));
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1,
+ int type, int nparams, png_charp units, png_charpp params));
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
+#endif
+
+extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_colorp *palette, int *num_palette));
+
+extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_colorp palette, int num_palette));
+
+#ifdef PNG_sBIT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_8p *sig_bit));
+#endif
+
+#ifdef PNG_sBIT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_8p sig_bit));
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int *intent));
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int intent));
+extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int intent));
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charpp name, int *compression_type,
+ png_charpp profile, png_uint_32 *proflen));
+ /* Note to maintainer: profile should be png_bytepp */
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charp name, int compression_type,
+ png_charp profile, png_uint_32 proflen));
+ /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_sPLT_tpp entries));
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_sPLT_tp entries, int nentries));
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_get_text also returns the number of text chunks in *num_text */
+extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_textp *text_ptr, int *num_text));
+#endif
+
+/*
+ * Note while png_set_text() will accept a structure whose text,
+ * language, and translated keywords are NULL pointers, the structure
+ * returned by png_get_text will always contain regular
+ * zero-terminated C strings. They might be empty strings but
+ * they will never be NULL pointers.
+ */
+
+#ifdef PNG_TEXT_SUPPORTED
+extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_textp text_ptr, int num_text));
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_timep *mod_time));
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_timep mod_time));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytep *trans, int *num_trans,
+ png_color_16p *trans_values));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytep trans, int num_trans,
+ png_color_16p trans_values));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int *unit, double *width, double *height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight));
+#endif
+#endif
+#endif /* PNG_sCAL_SUPPORTED */
+
+#ifdef PNG_sCAL_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int unit, double width, double height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int unit, png_charp swidth, png_charp sheight));
+#endif
+#endif
+#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+/* Provide a list of chunks and how they are to be handled, if the built-in
+ handling or default unknown chunk handling is not desired. Any chunks not
+ listed will be handled in the default manner. The IHDR and IEND chunks
+ must not be listed.
+ keep = 0: follow default behaviour
+ = 1: do not keep
+ = 2: keep only if safe-to-copy
+ = 3: keep even if unsafe-to-copy
+*/
+extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp
+ png_ptr, int keep, png_bytep chunk_list, int num_chunks));
+PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep
+ chunk_name));
+#endif
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns));
+extern PNG_EXPORT(void, png_set_unknown_chunk_location)
+ PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location));
+extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp
+ png_ptr, png_infop info_ptr, png_unknown_chunkpp entries));
+#endif
+
+/* Png_free_data() will turn off the "valid" flag for anything it frees.
+ * If you need to turn it off for a chunk that your application has freed,
+ * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK);
+ */
+extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int mask));
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+/* The "params" pointer is currently not used and is for future expansion. */
+extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr,
+ png_infop info_ptr,
+ int transforms,
+ png_voidp params));
+extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr,
+ png_infop info_ptr,
+ int transforms,
+ png_voidp params));
+#endif
+
+/* Define PNG_DEBUG at compile time for debugging information. Higher
+ * numbers for PNG_DEBUG mean more debugging information. This has
+ * only been added since version 0.95 so it is not implemented throughout
+ * libpng yet, but more support will be added as needed.
+ */
+#ifdef PNG_DEBUG
+#if (PNG_DEBUG > 0)
+#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
+#include <crtdbg.h>
+#if (PNG_DEBUG > 1)
+#ifndef _DEBUG
+# define _DEBUG
+#endif
+#ifndef png_debug
+#define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
+#endif
+#ifndef png_debug1
+#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
+#endif
+#ifndef png_debug2
+#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
+#endif
+#endif
+#else /* PNG_DEBUG_FILE || !_MSC_VER */
+#ifndef PNG_DEBUG_FILE
+#define PNG_DEBUG_FILE stderr
+#endif /* PNG_DEBUG_FILE */
+
+#if (PNG_DEBUG > 1)
+/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on non-ISO
+ * compilers.
+ */
+# ifdef __STDC__
+# ifndef png_debug
+# define png_debug(l,m) \
+ { \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
+ }
+# endif
+# ifndef png_debug1
+# define png_debug1(l,m,p1) \
+ { \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
+ }
+# endif
+# ifndef png_debug2
+# define png_debug2(l,m,p1,p2) \
+ { \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
+ }
+# endif
+# else /* __STDC __ */
+# ifndef png_debug
+# define png_debug(l,m) \
+ { \
+ int num_tabs=l; \
+ char format[256]; \
+ snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+ m,PNG_STRING_NEWLINE); \
+ fprintf(PNG_DEBUG_FILE,format); \
+ }
+# endif
+# ifndef png_debug1
+# define png_debug1(l,m,p1) \
+ { \
+ int num_tabs=l; \
+ char format[256]; \
+ snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+ m,PNG_STRING_NEWLINE); \
+ fprintf(PNG_DEBUG_FILE,format,p1); \
+ }
+# endif
+# ifndef png_debug2
+# define png_debug2(l,m,p1,p2) \
+ { \
+ int num_tabs=l; \
+ char format[256]; \
+ snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+ m,PNG_STRING_NEWLINE); \
+ fprintf(PNG_DEBUG_FILE,format,p1,p2); \
+ }
+# endif
+# endif /* __STDC __ */
+#endif /* (PNG_DEBUG > 1) */
+
+#endif /* _MSC_VER */
+#endif /* (PNG_DEBUG > 0) */
+#endif /* PNG_DEBUG */
+#ifndef png_debug
+#define png_debug(l, m)
+#endif
+#ifndef png_debug1
+#define png_debug1(l, m, p1)
+#endif
+#ifndef png_debug2
+#define png_debug2(l, m, p1, p2)
+#endif
+
+extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr));
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
+ png_ptr, png_uint_32 mng_features_permitted));
+#endif
+
+/* For use in png_set_keep_unknown, added to version 1.2.6 */
+#define PNG_HANDLE_CHUNK_AS_DEFAULT 0
+#define PNG_HANDLE_CHUNK_NEVER 1
+#define PNG_HANDLE_CHUNK_IF_SAFE 2
+#define PNG_HANDLE_CHUNK_ALWAYS 3
+
+/* Added to version 1.2.0 */
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+#ifdef PNG_MMX_CODE_SUPPORTED
+#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */
+#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */
+#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04
+#define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08
+#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10
+#define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20
+#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40
+#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80
+#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */
+
+#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
+ | PNG_ASM_FLAG_MMX_READ_INTERLACE \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_UP \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH )
+#define PNG_MMX_WRITE_FLAGS ( 0 )
+
+#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \
+ | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \
+ | PNG_MMX_READ_FLAGS \
+ | PNG_MMX_WRITE_FLAGS )
+
+#define PNG_SELECT_READ 1
+#define PNG_SELECT_WRITE 2
+#endif /* PNG_MMX_CODE_SUPPORTED */
+
+#ifndef PNG_1_0_X
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask)
+ PNGARG((int flag_select, int *compilerID));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask)
+ PNGARG((int flag_select));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_asm_flags)
+ PNGARG((png_structp png_ptr));
+
+/* pngget.c */
+extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold)
+ PNGARG((png_structp png_ptr));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold)
+ PNGARG((png_structp png_ptr));
+
+/* pngset.c */
+extern PNG_EXPORT(void,png_set_asm_flags)
+ PNGARG((png_structp png_ptr, png_uint_32 asm_flags));
+
+/* pngset.c */
+extern PNG_EXPORT(void,png_set_mmx_thresholds)
+ PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold,
+ png_uint_32 mmx_rowbytes_threshold));
+
+#endif /* PNG_1_0_X */
+
+#ifndef PNG_1_0_X
+/* png.c, pnggccrd.c, or pngvcrd.c */
+extern PNG_EXPORT(int,png_mmx_support) PNGARG((void));
+#endif /* PNG_1_0_X */
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+
+/* Strip the prepended error numbers ("#nnn ") from error and warning
+ * messages before passing them to the error or warning handler.
+ */
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
+ png_ptr, png_uint_32 strip_mode));
+#endif
+
+/* Added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp
+ png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max));
+extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp
+ png_ptr));
+extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp
+ png_ptr));
+#endif
+/* Maintainer: Put new public prototypes here ^, in libpng.3, and in
+ * project defs
+ */
+
+#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
+/* With these routines we avoid an integer divide, which will be slower on
+ * most machines. However, it does take more operations than the corresponding
+ * divide method, so it may be slower on a few RISC systems. There are two
+ * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
+ *
+ * Note that the rounding factors are NOT supposed to be the same! 128 and
+ * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
+ * standard method.
+ *
+ * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
+ */
+
+ /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
+
+# define png_composite(composite, fg, alpha, bg) \
+ { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \
+ + (png_uint_16)(bg)*(png_uint_16)(255 - \
+ (png_uint_16)(alpha)) + (png_uint_16)128); \
+ (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \
+ + (png_uint_32)(bg)*(png_uint_32)(65535L - \
+ (png_uint_32)(alpha)) + (png_uint_32)32768L); \
+ (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
+
+#else /* Standard method using integer division */
+
+# define png_composite(composite, fg, alpha, bg) \
+ (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \
+ (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+ (png_uint_16)127) / 255)
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+ (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \
+ (png_uint_32)32767) / (png_uint_32)65535L)
+
+#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
+
+/* Inline macros to do direct reads of bytes from the input buffer. These
+ * require that you are using an architecture that uses PNG byte ordering
+ * (MSB first) and supports unaligned data storage. I think that PowerPC
+ * in big-endian mode and 680x0 are the only ones that will support this.
+ * The x86 line of processors definitely do not. The png_get_int_32()
+ * routine also assumes we are using two's complement format for negative
+ * values, which is almost certainly true.
+ */
+#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
+# define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
+# define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
+# define png_get_int_32(buf) ( *((png_int_32p) (buf)))
+#else
+extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf));
+extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf));
+extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf));
+#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */
+extern PNG_EXPORT(png_uint_32,png_get_uint_31)
+ PNGARG((png_structp png_ptr, png_bytep buf));
+/* No png_get_int_16 -- may be added if there's a real need for it. */
+
+/* Place a 32-bit number into a buffer in PNG byte order (big-endian).
+ */
+extern PNG_EXPORT(void,png_save_uint_32)
+ PNGARG((png_bytep buf, png_uint_32 i));
+extern PNG_EXPORT(void,png_save_int_32)
+ PNGARG((png_bytep buf, png_int_32 i));
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+extern PNG_EXPORT(void,png_save_uint_16)
+ PNGARG((png_bytep buf, unsigned int i));
+/* No png_save_int_16 -- may be added if there's a real need for it. */
+
+/* ************************************************************************* */
+
+/* These next functions are used internally in the code. They generally
+ * shouldn't be used unless you are writing code to add or replace some
+ * functionality in libpng. More information about most functions can
+ * be found in the files where the functions are located.
+ */
+
+
+/* Various modes of operation, that are visible to applications because
+ * they are used for unknown chunk location.
+ */
+#define PNG_HAVE_IHDR 0x01
+#define PNG_HAVE_PLTE 0x02
+#define PNG_HAVE_IDAT 0x04
+#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */
+#define PNG_HAVE_IEND 0x10
+
+#ifdef PNG_INTERNAL
+
+/* More modes of operation. Note that after an init, mode is set to
+ * zero automatically when the structure is created.
+ */
+#define PNG_HAVE_gAMA 0x20
+#define PNG_HAVE_cHRM 0x40
+#define PNG_HAVE_sRGB 0x80
+#define PNG_HAVE_CHUNK_HEADER 0x100
+#define PNG_WROTE_tIME 0x200
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
+#define PNG_BACKGROUND_IS_GRAY 0x800
+#define PNG_HAVE_PNG_SIGNATURE 0x1000
+#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
+
+/* Flags for the transformations the PNG library does on the image data */
+#define PNG_BGR 0x0001
+#define PNG_INTERLACE 0x0002
+#define PNG_PACK 0x0004
+#define PNG_SHIFT 0x0008
+#define PNG_SWAP_BYTES 0x0010
+#define PNG_INVERT_MONO 0x0020
+#define PNG_DITHER 0x0040
+#define PNG_BACKGROUND 0x0080
+#define PNG_BACKGROUND_EXPAND 0x0100
+ /* 0x0200 unused */
+#define PNG_16_TO_8 0x0400
+#define PNG_RGBA 0x0800
+#define PNG_EXPAND 0x1000
+#define PNG_GAMMA 0x2000
+#define PNG_GRAY_TO_RGB 0x4000
+#define PNG_FILLER 0x8000L
+#define PNG_PACKSWAP 0x10000L
+#define PNG_SWAP_ALPHA 0x20000L
+#define PNG_STRIP_ALPHA 0x40000L
+#define PNG_INVERT_ALPHA 0x80000L
+#define PNG_USER_TRANSFORM 0x100000L
+#define PNG_RGB_TO_GRAY_ERR 0x200000L
+#define PNG_RGB_TO_GRAY_WARN 0x400000L
+#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */
+ /* 0x800000L Unused */
+#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */
+#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */
+#define PNG_PREMULTIPLY_ALPHA 0x4000000L /* Added to libpng-1.2.41 */
+ /* by volker */
+ /* 0x8000000L unused */
+ /* 0x10000000L unused */
+ /* 0x20000000L unused */
+ /* 0x40000000L unused */
+
+/* Flags for png_create_struct */
+#define PNG_STRUCT_PNG 0x0001
+#define PNG_STRUCT_INFO 0x0002
+
+/* Scaling factor for filter heuristic weighting calculations */
+#define PNG_WEIGHT_SHIFT 8
+#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
+#define PNG_COST_SHIFT 3
+#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
+
+/* Flags for the png_ptr->flags rather than declaring a byte for each one */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
+#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002
+#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004
+#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008
+#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010
+#define PNG_FLAG_ZLIB_FINISHED 0x0020
+#define PNG_FLAG_ROW_INIT 0x0040
+#define PNG_FLAG_FILLER_AFTER 0x0080
+#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
+#define PNG_FLAG_CRC_CRITICAL_USE 0x0400
+#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
+#define PNG_FLAG_FREE_PLTE 0x1000
+#define PNG_FLAG_FREE_TRNS 0x2000
+#define PNG_FLAG_FREE_HIST 0x4000
+#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L
+#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L
+#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L
+#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L
+#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L
+#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L
+#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */
+#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */
+ /* 0x800000L unused */
+ /* 0x1000000L unused */
+ /* 0x2000000L unused */
+ /* 0x4000000L unused */
+ /* 0x8000000L unused */
+ /* 0x10000000L unused */
+ /* 0x20000000L unused */
+ /* 0x40000000L unused */
+
+#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
+ PNG_FLAG_CRC_ANCILLARY_NOWARN)
+
+#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \
+ PNG_FLAG_CRC_CRITICAL_IGNORE)
+
+#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \
+ PNG_FLAG_CRC_CRITICAL_MASK)
+
+/* Save typing and make code easier to understand */
+
+#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
+ abs((int)((c1).green) - (int)((c2).green)) + \
+ abs((int)((c1).blue) - (int)((c2).blue)))
+
+/* Added to libpng-1.2.6 JB */
+#define PNG_ROWBYTES(pixel_bits, width) \
+ ((pixel_bits) >= 8 ? \
+ ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \
+ (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) )
+
+/* PNG_OUT_OF_RANGE returns true if value is outside the range
+ * ideal-delta..ideal+delta. Each argument is evaluated twice.
+ * "ideal" and "delta" should be constants, normally simple
+ * integers, "value" a variable. Added to libpng-1.2.6 JB
+ */
+#define PNG_OUT_OF_RANGE(value, ideal, delta) \
+ ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
+
+/* Variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* Place to hold the signature string for a PNG file. */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+ PNG_EXPORT_VAR (PNG_CONST png_byte FARDATA) png_sig[8];
+#else
+#endif
+#endif /* PNG_NO_EXTERN */
+
+/* Constant strings for known chunk types. If you need to add a chunk,
+ * define the name here, and add an invocation of the macro in png.c and
+ * wherever it's needed.
+ */
+#define PNG_IHDR png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'}
+#define PNG_IDAT png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'}
+#define PNG_IEND png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'}
+#define PNG_PLTE png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'}
+#define PNG_bKGD png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'}
+#define PNG_cHRM png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'}
+#define PNG_gAMA png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'}
+#define PNG_hIST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'}
+#define PNG_iCCP png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'}
+#define PNG_iTXt png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'}
+#define PNG_oFFs png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'}
+#define PNG_pCAL png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'}
+#define PNG_sCAL png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'}
+#define PNG_pHYs png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'}
+#define PNG_sBIT png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'}
+#define PNG_sPLT png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'}
+#define PNG_sRGB png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'}
+#define PNG_tEXt png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'}
+#define PNG_tIME png_byte png_tIME[5] = {116, 73, 77, 69, '\0'}
+#define PNG_tRNS png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'}
+#define PNG_zTXt png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'}
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_IDAT[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_IEND[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_PLTE[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_bKGD[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_cHRM[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_gAMA[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_hIST[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_iCCP[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_iTXt[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_oFFs[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_pCAL[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sCAL[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_pHYs[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sBIT[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sPLT[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_sRGB[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_tEXt[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5];
+PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5];
+#endif /* PNG_USE_GLOBAL_ARRAYS */
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Initialize png_ptr struct for reading, and allocate any other memory.
+ * (old interface - DEPRECATED - use png_create_read_struct instead).
+ */
+extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr))
+ PNG_DEPRECATED;
+#undef png_read_init
+#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \
+ PNG_LIBPNG_VER_STRING, png_sizeof(png_struct));
+#endif
+
+extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size));
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+ png_info_size));
+#endif
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Initialize png_ptr struct for writing, and allocate any other memory.
+ * (old interface - DEPRECATED - use png_create_write_struct instead).
+ */
+extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr))
+ PNG_DEPRECATED;
+#undef png_write_init
+#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \
+ PNG_LIBPNG_VER_STRING, png_sizeof(png_struct));
+#endif
+
+extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size));
+extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+ png_info_size));
+
+/* Allocate memory for an internal libpng struct */
+PNG_EXTERN png_voidp png_create_struct PNGARG((int type)) PNG_PRIVATE;
+
+/* Free memory from internal libpng struct */
+PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)) PNG_PRIVATE;
+
+PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
+ malloc_fn, png_voidp mem_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
+ png_free_ptr free_fn, png_voidp mem_ptr)) PNG_PRIVATE;
+
+/* Free any memory that info_ptr points to and reset struct. */
+PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
+ png_infop info_ptr)) PNG_PRIVATE;
+
+#ifndef PNG_1_0_X
+/* Function to allocate memory for zlib. */
+PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items,
+ uInt size)) PNG_PRIVATE;
+
+/* Function to free memory for zlib */
+PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)) PNG_PRIVATE;
+
+#ifdef PNG_SIZE_T
+/* Function to convert a sizeof an item to png_sizeof item */
+ PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size))
+ PNG_PRIVATE;
+#endif
+
+/* Next four functions are used internally as callbacks. PNGAPI is required
+ * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3.
+ */
+
+PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr,
+ png_bytep data, png_size_t length)) PNG_PRIVATE;
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t length)) PNG_PRIVATE;
+#endif
+
+PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr,
+ png_bytep data, png_size_t length)) PNG_PRIVATE;
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+#ifdef PNG_STDIO_SUPPORTED
+PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr))
+ PNG_PRIVATE;
+#endif
+#endif
+#else /* PNG_1_0_X */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t length)) PNG_PRIVATE;
+#endif
+#endif /* PNG_1_0_X */
+
+/* Reset the CRC variable */
+PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+/* Write the "data" buffer to whatever output you are using. */
+PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
+ png_size_t length)) PNG_PRIVATE;
+
+/* Read data from whatever input you are using into the "data" buffer */
+PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
+ png_size_t length)) PNG_PRIVATE;
+
+/* Read bytes into buf, and update png_ptr->crc */
+PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
+ png_size_t length)) PNG_PRIVATE;
+
+/* Decompress data in a chunk that uses compression */
+#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \
+ defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
+PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr,
+ int comp_type, png_size_t chunklength,
+ png_size_t prefix_length, png_size_t *data_length)) PNG_PRIVATE;
+#endif
+
+/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)
+ PNG_PRIVATE);
+
+/* Read the CRC from the file and compare it to the libpng calculated CRC */
+PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+/* Calculate the CRC over a section of data. Note that we are only
+ * passing a maximum of 64K on systems that have this as a memory limit,
+ * since this is the maximum buffer size we can specify.
+ */
+PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
+ png_size_t length)) PNG_PRIVATE;
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+#endif
+
+/* Simple function to write the signature */
+PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+/* Write various chunks */
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.
+ */
+PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
+ png_uint_32 height,
+ int bit_depth, int color_type, int compression_method, int filter_method,
+ int interlace_method)) PNG_PRIVATE;
+
+PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
+ png_uint_32 num_pal)) PNG_PRIVATE;
+
+PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
+ png_size_t length)) PNG_PRIVATE;
+
+PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma))
+ PNG_PRIVATE;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr,
+ png_fixed_point file_gamma)) PNG_PRIVATE;
+#endif
+#endif
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
+ int color_type)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
+ double white_x, double white_y,
+ double red_x, double red_y, double green_x, double green_y,
+ double blue_x, double blue_y)) PNG_PRIVATE;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
+ png_fixed_point int_white_x, png_fixed_point int_white_y,
+ png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+ int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+ png_fixed_point int_blue_y)) PNG_PRIVATE;
+#endif
+#endif
+
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
+ int intent)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
+ png_charp name, int compression_type,
+ png_charp profile, int proflen)) PNG_PRIVATE;
+ /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
+ png_sPLT_tp palette)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
+ png_color_16p values, int number, int color_type)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
+ png_color_16p values, int color_type)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
+ int num_hist)) PNG_PRIVATE;
+#endif
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
+ png_charp key, png_charpp new_key)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
+ png_charp text, png_size_t text_len)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
+ png_charp text, png_size_t text_len, int compression)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
+ int compression, png_charp key, png_charp lang, png_charp lang_key,
+ png_charp text)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */
+PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_textp text_ptr, int num_text)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
+ png_int_32 x_offset, png_int_32 y_offset, int unit_type)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
+ png_int_32 X0, png_int_32 X1, int type, int nparams,
+ png_charp units, png_charpp params)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
+ png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
+ int unit_type)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
+ png_timep mod_time)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
+ int unit, double width, double height)) PNG_PRIVATE;
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
+ int unit, png_charp width, png_charp height)) PNG_PRIVATE;
+#endif
+#endif
+#endif
+
+/* Called when finished processing a row of data */
+PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+/* Internal use only. Called before first row of data */
+PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+#endif
+
+/* Combine a row of data, dealing with alpha, etc. if requested */
+PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
+ int mask)) PNG_PRIVATE;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* Expand an interlaced row */
+/* OLD pre-1.0.9 interface:
+PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
+ png_bytep row, int pass, png_uint_32 transformations)) PNG_PRIVATE;
+ */
+PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+#endif
+
+/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+/* Grab pixels out of a row for an interlaced pass */
+PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
+ png_bytep row, int pass)) PNG_PRIVATE;
+#endif
+
+/* Unfilter a row */
+PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
+ png_row_infop row_info, png_bytep row, png_bytep prev_row,
+ int filter)) PNG_PRIVATE;
+
+/* Choose the best filter to use and filter the row data */
+PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
+ png_row_infop row_info)) PNG_PRIVATE;
+
+/* Write out the filtered row. */
+PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
+ png_bytep filtered_row)) PNG_PRIVATE;
+/* Finish a row while reading, dealing with interlacing passes, etc. */
+PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
+
+/* Initialize the row buffers, etc. */
+PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+/* Optional call to update the users info structure */
+PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
+ png_infop info_ptr)) PNG_PRIVATE;
+
+/* These are the functions that do the transformations */
+#ifdef PNG_READ_FILLER_SUPPORTED
+PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
+ png_bytep row, png_uint_32 filler, png_uint_32 flags)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+ defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
+ png_bytep row, png_uint_32 flags)) PNG_PRIVATE;
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop
+ row_info, png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_8p sig_bits)) PNG_PRIVATE;
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info,
+ png_bytep row, png_bytep palette_lookup,
+ png_bytep dither_lookup)) PNG_PRIVATE;
+
+# ifdef PNG_CORRECT_PALETTE_SUPPORTED
+PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
+ png_colorp palette, int num_palette)) PNG_PRIVATE;
+# endif
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
+ png_bytep row, png_uint_32 bit_depth)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_8p bit_depth)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+#ifdef PNG_READ_GAMMA_SUPPORTED
+PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_16p trans_values, png_color_16p background,
+ png_color_16p background_1,
+ png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+ png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+ png_uint_16pp gamma_16_to_1, int gamma_shift)) PNG_PRIVATE;
+#else
+PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_16p trans_values, png_color_16p background)) PNG_PRIVATE;
+#endif
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
+ png_bytep gamma_table, png_uint_16pp gamma_16_table,
+ int gamma_shift)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
+ png_bytep row, png_colorp palette, png_bytep trans,
+ int num_trans)) PNG_PRIVATE;
+PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
+ png_bytep row, png_color_16p trans_value)) PNG_PRIVATE;
+#endif
+
+/* The following decodes the appropriate chunks, and does error correction,
+ * then calls the appropriate callback for the chunk if it is valid.
+ */
+
+/* Decode the IHDR chunk */
+PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+#endif
+
+PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE;
+
+PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
+ png_bytep chunk_name)) PNG_PRIVATE;
+
+/* Handle the transformations for reading and writing */
+PNG_EXTERN void png_do_read_transformations
+ PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_do_write_transformations
+ PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+PNG_EXTERN void png_init_read_transformations
+ PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
+ png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
+ png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
+ png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t buffer_length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t buffer_length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
+ png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
+ png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr,
+ png_bytep row)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
+ png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
+ png_infop info_ptr)) PNG_PRIVATE;
+PNG_EXTERN void png_read_push_finish_row
+ PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+#ifdef PNG_READ_tEXt_SUPPORTED
+PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr)) PNG_PRIVATE;
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr)) PNG_PRIVATE;
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE;
+PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr)) PNG_PRIVATE;
+#endif
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
+ png_bytep row)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+#ifdef PNG_MMX_CODE_SUPPORTED
+/* png.c */ /* PRIVATE */
+PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+#endif
+#endif
+
+
+/* The following six functions will be exported in libpng-1.4.0. */
+#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
+PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_pHYs_SUPPORTED
+PNG_EXTERN png_uint_32 png_get_pHYs_dpi PNGARG((png_structp png_ptr,
+png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+#endif /* PNG_pHYs_SUPPORTED */
+#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
+
+/* Read the chunk header (length + type name) */
+PNG_EXTERN png_uint_32 png_read_chunk_header
+ PNGARG((png_structp png_ptr)) PNG_PRIVATE;
+
+/* Added at libpng version 1.2.34 */
+#ifdef PNG_cHRM_SUPPORTED
+PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr,
+ png_fixed_point int_white_x, png_fixed_point int_white_y,
+ png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+ int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+ png_fixed_point int_blue_y)) PNG_PRIVATE;
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_CHECK_cHRM_SUPPORTED
+/* Added at libpng version 1.2.34 */
+PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2,
+ unsigned long *hi_product, unsigned long *lo_product)) PNG_PRIVATE;
+#endif
+#endif
+
+/* Added at libpng version 1.2.41 */
+PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type)) PNG_PRIVATE;
+
+/* Added at libpng version 1.2.41 */
+PNG_EXTERN png_voidp png_calloc PNGARG((png_structp png_ptr,
+ png_uint_32 size));
+
+/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
+
+#endif /* PNG_INTERNAL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNG_VERSION_INFO_ONLY */
+/* Do not put anything past this line */
+#endif /* PNG_H */
diff --git a/src/libpng/pngconf.h b/src/libpng/pngconf.h
new file mode 100644
index 0000000..57293c3
--- /dev/null
+++ b/src/libpng/pngconf.h
@@ -0,0 +1,1665 @@
+
+/* pngconf.h - machine configurable file for libpng
+ *
+ * libpng version 1.2.46 - July 9, 2011
+ * Copyright (c) 1998-2011 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* Any machine specific code is near the front of this file, so if you
+ * are configuring libpng for a machine, you may want to read the section
+ * starting here down to where it starts to typedef png_color, png_text,
+ * and png_info.
+ */
+
+#ifndef PNGCONF_H
+#define PNGCONF_H
+
+#define PNG_1_2_X
+
+/*
+ * PNG_USER_CONFIG has to be defined on the compiler command line. This
+ * includes the resource compiler for Windows DLL configurations.
+ */
+#ifdef PNG_USER_CONFIG
+# ifndef PNG_USER_PRIVATEBUILD
+# define PNG_USER_PRIVATEBUILD
+# endif
+#include "pngusr.h"
+#endif
+
+/* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */
+#ifdef PNG_CONFIGURE_LIBPNG
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#endif
+
+/*
+ * Added at libpng-1.2.8
+ *
+ * If you create a private DLL you need to define in "pngusr.h" the followings:
+ * #define PNG_USER_PRIVATEBUILD <Describes by whom and why this version of
+ * the DLL was built>
+ * e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons."
+ * #define PNG_USER_DLLFNAME_POSTFIX <two-letter postfix that serve to
+ * distinguish your DLL from those of the official release. These
+ * correspond to the trailing letters that come after the version
+ * number and must match your private DLL name>
+ * e.g. // private DLL "libpng13gx.dll"
+ * #define PNG_USER_DLLFNAME_POSTFIX "gx"
+ *
+ * The following macros are also at your disposal if you want to complete the
+ * DLL VERSIONINFO structure.
+ * - PNG_USER_VERSIONINFO_COMMENTS
+ * - PNG_USER_VERSIONINFO_COMPANYNAME
+ * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS
+ */
+
+#ifdef __STDC__
+#ifdef SPECIALBUILD
+# pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\
+ are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.")
+#endif
+
+#ifdef PRIVATEBUILD
+# pragma message("PRIVATEBUILD is deprecated.\
+ Use PNG_USER_PRIVATEBUILD instead.")
+# define PNG_USER_PRIVATEBUILD PRIVATEBUILD
+#endif
+#endif /* __STDC__ */
+
+#ifndef PNG_VERSION_INFO_ONLY
+
+/* End of material added to libpng-1.2.8 */
+
+/* Added at libpng-1.2.19, removed at libpng-1.2.20 because it caused trouble
+ Restored at libpng-1.2.21 */
+#if !defined(PNG_NO_WARN_UNINITIALIZED_ROW) && \
+ !defined(PNG_WARN_UNINITIALIZED_ROW)
+# define PNG_WARN_UNINITIALIZED_ROW 1
+#endif
+/* End of material added at libpng-1.2.19/1.2.21 */
+
+/* This is the size of the compression buffer, and thus the size of
+ * an IDAT chunk. Make this whatever size you feel is best for your
+ * machine. One of these will be allocated per png_struct. When this
+ * is full, it writes the data to the disk, and does some other
+ * calculations. Making this an extremely small size will slow
+ * the library down, but you may want to experiment to determine
+ * where it becomes significant, if you are concerned with memory
+ * usage. Note that zlib allocates at least 32Kb also. For readers,
+ * this describes the size of the buffer available to read the data in.
+ * Unless this gets smaller than the size of a row (compressed),
+ * it should not make much difference how big this is.
+ */
+
+#ifndef PNG_ZBUF_SIZE
+# define PNG_ZBUF_SIZE 8192
+#endif
+
+/* Enable if you want a write-only libpng */
+
+#ifndef PNG_NO_READ_SUPPORTED
+# define PNG_READ_SUPPORTED
+#endif
+
+/* Enable if you want a read-only libpng */
+
+#ifndef PNG_NO_WRITE_SUPPORTED
+# define PNG_WRITE_SUPPORTED
+#endif
+
+/* Enabled in 1.2.41. */
+#ifdef PNG_ALLOW_BENIGN_ERRORS
+# define png_benign_error png_warning
+# define png_chunk_benign_error png_chunk_warning
+#else
+# ifndef PNG_BENIGN_ERRORS_SUPPORTED
+# define png_benign_error png_error
+# define png_chunk_benign_error png_chunk_error
+# endif
+#endif
+
+/* Added in libpng-1.2.41 */
+#if !defined(PNG_NO_WARNINGS) && !defined(PNG_WARNINGS_SUPPORTED)
+# define PNG_WARNINGS_SUPPORTED
+#endif
+
+#if !defined(PNG_NO_ERROR_TEXT) && !defined(PNG_ERROR_TEXT_SUPPORTED)
+# define PNG_ERROR_TEXT_SUPPORTED
+#endif
+
+#if !defined(PNG_NO_CHECK_cHRM) && !defined(PNG_CHECK_cHRM_SUPPORTED)
+# define PNG_CHECK_cHRM_SUPPORTED
+#endif
+
+/* Enabled by default in 1.2.0. You can disable this if you don't need to
+ * support PNGs that are embedded in MNG datastreams
+ */
+#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES)
+# ifndef PNG_MNG_FEATURES_SUPPORTED
+# define PNG_MNG_FEATURES_SUPPORTED
+# endif
+#endif
+
+#ifndef PNG_NO_FLOATING_POINT_SUPPORTED
+# ifndef PNG_FLOATING_POINT_SUPPORTED
+# define PNG_FLOATING_POINT_SUPPORTED
+# endif
+#endif
+
+/* If you are running on a machine where you cannot allocate more
+ * than 64K of memory at once, uncomment this. While libpng will not
+ * normally need that much memory in a chunk (unless you load up a very
+ * large file), zlib needs to know how big of a chunk it can use, and
+ * libpng thus makes sure to check any memory allocation to verify it
+ * will fit into memory.
+#define PNG_MAX_MALLOC_64K
+ */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+# define PNG_MAX_MALLOC_64K
+#endif
+
+/* Special munging to support doing things the 'cygwin' way:
+ * 'Normal' png-on-win32 defines/defaults:
+ * PNG_BUILD_DLL -- building dll
+ * PNG_USE_DLL -- building an application, linking to dll
+ * (no define) -- building static library, or building an
+ * application and linking to the static lib
+ * 'Cygwin' defines/defaults:
+ * PNG_BUILD_DLL -- (ignored) building the dll
+ * (no define) -- (ignored) building an application, linking to the dll
+ * PNG_STATIC -- (ignored) building the static lib, or building an
+ * application that links to the static lib.
+ * ALL_STATIC -- (ignored) building various static libs, or building an
+ * application that links to the static libs.
+ * Thus,
+ * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and
+ * this bit of #ifdefs will define the 'correct' config variables based on
+ * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but
+ * unnecessary.
+ *
+ * Also, the precedence order is:
+ * ALL_STATIC (since we can't #undef something outside our namespace)
+ * PNG_BUILD_DLL
+ * PNG_STATIC
+ * (nothing) == PNG_USE_DLL
+ *
+ * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent
+ * of auto-import in binutils, we no longer need to worry about
+ * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore,
+ * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes
+ * to __declspec() stuff. However, we DO need to worry about
+ * PNG_BUILD_DLL and PNG_STATIC because those change some defaults
+ * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed.
+ */
+#ifdef __CYGWIN__
+# ifdef ALL_STATIC
+# ifdef PNG_BUILD_DLL
+# undef PNG_BUILD_DLL
+# endif
+# ifdef PNG_USE_DLL
+# undef PNG_USE_DLL
+# endif
+# ifdef PNG_DLL
+# undef PNG_DLL
+# endif
+# ifndef PNG_STATIC
+# define PNG_STATIC
+# endif
+# else
+# ifdef PNG_BUILD_DLL
+# ifdef PNG_STATIC
+# undef PNG_STATIC
+# endif
+# ifdef PNG_USE_DLL
+# undef PNG_USE_DLL
+# endif
+# ifndef PNG_DLL
+# define PNG_DLL
+# endif
+# else
+# ifdef PNG_STATIC
+# ifdef PNG_USE_DLL
+# undef PNG_USE_DLL
+# endif
+# ifdef PNG_DLL
+# undef PNG_DLL
+# endif
+# else
+# ifndef PNG_USE_DLL
+# define PNG_USE_DLL
+# endif
+# ifndef PNG_DLL
+# define PNG_DLL
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* This protects us against compilers that run on a windowing system
+ * and thus don't have or would rather us not use the stdio types:
+ * stdin, stdout, and stderr. The only one currently used is stderr
+ * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will
+ * prevent these from being compiled and used. #defining PNG_NO_STDIO
+ * will also prevent these, plus will prevent the entire set of stdio
+ * macros and functions (FILE *, printf, etc.) from being compiled and used,
+ * unless (PNG_DEBUG > 0) has been #defined.
+ *
+ * #define PNG_NO_CONSOLE_IO
+ * #define PNG_NO_STDIO
+ */
+
+#if !defined(PNG_NO_STDIO) && !defined(PNG_STDIO_SUPPORTED)
+# define PNG_STDIO_SUPPORTED
+#endif
+
+#ifdef _WIN32_WCE
+# include <windows.h>
+ /* Console I/O functions are not supported on WindowsCE */
+# define PNG_NO_CONSOLE_IO
+ /* abort() may not be supported on some/all Windows CE platforms */
+# define PNG_ABORT() exit(-1)
+# ifdef PNG_DEBUG
+# undef PNG_DEBUG
+# endif
+#endif
+
+#ifdef PNG_BUILD_DLL
+# ifndef PNG_CONSOLE_IO_SUPPORTED
+# ifndef PNG_NO_CONSOLE_IO
+# define PNG_NO_CONSOLE_IO
+# endif
+# endif
+#endif
+
+# ifdef PNG_NO_STDIO
+# ifndef PNG_NO_CONSOLE_IO
+# define PNG_NO_CONSOLE_IO
+# endif
+# ifdef PNG_DEBUG
+# if (PNG_DEBUG > 0)
+# include <stdio.h>
+# endif
+# endif
+# else
+# ifndef _WIN32_WCE
+/* "stdio.h" functions are not supported on WindowsCE */
+# include <stdio.h>
+# endif
+# endif
+
+#if !(defined PNG_NO_CONSOLE_IO) && !defined(PNG_CONSOLE_IO_SUPPORTED)
+# define PNG_CONSOLE_IO_SUPPORTED
+#endif
+
+/* This macro protects us against machines that don't have function
+ * prototypes (ie K&R style headers). If your compiler does not handle
+ * function prototypes, define this macro and use the included ansi2knr.
+ * I've always been able to use _NO_PROTO as the indicator, but you may
+ * need to drag the empty declaration out in front of here, or change the
+ * ifdef to suit your own needs.
+ */
+#ifndef PNGARG
+
+#ifdef OF /* zlib prototype munger */
+# define PNGARG(arglist) OF(arglist)
+#else
+
+#ifdef _NO_PROTO
+# define PNGARG(arglist) ()
+# ifndef PNG_TYPECAST_NULL
+# define PNG_TYPECAST_NULL
+# endif
+#else
+# define PNGARG(arglist) arglist
+#endif /* _NO_PROTO */
+
+
+#endif /* OF */
+
+#endif /* PNGARG */
+
+/* Try to determine if we are compiling on a Mac. Note that testing for
+ * just __MWERKS__ is not good enough, because the Codewarrior is now used
+ * on non-Mac platforms.
+ */
+#ifndef MACOS
+# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
+ defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
+# define MACOS
+# endif
+#endif
+
+/* enough people need this for various reasons to include it here */
+#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE)
+# include <sys/types.h>
+#endif
+
+#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED)
+# define PNG_SETJMP_SUPPORTED
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* This is an attempt to force a single setjmp behaviour on Linux. If
+ * the X config stuff didn't define _BSD_SOURCE we wouldn't need this.
+ *
+ * You can bypass this test if you know that your application uses exactly
+ * the same setjmp.h that was included when libpng was built. Only define
+ * PNG_SKIP_SETJMP_CHECK while building your application, prior to the
+ * application's '#include "png.h"'. Don't define PNG_SKIP_SETJMP_CHECK
+ * while building a separate libpng library for general use.
+ */
+
+# ifndef PNG_SKIP_SETJMP_CHECK
+# ifdef __linux__
+# ifdef _BSD_SOURCE
+# define PNG_SAVE_BSD_SOURCE
+# undef _BSD_SOURCE
+# endif
+# ifdef _SETJMP_H
+ /* If you encounter a compiler error here, see the explanation
+ * near the end of INSTALL.
+ */
+ __pngconf.h__ in libpng already includes setjmp.h;
+ __dont__ include it again.;
+# endif
+# endif /* __linux__ */
+# endif /* PNG_SKIP_SETJMP_CHECK */
+
+ /* include setjmp.h for error handling */
+# include <setjmp.h>
+
+# ifdef __linux__
+# ifdef PNG_SAVE_BSD_SOURCE
+# ifndef _BSD_SOURCE
+# define _BSD_SOURCE
+# endif
+# undef PNG_SAVE_BSD_SOURCE
+# endif
+# endif /* __linux__ */
+#endif /* PNG_SETJMP_SUPPORTED */
+
+#ifdef BSD
+# include <strings.h>
+#else
+# include <string.h>
+#endif
+
+/* Other defines for things like memory and the like can go here. */
+#ifdef PNG_INTERNAL
+
+#include <stdlib.h>
+
+/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
+ * aren't usually used outside the library (as far as I know), so it is
+ * debatable if they should be exported at all. In the future, when it is
+ * possible to have run-time registry of chunk-handling functions, some of
+ * these will be made available again.
+#define PNG_EXTERN extern
+ */
+#define PNG_EXTERN
+
+/* Other defines specific to compilers can go here. Try to keep
+ * them inside an appropriate ifdef/endif pair for portability.
+ */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+# ifdef MACOS
+ /* We need to check that <math.h> hasn't already been included earlier
+ * as it seems it doesn't agree with <fp.h>, yet we should really use
+ * <fp.h> if possible.
+ */
+# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
+# include <fp.h>
+# endif
+# else
+# include <math.h>
+# endif
+# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
+ /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+ * MATH=68881
+ */
+# include <m68881.h>
+# endif
+#endif
+
+/* Codewarrior on NT has linking problems without this. */
+#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
+# define PNG_ALWAYS_EXTERN
+#endif
+
+/* This provides the non-ANSI (far) memory allocation routines. */
+#if defined(__TURBOC__) && defined(__MSDOS__)
+# include <mem.h>
+# include <alloc.h>
+#endif
+
+/* I have no idea why is this necessary... */
+#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \
+ defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__))
+# include <malloc.h>
+#endif
+
+/* This controls how fine the dithering gets. As this allocates
+ * a largish chunk of memory (32K), those who are not as concerned
+ * with dithering quality can decrease some or all of these.
+ */
+#ifndef PNG_DITHER_RED_BITS
+# define PNG_DITHER_RED_BITS 5
+#endif
+#ifndef PNG_DITHER_GREEN_BITS
+# define PNG_DITHER_GREEN_BITS 5
+#endif
+#ifndef PNG_DITHER_BLUE_BITS
+# define PNG_DITHER_BLUE_BITS 5
+#endif
+
+/* This controls how fine the gamma correction becomes when you
+ * are only interested in 8 bits anyway. Increasing this value
+ * results in more memory being used, and more pow() functions
+ * being called to fill in the gamma tables. Don't set this value
+ * less then 8, and even that may not work (I haven't tested it).
+ */
+
+#ifndef PNG_MAX_GAMMA_8
+# define PNG_MAX_GAMMA_8 11
+#endif
+
+/* This controls how much a difference in gamma we can tolerate before
+ * we actually start doing gamma conversion.
+ */
+#ifndef PNG_GAMMA_THRESHOLD
+# define PNG_GAMMA_THRESHOLD 0.05
+#endif
+
+#endif /* PNG_INTERNAL */
+
+/* The following uses const char * instead of char * for error
+ * and warning message functions, so some compilers won't complain.
+ * If you do not want to use const, define PNG_NO_CONST here.
+ */
+
+#ifndef PNG_NO_CONST
+# define PNG_CONST const
+#else
+# define PNG_CONST
+#endif
+
+/* The following defines give you the ability to remove code from the
+ * library that you will not be using. I wish I could figure out how to
+ * automate this, but I can't do that without making it seriously hard
+ * on the users. So if you are not using an ability, change the #define
+ * to and #undef, and that part of the library will not be compiled. If
+ * your linker can't find a function, you may want to make sure the
+ * ability is defined here. Some of these depend upon some others being
+ * defined. I haven't figured out all the interactions here, so you may
+ * have to experiment awhile to get everything to compile. If you are
+ * creating or using a shared library, you probably shouldn't touch this,
+ * as it will affect the size of the structures, and this will cause bad
+ * things to happen if the library and/or application ever change.
+ */
+
+/* Any features you will not be using can be undef'ed here */
+
+/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user
+ * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS
+ * on the compile line, then pick and choose which ones to define without
+ * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED
+ * if you only want to have a png-compliant reader/writer but don't need
+ * any of the extra transformations. This saves about 80 kbytes in a
+ * typical installation of the library. (PNG_NO_* form added in version
+ * 1.0.1c, for consistency)
+ */
+
+/* The size of the png_text structure changed in libpng-1.0.6 when
+ * iTXt support was added. iTXt support was turned off by default through
+ * libpng-1.2.x, to support old apps that malloc the png_text structure
+ * instead of calling png_set_text() and letting libpng malloc it. It
+ * will be turned on by default in libpng-1.4.0.
+ */
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+# ifndef PNG_NO_iTXt_SUPPORTED
+# define PNG_NO_iTXt_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_iTXt
+# define PNG_NO_READ_iTXt
+# endif
+# ifndef PNG_NO_WRITE_iTXt
+# define PNG_NO_WRITE_iTXt
+# endif
+#endif
+
+#if !defined(PNG_NO_iTXt_SUPPORTED)
+# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt)
+# define PNG_READ_iTXt
+# endif
+# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt)
+# define PNG_WRITE_iTXt
+# endif
+#endif
+
+/* The following support, added after version 1.0.0, can be turned off here en
+ * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility
+ * with old applications that require the length of png_struct and png_info
+ * to remain unchanged.
+ */
+
+#ifdef PNG_LEGACY_SUPPORTED
+# define PNG_NO_FREE_ME
+# define PNG_NO_READ_UNKNOWN_CHUNKS
+# define PNG_NO_WRITE_UNKNOWN_CHUNKS
+# define PNG_NO_HANDLE_AS_UNKNOWN
+# define PNG_NO_READ_USER_CHUNKS
+# define PNG_NO_READ_iCCP
+# define PNG_NO_WRITE_iCCP
+# define PNG_NO_READ_iTXt
+# define PNG_NO_WRITE_iTXt
+# define PNG_NO_READ_sCAL
+# define PNG_NO_WRITE_sCAL
+# define PNG_NO_READ_sPLT
+# define PNG_NO_WRITE_sPLT
+# define PNG_NO_INFO_IMAGE
+# define PNG_NO_READ_RGB_TO_GRAY
+# define PNG_NO_READ_USER_TRANSFORM
+# define PNG_NO_WRITE_USER_TRANSFORM
+# define PNG_NO_USER_MEM
+# define PNG_NO_READ_EMPTY_PLTE
+# define PNG_NO_MNG_FEATURES
+# define PNG_NO_FIXED_POINT_SUPPORTED
+#endif
+
+/* Ignore attempt to turn off both floating and fixed point support */
+#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \
+ !defined(PNG_NO_FIXED_POINT_SUPPORTED)
+# define PNG_FIXED_POINT_SUPPORTED
+#endif
+
+#ifndef PNG_NO_FREE_ME
+# define PNG_FREE_ME_SUPPORTED
+#endif
+
+#ifdef PNG_READ_SUPPORTED
+
+#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_READ_TRANSFORMS)
+# define PNG_READ_TRANSFORMS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+# ifndef PNG_NO_READ_EXPAND
+# define PNG_READ_EXPAND_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_SHIFT
+# define PNG_READ_SHIFT_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_PACK
+# define PNG_READ_PACK_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_BGR
+# define PNG_READ_BGR_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_SWAP
+# define PNG_READ_SWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_PACKSWAP
+# define PNG_READ_PACKSWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_INVERT
+# define PNG_READ_INVERT_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_DITHER
+# define PNG_READ_DITHER_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_BACKGROUND
+# define PNG_READ_BACKGROUND_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_16_TO_8
+# define PNG_READ_16_TO_8_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_FILLER
+# define PNG_READ_FILLER_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_GAMMA
+# define PNG_READ_GAMMA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_GRAY_TO_RGB
+# define PNG_READ_GRAY_TO_RGB_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_SWAP_ALPHA
+# define PNG_READ_SWAP_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_INVERT_ALPHA
+# define PNG_READ_INVERT_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_STRIP_ALPHA
+# define PNG_READ_STRIP_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_USER_TRANSFORM
+# define PNG_READ_USER_TRANSFORM_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_RGB_TO_GRAY
+# define PNG_READ_RGB_TO_GRAY_SUPPORTED
+# endif
+#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
+
+/* PNG_PROGRESSIVE_READ_NOT_SUPPORTED is deprecated. */
+#if !defined(PNG_NO_PROGRESSIVE_READ) && \
+ !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED) /* if you don't do progressive */
+# define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */
+#endif /* about interlacing capability! You'll */
+ /* still have interlacing unless you change the following define: */
+#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */
+
+/* PNG_NO_SEQUENTIAL_READ_SUPPORTED is deprecated. */
+#if !defined(PNG_NO_SEQUENTIAL_READ) && \
+ !defined(PNG_SEQUENTIAL_READ_SUPPORTED) && \
+ !defined(PNG_NO_SEQUENTIAL_READ_SUPPORTED)
+# define PNG_SEQUENTIAL_READ_SUPPORTED
+#endif
+
+#define PNG_READ_INTERLACING_SUPPORTED /* required in PNG-compliant decoders */
+
+#ifndef PNG_NO_READ_COMPOSITE_NODIV
+# ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */
+# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */
+# endif
+#endif
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Deprecated, will be removed from version 2.0.0.
+ Use PNG_MNG_FEATURES_SUPPORTED instead. */
+#ifndef PNG_NO_READ_EMPTY_PLTE
+# define PNG_READ_EMPTY_PLTE_SUPPORTED
+#endif
+#endif
+
+#endif /* PNG_READ_SUPPORTED */
+
+#ifdef PNG_WRITE_SUPPORTED
+
+# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_WRITE_TRANSFORMS)
+# define PNG_WRITE_TRANSFORMS_SUPPORTED
+#endif
+
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+# ifndef PNG_NO_WRITE_SHIFT
+# define PNG_WRITE_SHIFT_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_PACK
+# define PNG_WRITE_PACK_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_BGR
+# define PNG_WRITE_BGR_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_SWAP
+# define PNG_WRITE_SWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_PACKSWAP
+# define PNG_WRITE_PACKSWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_INVERT
+# define PNG_WRITE_INVERT_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_FILLER
+# define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */
+# endif
+# ifndef PNG_NO_WRITE_SWAP_ALPHA
+# define PNG_WRITE_SWAP_ALPHA_SUPPORTED
+# endif
+#ifndef PNG_1_0_X
+# ifndef PNG_NO_WRITE_INVERT_ALPHA
+# define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+# endif
+#endif
+# ifndef PNG_NO_WRITE_USER_TRANSFORM
+# define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+# endif
+#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
+
+#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \
+ !defined(PNG_WRITE_INTERLACING_SUPPORTED)
+#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant
+ encoders, but can cause trouble
+ if left undefined */
+#endif
+
+#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \
+ !defined(PNG_WRITE_WEIGHTED_FILTER) && \
+ defined(PNG_FLOATING_POINT_SUPPORTED)
+# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#endif
+
+#ifndef PNG_NO_WRITE_FLUSH
+# define PNG_WRITE_FLUSH_SUPPORTED
+#endif
+
+#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
+/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */
+#ifndef PNG_NO_WRITE_EMPTY_PLTE
+# define PNG_WRITE_EMPTY_PLTE_SUPPORTED
+#endif
+#endif
+
+#endif /* PNG_WRITE_SUPPORTED */
+
+#ifndef PNG_1_0_X
+# ifndef PNG_NO_ERROR_NUMBERS
+# define PNG_ERROR_NUMBERS_SUPPORTED
+# endif
+#endif /* PNG_1_0_X */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+# ifndef PNG_NO_USER_TRANSFORM_PTR
+# define PNG_USER_TRANSFORM_PTR_SUPPORTED
+# endif
+#endif
+
+#ifndef PNG_NO_STDIO
+# define PNG_TIME_RFC1123_SUPPORTED
+#endif
+
+/* This adds extra functions in pngget.c for accessing data from the
+ * info pointer (added in version 0.99)
+ * png_get_image_width()
+ * png_get_image_height()
+ * png_get_bit_depth()
+ * png_get_color_type()
+ * png_get_compression_type()
+ * png_get_filter_type()
+ * png_get_interlace_type()
+ * png_get_pixel_aspect_ratio()
+ * png_get_pixels_per_meter()
+ * png_get_x_offset_pixels()
+ * png_get_y_offset_pixels()
+ * png_get_x_offset_microns()
+ * png_get_y_offset_microns()
+ */
+#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED)
+# define PNG_EASY_ACCESS_SUPPORTED
+#endif
+
+/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0
+ * and removed from version 1.2.20. The following will be removed
+ * from libpng-1.4.0
+*/
+
+#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_OPTIMIZED_CODE)
+# ifndef PNG_OPTIMIZED_CODE_SUPPORTED
+# define PNG_OPTIMIZED_CODE_SUPPORTED
+# endif
+#endif
+
+#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE)
+# ifndef PNG_ASSEMBLER_CODE_SUPPORTED
+# define PNG_ASSEMBLER_CODE_SUPPORTED
+# endif
+
+# if defined(__GNUC__) && defined(__x86_64__) && (__GNUC__ < 4)
+ /* work around 64-bit gcc compiler bugs in gcc-3.x */
+# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+# define PNG_NO_MMX_CODE
+# endif
+# endif
+
+# ifdef __APPLE__
+# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+# define PNG_NO_MMX_CODE
+# endif
+# endif
+
+# if (defined(__MWERKS__) && ((__MWERKS__ < 0x0900) || macintosh))
+# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+# define PNG_NO_MMX_CODE
+# endif
+# endif
+
+# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+# define PNG_MMX_CODE_SUPPORTED
+# endif
+
+#endif
+/* end of obsolete code to be removed from libpng-1.4.0 */
+
+/* Added at libpng-1.2.0 */
+#ifndef PNG_1_0_X
+#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED)
+# define PNG_USER_MEM_SUPPORTED
+#endif
+#endif /* PNG_1_0_X */
+
+/* Added at libpng-1.2.6 */
+#ifndef PNG_1_0_X
+# ifndef PNG_SET_USER_LIMITS_SUPPORTED
+# ifndef PNG_NO_SET_USER_LIMITS
+# define PNG_SET_USER_LIMITS_SUPPORTED
+# endif
+# endif
+#endif /* PNG_1_0_X */
+
+/* Added at libpng-1.0.53 and 1.2.43 */
+#ifndef PNG_USER_LIMITS_SUPPORTED
+# ifndef PNG_NO_USER_LIMITS
+# define PNG_USER_LIMITS_SUPPORTED
+# endif
+#endif
+
+/* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGS no matter
+ * how large, set these limits to 0x7fffffffL
+ */
+#ifndef PNG_USER_WIDTH_MAX
+# define PNG_USER_WIDTH_MAX 1000000L
+#endif
+#ifndef PNG_USER_HEIGHT_MAX
+# define PNG_USER_HEIGHT_MAX 1000000L
+#endif
+
+/* Added at libpng-1.2.43. To accept all valid PNGs no matter
+ * how large, set these two limits to 0.
+ */
+#ifndef PNG_USER_CHUNK_CACHE_MAX
+# define PNG_USER_CHUNK_CACHE_MAX 0
+#endif
+
+/* Added at libpng-1.2.43 */
+#ifndef PNG_USER_CHUNK_MALLOC_MAX
+# define PNG_USER_CHUNK_MALLOC_MAX 0
+#endif
+
+#ifndef PNG_LITERAL_SHARP
+# define PNG_LITERAL_SHARP 0x23
+#endif
+#ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
+# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
+#endif
+#ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
+# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
+#endif
+
+/* Added at libpng-1.2.34 */
+#ifndef PNG_STRING_NEWLINE
+#define PNG_STRING_NEWLINE "\n"
+#endif
+
+/* These are currently experimental features, define them if you want */
+
+/* very little testing */
+/*
+#ifdef PNG_READ_SUPPORTED
+# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+# define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+# endif
+#endif
+*/
+
+/* This is only for PowerPC big-endian and 680x0 systems */
+/* some testing */
+/*
+#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
+# define PNG_READ_BIG_ENDIAN_SUPPORTED
+#endif
+*/
+
+/* Buggy compilers (e.g., gcc 2.7.2.2) need this */
+/*
+#define PNG_NO_POINTER_INDEXING
+*/
+
+#if !defined(PNG_NO_POINTER_INDEXING) && \
+ !defined(PNG_POINTER_INDEXING_SUPPORTED)
+# define PNG_POINTER_INDEXING_SUPPORTED
+#endif
+
+/* These functions are turned off by default, as they will be phased out. */
+/*
+#define PNG_USELESS_TESTS_SUPPORTED
+#define PNG_CORRECT_PALETTE_SUPPORTED
+*/
+
+/* Any chunks you are not interested in, you can undef here. The
+ * ones that allocate memory may be expecially important (hIST,
+ * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info
+ * a bit smaller.
+ */
+
+#if defined(PNG_READ_SUPPORTED) && \
+ !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_READ_ANCILLARY_CHUNKS)
+# define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+
+#if defined(PNG_WRITE_SUPPORTED) && \
+ !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS)
+# define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_READ_TEXT
+# define PNG_NO_READ_iTXt
+# define PNG_NO_READ_tEXt
+# define PNG_NO_READ_zTXt
+#endif
+#ifndef PNG_NO_READ_bKGD
+# define PNG_READ_bKGD_SUPPORTED
+# define PNG_bKGD_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_cHRM
+# define PNG_READ_cHRM_SUPPORTED
+# define PNG_cHRM_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_gAMA
+# define PNG_READ_gAMA_SUPPORTED
+# define PNG_gAMA_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_hIST
+# define PNG_READ_hIST_SUPPORTED
+# define PNG_hIST_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iCCP
+# define PNG_READ_iCCP_SUPPORTED
+# define PNG_iCCP_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iTXt
+# ifndef PNG_READ_iTXt_SUPPORTED
+# define PNG_READ_iTXt_SUPPORTED
+# endif
+# ifndef PNG_iTXt_SUPPORTED
+# define PNG_iTXt_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_READ_oFFs
+# define PNG_READ_oFFs_SUPPORTED
+# define PNG_oFFs_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_pCAL
+# define PNG_READ_pCAL_SUPPORTED
+# define PNG_pCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sCAL
+# define PNG_READ_sCAL_SUPPORTED
+# define PNG_sCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_pHYs
+# define PNG_READ_pHYs_SUPPORTED
+# define PNG_pHYs_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sBIT
+# define PNG_READ_sBIT_SUPPORTED
+# define PNG_sBIT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sPLT
+# define PNG_READ_sPLT_SUPPORTED
+# define PNG_sPLT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sRGB
+# define PNG_READ_sRGB_SUPPORTED
+# define PNG_sRGB_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tEXt
+# define PNG_READ_tEXt_SUPPORTED
+# define PNG_tEXt_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tIME
+# define PNG_READ_tIME_SUPPORTED
+# define PNG_tIME_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tRNS
+# define PNG_READ_tRNS_SUPPORTED
+# define PNG_tRNS_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_zTXt
+# define PNG_READ_zTXt_SUPPORTED
+# define PNG_zTXt_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_OPT_PLTE
+# define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */
+#endif /* optional PLTE chunk in RGB and RGBA images */
+#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \
+ defined(PNG_READ_zTXt_SUPPORTED)
+# define PNG_READ_TEXT_SUPPORTED
+# define PNG_TEXT_SUPPORTED
+#endif
+
+#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
+
+#ifndef PNG_NO_READ_UNKNOWN_CHUNKS
+# define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+# define PNG_UNKNOWN_CHUNKS_SUPPORTED
+# endif
+#endif
+#if !defined(PNG_NO_READ_USER_CHUNKS) && \
+ defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+# define PNG_READ_USER_CHUNKS_SUPPORTED
+# define PNG_USER_CHUNKS_SUPPORTED
+# ifdef PNG_NO_READ_UNKNOWN_CHUNKS
+# undef PNG_NO_READ_UNKNOWN_CHUNKS
+# endif
+# ifdef PNG_NO_HANDLE_AS_UNKNOWN
+# undef PNG_NO_HANDLE_AS_UNKNOWN
+# endif
+#endif
+
+#ifndef PNG_NO_HANDLE_AS_UNKNOWN
+# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# endif
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_WRITE_TEXT
+# define PNG_NO_WRITE_iTXt
+# define PNG_NO_WRITE_tEXt
+# define PNG_NO_WRITE_zTXt
+#endif
+#ifndef PNG_NO_WRITE_bKGD
+# define PNG_WRITE_bKGD_SUPPORTED
+# ifndef PNG_bKGD_SUPPORTED
+# define PNG_bKGD_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_cHRM
+# define PNG_WRITE_cHRM_SUPPORTED
+# ifndef PNG_cHRM_SUPPORTED
+# define PNG_cHRM_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_gAMA
+# define PNG_WRITE_gAMA_SUPPORTED
+# ifndef PNG_gAMA_SUPPORTED
+# define PNG_gAMA_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_hIST
+# define PNG_WRITE_hIST_SUPPORTED
+# ifndef PNG_hIST_SUPPORTED
+# define PNG_hIST_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_iCCP
+# define PNG_WRITE_iCCP_SUPPORTED
+# ifndef PNG_iCCP_SUPPORTED
+# define PNG_iCCP_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_iTXt
+# ifndef PNG_WRITE_iTXt_SUPPORTED
+# define PNG_WRITE_iTXt_SUPPORTED
+# endif
+# ifndef PNG_iTXt_SUPPORTED
+# define PNG_iTXt_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_oFFs
+# define PNG_WRITE_oFFs_SUPPORTED
+# ifndef PNG_oFFs_SUPPORTED
+# define PNG_oFFs_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_pCAL
+# define PNG_WRITE_pCAL_SUPPORTED
+# ifndef PNG_pCAL_SUPPORTED
+# define PNG_pCAL_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sCAL
+# define PNG_WRITE_sCAL_SUPPORTED
+# ifndef PNG_sCAL_SUPPORTED
+# define PNG_sCAL_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_pHYs
+# define PNG_WRITE_pHYs_SUPPORTED
+# ifndef PNG_pHYs_SUPPORTED
+# define PNG_pHYs_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sBIT
+# define PNG_WRITE_sBIT_SUPPORTED
+# ifndef PNG_sBIT_SUPPORTED
+# define PNG_sBIT_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sPLT
+# define PNG_WRITE_sPLT_SUPPORTED
+# ifndef PNG_sPLT_SUPPORTED
+# define PNG_sPLT_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sRGB
+# define PNG_WRITE_sRGB_SUPPORTED
+# ifndef PNG_sRGB_SUPPORTED
+# define PNG_sRGB_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_tEXt
+# define PNG_WRITE_tEXt_SUPPORTED
+# ifndef PNG_tEXt_SUPPORTED
+# define PNG_tEXt_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_tIME
+# define PNG_WRITE_tIME_SUPPORTED
+# ifndef PNG_tIME_SUPPORTED
+# define PNG_tIME_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_tRNS
+# define PNG_WRITE_tRNS_SUPPORTED
+# ifndef PNG_tRNS_SUPPORTED
+# define PNG_tRNS_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_zTXt
+# define PNG_WRITE_zTXt_SUPPORTED
+# ifndef PNG_zTXt_SUPPORTED
+# define PNG_zTXt_SUPPORTED
+# endif
+#endif
+#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
+ defined(PNG_WRITE_zTXt_SUPPORTED)
+# define PNG_WRITE_TEXT_SUPPORTED
+# ifndef PNG_TEXT_SUPPORTED
+# define PNG_TEXT_SUPPORTED
+# endif
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+# ifndef PNG_NO_CONVERT_tIME
+# ifndef _WIN32_WCE
+/* The "tm" structure is not supported on WindowsCE */
+# ifndef PNG_CONVERT_tIME_SUPPORTED
+# define PNG_CONVERT_tIME_SUPPORTED
+# endif
+# endif
+# endif
+#endif
+
+#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
+
+#if !defined(PNG_NO_WRITE_FILTER) && !defined(PNG_WRITE_FILTER_SUPPORTED)
+# define PNG_WRITE_FILTER_SUPPORTED
+#endif
+
+#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS
+# define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+# define PNG_UNKNOWN_CHUNKS_SUPPORTED
+# endif
+#endif
+
+#ifndef PNG_NO_HANDLE_AS_UNKNOWN
+# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# endif
+#endif
+#endif /* PNG_WRITE_SUPPORTED */
+
+/* Turn this off to disable png_read_png() and
+ * png_write_png() and leave the row_pointers member
+ * out of the info structure.
+ */
+#ifndef PNG_NO_INFO_IMAGE
+# define PNG_INFO_IMAGE_SUPPORTED
+#endif
+
+/* Need the time information for converting tIME chunks */
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+ /* "time.h" functions are not supported on WindowsCE */
+# include <time.h>
+#endif
+
+/* Some typedefs to get us started. These should be safe on most of the
+ * common platforms. The typedefs should be at least as large as the
+ * numbers suggest (a png_uint_32 must be at least 32 bits long), but they
+ * don't have to be exactly that size. Some compilers dislike passing
+ * unsigned shorts as function parameters, so you may be better off using
+ * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may
+ * want to have unsigned int for png_uint_32 instead of unsigned long.
+ */
+
+typedef unsigned long png_uint_32;
+typedef long png_int_32;
+typedef unsigned short png_uint_16;
+typedef short png_int_16;
+typedef unsigned char png_byte;
+
+/* This is usually size_t. It is typedef'ed just in case you need it to
+ change (I'm not sure if you will or not, so I thought I'd be safe) */
+#ifdef PNG_SIZE_T
+ typedef PNG_SIZE_T png_size_t;
+# define png_sizeof(x) png_convert_size(sizeof(x))
+#else
+ typedef size_t png_size_t;
+# define png_sizeof(x) sizeof(x)
+#endif
+
+/* The following is needed for medium model support. It cannot be in the
+ * PNG_INTERNAL section. Needs modification for other compilers besides
+ * MSC. Model independent support declares all arrays and pointers to be
+ * large using the far keyword. The zlib version used must also support
+ * model independent data. As of version zlib 1.0.4, the necessary changes
+ * have been made in zlib. The USE_FAR_KEYWORD define triggers other
+ * changes that are needed. (Tim Wegner)
+ */
+
+/* Separate compiler dependencies (problem here is that zlib.h always
+ defines FAR. (SJT) */
+#ifdef __BORLANDC__
+# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
+# define LDATA 1
+# else
+# define LDATA 0
+# endif
+ /* GRR: why is Cygwin in here? Cygwin is not Borland C... */
+# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
+# define PNG_MAX_MALLOC_64K
+# if (LDATA != 1)
+# ifndef FAR
+# define FAR __far
+# endif
+# define USE_FAR_KEYWORD
+# endif /* LDATA != 1 */
+ /* Possibly useful for moving data out of default segment.
+ * Uncomment it if you want. Could also define FARDATA as
+ * const if your compiler supports it. (SJT)
+# define FARDATA FAR
+ */
+# endif /* __WIN32__, __FLAT__, __CYGWIN__ */
+#endif /* __BORLANDC__ */
+
+
+/* Suggest testing for specific compiler first before testing for
+ * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM,
+ * making reliance oncertain keywords suspect. (SJT)
+ */
+
+/* MSC Medium model */
+#ifdef FAR
+# ifdef M_I86MM
+# define USE_FAR_KEYWORD
+# define FARDATA FAR
+# include <dos.h>
+# endif
+#endif
+
+/* SJT: default case */
+#ifndef FAR
+# define FAR
+#endif
+
+/* At this point FAR is always defined */
+#ifndef FARDATA
+# define FARDATA
+#endif
+
+/* Typedef for floating-point numbers that are converted
+ to fixed-point with a multiple of 100,000, e.g., int_gamma */
+typedef png_int_32 png_fixed_point;
+
+/* Add typedefs for pointers */
+typedef void FAR * png_voidp;
+typedef png_byte FAR * png_bytep;
+typedef png_uint_32 FAR * png_uint_32p;
+typedef png_int_32 FAR * png_int_32p;
+typedef png_uint_16 FAR * png_uint_16p;
+typedef png_int_16 FAR * png_int_16p;
+typedef PNG_CONST char FAR * png_const_charp;
+typedef char FAR * png_charp;
+typedef png_fixed_point FAR * png_fixed_point_p;
+
+#ifndef PNG_NO_STDIO
+#ifdef _WIN32_WCE
+typedef HANDLE png_FILE_p;
+#else
+typedef FILE * png_FILE_p;
+#endif
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double FAR * png_doublep;
+#endif
+
+/* Pointers to pointers; i.e. arrays */
+typedef png_byte FAR * FAR * png_bytepp;
+typedef png_uint_32 FAR * FAR * png_uint_32pp;
+typedef png_int_32 FAR * FAR * png_int_32pp;
+typedef png_uint_16 FAR * FAR * png_uint_16pp;
+typedef png_int_16 FAR * FAR * png_int_16pp;
+typedef PNG_CONST char FAR * FAR * png_const_charpp;
+typedef char FAR * FAR * png_charpp;
+typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double FAR * FAR * png_doublepp;
+#endif
+
+/* Pointers to pointers to pointers; i.e., pointer to array */
+typedef char FAR * FAR * FAR * png_charppp;
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* SPC - Is this stuff deprecated? */
+/* It'll be removed as of libpng-1.4.0 - GR-P */
+/* libpng typedefs for types in zlib. If zlib changes
+ * or another compression library is used, then change these.
+ * Eliminates need to change all the source files.
+ */
+typedef charf * png_zcharp;
+typedef charf * FAR * png_zcharpp;
+typedef z_stream FAR * png_zstreamp;
+#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */
+
+/*
+ * Define PNG_BUILD_DLL if the module being built is a Windows
+ * LIBPNG DLL.
+ *
+ * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL.
+ * It is equivalent to Microsoft predefined macro _DLL that is
+ * automatically defined when you compile using the share
+ * version of the CRT (C Run-Time library)
+ *
+ * The cygwin mods make this behavior a little different:
+ * Define PNG_BUILD_DLL if you are building a dll for use with cygwin
+ * Define PNG_STATIC if you are building a static library for use with cygwin,
+ * -or- if you are building an application that you want to link to the
+ * static library.
+ * PNG_USE_DLL is defined by default (no user action needed) unless one of
+ * the other flags is defined.
+ */
+
+#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL))
+# define PNG_DLL
+#endif
+/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib.
+ * When building a static lib, default to no GLOBAL ARRAYS, but allow
+ * command-line override
+ */
+#ifdef __CYGWIN__
+# ifndef PNG_STATIC
+# ifdef PNG_USE_GLOBAL_ARRAYS
+# undef PNG_USE_GLOBAL_ARRAYS
+# endif
+# ifndef PNG_USE_LOCAL_ARRAYS
+# define PNG_USE_LOCAL_ARRAYS
+# endif
+# else
+# if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS)
+# ifdef PNG_USE_GLOBAL_ARRAYS
+# undef PNG_USE_GLOBAL_ARRAYS
+# endif
+# endif
+# endif
+# if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+# define PNG_USE_LOCAL_ARRAYS
+# endif
+#endif
+
+/* Do not use global arrays (helps with building DLL's)
+ * They are no longer used in libpng itself, since version 1.0.5c,
+ * but might be required for some pre-1.0.5c applications.
+ */
+#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+# if defined(PNG_NO_GLOBAL_ARRAYS) || \
+ (defined(__GNUC__) && defined(PNG_DLL)) || defined(_MSC_VER)
+# define PNG_USE_LOCAL_ARRAYS
+# else
+# define PNG_USE_GLOBAL_ARRAYS
+# endif
+#endif
+
+#ifdef __CYGWIN__
+# undef PNGAPI
+# define PNGAPI __cdecl
+# undef PNG_IMPEXP
+# define PNG_IMPEXP
+#endif
+
+/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall",
+ * you may get warnings regarding the linkage of png_zalloc and png_zfree.
+ * Don't ignore those warnings; you must also reset the default calling
+ * convention in your compiler to match your PNGAPI, and you must build
+ * zlib and your applications the same way you build libpng.
+ */
+
+#if defined(__MINGW32__) && !defined(PNG_MODULEDEF)
+# ifndef PNG_NO_MODULEDEF
+# define PNG_NO_MODULEDEF
+# endif
+#endif
+
+#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF)
+# define PNG_IMPEXP
+#endif
+
+#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \
+ (( defined(_Windows) || defined(_WINDOWS) || \
+ defined(WIN32) || defined(_WIN32) || defined(__WIN32__) ))
+
+# ifndef PNGAPI
+# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
+# define PNGAPI __cdecl
+# else
+# define PNGAPI _cdecl
+# endif
+# endif
+
+# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \
+ 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */)
+# define PNG_IMPEXP
+# endif
+
+# ifndef PNG_IMPEXP
+
+# define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol
+# define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol
+
+ /* Borland/Microsoft */
+# if defined(_MSC_VER) || defined(__BORLANDC__)
+# if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500)
+# define PNG_EXPORT PNG_EXPORT_TYPE1
+# else
+# define PNG_EXPORT PNG_EXPORT_TYPE2
+# ifdef PNG_BUILD_DLL
+# define PNG_IMPEXP __export
+# else
+# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in
+ VC++ */
+# endif /* Exists in Borland C++ for
+ C++ classes (== huge) */
+# endif
+# endif
+
+# ifndef PNG_IMPEXP
+# ifdef PNG_BUILD_DLL
+# define PNG_IMPEXP __declspec(dllexport)
+# else
+# define PNG_IMPEXP __declspec(dllimport)
+# endif
+# endif
+# endif /* PNG_IMPEXP */
+#else /* !(DLL || non-cygwin WINDOWS) */
+# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
+# ifndef PNGAPI
+# define PNGAPI _System
+# endif
+# else
+# if 0 /* ... other platforms, with other meanings */
+# endif
+# endif
+#endif
+
+#ifndef PNGAPI
+# define PNGAPI
+#endif
+#ifndef PNG_IMPEXP
+# define PNG_IMPEXP
+#endif
+
+#ifdef PNG_BUILDSYMS
+# ifndef PNG_EXPORT
+# define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END
+# endif
+# ifdef PNG_USE_GLOBAL_ARRAYS
+# ifndef PNG_EXPORT_VAR
+# define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT
+# endif
+# endif
+#endif
+
+#ifndef PNG_EXPORT
+# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol
+#endif
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+# ifndef PNG_EXPORT_VAR
+# define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type
+# endif
+#endif
+
+#ifdef PNG_PEDANTIC_WARNINGS
+# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
+# define PNG_PEDANTIC_WARNINGS_SUPPORTED
+# endif
+#endif
+
+#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
+/* Support for compiler specific function attributes. These are used
+ * so that where compiler support is available incorrect use of API
+ * functions in png.h will generate compiler warnings. Added at libpng
+ * version 1.2.41.
+ */
+# ifdef __GNUC__
+# ifndef PNG_USE_RESULT
+# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
+# endif
+# ifndef PNG_NORETURN
+# define PNG_NORETURN __attribute__((__noreturn__))
+# endif
+# ifndef PNG_ALLOCATED
+# define PNG_ALLOCATED __attribute__((__malloc__))
+# endif
+
+ /* This specifically protects structure members that should only be
+ * accessed from within the library, therefore should be empty during
+ * a library build.
+ */
+# ifndef PNG_DEPRECATED
+# define PNG_DEPRECATED __attribute__((__deprecated__))
+# endif
+# ifndef PNG_DEPSTRUCT
+# define PNG_DEPSTRUCT __attribute__((__deprecated__))
+# endif
+# ifndef PNG_PRIVATE
+# if 0 /* Doesn't work so we use deprecated instead*/
+# define PNG_PRIVATE \
+ __attribute__((warning("This function is not exported by libpng.")))
+# else
+# define PNG_PRIVATE \
+ __attribute__((__deprecated__))
+# endif
+# endif /* PNG_PRIVATE */
+# endif /* __GNUC__ */
+#endif /* PNG_PEDANTIC_WARNINGS */
+
+#ifndef PNG_DEPRECATED
+# define PNG_DEPRECATED /* Use of this function is deprecated */
+#endif
+#ifndef PNG_USE_RESULT
+# define PNG_USE_RESULT /* The result of this function must be checked */
+#endif
+#ifndef PNG_NORETURN
+# define PNG_NORETURN /* This function does not return */
+#endif
+#ifndef PNG_ALLOCATED
+# define PNG_ALLOCATED /* The result of the function is new memory */
+#endif
+#ifndef PNG_DEPSTRUCT
+# define PNG_DEPSTRUCT /* Access to this struct member is deprecated */
+#endif
+#ifndef PNG_PRIVATE
+# define PNG_PRIVATE /* This is a private libpng function */
+#endif
+
+/* User may want to use these so they are not in PNG_INTERNAL. Any library
+ * functions that are passed far data must be model independent.
+ */
+
+#ifndef PNG_ABORT
+# define PNG_ABORT() abort()
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#else
+# define png_jmpbuf(png_ptr) \
+ (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED)
+#endif
+
+#ifdef USE_FAR_KEYWORD /* memory model independent fns */
+/* Use this to make far-to-near assignments */
+# define CHECK 1
+# define NOCHECK 0
+# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
+# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
+# define png_snprintf _fsnprintf /* Added to v 1.2.19 */
+# define png_strlen _fstrlen
+# define png_memcmp _fmemcmp /* SJT: added */
+# define png_memcpy _fmemcpy
+# define png_memset _fmemset
+#else /* Use the usual functions */
+# define CVT_PTR(ptr) (ptr)
+# define CVT_PTR_NOCHECK(ptr) (ptr)
+# ifndef PNG_NO_SNPRINTF
+# ifdef _MSC_VER
+# define png_snprintf _snprintf /* Added to v 1.2.19 */
+# define png_snprintf2 _snprintf
+# define png_snprintf6 _snprintf
+# else
+# define png_snprintf snprintf /* Added to v 1.2.19 */
+# define png_snprintf2 snprintf
+# define png_snprintf6 snprintf
+# endif
+# else
+ /* You don't have or don't want to use snprintf(). Caution: Using
+ * sprintf instead of snprintf exposes your application to accidental
+ * or malevolent buffer overflows. If you don't have snprintf()
+ * as a general rule you should provide one (you can get one from
+ * Portable OpenSSH).
+ */
+# define png_snprintf(s1,n,fmt,x1) sprintf(s1,fmt,x1)
+# define png_snprintf2(s1,n,fmt,x1,x2) sprintf(s1,fmt,x1,x2)
+# define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \
+ sprintf(s1,fmt,x1,x2,x3,x4,x5,x6)
+# endif
+# define png_strlen strlen
+# define png_memcmp memcmp /* SJT: added */
+# define png_memcpy memcpy
+# define png_memset memset
+#endif
+/* End of memory model independent support */
+
+/* Just a little check that someone hasn't tried to define something
+ * contradictory.
+ */
+#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
+# undef PNG_ZBUF_SIZE
+# define PNG_ZBUF_SIZE 65536L
+#endif
+
+/* Added at libpng-1.2.8 */
+#endif /* PNG_VERSION_INFO_ONLY */
+
+#endif /* PNGCONF_H */
diff --git a/src/libpng/pngerror.c b/src/libpng/pngerror.c
new file mode 100644
index 0000000..025d52e
--- /dev/null
+++ b/src/libpng/pngerror.c
@@ -0,0 +1,396 @@
+
+/* pngerror.c - stub functions for i/o and memory allocation
+ *
+ * Last changed in libpng 1.2.45 [July 7, 2011]
+ * Copyright (c) 1998-2011 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all error handling. Users who
+ * need special error handling are expected to write replacement functions
+ * and use png_set_error_fn() to use those functions. See the instructions
+ * at each function.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+static void /* PRIVATE */
+png_default_error PNGARG((png_structp png_ptr,
+ png_const_charp error_message)) PNG_NORETURN;
+#ifdef PNG_WARNINGS_SUPPORTED
+static void /* PRIVATE */
+png_default_warning PNGARG((png_structp png_ptr,
+ png_const_charp warning_message));
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+/* This function is called whenever there is a fatal error. This function
+ * should not be changed. If there is a need to handle errors differently,
+ * you should supply a replacement error function and use png_set_error_fn()
+ * to replace the error function at run-time.
+ */
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+void PNGAPI
+png_error(png_structp png_ptr, png_const_charp error_message)
+{
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ char msg[16];
+ if (png_ptr != NULL)
+ {
+ if (png_ptr->flags&
+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+ {
+ if (*error_message == PNG_LITERAL_SHARP)
+ {
+ /* Strip "#nnnn " from beginning of error message. */
+ int offset;
+ for (offset = 1; offset<15; offset++)
+ if (error_message[offset] == ' ')
+ break;
+ if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+ {
+ int i;
+ for (i = 0; i < offset - 1; i++)
+ msg[i] = error_message[i + 1];
+ msg[i - 1] = '\0';
+ error_message = msg;
+ }
+ else
+ error_message += offset;
+ }
+ else
+ {
+ if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+ {
+ msg[0] = '0';
+ msg[1] = '\0';
+ error_message = msg;
+ }
+ }
+ }
+ }
+#endif
+ if (png_ptr != NULL && png_ptr->error_fn != NULL)
+ (*(png_ptr->error_fn))(png_ptr, error_message);
+
+ /* If the custom handler doesn't exist, or if it returns,
+ use the default handler, which will not return. */
+ png_default_error(png_ptr, error_message);
+}
+#else
+void PNGAPI
+png_err(png_structp png_ptr)
+{
+ /* Prior to 1.2.45 the error_fn received a NULL pointer, expressed
+ * erroneously as '\0', instead of the empty string "". This was
+ * apparently an error, introduced in libpng-1.2.20, and png_default_error
+ * will crash in this case.
+ */
+ if (png_ptr != NULL && png_ptr->error_fn != NULL)
+ (*(png_ptr->error_fn))(png_ptr, "");
+
+ /* If the custom handler doesn't exist, or if it returns,
+ use the default handler, which will not return. */
+ png_default_error(png_ptr, "");
+}
+#endif /* PNG_ERROR_TEXT_SUPPORTED */
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* This function is called whenever there is a non-fatal error. This function
+ * should not be changed. If there is a need to handle warnings differently,
+ * you should supply a replacement warning function and use
+ * png_set_error_fn() to replace the warning function at run-time.
+ */
+void PNGAPI
+png_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+ int offset = 0;
+ if (png_ptr != NULL)
+ {
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (png_ptr->flags&
+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+#endif
+ {
+ if (*warning_message == PNG_LITERAL_SHARP)
+ {
+ for (offset = 1; offset < 15; offset++)
+ if (warning_message[offset] == ' ')
+ break;
+ }
+ }
+ }
+ if (png_ptr != NULL && png_ptr->warning_fn != NULL)
+ (*(png_ptr->warning_fn))(png_ptr, warning_message + offset);
+ else
+ png_default_warning(png_ptr, warning_message + offset);
+}
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_benign_error(png_structp png_ptr, png_const_charp error_message)
+{
+ if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
+ png_warning(png_ptr, error_message);
+ else
+ png_error(png_ptr, error_message);
+}
+#endif
+
+/* These utilities are used internally to build an error message that relates
+ * to the current chunk. The chunk name comes from png_ptr->chunk_name,
+ * this is used to prefix the message. The message is limited in length
+ * to 63 bytes, the name characters are output as hex digits wrapped in []
+ * if the character is invalid.
+ */
+#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+static PNG_CONST char png_digit[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+#define PNG_MAX_ERROR_TEXT 64
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
+static void /* PRIVATE */
+png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
+ error_message)
+{
+ int iout = 0, iin = 0;
+
+ while (iin < 4)
+ {
+ int c = png_ptr->chunk_name[iin++];
+ if (isnonalpha(c))
+ {
+ buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
+ buffer[iout++] = png_digit[(c & 0xf0) >> 4];
+ buffer[iout++] = png_digit[c & 0x0f];
+ buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
+ }
+ else
+ {
+ buffer[iout++] = (png_byte)c;
+ }
+ }
+
+ if (error_message == NULL)
+ buffer[iout] = '\0';
+ else
+ {
+ buffer[iout++] = ':';
+ buffer[iout++] = ' ';
+
+ iin = 0;
+ while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
+ buffer[iout++] = error_message[iin++];
+
+ /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */
+ buffer[iout] = '\0';
+ }
+}
+
+#ifdef PNG_READ_SUPPORTED
+void PNGAPI
+png_chunk_error(png_structp png_ptr, png_const_charp error_message)
+{
+ char msg[18+PNG_MAX_ERROR_TEXT];
+ if (png_ptr == NULL)
+ png_error(png_ptr, error_message);
+ else
+ {
+ png_format_buffer(png_ptr, msg, error_message);
+ png_error(png_ptr, msg);
+ }
+}
+#endif /* PNG_READ_SUPPORTED */
+#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
+
+#ifdef PNG_WARNINGS_SUPPORTED
+void PNGAPI
+png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+ char msg[18+PNG_MAX_ERROR_TEXT];
+ if (png_ptr == NULL)
+ png_warning(png_ptr, warning_message);
+ else
+ {
+ png_format_buffer(png_ptr, msg, warning_message);
+ png_warning(png_ptr, msg);
+ }
+}
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+#ifdef PNG_READ_SUPPORTED
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message)
+{
+ if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
+ png_chunk_warning(png_ptr, error_message);
+ else
+ png_chunk_error(png_ptr, error_message);
+}
+#endif
+#endif /* PNG_READ_SUPPORTED */
+
+/* This is the default error handling function. Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash. This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static void /* PRIVATE */
+png_default_error(png_structp png_ptr, png_const_charp error_message)
+{
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (*error_message == PNG_LITERAL_SHARP)
+ {
+ /* Strip "#nnnn " from beginning of error message. */
+ int offset;
+ char error_number[16];
+ for (offset = 0; offset<15; offset++)
+ {
+ error_number[offset] = error_message[offset + 1];
+ if (error_message[offset] == ' ')
+ break;
+ }
+ if ((offset > 1) && (offset < 15))
+ {
+ error_number[offset - 1] = '\0';
+ fprintf(stderr, "libpng error no. %s: %s",
+ error_number, error_message + offset + 1);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+ else
+ {
+ fprintf(stderr, "libpng error: %s, offset=%d",
+ error_message, offset);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+ }
+ else
+#endif
+ {
+ fprintf(stderr, "libpng error: %s", error_message);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ if (png_ptr)
+ {
+# ifdef USE_FAR_KEYWORD
+ {
+ jmp_buf jmpbuf;
+ png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf));
+ longjmp(jmpbuf,1);
+ }
+# else
+ longjmp(png_ptr->jmpbuf, 1);
+# endif
+ }
+#endif
+ /* Here if not setjmp support or if png_ptr is null. */
+ PNG_ABORT();
+#ifndef PNG_CONSOLE_IO_SUPPORTED
+ error_message = error_message; /* Make compiler happy */
+#endif
+}
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway. Replacement functions don't have to do anything
+ * here if you don't want them to. In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void /* PRIVATE */
+png_default_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+# ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (*warning_message == PNG_LITERAL_SHARP)
+ {
+ int offset;
+ char warning_number[16];
+ for (offset = 0; offset < 15; offset++)
+ {
+ warning_number[offset] = warning_message[offset + 1];
+ if (warning_message[offset] == ' ')
+ break;
+ }
+ if ((offset > 1) && (offset < 15))
+ {
+ warning_number[offset + 1] = '\0';
+ fprintf(stderr, "libpng warning no. %s: %s",
+ warning_number, warning_message + offset);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+ else
+ {
+ fprintf(stderr, "libpng warning: %s",
+ warning_message);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+ }
+ else
+# endif
+ {
+ fprintf(stderr, "libpng warning: %s", warning_message);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+#else
+ warning_message = warning_message; /* Make compiler happy */
+#endif
+ png_ptr = png_ptr; /* Make compiler happy */
+}
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+/* This function is called when the application wants to use another method
+ * of handling errors and warnings. Note that the error function MUST NOT
+ * return to the calling routine or serious problems will occur. The return
+ * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
+ */
+void PNGAPI
+png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warning_fn)
+{
+ if (png_ptr == NULL)
+ return;
+ png_ptr->error_ptr = error_ptr;
+ png_ptr->error_fn = error_fn;
+ png_ptr->warning_fn = warning_fn;
+}
+
+
+/* This function returns a pointer to the error_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_error_ptr(png_structp png_ptr)
+{
+ if (png_ptr == NULL)
+ return NULL;
+ return ((png_voidp)png_ptr->error_ptr);
+}
+
+
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+void PNGAPI
+png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
+{
+ if (png_ptr != NULL)
+ {
+ png_ptr->flags &=
+ ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
+ }
+}
+#endif
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/src/libpng/pnggccrd.c b/src/libpng/pnggccrd.c
new file mode 100644
index 0000000..78b8a7e
--- /dev/null
+++ b/src/libpng/pnggccrd.c
@@ -0,0 +1,103 @@
+/* pnggccrd.c was removed from libpng-1.2.20. */
+
+/* This code snippet is for use by configure's compilation test. */
+
+#if (!defined _MSC_VER) && \
+ defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
+ defined(PNG_MMX_CODE_SUPPORTED)
+
+int PNGAPI png_dummy_mmx_support(void);
+
+static int _mmx_supported = 2; // 0: no MMX; 1: MMX supported; 2: not tested
+
+int PNGAPI
+png_dummy_mmx_support(void) __attribute__((noinline));
+
+int PNGAPI
+png_dummy_mmx_support(void)
+{
+ int result;
+#ifdef PNG_MMX_CODE_SUPPORTED // superfluous, but what the heck
+ __asm__ __volatile__ (
+#ifdef __x86_64__
+ "pushq %%rbx \n\t" // rbx gets clobbered by CPUID instruction
+ "pushq %%rcx \n\t" // so does rcx...
+ "pushq %%rdx \n\t" // ...and rdx (but rcx & rdx safe on Linux)
+ "pushfq \n\t" // save Eflag to stack
+ "popq %%rax \n\t" // get Eflag from stack into rax
+ "movq %%rax, %%rcx \n\t" // make another copy of Eflag in rcx
+ "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
+ "pushq %%rax \n\t" // save modified Eflag back to stack
+ "popfq \n\t" // restore modified value to Eflag reg
+ "pushfq \n\t" // save Eflag to stack
+ "popq %%rax \n\t" // get Eflag from stack
+ "pushq %%rcx \n\t" // save original Eflag to stack
+ "popfq \n\t" // restore original Eflag
+#else
+ "pushl %%ebx \n\t" // ebx gets clobbered by CPUID instruction
+ "pushl %%ecx \n\t" // so does ecx...
+ "pushl %%edx \n\t" // ...and edx (but ecx & edx safe on Linux)
+ "pushfl \n\t" // save Eflag to stack
+ "popl %%eax \n\t" // get Eflag from stack into eax
+ "movl %%eax, %%ecx \n\t" // make another copy of Eflag in ecx
+ "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
+ "pushl %%eax \n\t" // save modified Eflag back to stack
+ "popfl \n\t" // restore modified value to Eflag reg
+ "pushfl \n\t" // save Eflag to stack
+ "popl %%eax \n\t" // get Eflag from stack
+ "pushl %%ecx \n\t" // save original Eflag to stack
+ "popfl \n\t" // restore original Eflag
+#endif
+ "xorl %%ecx, %%eax \n\t" // compare new Eflag with original Eflag
+ "jz 0f \n\t" // if same, CPUID instr. is not supported
+
+ "xorl %%eax, %%eax \n\t" // set eax to zero
+// ".byte 0x0f, 0xa2 \n\t" // CPUID instruction (two-byte opcode)
+ "cpuid \n\t" // get the CPU identification info
+ "cmpl $1, %%eax \n\t" // make sure eax return non-zero value
+ "jl 0f \n\t" // if eax is zero, MMX is not supported
+
+ "xorl %%eax, %%eax \n\t" // set eax to zero and...
+ "incl %%eax \n\t" // ...increment eax to 1. This pair is
+ // faster than the instruction "mov eax, 1"
+ "cpuid \n\t" // get the CPU identification info again
+ "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23)
+ "cmpl $0, %%edx \n\t" // 0 = MMX not supported
+ "jz 0f \n\t" // non-zero = yes, MMX IS supported
+
+ "movl $1, %%eax \n\t" // set return value to 1
+ "jmp 1f \n\t" // DONE: have MMX support
+
+ "0: \n\t" // .NOT_SUPPORTED: target label for jump instructions
+ "movl $0, %%eax \n\t" // set return value to 0
+ "1: \n\t" // .RETURN: target label for jump instructions
+#ifdef __x86_64__
+ "popq %%rdx \n\t" // restore rdx
+ "popq %%rcx \n\t" // restore rcx
+ "popq %%rbx \n\t" // restore rbx
+#else
+ "popl %%edx \n\t" // restore edx
+ "popl %%ecx \n\t" // restore ecx
+ "popl %%ebx \n\t" // restore ebx
+#endif
+
+// "ret \n\t" // DONE: no MMX support
+ // (fall through to standard C "ret")
+
+ : "=a" (result) // output list
+
+ : // any variables used on input (none)
+
+ // no clobber list
+// , "%ebx", "%ecx", "%edx" // GRR: we handle these manually
+// , "memory" // if write to a variable gcc thought was in a reg
+// , "cc" // "condition codes" (flag bits)
+ );
+ _mmx_supported = result;
+#else
+ _mmx_supported = 0;
+#endif /* PNG_MMX_CODE_SUPPORTED */
+
+ return _mmx_supported;
+}
+#endif
diff --git a/src/libpng/pngget.c b/src/libpng/pngget.c
new file mode 100644
index 0000000..d397329
--- /dev/null
+++ b/src/libpng/pngget.c
@@ -0,0 +1,944 @@
+
+/* pngget.c - retrieval of values from info struct
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+png_uint_32 PNGAPI
+png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->valid & flag);
+
+ else
+ return(0);
+}
+
+png_uint_32 PNGAPI
+png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->rowbytes);
+
+ else
+ return(0);
+}
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+png_bytepp PNGAPI
+png_get_rows(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->row_pointers);
+
+ else
+ return(0);
+}
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Easy access to info, added in libpng-0.99 */
+png_uint_32 PNGAPI
+png_get_image_width(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->width;
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_image_height(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->height;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->bit_depth;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_color_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->color_type;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->filter_type;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->interlace_type;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->compression_type;
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#ifdef PNG_pHYs_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_x_pixels_per_meter");
+
+ if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+ return (0);
+
+ else
+ return (info_ptr->x_pixels_per_unit);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#ifdef PNG_pHYs_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_y_pixels_per_meter");
+
+ if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+ return (0);
+
+ else
+ return (info_ptr->y_pixels_per_unit);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#ifdef PNG_pHYs_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
+
+ if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
+ info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
+ return (0);
+
+ else
+ return (info_ptr->x_pixels_per_unit);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
+ {
+ if (png_ptr != NULL && info_ptr != NULL)
+#ifdef PNG_pHYs_SUPPORTED
+
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
+
+ if (info_ptr->x_pixels_per_unit == 0)
+ return ((float)0.0);
+
+ else
+ return ((float)((float)info_ptr->y_pixels_per_unit
+ /(float)info_ptr->x_pixels_per_unit));
+ }
+#else
+ return (0.0);
+#endif
+ return ((float)0.0);
+}
+#endif
+
+png_int_32 PNGAPI
+png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#ifdef PNG_oFFs_SUPPORTED
+
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
+
+ if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+ return (0);
+
+ else
+ return (info_ptr->x_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+
+#ifdef PNG_oFFs_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
+
+ if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+ return (0);
+
+ else
+ return (info_ptr->y_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+
+#ifdef PNG_oFFs_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
+
+ if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+ return (0);
+
+ else
+ return (info_ptr->x_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+
+#ifdef PNG_oFFs_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
+
+ if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+ return (0);
+
+ else
+ return (info_ptr->y_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
+ *.0254 +.5));
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
+ *.0254 +.5));
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
+ *.0254 +.5));
+}
+
+float PNGAPI
+png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
+ *.00003937);
+}
+
+float PNGAPI
+png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
+ *.00003937);
+}
+
+#ifdef PNG_pHYs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+ png_uint_32 retval = 0;
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_debug1(1, "in %s retrieval function", "pHYs");
+
+ if (res_x != NULL)
+ {
+ *res_x = info_ptr->x_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+ if (res_y != NULL)
+ {
+ *res_y = info_ptr->y_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+ if (unit_type != NULL)
+ {
+ *unit_type = (int)info_ptr->phys_unit_type;
+ retval |= PNG_INFO_pHYs;
+ if (*unit_type == 1)
+ {
+ if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
+ if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
+ }
+ }
+ }
+ return (retval);
+}
+#endif /* PNG_pHYs_SUPPORTED */
+#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
+
+/* png_get_channels really belongs in here, too, but it's been around longer */
+
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
+
+png_byte PNGAPI
+png_get_channels(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->channels);
+ else
+ return (0);
+}
+
+png_bytep PNGAPI
+png_get_signature(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->signature);
+ else
+ return (NULL);
+}
+
+#ifdef PNG_bKGD_SUPPORTED
+png_uint_32 PNGAPI
+png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
+ png_color_16p *background)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
+ && background != NULL)
+ {
+ png_debug1(1, "in %s retrieval function", "bKGD");
+
+ *background = &(info_ptr->background);
+ return (PNG_INFO_bKGD);
+ }
+ return (0);
+}
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
+ double *white_x, double *white_y, double *red_x, double *red_y,
+ double *green_x, double *green_y, double *blue_x, double *blue_y)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+ {
+ png_debug1(1, "in %s retrieval function", "cHRM");
+
+ if (white_x != NULL)
+ *white_x = (double)info_ptr->x_white;
+ if (white_y != NULL)
+ *white_y = (double)info_ptr->y_white;
+ if (red_x != NULL)
+ *red_x = (double)info_ptr->x_red;
+ if (red_y != NULL)
+ *red_y = (double)info_ptr->y_red;
+ if (green_x != NULL)
+ *green_x = (double)info_ptr->x_green;
+ if (green_y != NULL)
+ *green_y = (double)info_ptr->y_green;
+ if (blue_x != NULL)
+ *blue_x = (double)info_ptr->x_blue;
+ if (blue_y != NULL)
+ *blue_y = (double)info_ptr->y_blue;
+ return (PNG_INFO_cHRM);
+ }
+ return (0);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+ png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
+ png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
+ png_fixed_point *blue_x, png_fixed_point *blue_y)
+{
+ png_debug1(1, "in %s retrieval function", "cHRM");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+ {
+ if (white_x != NULL)
+ *white_x = info_ptr->int_x_white;
+ if (white_y != NULL)
+ *white_y = info_ptr->int_y_white;
+ if (red_x != NULL)
+ *red_x = info_ptr->int_x_red;
+ if (red_y != NULL)
+ *red_y = info_ptr->int_y_red;
+ if (green_x != NULL)
+ *green_x = info_ptr->int_x_green;
+ if (green_y != NULL)
+ *green_y = info_ptr->int_y_green;
+ if (blue_x != NULL)
+ *blue_x = info_ptr->int_x_blue;
+ if (blue_y != NULL)
+ *blue_y = info_ptr->int_y_blue;
+ return (PNG_INFO_cHRM);
+ }
+ return (0);
+}
+#endif
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
+{
+ png_debug1(1, "in %s retrieval function", "gAMA");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+ && file_gamma != NULL)
+ {
+ *file_gamma = (double)info_ptr->gamma;
+ return (PNG_INFO_gAMA);
+ }
+ return (0);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
+ png_fixed_point *int_file_gamma)
+{
+ png_debug1(1, "in %s retrieval function", "gAMA");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+ && int_file_gamma != NULL)
+ {
+ *int_file_gamma = info_ptr->int_gamma;
+ return (PNG_INFO_gAMA);
+ }
+ return (0);
+}
+#endif
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
+{
+ png_debug1(1, "in %s retrieval function", "sRGB");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
+ && file_srgb_intent != NULL)
+ {
+ *file_srgb_intent = (int)info_ptr->srgb_intent;
+ return (PNG_INFO_sRGB);
+ }
+ return (0);
+}
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+png_uint_32 PNGAPI
+png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
+ png_charpp name, int *compression_type,
+ png_charpp profile, png_uint_32 *proflen)
+{
+ png_debug1(1, "in %s retrieval function", "iCCP");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
+ && name != NULL && profile != NULL && proflen != NULL)
+ {
+ *name = info_ptr->iccp_name;
+ *profile = info_ptr->iccp_profile;
+ /* Compression_type is a dummy so the API won't have to change
+ * if we introduce multiple compression types later.
+ */
+ *proflen = (int)info_ptr->iccp_proflen;
+ *compression_type = (int)info_ptr->iccp_compression;
+ return (PNG_INFO_iCCP);
+ }
+ return (0);
+}
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
+ png_sPLT_tpp spalettes)
+{
+ if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
+ {
+ *spalettes = info_ptr->splt_palettes;
+ return ((png_uint_32)info_ptr->splt_palettes_num);
+ }
+ return (0);
+}
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+png_uint_32 PNGAPI
+png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
+{
+ png_debug1(1, "in %s retrieval function", "hIST");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
+ && hist != NULL)
+ {
+ *hist = info_ptr->hist;
+ return (PNG_INFO_hIST);
+ }
+ return (0);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 *width, png_uint_32 *height, int *bit_depth,
+ int *color_type, int *interlace_type, int *compression_type,
+ int *filter_type)
+
+{
+ png_debug1(1, "in %s retrieval function", "IHDR");
+
+ if (png_ptr == NULL || info_ptr == NULL || width == NULL ||
+ height == NULL || bit_depth == NULL || color_type == NULL)
+ return (0);
+
+ *width = info_ptr->width;
+ *height = info_ptr->height;
+ *bit_depth = info_ptr->bit_depth;
+ *color_type = info_ptr->color_type;
+
+ if (compression_type != NULL)
+ *compression_type = info_ptr->compression_type;
+
+ if (filter_type != NULL)
+ *filter_type = info_ptr->filter_type;
+
+ if (interlace_type != NULL)
+ *interlace_type = info_ptr->interlace_type;
+
+ /* This is redundant if we can be sure that the info_ptr values were all
+ * assigned in png_set_IHDR(). We do the check anyhow in case an
+ * application has ignored our advice not to mess with the members
+ * of info_ptr directly.
+ */
+ png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
+ info_ptr->compression_type, info_ptr->filter_type);
+
+ return (1);
+}
+
+#ifdef PNG_oFFs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
+ png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
+{
+ png_debug1(1, "in %s retrieval function", "oFFs");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
+ && offset_x != NULL && offset_y != NULL && unit_type != NULL)
+ {
+ *offset_x = info_ptr->x_offset;
+ *offset_y = info_ptr->y_offset;
+ *unit_type = (int)info_ptr->offset_unit_type;
+ return (PNG_INFO_oFFs);
+ }
+ return (0);
+}
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
+ png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
+ png_charp *units, png_charpp *params)
+{
+ png_debug1(1, "in %s retrieval function", "pCAL");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
+ && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
+ nparams != NULL && units != NULL && params != NULL)
+ {
+ *purpose = info_ptr->pcal_purpose;
+ *X0 = info_ptr->pcal_X0;
+ *X1 = info_ptr->pcal_X1;
+ *type = (int)info_ptr->pcal_type;
+ *nparams = (int)info_ptr->pcal_nparams;
+ *units = info_ptr->pcal_units;
+ *params = info_ptr->pcal_params;
+ return (PNG_INFO_pCAL);
+ }
+ return (0);
+}
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
+ int *unit, double *width, double *height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ *unit = info_ptr->scal_unit;
+ *width = info_ptr->scal_pixel_width;
+ *height = info_ptr->scal_pixel_height;
+ return (PNG_INFO_sCAL);
+ }
+ return(0);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+ int *unit, png_charpp width, png_charpp height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ *unit = info_ptr->scal_unit;
+ *width = info_ptr->scal_s_width;
+ *height = info_ptr->scal_s_height;
+ return (PNG_INFO_sCAL);
+ }
+ return(0);
+}
+#endif
+#endif
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+ png_uint_32 retval = 0;
+
+ png_debug1(1, "in %s retrieval function", "pHYs");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ if (res_x != NULL)
+ {
+ *res_x = info_ptr->x_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+
+ if (res_y != NULL)
+ {
+ *res_y = info_ptr->y_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+
+ if (unit_type != NULL)
+ {
+ *unit_type = (int)info_ptr->phys_unit_type;
+ retval |= PNG_INFO_pHYs;
+ }
+ }
+ return (retval);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
+ int *num_palette)
+{
+ png_debug1(1, "in %s retrieval function", "PLTE");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
+ && palette != NULL)
+ {
+ *palette = info_ptr->palette;
+ *num_palette = info_ptr->num_palette;
+ png_debug1(3, "num_palette = %d", *num_palette);
+ return (PNG_INFO_PLTE);
+ }
+ return (0);
+}
+
+#ifdef PNG_sBIT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
+{
+ png_debug1(1, "in %s retrieval function", "sBIT");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
+ && sig_bit != NULL)
+ {
+ *sig_bit = &(info_ptr->sig_bit);
+ return (PNG_INFO_sBIT);
+ }
+ return (0);
+}
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
+ int *num_text)
+{
+ if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
+ {
+ png_debug1(1, "in %s retrieval function",
+ (png_ptr->chunk_name[0] == '\0' ? "text"
+ : (png_const_charp)png_ptr->chunk_name));
+
+ if (text_ptr != NULL)
+ *text_ptr = info_ptr->text;
+
+ if (num_text != NULL)
+ *num_text = info_ptr->num_text;
+
+ return ((png_uint_32)info_ptr->num_text);
+ }
+ if (num_text != NULL)
+ *num_text = 0;
+ return(0);
+}
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+png_uint_32 PNGAPI
+png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
+{
+ png_debug1(1, "in %s retrieval function", "tIME");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
+ && mod_time != NULL)
+ {
+ *mod_time = &(info_ptr->mod_time);
+ return (PNG_INFO_tIME);
+ }
+ return (0);
+}
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+png_uint_32 PNGAPI
+png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
+ png_bytep *trans, int *num_trans, png_color_16p *trans_values)
+{
+ png_uint_32 retval = 0;
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ png_debug1(1, "in %s retrieval function", "tRNS");
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (trans != NULL)
+ {
+ *trans = info_ptr->trans;
+ retval |= PNG_INFO_tRNS;
+ }
+
+ if (trans_values != NULL)
+ *trans_values = &(info_ptr->trans_values);
+ }
+ else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
+ {
+ if (trans_values != NULL)
+ {
+ *trans_values = &(info_ptr->trans_values);
+ retval |= PNG_INFO_tRNS;
+ }
+
+ if (trans != NULL)
+ *trans = NULL;
+ }
+ if (num_trans != NULL)
+ {
+ *num_trans = info_ptr->num_trans;
+ retval |= PNG_INFO_tRNS;
+ }
+ }
+ return (retval);
+}
+#endif
+
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+png_uint_32 PNGAPI
+png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
+ png_unknown_chunkpp unknowns)
+{
+ if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
+ {
+ *unknowns = info_ptr->unknown_chunks;
+ return ((png_uint_32)info_ptr->unknown_chunks_num);
+ }
+ return (0);
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+png_byte PNGAPI
+png_get_rgb_to_gray_status (png_structp png_ptr)
+{
+ return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
+}
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+png_voidp PNGAPI
+png_get_user_chunk_ptr(png_structp png_ptr)
+{
+ return (png_ptr? png_ptr->user_chunk_ptr : NULL);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_compression_buffer_size(png_structp png_ptr)
+{
+ return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L);
+}
+
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+#ifndef PNG_1_0_X
+/* This function was added to libpng 1.2.0 and should exist by default */
+png_uint_32 PNGAPI
+png_get_asm_flags (png_structp png_ptr)
+{
+ /* Obsolete, to be removed from libpng-1.4.0 */
+ return (png_ptr? 0L: 0L);
+}
+
+/* This function was added to libpng 1.2.0 and should exist by default */
+png_uint_32 PNGAPI
+png_get_asm_flagmask (int flag_select)
+{
+ /* Obsolete, to be removed from libpng-1.4.0 */
+ flag_select=flag_select;
+ return 0L;
+}
+
+ /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */
+/* This function was added to libpng 1.2.0 */
+png_uint_32 PNGAPI
+png_get_mmx_flagmask (int flag_select, int *compilerID)
+{
+ /* Obsolete, to be removed from libpng-1.4.0 */
+ flag_select=flag_select;
+ *compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */
+ return 0L;
+}
+
+/* This function was added to libpng 1.2.0 */
+png_byte PNGAPI
+png_get_mmx_bitdepth_threshold (png_structp png_ptr)
+{
+ /* Obsolete, to be removed from libpng-1.4.0 */
+ return (png_ptr? 0: 0);
+}
+
+/* This function was added to libpng 1.2.0 */
+png_uint_32 PNGAPI
+png_get_mmx_rowbytes_threshold (png_structp png_ptr)
+{
+ /* Obsolete, to be removed from libpng-1.4.0 */
+ return (png_ptr? 0L: 0L);
+}
+#endif /* ?PNG_1_0_X */
+#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* These functions were added to libpng 1.2.6 but not enabled
+* by default. They will be enabled in libpng-1.4.0 */
+png_uint_32 PNGAPI
+png_get_user_width_max (png_structp png_ptr)
+{
+ return (png_ptr? png_ptr->user_width_max : 0);
+}
+png_uint_32 PNGAPI
+png_get_user_height_max (png_structp png_ptr)
+{
+ return (png_ptr? png_ptr->user_height_max : 0);
+}
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
+
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/src/libpng/pngmem.c b/src/libpng/pngmem.c
new file mode 100644
index 0000000..a18719b
--- /dev/null
+++ b/src/libpng/pngmem.c
@@ -0,0 +1,641 @@
+
+/* pngmem.c - stub functions for memory allocation
+ *
+ * Last changed in libpng 1.2.41 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all memory allocation. Users who
+ * need special memory handling are expected to supply replacement
+ * functions for png_malloc() and png_free(), and to use
+ * png_create_read_struct_2() and png_create_write_struct_2() to
+ * identify the replacement functions.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+/* Borland DOS special memory handler */
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* If you change this, be sure to change the one in png.h also */
+
+/* Allocate memory for a png_struct. The malloc and memset can be replaced
+ by a single call to calloc() if this is thought to improve performance. */
+png_voidp /* PRIVATE */
+png_create_struct(int type)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
+}
+
+/* Alternate version of png_create_struct, for use with user-defined malloc. */
+png_voidp /* PRIVATE */
+png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+ png_size_t size;
+ png_voidp struct_ptr;
+
+ if (type == PNG_STRUCT_INFO)
+ size = png_sizeof(png_info);
+ else if (type == PNG_STRUCT_PNG)
+ size = png_sizeof(png_struct);
+ else
+ return (png_get_copyright(NULL));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (malloc_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
+ }
+ else
+#endif /* PNG_USER_MEM_SUPPORTED */
+ struct_ptr = (png_voidp)farmalloc(size);
+ if (struct_ptr != NULL)
+ png_memset(struct_ptr, 0, size);
+ return (struct_ptr);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct(png_voidp struct_ptr)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
+ png_voidp mem_ptr)
+{
+#endif
+ if (struct_ptr != NULL)
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (free_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ (*(free_fn))(png_ptr, struct_ptr);
+ return;
+ }
+#endif /* PNG_USER_MEM_SUPPORTED */
+ farfree (struct_ptr);
+ }
+}
+
+/* Allocate memory. For reasonable files, size should never exceed
+ * 64K. However, zlib may allocate more then 64K if you don't tell
+ * it not to. See zconf.h and png.h for more information. zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ *
+ * Borland seems to have a problem in DOS mode for exactly 64K.
+ * It gives you a segment with an offset of 8 (perhaps to store its
+ * memory stuff). zlib doesn't like this at all, so we have to
+ * detect and deal with it. This code should not be needed in
+ * Windows or OS/2 modes, and only in 16 bit mode. This code has
+ * been updated by Alexander Lehmann for version 0.89 to waste less
+ * memory.
+ *
+ * Note that we can't use png_size_t for the "size" declaration,
+ * since on some systems a png_size_t is a 16-bit quantity, and as a
+ * result, we would be truncating potentially larger memory requests
+ * (which should cause a fatal error) and introducing major problems.
+ */
+png_voidp /* PRIVATE */
+png_calloc(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+
+ ret = (png_malloc(png_ptr, size));
+ if (ret != NULL)
+ png_memset(ret,0,(png_size_t)size);
+ return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+
+ if (png_ptr == NULL || size == 0)
+ return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr->malloc_fn != NULL)
+ ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
+ else
+ ret = (png_malloc_default(png_ptr, size));
+ if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of memory!");
+ return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc_default(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+ if (png_ptr == NULL || size == 0)
+ return (NULL);
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (size > (png_uint_32)65536L)
+ {
+ png_warning(png_ptr, "Cannot Allocate > 64K");
+ ret = NULL;
+ }
+ else
+#endif
+
+ if (size != (size_t)size)
+ ret = NULL;
+ else if (size == (png_uint_32)65536L)
+ {
+ if (png_ptr->offset_table == NULL)
+ {
+ /* Try to see if we need to do any of this fancy stuff */
+ ret = farmalloc(size);
+ if (ret == NULL || ((png_size_t)ret & 0xffff))
+ {
+ int num_blocks;
+ png_uint_32 total_size;
+ png_bytep table;
+ int i;
+ png_byte huge * hptr;
+
+ if (ret != NULL)
+ {
+ farfree(ret);
+ ret = NULL;
+ }
+
+ if (png_ptr->zlib_window_bits > 14)
+ num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
+ else
+ num_blocks = 1;
+ if (png_ptr->zlib_mem_level >= 7)
+ num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
+ else
+ num_blocks++;
+
+ total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
+
+ table = farmalloc(total_size);
+
+ if (table == NULL)
+ {
+#ifndef PNG_USER_MEM_SUPPORTED
+ if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out Of Memory."); /* Note "O", "M" */
+ else
+ png_warning(png_ptr, "Out Of Memory.");
+#endif
+ return (NULL);
+ }
+
+ if ((png_size_t)table & 0xfff0)
+ {
+#ifndef PNG_USER_MEM_SUPPORTED
+ if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr,
+ "Farmalloc didn't return normalized pointer");
+ else
+ png_warning(png_ptr,
+ "Farmalloc didn't return normalized pointer");
+#endif
+ return (NULL);
+ }
+
+ png_ptr->offset_table = table;
+ png_ptr->offset_table_ptr = farmalloc(num_blocks *
+ png_sizeof(png_bytep));
+
+ if (png_ptr->offset_table_ptr == NULL)
+ {
+#ifndef PNG_USER_MEM_SUPPORTED
+ if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out Of memory."); /* Note "O", "m" */
+ else
+ png_warning(png_ptr, "Out Of memory.");
+#endif
+ return (NULL);
+ }
+
+ hptr = (png_byte huge *)table;
+ if ((png_size_t)hptr & 0xf)
+ {
+ hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
+ hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
+ }
+ for (i = 0; i < num_blocks; i++)
+ {
+ png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
+ hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
+ }
+
+ png_ptr->offset_table_number = num_blocks;
+ png_ptr->offset_table_count = 0;
+ png_ptr->offset_table_count_free = 0;
+ }
+ }
+
+ if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
+ {
+#ifndef PNG_USER_MEM_SUPPORTED
+ if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
+ else
+ png_warning(png_ptr, "Out of Memory.");
+#endif
+ return (NULL);
+ }
+
+ ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
+ }
+ else
+ ret = farmalloc(size);
+
+#ifndef PNG_USER_MEM_SUPPORTED
+ if (ret == NULL)
+ {
+ if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
+ else
+ png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
+ }
+#endif
+
+ return (ret);
+}
+
+/* Free a pointer allocated by png_malloc(). In the default
+ * configuration, png_ptr is not used, but is passed in case it
+ * is needed. If ptr is NULL, return without taking any action.
+ */
+void PNGAPI
+png_free(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr->free_fn != NULL)
+ {
+ (*(png_ptr->free_fn))(png_ptr, ptr);
+ return;
+ }
+ else
+ png_free_default(png_ptr, ptr);
+}
+
+void PNGAPI
+png_free_default(png_structp png_ptr, png_voidp ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+ if (png_ptr->offset_table != NULL)
+ {
+ int i;
+
+ for (i = 0; i < png_ptr->offset_table_count; i++)
+ {
+ if (ptr == png_ptr->offset_table_ptr[i])
+ {
+ ptr = NULL;
+ png_ptr->offset_table_count_free++;
+ break;
+ }
+ }
+ if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
+ {
+ farfree(png_ptr->offset_table);
+ farfree(png_ptr->offset_table_ptr);
+ png_ptr->offset_table = NULL;
+ png_ptr->offset_table_ptr = NULL;
+ }
+ }
+
+ if (ptr != NULL)
+ {
+ farfree(ptr);
+ }
+}
+
+#else /* Not the Borland DOS special memory handler */
+
+/* Allocate memory for a png_struct or a png_info. The malloc and
+ memset can be replaced by a single call to calloc() if this is thought
+ to improve performance noticably. */
+png_voidp /* PRIVATE */
+png_create_struct(int type)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
+}
+
+/* Allocate memory for a png_struct or a png_info. The malloc and
+ memset can be replaced by a single call to calloc() if this is thought
+ to improve performance noticably. */
+png_voidp /* PRIVATE */
+png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+ png_size_t size;
+ png_voidp struct_ptr;
+
+ if (type == PNG_STRUCT_INFO)
+ size = png_sizeof(png_info);
+ else if (type == PNG_STRUCT_PNG)
+ size = png_sizeof(png_struct);
+ else
+ return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (malloc_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ struct_ptr = (*(malloc_fn))(png_ptr, size);
+ if (struct_ptr != NULL)
+ png_memset(struct_ptr, 0, size);
+ return (struct_ptr);
+ }
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ struct_ptr = (png_voidp)farmalloc(size);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ struct_ptr = (png_voidp)halloc(size, 1);
+# else
+ struct_ptr = (png_voidp)malloc(size);
+# endif
+#endif
+ if (struct_ptr != NULL)
+ png_memset(struct_ptr, 0, size);
+
+ return (struct_ptr);
+}
+
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct(png_voidp struct_ptr)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
+ png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+ if (struct_ptr != NULL)
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (free_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ (*(free_fn))(png_ptr, struct_ptr);
+ return;
+ }
+#endif /* PNG_USER_MEM_SUPPORTED */
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ farfree(struct_ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ hfree(struct_ptr);
+# else
+ free(struct_ptr);
+# endif
+#endif
+ }
+}
+
+/* Allocate memory. For reasonable files, size should never exceed
+ * 64K. However, zlib may allocate more then 64K if you don't tell
+ * it not to. See zconf.h and png.h for more information. zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ */
+
+png_voidp /* PRIVATE */
+png_calloc(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+
+ ret = (png_malloc(png_ptr, size));
+ if (ret != NULL)
+ png_memset(ret,0,(png_size_t)size);
+ return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr == NULL || size == 0)
+ return (NULL);
+
+ if (png_ptr->malloc_fn != NULL)
+ ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
+ else
+ ret = (png_malloc_default(png_ptr, size));
+ if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of Memory!");
+ return (ret);
+}
+
+png_voidp PNGAPI
+png_malloc_default(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+ if (png_ptr == NULL || size == 0)
+ return (NULL);
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (size > (png_uint_32)65536L)
+ {
+#ifndef PNG_USER_MEM_SUPPORTED
+ if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Cannot Allocate > 64K");
+ else
+#endif
+ return NULL;
+ }
+#endif
+
+ /* Check for overflow */
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ if (size != (unsigned long)size)
+ ret = NULL;
+ else
+ ret = farmalloc(size);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ if (size != (unsigned long)size)
+ ret = NULL;
+ else
+ ret = halloc(size, 1);
+# else
+ if (size != (size_t)size)
+ ret = NULL;
+ else
+ ret = malloc((size_t)size);
+# endif
+#endif
+
+#ifndef PNG_USER_MEM_SUPPORTED
+ if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of Memory");
+#endif
+
+ return (ret);
+}
+
+/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
+ * without taking any action.
+ */
+void PNGAPI
+png_free(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr->free_fn != NULL)
+ {
+ (*(png_ptr->free_fn))(png_ptr, ptr);
+ return;
+ }
+ else
+ png_free_default(png_ptr, ptr);
+}
+void PNGAPI
+png_free_default(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ farfree(ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ hfree(ptr);
+# else
+ free(ptr);
+# endif
+#endif
+}
+
+#endif /* Not Borland DOS special memory handler */
+
+#ifdef PNG_1_0_X
+# define png_malloc_warn png_malloc
+#else
+/* This function was added at libpng version 1.2.3. The png_malloc_warn()
+ * function will set up png_malloc() to issue a png_warning and return NULL
+ * instead of issuing a png_error, if it fails to allocate the requested
+ * memory.
+ */
+png_voidp PNGAPI
+png_malloc_warn(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ptr;
+ png_uint_32 save_flags;
+ if (png_ptr == NULL)
+ return (NULL);
+
+ save_flags = png_ptr->flags;
+ png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
+ ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
+ png_ptr->flags=save_flags;
+ return(ptr);
+}
+#endif
+
+png_voidp PNGAPI
+png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
+ png_uint_32 length)
+{
+ png_size_t size;
+
+ size = (png_size_t)length;
+ if ((png_uint_32)size != length)
+ png_error(png_ptr, "Overflow in png_memcpy_check.");
+
+ return(png_memcpy (s1, s2, size));
+}
+
+png_voidp PNGAPI
+png_memset_check (png_structp png_ptr, png_voidp s1, int value,
+ png_uint_32 length)
+{
+ png_size_t size;
+
+ size = (png_size_t)length;
+ if ((png_uint_32)size != length)
+ png_error(png_ptr, "Overflow in png_memset_check.");
+
+ return (png_memset (s1, value, size));
+
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* This function is called when the application wants to use another method
+ * of allocating and freeing memory.
+ */
+void PNGAPI
+png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+ malloc_fn, png_free_ptr free_fn)
+{
+ if (png_ptr != NULL)
+ {
+ png_ptr->mem_ptr = mem_ptr;
+ png_ptr->malloc_fn = malloc_fn;
+ png_ptr->free_fn = free_fn;
+ }
+}
+
+/* This function returns a pointer to the mem_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_mem_ptr(png_structp png_ptr)
+{
+ if (png_ptr == NULL)
+ return (NULL);
+ return ((png_voidp)png_ptr->mem_ptr);
+}
+#endif /* PNG_USER_MEM_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/src/libpng/pngpread.c b/src/libpng/pngpread.c
new file mode 100644
index 0000000..d066944
--- /dev/null
+++ b/src/libpng/pngpread.c
@@ -0,0 +1,1774 @@
+
+/* pngpread.c - read a png file in push mode
+ *
+ * Last changed in libpng 1.2.44 [June 26, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+
+/* Push model modes */
+#define PNG_READ_SIG_MODE 0
+#define PNG_READ_CHUNK_MODE 1
+#define PNG_READ_IDAT_MODE 2
+#define PNG_SKIP_MODE 3
+#define PNG_READ_tEXt_MODE 4
+#define PNG_READ_zTXt_MODE 5
+#define PNG_READ_DONE_MODE 6
+#define PNG_READ_iTXt_MODE 7
+#define PNG_ERROR_MODE 8
+
+void PNGAPI
+png_process_data(png_structp png_ptr, png_infop info_ptr,
+ png_bytep buffer, png_size_t buffer_size)
+{
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_push_restore_buffer(png_ptr, buffer, buffer_size);
+
+ while (png_ptr->buffer_size)
+ {
+ png_process_some_data(png_ptr, info_ptr);
+ }
+}
+
+/* What we do with the incoming data depends on what we were previously
+ * doing before we ran out of data...
+ */
+void /* PRIVATE */
+png_process_some_data(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr == NULL)
+ return;
+
+ switch (png_ptr->process_mode)
+ {
+ case PNG_READ_SIG_MODE:
+ {
+ png_push_read_sig(png_ptr, info_ptr);
+ break;
+ }
+
+ case PNG_READ_CHUNK_MODE:
+ {
+ png_push_read_chunk(png_ptr, info_ptr);
+ break;
+ }
+
+ case PNG_READ_IDAT_MODE:
+ {
+ png_push_read_IDAT(png_ptr);
+ break;
+ }
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+ case PNG_READ_tEXt_MODE:
+ {
+ png_push_read_tEXt(png_ptr, info_ptr);
+ break;
+ }
+
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+ case PNG_READ_zTXt_MODE:
+ {
+ png_push_read_zTXt(png_ptr, info_ptr);
+ break;
+ }
+
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+ case PNG_READ_iTXt_MODE:
+ {
+ png_push_read_iTXt(png_ptr, info_ptr);
+ break;
+ }
+
+#endif
+ case PNG_SKIP_MODE:
+ {
+ png_push_crc_finish(png_ptr);
+ break;
+ }
+
+ default:
+ {
+ png_ptr->buffer_size = 0;
+ break;
+ }
+ }
+}
+
+/* Read any remaining signature bytes from the stream and compare them with
+ * the correct PNG signature. It is possible that this routine is called
+ * with bytes already read from the signature, either because they have been
+ * checked by the calling application, or because of multiple calls to this
+ * routine.
+ */
+void /* PRIVATE */
+png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
+{
+ png_size_t num_checked = png_ptr->sig_bytes,
+ num_to_check = 8 - num_checked;
+
+ if (png_ptr->buffer_size < num_to_check)
+ {
+ num_to_check = png_ptr->buffer_size;
+ }
+
+ png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
+ num_to_check);
+ png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
+
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+ {
+ if (num_checked < 4 &&
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_error(png_ptr, "Not a PNG file");
+ else
+ png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+ }
+ else
+ {
+ if (png_ptr->sig_bytes >= 8)
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+ }
+}
+
+void /* PRIVATE */
+png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IHDR;
+ PNG_CONST PNG_IDAT;
+ PNG_CONST PNG_IEND;
+ PNG_CONST PNG_PLTE;
+#ifdef PNG_READ_bKGD_SUPPORTED
+ PNG_CONST PNG_bKGD;
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+ PNG_CONST PNG_cHRM;
+#endif
+#ifdef PNG_READ_gAMA_SUPPORTED
+ PNG_CONST PNG_gAMA;
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+ PNG_CONST PNG_hIST;
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+ PNG_CONST PNG_iCCP;
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+ PNG_CONST PNG_iTXt;
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+ PNG_CONST PNG_oFFs;
+#endif
+#ifdef PNG_READ_pCAL_SUPPORTED
+ PNG_CONST PNG_pCAL;
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+ PNG_CONST PNG_pHYs;
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+ PNG_CONST PNG_sBIT;
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+ PNG_CONST PNG_sCAL;
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+ PNG_CONST PNG_sRGB;
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+ PNG_CONST PNG_sPLT;
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+ PNG_CONST PNG_tEXt;
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+ PNG_CONST PNG_tIME;
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+ PNG_CONST PNG_tRNS;
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+ PNG_CONST PNG_zTXt;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
+
+ /* First we make sure we have enough data for the 4 byte chunk name
+ * and the 4 byte chunk length before proceeding with decoding the
+ * chunk data. To fully decode each of these chunks, we also make
+ * sure we have enough data in the buffer for the 4 byte CRC at the
+ * end of every chunk (except IDAT, which is handled separately).
+ */
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+ {
+ png_byte chunk_length[4];
+
+ if (png_ptr->buffer_size < 8)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+ }
+
+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ if (png_ptr->mode & PNG_AFTER_IDAT)
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
+ if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+ {
+ if (png_ptr->push_length != 13)
+ png_error(png_ptr, "Invalid IHDR length");
+
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+ else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
+
+ png_ptr->process_mode = PNG_READ_DONE_MODE;
+ png_push_have_end(png_ptr, info_ptr);
+ }
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ png_ptr->mode |= PNG_HAVE_IDAT;
+
+ png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+
+ if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ png_ptr->mode |= PNG_HAVE_PLTE;
+
+ else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+ }
+ }
+
+#endif
+ else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+ else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ /* If we reach an IDAT chunk, this means we have read all of the
+ * header chunks, and we can start reading the image (or if this
+ * is called after the image has been read - we have an error).
+ */
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ if (png_ptr->push_length == 0)
+ return;
+
+ if (png_ptr->mode & PNG_AFTER_IDAT)
+ png_error(png_ptr, "Too many IDAT's found");
+ }
+
+ png_ptr->idat_size = png_ptr->push_length;
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ png_ptr->process_mode = PNG_READ_IDAT_MODE;
+ png_push_have_info(png_ptr, info_ptr);
+ png_ptr->zstream.avail_out =
+ (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
+ png_ptr->iwidth) + 1;
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ return;
+ }
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+ else
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+}
+
+void /* PRIVATE */
+png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
+{
+ png_ptr->process_mode = PNG_SKIP_MODE;
+ png_ptr->skip_length = skip;
+}
+
+void /* PRIVATE */
+png_push_crc_finish(png_structp png_ptr)
+{
+ if (png_ptr->skip_length && png_ptr->save_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
+ save_size = (png_size_t)png_ptr->skip_length;
+ else
+ save_size = png_ptr->save_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+ png_ptr->skip_length -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (png_ptr->skip_length && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
+ save_size = (png_size_t)png_ptr->skip_length;
+ else
+ save_size = png_ptr->current_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_ptr->skip_length -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+ if (!png_ptr->skip_length)
+ {
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_crc_finish(png_ptr, 0);
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+}
+
+void PNGAPI
+png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
+{
+ png_bytep ptr;
+
+ if (png_ptr == NULL)
+ return;
+
+ ptr = buffer;
+ if (png_ptr->save_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (length < png_ptr->save_buffer_size)
+ save_size = length;
+ else
+ save_size = png_ptr->save_buffer_size;
+
+ png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
+ length -= save_size;
+ ptr += save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (length && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (length < png_ptr->current_buffer_size)
+ save_size = length;
+
+ else
+ save_size = png_ptr->current_buffer_size;
+
+ png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+}
+
+void /* PRIVATE */
+png_push_save_buffer(png_structp png_ptr)
+{
+ if (png_ptr->save_buffer_size)
+ {
+ if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
+ {
+ png_size_t i, istop;
+ png_bytep sp;
+ png_bytep dp;
+
+ istop = png_ptr->save_buffer_size;
+ for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
+ i < istop; i++, sp++, dp++)
+ {
+ *dp = *sp;
+ }
+ }
+ }
+ if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
+ png_ptr->save_buffer_max)
+ {
+ png_size_t new_max;
+ png_bytep old_buffer;
+
+ if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
+ (png_ptr->current_buffer_size + 256))
+ {
+ png_error(png_ptr, "Potential overflow of save_buffer");
+ }
+
+ new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
+ old_buffer = png_ptr->save_buffer;
+ png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
+ (png_uint_32)new_max);
+ if (png_ptr->save_buffer == NULL)
+ {
+ png_free(png_ptr, old_buffer);
+ png_error(png_ptr, "Insufficient memory for save_buffer");
+ }
+ png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+ png_free(png_ptr, old_buffer);
+ png_ptr->save_buffer_max = new_max;
+ }
+ if (png_ptr->current_buffer_size)
+ {
+ png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
+ png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
+ png_ptr->save_buffer_size += png_ptr->current_buffer_size;
+ png_ptr->current_buffer_size = 0;
+ }
+ png_ptr->save_buffer_ptr = png_ptr->save_buffer;
+ png_ptr->buffer_size = 0;
+}
+
+void /* PRIVATE */
+png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
+ png_size_t buffer_length)
+{
+ png_ptr->current_buffer = buffer;
+ png_ptr->current_buffer_size = buffer_length;
+ png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
+ png_ptr->current_buffer_ptr = png_ptr->current_buffer;
+}
+
+void /* PRIVATE */
+png_push_read_IDAT(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IDAT;
+#endif
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+ {
+ png_byte chunk_length[4];
+
+ if (png_ptr->buffer_size < 8)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+
+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+ png_error(png_ptr, "Not enough compressed data");
+ return;
+ }
+
+ png_ptr->idat_size = png_ptr->push_length;
+ }
+ if (png_ptr->idat_size && png_ptr->save_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
+ {
+ save_size = (png_size_t)png_ptr->idat_size;
+
+ /* Check for overflow */
+ if ((png_uint_32)save_size != png_ptr->idat_size)
+ png_error(png_ptr, "save_size overflowed in pngpread");
+ }
+ else
+ save_size = png_ptr->save_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+ png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+ png_ptr->idat_size -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (png_ptr->idat_size && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
+ {
+ save_size = (png_size_t)png_ptr->idat_size;
+
+ /* Check for overflow */
+ if ((png_uint_32)save_size != png_ptr->idat_size)
+ png_error(png_ptr, "save_size overflowed in pngpread");
+ }
+ else
+ save_size = png_ptr->current_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_ptr->idat_size -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+ if (!png_ptr->idat_size)
+ {
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_crc_finish(png_ptr, 0);
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ }
+}
+
+void /* PRIVATE */
+png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
+ png_size_t buffer_length)
+{
+ /* The caller checks for a non-zero buffer length. */
+ if (!(buffer_length > 0) || buffer == NULL)
+ png_error(png_ptr, "No IDAT data (internal error)");
+
+ /* This routine must process all the data it has been given
+ * before returning, calling the row callback as required to
+ * handle the uncompressed results.
+ */
+ png_ptr->zstream.next_in = buffer;
+ png_ptr->zstream.avail_in = (uInt)buffer_length;
+
+ /* Keep going until the decompressed data is all processed
+ * or the stream marked as finished.
+ */
+ while (png_ptr->zstream.avail_in > 0 &&
+ !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+ {
+ int ret;
+
+ /* We have data for zlib, but we must check that zlib
+ * has somewhere to put the results. It doesn't matter
+ * if we don't expect any results -- it may be the input
+ * data is just the LZ end code.
+ */
+ if (!(png_ptr->zstream.avail_out > 0))
+ {
+ png_ptr->zstream.avail_out =
+ (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
+ png_ptr->iwidth) + 1;
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ }
+
+ /* Using Z_SYNC_FLUSH here means that an unterminated
+ * LZ stream can still be handled (a stream with a missing
+ * end code), otherwise (Z_NO_FLUSH) a future zlib
+ * implementation might defer output and, therefore,
+ * change the current behavior. (See comments in inflate.c
+ * for why this doesn't happen at present with zlib 1.2.5.)
+ */
+ ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+
+ /* Check for any failure before proceeding. */
+ if (ret != Z_OK && ret != Z_STREAM_END)
+ {
+ /* Terminate the decompression. */
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+
+ /* This may be a truncated stream (missing or
+ * damaged end code). Treat that as a warning.
+ */
+ if (png_ptr->row_number >= png_ptr->num_rows ||
+ png_ptr->pass > 6)
+ png_warning(png_ptr, "Truncated compressed data in IDAT");
+ else
+ png_error(png_ptr, "Decompression error in IDAT");
+
+ /* Skip the check on unprocessed input */
+ return;
+ }
+
+ /* Did inflate output any data? */
+ if (png_ptr->zstream.next_out != png_ptr->row_buf)
+ {
+ /* Is this unexpected data after the last row?
+ * If it is, artificially terminate the LZ output
+ * here.
+ */
+ if (png_ptr->row_number >= png_ptr->num_rows ||
+ png_ptr->pass > 6)
+ {
+ /* Extra data. */
+ png_warning(png_ptr, "Extra compressed data in IDAT");
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ /* Do no more processing; skip the unprocessed
+ * input check below.
+ */
+ return;
+ }
+
+ /* Do we have a complete row? */
+ if (png_ptr->zstream.avail_out == 0)
+ png_push_process_row(png_ptr);
+ }
+
+ /* And check for the end of the stream. */
+ if (ret == Z_STREAM_END)
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ }
+
+ /* All the data should have been processed, if anything
+ * is left at this point we have bytes of IDAT data
+ * after the zlib end code.
+ */
+ if (png_ptr->zstream.avail_in > 0)
+ png_warning(png_ptr, "Extra compression data");
+}
+
+void /* PRIVATE */
+png_push_process_row(png_structp png_ptr)
+{
+ png_ptr->row_info.color_type = png_ptr->color_type;
+ png_ptr->row_info.width = png_ptr->iwidth;
+ png_ptr->row_info.channels = png_ptr->channels;
+ png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+ png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+
+ png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+ png_ptr->row_info.width);
+
+ png_read_filter_row(png_ptr, &(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+ (int)(png_ptr->row_buf[0]));
+
+ png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+ png_ptr->rowbytes + 1);
+
+ if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
+ png_do_read_transformations(png_ptr);
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Blow up interlaced rows to full size */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ if (png_ptr->pass < 6)
+/* old interface (pre-1.0.9):
+ png_do_read_interlace(&(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+ */
+ png_do_read_interlace(png_ptr);
+
+ switch (png_ptr->pass)
+ {
+ case 0:
+ {
+ int i;
+ for (i = 0; i < 8 && png_ptr->pass == 0; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
+ }
+
+ if (png_ptr->pass == 2) /* Pass 1 might be empty */
+ {
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ if (png_ptr->pass == 4 && png_ptr->height <= 4)
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ if (png_ptr->pass == 6 && png_ptr->height <= 4)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ break;
+ }
+
+ case 1:
+ {
+ int i;
+ for (i = 0; i < 8 && png_ptr->pass == 1; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 2) /* Skip top 4 generated rows */
+ {
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ break;
+ }
+
+ case 2:
+ {
+ int i;
+
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 4) /* Pass 3 might be empty */
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ break;
+ }
+
+ case 3:
+ {
+ int i;
+
+ for (i = 0; i < 4 && png_ptr->pass == 3; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 4) /* Skip top two generated rows */
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ break;
+ }
+
+ case 4:
+ {
+ int i;
+
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 6) /* Pass 5 might be empty */
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ break;
+ }
+
+ case 5:
+ {
+ int i;
+
+ for (i = 0; i < 2 && png_ptr->pass == 5; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 6) /* Skip top generated row */
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ break;
+ }
+ case 6:
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+
+ if (png_ptr->pass != 6)
+ break;
+
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ }
+ else
+#endif
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+}
+
+void /* PRIVATE */
+png_read_push_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+ /* Height of interlace block. This is not currently used - if you need
+ * it, uncomment it here and in png.h
+ PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+ */
+#endif
+
+ png_ptr->row_number++;
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+ png_memset_check(png_ptr, png_ptr->prev_row, 0,
+ png_ptr->rowbytes + 1);
+ do
+ {
+ png_ptr->pass++;
+ if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
+ (png_ptr->pass == 3 && png_ptr->width < 3) ||
+ (png_ptr->pass == 5 && png_ptr->width < 2))
+ png_ptr->pass++;
+
+ if (png_ptr->pass > 7)
+ png_ptr->pass--;
+
+ if (png_ptr->pass >= 7)
+ break;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ if (png_ptr->transformations & PNG_INTERLACE)
+ break;
+
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+
+ } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
+ }
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+}
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+void /* PRIVATE */
+png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+ {
+ png_error(png_ptr, "Out of place tEXt");
+ info_ptr = info_ptr; /* To quiet some compiler warnings */
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ png_ptr->skip_length = 0; /* This may not be necessary */
+
+ if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
+ {
+ png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+ png_ptr->skip_length = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(length + 1));
+ png_ptr->current_text[length] = '\0';
+ png_ptr->current_text_ptr = png_ptr->current_text;
+ png_ptr->current_text_size = (png_size_t)length;
+ png_ptr->current_text_left = (png_size_t)length;
+ png_ptr->process_mode = PNG_READ_tEXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->buffer_size && png_ptr->current_text_left)
+ {
+ png_size_t text_size;
+
+ if (png_ptr->buffer_size < png_ptr->current_text_left)
+ text_size = png_ptr->buffer_size;
+
+ else
+ text_size = png_ptr->current_text_left;
+
+ png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+ png_ptr->current_text_left -= text_size;
+ png_ptr->current_text_ptr += text_size;
+ }
+ if (!(png_ptr->current_text_left))
+ {
+ png_textp text_ptr;
+ png_charp text;
+ png_charp key;
+ int ret;
+
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_crc_finish(png_ptr);
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (png_ptr->skip_length)
+ return;
+#endif
+
+ key = png_ptr->current_text;
+
+ for (text = key; *text; text++)
+ /* Empty loop */ ;
+
+ if (text < key + png_ptr->current_text_size)
+ text++;
+
+ text_ptr = (png_textp)png_malloc(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+ text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+ text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+#endif
+ text_ptr->text = text;
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, key);
+ png_free(png_ptr, text_ptr);
+ png_ptr->current_text = NULL;
+
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to store text chunk.");
+ }
+}
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+void /* PRIVATE */
+png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+ {
+ png_error(png_ptr, "Out of place zTXt");
+ info_ptr = info_ptr; /* To quiet some compiler warnings */
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ /* We can't handle zTXt chunks > 64K, since we don't have enough space
+ * to be able to store the uncompressed data. Actually, the threshold
+ * is probably around 32K, but it isn't as definite as 64K is.
+ */
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "zTXt chunk too large to fit in memory");
+ png_push_crc_skip(png_ptr, length);
+ return;
+ }
+#endif
+
+ png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(length + 1));
+ png_ptr->current_text[length] = '\0';
+ png_ptr->current_text_ptr = png_ptr->current_text;
+ png_ptr->current_text_size = (png_size_t)length;
+ png_ptr->current_text_left = (png_size_t)length;
+ png_ptr->process_mode = PNG_READ_zTXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->buffer_size && png_ptr->current_text_left)
+ {
+ png_size_t text_size;
+
+ if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
+ text_size = png_ptr->buffer_size;
+
+ else
+ text_size = png_ptr->current_text_left;
+
+ png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+ png_ptr->current_text_left -= text_size;
+ png_ptr->current_text_ptr += text_size;
+ }
+ if (!(png_ptr->current_text_left))
+ {
+ png_textp text_ptr;
+ png_charp text;
+ png_charp key;
+ int ret;
+ png_size_t text_size, key_size;
+
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_crc_finish(png_ptr);
+
+ key = png_ptr->current_text;
+
+ for (text = key; *text; text++)
+ /* Empty loop */ ;
+
+ /* zTXt can't have zero text */
+ if (text >= key + png_ptr->current_text_size)
+ {
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ return;
+ }
+
+ text++;
+
+ if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
+ {
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ return;
+ }
+
+ text++;
+
+ png_ptr->zstream.next_in = (png_bytep )text;
+ png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
+ (text - key));
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ key_size = text - key;
+ text_size = 0;
+ text = NULL;
+ ret = Z_STREAM_END;
+
+ while (png_ptr->zstream.avail_in)
+ {
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret != Z_OK && ret != Z_STREAM_END)
+ {
+ inflateReset(&png_ptr->zstream);
+ png_ptr->zstream.avail_in = 0;
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ png_free(png_ptr, text);
+ return;
+ }
+ if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
+ {
+ if (text == NULL)
+ {
+ text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(png_ptr->zbuf_size
+ - png_ptr->zstream.avail_out + key_size + 1));
+
+ png_memcpy(text + key_size, png_ptr->zbuf,
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+
+ png_memcpy(text, key, key_size);
+
+ text_size = key_size + png_ptr->zbuf_size -
+ png_ptr->zstream.avail_out;
+
+ *(text + text_size) = '\0';
+ }
+ else
+ {
+ png_charp tmp;
+
+ tmp = text;
+ text = (png_charp)png_malloc(png_ptr, text_size +
+ (png_uint_32)(png_ptr->zbuf_size
+ - png_ptr->zstream.avail_out + 1));
+
+ png_memcpy(text, tmp, text_size);
+ png_free(png_ptr, tmp);
+
+ png_memcpy(text + text_size, png_ptr->zbuf,
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+
+ text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+ *(text + text_size) = '\0';
+ }
+ if (ret != Z_STREAM_END)
+ {
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ if (ret == Z_STREAM_END)
+ break;
+ }
+
+ inflateReset(&png_ptr->zstream);
+ png_ptr->zstream.avail_in = 0;
+
+ if (ret != Z_STREAM_END)
+ {
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ png_free(png_ptr, text);
+ return;
+ }
+
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ key = text;
+ text += key_size;
+
+ text_ptr = (png_textp)png_malloc(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+ text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
+ text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+#endif
+ text_ptr->text = text;
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, key);
+ png_free(png_ptr, text_ptr);
+
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to store text chunk.");
+ }
+}
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+void /* PRIVATE */
+png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+ {
+ png_error(png_ptr, "Out of place iTXt");
+ info_ptr = info_ptr; /* To quiet some compiler warnings */
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ png_ptr->skip_length = 0; /* This may not be necessary */
+
+ if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
+ {
+ png_warning(png_ptr, "iTXt chunk too large to fit in memory");
+ png_ptr->skip_length = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(length + 1));
+ png_ptr->current_text[length] = '\0';
+ png_ptr->current_text_ptr = png_ptr->current_text;
+ png_ptr->current_text_size = (png_size_t)length;
+ png_ptr->current_text_left = (png_size_t)length;
+ png_ptr->process_mode = PNG_READ_iTXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
+{
+
+ if (png_ptr->buffer_size && png_ptr->current_text_left)
+ {
+ png_size_t text_size;
+
+ if (png_ptr->buffer_size < png_ptr->current_text_left)
+ text_size = png_ptr->buffer_size;
+
+ else
+ text_size = png_ptr->current_text_left;
+
+ png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+ png_ptr->current_text_left -= text_size;
+ png_ptr->current_text_ptr += text_size;
+ }
+ if (!(png_ptr->current_text_left))
+ {
+ png_textp text_ptr;
+ png_charp key;
+ int comp_flag;
+ png_charp lang;
+ png_charp lang_key;
+ png_charp text;
+ int ret;
+
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_crc_finish(png_ptr);
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (png_ptr->skip_length)
+ return;
+#endif
+
+ key = png_ptr->current_text;
+
+ for (lang = key; *lang; lang++)
+ /* Empty loop */ ;
+
+ if (lang < key + png_ptr->current_text_size - 3)
+ lang++;
+
+ comp_flag = *lang++;
+ lang++; /* Skip comp_type, always zero */
+
+ for (lang_key = lang; *lang_key; lang_key++)
+ /* Empty loop */ ;
+
+ lang_key++; /* Skip NUL separator */
+
+ text=lang_key;
+
+ if (lang_key < key + png_ptr->current_text_size - 1)
+ {
+ for (; *text; text++)
+ /* Empty loop */ ;
+ }
+
+ if (text < key + png_ptr->current_text_size)
+ text++;
+
+ text_ptr = (png_textp)png_malloc(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+
+ text_ptr->compression = comp_flag + 2;
+ text_ptr->key = key;
+ text_ptr->lang = lang;
+ text_ptr->lang_key = lang_key;
+ text_ptr->text = text;
+ text_ptr->text_length = 0;
+ text_ptr->itxt_length = png_strlen(text);
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_ptr->current_text = NULL;
+
+ png_free(png_ptr, text_ptr);
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
+ }
+}
+#endif
+
+/* This function is called when we haven't found a handler for this
+ * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
+ * name or a critical chunk), the chunk is (currently) silently ignored.
+ */
+void /* PRIVATE */
+png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ png_uint_32 skip = 0;
+
+ if (!(png_ptr->chunk_name[0] & 0x20))
+ {
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+ if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ PNG_HANDLE_CHUNK_ALWAYS
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+ && png_ptr->read_user_chunk_fn == NULL
+#endif
+ )
+#endif
+ png_chunk_error(png_ptr, "unknown critical chunk");
+
+ info_ptr = info_ptr; /* To quiet some compiler warnings */
+ }
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+ if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+ {
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "unknown chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+ png_memcpy((png_charp)png_ptr->unknown_chunk.name,
+ (png_charp)png_ptr->chunk_name,
+ png_sizeof(png_ptr->unknown_chunk.name));
+ png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
+ = '\0';
+
+ png_ptr->unknown_chunk.size = (png_size_t)length;
+
+ if (length == 0)
+ png_ptr->unknown_chunk.data = NULL;
+
+ else
+ {
+ png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)length);
+ png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
+ }
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+ if (png_ptr->read_user_chunk_fn != NULL)
+ {
+ /* Callback to user unknown chunk handler */
+ int ret;
+ ret = (*(png_ptr->read_user_chunk_fn))
+ (png_ptr, &png_ptr->unknown_chunk);
+
+ if (ret < 0)
+ png_chunk_error(png_ptr, "error in user chunk");
+
+ if (ret == 0)
+ {
+ if (!(png_ptr->chunk_name[0] & 0x20))
+ if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ PNG_HANDLE_CHUNK_ALWAYS)
+ png_chunk_error(png_ptr, "unknown critical chunk");
+ png_set_unknown_chunks(png_ptr, info_ptr,
+ &png_ptr->unknown_chunk, 1);
+ }
+ }
+
+ else
+#endif
+ png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
+ }
+
+ else
+#endif
+ skip=length;
+ png_push_crc_skip(png_ptr, skip);
+}
+
+void /* PRIVATE */
+png_push_have_info(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->info_fn != NULL)
+ (*(png_ptr->info_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_end(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->end_fn != NULL)
+ (*(png_ptr->end_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_row(png_structp png_ptr, png_bytep row)
+{
+ if (png_ptr->row_fn != NULL)
+ (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
+ (int)png_ptr->pass);
+}
+
+void PNGAPI
+png_progressive_combine_row (png_structp png_ptr,
+ png_bytep old_row, png_bytep new_row)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST int FARDATA png_pass_dsp_mask[7] =
+ {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+#endif
+
+ if (png_ptr == NULL)
+ return;
+
+ if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
+ png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
+}
+
+void PNGAPI
+png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
+ png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+ png_progressive_end_ptr end_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->info_fn = info_fn;
+ png_ptr->row_fn = row_fn;
+ png_ptr->end_fn = end_fn;
+
+ png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
+}
+
+png_voidp PNGAPI
+png_get_progressive_ptr(png_structp png_ptr)
+{
+ if (png_ptr == NULL)
+ return (NULL);
+
+ return png_ptr->io_ptr;
+}
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
diff --git a/src/libpng/pngread.c b/src/libpng/pngread.c
new file mode 100644
index 0000000..6207624
--- /dev/null
+++ b/src/libpng/pngread.c
@@ -0,0 +1,1528 @@
+
+/* pngread.c - read a PNG file
+ *
+ * Last changed in libpng 1.2.44 [June 26, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains routines that an application calls directly to
+ * read a PNG file or stream.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_READ_SUPPORTED
+
+
+/* Create a PNG structure for reading, and allocate any memory needed. */
+png_structp PNGAPI
+png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
+ warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
+}
+
+/* Alternate create PNG structure for reading, and allocate any memory
+ * needed.
+ */
+png_structp PNGAPI
+png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#ifdef PNG_SETJMP_SUPPORTED
+ volatile
+#endif
+ png_structp png_ptr;
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ jmp_buf jmpbuf;
+#endif
+#endif
+
+ int i;
+
+ png_debug(1, "in png_create_read_struct");
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
+ (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
+#else
+ png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+#endif
+ if (png_ptr == NULL)
+ return (NULL);
+
+ /* Added at libpng-1.2.6 */
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
+ png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
+# ifdef PNG_USER_CHUNK_CACHE_MAX
+ /* Added at libpng-1.2.43 and 1.4.0 */
+ png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
+# endif
+# ifdef PNG_SET_USER_CHUNK_MALLOC_MAX
+ /* Added at libpng-1.2.43 and 1.4.1 */
+ png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+#else
+ if (setjmp(png_ptr->jmpbuf))
+#endif
+ {
+ png_free(png_ptr, png_ptr->zbuf);
+ png_ptr->zbuf = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)png_ptr,
+ (png_free_ptr)free_fn, (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)png_ptr);
+#endif
+ return (NULL);
+ }
+#ifdef USE_FAR_KEYWORD
+ png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
+#endif
+#endif /* PNG_SETJMP_SUPPORTED */
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
+#endif
+
+ png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+ if (user_png_ver)
+ {
+ i = 0;
+ do
+ {
+ if (user_png_ver[i] != png_libpng_ver[i])
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+ } while (png_libpng_ver[i++]);
+ }
+ else
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+
+
+ if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+ {
+ /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+ * we must recompile any applications that use any older library version.
+ * For versions after libpng 1.0, we will be compatible, so we need
+ * only check the first digit.
+ */
+ if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+ (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
+ (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+ {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+ char msg[80];
+ if (user_png_ver)
+ {
+ png_snprintf(msg, 80,
+ "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ png_snprintf(msg, 80,
+ "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+#endif
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags = 0;
+#endif
+ png_error(png_ptr,
+ "Incompatible libpng version in application and library");
+ }
+ }
+
+ /* Initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+ png_ptr->zstream.zalloc = png_zalloc;
+ png_ptr->zstream.zfree = png_zfree;
+ png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+ switch (inflateInit(&png_ptr->zstream))
+ {
+ case Z_OK: /* Do nothing */ break;
+ case Z_MEM_ERROR:
+ case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error");
+ break;
+ case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error");
+ break;
+ default: png_error(png_ptr, "Unknown zlib error");
+ }
+
+
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* Applications that neglect to set up their own setjmp() and then
+ encounter a png_error() will longjmp here. Since the jmpbuf is
+ then meaningless we abort instead of returning. */
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+ PNG_ABORT();
+ png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
+#else
+ if (setjmp(png_ptr->jmpbuf))
+ PNG_ABORT();
+#endif
+#endif /* PNG_SETJMP_SUPPORTED */
+
+ return (png_ptr);
+}
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* Initialize PNG structure for reading, and allocate any memory needed.
+ * This interface is deprecated in favour of the png_create_read_struct(),
+ * and it will disappear as of libpng-1.3.0.
+ */
+#undef png_read_init
+void PNGAPI
+png_read_init(png_structp png_ptr)
+{
+ /* We only come here via pre-1.0.7-compiled applications */
+ png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
+}
+
+void PNGAPI
+png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size, png_size_t png_info_size)
+{
+ /* We only come here via pre-1.0.12-compiled applications */
+ if (png_ptr == NULL)
+ return;
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+ if (png_sizeof(png_struct) > png_struct_size ||
+ png_sizeof(png_info) > png_info_size)
+ {
+ char msg[80];
+ png_ptr->warning_fn = NULL;
+ if (user_png_ver)
+ {
+ png_snprintf(msg, 80,
+ "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ png_snprintf(msg, 80,
+ "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+ }
+#endif
+ if (png_sizeof(png_struct) > png_struct_size)
+ {
+ png_ptr->error_fn = NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags = 0;
+#endif
+ png_error(png_ptr,
+ "The png struct allocated by the application for reading is"
+ " too small.");
+ }
+ if (png_sizeof(png_info) > png_info_size)
+ {
+ png_ptr->error_fn = NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags = 0;
+#endif
+ png_error(png_ptr,
+ "The info struct allocated by application for reading is"
+ " too small.");
+ }
+ png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
+}
+#endif /* PNG_1_0_X || PNG_1_2_X */
+
+void PNGAPI
+png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp; /* to save current jump buffer */
+#endif
+
+ int i = 0;
+
+ png_structp png_ptr=*ptr_ptr;
+
+ if (png_ptr == NULL)
+ return;
+
+ do
+ {
+ if (user_png_ver[i] != png_libpng_ver[i])
+ {
+#ifdef PNG_LEGACY_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+ png_ptr->warning_fn = NULL;
+ png_warning(png_ptr,
+ "Application uses deprecated png_read_init() and should be"
+ " recompiled.");
+ break;
+#endif
+ }
+ } while (png_libpng_ver[i++]);
+
+ png_debug(1, "in png_read_init_3");
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* Save jump buffer and error functions */
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
+#endif
+
+ if (png_sizeof(png_struct) > png_struct_size)
+ {
+ png_destroy_struct(png_ptr);
+ *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+ png_ptr = *ptr_ptr;
+ }
+
+ /* Reset all variables to 0 */
+ png_memset(png_ptr, 0, png_sizeof(png_struct));
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* Restore jump buffer */
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
+#endif
+
+ /* Added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
+ png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
+#endif
+
+ /* Initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zstream.zalloc = png_zalloc;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+ png_ptr->zstream.zalloc = png_zalloc;
+ png_ptr->zstream.zfree = png_zfree;
+ png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+ switch (inflateInit(&png_ptr->zstream))
+ {
+ case Z_OK: /* Do nothing */ break;
+ case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
+ case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error");
+ break;
+ default: png_error(png_ptr, "Unknown zlib error");
+ }
+
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data. This has been
+ * changed in v0.90 to allow reading a file that already has the magic
+ * bytes read from the stream. You can tell libpng how many bytes have
+ * been read from the beginning of the stream (up to the maximum of 8)
+ * via png_set_sig_bytes(), and we will only check the remaining bytes
+ * here. The application can then have access to the signature bytes we
+ * read if it is determined that this isn't a valid PNG file.
+ */
+void PNGAPI
+png_read_info(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_read_info");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* If we haven't checked all of the PNG signature bytes, do so now. */
+ if (png_ptr->sig_bytes < 8)
+ {
+ png_size_t num_checked = png_ptr->sig_bytes,
+ num_to_check = 8 - num_checked;
+
+ png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
+ png_ptr->sig_bytes = 8;
+
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+ {
+ if (num_checked < 4 &&
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_error(png_ptr, "Not a PNG file");
+ else
+ png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+ }
+ if (num_checked < 3)
+ png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+ }
+
+ for (;;)
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IHDR;
+ PNG_CONST PNG_IDAT;
+ PNG_CONST PNG_IEND;
+ PNG_CONST PNG_PLTE;
+#ifdef PNG_READ_bKGD_SUPPORTED
+ PNG_CONST PNG_bKGD;
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+ PNG_CONST PNG_cHRM;
+#endif
+#ifdef PNG_READ_gAMA_SUPPORTED
+ PNG_CONST PNG_gAMA;
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+ PNG_CONST PNG_hIST;
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+ PNG_CONST PNG_iCCP;
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+ PNG_CONST PNG_iTXt;
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+ PNG_CONST PNG_oFFs;
+#endif
+#ifdef PNG_READ_pCAL_SUPPORTED
+ PNG_CONST PNG_pCAL;
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+ PNG_CONST PNG_pHYs;
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+ PNG_CONST PNG_sBIT;
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+ PNG_CONST PNG_sCAL;
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+ PNG_CONST PNG_sPLT;
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+ PNG_CONST PNG_sRGB;
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+ PNG_CONST PNG_tEXt;
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+ PNG_CONST PNG_tIME;
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+ PNG_CONST PNG_tRNS;
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+ PNG_CONST PNG_zTXt;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
+ png_uint_32 length = png_read_chunk_header(png_ptr);
+ PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
+
+ /* This should be a binary subdivision search or a hash for
+ * matching the chunk name rather than a linear search.
+ */
+ if (!png_memcmp(chunk_name, png_IDAT, 4))
+ if (png_ptr->mode & PNG_AFTER_IDAT)
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
+ if (!png_memcmp(chunk_name, png_IHDR, 4))
+ png_handle_IHDR(png_ptr, info_ptr, length);
+ else if (!png_memcmp(chunk_name, png_IEND, 4))
+ png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if (png_handle_as_unknown(png_ptr, chunk_name))
+ {
+ if (!png_memcmp(chunk_name, png_IDAT, 4))
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ png_handle_unknown(png_ptr, info_ptr, length);
+ if (!png_memcmp(chunk_name, png_PLTE, 4))
+ png_ptr->mode |= PNG_HAVE_PLTE;
+ else if (!png_memcmp(chunk_name, png_IDAT, 4))
+ {
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+ break;
+ }
+ }
+#endif
+ else if (!png_memcmp(chunk_name, png_PLTE, 4))
+ png_handle_PLTE(png_ptr, info_ptr, length);
+ else if (!png_memcmp(chunk_name, png_IDAT, 4))
+ {
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+
+ png_ptr->idat_size = length;
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ break;
+ }
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_bKGD, 4))
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_cHRM, 4))
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_gAMA, 4))
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_hIST, 4))
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_oFFs, 4))
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_pCAL, 4))
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_sCAL, 4))
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_pHYs, 4))
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_sBIT, 4))
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_sRGB, 4))
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_iCCP, 4))
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_sPLT, 4))
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_tEXt, 4))
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_tIME, 4))
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_tRNS, 4))
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_zTXt, 4))
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_iTXt, 4))
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+ else
+ png_handle_unknown(png_ptr, info_ptr, length);
+ }
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+/* Optional call to update the users info_ptr structure */
+void PNGAPI
+png_read_update_info(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_read_update_info");
+
+ if (png_ptr == NULL)
+ return;
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ png_read_start_row(png_ptr);
+ else
+ png_warning(png_ptr,
+ "Ignoring extra png_read_update_info() call; row buffer not reallocated");
+
+ png_read_transform_info(png_ptr, info_ptr);
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Initialize palette, background, etc, after transformations
+ * are set, but before any reading takes place. This allows
+ * the user to obtain a gamma-corrected palette, for example.
+ * If the user doesn't call this, we will do it ourselves.
+ */
+void PNGAPI
+png_start_read_image(png_structp png_ptr)
+{
+ png_debug(1, "in png_start_read_image");
+
+ if (png_ptr == NULL)
+ return;
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ png_read_start_row(png_ptr);
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+void PNGAPI
+png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
+{
+ PNG_CONST PNG_IDAT;
+ PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
+ 0xff};
+ PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+ int ret;
+
+ if (png_ptr == NULL)
+ return;
+
+ png_debug2(1, "in png_read_row (row %lu, pass %d)",
+ png_ptr->row_number, png_ptr->pass);
+
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ png_read_start_row(png_ptr);
+ if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+ {
+ /* Check for transforms that have been set but were defined out */
+#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
+ !defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
+#endif
+ }
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* If interlaced and we do not need a new row, combine row and return */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ switch (png_ptr->pass)
+ {
+ case 0:
+ if (png_ptr->row_number & 0x07)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 1:
+ if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 2:
+ if ((png_ptr->row_number & 0x07) != 4)
+ {
+ if (dsp_row != NULL && (png_ptr->row_number & 4))
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 3:
+ if ((png_ptr->row_number & 3) || png_ptr->width < 3)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 4:
+ if ((png_ptr->row_number & 3) != 2)
+ {
+ if (dsp_row != NULL && (png_ptr->row_number & 2))
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 5:
+ if ((png_ptr->row_number & 1) || png_ptr->width < 2)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 6:
+ if (!(png_ptr->row_number & 1))
+ {
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IDAT))
+ png_error(png_ptr, "Invalid attempt to read row data");
+
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ png_ptr->zstream.avail_out =
+ (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
+ png_ptr->iwidth) + 1);
+ do
+ {
+ if (!(png_ptr->zstream.avail_in))
+ {
+ while (!png_ptr->idat_size)
+ {
+ png_crc_finish(png_ptr, 0);
+
+ png_ptr->idat_size = png_read_chunk_header(png_ptr);
+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ png_error(png_ptr, "Not enough image data");
+ }
+ png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_in = png_ptr->zbuf;
+ if (png_ptr->zbuf_size > png_ptr->idat_size)
+ png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+ png_crc_read(png_ptr, png_ptr->zbuf,
+ (png_size_t)png_ptr->zstream.avail_in);
+ png_ptr->idat_size -= png_ptr->zstream.avail_in;
+ }
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret == Z_STREAM_END)
+ {
+ if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
+ png_ptr->idat_size)
+ png_error(png_ptr, "Extra compressed data");
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+ if (ret != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+ "Decompression error");
+
+ } while (png_ptr->zstream.avail_out);
+
+ png_ptr->row_info.color_type = png_ptr->color_type;
+ png_ptr->row_info.width = png_ptr->iwidth;
+ png_ptr->row_info.channels = png_ptr->channels;
+ png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+ png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+ png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+ png_ptr->row_info.width);
+
+ if (png_ptr->row_buf[0])
+ png_read_filter_row(png_ptr, &(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+ (int)(png_ptr->row_buf[0]));
+
+ png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+ png_ptr->rowbytes + 1);
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+ {
+ /* Intrapixel differencing */
+ png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+ }
+#endif
+
+
+ if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
+ png_do_read_transformations(png_ptr);
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Blow up interlaced rows to full size */
+ if (png_ptr->interlaced &&
+ (png_ptr->transformations & PNG_INTERLACE))
+ {
+ if (png_ptr->pass < 6)
+ /* Old interface (pre-1.0.9):
+ * png_do_read_interlace(&(png_ptr->row_info),
+ * png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+ */
+ png_do_read_interlace(png_ptr);
+
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ if (row != NULL)
+ png_combine_row(png_ptr, row,
+ png_pass_mask[png_ptr->pass]);
+ }
+ else
+#endif
+ {
+ if (row != NULL)
+ png_combine_row(png_ptr, row, 0xff);
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 0xff);
+ }
+ png_read_finish_row(png_ptr);
+
+ if (png_ptr->read_row_fn != NULL)
+ (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data. If the image is interlaced,
+ * and png_set_interlace_handling() has been called, the rows need to
+ * contain the contents of the rows from the previous pass. If the
+ * image has alpha or transparency, and png_handle_alpha()[*] has been
+ * called, the rows contents must be initialized to the contents of the
+ * screen.
+ *
+ * "row" holds the actual image, and pixels are placed in it
+ * as they arrive. If the image is displayed after each pass, it will
+ * appear to "sparkle" in. "display_row" can be used to display a
+ * "chunky" progressive image, with finer detail added as it becomes
+ * available. If you do not want this "chunky" display, you may pass
+ * NULL for display_row. If you do not want the sparkle display, and
+ * you have not called png_handle_alpha(), you may pass NULL for rows.
+ * If you have called png_handle_alpha(), and the image has either an
+ * alpha channel or a transparency chunk, you must provide a buffer for
+ * rows. In this case, you do not have to provide a display_row buffer
+ * also, but you may. If the image is not interlaced, or if you have
+ * not called png_set_interlace_handling(), the display_row buffer will
+ * be ignored, so pass NULL to it.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+
+void PNGAPI
+png_read_rows(png_structp png_ptr, png_bytepp row,
+ png_bytepp display_row, png_uint_32 num_rows)
+{
+ png_uint_32 i;
+ png_bytepp rp;
+ png_bytepp dp;
+
+ png_debug(1, "in png_read_rows");
+
+ if (png_ptr == NULL)
+ return;
+ rp = row;
+ dp = display_row;
+ if (rp != NULL && dp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep rptr = *rp++;
+ png_bytep dptr = *dp++;
+
+ png_read_row(png_ptr, rptr, dptr);
+ }
+ else if (rp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep rptr = *rp;
+ png_read_row(png_ptr, rptr, png_bytep_NULL);
+ rp++;
+ }
+ else if (dp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep dptr = *dp;
+ png_read_row(png_ptr, png_bytep_NULL, dptr);
+ dp++;
+ }
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the entire image. If the image has an alpha channel or a tRNS
+ * chunk, and you have called png_handle_alpha()[*], you will need to
+ * initialize the image to the current image that PNG will be overlaying.
+ * We set the num_rows again here, in case it was incorrectly set in
+ * png_read_start_row() by a call to png_read_update_info() or
+ * png_start_read_image() if png_set_interlace_handling() wasn't called
+ * prior to either of these functions like it should have been. You can
+ * only call this function once. If you desire to have an image for
+ * each pass of a interlaced image, use png_read_rows() instead.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+void PNGAPI
+png_read_image(png_structp png_ptr, png_bytepp image)
+{
+ png_uint_32 i, image_height;
+ int pass, j;
+ png_bytepp rp;
+
+ png_debug(1, "in png_read_image");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ pass = png_set_interlace_handling(png_ptr);
+#else
+ if (png_ptr->interlaced)
+ png_error(png_ptr,
+ "Cannot read interlaced image -- interlace handler disabled.");
+ pass = 1;
+#endif
+
+
+ image_height=png_ptr->height;
+ png_ptr->num_rows = image_height; /* Make sure this is set correctly */
+
+ for (j = 0; j < pass; j++)
+ {
+ rp = image;
+ for (i = 0; i < image_height; i++)
+ {
+ png_read_row(png_ptr, *rp, png_bytep_NULL);
+ rp++;
+ }
+ }
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file. Will not read past the end of the
+ * file, will verify the end is accurate, and will read any comments
+ * or time information at the end of the file, if info is not NULL.
+ */
+void PNGAPI
+png_read_end(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_read_end");
+
+ if (png_ptr == NULL)
+ return;
+ png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
+
+ do
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IHDR;
+ PNG_CONST PNG_IDAT;
+ PNG_CONST PNG_IEND;
+ PNG_CONST PNG_PLTE;
+#ifdef PNG_READ_bKGD_SUPPORTED
+ PNG_CONST PNG_bKGD;
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+ PNG_CONST PNG_cHRM;
+#endif
+#ifdef PNG_READ_gAMA_SUPPORTED
+ PNG_CONST PNG_gAMA;
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+ PNG_CONST PNG_hIST;
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+ PNG_CONST PNG_iCCP;
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+ PNG_CONST PNG_iTXt;
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+ PNG_CONST PNG_oFFs;
+#endif
+#ifdef PNG_READ_pCAL_SUPPORTED
+ PNG_CONST PNG_pCAL;
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+ PNG_CONST PNG_pHYs;
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+ PNG_CONST PNG_sBIT;
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+ PNG_CONST PNG_sCAL;
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+ PNG_CONST PNG_sPLT;
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+ PNG_CONST PNG_sRGB;
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+ PNG_CONST PNG_tEXt;
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+ PNG_CONST PNG_tIME;
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+ PNG_CONST PNG_tRNS;
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+ PNG_CONST PNG_zTXt;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
+ png_uint_32 length = png_read_chunk_header(png_ptr);
+ PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
+
+ if (!png_memcmp(chunk_name, png_IHDR, 4))
+ png_handle_IHDR(png_ptr, info_ptr, length);
+ else if (!png_memcmp(chunk_name, png_IEND, 4))
+ png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if (png_handle_as_unknown(png_ptr, chunk_name))
+ {
+ if (!png_memcmp(chunk_name, png_IDAT, 4))
+ {
+ if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ png_error(png_ptr, "Too many IDAT's found");
+ }
+ png_handle_unknown(png_ptr, info_ptr, length);
+ if (!png_memcmp(chunk_name, png_PLTE, 4))
+ png_ptr->mode |= PNG_HAVE_PLTE;
+ }
+#endif
+ else if (!png_memcmp(chunk_name, png_IDAT, 4))
+ {
+ /* Zero length IDATs are legal after the last IDAT has been
+ * read, but not after other chunks have been read.
+ */
+ if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ png_error(png_ptr, "Too many IDAT's found");
+ png_crc_finish(png_ptr, length);
+ }
+ else if (!png_memcmp(chunk_name, png_PLTE, 4))
+ png_handle_PLTE(png_ptr, info_ptr, length);
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_bKGD, 4))
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_cHRM, 4))
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_gAMA, 4))
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_hIST, 4))
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_oFFs, 4))
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_pCAL, 4))
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_sCAL, 4))
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_pHYs, 4))
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_sBIT, 4))
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_sRGB, 4))
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_iCCP, 4))
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_sPLT, 4))
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_tEXt, 4))
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_tIME, 4))
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_tRNS, 4))
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_zTXt, 4))
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (!png_memcmp(chunk_name, png_iTXt, 4))
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+ else
+ png_handle_unknown(png_ptr, info_ptr, length);
+ } while (!(png_ptr->mode & PNG_HAVE_IEND));
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+/* Free all memory used by the read */
+void PNGAPI
+png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
+ png_infopp end_info_ptr_ptr)
+{
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL, end_info_ptr = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn = NULL;
+ png_voidp mem_ptr = NULL;
+#endif
+
+ png_debug(1, "in png_destroy_read_struct");
+
+ if (png_ptr_ptr != NULL)
+ png_ptr = *png_ptr_ptr;
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+ mem_ptr = png_ptr->mem_ptr;
+#endif
+
+ if (info_ptr_ptr != NULL)
+ info_ptr = *info_ptr_ptr;
+
+ if (end_info_ptr_ptr != NULL)
+ end_info_ptr = *end_info_ptr_ptr;
+
+ png_read_destroy(png_ptr, info_ptr, end_info_ptr);
+
+ if (info_ptr != NULL)
+ {
+#ifdef PNG_TEXT_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)info_ptr);
+#endif
+ *info_ptr_ptr = NULL;
+ }
+
+ if (end_info_ptr != NULL)
+ {
+#ifdef PNG_READ_TEXT_SUPPORTED
+ png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
+#endif
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)end_info_ptr);
+#endif
+ *end_info_ptr_ptr = NULL;
+ }
+
+ if (png_ptr != NULL)
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)png_ptr);
+#endif
+ *png_ptr_ptr = NULL;
+ }
+}
+
+/* Free all memory used by the read (old method) */
+void /* PRIVATE */
+png_read_destroy(png_structp png_ptr, png_infop info_ptr,
+ png_infop end_info_ptr)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp;
+#endif
+ png_error_ptr error_fn;
+ png_error_ptr warning_fn;
+ png_voidp error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn;
+#endif
+
+ png_debug(1, "in png_read_destroy");
+
+ if (info_ptr != NULL)
+ png_info_destroy(png_ptr, info_ptr);
+
+ if (end_info_ptr != NULL)
+ png_info_destroy(png_ptr, end_info_ptr);
+
+ png_free(png_ptr, png_ptr->zbuf);
+ png_free(png_ptr, png_ptr->big_row_buf);
+ png_free(png_ptr, png_ptr->prev_row);
+ png_free(png_ptr, png_ptr->chunkdata);
+#ifdef PNG_READ_DITHER_SUPPORTED
+ png_free(png_ptr, png_ptr->palette_lookup);
+ png_free(png_ptr, png_ptr->dither_index);
+#endif
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ png_free(png_ptr, png_ptr->gamma_table);
+#endif
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ png_free(png_ptr, png_ptr->gamma_from_1);
+ png_free(png_ptr, png_ptr->gamma_to_1);
+#endif
+#ifdef PNG_FREE_ME_SUPPORTED
+ if (png_ptr->free_me & PNG_FREE_PLTE)
+ png_zfree(png_ptr, png_ptr->palette);
+ png_ptr->free_me &= ~PNG_FREE_PLTE;
+#else
+ if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
+ png_zfree(png_ptr, png_ptr->palette);
+ png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
+#endif
+#if defined(PNG_tRNS_SUPPORTED) || \
+ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+ if (png_ptr->free_me & PNG_FREE_TRNS)
+ png_free(png_ptr, png_ptr->trans);
+ png_ptr->free_me &= ~PNG_FREE_TRNS;
+#else
+ if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
+ png_free(png_ptr, png_ptr->trans);
+ png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
+#endif
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+#ifdef PNG_FREE_ME_SUPPORTED
+ if (png_ptr->free_me & PNG_FREE_HIST)
+ png_free(png_ptr, png_ptr->hist);
+ png_ptr->free_me &= ~PNG_FREE_HIST;
+#else
+ if (png_ptr->flags & PNG_FLAG_FREE_HIST)
+ png_free(png_ptr, png_ptr->hist);
+ png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
+#endif
+#endif
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (png_ptr->gamma_16_table != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_table[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_table);
+ }
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ if (png_ptr->gamma_16_from_1 != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_from_1);
+ }
+ if (png_ptr->gamma_16_to_1 != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_to_1);
+ }
+#endif
+#endif
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+ png_free(png_ptr, png_ptr->time_buffer);
+#endif
+
+ inflateEnd(&png_ptr->zstream);
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ png_free(png_ptr, png_ptr->save_buffer);
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+#ifdef PNG_TEXT_SUPPORTED
+ png_free(png_ptr, png_ptr->current_text);
+#endif /* PNG_TEXT_SUPPORTED */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+ /* Save the important info out of the png_struct, in case it is
+ * being used again.
+ */
+#ifdef PNG_SETJMP_SUPPORTED
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
+#endif
+
+ error_fn = png_ptr->error_fn;
+ warning_fn = png_ptr->warning_fn;
+ error_ptr = png_ptr->error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+#endif
+
+ png_memset(png_ptr, 0, png_sizeof(png_struct));
+
+ png_ptr->error_fn = error_fn;
+ png_ptr->warning_fn = warning_fn;
+ png_ptr->error_ptr = error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr->free_fn = free_fn;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
+#endif
+
+}
+
+void PNGAPI
+png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
+{
+ if (png_ptr == NULL)
+ return;
+ png_ptr->read_row_fn = read_row_fn;
+}
+
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_read_png(png_structp png_ptr, png_infop info_ptr,
+ int transforms,
+ voidp params)
+{
+ int row;
+
+ if (png_ptr == NULL)
+ return;
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ /* Invert the alpha channel from opacity to transparency
+ */
+ if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+ png_set_invert_alpha(png_ptr);
+#endif
+
+ /* png_read_info() gives us all of the information from the
+ * PNG file before the first IDAT (image data chunk).
+ */
+ png_read_info(png_ptr, info_ptr);
+ if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
+ png_error(png_ptr, "Image is too high to process with png_read_png()");
+
+ /* -------------- image transformations start here ------------------- */
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+ /* Tell libpng to strip 16 bit/color files down to 8 bits per color.
+ */
+ if (transforms & PNG_TRANSFORM_STRIP_16)
+ png_set_strip_16(png_ptr);
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ /* Strip alpha bytes from the input data without combining with
+ * the background (not recommended).
+ */
+ if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
+ png_set_strip_alpha(png_ptr);
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
+ /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
+ * byte into separate bytes (useful for paletted and grayscale images).
+ */
+ if (transforms & PNG_TRANSFORM_PACKING)
+ png_set_packing(png_ptr);
+#endif
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ /* Change the order of packed pixels to least significant bit first
+ * (not useful if you are using png_set_packing).
+ */
+ if (transforms & PNG_TRANSFORM_PACKSWAP)
+ png_set_packswap(png_ptr);
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ /* Expand paletted colors into true RGB triplets
+ * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
+ * Expand paletted or RGB images with transparency to full alpha
+ * channels so the data will be available as RGBA quartets.
+ */
+ if (transforms & PNG_TRANSFORM_EXPAND)
+ if ((png_ptr->bit_depth < 8) ||
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
+ (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
+ png_set_expand(png_ptr);
+#endif
+
+ /* We don't handle background color or gamma transformation or dithering.
+ */
+
+#ifdef PNG_READ_INVERT_SUPPORTED
+ /* Invert monochrome files to have 0 as white and 1 as black
+ */
+ if (transforms & PNG_TRANSFORM_INVERT_MONO)
+ png_set_invert_mono(png_ptr);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ /* If you want to shift the pixel values from the range [0,255] or
+ * [0,65535] to the original [0,7] or [0,31], or whatever range the
+ * colors were originally in:
+ */
+ if ((transforms & PNG_TRANSFORM_SHIFT)
+ && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+ {
+ png_color_8p sig_bit;
+
+ png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+ png_set_shift(png_ptr, sig_bit);
+ }
+#endif
+
+#ifdef PNG_READ_BGR_SUPPORTED
+ /* Flip the RGB pixels to BGR (or RGBA to BGRA)
+ */
+ if (transforms & PNG_TRANSFORM_BGR)
+ png_set_bgr(png_ptr);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+ /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
+ */
+ if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+ png_set_swap_alpha(png_ptr);
+#endif
+
+#ifdef PNG_READ_SWAP_SUPPORTED
+ /* Swap bytes of 16 bit files to least significant byte first
+ */
+ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+ png_set_swap(png_ptr);
+#endif
+
+/* Added at libpng-1.2.41 */
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ /* Invert the alpha channel from opacity to transparency
+ */
+ if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+ png_set_invert_alpha(png_ptr);
+#endif
+
+/* Added at libpng-1.2.41 */
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* Expand grayscale image to RGB
+ */
+ if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
+ png_set_gray_to_rgb(png_ptr);
+#endif
+
+ /* We don't handle adding filler bytes */
+
+ /* Optional call to gamma correct and add the background to the palette
+ * and update info structure. REQUIRED if you are expecting libpng to
+ * update the palette for you (i.e., you selected such a transform above).
+ */
+ png_read_update_info(png_ptr, info_ptr);
+
+ /* -------------- image transformations end here ------------------- */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+#endif
+ if (info_ptr->row_pointers == NULL)
+ {
+ info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
+ info_ptr->height * png_sizeof(png_bytep));
+ png_memset(info_ptr->row_pointers, 0, info_ptr->height
+ * png_sizeof(png_bytep));
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_ROWS;
+#endif
+
+ for (row = 0; row < (int)info_ptr->height; row++)
+ info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
+ png_get_rowbytes(png_ptr, info_ptr));
+ }
+
+ png_read_image(png_ptr, info_ptr->row_pointers);
+ info_ptr->valid |= PNG_INFO_IDAT;
+
+ /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
+ png_read_end(png_ptr, info_ptr);
+
+ transforms = transforms; /* Quiet compiler warnings */
+ params = params;
+
+}
+#endif /* PNG_INFO_IMAGE_SUPPORTED */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
diff --git a/src/libpng/pngrio.c b/src/libpng/pngrio.c
new file mode 100644
index 0000000..6978682
--- /dev/null
+++ b/src/libpng/pngrio.c
@@ -0,0 +1,180 @@
+
+/* pngrio.c - functions for data input
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all input. Users who need
+ * special handling are expected to write a function that has the same
+ * arguments as this and performs a similar function, but that possibly
+ * has a different input method. Note that you shouldn't change this
+ * function, but rather write a replacement function and then make
+ * libpng use it at run time with png_set_read_fn(...).
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_READ_SUPPORTED
+
+/* Read the data from whatever input you are using. The default routine
+ * reads from a file pointer. Note that this routine sometimes gets called
+ * with very small lengths, so you should implement some kind of simple
+ * buffering if you are using unbuffered reads. This should never be asked
+ * to read more then 64K on a 16 bit machine.
+ */
+void /* PRIVATE */
+png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_debug1(4, "reading %d bytes", (int)length);
+
+ if (png_ptr->read_data_fn != NULL)
+ (*(png_ptr->read_data_fn))(png_ptr, data, length);
+ else
+ png_error(png_ptr, "Call to NULL read function");
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+/* This is the function that does the actual reading of data. If you are
+ * not reading from a standard C stream, you should create a replacement
+ * read_data function and use it at run time with png_set_read_fn(), rather
+ * than changing the library.
+ */
+#ifndef USE_FAR_KEYWORD
+void PNGAPI
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_size_t check;
+
+ if (png_ptr == NULL)
+ return;
+ /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+ * instead of an int, which is what fread() actually returns.
+ */
+#ifdef _WIN32_WCE
+ if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+ check = 0;
+#else
+ check = (png_size_t)fread(data, (png_size_t)1, length,
+ (png_FILE_p)png_ptr->io_ptr);
+#endif
+
+ if (check != length)
+ png_error(png_ptr, "Read Error");
+}
+#else
+/* This is the model-independent version. Since the standard I/O library
+ can't handle far buffers in the medium and small models, we have to copy
+ the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void PNGAPI
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ int check;
+ png_byte *n_data;
+ png_FILE_p io_ptr;
+
+ if (png_ptr == NULL)
+ return;
+ /* Check if data really is near. If so, use usual code. */
+ n_data = (png_byte *)CVT_PTR_NOCHECK(data);
+ io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+ if ((png_bytep)n_data == data)
+ {
+#ifdef _WIN32_WCE
+ if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check,
+ NULL) )
+ check = 0;
+#else
+ check = fread(n_data, 1, length, io_ptr);
+#endif
+ }
+ else
+ {
+ png_byte buf[NEAR_BUF_SIZE];
+ png_size_t read, remaining, err;
+ check = 0;
+ remaining = length;
+ do
+ {
+ read = MIN(NEAR_BUF_SIZE, remaining);
+#ifdef _WIN32_WCE
+ if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
+ err = 0;
+#else
+ err = fread(buf, (png_size_t)1, read, io_ptr);
+#endif
+ png_memcpy(data, buf, read); /* copy far buffer to near buffer */
+ if (err != read)
+ break;
+ else
+ check += err;
+ data += read;
+ remaining -= read;
+ }
+ while (remaining != 0);
+ }
+ if ((png_uint_32)check != (png_uint_32)length)
+ png_error(png_ptr, "read Error");
+}
+#endif
+#endif
+
+/* This function allows the application to supply a new input function
+ * for libpng if standard C streams aren't being used.
+ *
+ * This function takes as its arguments:
+ * png_ptr - pointer to a png input data structure
+ * io_ptr - pointer to user supplied structure containing info about
+ * the input functions. May be NULL.
+ * read_data_fn - pointer to a new input function that takes as its
+ * arguments a pointer to a png_struct, a pointer to
+ * a location where input data can be stored, and a 32-bit
+ * unsigned int that is the number of bytes to be read.
+ * To exit and output any fatal error messages the new write
+ * function should call png_error(png_ptr, "Error msg").
+ * May be NULL, in which case libpng's default function will
+ * be used.
+ */
+void PNGAPI
+png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
+ png_rw_ptr read_data_fn)
+{
+ if (png_ptr == NULL)
+ return;
+ png_ptr->io_ptr = io_ptr;
+
+#ifdef PNG_STDIO_SUPPORTED
+ if (read_data_fn != NULL)
+ png_ptr->read_data_fn = read_data_fn;
+ else
+ png_ptr->read_data_fn = png_default_read_data;
+#else
+ png_ptr->read_data_fn = read_data_fn;
+#endif
+
+ /* It is an error to write to a read device */
+ if (png_ptr->write_data_fn != NULL)
+ {
+ png_ptr->write_data_fn = NULL;
+ png_warning(png_ptr,
+ "It's an error to set both read_data_fn and write_data_fn in the ");
+ png_warning(png_ptr,
+ "same structure. Resetting write_data_fn to NULL.");
+ }
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+ png_ptr->output_flush_fn = NULL;
+#endif
+}
+#endif /* PNG_READ_SUPPORTED */
diff --git a/src/libpng/pngrtran.c b/src/libpng/pngrtran.c
new file mode 100644
index 0000000..33703d4
--- /dev/null
+++ b/src/libpng/pngrtran.c
@@ -0,0 +1,4467 @@
+
+/* pngrtran.c - transforms the data in a row for PNG readers
+ *
+ * Last changed in libpng 1.2.45 [July 7, 2011]
+ * Copyright (c) 1998-2011 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains functions optionally called by an application
+ * in order to tell libpng how to handle data when reading a PNG.
+ * Transformations that are used in both reading and writing are
+ * in pngtrans.c.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_READ_SUPPORTED
+
+/* Set the action on getting a CRC error for an ancillary or critical chunk. */
+void PNGAPI
+png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
+{
+ png_debug(1, "in png_set_crc_action");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* Tell libpng how we react to CRC errors in critical chunks */
+ switch (crit_action)
+ {
+ case PNG_CRC_NO_CHANGE: /* Leave setting as is */
+ break;
+
+ case PNG_CRC_WARN_USE: /* Warn/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
+ break;
+
+ case PNG_CRC_QUIET_USE: /* Quiet/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
+ PNG_FLAG_CRC_CRITICAL_IGNORE;
+ break;
+
+ case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */
+ png_warning(png_ptr,
+ "Can't discard critical data on CRC error.");
+ case PNG_CRC_ERROR_QUIT: /* Error/quit */
+
+ case PNG_CRC_DEFAULT:
+ default:
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ break;
+ }
+
+ /* Tell libpng how we react to CRC errors in ancillary chunks */
+ switch (ancil_action)
+ {
+ case PNG_CRC_NO_CHANGE: /* Leave setting as is */
+ break;
+
+ case PNG_CRC_WARN_USE: /* Warn/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
+ break;
+
+ case PNG_CRC_QUIET_USE: /* Quiet/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
+ PNG_FLAG_CRC_ANCILLARY_NOWARN;
+ break;
+
+ case PNG_CRC_ERROR_QUIT: /* Error/quit */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
+ break;
+
+ case PNG_CRC_WARN_DISCARD: /* Warn/discard data */
+
+ case PNG_CRC_DEFAULT:
+ default:
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ break;
+ }
+}
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+ defined(PNG_FLOATING_POINT_SUPPORTED)
+/* Handle alpha and tRNS via a background color */
+void PNGAPI
+png_set_background(png_structp png_ptr,
+ png_color_16p background_color, int background_gamma_code,
+ int need_expand, double background_gamma)
+{
+ png_debug(1, "in png_set_background");
+
+ if (png_ptr == NULL)
+ return;
+ if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
+ {
+ png_warning(png_ptr, "Application must supply a known background gamma");
+ return;
+ }
+
+ png_ptr->transformations |= PNG_BACKGROUND;
+ png_memcpy(&(png_ptr->background), background_color,
+ png_sizeof(png_color_16));
+ png_ptr->background_gamma = (float)background_gamma;
+ png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
+ png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
+}
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+/* Strip 16 bit depth files to 8 bit depth */
+void PNGAPI
+png_set_strip_16(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_strip_16");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->transformations |= PNG_16_TO_8;
+}
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+void PNGAPI
+png_set_strip_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_strip_alpha");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
+}
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+/* Dither file to 8 bit. Supply a palette, the current number
+ * of elements in the palette, the maximum number of elements
+ * allowed, and a histogram if possible. If the current number
+ * of colors is greater then the maximum number, the palette will be
+ * modified to fit in the maximum number. "full_dither" indicates
+ * whether we need a dithering cube set up for RGB images, or if we
+ * simply are reducing the number of colors in a paletted image.
+ */
+
+typedef struct png_dsort_struct
+{
+ struct png_dsort_struct FAR * next;
+ png_byte left;
+ png_byte right;
+} png_dsort;
+typedef png_dsort FAR * png_dsortp;
+typedef png_dsort FAR * FAR * png_dsortpp;
+
+void PNGAPI
+png_set_dither(png_structp png_ptr, png_colorp palette,
+ int num_palette, int maximum_colors, png_uint_16p histogram,
+ int full_dither)
+{
+ png_debug(1, "in png_set_dither");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->transformations |= PNG_DITHER;
+
+ if (!full_dither)
+ {
+ int i;
+
+ png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * png_sizeof(png_byte)));
+ for (i = 0; i < num_palette; i++)
+ png_ptr->dither_index[i] = (png_byte)i;
+ }
+
+ if (num_palette > maximum_colors)
+ {
+ if (histogram != NULL)
+ {
+ /* This is easy enough, just throw out the least used colors.
+ * Perhaps not the best solution, but good enough.
+ */
+
+ int i;
+
+ /* Initialize an array to sort colors */
+ png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * png_sizeof(png_byte)));
+
+ /* Initialize the dither_sort array */
+ for (i = 0; i < num_palette; i++)
+ png_ptr->dither_sort[i] = (png_byte)i;
+
+ /* Find the least used palette entries by starting a
+ * bubble sort, and running it until we have sorted
+ * out enough colors. Note that we don't care about
+ * sorting all the colors, just finding which are
+ * least used.
+ */
+
+ for (i = num_palette - 1; i >= maximum_colors; i--)
+ {
+ int done; /* To stop early if the list is pre-sorted */
+ int j;
+
+ done = 1;
+ for (j = 0; j < i; j++)
+ {
+ if (histogram[png_ptr->dither_sort[j]]
+ < histogram[png_ptr->dither_sort[j + 1]])
+ {
+ png_byte t;
+
+ t = png_ptr->dither_sort[j];
+ png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
+ png_ptr->dither_sort[j + 1] = t;
+ done = 0;
+ }
+ }
+ if (done)
+ break;
+ }
+
+ /* Swap the palette around, and set up a table, if necessary */
+ if (full_dither)
+ {
+ int j = num_palette;
+
+ /* Put all the useful colors within the max, but don't
+ * move the others.
+ */
+ for (i = 0; i < maximum_colors; i++)
+ {
+ if ((int)png_ptr->dither_sort[i] >= maximum_colors)
+ {
+ do
+ j--;
+ while ((int)png_ptr->dither_sort[j] >= maximum_colors);
+ palette[i] = palette[j];
+ }
+ }
+ }
+ else
+ {
+ int j = num_palette;
+
+ /* Move all the used colors inside the max limit, and
+ * develop a translation table.
+ */
+ for (i = 0; i < maximum_colors; i++)
+ {
+ /* Only move the colors we need to */
+ if ((int)png_ptr->dither_sort[i] >= maximum_colors)
+ {
+ png_color tmp_color;
+
+ do
+ j--;
+ while ((int)png_ptr->dither_sort[j] >= maximum_colors);
+
+ tmp_color = palette[j];
+ palette[j] = palette[i];
+ palette[i] = tmp_color;
+ /* Indicate where the color went */
+ png_ptr->dither_index[j] = (png_byte)i;
+ png_ptr->dither_index[i] = (png_byte)j;
+ }
+ }
+
+ /* Find closest color for those colors we are not using */
+ for (i = 0; i < num_palette; i++)
+ {
+ if ((int)png_ptr->dither_index[i] >= maximum_colors)
+ {
+ int min_d, k, min_k, d_index;
+
+ /* Find the closest color to one we threw out */
+ d_index = png_ptr->dither_index[i];
+ min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
+ for (k = 1, min_k = 0; k < maximum_colors; k++)
+ {
+ int d;
+
+ d = PNG_COLOR_DIST(palette[d_index], palette[k]);
+
+ if (d < min_d)
+ {
+ min_d = d;
+ min_k = k;
+ }
+ }
+ /* Point to closest color */
+ png_ptr->dither_index[i] = (png_byte)min_k;
+ }
+ }
+ }
+ png_free(png_ptr, png_ptr->dither_sort);
+ png_ptr->dither_sort = NULL;
+ }
+ else
+ {
+ /* This is much harder to do simply (and quickly). Perhaps
+ * we need to go through a median cut routine, but those
+ * don't always behave themselves with only a few colors
+ * as input. So we will just find the closest two colors,
+ * and throw out one of them (chosen somewhat randomly).
+ * [We don't understand this at all, so if someone wants to
+ * work on improving it, be our guest - AED, GRP]
+ */
+ int i;
+ int max_d;
+ int num_new_palette;
+ png_dsortp t;
+ png_dsortpp hash;
+
+ t = NULL;
+
+ /* Initialize palette index arrays */
+ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * png_sizeof(png_byte)));
+ png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * png_sizeof(png_byte)));
+
+ /* Initialize the sort array */
+ for (i = 0; i < num_palette; i++)
+ {
+ png_ptr->index_to_palette[i] = (png_byte)i;
+ png_ptr->palette_to_index[i] = (png_byte)i;
+ }
+
+ hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
+ png_sizeof(png_dsortp)));
+
+ num_new_palette = num_palette;
+
+ /* Initial wild guess at how far apart the farthest pixel
+ * pair we will be eliminating will be. Larger
+ * numbers mean more areas will be allocated, Smaller
+ * numbers run the risk of not saving enough data, and
+ * having to do this all over again.
+ *
+ * I have not done extensive checking on this number.
+ */
+ max_d = 96;
+
+ while (num_new_palette > maximum_colors)
+ {
+ for (i = 0; i < num_new_palette - 1; i++)
+ {
+ int j;
+
+ for (j = i + 1; j < num_new_palette; j++)
+ {
+ int d;
+
+ d = PNG_COLOR_DIST(palette[i], palette[j]);
+
+ if (d <= max_d)
+ {
+
+ t = (png_dsortp)png_malloc_warn(png_ptr,
+ (png_uint_32)(png_sizeof(png_dsort)));
+ if (t == NULL)
+ break;
+ t->next = hash[d];
+ t->left = (png_byte)i;
+ t->right = (png_byte)j;
+ hash[d] = t;
+ }
+ }
+ if (t == NULL)
+ break;
+ }
+
+ if (t != NULL)
+ for (i = 0; i <= max_d; i++)
+ {
+ if (hash[i] != NULL)
+ {
+ png_dsortp p;
+
+ for (p = hash[i]; p; p = p->next)
+ {
+ if ((int)png_ptr->index_to_palette[p->left]
+ < num_new_palette &&
+ (int)png_ptr->index_to_palette[p->right]
+ < num_new_palette)
+ {
+ int j, next_j;
+
+ if (num_new_palette & 0x01)
+ {
+ j = p->left;
+ next_j = p->right;
+ }
+ else
+ {
+ j = p->right;
+ next_j = p->left;
+ }
+
+ num_new_palette--;
+ palette[png_ptr->index_to_palette[j]]
+ = palette[num_new_palette];
+ if (!full_dither)
+ {
+ int k;
+
+ for (k = 0; k < num_palette; k++)
+ {
+ if (png_ptr->dither_index[k] ==
+ png_ptr->index_to_palette[j])
+ png_ptr->dither_index[k] =
+ png_ptr->index_to_palette[next_j];
+ if ((int)png_ptr->dither_index[k] ==
+ num_new_palette)
+ png_ptr->dither_index[k] =
+ png_ptr->index_to_palette[j];
+ }
+ }
+
+ png_ptr->index_to_palette[png_ptr->palette_to_index
+ [num_new_palette]] = png_ptr->index_to_palette[j];
+ png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
+ = png_ptr->palette_to_index[num_new_palette];
+
+ png_ptr->index_to_palette[j] =
+ (png_byte)num_new_palette;
+ png_ptr->palette_to_index[num_new_palette] =
+ (png_byte)j;
+ }
+ if (num_new_palette <= maximum_colors)
+ break;
+ }
+ if (num_new_palette <= maximum_colors)
+ break;
+ }
+ }
+
+ for (i = 0; i < 769; i++)
+ {
+ if (hash[i] != NULL)
+ {
+ png_dsortp p = hash[i];
+ while (p)
+ {
+ t = p->next;
+ png_free(png_ptr, p);
+ p = t;
+ }
+ }
+ hash[i] = 0;
+ }
+ max_d += 96;
+ }
+ png_free(png_ptr, hash);
+ png_free(png_ptr, png_ptr->palette_to_index);
+ png_free(png_ptr, png_ptr->index_to_palette);
+ png_ptr->palette_to_index = NULL;
+ png_ptr->index_to_palette = NULL;
+ }
+ num_palette = maximum_colors;
+ }
+ if (png_ptr->palette == NULL)
+ {
+ png_ptr->palette = palette;
+ }
+ png_ptr->num_palette = (png_uint_16)num_palette;
+
+ if (full_dither)
+ {
+ int i;
+ png_bytep distance;
+ int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
+ PNG_DITHER_BLUE_BITS;
+ int num_red = (1 << PNG_DITHER_RED_BITS);
+ int num_green = (1 << PNG_DITHER_GREEN_BITS);
+ int num_blue = (1 << PNG_DITHER_BLUE_BITS);
+ png_size_t num_entries = ((png_size_t)1 << total_bits);
+
+ png_ptr->palette_lookup = (png_bytep )png_calloc(png_ptr,
+ (png_uint_32)(num_entries * png_sizeof(png_byte)));
+
+ distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+ png_sizeof(png_byte)));
+ png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
+
+ for (i = 0; i < num_palette; i++)
+ {
+ int ir, ig, ib;
+ int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
+ int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
+ int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
+
+ for (ir = 0; ir < num_red; ir++)
+ {
+ /* int dr = abs(ir - r); */
+ int dr = ((ir > r) ? ir - r : r - ir);
+ int index_r = (ir << (PNG_DITHER_BLUE_BITS +
+ PNG_DITHER_GREEN_BITS));
+
+ for (ig = 0; ig < num_green; ig++)
+ {
+ /* int dg = abs(ig - g); */
+ int dg = ((ig > g) ? ig - g : g - ig);
+ int dt = dr + dg;
+ int dm = ((dr > dg) ? dr : dg);
+ int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
+
+ for (ib = 0; ib < num_blue; ib++)
+ {
+ int d_index = index_g | ib;
+ /* int db = abs(ib - b); */
+ int db = ((ib > b) ? ib - b : b - ib);
+ int dmax = ((dm > db) ? dm : db);
+ int d = dmax + dt + db;
+
+ if (d < (int)distance[d_index])
+ {
+ distance[d_index] = (png_byte)d;
+ png_ptr->palette_lookup[d_index] = (png_byte)i;
+ }
+ }
+ }
+ }
+ }
+
+ png_free(png_ptr, distance);
+ }
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+/* Transform the image from the file_gamma to the screen_gamma. We
+ * only do transformations on images where the file_gamma and screen_gamma
+ * are not close reciprocals, otherwise it slows things down slightly, and
+ * also needlessly introduces small errors.
+ *
+ * We will turn off gamma transformation later if no semitransparent entries
+ * are present in the tRNS array for palette images. We can't do it here
+ * because we don't necessarily have the tRNS chunk yet.
+ */
+void PNGAPI
+png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
+{
+ png_debug(1, "in png_set_gamma");
+
+ if (png_ptr == NULL)
+ return;
+
+ if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
+ png_ptr->transformations |= PNG_GAMMA;
+ png_ptr->gamma = (float)file_gamma;
+ png_ptr->screen_gamma = (float)scrn_gamma;
+}
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expand paletted images to RGB, expand grayscale images of
+ * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
+ * to alpha channels.
+ */
+void PNGAPI
+png_set_expand(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_expand");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+ png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
+}
+
+/* GRR 19990627: the following three functions currently are identical
+ * to png_set_expand(). However, it is entirely reasonable that someone
+ * might wish to expand an indexed image to RGB but *not* expand a single,
+ * fully transparent palette entry to a full alpha channel--perhaps instead
+ * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
+ * the transparent color with a particular RGB value, or drop tRNS entirely.
+ * IOW, a future version of the library may make the transformations flag
+ * a bit more fine-grained, with separate bits for each of these three
+ * functions.
+ *
+ * More to the point, these functions make it obvious what libpng will be
+ * doing, whereas "expand" can (and does) mean any number of things.
+ *
+ * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
+ * to expand only the sample depth but not to expand the tRNS to alpha
+ * and its name was changed to png_set_expand_gray_1_2_4_to_8().
+ */
+
+/* Expand paletted images to RGB. */
+void PNGAPI
+png_set_palette_to_rgb(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_palette_to_rgb");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+ png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
+}
+
+#ifndef PNG_1_0_X
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+void PNGAPI
+png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_EXPAND;
+ png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
+}
+#endif
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+/* Deprecated as of libpng-1.2.9 */
+void PNGAPI
+png_set_gray_1_2_4_to_8(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_gray_1_2_4_to_8");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+#endif
+
+
+/* Expand tRNS chunks to alpha channels. */
+void PNGAPI
+png_set_tRNS_to_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_tRNS_to_alpha");
+
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+ png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
+}
+#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+void PNGAPI
+png_set_gray_to_rgb(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_gray_to_rgb");
+
+ png_ptr->transformations |= PNG_GRAY_TO_RGB;
+ png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+/* Convert a RGB image to a grayscale of the same width. This allows us,
+ * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
+ */
+
+void PNGAPI
+png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
+ double green)
+{
+ int red_fixed, green_fixed;
+ if (png_ptr == NULL)
+ return;
+ if (red > 21474.83647 || red < -21474.83648 ||
+ green > 21474.83647 || green < -21474.83648)
+ {
+ png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
+ red_fixed = -1;
+ green_fixed = -1;
+ }
+ else
+ {
+ red_fixed = (int)((float)red*100000.0 + 0.5);
+ green_fixed = (int)((float)green*100000.0 + 0.5);
+ }
+ png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
+}
+#endif
+
+void PNGAPI
+png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
+ png_fixed_point red, png_fixed_point green)
+{
+ png_debug(1, "in png_set_rgb_to_gray");
+
+ if (png_ptr == NULL)
+ return;
+
+ switch(error_action)
+ {
+ case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
+ break;
+
+ case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
+ break;
+
+ case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
+ }
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ png_ptr->transformations |= PNG_EXPAND;
+#else
+ {
+ png_warning(png_ptr,
+ "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
+ png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
+ }
+#endif
+ {
+ png_uint_16 red_int, green_int;
+ if (red < 0 || green < 0)
+ {
+ red_int = 6968; /* .212671 * 32768 + .5 */
+ green_int = 23434; /* .715160 * 32768 + .5 */
+ }
+ else if (red + green < 100000L)
+ {
+ red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
+ green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
+ }
+ else
+ {
+ png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
+ red_int = 6968;
+ green_int = 23434;
+ }
+ png_ptr->rgb_to_gray_red_coeff = red_int;
+ png_ptr->rgb_to_gray_green_coeff = green_int;
+ png_ptr->rgb_to_gray_blue_coeff =
+ (png_uint_16)(32768 - red_int - green_int);
+ }
+}
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void PNGAPI
+png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+ read_user_transform_fn)
+{
+ png_debug(1, "in png_set_read_user_transform_fn");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ png_ptr->transformations |= PNG_USER_TRANSFORM;
+ png_ptr->read_user_transform_fn = read_user_transform_fn;
+#endif
+#ifdef PNG_LEGACY_SUPPORTED
+ if (read_user_transform_fn)
+ png_warning(png_ptr,
+ "This version of libpng does not support user transforms");
+#endif
+}
+#endif
+
+/* Initialize everything needed for the read. This includes modifying
+ * the palette.
+ */
+void /* PRIVATE */
+png_init_read_transformations(png_structp png_ptr)
+{
+ png_debug(1, "in png_init_read_transformations");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (png_ptr != NULL)
+#endif
+ {
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_SHIFT_SUPPORTED) || \
+ defined(PNG_READ_GAMMA_SUPPORTED)
+ int color_type = png_ptr->color_type;
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* Detect gray background and attempt to enable optimization
+ * for gray --> RGB case
+ *
+ * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
+ * RGB_ALPHA (in which case need_expand is superfluous anyway), the
+ * background color might actually be gray yet not be flagged as such.
+ * This is not a problem for the current code, which uses
+ * PNG_BACKGROUND_IS_GRAY only to decide when to do the
+ * png_do_gray_to_rgb() transformation.
+ */
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ !(color_type & PNG_COLOR_MASK_COLOR))
+ {
+ png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+ } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
+ !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ png_ptr->background.red == png_ptr->background.green &&
+ png_ptr->background.red == png_ptr->background.blue)
+ {
+ png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+ png_ptr->background.gray = png_ptr->background.red;
+ }
+#endif
+
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ (png_ptr->transformations & PNG_EXPAND))
+ {
+ if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */
+ {
+ /* Expand background and tRNS chunks */
+ switch (png_ptr->bit_depth)
+ {
+ case 1:
+ png_ptr->background.gray *= (png_uint_16)0xff;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+ {
+ png_ptr->trans_values.gray *= (png_uint_16)0xff;
+ png_ptr->trans_values.red = png_ptr->trans_values.green
+ = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
+ }
+ break;
+
+ case 2:
+ png_ptr->background.gray *= (png_uint_16)0x55;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+ {
+ png_ptr->trans_values.gray *= (png_uint_16)0x55;
+ png_ptr->trans_values.red = png_ptr->trans_values.green
+ = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
+ }
+ break;
+
+ case 4:
+ png_ptr->background.gray *= (png_uint_16)0x11;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+ {
+ png_ptr->trans_values.gray *= (png_uint_16)0x11;
+ png_ptr->trans_values.red = png_ptr->trans_values.green
+ = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
+ }
+ break;
+
+ case 8:
+
+ case 16:
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ break;
+ }
+ }
+ else if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_ptr->background.red =
+ png_ptr->palette[png_ptr->background.index].red;
+ png_ptr->background.green =
+ png_ptr->palette[png_ptr->background.index].green;
+ png_ptr->background.blue =
+ png_ptr->palette[png_ptr->background.index].blue;
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ {
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+#endif
+ {
+ /* Invert the alpha channel (in tRNS) unless the pixels are
+ * going to be expanded, in which case leave it for later
+ */
+ int i, istop;
+ istop=(int)png_ptr->num_trans;
+ for (i=0; i<istop; i++)
+ png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
+ }
+ }
+#endif
+
+ }
+ }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+ png_ptr->background_1 = png_ptr->background;
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+
+ if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
+ && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
+ < PNG_GAMMA_THRESHOLD))
+ {
+ int i, k;
+ k=0;
+ for (i=0; i<png_ptr->num_trans; i++)
+ {
+ if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
+ k=1; /* Partial transparency is present */
+ }
+ if (k == 0)
+ png_ptr->transformations &= ~PNG_GAMMA;
+ }
+
+ if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
+ png_ptr->gamma != 0.0)
+ {
+ png_build_gamma_table(png_ptr);
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ if (png_ptr->transformations & PNG_BACKGROUND)
+ {
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ /* Could skip if no transparency */
+ png_color back, back_1;
+ png_colorp palette = png_ptr->palette;
+ int num_palette = png_ptr->num_palette;
+ int i;
+ if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+ {
+ back.red = png_ptr->gamma_table[png_ptr->background.red];
+ back.green = png_ptr->gamma_table[png_ptr->background.green];
+ back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+ back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+ back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+ back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+ }
+ else
+ {
+ double g, gs;
+
+ switch (png_ptr->background_gamma_type)
+ {
+ case PNG_BACKGROUND_GAMMA_SCREEN:
+ g = (png_ptr->screen_gamma);
+ gs = 1.0;
+ break;
+
+ case PNG_BACKGROUND_GAMMA_FILE:
+ g = 1.0 / (png_ptr->gamma);
+ gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+ break;
+
+ case PNG_BACKGROUND_GAMMA_UNIQUE:
+ g = 1.0 / (png_ptr->background_gamma);
+ gs = 1.0 / (png_ptr->background_gamma *
+ png_ptr->screen_gamma);
+ break;
+ default:
+ g = 1.0; /* back_1 */
+ gs = 1.0; /* back */
+ }
+
+ if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
+ {
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+ }
+ else
+ {
+ back.red = (png_byte)(pow(
+ (double)png_ptr->background.red/255, gs) * 255.0 + .5);
+ back.green = (png_byte)(pow(
+ (double)png_ptr->background.green/255, gs) * 255.0
+ + .5);
+ back.blue = (png_byte)(pow(
+ (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
+ }
+
+ back_1.red = (png_byte)(pow(
+ (double)png_ptr->background.red/255, g) * 255.0 + .5);
+ back_1.green = (png_byte)(pow(
+ (double)png_ptr->background.green/255, g) * 255.0 + .5);
+ back_1.blue = (png_byte)(pow(
+ (double)png_ptr->background.blue/255, g) * 255.0 + .5);
+ }
+ for (i = 0; i < num_palette; i++)
+ {
+ if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+ {
+ if (png_ptr->trans[i] == 0)
+ {
+ palette[i] = back;
+ }
+ else /* if (png_ptr->trans[i] != 0xff) */
+ {
+ png_byte v, w;
+
+ v = png_ptr->gamma_to_1[palette[i].red];
+ png_composite(w, v, png_ptr->trans[i], back_1.red);
+ palette[i].red = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[palette[i].green];
+ png_composite(w, v, png_ptr->trans[i], back_1.green);
+ palette[i].green = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[palette[i].blue];
+ png_composite(w, v, png_ptr->trans[i], back_1.blue);
+ palette[i].blue = png_ptr->gamma_from_1[w];
+ }
+ }
+ else
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+ /* Prevent the transformations being done again, and make sure
+ * that the now spurious alpha channel is stripped - the code
+ * has just reduced background composition and gamma correction
+ * to a simple alpha channel strip.
+ */
+ png_ptr->transformations &= ~PNG_BACKGROUND;
+ png_ptr->transformations &= ~PNG_GAMMA;
+ png_ptr->transformations |= PNG_STRIP_ALPHA;
+ }
+ /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
+ else
+ /* color_type != PNG_COLOR_TYPE_PALETTE */
+ {
+ double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
+ double g = 1.0;
+ double gs = 1.0;
+
+ switch (png_ptr->background_gamma_type)
+ {
+ case PNG_BACKGROUND_GAMMA_SCREEN:
+ g = (png_ptr->screen_gamma);
+ gs = 1.0;
+ break;
+
+ case PNG_BACKGROUND_GAMMA_FILE:
+ g = 1.0 / (png_ptr->gamma);
+ gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+ break;
+
+ case PNG_BACKGROUND_GAMMA_UNIQUE:
+ g = 1.0 / (png_ptr->background_gamma);
+ gs = 1.0 / (png_ptr->background_gamma *
+ png_ptr->screen_gamma);
+ break;
+ }
+
+ png_ptr->background_1.gray = (png_uint_16)(pow(
+ (double)png_ptr->background.gray / m, g) * m + .5);
+ png_ptr->background.gray = (png_uint_16)(pow(
+ (double)png_ptr->background.gray / m, gs) * m + .5);
+
+ if ((png_ptr->background.red != png_ptr->background.green) ||
+ (png_ptr->background.red != png_ptr->background.blue) ||
+ (png_ptr->background.red != png_ptr->background.gray))
+ {
+ /* RGB or RGBA with color background */
+ png_ptr->background_1.red = (png_uint_16)(pow(
+ (double)png_ptr->background.red / m, g) * m + .5);
+ png_ptr->background_1.green = (png_uint_16)(pow(
+ (double)png_ptr->background.green / m, g) * m + .5);
+ png_ptr->background_1.blue = (png_uint_16)(pow(
+ (double)png_ptr->background.blue / m, g) * m + .5);
+ png_ptr->background.red = (png_uint_16)(pow(
+ (double)png_ptr->background.red / m, gs) * m + .5);
+ png_ptr->background.green = (png_uint_16)(pow(
+ (double)png_ptr->background.green / m, gs) * m + .5);
+ png_ptr->background.blue = (png_uint_16)(pow(
+ (double)png_ptr->background.blue / m, gs) * m + .5);
+ }
+ else
+ {
+ /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
+ png_ptr->background_1.red = png_ptr->background_1.green
+ = png_ptr->background_1.blue = png_ptr->background_1.gray;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ }
+ }
+ }
+ else
+ /* Transformation does not include PNG_BACKGROUND */
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_colorp palette = png_ptr->palette;
+ int num_palette = png_ptr->num_palette;
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+
+ /* Done the gamma correction. */
+ png_ptr->transformations &= ~PNG_GAMMA;
+ }
+ }
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ else
+#endif
+#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ /* No GAMMA transformation */
+ if ((png_ptr->transformations & PNG_BACKGROUND) &&
+ (color_type == PNG_COLOR_TYPE_PALETTE))
+ {
+ int i;
+ int istop = (int)png_ptr->num_trans;
+ png_color back;
+ png_colorp palette = png_ptr->palette;
+
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+
+ for (i = 0; i < istop; i++)
+ {
+ if (png_ptr->trans[i] == 0)
+ {
+ palette[i] = back;
+ }
+ else if (png_ptr->trans[i] != 0xff)
+ {
+ /* The png_composite() macro is defined in png.h */
+ png_composite(palette[i].red, palette[i].red,
+ png_ptr->trans[i], back.red);
+ png_composite(palette[i].green, palette[i].green,
+ png_ptr->trans[i], back.green);
+ png_composite(palette[i].blue, palette[i].blue,
+ png_ptr->trans[i], back.blue);
+ }
+ }
+
+ /* Handled alpha, still need to strip the channel. */
+ png_ptr->transformations &= ~PNG_BACKGROUND;
+ png_ptr->transformations |= PNG_STRIP_ALPHA;
+ }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ if ((png_ptr->transformations & PNG_SHIFT) &&
+ (color_type == PNG_COLOR_TYPE_PALETTE))
+ {
+ png_uint_16 i;
+ png_uint_16 istop = png_ptr->num_palette;
+ int sr = 8 - png_ptr->sig_bit.red;
+ int sg = 8 - png_ptr->sig_bit.green;
+ int sb = 8 - png_ptr->sig_bit.blue;
+
+ if (sr < 0 || sr > 8)
+ sr = 0;
+ if (sg < 0 || sg > 8)
+ sg = 0;
+ if (sb < 0 || sb > 8)
+ sb = 0;
+ for (i = 0; i < istop; i++)
+ {
+ png_ptr->palette[i].red >>= sr;
+ png_ptr->palette[i].green >>= sg;
+ png_ptr->palette[i].blue >>= sb;
+ }
+ }
+#endif /* PNG_READ_SHIFT_SUPPORTED */
+ }
+#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
+ && !defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr)
+ return;
+#endif
+}
+
+/* Modify the info structure to reflect the transformations. The
+ * info should be updated so a PNG file could be written with it,
+ * assuming the transformations result in valid PNG data.
+ */
+void /* PRIVATE */
+png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_read_transform_info");
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (png_ptr->num_trans)
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ else
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+ info_ptr->bit_depth = 8;
+ info_ptr->num_trans = 0;
+ }
+ else
+ {
+ if (png_ptr->num_trans)
+ {
+ if (png_ptr->transformations & PNG_EXPAND_tRNS)
+ info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+ }
+ if (info_ptr->bit_depth < 8)
+ info_ptr->bit_depth = 8;
+ info_ptr->num_trans = 0;
+ }
+ }
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ if (png_ptr->transformations & PNG_BACKGROUND)
+ {
+ info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+ info_ptr->num_trans = 0;
+ info_ptr->background = png_ptr->background;
+ }
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (png_ptr->transformations & PNG_GAMMA)
+ {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ info_ptr->gamma = png_ptr->gamma;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_gamma = png_ptr->int_gamma;
+#endif
+ }
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+ if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
+ info_ptr->bit_depth = 8;
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+ info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+ if (png_ptr->transformations & PNG_DITHER)
+ {
+ if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
+ png_ptr->palette_lookup && info_ptr->bit_depth == 8)
+ {
+ info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+ }
+ }
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
+ info_ptr->bit_depth = 8;
+#endif
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ info_ptr->channels = 1;
+ else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ info_ptr->channels = 3;
+ else
+ info_ptr->channels = 1;
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
+ info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+#endif
+
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+ info_ptr->channels++;
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+ /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
+ if ((png_ptr->transformations & PNG_FILLER) &&
+ ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
+ {
+ info_ptr->channels++;
+ /* If adding a true alpha channel not just filler */
+#ifndef PNG_1_0_X
+ if (png_ptr->transformations & PNG_ADD_ALPHA)
+ info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+#endif
+ }
+#endif
+
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
+defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ if (info_ptr->bit_depth < png_ptr->user_transform_depth)
+ info_ptr->bit_depth = png_ptr->user_transform_depth;
+ if (info_ptr->channels < png_ptr->user_transform_channels)
+ info_ptr->channels = png_ptr->user_transform_channels;
+ }
+#endif
+
+ info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
+ info_ptr->bit_depth);
+
+ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
+
+#ifndef PNG_READ_EXPAND_SUPPORTED
+ if (png_ptr)
+ return;
+#endif
+}
+
+/* Transform the row. The order of transformations is significant,
+ * and is very touchy. If you add a transformation, take care to
+ * decide how it fits in with the other transformations here.
+ */
+void /* PRIVATE */
+png_do_read_transformations(png_structp png_ptr)
+{
+ png_debug(1, "in png_do_read_transformations");
+
+ if (png_ptr->row_buf == NULL)
+ {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+ char msg[50];
+
+ png_snprintf2(msg, 50,
+ "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number,
+ png_ptr->pass);
+ png_error(png_ptr, msg);
+#else
+ png_error(png_ptr, "NULL row buffer");
+#endif
+ }
+#ifdef PNG_WARN_UNINITIALIZED_ROW
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ /* Application has failed to call either png_read_start_image()
+ * or png_read_update_info() after setting transforms that expand
+ * pixels. This check added to libpng-1.2.19
+ */
+#if (PNG_WARN_UNINITIALIZED_ROW==1)
+ png_error(png_ptr, "Uninitialized row");
+#else
+ png_warning(png_ptr, "Uninitialized row");
+#endif
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
+ }
+ else
+ {
+ if (png_ptr->num_trans &&
+ (png_ptr->transformations & PNG_EXPAND_tRNS))
+ png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->trans_values));
+ else
+ png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ NULL);
+ }
+ }
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
+ png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ {
+ int rgb_error =
+ png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info),
+ png_ptr->row_buf + 1);
+ if (rgb_error)
+ {
+ png_ptr->rgb_to_gray_status=1;
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+ PNG_RGB_TO_GRAY_WARN)
+ png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+ PNG_RGB_TO_GRAY_ERR)
+ png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+ }
+ }
+#endif
+
+/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
+ *
+ * In most cases, the "simple transparency" should be done prior to doing
+ * gray-to-RGB, or you will have to test 3x as many bytes to check if a
+ * pixel is transparent. You would also need to make sure that the
+ * transparency information is upgraded to RGB.
+ *
+ * To summarize, the current flow is:
+ * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
+ * with background "in place" if transparent,
+ * convert to RGB if necessary
+ * - Gray + alpha -> composite with gray background and remove alpha bytes,
+ * convert to RGB if necessary
+ *
+ * To support RGB backgrounds for gray images we need:
+ * - Gray + simple transparency -> convert to RGB + simple transparency,
+ * compare 3 or 6 bytes and composite with
+ * background "in place" if transparent
+ * (3x compare/pixel compared to doing
+ * composite with gray bkgrnd)
+ * - Gray + alpha -> convert to RGB + alpha, composite with background and
+ * remove alpha bytes (3x float
+ * operations/pixel compared with composite
+ * on gray background)
+ *
+ * Greg's change will do this. The reason it wasn't done before is for
+ * performance, as this increases the per-pixel operations. If we would check
+ * in advance if the background was gray or RGB, and position the gray-to-RGB
+ * transform appropriately, then it would save a lot of work/time.
+ */
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* If gray -> RGB, do so now only if background is non-gray; else do later
+ * for performance reasons
+ */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+ png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ if ((png_ptr->transformations & PNG_BACKGROUND) &&
+ ((png_ptr->num_trans != 0 ) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
+ png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->trans_values), &(png_ptr->background)
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ , &(png_ptr->background_1),
+ png_ptr->gamma_table, png_ptr->gamma_from_1,
+ png_ptr->gamma_to_1, png_ptr->gamma_16_table,
+ png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
+ png_ptr->gamma_shift
+#endif
+);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if ((png_ptr->transformations & PNG_GAMMA) &&
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ !((png_ptr->transformations & PNG_BACKGROUND) &&
+ ((png_ptr->num_trans != 0) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
+#endif
+ (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
+ png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->gamma_table, png_ptr->gamma_16_table,
+ png_ptr->gamma_shift);
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+ if (png_ptr->transformations & PNG_16_TO_8)
+ png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+ if (png_ptr->transformations & PNG_DITHER)
+ {
+ png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->palette_lookup, png_ptr->dither_index);
+ if (png_ptr->row_info.rowbytes == (png_uint_32)0)
+ png_error(png_ptr, "png_do_dither returned rowbytes=0");
+ }
+#endif
+
+#ifdef PNG_READ_INVERT_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+ if (png_ptr->transformations & PNG_PACK)
+ png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_BGR_SUPPORTED
+ if (png_ptr->transformations & PNG_BGR)
+ png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* If gray -> RGB, do so now only if we did not do so above */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+ png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+ if (png_ptr->transformations & PNG_FILLER)
+ png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->filler, png_ptr->flags);
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_ALPHA)
+ png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ if (png_ptr->read_user_transform_fn != NULL)
+ (*(png_ptr->read_user_transform_fn)) /* User read transform function */
+ (png_ptr, /* png_ptr */
+ &(png_ptr->row_info), /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_uint_32 rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+ if (png_ptr->user_transform_depth)
+ png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
+ if (png_ptr->user_transform_channels)
+ png_ptr->row_info.channels = png_ptr->user_transform_channels;
+#endif
+ png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+ png_ptr->row_info.channels);
+ png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+ png_ptr->row_info.width);
+ }
+#endif
+
+}
+
+#ifdef PNG_READ_PACK_SUPPORTED
+/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
+ * without changing the actual values. Thus, if you had a row with
+ * a bit depth of 1, you would end up with bytes that only contained
+ * the numbers 0 or 1. If you would rather they contain 0 and 255, use
+ * png_do_shift() after this.
+ */
+void /* PRIVATE */
+png_do_unpack(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_unpack");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
+#else
+ if (row_info->bit_depth < 8)
+#endif
+ {
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x01);
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x03);
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x0f);
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift = 4;
+
+ dp--;
+ }
+ break;
+ }
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_width * row_info->channels;
+ }
+}
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+/* Reverse the effects of png_do_shift. This routine merely shifts the
+ * pixels back to their significant bits values. Thus, if you have
+ * a row of bit depth 8, but only 5 are significant, this will shift
+ * the values back to 0 through 31.
+ */
+void /* PRIVATE */
+png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
+{
+ png_debug(1, "in png_do_unshift");
+
+ if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL && sig_bits != NULL &&
+#endif
+ row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ int shift[4];
+ int channels = 0;
+ int c;
+ png_uint_16 value = 0;
+ png_uint_32 row_width = row_info->width;
+
+ if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ shift[channels++] = row_info->bit_depth - sig_bits->red;
+ shift[channels++] = row_info->bit_depth - sig_bits->green;
+ shift[channels++] = row_info->bit_depth - sig_bits->blue;
+ }
+ else
+ {
+ shift[channels++] = row_info->bit_depth - sig_bits->gray;
+ }
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ shift[channels++] = row_info->bit_depth - sig_bits->alpha;
+ }
+
+ for (c = 0; c < channels; c++)
+ {
+ if (shift[c] <= 0)
+ shift[c] = 0;
+ else
+ value = 1;
+ }
+
+ if (!value)
+ return;
+
+ switch (row_info->bit_depth)
+ {
+ case 2:
+ {
+ png_bytep bp;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (bp = row, i = 0; i < istop; i++)
+ {
+ *bp >>= 1;
+ *bp++ &= 0x55;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
+ (png_byte)((int)0xf >> shift[0]));
+
+ for (i = 0; i < istop; i++)
+ {
+ *bp >>= shift[0];
+ *bp++ &= mask;
+ }
+ break;
+ }
+
+ case 8:
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_width * channels;
+
+ for (i = 0; i < istop; i++)
+ {
+ *bp++ >>= shift[i%channels];
+ }
+ break;
+ }
+
+ case 16:
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_width;
+
+ for (i = 0; i < istop; i++)
+ {
+ value = (png_uint_16)((*bp << 8) + *(bp + 1));
+ value >>= shift[i%channels];
+ *bp++ = (png_byte)(value >> 8);
+ *bp++ = (png_byte)(value & 0xff);
+ }
+ break;
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_16_TO_8_SUPPORTED
+/* Chop rows of bit depth 16 down to 8 */
+void /* PRIVATE */
+png_do_chop(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_chop");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
+#else
+ if (row_info->bit_depth == 16)
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->width * row_info->channels;
+
+ for (i = 0; i<istop; i++, sp += 2, dp++)
+ {
+#ifdef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+ /* This does a more accurate scaling of the 16-bit color
+ * value, rather than a simple low-byte truncation.
+ *
+ * What the ideal calculation should be:
+ * *dp = (((((png_uint_32)(*sp) << 8) |
+ * (png_uint_32)(*(sp + 1))) * 255 + 127)
+ * / (png_uint_32)65535L;
+ *
+ * GRR: no, I think this is what it really should be:
+ * *dp = (((((png_uint_32)(*sp) << 8) |
+ * (png_uint_32)(*(sp + 1))) + 128L)
+ * / (png_uint_32)257L;
+ *
+ * GRR: here's the exact calculation with shifts:
+ * temp = (((png_uint_32)(*sp) << 8) |
+ * (png_uint_32)(*(sp + 1))) + 128L;
+ * *dp = (temp - (temp >> 8)) >> 8;
+ *
+ * Approximate calculation with shift/add instead of multiply/divide:
+ * *dp = ((((png_uint_32)(*sp) << 8) |
+ * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
+ *
+ * What we actually do to avoid extra shifting and conversion:
+ */
+
+ *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
+#else
+ /* Simply discard the low order byte */
+ *dp = *sp;
+#endif
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_info->width * row_info->channels;
+ }
+}
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_swap_alpha");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This converts from RGBA to ARGB */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
+ }
+ /* This converts from RRGGBBAA to AARRGGBB */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This converts from GA to AG */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
+ }
+ /* This converts from GGAA to AAGG */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_invert_alpha");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This inverts the alpha channel in RGBA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+
+/* This does nothing:
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ We can replace it with:
+*/
+ sp-=3;
+ dp=sp;
+ }
+ }
+ /* This inverts the alpha channel in RRGGBBAA */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = (png_byte)(255 - *(--sp));
+
+/* This does nothing:
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ We can replace it with:
+*/
+ sp-=6;
+ dp=sp;
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This inverts the alpha channel in GA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = *(--sp);
+ }
+ }
+ /* This inverts the alpha channel in GGAA */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = (png_byte)(255 - *(--sp));
+/*
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+*/
+ sp-=2;
+ dp=sp;
+ }
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+/* Add filler channel if we have RGB color */
+void /* PRIVATE */
+png_do_read_filler(png_row_infop row_info, png_bytep row,
+ png_uint_32 filler, png_uint_32 flags)
+{
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
+ png_byte lo_filler = (png_byte)(filler & 0xff);
+
+ png_debug(1, "in png_do_read_filler");
+
+ if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This changes the data from G to GX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ row_info->channels = 2;
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+ /* This changes the data from G to XG */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 2;
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ /* This changes the data from GG to GGXX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ row_info->channels = 2;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ /* This changes the data from GG to XXGG */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 2;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ }
+ } /* COLOR_TYPE == GRAY */
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This changes the data from RGB to RGBX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ row_info->channels = 4;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ /* This changes the data from RGB to XRGB */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 4;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ /* This changes the data from RRGGBB to RRGGBBXX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ row_info->channels = 4;
+ row_info->pixel_depth = 64;
+ row_info->rowbytes = row_width * 8;
+ }
+ /* This changes the data from RRGGBB to XXRRGGBB */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 4;
+ row_info->pixel_depth = 64;
+ row_info->rowbytes = row_width * 8;
+ }
+ }
+ } /* COLOR_TYPE == RGB */
+}
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+/* Expand grayscale files to RGB, with or without alpha */
+void /* PRIVATE */
+png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
+{
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ png_debug(1, "in png_do_gray_to_rgb");
+
+ if (row_info->bit_depth >= 8 &&
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ !(row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + (png_size_t)row_width - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *sp;
+ *(dp--) = *sp;
+ *(dp--) = *(sp--);
+ }
+ }
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *(sp--);
+ *(dp--) = *sp;
+ *(dp--) = *sp;
+ *(dp--) = *(sp--);
+ }
+ }
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 4 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ }
+ }
+ }
+ row_info->channels += (png_byte)2;
+ row_info->color_type |= PNG_COLOR_MASK_COLOR;
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+/* Reduce RGB files to grayscale, with or without alpha
+ * using the equation given in Poynton's ColorFAQ at
+ * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008)
+ * New link:
+ * <http://www.poynton.com/notes/colour_and_gamma/>
+ * Charles Poynton poynton at poynton.com
+ *
+ * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+ *
+ * We approximate this with
+ *
+ * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
+ *
+ * which can be expressed with integers as
+ *
+ * Y = (6969 * R + 23434 * G + 2365 * B)/32768
+ *
+ * The calculation is to be done in a linear colorspace.
+ *
+ * Other integer coefficents can be used via png_set_rgb_to_gray().
+ */
+int /* PRIVATE */
+png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
+
+{
+ png_uint_32 i;
+
+ png_uint_32 row_width = row_info->width;
+ int rgb_error = 0;
+
+ png_debug(1, "in png_do_rgb_to_gray");
+
+ if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
+ png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
+ png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = png_ptr->gamma_to_1[*(sp++)];
+ png_byte green = png_ptr->gamma_to_1[*(sp++)];
+ png_byte blue = png_ptr->gamma_to_1[*(sp++)];
+ if (red != green || red != blue)
+ {
+ rgb_error |= 1;
+ *(dp++) = png_ptr->gamma_from_1[
+ (rc*red + gc*green + bc*blue)>>15];
+ }
+ else
+ *(dp++) = *(sp - 1);
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = *(sp++);
+ png_byte green = *(sp++);
+ png_byte blue = *(sp++);
+ if (red != green || red != blue)
+ {
+ rgb_error |= 1;
+ *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
+ }
+ else
+ *(dp++) = *(sp - 1);
+ }
+ }
+ }
+
+ else /* RGB bit_depth == 16 */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_16_to_1 != NULL &&
+ png_ptr->gamma_16_from_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, w;
+
+ red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+ if (red == green && red == blue)
+ w = red;
+ else
+ {
+ png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
+ png_ptr->gamma_shift][red>>8];
+ png_uint_16 green_1 =
+ png_ptr->gamma_16_to_1[(green&0xff) >>
+ png_ptr->gamma_shift][green>>8];
+ png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
+ png_ptr->gamma_shift][blue>>8];
+ png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
+ + bc*blue_1)>>15);
+ w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+ png_ptr->gamma_shift][gray16 >> 8];
+ rgb_error |= 1;
+ }
+
+ *(dp++) = (png_byte)((w>>8) & 0xff);
+ *(dp++) = (png_byte)(w & 0xff);
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, gray16;
+
+ red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+ if (red != green || red != blue)
+ rgb_error |= 1;
+ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+ *(dp++) = (png_byte)((gray16>>8) & 0xff);
+ *(dp++) = (png_byte)(gray16 & 0xff);
+ }
+ }
+ }
+ }
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = png_ptr->gamma_to_1[*(sp++)];
+ png_byte green = png_ptr->gamma_to_1[*(sp++)];
+ png_byte blue = png_ptr->gamma_to_1[*(sp++)];
+ if (red != green || red != blue)
+ rgb_error |= 1;
+ *(dp++) = png_ptr->gamma_from_1
+ [(rc*red + gc*green + bc*blue)>>15];
+ *(dp++) = *(sp++); /* alpha */
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = *(sp++);
+ png_byte green = *(sp++);
+ png_byte blue = *(sp++);
+ if (red != green || red != blue)
+ rgb_error |= 1;
+ *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
+ *(dp++) = *(sp++); /* alpha */
+ }
+ }
+ }
+ else /* RGBA bit_depth == 16 */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_16_to_1 != NULL &&
+ png_ptr->gamma_16_from_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, w;
+
+ red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+ if (red == green && red == blue)
+ w = red;
+ else
+ {
+ png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
+ png_ptr->gamma_shift][red>>8];
+ png_uint_16 green_1 =
+ png_ptr->gamma_16_to_1[(green&0xff) >>
+ png_ptr->gamma_shift][green>>8];
+ png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
+ png_ptr->gamma_shift][blue>>8];
+ png_uint_16 gray16 = (png_uint_16)((rc * red_1
+ + gc * green_1 + bc * blue_1)>>15);
+ w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+ png_ptr->gamma_shift][gray16 >> 8];
+ rgb_error |= 1;
+ }
+
+ *(dp++) = (png_byte)((w>>8) & 0xff);
+ *(dp++) = (png_byte)(w & 0xff);
+ *(dp++) = *(sp++); /* alpha */
+ *(dp++) = *(sp++);
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, gray16;
+ red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+ if (red != green || red != blue)
+ rgb_error |= 1;
+ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+ *(dp++) = (png_byte)((gray16>>8) & 0xff);
+ *(dp++) = (png_byte)(gray16 & 0xff);
+ *(dp++) = *(sp++); /* alpha */
+ *(dp++) = *(sp++);
+ }
+ }
+ }
+ }
+ row_info->channels -= (png_byte)2;
+ row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+ return rgb_error;
+}
+#endif
+
+/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
+ * large of png_color. This lets grayscale images be treated as
+ * paletted. Most useful for gamma correction and simplification
+ * of code.
+ */
+void PNGAPI
+png_build_grayscale_palette(int bit_depth, png_colorp palette)
+{
+ int num_palette;
+ int color_inc;
+ int i;
+ int v;
+
+ png_debug(1, "in png_do_build_grayscale_palette");
+
+ if (palette == NULL)
+ return;
+
+ switch (bit_depth)
+ {
+ case 1:
+ num_palette = 2;
+ color_inc = 0xff;
+ break;
+
+ case 2:
+ num_palette = 4;
+ color_inc = 0x55;
+ break;
+
+ case 4:
+ num_palette = 16;
+ color_inc = 0x11;
+ break;
+
+ case 8:
+ num_palette = 256;
+ color_inc = 1;
+ break;
+
+ default:
+ num_palette = 0;
+ color_inc = 0;
+ break;
+ }
+
+ for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
+ {
+ palette[i].red = (png_byte)v;
+ palette[i].green = (png_byte)v;
+ palette[i].blue = (png_byte)v;
+ }
+}
+
+/* This function is currently unused. Do we really need it? */
+#if defined(PNG_READ_DITHER_SUPPORTED) && \
+ defined(PNG_CORRECT_PALETTE_SUPPORTED)
+void /* PRIVATE */
+png_correct_palette(png_structp png_ptr, png_colorp palette,
+ int num_palette)
+{
+ png_debug(1, "in png_correct_palette");
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+ defined(PNG_READ_GAMMA_SUPPORTED) && \
+ defined(PNG_FLOATING_POINT_SUPPORTED)
+ if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
+ {
+ png_color back, back_1;
+
+ if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+ {
+ back.red = png_ptr->gamma_table[png_ptr->background.red];
+ back.green = png_ptr->gamma_table[png_ptr->background.green];
+ back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+ back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+ back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+ back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+ }
+ else
+ {
+ double g;
+
+ g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
+
+ if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN
+ || fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
+ {
+ back.red = png_ptr->background.red;
+ back.green = png_ptr->background.green;
+ back.blue = png_ptr->background.blue;
+ }
+ else
+ {
+ back.red =
+ (png_byte)(pow((double)png_ptr->background.red/255, g) *
+ 255.0 + 0.5);
+ back.green =
+ (png_byte)(pow((double)png_ptr->background.green/255, g) *
+ 255.0 + 0.5);
+ back.blue =
+ (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+ 255.0 + 0.5);
+ }
+
+ g = 1.0 / png_ptr->background_gamma;
+
+ back_1.red =
+ (png_byte)(pow((double)png_ptr->background.red/255, g) *
+ 255.0 + 0.5);
+ back_1.green =
+ (png_byte)(pow((double)png_ptr->background.green/255, g) *
+ 255.0 + 0.5);
+ back_1.blue =
+ (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+ 255.0 + 0.5);
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_uint_32 i;
+
+ for (i = 0; i < (png_uint_32)num_palette; i++)
+ {
+ if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
+ {
+ palette[i] = back;
+ }
+ else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+ {
+ png_byte v, w;
+
+ v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
+ png_composite(w, v, png_ptr->trans[i], back_1.red);
+ palette[i].red = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
+ png_composite(w, v, png_ptr->trans[i], back_1.green);
+ palette[i].green = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
+ png_composite(w, v, png_ptr->trans[i], back_1.blue);
+ palette[i].blue = png_ptr->gamma_from_1[w];
+ }
+ else
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
+ {
+ palette[i] = back;
+ }
+ else
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+ }
+ }
+ else
+#endif
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (png_ptr->transformations & PNG_GAMMA)
+ {
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ else
+#endif
+#endif
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ if (png_ptr->transformations & PNG_BACKGROUND)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_color back;
+
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+
+ for (i = 0; i < (int)png_ptr->num_trans; i++)
+ {
+ if (png_ptr->trans[i] == 0)
+ {
+ palette[i].red = back.red;
+ palette[i].green = back.green;
+ palette[i].blue = back.blue;
+ }
+ else if (png_ptr->trans[i] != 0xff)
+ {
+ png_composite(palette[i].red, png_ptr->palette[i].red,
+ png_ptr->trans[i], back.red);
+ png_composite(palette[i].green, png_ptr->palette[i].green,
+ png_ptr->trans[i], back.green);
+ png_composite(palette[i].blue, png_ptr->palette[i].blue,
+ png_ptr->trans[i], back.blue);
+ }
+ }
+ }
+ else /* Assume grayscale palette (what else could it be?) */
+ {
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ if (i == (png_byte)png_ptr->trans_values.gray)
+ {
+ palette[i].red = (png_byte)png_ptr->background.red;
+ palette[i].green = (png_byte)png_ptr->background.green;
+ palette[i].blue = (png_byte)png_ptr->background.blue;
+ }
+ }
+ }
+ }
+#endif
+}
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+/* Replace any alpha or transparency with the supplied background color.
+ * "background" is already in the screen gamma, while "background_1" is
+ * at a gamma of 1.0. Paletted files have already been taken care of.
+ */
+void /* PRIVATE */
+png_do_background(png_row_infop row_info, png_bytep row,
+ png_color_16p trans_values, png_color_16p background
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ , png_color_16p background_1,
+ png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+ png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+ png_uint_16pp gamma_16_to_1, int gamma_shift
+#endif
+ )
+{
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+ int shift;
+
+ png_debug(1, "in png_do_background");
+
+ if (background != NULL &&
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
+ (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
+ {
+ switch (row_info->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ sp = row;
+ shift = 7;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x01)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ if (!shift)
+ {
+ shift = 7;
+ sp++;
+ }
+ else
+ shift--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ else
+ {
+ png_byte p = (png_byte)((*sp >> shift) & 0x03);
+ png_byte g = (png_byte)((gamma_table [p | (p << 2) |
+ (p << 4) | (p << 6)] >> 6) & 0x03);
+ *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *sp |= (png_byte)(g << shift);
+ }
+ if (!shift)
+ {
+ shift = 6;
+ sp++;
+ }
+ else
+ shift -= 2;
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ if (!shift)
+ {
+ shift = 6;
+ sp++;
+ }
+ else
+ shift -= 2;
+ }
+ }
+ break;
+ }
+
+ case 4:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ else
+ {
+ png_byte p = (png_byte)((*sp >> shift) & 0x0f);
+ png_byte g = (png_byte)((gamma_table[p |
+ (p << 4)] >> 4) & 0x0f);
+ *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *sp |= (png_byte)(g << shift);
+ }
+ if (!shift)
+ {
+ shift = 4;
+ sp++;
+ }
+ else
+ shift -= 4;
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ if (!shift)
+ {
+ shift = 4;
+ sp++;
+ }
+ else
+ shift -= 4;
+ }
+ }
+ break;
+ }
+
+ case 8:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == trans_values->gray)
+ {
+ *sp = (png_byte)background->gray;
+ }
+ else
+ {
+ *sp = gamma_table[*sp];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == trans_values->gray)
+ {
+ *sp = (png_byte)background->gray;
+ }
+ }
+ }
+ break;
+ }
+
+ case 16:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ if (v == trans_values->gray)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((background->gray >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->gray & 0xff);
+ }
+ else
+ {
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ if (v == trans_values->gray)
+ {
+ *sp = (png_byte)((background->gray >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->gray & 0xff);
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_RGB:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 3)
+ {
+ if (*sp == trans_values->red &&
+ *(sp + 1) == trans_values->green &&
+ *(sp + 2) == trans_values->blue)
+ {
+ *sp = (png_byte)background->red;
+ *(sp + 1) = (png_byte)background->green;
+ *(sp + 2) = (png_byte)background->blue;
+ }
+ else
+ {
+ *sp = gamma_table[*sp];
+ *(sp + 1) = gamma_table[*(sp + 1)];
+ *(sp + 2) = gamma_table[*(sp + 2)];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 3)
+ {
+ if (*sp == trans_values->red &&
+ *(sp + 1) == trans_values->green &&
+ *(sp + 2) == trans_values->blue)
+ {
+ *sp = (png_byte)background->red;
+ *(sp + 1) = (png_byte)background->green;
+ *(sp + 2) = (png_byte)background->blue;
+ }
+ }
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 6)
+ {
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+ png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
+ if (r == trans_values->red && g == trans_values->green &&
+ b == trans_values->blue)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((background->red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->red & 0xff);
+ *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(background->green & 0xff);
+ *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ else
+ {
+ png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 6)
+ {
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
+ png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+ png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
+
+ if (r == trans_values->red && g == trans_values->green &&
+ b == trans_values->blue)
+ {
+ *sp = (png_byte)((background->red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->red & 0xff);
+ *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(background->green & 0xff);
+ *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 2, dp++)
+ {
+ png_uint_16 a = *(sp + 1);
+
+ if (a == 0xff)
+ {
+ *dp = gamma_table[*sp];
+ }
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *dp = (png_byte)background->gray;
+ }
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, background_1->gray);
+ *dp = gamma_from_1[w];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 2, dp++)
+ {
+ png_byte a = *(sp + 1);
+
+ if (a == 0xff)
+ {
+ *dp = *sp;
+ }
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ else if (a == 0)
+ {
+ *dp = (png_byte)background->gray;
+ }
+ else
+ {
+ png_composite(*dp, *sp, a, background_1->gray);
+ }
+#else
+ *dp = (png_byte)background->gray;
+#endif
+ }
+ }
+ }
+ else /* if (png_ptr->bit_depth == 16) */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 2)
+ {
+ png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+
+ if (a == (png_uint_16)0xffff)
+ {
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ }
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ else if (a == 0)
+#else
+ else
+#endif
+ {
+ /* Background is already in screen gamma */
+ *dp = (png_byte)((background->gray >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->gray & 0xff);
+ }
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ else
+ {
+ png_uint_16 g, v, w;
+
+ g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(v, g, a, background_1->gray);
+ w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
+ *dp = (png_byte)((w >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(w & 0xff);
+ }
+#endif
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 2)
+ {
+ png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+ if (a == (png_uint_16)0xffff)
+ {
+ png_memcpy(dp, sp, 2);
+ }
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ else if (a == 0)
+#else
+ else
+#endif
+ {
+ *dp = (png_byte)((background->gray >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->gray & 0xff);
+ }
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ else
+ {
+ png_uint_16 g, v;
+
+ g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_composite_16(v, g, a, background_1->gray);
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ }
+#endif
+ }
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 3)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0xff)
+ {
+ *dp = gamma_table[*sp];
+ *(dp + 1) = gamma_table[*(sp + 1)];
+ *(dp + 2) = gamma_table[*(sp + 2)];
+ }
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *dp = (png_byte)background->red;
+ *(dp + 1) = (png_byte)background->green;
+ *(dp + 2) = (png_byte)background->blue;
+ }
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, background_1->red);
+ *dp = gamma_from_1[w];
+ v = gamma_to_1[*(sp + 1)];
+ png_composite(w, v, a, background_1->green);
+ *(dp + 1) = gamma_from_1[w];
+ v = gamma_to_1[*(sp + 2)];
+ png_composite(w, v, a, background_1->blue);
+ *(dp + 2) = gamma_from_1[w];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 3)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0xff)
+ {
+ *dp = *sp;
+ *(dp + 1) = *(sp + 1);
+ *(dp + 2) = *(sp + 2);
+ }
+ else if (a == 0)
+ {
+ *dp = (png_byte)background->red;
+ *(dp + 1) = (png_byte)background->green;
+ *(dp + 2) = (png_byte)background->blue;
+ }
+ else
+ {
+ png_composite(*dp, *sp, a, background->red);
+ png_composite(*(dp + 1), *(sp + 1), a,
+ background->green);
+ png_composite(*(dp + 2), *(sp + 2), a,
+ background->blue);
+ }
+ }
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 8, dp += 6)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+ if (a == (png_uint_16)0xffff)
+ {
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(v & 0xff);
+ }
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *dp = (png_byte)((background->red >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->red & 0xff);
+ *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(background->green & 0xff);
+ *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ else
+ {
+ png_uint_16 v, w, x;
+
+ v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(w, v, a, background_1->red);
+ x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+ *dp = (png_byte)((x >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(x & 0xff);
+ v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ png_composite_16(w, v, a, background_1->green);
+ x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+ *(dp + 2) = (png_byte)((x >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(x & 0xff);
+ v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ png_composite_16(w, v, a, background_1->blue);
+ x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
+ *(dp + 4) = (png_byte)((x >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(x & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 8, dp += 6)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+ if (a == (png_uint_16)0xffff)
+ {
+ png_memcpy(dp, sp, 6);
+ }
+ else if (a == 0)
+ {
+ *dp = (png_byte)((background->red >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->red & 0xff);
+ *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(background->green & 0xff);
+ *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ else
+ {
+ png_uint_16 v;
+
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ png_composite_16(v, r, a, background->red);
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ png_composite_16(v, g, a, background->green);
+ *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(v & 0xff);
+ png_composite_16(v, b, a, background->blue);
+ *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+ row_info->channels--;
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* Gamma correct the image, avoiding the alpha channel. Make sure
+ * you do this after you deal with the transparency issue on grayscale
+ * or RGB images. If your bit depth is 8, use gamma_table, if it
+ * is 16, use gamma_16_table and gamma_shift. Build these with
+ * build_gamma_table().
+ */
+void /* PRIVATE */
+png_do_gamma(png_row_infop row_info, png_bytep row,
+ png_bytep gamma_table, png_uint_16pp gamma_16_table,
+ int gamma_shift)
+{
+ png_bytep sp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_gamma");
+
+ if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
+ (row_info->bit_depth == 16 && gamma_16_table != NULL)))
+ {
+ switch (row_info->color_type)
+ {
+ case PNG_COLOR_TYPE_RGB:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ sp++;
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 4;
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp += 2;
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 4;
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_GRAY:
+ {
+ if (row_info->bit_depth == 2)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i += 4)
+ {
+ int a = *sp & 0xc0;
+ int b = *sp & 0x30;
+ int c = *sp & 0x0c;
+ int d = *sp & 0x03;
+
+ *sp = (png_byte)(
+ ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
+ ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
+ ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
+ ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
+ sp++;
+ }
+ }
+
+ if (row_info->bit_depth == 4)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i += 2)
+ {
+ int msb = *sp & 0xf0;
+ int lsb = *sp & 0x0f;
+
+ *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
+ | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
+ sp++;
+ }
+ }
+
+ else if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ }
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expands a palette row to an RGB or RGBA row depending
+ * upon whether you supply trans and num_trans.
+ */
+void /* PRIVATE */
+png_do_expand_palette(png_row_infop row_info, png_bytep row,
+ png_colorp palette, png_bytep trans, int num_trans)
+{
+ int shift, value;
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_expand_palette");
+
+ if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (row_info->bit_depth < 8)
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
+ shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*sp >> shift) & 0x01)
+ *dp = 1;
+ else
+ *dp = 0;
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp = (png_byte)value;
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((row_width & 0x01) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x0f;
+ *dp = (png_byte)value;
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 4;
+
+ dp--;
+ }
+ break;
+ }
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+ switch (row_info->bit_depth)
+ {
+ case 8:
+ {
+ if (trans != NULL)
+ {
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width << 2) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if ((int)(*sp) >= num_trans)
+ *dp-- = 0xff;
+ else
+ *dp-- = trans[*sp];
+ *dp-- = palette[*sp].blue;
+ *dp-- = palette[*sp].green;
+ *dp-- = palette[*sp].red;
+ sp--;
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ row_info->color_type = 6;
+ row_info->channels = 4;
+ }
+ else
+ {
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width * 3) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *dp-- = palette[*sp].blue;
+ *dp-- = palette[*sp].green;
+ *dp-- = palette[*sp].red;
+ sp--;
+ }
+
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 24;
+ row_info->rowbytes = row_width * 3;
+ row_info->color_type = 2;
+ row_info->channels = 3;
+ }
+ break;
+ }
+ }
+ }
+}
+
+/* If the bit depth < 8, it is expanded to 8. Also, if the already
+ * expanded transparency value is supplied, an alpha channel is built.
+ */
+void /* PRIVATE */
+png_do_expand(png_row_infop row_info, png_bytep row,
+ png_color_16p trans_value)
+{
+ int shift, value;
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_expand");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
+
+ if (row_info->bit_depth < 8)
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ gray = (png_uint_16)((gray&0x01)*0xff);
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
+ shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*sp >> shift) & 0x01)
+ *dp = 0xff;
+ else
+ *dp = 0;
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+ gray = (png_uint_16)((gray&0x03)*0x55);
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp = (png_byte)(value | (value << 2) | (value << 4) |
+ (value << 6));
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ gray = (png_uint_16)((gray&0x0f)*0x11);
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x0f;
+ *dp = (png_byte)(value | (value << 4));
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift = 4;
+
+ dp--;
+ }
+ break;
+ }
+ }
+
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+
+ if (trans_value != NULL)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ gray = gray & 0xff;
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width << 1) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*sp == gray)
+ *dp-- = 0;
+ else
+ *dp-- = 0xff;
+ *dp-- = *sp--;
+ }
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ png_byte gray_high = (gray >> 8) & 0xff;
+ png_byte gray_low = gray & 0xff;
+ sp = row + row_info->rowbytes - 1;
+ dp = row + (row_info->rowbytes << 1) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 1) == gray_high && *(sp) == gray_low)
+ {
+ *dp-- = 0;
+ *dp-- = 0;
+ }
+ else
+ {
+ *dp-- = 0xff;
+ *dp-- = 0xff;
+ }
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+
+ row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+ row_info->channels = 2;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_width);
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ png_byte red = trans_value->red & 0xff;
+ png_byte green = trans_value->green & 0xff;
+ png_byte blue = trans_value->blue & 0xff;
+ sp = row + (png_size_t)row_info->rowbytes - 1;
+ dp = row + (png_size_t)(row_width << 2) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
+ *dp-- = 0;
+ else
+ *dp-- = 0xff;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_byte red_high = (trans_value->red >> 8) & 0xff;
+ png_byte green_high = (trans_value->green >> 8) & 0xff;
+ png_byte blue_high = (trans_value->blue >> 8) & 0xff;
+ png_byte red_low = trans_value->red & 0xff;
+ png_byte green_low = trans_value->green & 0xff;
+ png_byte blue_low = trans_value->blue & 0xff;
+ sp = row + row_info->rowbytes - 1;
+ dp = row + (png_size_t)(row_width << 3) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 5) == red_high &&
+ *(sp - 4) == red_low &&
+ *(sp - 3) == green_high &&
+ *(sp - 2) == green_low &&
+ *(sp - 1) == blue_high &&
+ *(sp ) == blue_low)
+ {
+ *dp-- = 0;
+ *dp-- = 0;
+ }
+ else
+ {
+ *dp-- = 0xff;
+ *dp-- = 0xff;
+ }
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ row_info->channels = 4;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_DITHER_SUPPORTED
+void /* PRIVATE */
+png_do_dither(png_row_infop row_info, png_bytep row,
+ png_bytep palette_lookup, png_bytep dither_lookup)
+{
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_dither");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
+ palette_lookup && row_info->bit_depth == 8)
+ {
+ int r, g, b, p;
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ r = *sp++;
+ g = *sp++;
+ b = *sp++;
+
+ /* This looks real messy, but the compiler will reduce
+ * it down to a reasonable formula. For example, with
+ * 5 bits per color, we get:
+ * p = (((r >> 3) & 0x1f) << 10) |
+ * (((g >> 3) & 0x1f) << 5) |
+ * ((b >> 3) & 0x1f);
+ */
+ p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+ ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+ (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+ (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+ ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+ (PNG_DITHER_BLUE_BITS)) |
+ ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+ ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+ *dp++ = palette_lookup[p];
+ }
+ row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+ row_info->channels = 1;
+ row_info->pixel_depth = row_info->bit_depth;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+ palette_lookup != NULL && row_info->bit_depth == 8)
+ {
+ int r, g, b, p;
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ r = *sp++;
+ g = *sp++;
+ b = *sp++;
+ sp++;
+
+ p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+ ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+ (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+ (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+ ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+ (PNG_DITHER_BLUE_BITS)) |
+ ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+ ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+ *dp++ = palette_lookup[p];
+ }
+ row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+ row_info->channels = 1;
+ row_info->pixel_depth = row_info->bit_depth;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+ dither_lookup && row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ *sp = dither_lookup[*sp];
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+#ifdef PNG_READ_GAMMA_SUPPORTED
+static PNG_CONST int png_gamma_shift[] =
+ {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
+
+/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
+ * tables, we don't make a full table if we are reducing to 8-bit in
+ * the future. Note also how the gamma_16 tables are segmented so that
+ * we don't need to allocate > 64K chunks for a full 16-bit table.
+ *
+ * See the PNG extensions document for an integer algorithm for creating
+ * the gamma tables. Maybe we will implement that here someday.
+ *
+ * We should only reach this point if
+ *
+ * the file_gamma is known (i.e., the gAMA or sRGB chunk is present,
+ * or the application has provided a file_gamma)
+ *
+ * AND
+ * {
+ * the screen_gamma is known
+ * OR
+ *
+ * RGB_to_gray transformation is being performed
+ * }
+ *
+ * AND
+ * {
+ * the screen_gamma is different from the reciprocal of the
+ * file_gamma by more than the specified threshold
+ *
+ * OR
+ *
+ * a background color has been specified and the file_gamma
+ * and screen_gamma are not 1.0, within the specified threshold.
+ * }
+ */
+
+void /* PRIVATE */
+png_build_gamma_table(png_structp png_ptr)
+{
+ png_debug(1, "in png_build_gamma_table");
+
+ if (png_ptr->bit_depth <= 8)
+ {
+ int i;
+ double g;
+
+ if (png_ptr->screen_gamma > .000001)
+ g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+
+ else
+ g = 1.0;
+
+ png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)256);
+
+ for (i = 0; i < 256; i++)
+ {
+ png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
+ g) * 255.0 + .5);
+ }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
+ {
+
+ g = 1.0 / (png_ptr->gamma);
+
+ png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)256);
+
+ for (i = 0; i < 256; i++)
+ {
+ png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
+ g) * 255.0 + .5);
+ }
+
+
+ png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)256);
+
+ if (png_ptr->screen_gamma > 0.000001)
+ g = 1.0 / png_ptr->screen_gamma;
+
+ else
+ g = png_ptr->gamma; /* Probably doing rgb_to_gray */
+
+ for (i = 0; i < 256; i++)
+ {
+ png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
+ g) * 255.0 + .5);
+
+ }
+ }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
+ }
+ else
+ {
+ double g;
+ int i, j, shift, num;
+ int sig_bit;
+ png_uint_32 ig;
+
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ sig_bit = (int)png_ptr->sig_bit.red;
+
+ if ((int)png_ptr->sig_bit.green > sig_bit)
+ sig_bit = png_ptr->sig_bit.green;
+
+ if ((int)png_ptr->sig_bit.blue > sig_bit)
+ sig_bit = png_ptr->sig_bit.blue;
+ }
+ else
+ {
+ sig_bit = (int)png_ptr->sig_bit.gray;
+ }
+
+ if (sig_bit > 0)
+ shift = 16 - sig_bit;
+
+ else
+ shift = 0;
+
+ if (png_ptr->transformations & PNG_16_TO_8)
+ {
+ if (shift < (16 - PNG_MAX_GAMMA_8))
+ shift = (16 - PNG_MAX_GAMMA_8);
+ }
+
+ if (shift > 8)
+ shift = 8;
+
+ if (shift < 0)
+ shift = 0;
+
+ png_ptr->gamma_shift = (png_byte)shift;
+
+ num = (1 << (8 - shift));
+
+ if (png_ptr->screen_gamma > .000001)
+ g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+ else
+ g = 1.0;
+
+ png_ptr->gamma_16_table = (png_uint_16pp)png_calloc(png_ptr,
+ (png_uint_32)(num * png_sizeof(png_uint_16p)));
+
+ if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
+ {
+ double fin, fout;
+ png_uint_32 last, max;
+
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * png_sizeof(png_uint_16)));
+ }
+
+ g = 1.0 / g;
+ last = 0;
+ for (i = 0; i < 256; i++)
+ {
+ fout = ((double)i + 0.5) / 256.0;
+ fin = pow(fout, g);
+ max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
+ while (last <= max)
+ {
+ png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+ [(int)(last >> (8 - shift))] = (png_uint_16)(
+ (png_uint_16)i | ((png_uint_16)i << 8));
+ last++;
+ }
+ }
+ while (last < ((png_uint_32)num << 8))
+ {
+ png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+ [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
+ last++;
+ }
+ }
+ else
+ {
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * png_sizeof(png_uint_16)));
+
+ ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
+
+ for (j = 0; j < 256; j++)
+ {
+ png_ptr->gamma_16_table[i][j] =
+ (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+ 65535.0, g) * 65535.0 + .5);
+ }
+ }
+ }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
+ {
+
+ g = 1.0 / (png_ptr->gamma);
+
+ png_ptr->gamma_16_to_1 = (png_uint_16pp)png_calloc(png_ptr,
+ (png_uint_32)(num * png_sizeof(png_uint_16p )));
+
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * png_sizeof(png_uint_16)));
+
+ ig = (((png_uint_32)i *
+ (png_uint_32)png_gamma_shift[shift]) >> 4);
+ for (j = 0; j < 256; j++)
+ {
+ png_ptr->gamma_16_to_1[i][j] =
+ (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+ 65535.0, g) * 65535.0 + .5);
+ }
+ }
+
+ if (png_ptr->screen_gamma > 0.000001)
+ g = 1.0 / png_ptr->screen_gamma;
+
+ else
+ g = png_ptr->gamma; /* Probably doing rgb_to_gray */
+
+ png_ptr->gamma_16_from_1 = (png_uint_16pp)png_calloc(png_ptr,
+ (png_uint_32)(num * png_sizeof(png_uint_16p)));
+
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * png_sizeof(png_uint_16)));
+
+ ig = (((png_uint_32)i *
+ (png_uint_32)png_gamma_shift[shift]) >> 4);
+
+ for (j = 0; j < 256; j++)
+ {
+ png_ptr->gamma_16_from_1[i][j] =
+ (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+ 65535.0, g) * 65535.0 + .5);
+ }
+ }
+ }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
+ }
+}
+#endif
+/* To do: install integer version of png_build_gamma_table here */
+#endif
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Undoes intrapixel differencing */
+void /* PRIVATE */
+png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_intrapixel");
+
+ if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
+
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
+ *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
+
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
+ png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
+ png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
+ png_uint_32 red = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL);
+ png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL);
+ *(rp ) = (png_byte)((red >> 8) & 0xff);
+ *(rp+1) = (png_byte)(red & 0xff);
+ *(rp+4) = (png_byte)((blue >> 8) & 0xff);
+ *(rp+5) = (png_byte)(blue & 0xff);
+ }
+ }
+ }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
diff --git a/src/libpng/pngrutil.c b/src/libpng/pngrutil.c
new file mode 100644
index 0000000..45e7ddd
--- /dev/null
+++ b/src/libpng/pngrutil.c
@@ -0,0 +1,3390 @@
+
+/* pngrutil.c - utilities to read a PNG file
+ *
+ * Last changed in libpng 1.2.45 [July 7, 2011]
+ * Copyright (c) 1998-2011 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains routines that are only called from within
+ * libpng itself during the course of reading an image.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_READ_SUPPORTED
+
+#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
+# define WIN32_WCE_OLD
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+# ifdef WIN32_WCE_OLD
+/* The strtod() function is not supported on WindowsCE */
+__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr,
+ char **endptr)
+{
+ double result = 0;
+ int len;
+ wchar_t *str, *end;
+
+ len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
+ str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
+ if ( NULL != str )
+ {
+ MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
+ result = wcstod(str, &end);
+ len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
+ *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
+ png_free(png_ptr, str);
+ }
+ return result;
+}
+# else
+# define png_strtod(p,a,b) strtod(a,b)
+# endif
+#endif
+
+png_uint_32 PNGAPI
+png_get_uint_31(png_structp png_ptr, png_bytep buf)
+{
+#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
+ png_uint_32 i = png_get_uint_32(buf);
+#else
+ /* Avoid an extra function call by inlining the result. */
+ png_uint_32 i = ((png_uint_32)(*buf) << 24) +
+ ((png_uint_32)(*(buf + 1)) << 16) +
+ ((png_uint_32)(*(buf + 2)) << 8) +
+ (png_uint_32)(*(buf + 3));
+#endif
+ if (i > PNG_UINT_31_MAX)
+ png_error(png_ptr, "PNG unsigned integer out of range.");
+ return (i);
+}
+#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
+/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
+png_uint_32 PNGAPI
+png_get_uint_32(png_bytep buf)
+{
+ png_uint_32 i = ((png_uint_32)(*buf) << 24) +
+ ((png_uint_32)(*(buf + 1)) << 16) +
+ ((png_uint_32)(*(buf + 2)) << 8) +
+ (png_uint_32)(*(buf + 3));
+
+ return (i);
+}
+
+/* Grab a signed 32-bit integer from a buffer in big-endian format. The
+ * data is stored in the PNG file in two's complement format, and it is
+ * assumed that the machine format for signed integers is the same.
+ */
+png_int_32 PNGAPI
+png_get_int_32(png_bytep buf)
+{
+ png_int_32 i = ((png_int_32)(*buf) << 24) +
+ ((png_int_32)(*(buf + 1)) << 16) +
+ ((png_int_32)(*(buf + 2)) << 8) +
+ (png_int_32)(*(buf + 3));
+
+ return (i);
+}
+
+/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
+png_uint_16 PNGAPI
+png_get_uint_16(png_bytep buf)
+{
+ png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
+ (png_uint_16)(*(buf + 1)));
+
+ return (i);
+}
+#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
+
+/* Read the chunk header (length + type name).
+ * Put the type name into png_ptr->chunk_name, and return the length.
+ */
+png_uint_32 /* PRIVATE */
+png_read_chunk_header(png_structp png_ptr)
+{
+ png_byte buf[8];
+ png_uint_32 length;
+
+ /* Read the length and the chunk name */
+ png_read_data(png_ptr, buf, 8);
+ length = png_get_uint_31(png_ptr, buf);
+
+ /* Put the chunk name into png_ptr->chunk_name */
+ png_memcpy(png_ptr->chunk_name, buf + 4, 4);
+
+ png_debug2(0, "Reading %s chunk, length = %lu",
+ png_ptr->chunk_name, length);
+
+ /* Reset the crc and run it over the chunk name */
+ png_reset_crc(png_ptr);
+ png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
+
+ /* Check to see if chunk name is valid */
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+ return length;
+}
+
+/* Read data, and (optionally) run it through the CRC. */
+void /* PRIVATE */
+png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
+{
+ if (png_ptr == NULL)
+ return;
+ png_read_data(png_ptr, buf, length);
+ png_calculate_crc(png_ptr, buf, length);
+}
+
+/* Optionally skip data and then check the CRC. Depending on whether we
+ * are reading a ancillary or critical chunk, and how the program has set
+ * things up, we may calculate the CRC on the data and print a message.
+ * Returns '1' if there was a CRC error, '0' otherwise.
+ */
+int /* PRIVATE */
+png_crc_finish(png_structp png_ptr, png_uint_32 skip)
+{
+ png_size_t i;
+ png_size_t istop = png_ptr->zbuf_size;
+
+ for (i = (png_size_t)skip; i > istop; i -= istop)
+ {
+ png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+ }
+ if (i)
+ {
+ png_crc_read(png_ptr, png_ptr->zbuf, i);
+ }
+
+ if (png_crc_error(png_ptr))
+ {
+ if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
+ !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
+ (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
+ (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ }
+ else
+ {
+ png_chunk_error(png_ptr, "CRC error");
+ }
+ return (1);
+ }
+
+ return (0);
+}
+
+/* Compare the CRC stored in the PNG file with that calculated by libpng from
+ * the data it has read thus far.
+ */
+int /* PRIVATE */
+png_crc_error(png_structp png_ptr)
+{
+ png_byte crc_bytes[4];
+ png_uint_32 crc;
+ int need_crc = 1;
+
+ if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+ (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ need_crc = 0;
+ }
+ else /* critical */
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+ need_crc = 0;
+ }
+
+ png_read_data(png_ptr, crc_bytes, 4);
+
+ if (need_crc)
+ {
+ crc = png_get_uint_32(crc_bytes);
+ return ((int)(crc != png_ptr->crc));
+ }
+ else
+ return (0);
+}
+
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
+ defined(PNG_READ_iCCP_SUPPORTED)
+static png_size_t
+png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
+ png_bytep output, png_size_t output_size)
+{
+ png_size_t count = 0;
+
+ png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */
+ png_ptr->zstream.avail_in = size;
+
+ while (1)
+ {
+ int ret, avail;
+
+ /* Reset the output buffer each time round - we empty it
+ * after every inflate call.
+ */
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = png_ptr->zbuf_size;
+
+ ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
+ avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+
+ /* First copy/count any new output - but only if we didn't
+ * get an error code.
+ */
+ if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
+ {
+ if (output != 0 && output_size > count)
+ {
+ int copy = output_size - count;
+ if (avail < copy) copy = avail;
+ png_memcpy(output + count, png_ptr->zbuf, copy);
+ }
+ count += avail;
+ }
+
+ if (ret == Z_OK)
+ continue;
+
+ /* Termination conditions - always reset the zstream, it
+ * must be left in inflateInit state.
+ */
+ png_ptr->zstream.avail_in = 0;
+ inflateReset(&png_ptr->zstream);
+
+ if (ret == Z_STREAM_END)
+ return count; /* NOTE: may be zero. */
+
+ /* Now handle the error codes - the API always returns 0
+ * and the error message is dumped into the uncompressed
+ * buffer if available.
+ */
+ {
+ PNG_CONST char *msg;
+ if (png_ptr->zstream.msg != 0)
+ msg = png_ptr->zstream.msg;
+ else
+ {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+ char umsg[52];
+
+ switch (ret)
+ {
+ case Z_BUF_ERROR:
+ msg = "Buffer error in compressed datastream in %s chunk";
+ break;
+ case Z_DATA_ERROR:
+ msg = "Data error in compressed datastream in %s chunk";
+ break;
+ default:
+ msg = "Incomplete compressed datastream in %s chunk";
+ break;
+ }
+
+ png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
+ msg = umsg;
+#else
+ msg = "Damaged compressed datastream in chunk other than IDAT";
+#endif
+ }
+
+ png_warning(png_ptr, msg);
+ }
+
+ /* 0 means an error - notice that this code simple ignores
+ * zero length compressed chunks as a result.
+ */
+ return 0;
+ }
+}
+
+/*
+ * Decompress trailing data in a chunk. The assumption is that chunkdata
+ * points at an allocated area holding the contents of a chunk with a
+ * trailing compressed part. What we get back is an allocated area
+ * holding the original prefix part and an uncompressed version of the
+ * trailing part (the malloc area passed in is freed).
+ */
+void /* PRIVATE */
+png_decompress_chunk(png_structp png_ptr, int comp_type,
+ png_size_t chunklength,
+ png_size_t prefix_size, png_size_t *newlength)
+{
+ /* The caller should guarantee this */
+ if (prefix_size > chunklength)
+ {
+ /* The recovery is to delete the chunk. */
+ png_warning(png_ptr, "invalid chunklength");
+ prefix_size = 0; /* To delete everything */
+ }
+
+ else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
+ {
+ png_size_t expanded_size = png_inflate(png_ptr,
+ (png_bytep)(png_ptr->chunkdata + prefix_size),
+ chunklength - prefix_size,
+ 0/*output*/, 0/*output size*/);
+
+ /* Now check the limits on this chunk - if the limit fails the
+ * compressed data will be removed, the prefix will remain.
+ */
+#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
+ if (png_ptr->user_chunk_malloc_max &&
+ (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
+#else
+# ifdef PNG_USER_CHUNK_MALLOC_MAX
+ if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
+ prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
+# endif
+#endif
+ png_warning(png_ptr, "Exceeded size limit while expanding chunk");
+
+ /* If the size is zero either there was an error and a message
+ * has already been output (warning) or the size really is zero
+ * and we have nothing to do - the code will exit through the
+ * error case below.
+ */
+#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
+ defined(PNG_USER_CHUNK_MALLOC_MAX)
+ else
+#endif
+ if (expanded_size > 0)
+ {
+ /* Success (maybe) - really uncompress the chunk. */
+ png_size_t new_size = 0;
+ png_charp text = png_malloc_warn(png_ptr,
+ prefix_size + expanded_size + 1);
+
+ if (text != NULL)
+ {
+ png_memcpy(text, png_ptr->chunkdata, prefix_size);
+ new_size = png_inflate(png_ptr,
+ (png_bytep)(png_ptr->chunkdata + prefix_size),
+ chunklength - prefix_size,
+ (png_bytep)(text + prefix_size), expanded_size);
+ text[prefix_size + expanded_size] = 0; /* just in case */
+
+ if (new_size == expanded_size)
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = text;
+ *newlength = prefix_size + expanded_size;
+ return; /* The success return! */
+ }
+
+ png_warning(png_ptr, "png_inflate logic error");
+ png_free(png_ptr, text);
+ }
+ else
+ png_warning(png_ptr, "Not enough memory to decompress chunk.");
+ }
+ }
+
+ else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
+ {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+ char umsg[50];
+
+ png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
+ comp_type);
+ png_warning(png_ptr, umsg);
+#else
+ png_warning(png_ptr, "Unknown zTXt compression type");
+#endif
+
+ /* The recovery is to simply drop the data. */
+ }
+
+ /* Generic error return - leave the prefix, delete the compressed
+ * data, reallocate the chunkdata to remove the potentially large
+ * amount of compressed data.
+ */
+ {
+ png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
+ if (text != NULL)
+ {
+ if (prefix_size > 0)
+ png_memcpy(text, png_ptr->chunkdata, prefix_size);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = text;
+
+ /* This is an extra zero in the 'uncompressed' part. */
+ *(png_ptr->chunkdata + prefix_size) = 0x00;
+ }
+ /* Ignore a malloc error here - it is safe. */
+ }
+
+ *newlength = prefix_size;
+}
+#endif
+
+/* Read and check the IDHR chunk */
+void /* PRIVATE */
+png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[13];
+ png_uint_32 width, height;
+ int bit_depth, color_type, compression_type, filter_type;
+ int interlace_type;
+
+ png_debug(1, "in png_handle_IHDR");
+
+ if (png_ptr->mode & PNG_HAVE_IHDR)
+ png_error(png_ptr, "Out of place IHDR");
+
+ /* Check the length */
+ if (length != 13)
+ png_error(png_ptr, "Invalid IHDR chunk");
+
+ png_ptr->mode |= PNG_HAVE_IHDR;
+
+ png_crc_read(png_ptr, buf, 13);
+ png_crc_finish(png_ptr, 0);
+
+ width = png_get_uint_31(png_ptr, buf);
+ height = png_get_uint_31(png_ptr, buf + 4);
+ bit_depth = buf[8];
+ color_type = buf[9];
+ compression_type = buf[10];
+ filter_type = buf[11];
+ interlace_type = buf[12];
+
+ /* Set internal variables */
+ png_ptr->width = width;
+ png_ptr->height = height;
+ png_ptr->bit_depth = (png_byte)bit_depth;
+ png_ptr->interlaced = (png_byte)interlace_type;
+ png_ptr->color_type = (png_byte)color_type;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ png_ptr->filter_type = (png_byte)filter_type;
+#endif
+ png_ptr->compression_type = (png_byte)compression_type;
+
+ /* Find number of channels */
+ switch (png_ptr->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_PALETTE:
+ png_ptr->channels = 1;
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ png_ptr->channels = 3;
+ break;
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ png_ptr->channels = 2;
+ break;
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ png_ptr->channels = 4;
+ break;
+ }
+
+ /* Set up other useful info */
+ png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
+ png_ptr->channels);
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
+ png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
+ png_debug1(3, "channels = %d", png_ptr->channels);
+ png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
+ png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
+ color_type, interlace_type, compression_type, filter_type);
+}
+
+/* Read and check the palette */
+void /* PRIVATE */
+png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_color palette[PNG_MAX_PALETTE_LENGTH];
+ int num, i;
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ png_colorp pal_ptr;
+#endif
+
+ png_debug(1, "in png_handle_PLTE");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before PLTE");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid PLTE after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ png_error(png_ptr, "Duplicate PLTE chunk");
+
+ png_ptr->mode |= PNG_HAVE_PLTE;
+
+ if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
+ {
+ png_warning(png_ptr,
+ "Ignoring PLTE chunk in grayscale PNG");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
+ {
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ png_warning(png_ptr, "Invalid palette chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ else
+ {
+ png_error(png_ptr, "Invalid palette chunk");
+ }
+ }
+
+ num = (int)length / 3;
+
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ pal_ptr->red = buf[0];
+ pal_ptr->green = buf[1];
+ pal_ptr->blue = buf[2];
+ }
+#else
+ for (i = 0; i < num; i++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ /* Don't depend upon png_color being any order */
+ palette[i].red = buf[0];
+ palette[i].green = buf[1];
+ palette[i].blue = buf[2];
+ }
+#endif
+
+ /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
+ * whatever the normal CRC configuration tells us. However, if we
+ * have an RGB image, the PLTE can be considered ancillary, so
+ * we will act as though it is.
+ */
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#endif
+ {
+ png_crc_finish(png_ptr, 0);
+ }
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
+ {
+ /* If we don't want to use the data from an ancillary chunk,
+ we have two options: an error abort, or a warning and we
+ ignore the data in this chunk (which should be OK, since
+ it's considered ancillary for a RGB or RGBA image). */
+ if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
+ {
+ png_chunk_error(png_ptr, "CRC error");
+ }
+ else
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ return;
+ }
+ }
+ /* Otherwise, we (optionally) emit a warning and use the chunk. */
+ else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ }
+ }
+#endif
+
+ png_set_PLTE(png_ptr, info_ptr, palette, num);
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ if (png_ptr->num_trans > (png_uint_16)num)
+ {
+ png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
+ png_ptr->num_trans = (png_uint_16)num;
+ }
+ if (info_ptr->num_trans > (png_uint_16)num)
+ {
+ png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
+ info_ptr->num_trans = (png_uint_16)num;
+ }
+ }
+ }
+#endif
+
+}
+
+void /* PRIVATE */
+png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_debug(1, "in png_handle_IEND");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
+ {
+ png_error(png_ptr, "No image in file");
+ }
+
+ png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
+
+ if (length != 0)
+ {
+ png_warning(png_ptr, "Incorrect IEND chunk length");
+ }
+ png_crc_finish(png_ptr, length);
+
+ info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
+}
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+void /* PRIVATE */
+png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_fixed_point igamma;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float file_gamma;
+#endif
+ png_byte buf[4];
+
+ png_debug(1, "in png_handle_gAMA");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before gAMA");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid gAMA after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place gAMA chunk");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+#ifdef PNG_READ_sRGB_SUPPORTED
+ && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+ )
+ {
+ png_warning(png_ptr, "Duplicate gAMA chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 4)
+ {
+ png_warning(png_ptr, "Incorrect gAMA chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 4);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ igamma = (png_fixed_point)png_get_uint_32(buf);
+ /* Check for zero gamma */
+ if (igamma == 0)
+ {
+ png_warning(png_ptr,
+ "Ignoring gAMA chunk with gamma=0");
+ return;
+ }
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
+ if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
+ {
+ png_warning(png_ptr,
+ "Ignoring incorrect gAMA value when sRGB is also present");
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+ fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
+#endif
+ return;
+ }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ file_gamma = (float)igamma / (float)100000.0;
+# ifdef PNG_READ_GAMMA_SUPPORTED
+ png_ptr->gamma = file_gamma;
+# endif
+ png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
+#endif
+}
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+void /* PRIVATE */
+png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_size_t truelen;
+ png_byte buf[4];
+
+ png_debug(1, "in png_handle_sBIT");
+
+ buf[0] = buf[1] = buf[2] = buf[3] = 0;
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sBIT");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sBIT after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ {
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place sBIT chunk");
+ }
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
+ {
+ png_warning(png_ptr, "Duplicate sBIT chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ truelen = 3;
+ else
+ truelen = (png_size_t)png_ptr->channels;
+
+ if (length != truelen || length > 4)
+ {
+ png_warning(png_ptr, "Incorrect sBIT chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, truelen);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_ptr->sig_bit.red = buf[0];
+ png_ptr->sig_bit.green = buf[1];
+ png_ptr->sig_bit.blue = buf[2];
+ png_ptr->sig_bit.alpha = buf[3];
+ }
+ else
+ {
+ png_ptr->sig_bit.gray = buf[0];
+ png_ptr->sig_bit.red = buf[0];
+ png_ptr->sig_bit.green = buf[0];
+ png_ptr->sig_bit.blue = buf[0];
+ png_ptr->sig_bit.alpha = buf[1];
+ }
+ png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
+}
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+void /* PRIVATE */
+png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[32];
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+ png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+ int_y_green, int_x_blue, int_y_blue;
+
+ png_uint_32 uint_x, uint_y;
+
+ png_debug(1, "in png_handle_cHRM");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before cHRM");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid cHRM after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Missing PLTE before cHRM");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
+#ifdef PNG_READ_sRGB_SUPPORTED
+ && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+ )
+ {
+ png_warning(png_ptr, "Duplicate cHRM chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 32)
+ {
+ png_warning(png_ptr, "Incorrect cHRM chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 32);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ uint_x = png_get_uint_32(buf);
+ uint_y = png_get_uint_32(buf + 4);
+ int_x_white = (png_fixed_point)uint_x;
+ int_y_white = (png_fixed_point)uint_y;
+
+ uint_x = png_get_uint_32(buf + 8);
+ uint_y = png_get_uint_32(buf + 12);
+ int_x_red = (png_fixed_point)uint_x;
+ int_y_red = (png_fixed_point)uint_y;
+
+ uint_x = png_get_uint_32(buf + 16);
+ uint_y = png_get_uint_32(buf + 20);
+ int_x_green = (png_fixed_point)uint_x;
+ int_y_green = (png_fixed_point)uint_y;
+
+ uint_x = png_get_uint_32(buf + 24);
+ uint_y = png_get_uint_32(buf + 28);
+ int_x_blue = (png_fixed_point)uint_x;
+ int_y_blue = (png_fixed_point)uint_y;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ white_x = (float)int_x_white / (float)100000.0;
+ white_y = (float)int_y_white / (float)100000.0;
+ red_x = (float)int_x_red / (float)100000.0;
+ red_y = (float)int_y_red / (float)100000.0;
+ green_x = (float)int_x_green / (float)100000.0;
+ green_y = (float)int_y_green / (float)100000.0;
+ blue_x = (float)int_x_blue / (float)100000.0;
+ blue_y = (float)int_y_blue / (float)100000.0;
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+ if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
+ {
+ if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
+ PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
+ PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
+ PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
+ PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
+ PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
+ PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
+ PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
+ {
+ png_warning(png_ptr,
+ "Ignoring incorrect cHRM value when sRGB is also present");
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
+ white_x, white_y, red_x, red_y);
+ fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
+ green_x, green_y, blue_x, blue_y);
+#else
+ fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
+ (long)int_x_white, (long)int_y_white,
+ (long)int_x_red, (long)int_y_red);
+ fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
+ (long)int_x_green, (long)int_y_green,
+ (long)int_x_blue, (long)int_y_blue);
+#endif
+#endif /* PNG_CONSOLE_IO_SUPPORTED */
+ }
+ return;
+ }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_set_cHRM(png_ptr, info_ptr,
+ white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_set_cHRM_fixed(png_ptr, info_ptr,
+ int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+ int_y_green, int_x_blue, int_y_blue);
+#endif
+}
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+void /* PRIVATE */
+png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ int intent;
+ png_byte buf[1];
+
+ png_debug(1, "in png_handle_sRGB");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sRGB");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sRGB after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place sRGB chunk");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
+ {
+ png_warning(png_ptr, "Duplicate sRGB chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 1)
+ {
+ png_warning(png_ptr, "Incorrect sRGB chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 1);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ intent = buf[0];
+ /* Check for bad intent */
+ if (intent >= PNG_sRGB_INTENT_LAST)
+ {
+ png_warning(png_ptr, "Unknown sRGB intent");
+ return;
+ }
+
+#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
+ {
+ png_fixed_point igamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ igamma=info_ptr->int_gamma;
+#else
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
+# endif
+#endif
+ if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
+ {
+ png_warning(png_ptr,
+ "Ignoring incorrect gAMA value when sRGB is also present");
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+# ifdef PNG_FIXED_POINT_SUPPORTED
+ fprintf(stderr, "incorrect gamma=(%d/100000)\n",
+ (int)png_ptr->int_gamma);
+# else
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
+# endif
+# endif
+#endif
+ }
+ }
+#endif /* PNG_READ_gAMA_SUPPORTED */
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+ if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
+ PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
+ {
+ png_warning(png_ptr,
+ "Ignoring incorrect cHRM value when sRGB is also present");
+ }
+#endif /* PNG_FIXED_POINT_SUPPORTED */
+#endif /* PNG_READ_cHRM_SUPPORTED */
+
+ png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
+}
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+void /* PRIVATE */
+png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+ png_byte compression_type;
+ png_bytep pC;
+ png_charp profile;
+ png_uint_32 skip = 0;
+ png_uint_32 profile_size, profile_length;
+ png_size_t slength, prefix_length, data_length;
+
+ png_debug(1, "in png_handle_iCCP");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before iCCP");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid iCCP after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place iCCP chunk");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
+ {
+ png_warning(png_ptr, "Duplicate iCCP chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "iCCP chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+
+ if (png_crc_finish(png_ptr, skip))
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
+ png_ptr->chunkdata[slength] = 0x00;
+
+ for (profile = png_ptr->chunkdata; *profile; profile++)
+ /* Empty loop to find end of name */ ;
+
+ ++profile;
+
+ /* There should be at least one zero (the compression type byte)
+ * following the separator, and we should be on it
+ */
+ if ( profile >= png_ptr->chunkdata + slength - 1)
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_warning(png_ptr, "Malformed iCCP chunk");
+ return;
+ }
+
+ /* Compression_type should always be zero */
+ compression_type = *profile++;
+ if (compression_type)
+ {
+ png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
+ compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
+ wrote nonzero) */
+ }
+
+ prefix_length = profile - png_ptr->chunkdata;
+ png_decompress_chunk(png_ptr, compression_type,
+ slength, prefix_length, &data_length);
+
+ profile_length = data_length - prefix_length;
+
+ if ( prefix_length > data_length || profile_length < 4)
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_warning(png_ptr, "Profile size field missing from iCCP chunk");
+ return;
+ }
+
+ /* Check the profile_size recorded in the first 32 bits of the ICC profile */
+ pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
+ profile_size = ((*(pC ))<<24) |
+ ((*(pC + 1))<<16) |
+ ((*(pC + 2))<< 8) |
+ ((*(pC + 3)) );
+
+ if (profile_size < profile_length)
+ profile_length = profile_size;
+
+ if (profile_size > profile_length)
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_warning(png_ptr, "Ignoring truncated iCCP profile.");
+ return;
+ }
+
+ png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
+ compression_type, png_ptr->chunkdata + prefix_length, profile_length);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+}
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+void /* PRIVATE */
+png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+ png_bytep entry_start;
+ png_sPLT_t new_palette;
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ png_sPLT_entryp pp;
+#endif
+ int data_length, entry_size, i;
+ png_uint_32 skip = 0;
+ png_size_t slength;
+
+ png_debug(1, "in png_handle_sPLT");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_warning(png_ptr, "No space in chunk cache for sPLT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sPLT");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sPLT after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "sPLT chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+
+ if (png_crc_finish(png_ptr, skip))
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
+ png_ptr->chunkdata[slength] = 0x00;
+
+ for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
+ entry_start++)
+ /* Empty loop to find end of name */ ;
+ ++entry_start;
+
+ /* A sample depth should follow the separator, and we should be on it */
+ if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_warning(png_ptr, "malformed sPLT chunk");
+ return;
+ }
+
+ new_palette.depth = *entry_start++;
+ entry_size = (new_palette.depth == 8 ? 6 : 10);
+ data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
+
+ /* Integrity-check the data length */
+ if (data_length % entry_size)
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_warning(png_ptr, "sPLT chunk has bad length");
+ return;
+ }
+
+ new_palette.nentries = (png_int_32) ( data_length / entry_size);
+ if ((png_uint_32) new_palette.nentries >
+ (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
+ {
+ png_warning(png_ptr, "sPLT chunk too long");
+ return;
+ }
+ new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
+ png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
+ if (new_palette.entries == NULL)
+ {
+ png_warning(png_ptr, "sPLT chunk requires too much memory");
+ return;
+ }
+
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ for (i = 0; i < new_palette.nentries; i++)
+ {
+ pp = new_palette.entries + i;
+
+ if (new_palette.depth == 8)
+ {
+ pp->red = *entry_start++;
+ pp->green = *entry_start++;
+ pp->blue = *entry_start++;
+ pp->alpha = *entry_start++;
+ }
+ else
+ {
+ pp->red = png_get_uint_16(entry_start); entry_start += 2;
+ pp->green = png_get_uint_16(entry_start); entry_start += 2;
+ pp->blue = png_get_uint_16(entry_start); entry_start += 2;
+ pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
+ }
+ pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+ }
+#else
+ pp = new_palette.entries;
+ for (i = 0; i < new_palette.nentries; i++)
+ {
+
+ if (new_palette.depth == 8)
+ {
+ pp[i].red = *entry_start++;
+ pp[i].green = *entry_start++;
+ pp[i].blue = *entry_start++;
+ pp[i].alpha = *entry_start++;
+ }
+ else
+ {
+ pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
+ }
+ pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+ }
+#endif
+
+ /* Discard all chunk data except the name and stash that */
+ new_palette.name = png_ptr->chunkdata;
+
+ png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
+
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_free(png_ptr, new_palette.entries);
+}
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+void /* PRIVATE */
+png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
+
+ png_debug(1, "in png_handle_tRNS");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before tRNS");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid tRNS after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ png_warning(png_ptr, "Duplicate tRNS chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_byte buf[2];
+
+ if (length != 2)
+ {
+ png_warning(png_ptr, "Incorrect tRNS chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 2);
+ png_ptr->num_trans = 1;
+ png_ptr->trans_values.gray = png_get_uint_16(buf);
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_byte buf[6];
+
+ if (length != 6)
+ {
+ png_warning(png_ptr, "Incorrect tRNS chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ png_crc_read(png_ptr, buf, (png_size_t)length);
+ png_ptr->num_trans = 1;
+ png_ptr->trans_values.red = png_get_uint_16(buf);
+ png_ptr->trans_values.green = png_get_uint_16(buf + 2);
+ png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (!(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ /* Should be an error, but we can cope with it. */
+ png_warning(png_ptr, "Missing PLTE before tRNS");
+ }
+ if (length > (png_uint_32)png_ptr->num_palette ||
+ length > PNG_MAX_PALETTE_LENGTH)
+ {
+ png_warning(png_ptr, "Incorrect tRNS chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ if (length == 0)
+ {
+ png_warning(png_ptr, "Zero length tRNS chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ png_crc_read(png_ptr, readbuf, (png_size_t)length);
+ png_ptr->num_trans = (png_uint_16)length;
+ }
+ else
+ {
+ png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_ptr->num_trans = 0;
+ return;
+ }
+
+ png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
+ &(png_ptr->trans_values));
+}
+#endif
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+void /* PRIVATE */
+png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_size_t truelen;
+ png_byte buf[6];
+
+ png_debug(1, "in png_handle_bKGD");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before bKGD");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid bKGD after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ png_warning(png_ptr, "Missing PLTE before bKGD");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
+ {
+ png_warning(png_ptr, "Duplicate bKGD chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ truelen = 1;
+ else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ truelen = 6;
+ else
+ truelen = 2;
+
+ if (length != truelen)
+ {
+ png_warning(png_ptr, "Incorrect bKGD chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, truelen);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ /* We convert the index value into RGB components so that we can allow
+ * arbitrary RGB values for background when we have transparency, and
+ * so it is easy to determine the RGB values of the background color
+ * from the info_ptr struct. */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_ptr->background.index = buf[0];
+ if (info_ptr && info_ptr->num_palette)
+ {
+ if (buf[0] >= info_ptr->num_palette)
+ {
+ png_warning(png_ptr, "Incorrect bKGD chunk index value");
+ return;
+ }
+ png_ptr->background.red =
+ (png_uint_16)png_ptr->palette[buf[0]].red;
+ png_ptr->background.green =
+ (png_uint_16)png_ptr->palette[buf[0]].green;
+ png_ptr->background.blue =
+ (png_uint_16)png_ptr->palette[buf[0]].blue;
+ }
+ }
+ else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
+ {
+ png_ptr->background.red =
+ png_ptr->background.green =
+ png_ptr->background.blue =
+ png_ptr->background.gray = png_get_uint_16(buf);
+ }
+ else
+ {
+ png_ptr->background.red = png_get_uint_16(buf);
+ png_ptr->background.green = png_get_uint_16(buf + 2);
+ png_ptr->background.blue = png_get_uint_16(buf + 4);
+ }
+
+ png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
+}
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+void /* PRIVATE */
+png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ unsigned int num, i;
+ png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
+
+ png_debug(1, "in png_handle_hIST");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before hIST");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid hIST after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (!(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ png_warning(png_ptr, "Missing PLTE before hIST");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
+ {
+ png_warning(png_ptr, "Duplicate hIST chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ num = length / 2 ;
+ if (num != (unsigned int) png_ptr->num_palette || num >
+ (unsigned int) PNG_MAX_PALETTE_LENGTH)
+ {
+ png_warning(png_ptr, "Incorrect hIST chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ for (i = 0; i < num; i++)
+ {
+ png_byte buf[2];
+
+ png_crc_read(png_ptr, buf, 2);
+ readbuf[i] = png_get_uint_16(buf);
+ }
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ png_set_hIST(png_ptr, info_ptr, readbuf);
+}
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+void /* PRIVATE */
+png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[9];
+ png_uint_32 res_x, res_y;
+ int unit_type;
+
+ png_debug(1, "in png_handle_pHYs");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before pHYs");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid pHYs after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_warning(png_ptr, "Duplicate pHYs chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_warning(png_ptr, "Incorrect pHYs chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 9);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ res_x = png_get_uint_32(buf);
+ res_y = png_get_uint_32(buf + 4);
+ unit_type = buf[8];
+ png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
+}
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+void /* PRIVATE */
+png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[9];
+ png_int_32 offset_x, offset_y;
+ int unit_type;
+
+ png_debug(1, "in png_handle_oFFs");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before oFFs");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid oFFs after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+ {
+ png_warning(png_ptr, "Duplicate oFFs chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_warning(png_ptr, "Incorrect oFFs chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 9);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ offset_x = png_get_int_32(buf);
+ offset_y = png_get_int_32(buf + 4);
+ unit_type = buf[8];
+ png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
+}
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+/* Read the pCAL chunk (described in the PNG Extensions document) */
+void /* PRIVATE */
+png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_int_32 X0, X1;
+ png_byte type, nparams;
+ png_charp buf, units, endptr;
+ png_charpp params;
+ png_size_t slength;
+ int i;
+
+ png_debug(1, "in png_handle_pCAL");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before pCAL");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid pCAL after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
+ {
+ png_warning(png_ptr, "Duplicate pCAL chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
+ length + 1);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (png_ptr->chunkdata == NULL)
+ {
+ png_warning(png_ptr, "No memory for pCAL purpose.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
+ png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
+
+ png_debug(3, "Finding end of pCAL purpose string");
+ for (buf = png_ptr->chunkdata; *buf; buf++)
+ /* Empty loop */ ;
+
+ endptr = png_ptr->chunkdata + slength;
+
+ /* We need to have at least 12 bytes after the purpose string
+ in order to get the parameter information. */
+ if (endptr <= buf + 12)
+ {
+ png_warning(png_ptr, "Invalid pCAL data");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
+ png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
+ X0 = png_get_int_32((png_bytep)buf+1);
+ X1 = png_get_int_32((png_bytep)buf+5);
+ type = buf[9];
+ nparams = buf[10];
+ units = buf + 11;
+
+ png_debug(3, "Checking pCAL equation type and number of parameters");
+ /* Check that we have the right number of parameters for known
+ equation types. */
+ if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
+ (type == PNG_EQUATION_BASE_E && nparams != 3) ||
+ (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
+ (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
+ {
+ png_warning(png_ptr, "Invalid pCAL parameters for equation type");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+ else if (type >= PNG_EQUATION_LAST)
+ {
+ png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+ }
+
+ for (buf = units; *buf; buf++)
+ /* Empty loop to move past the units string. */ ;
+
+ png_debug(3, "Allocating pCAL parameters array");
+ params = (png_charpp)png_malloc_warn(png_ptr,
+ (png_uint_32)(nparams * png_sizeof(png_charp))) ;
+ if (params == NULL)
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_warning(png_ptr, "No memory for pCAL params.");
+ return;
+ }
+
+ /* Get pointers to the start of each parameter string. */
+ for (i = 0; i < (int)nparams; i++)
+ {
+ buf++; /* Skip the null string terminator from previous parameter. */
+
+ png_debug1(3, "Reading pCAL parameter %d", i);
+ for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
+ /* Empty loop to move past each parameter string */ ;
+
+ /* Make sure we haven't run out of data yet */
+ if (buf > endptr)
+ {
+ png_warning(png_ptr, "Invalid pCAL data");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_free(png_ptr, params);
+ return;
+ }
+ }
+
+ png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
+ units, params);
+
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_free(png_ptr, params);
+}
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+/* Read the sCAL chunk */
+void /* PRIVATE */
+png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_charp ep;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ double width, height;
+ png_charp vp;
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_charp swidth, sheight;
+#endif
+#endif
+ png_size_t slength;
+
+ png_debug(1, "in png_handle_sCAL");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sCAL");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sCAL after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ png_warning(png_ptr, "Duplicate sCAL chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ /* Need unit type, width, \0, height: minimum 4 bytes */
+ else if (length < 4)
+ {
+ png_warning(png_ptr, "sCAL chunk too short");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
+ length + 1);
+ png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (png_ptr->chunkdata == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
+ png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
+
+ ep = png_ptr->chunkdata + 1; /* Skip unit byte */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ width = png_strtod(png_ptr, ep, &vp);
+ if (*vp)
+ {
+ png_warning(png_ptr, "malformed width string in sCAL chunk");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
+ if (swidth == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+ png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
+#endif
+#endif
+
+ for (ep = png_ptr->chunkdata; *ep; ep++)
+ /* Empty loop */ ;
+ ep++;
+
+ if (png_ptr->chunkdata + slength < ep)
+ {
+ png_warning(png_ptr, "Truncated sCAL chunk");
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, swidth);
+#endif
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ height = png_strtod(png_ptr, ep, &vp);
+ if (*vp)
+ {
+ png_warning(png_ptr, "malformed height string in sCAL chunk");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, swidth);
+#endif
+ return;
+ }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
+ if (sheight == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, swidth);
+#endif
+ return;
+ }
+ png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
+#endif
+#endif
+
+ if (png_ptr->chunkdata + slength < ep
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ || width <= 0. || height <= 0.
+#endif
+ )
+ {
+ png_warning(png_ptr, "Invalid sCAL data");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, swidth);
+ png_free(png_ptr, sheight);
+#endif
+ return;
+ }
+
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
+#endif
+#endif
+
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, swidth);
+ png_free(png_ptr, sheight);
+#endif
+}
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+void /* PRIVATE */
+png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[7];
+ png_time mod_time;
+
+ png_debug(1, "in png_handle_tIME");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Out of place tIME chunk");
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
+ {
+ png_warning(png_ptr, "Duplicate tIME chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ if (length != 7)
+ {
+ png_warning(png_ptr, "Incorrect tIME chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 7);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ mod_time.second = buf[6];
+ mod_time.minute = buf[5];
+ mod_time.hour = buf[4];
+ mod_time.day = buf[3];
+ mod_time.month = buf[2];
+ mod_time.year = png_get_uint_16(buf);
+
+ png_set_tIME(png_ptr, info_ptr, &mod_time);
+}
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_textp text_ptr;
+ png_charp key;
+ png_charp text;
+ png_uint_32 skip = 0;
+ png_size_t slength;
+ int ret;
+
+ png_debug(1, "in png_handle_tEXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_warning(png_ptr, "No space in chunk cache for tEXt");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before tEXt");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ png_free(png_ptr, png_ptr->chunkdata);
+
+ png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (png_ptr->chunkdata == NULL)
+ {
+ png_warning(png_ptr, "No memory to process text chunk.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+
+ if (png_crc_finish(png_ptr, skip))
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
+ key = png_ptr->chunkdata;
+
+ key[slength] = 0x00;
+
+ for (text = key; *text; text++)
+ /* Empty loop to find end of key */ ;
+
+ if (text != key + slength)
+ text++;
+
+ text_ptr = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+ if (text_ptr == NULL)
+ {
+ png_warning(png_ptr, "Not enough memory to process text chunk.");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+ text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+ text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+ text_ptr->itxt_length = 0;
+#endif
+ text_ptr->text = text;
+ text_ptr->text_length = png_strlen(text);
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_free(png_ptr, text_ptr);
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to process text chunk.");
+}
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+/* Note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_textp text_ptr;
+ png_charp text;
+ int comp_type;
+ int ret;
+ png_size_t slength, prefix_len, data_len;
+
+ png_debug(1, "in png_handle_zTXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_warning(png_ptr, "No space in chunk cache for zTXt");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before zTXt");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ /* We will no doubt have problems with chunks even half this size, but
+ there is no hard and fast rule to tell us where to stop. */
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "zTXt chunk too large to fit in memory");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (png_ptr->chunkdata == NULL)
+ {
+ png_warning(png_ptr, "Out of memory processing zTXt chunk.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
+ png_ptr->chunkdata[slength] = 0x00;
+
+ for (text = png_ptr->chunkdata; *text; text++)
+ /* Empty loop */ ;
+
+ /* zTXt must have some text after the chunkdataword */
+ if (text >= png_ptr->chunkdata + slength - 2)
+ {
+ png_warning(png_ptr, "Truncated zTXt chunk");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+ else
+ {
+ comp_type = *(++text);
+ if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
+ {
+ png_warning(png_ptr, "Unknown compression type in zTXt chunk");
+ comp_type = PNG_TEXT_COMPRESSION_zTXt;
+ }
+ text++; /* Skip the compression_method byte */
+ }
+ prefix_len = text - png_ptr->chunkdata;
+
+ png_decompress_chunk(png_ptr, comp_type,
+ (png_size_t)length, prefix_len, &data_len);
+
+ text_ptr = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+ if (text_ptr == NULL)
+ {
+ png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+ text_ptr->compression = comp_type;
+ text_ptr->key = png_ptr->chunkdata;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+ text_ptr->itxt_length = 0;
+#endif
+ text_ptr->text = png_ptr->chunkdata + prefix_len;
+ text_ptr->text_length = data_len;
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, text_ptr);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ if (ret)
+ png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
+}
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+/* Note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_textp text_ptr;
+ png_charp key, lang, text, lang_key;
+ int comp_flag;
+ int comp_type = 0;
+ int ret;
+ png_size_t slength, prefix_len, data_len;
+
+ png_debug(1, "in png_handle_iTXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_warning(png_ptr, "No space in chunk cache for iTXt");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before iTXt");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ /* We will no doubt have problems with chunks even half this size, but
+ there is no hard and fast rule to tell us where to stop. */
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "iTXt chunk too large to fit in memory");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (png_ptr->chunkdata == NULL)
+ {
+ png_warning(png_ptr, "No memory to process iTXt chunk.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
+ png_ptr->chunkdata[slength] = 0x00;
+
+ for (lang = png_ptr->chunkdata; *lang; lang++)
+ /* Empty loop */ ;
+ lang++; /* Skip NUL separator */
+
+ /* iTXt must have a language tag (possibly empty), two compression bytes,
+ * translated keyword (possibly empty), and possibly some text after the
+ * keyword
+ */
+
+ if (lang >= png_ptr->chunkdata + slength - 3)
+ {
+ png_warning(png_ptr, "Truncated iTXt chunk");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+ else
+ {
+ comp_flag = *lang++;
+ comp_type = *lang++;
+ }
+
+ for (lang_key = lang; *lang_key; lang_key++)
+ /* Empty loop */ ;
+ lang_key++; /* Skip NUL separator */
+
+ if (lang_key >= png_ptr->chunkdata + slength)
+ {
+ png_warning(png_ptr, "Truncated iTXt chunk");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
+ for (text = lang_key; *text; text++)
+ /* Empty loop */ ;
+ text++; /* Skip NUL separator */
+ if (text >= png_ptr->chunkdata + slength)
+ {
+ png_warning(png_ptr, "Malformed iTXt chunk");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
+ prefix_len = text - png_ptr->chunkdata;
+
+ key=png_ptr->chunkdata;
+ if (comp_flag)
+ png_decompress_chunk(png_ptr, comp_type,
+ (size_t)length, prefix_len, &data_len);
+ else
+ data_len = png_strlen(png_ptr->chunkdata + prefix_len);
+ text_ptr = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)png_sizeof(png_text));
+ if (text_ptr == NULL)
+ {
+ png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+ text_ptr->compression = (int)comp_flag + 1;
+ text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
+ text_ptr->lang = png_ptr->chunkdata + (lang - key);
+ text_ptr->itxt_length = data_len;
+ text_ptr->text_length = 0;
+ text_ptr->key = png_ptr->chunkdata;
+ text_ptr->text = png_ptr->chunkdata + prefix_len;
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, text_ptr);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ if (ret)
+ png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
+}
+#endif
+
+/* This function is called when we haven't found a handler for a
+ chunk. If there isn't a problem with the chunk itself (ie bad
+ chunk name, CRC, or a critical chunk), the chunk is silently ignored
+ -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
+ case it will be saved away to be written out later. */
+void /* PRIVATE */
+png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_uint_32 skip = 0;
+
+ png_debug(1, "in png_handle_unknown");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_warning(png_ptr, "No space in chunk cache for unknown chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ }
+#endif
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IDAT;
+#endif
+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ }
+
+ if (!(png_ptr->chunk_name[0] & 0x20))
+ {
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ PNG_HANDLE_CHUNK_ALWAYS
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+ && png_ptr->read_user_chunk_fn == NULL
+#endif
+ )
+#endif
+ png_chunk_error(png_ptr, "unknown critical chunk");
+ }
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+ if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+ || (png_ptr->read_user_chunk_fn != NULL)
+#endif
+ )
+ {
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "unknown chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+ png_memcpy((png_charp)png_ptr->unknown_chunk.name,
+ (png_charp)png_ptr->chunk_name,
+ png_sizeof(png_ptr->unknown_chunk.name));
+ png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
+ = '\0';
+ png_ptr->unknown_chunk.size = (png_size_t)length;
+ if (length == 0)
+ png_ptr->unknown_chunk.data = NULL;
+ else
+ {
+ png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
+ png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
+ }
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+ if (png_ptr->read_user_chunk_fn != NULL)
+ {
+ /* Callback to user unknown chunk handler */
+ int ret;
+ ret = (*(png_ptr->read_user_chunk_fn))
+ (png_ptr, &png_ptr->unknown_chunk);
+ if (ret < 0)
+ png_chunk_error(png_ptr, "error in user chunk");
+ if (ret == 0)
+ {
+ if (!(png_ptr->chunk_name[0] & 0x20))
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ PNG_HANDLE_CHUNK_ALWAYS)
+#endif
+ png_chunk_error(png_ptr, "unknown critical chunk");
+ png_set_unknown_chunks(png_ptr, info_ptr,
+ &png_ptr->unknown_chunk, 1);
+ }
+ }
+ else
+#endif
+ png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
+ }
+ else
+#endif
+ skip = length;
+
+ png_crc_finish(png_ptr, skip);
+
+#ifndef PNG_READ_USER_CHUNKS_SUPPORTED
+ info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
+#endif
+}
+
+/* This function is called to verify that a chunk name is valid.
+ This function can't have the "critical chunk check" incorporated
+ into it, since in the future we will need to be able to call user
+ functions to handle unknown critical chunks after we check that
+ the chunk name itself is valid. */
+
+#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+
+void /* PRIVATE */
+png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
+{
+ png_debug(1, "in png_check_chunk_name");
+ if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
+ isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
+ {
+ png_chunk_error(png_ptr, "invalid chunk type");
+ }
+}
+
+/* Combines the row recently read in with the existing pixels in the
+ row. This routine takes care of alpha and transparency if requested.
+ This routine also handles the two methods of progressive display
+ of interlaced images, depending on the mask value.
+ The mask value describes which pixels are to be combined with
+ the row. The pattern always repeats every 8 pixels, so just 8
+ bits are needed. A one indicates the pixel is to be combined,
+ a zero indicates the pixel is to be skipped. This is in addition
+ to any alpha or transparency value associated with the pixel. If
+ you want all pixels to be combined, pass 0xff (255) in mask. */
+
+void /* PRIVATE */
+png_combine_row(png_structp png_ptr, png_bytep row, int mask)
+{
+ png_debug(1, "in png_combine_row");
+ if (mask == 0xff)
+ {
+ png_memcpy(row, png_ptr->row_buf + 1,
+ PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
+ }
+ else
+ {
+ switch (png_ptr->row_info.pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ int s_inc, s_start, s_end;
+ int m = 0x80;
+ int shift;
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+ else
+#endif
+ {
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+
+ shift = s_start;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & mask)
+ {
+ int value;
+
+ value = (*sp >> shift) & 0x01;
+ *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ int s_start, s_end, s_inc;
+ int m = 0x80;
+ int shift;
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+ int value;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+ else
+#endif
+ {
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+
+ shift = s_start;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & mask)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ int s_start, s_end, s_inc;
+ int m = 0x80;
+ int shift;
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+ int value;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+ else
+#endif
+ {
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+ shift = s_start;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & mask)
+ {
+ value = (*sp >> shift) & 0xf;
+ *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ default:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+ png_byte m = 0x80;
+
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & mask)
+ {
+ png_memcpy(dp, sp, pixel_bytes);
+ }
+
+ sp += pixel_bytes;
+ dp += pixel_bytes;
+
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ }
+ }
+}
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* OLD pre-1.0.9 interface:
+void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
+ png_uint_32 transformations)
+ */
+void /* PRIVATE */
+png_do_read_interlace(png_structp png_ptr)
+{
+ png_row_infop row_info = &(png_ptr->row_info);
+ png_bytep row = png_ptr->row_buf + 1;
+ int pass = png_ptr->pass;
+ png_uint_32 transformations = png_ptr->transformations;
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+ /* Offset to next interlace block */
+ PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ png_debug(1, "in png_do_read_interlace");
+ if (row != NULL && row_info != NULL)
+ {
+ png_uint_32 final_width;
+
+ final_width = row_info->width * png_pass_inc[pass];
+
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ int jstop = png_pass_inc[pass];
+ png_byte v;
+ png_uint_32 i;
+ int j;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)((row_info->width + 7) & 0x07);
+ dshift = (int)((final_width + 7) & 0x07);
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+ else
+#endif
+ {
+ sshift = 7 - (int)((row_info->width + 7) & 0x07);
+ dshift = 7 - (int)((final_width + 7) & 0x07);
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ v = (png_byte)((*sp >> sshift) & 0x01);
+ for (j = 0; j < jstop; j++)
+ {
+ *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
+ png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ int jstop = png_pass_inc[pass];
+ png_uint_32 i;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)(((row_info->width + 3) & 0x03) << 1);
+ dshift = (int)(((final_width + 3) & 0x03) << 1);
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+ else
+#endif
+ {
+ sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
+ dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v;
+ int j;
+
+ v = (png_byte)((*sp >> sshift) & 0x03);
+ for (j = 0; j < jstop; j++)
+ {
+ *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ png_uint_32 i;
+ int jstop = png_pass_inc[pass];
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)(((row_info->width + 1) & 0x01) << 2);
+ dshift = (int)(((final_width + 1) & 0x01) << 2);
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+ else
+#endif
+ {
+ sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
+ dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v = (png_byte)((*sp >> sshift) & 0xf);
+ int j;
+
+ for (j = 0; j < jstop; j++)
+ {
+ *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+ default:
+ {
+ png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
+ png_bytep sp = row + (png_size_t)(row_info->width - 1)
+ * pixel_bytes;
+ png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
+
+ int jstop = png_pass_inc[pass];
+ png_uint_32 i;
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v[8];
+ int j;
+
+ png_memcpy(v, sp, pixel_bytes);
+ for (j = 0; j < jstop; j++)
+ {
+ png_memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+ sp -= pixel_bytes;
+ }
+ break;
+ }
+ }
+ row_info->width = final_width;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
+ }
+#ifndef PNG_READ_PACKSWAP_SUPPORTED
+ transformations = transformations; /* Silence compiler warning */
+#endif
+}
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+void /* PRIVATE */
+png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
+ png_bytep prev_row, int filter)
+{
+ png_debug(1, "in png_read_filter_row");
+ png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
+ switch (filter)
+ {
+ case PNG_FILTER_VALUE_NONE:
+ break;
+ case PNG_FILTER_VALUE_SUB:
+ {
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_bytep rp = row + bpp;
+ png_bytep lp = row;
+
+ for (i = bpp; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ case PNG_FILTER_VALUE_UP:
+ {
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ case PNG_FILTER_VALUE_AVG:
+ {
+ png_uint_32 i;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+ png_bytep lp = row;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_uint_32 istop = row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ ((int)(*pp++) / 2 )) & 0xff);
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *lp++) / 2 ) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ case PNG_FILTER_VALUE_PAETH:
+ {
+ png_uint_32 i;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+ png_bytep lp = row;
+ png_bytep cp = prev_row;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_uint_32 istop=row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++) /* Use leftover rp,pp */
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ a = *lp++;
+ b = *pp++;
+ c = *cp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ /*
+ if (pa <= pb && pa <= pc)
+ p = a;
+ else if (pb <= pc)
+ p = b;
+ else
+ p = c;
+ */
+
+ p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
+
+ *rp = (png_byte)(((int)(*rp) + p) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ default:
+ png_warning(png_ptr, "Ignoring bad adaptive filter type");
+ *row = 0;
+ break;
+ }
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+void /* PRIVATE */
+png_read_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+ png_debug(1, "in png_read_finish_row");
+ png_ptr->row_number++;
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+ png_memset_check(png_ptr, png_ptr->prev_row, 0,
+ png_ptr->rowbytes + 1);
+ do
+ {
+ png_ptr->pass++;
+ if (png_ptr->pass >= 7)
+ break;
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+ if (!(png_ptr->num_rows))
+ continue;
+ }
+ else /* if (png_ptr->transformations & PNG_INTERLACE) */
+ break;
+ } while (png_ptr->iwidth == 0);
+
+ if (png_ptr->pass < 7)
+ return;
+ }
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_CONST PNG_IDAT;
+#endif
+ char extra;
+ int ret;
+
+ png_ptr->zstream.next_out = (Byte *)&extra;
+ png_ptr->zstream.avail_out = (uInt)1;
+ for (;;)
+ {
+ if (!(png_ptr->zstream.avail_in))
+ {
+ while (!png_ptr->idat_size)
+ {
+ png_byte chunk_length[4];
+
+ png_crc_finish(png_ptr, 0);
+
+ png_read_data(png_ptr, chunk_length, 4);
+ png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ png_error(png_ptr, "Not enough image data");
+
+ }
+ png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_in = png_ptr->zbuf;
+ if (png_ptr->zbuf_size > png_ptr->idat_size)
+ png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+ png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
+ png_ptr->idat_size -= png_ptr->zstream.avail_in;
+ }
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret == Z_STREAM_END)
+ {
+ if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
+ png_ptr->idat_size)
+ png_warning(png_ptr, "Extra compressed data.");
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+ if (ret != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+ "Decompression Error");
+
+ if (!(png_ptr->zstream.avail_out))
+ {
+ png_warning(png_ptr, "Extra compressed data.");
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+
+ }
+ png_ptr->zstream.avail_out = 0;
+ }
+
+ if (png_ptr->idat_size || png_ptr->zstream.avail_in)
+ png_warning(png_ptr, "Extra compression data.");
+
+ inflateReset(&png_ptr->zstream);
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+void /* PRIVATE */
+png_read_start_row(png_structp png_ptr)
+{
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ int max_pixel_depth;
+ png_size_t row_bytes;
+
+ png_debug(1, "in png_read_start_row");
+ png_ptr->zstream.avail_in = 0;
+ png_init_read_transformations(png_ptr);
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (png_ptr->interlaced)
+ {
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+ png_pass_ystart[0]) / png_pass_yinc[0];
+ else
+ png_ptr->num_rows = png_ptr->height;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+ }
+ else
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->iwidth = png_ptr->width;
+ }
+ max_pixel_depth = png_ptr->pixel_depth;
+
+#ifdef PNG_READ_PACK_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
+ max_pixel_depth = 8;
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (png_ptr->num_trans)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 24;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (max_pixel_depth < 8)
+ max_pixel_depth = 8;
+ if (png_ptr->num_trans)
+ max_pixel_depth *= 2;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (png_ptr->num_trans)
+ {
+ max_pixel_depth *= 4;
+ max_pixel_depth /= 3;
+ }
+ }
+ }
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+ if (png_ptr->transformations & (PNG_FILLER))
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ max_pixel_depth = 32;
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (max_pixel_depth <= 8)
+ max_pixel_depth = 16;
+ else
+ max_pixel_depth = 32;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (max_pixel_depth <= 32)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 64;
+ }
+ }
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+ {
+ if (
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
+#endif
+#ifdef PNG_READ_FILLER_SUPPORTED
+ (png_ptr->transformations & (PNG_FILLER)) ||
+#endif
+ png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (max_pixel_depth <= 16)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 64;
+ }
+ else
+ {
+ if (max_pixel_depth <= 8)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 24;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ max_pixel_depth = 64;
+ else
+ max_pixel_depth = 48;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
+defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ int user_pixel_depth = png_ptr->user_transform_depth*
+ png_ptr->user_transform_channels;
+ if (user_pixel_depth > max_pixel_depth)
+ max_pixel_depth=user_pixel_depth;
+ }
+#endif
+
+ /* Align the width on the next larger 8 pixels. Mainly used
+ * for interlacing
+ */
+ row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
+ /* Calculate the maximum bytes needed, adding a byte and a pixel
+ * for safety's sake
+ */
+ row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
+ 1 + ((max_pixel_depth + 7) >> 3);
+#ifdef PNG_MAX_MALLOC_64K
+ if (row_bytes > (png_uint_32)65536L)
+ png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+
+ if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
+ {
+ png_free(png_ptr, png_ptr->big_row_buf);
+ if (png_ptr->interlaced)
+ png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
+ row_bytes + 64);
+ else
+ png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
+ row_bytes + 64);
+ png_ptr->old_big_row_buf_size = row_bytes + 64;
+
+ /* Use 32 bytes of padding before and after row_buf. */
+ png_ptr->row_buf = png_ptr->big_row_buf + 32;
+ png_ptr->old_big_row_buf_size = row_bytes + 64;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L)
+ png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+ if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1))
+ png_error(png_ptr, "Row has too many bytes to allocate in memory.");
+
+ if (row_bytes + 1 > png_ptr->old_prev_row_size)
+ {
+ png_free(png_ptr, png_ptr->prev_row);
+ png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
+ row_bytes + 1));
+ png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1);
+ png_ptr->old_prev_row_size = row_bytes + 1;
+ }
+
+ png_ptr->rowbytes = row_bytes;
+
+ png_debug1(3, "width = %lu,", png_ptr->width);
+ png_debug1(3, "height = %lu,", png_ptr->height);
+ png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
+ png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
+ png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
+ png_debug1(3, "irowbytes = %lu",
+ PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
+
+ png_ptr->flags |= PNG_FLAG_ROW_INIT;
+}
+#endif /* PNG_READ_SUPPORTED */
diff --git a/src/libpng/pngset.c b/src/libpng/pngset.c
new file mode 100644
index 0000000..717757f
--- /dev/null
+++ b/src/libpng/pngset.c
@@ -0,0 +1,1226 @@
+
+/* pngset.c - storage of image information into info struct
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * The functions here are used during reads to store data from the file
+ * into the info struct, and during writes to store application data
+ * into the info struct for writing into the file. This abstracts the
+ * info struct and allows us to change the structure in the future.
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+#ifdef PNG_bKGD_SUPPORTED
+void PNGAPI
+png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
+{
+ png_debug1(1, "in %s storage function", "bKGD");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
+ info_ptr->valid |= PNG_INFO_bKGD;
+}
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
+ double white_x, double white_y, double red_x, double red_y,
+ double green_x, double green_y, double blue_x, double blue_y)
+{
+ png_debug1(1, "in %s storage function", "cHRM");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->x_white = (float)white_x;
+ info_ptr->y_white = (float)white_y;
+ info_ptr->x_red = (float)red_x;
+ info_ptr->y_red = (float)red_y;
+ info_ptr->x_green = (float)green_x;
+ info_ptr->y_green = (float)green_y;
+ info_ptr->x_blue = (float)blue_x;
+ info_ptr->y_blue = (float)blue_y;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
+ info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
+ info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5);
+ info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5);
+ info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
+ info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
+ info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5);
+ info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5);
+#endif
+ info_ptr->valid |= PNG_INFO_cHRM;
+}
+#endif /* PNG_FLOATING_POINT_SUPPORTED */
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+ png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
+ png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
+ png_fixed_point blue_x, png_fixed_point blue_y)
+{
+ png_debug1(1, "in %s storage function", "cHRM fixed");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+#ifdef PNG_CHECK_cHRM_SUPPORTED
+ if (png_check_cHRM_fixed(png_ptr,
+ white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y))
+#endif
+ {
+ info_ptr->int_x_white = white_x;
+ info_ptr->int_y_white = white_y;
+ info_ptr->int_x_red = red_x;
+ info_ptr->int_y_red = red_y;
+ info_ptr->int_x_green = green_x;
+ info_ptr->int_y_green = green_y;
+ info_ptr->int_x_blue = blue_x;
+ info_ptr->int_y_blue = blue_y;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ info_ptr->x_white = (float)(white_x/100000.);
+ info_ptr->y_white = (float)(white_y/100000.);
+ info_ptr->x_red = (float)( red_x/100000.);
+ info_ptr->y_red = (float)( red_y/100000.);
+ info_ptr->x_green = (float)(green_x/100000.);
+ info_ptr->y_green = (float)(green_y/100000.);
+ info_ptr->x_blue = (float)( blue_x/100000.);
+ info_ptr->y_blue = (float)( blue_y/100000.);
+#endif
+ info_ptr->valid |= PNG_INFO_cHRM;
+ }
+}
+#endif /* PNG_FIXED_POINT_SUPPORTED */
+#endif /* PNG_cHRM_SUPPORTED */
+
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
+{
+ double png_gamma;
+
+ png_debug1(1, "in %s storage function", "gAMA");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* Check for overflow */
+ if (file_gamma > 21474.83)
+ {
+ png_warning(png_ptr, "Limiting gamma to 21474.83");
+ png_gamma=21474.83;
+ }
+ else
+ png_gamma = file_gamma;
+ info_ptr->gamma = (float)png_gamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_gamma = (int)(png_gamma*100000.+.5);
+#endif
+ info_ptr->valid |= PNG_INFO_gAMA;
+ if (png_gamma == 0.0)
+ png_warning(png_ptr, "Setting gamma=0");
+}
+#endif
+void PNGAPI
+png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
+ int_gamma)
+{
+ png_fixed_point png_gamma;
+
+ png_debug1(1, "in %s storage function", "gAMA");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (int_gamma > (png_fixed_point)PNG_UINT_31_MAX)
+ {
+ png_warning(png_ptr, "Limiting gamma to 21474.83");
+ png_gamma=PNG_UINT_31_MAX;
+ }
+ else
+ {
+ if (int_gamma < 0)
+ {
+ png_warning(png_ptr, "Setting negative gamma to zero");
+ png_gamma = 0;
+ }
+ else
+ png_gamma = int_gamma;
+ }
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ info_ptr->gamma = (float)(png_gamma/100000.);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_gamma = png_gamma;
+#endif
+ info_ptr->valid |= PNG_INFO_gAMA;
+ if (png_gamma == 0)
+ png_warning(png_ptr, "Setting gamma=0");
+}
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+void PNGAPI
+png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
+{
+ int i;
+
+ png_debug1(1, "in %s storage function", "hIST");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (info_ptr->num_palette == 0 || info_ptr->num_palette
+ > PNG_MAX_PALETTE_LENGTH)
+ {
+ png_warning(png_ptr,
+ "Invalid palette size, hIST allocation skipped.");
+ return;
+ }
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
+#endif
+ /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
+ * version 1.2.1
+ */
+ png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
+ (png_uint_32)(PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16)));
+ if (png_ptr->hist == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for hIST chunk data.");
+ return;
+ }
+
+ for (i = 0; i < info_ptr->num_palette; i++)
+ png_ptr->hist[i] = hist[i];
+ info_ptr->hist = png_ptr->hist;
+ info_ptr->valid |= PNG_INFO_hIST;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_HIST;
+#else
+ png_ptr->flags |= PNG_FLAG_FREE_HIST;
+#endif
+}
+#endif
+
+void PNGAPI
+png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type)
+{
+ png_debug1(1, "in %s storage function", "IHDR");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->width = width;
+ info_ptr->height = height;
+ info_ptr->bit_depth = (png_byte)bit_depth;
+ info_ptr->color_type = (png_byte)color_type;
+ info_ptr->compression_type = (png_byte)compression_type;
+ info_ptr->filter_type = (png_byte)filter_type;
+ info_ptr->interlace_type = (png_byte)interlace_type;
+
+ png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
+ info_ptr->compression_type, info_ptr->filter_type);
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ info_ptr->channels = 1;
+ else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ info_ptr->channels = 3;
+ else
+ info_ptr->channels = 1;
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+ info_ptr->channels++;
+ info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
+
+ /* Check for potential overflow */
+ if (width > (PNG_UINT_32_MAX
+ >> 3) /* 8-byte RGBA pixels */
+ - 64 /* bigrowbuf hack */
+ - 1 /* filter byte */
+ - 7*8 /* rounding of width to multiple of 8 pixels */
+ - 8) /* extra max_pixel_depth pad */
+ info_ptr->rowbytes = (png_size_t)0;
+ else
+ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
+}
+
+#ifdef PNG_oFFs_SUPPORTED
+void PNGAPI
+png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
+ png_int_32 offset_x, png_int_32 offset_y, int unit_type)
+{
+ png_debug1(1, "in %s storage function", "oFFs");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->x_offset = offset_x;
+ info_ptr->y_offset = offset_y;
+ info_ptr->offset_unit_type = (png_byte)unit_type;
+ info_ptr->valid |= PNG_INFO_oFFs;
+}
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+void PNGAPI
+png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
+ png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
+ png_charp units, png_charpp params)
+{
+ png_uint_32 length;
+ int i;
+
+ png_debug1(1, "in %s storage function", "pCAL");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ length = png_strlen(purpose) + 1;
+ png_debug1(3, "allocating purpose for info (%lu bytes)",
+ (unsigned long)length);
+ info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->pcal_purpose == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL purpose.");
+ return;
+ }
+ png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
+
+ png_debug(3, "storing X0, X1, type, and nparams in info");
+ info_ptr->pcal_X0 = X0;
+ info_ptr->pcal_X1 = X1;
+ info_ptr->pcal_type = (png_byte)type;
+ info_ptr->pcal_nparams = (png_byte)nparams;
+
+ length = png_strlen(units) + 1;
+ png_debug1(3, "allocating units for info (%lu bytes)",
+ (unsigned long)length);
+ info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->pcal_units == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL units.");
+ return;
+ }
+ png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
+
+ info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
+ (png_uint_32)((nparams + 1) * png_sizeof(png_charp)));
+ if (info_ptr->pcal_params == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL params.");
+ return;
+ }
+
+ png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp));
+
+ for (i = 0; i < nparams; i++)
+ {
+ length = png_strlen(params[i]) + 1;
+ png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
+ (unsigned long)length);
+ info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->pcal_params[i] == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL parameter.");
+ return;
+ }
+ png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
+ }
+
+ info_ptr->valid |= PNG_INFO_pCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_PCAL;
+#endif
+}
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
+ int unit, double width, double height)
+{
+ png_debug1(1, "in %s storage function", "sCAL");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->scal_unit = (png_byte)unit;
+ info_ptr->scal_pixel_width = width;
+ info_ptr->scal_pixel_height = height;
+
+ info_ptr->valid |= PNG_INFO_sCAL;
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+ int unit, png_charp swidth, png_charp sheight)
+{
+ png_uint_32 length;
+
+ png_debug1(1, "in %s storage function", "sCAL");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->scal_unit = (png_byte)unit;
+
+ length = png_strlen(swidth) + 1;
+ png_debug1(3, "allocating unit for info (%u bytes)",
+ (unsigned int)length);
+ info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->scal_s_width == NULL)
+ {
+ png_warning(png_ptr,
+ "Memory allocation failed while processing sCAL.");
+ return;
+ }
+ png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
+
+ length = png_strlen(sheight) + 1;
+ png_debug1(3, "allocating unit for info (%u bytes)",
+ (unsigned int)length);
+ info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->scal_s_height == NULL)
+ {
+ png_free (png_ptr, info_ptr->scal_s_width);
+ info_ptr->scal_s_width = NULL;
+ png_warning(png_ptr,
+ "Memory allocation failed while processing sCAL.");
+ return;
+ }
+ png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
+ info_ptr->valid |= PNG_INFO_sCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_SCAL;
+#endif
+}
+#endif
+#endif
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+void PNGAPI
+png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 res_x, png_uint_32 res_y, int unit_type)
+{
+ png_debug1(1, "in %s storage function", "pHYs");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->x_pixels_per_unit = res_x;
+ info_ptr->y_pixels_per_unit = res_y;
+ info_ptr->phys_unit_type = (png_byte)unit_type;
+ info_ptr->valid |= PNG_INFO_pHYs;
+}
+#endif
+
+void PNGAPI
+png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
+ png_colorp palette, int num_palette)
+{
+
+ png_debug1(1, "in %s storage function", "PLTE");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
+ {
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_error(png_ptr, "Invalid palette length");
+ else
+ {
+ png_warning(png_ptr, "Invalid palette length");
+ return;
+ }
+ }
+
+ /* It may not actually be necessary to set png_ptr->palette here;
+ * we do it for backward compatibility with the way the png_handle_tRNS
+ * function used to do the allocation.
+ */
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
+#endif
+
+ /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
+ * of num_palette entries, in case of an invalid PNG file that has
+ * too-large sample values.
+ */
+ png_ptr->palette = (png_colorp)png_calloc(png_ptr,
+ PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
+ png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));
+ info_ptr->palette = png_ptr->palette;
+ info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_PLTE;
+#else
+ png_ptr->flags |= PNG_FLAG_FREE_PLTE;
+#endif
+
+ info_ptr->valid |= PNG_INFO_PLTE;
+}
+
+#ifdef PNG_sBIT_SUPPORTED
+void PNGAPI
+png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
+ png_color_8p sig_bit)
+{
+ png_debug1(1, "in %s storage function", "sBIT");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));
+ info_ptr->valid |= PNG_INFO_sBIT;
+}
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+void PNGAPI
+png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
+{
+ png_debug1(1, "in %s storage function", "sRGB");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->srgb_intent = (png_byte)intent;
+ info_ptr->valid |= PNG_INFO_sRGB;
+}
+
+void PNGAPI
+png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
+ int intent)
+{
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float file_gamma;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_fixed_point int_file_gamma;
+#endif
+#endif
+#ifdef PNG_cHRM_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+ png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
+ int_green_y, int_blue_x, int_blue_y;
+#endif
+ png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_set_sRGB(png_ptr, info_ptr, intent);
+
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ file_gamma = (float).45455;
+ png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ int_file_gamma = 45455L;
+ png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
+#endif
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+ int_white_x = 31270L;
+ int_white_y = 32900L;
+ int_red_x = 64000L;
+ int_red_y = 33000L;
+ int_green_x = 30000L;
+ int_green_y = 60000L;
+ int_blue_x = 15000L;
+ int_blue_y = 6000L;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ white_x = (float).3127;
+ white_y = (float).3290;
+ red_x = (float).64;
+ red_y = (float).33;
+ green_x = (float).30;
+ green_y = (float).60;
+ blue_x = (float).15;
+ blue_y = (float).06;
+#endif
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_set_cHRM_fixed(png_ptr, info_ptr,
+ int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
+ int_green_y, int_blue_x, int_blue_y);
+#endif
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_set_cHRM(png_ptr, info_ptr,
+ white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#endif /* cHRM */
+}
+#endif /* sRGB */
+
+
+#ifdef PNG_iCCP_SUPPORTED
+void PNGAPI
+png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
+ png_charp name, int compression_type,
+ png_charp profile, png_uint_32 proflen)
+{
+ png_charp new_iccp_name;
+ png_charp new_iccp_profile;
+ png_uint_32 length;
+
+ png_debug1(1, "in %s storage function", "iCCP");
+
+ if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
+ return;
+
+ length = png_strlen(name)+1;
+ new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);
+ if (new_iccp_name == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory to process iCCP chunk.");
+ return;
+ }
+ png_memcpy(new_iccp_name, name, length);
+ new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen);
+ if (new_iccp_profile == NULL)
+ {
+ png_free (png_ptr, new_iccp_name);
+ png_warning(png_ptr,
+ "Insufficient memory to process iCCP profile.");
+ return;
+ }
+ png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
+
+ info_ptr->iccp_proflen = proflen;
+ info_ptr->iccp_name = new_iccp_name;
+ info_ptr->iccp_profile = new_iccp_profile;
+ /* Compression is always zero but is here so the API and info structure
+ * does not have to change if we introduce multiple compression types
+ */
+ info_ptr->iccp_compression = (png_byte)compression_type;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_ICCP;
+#endif
+ info_ptr->valid |= PNG_INFO_iCCP;
+}
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+void PNGAPI
+png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
+ int num_text)
+{
+ int ret;
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
+ if (ret)
+ png_error(png_ptr, "Insufficient memory to store text");
+}
+
+int /* PRIVATE */
+png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
+ int num_text)
+{
+ int i;
+
+ png_debug1(1, "in %s storage function", ((png_ptr == NULL ||
+ png_ptr->chunk_name[0] == '\0') ?
+ "text" : (png_const_charp)png_ptr->chunk_name));
+
+ if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
+ return(0);
+
+ /* Make sure we have enough space in the "text" array in info_struct
+ * to hold all of the incoming text_ptr objects.
+ */
+ if (info_ptr->num_text + num_text > info_ptr->max_text)
+ {
+ if (info_ptr->text != NULL)
+ {
+ png_textp old_text;
+ int old_max;
+
+ old_max = info_ptr->max_text;
+ info_ptr->max_text = info_ptr->num_text + num_text + 8;
+ old_text = info_ptr->text;
+ info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)(info_ptr->max_text * png_sizeof(png_text)));
+ if (info_ptr->text == NULL)
+ {
+ png_free(png_ptr, old_text);
+ return(1);
+ }
+ png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
+ png_sizeof(png_text)));
+ png_free(png_ptr, old_text);
+ }
+ else
+ {
+ info_ptr->max_text = num_text + 8;
+ info_ptr->num_text = 0;
+ info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)(info_ptr->max_text * png_sizeof(png_text)));
+ if (info_ptr->text == NULL)
+ return(1);
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_TEXT;
+#endif
+ }
+ png_debug1(3, "allocated %d entries for info_ptr->text",
+ info_ptr->max_text);
+ }
+ for (i = 0; i < num_text; i++)
+ {
+ png_size_t text_length, key_len;
+ png_size_t lang_len, lang_key_len;
+ png_textp textp = &(info_ptr->text[info_ptr->num_text]);
+
+ if (text_ptr[i].key == NULL)
+ continue;
+
+ key_len = png_strlen(text_ptr[i].key);
+
+ if (text_ptr[i].compression <= 0)
+ {
+ lang_len = 0;
+ lang_key_len = 0;
+ }
+
+ else
+#ifdef PNG_iTXt_SUPPORTED
+ {
+ /* Set iTXt data */
+
+ if (text_ptr[i].lang != NULL)
+ lang_len = png_strlen(text_ptr[i].lang);
+ else
+ lang_len = 0;
+ if (text_ptr[i].lang_key != NULL)
+ lang_key_len = png_strlen(text_ptr[i].lang_key);
+ else
+ lang_key_len = 0;
+ }
+#else /* PNG_iTXt_SUPPORTED */
+ {
+ png_warning(png_ptr, "iTXt chunk not supported.");
+ continue;
+ }
+#endif
+
+ if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
+ {
+ text_length = 0;
+#ifdef PNG_iTXt_SUPPORTED
+ if (text_ptr[i].compression > 0)
+ textp->compression = PNG_ITXT_COMPRESSION_NONE;
+ else
+#endif
+ textp->compression = PNG_TEXT_COMPRESSION_NONE;
+ }
+
+ else
+ {
+ text_length = png_strlen(text_ptr[i].text);
+ textp->compression = text_ptr[i].compression;
+ }
+
+ textp->key = (png_charp)png_malloc_warn(png_ptr,
+ (png_uint_32)
+ (key_len + text_length + lang_len + lang_key_len + 4));
+ if (textp->key == NULL)
+ return(1);
+ png_debug2(2, "Allocated %lu bytes at %x in png_set_text",
+ (png_uint_32)
+ (key_len + lang_len + lang_key_len + text_length + 4),
+ (int)textp->key);
+
+ png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len));
+ *(textp->key + key_len) = '\0';
+#ifdef PNG_iTXt_SUPPORTED
+ if (text_ptr[i].compression > 0)
+ {
+ textp->lang = textp->key + key_len + 1;
+ png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
+ *(textp->lang + lang_len) = '\0';
+ textp->lang_key = textp->lang + lang_len + 1;
+ png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
+ *(textp->lang_key + lang_key_len) = '\0';
+ textp->text = textp->lang_key + lang_key_len + 1;
+ }
+ else
+#endif
+ {
+#ifdef PNG_iTXt_SUPPORTED
+ textp->lang=NULL;
+ textp->lang_key=NULL;
+#endif
+ textp->text = textp->key + key_len + 1;
+ }
+ if (text_length)
+ png_memcpy(textp->text, text_ptr[i].text,
+ (png_size_t)(text_length));
+ *(textp->text + text_length) = '\0';
+
+#ifdef PNG_iTXt_SUPPORTED
+ if (textp->compression > 0)
+ {
+ textp->text_length = 0;
+ textp->itxt_length = text_length;
+ }
+ else
+#endif
+
+ {
+ textp->text_length = text_length;
+#ifdef PNG_iTXt_SUPPORTED
+ textp->itxt_length = 0;
+#endif
+ }
+ info_ptr->num_text++;
+ png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
+ }
+ return(0);
+}
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+void PNGAPI
+png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
+{
+ png_debug1(1, "in %s storage function", "tIME");
+
+ if (png_ptr == NULL || info_ptr == NULL ||
+ (png_ptr->mode & PNG_WROTE_tIME))
+ return;
+
+ png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
+ info_ptr->valid |= PNG_INFO_tIME;
+}
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+void PNGAPI
+png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
+ png_bytep trans, int num_trans, png_color_16p trans_values)
+{
+ png_debug1(1, "in %s storage function", "tRNS");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (trans != NULL)
+ {
+ /* It may not actually be necessary to set png_ptr->trans here;
+ * we do it for backward compatibility with the way the png_handle_tRNS
+ * function used to do the allocation.
+ */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
+#endif
+
+ /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
+ png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)PNG_MAX_PALETTE_LENGTH);
+ if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
+ png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans);
+ }
+
+ if (trans_values != NULL)
+ {
+ int sample_max = (1 << info_ptr->bit_depth);
+ if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
+ (int)trans_values->gray > sample_max) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
+ ((int)trans_values->red > sample_max ||
+ (int)trans_values->green > sample_max ||
+ (int)trans_values->blue > sample_max)))
+ png_warning(png_ptr,
+ "tRNS chunk has out-of-range samples for bit_depth");
+ png_memcpy(&(info_ptr->trans_values), trans_values,
+ png_sizeof(png_color_16));
+ if (num_trans == 0)
+ num_trans = 1;
+ }
+
+ info_ptr->num_trans = (png_uint_16)num_trans;
+ if (num_trans != 0)
+ {
+ info_ptr->valid |= PNG_INFO_tRNS;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_TRNS;
+#else
+ png_ptr->flags |= PNG_FLAG_FREE_TRNS;
+#endif
+ }
+}
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+void PNGAPI
+png_set_sPLT(png_structp png_ptr,
+ png_infop info_ptr, png_sPLT_tp entries, int nentries)
+/*
+ * entries - array of png_sPLT_t structures
+ * to be added to the list of palettes
+ * in the info structure.
+ * nentries - number of palette structures to be
+ * added.
+ */
+{
+ png_sPLT_tp np;
+ int i;
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ np = (png_sPLT_tp)png_malloc_warn(png_ptr,
+ (info_ptr->splt_palettes_num + nentries) *
+ (png_uint_32)png_sizeof(png_sPLT_t));
+ if (np == NULL)
+ {
+ png_warning(png_ptr, "No memory for sPLT palettes.");
+ return;
+ }
+
+ png_memcpy(np, info_ptr->splt_palettes,
+ info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
+ png_free(png_ptr, info_ptr->splt_palettes);
+ info_ptr->splt_palettes=NULL;
+
+ for (i = 0; i < nentries; i++)
+ {
+ png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
+ png_sPLT_tp from = entries + i;
+ png_uint_32 length;
+
+ length = png_strlen(from->name) + 1;
+ to->name = (png_charp)png_malloc_warn(png_ptr, length);
+ if (to->name == NULL)
+ {
+ png_warning(png_ptr,
+ "Out of memory while processing sPLT chunk");
+ continue;
+ }
+ png_memcpy(to->name, from->name, length);
+ to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
+ (png_uint_32)(from->nentries * png_sizeof(png_sPLT_entry)));
+ if (to->entries == NULL)
+ {
+ png_warning(png_ptr,
+ "Out of memory while processing sPLT chunk");
+ png_free(png_ptr, to->name);
+ to->name = NULL;
+ continue;
+ }
+ png_memcpy(to->entries, from->entries,
+ from->nentries * png_sizeof(png_sPLT_entry));
+ to->nentries = from->nentries;
+ to->depth = from->depth;
+ }
+
+ info_ptr->splt_palettes = np;
+ info_ptr->splt_palettes_num += nentries;
+ info_ptr->valid |= PNG_INFO_sPLT;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_SPLT;
+#endif
+}
+#endif /* PNG_sPLT_SUPPORTED */
+
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+void PNGAPI
+png_set_unknown_chunks(png_structp png_ptr,
+ png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
+{
+ png_unknown_chunkp np;
+ int i;
+
+ if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
+ return;
+
+ np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
+ (png_uint_32)((info_ptr->unknown_chunks_num + num_unknowns) *
+ png_sizeof(png_unknown_chunk)));
+ if (np == NULL)
+ {
+ png_warning(png_ptr,
+ "Out of memory while processing unknown chunk.");
+ return;
+ }
+
+ png_memcpy(np, info_ptr->unknown_chunks,
+ info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
+ png_free(png_ptr, info_ptr->unknown_chunks);
+ info_ptr->unknown_chunks = NULL;
+
+ for (i = 0; i < num_unknowns; i++)
+ {
+ png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
+ png_unknown_chunkp from = unknowns + i;
+
+ png_memcpy((png_charp)to->name, (png_charp)from->name,
+ png_sizeof(from->name));
+ to->name[png_sizeof(to->name)-1] = '\0';
+ to->size = from->size;
+ /* Note our location in the read or write sequence */
+ to->location = (png_byte)(png_ptr->mode & 0xff);
+
+ if (from->size == 0)
+ to->data=NULL;
+ else
+ {
+ to->data = (png_bytep)png_malloc_warn(png_ptr,
+ (png_uint_32)from->size);
+ if (to->data == NULL)
+ {
+ png_warning(png_ptr,
+ "Out of memory while processing unknown chunk.");
+ to->size = 0;
+ }
+ else
+ png_memcpy(to->data, from->data, from->size);
+ }
+ }
+
+ info_ptr->unknown_chunks = np;
+ info_ptr->unknown_chunks_num += num_unknowns;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_UNKN;
+#endif
+}
+void PNGAPI
+png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
+ int chunk, int location)
+{
+ if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
+ (int)info_ptr->unknown_chunks_num)
+ info_ptr->unknown_chunks[chunk].location = (png_byte)location;
+}
+#endif
+
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+void PNGAPI
+png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
+{
+ /* This function is deprecated in favor of png_permit_mng_features()
+ and will be removed from libpng-1.3.0 */
+
+ png_debug(1, "in png_permit_empty_plte, DEPRECATED.");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->mng_features_permitted = (png_byte)
+ ((png_ptr->mng_features_permitted & (~PNG_FLAG_MNG_EMPTY_PLTE)) |
+ ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
+}
+#endif
+#endif
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+png_uint_32 PNGAPI
+png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
+{
+ png_debug(1, "in png_permit_mng_features");
+
+ if (png_ptr == NULL)
+ return (png_uint_32)0;
+ png_ptr->mng_features_permitted =
+ (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
+ return (png_uint_32)png_ptr->mng_features_permitted;
+}
+#endif
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+void PNGAPI
+png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
+ chunk_list, int num_chunks)
+{
+ png_bytep new_list, p;
+ int i, old_num_chunks;
+ if (png_ptr == NULL)
+ return;
+ if (num_chunks == 0)
+ {
+ if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
+ png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+ else
+ png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+
+ if (keep == PNG_HANDLE_CHUNK_ALWAYS)
+ png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+ else
+ png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+ return;
+ }
+ if (chunk_list == NULL)
+ return;
+ old_num_chunks = png_ptr->num_chunk_list;
+ new_list=(png_bytep)png_malloc(png_ptr,
+ (png_uint_32)
+ (5*(num_chunks + old_num_chunks)));
+ if (png_ptr->chunk_list != NULL)
+ {
+ png_memcpy(new_list, png_ptr->chunk_list,
+ (png_size_t)(5*old_num_chunks));
+ png_free(png_ptr, png_ptr->chunk_list);
+ png_ptr->chunk_list=NULL;
+ }
+ png_memcpy(new_list + 5*old_num_chunks, chunk_list,
+ (png_size_t)(5*num_chunks));
+ for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5)
+ *p=(png_byte)keep;
+ png_ptr->num_chunk_list = old_num_chunks + num_chunks;
+ png_ptr->chunk_list = new_list;
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_ptr->free_me |= PNG_FREE_LIST;
+#endif
+}
+#endif
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+void PNGAPI
+png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
+ png_user_chunk_ptr read_user_chunk_fn)
+{
+ png_debug(1, "in png_set_read_user_chunk_fn");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->read_user_chunk_fn = read_user_chunk_fn;
+ png_ptr->user_chunk_ptr = user_chunk_ptr;
+}
+#endif
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
+{
+ png_debug1(1, "in %s storage function", "rows");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+ info_ptr->row_pointers = row_pointers;
+ if (row_pointers)
+ info_ptr->valid |= PNG_INFO_IDAT;
+}
+#endif
+
+void PNGAPI
+png_set_compression_buffer_size(png_structp png_ptr,
+ png_uint_32 size)
+{
+ if (png_ptr == NULL)
+ return;
+ png_free(png_ptr, png_ptr->zbuf);
+ png_ptr->zbuf_size = (png_size_t)size;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+}
+
+void PNGAPI
+png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
+{
+ if (png_ptr && info_ptr)
+ info_ptr->valid &= ~mask;
+}
+
+
+#ifndef PNG_1_0_X
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+/* Function was added to libpng 1.2.0 and should always exist by default */
+void PNGAPI
+png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags)
+{
+/* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */
+ if (png_ptr != NULL)
+ png_ptr->asm_flags = 0;
+ asm_flags = asm_flags; /* Quiet the compiler */
+}
+
+/* This function was added to libpng 1.2.0 */
+void PNGAPI
+png_set_mmx_thresholds (png_structp png_ptr,
+ png_byte mmx_bitdepth_threshold,
+ png_uint_32 mmx_rowbytes_threshold)
+{
+/* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */
+ if (png_ptr == NULL)
+ return;
+ /* Quiet the compiler */
+ mmx_bitdepth_threshold = mmx_bitdepth_threshold;
+ mmx_rowbytes_threshold = mmx_rowbytes_threshold;
+}
+#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* This function was added to libpng 1.2.6 */
+void PNGAPI
+png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
+ png_uint_32 user_height_max)
+{
+ /* Images with dimensions larger than these limits will be
+ * rejected by png_set_IHDR(). To accept any PNG datastream
+ * regardless of dimensions, set both limits to 0x7ffffffL.
+ */
+ if (png_ptr == NULL)
+ return;
+ png_ptr->user_width_max = user_width_max;
+ png_ptr->user_height_max = user_height_max;
+}
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
+
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_set_benign_errors(png_structp png_ptr, int allowed)
+{
+ png_debug(1, "in png_set_benign_errors");
+
+ if (allowed)
+ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
+ else
+ png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN;
+}
+#endif /* PNG_BENIGN_ERRORS_SUPPORTED */
+#endif /* ?PNG_1_0_X */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/src/libpng/pngtrans.c b/src/libpng/pngtrans.c
new file mode 100644
index 0000000..6ad9dcf
--- /dev/null
+++ b/src/libpng/pngtrans.c
@@ -0,0 +1,699 @@
+
+/* pngtrans.c - transforms the data in a row (used by both readers and writers)
+ *
+ * Last changed in libpng 1.2.41 [December 3, 2009]
+ * Copyright (c) 1998-2009 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Turn on BGR-to-RGB mapping */
+void PNGAPI
+png_set_bgr(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_bgr");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->transformations |= PNG_BGR;
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Turn on 16 bit byte swapping */
+void PNGAPI
+png_set_swap(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_swap");
+
+ if (png_ptr == NULL)
+ return;
+ if (png_ptr->bit_depth == 16)
+ png_ptr->transformations |= PNG_SWAP_BYTES;
+}
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Turn on pixel packing */
+void PNGAPI
+png_set_packing(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_packing");
+
+ if (png_ptr == NULL)
+ return;
+ if (png_ptr->bit_depth < 8)
+ {
+ png_ptr->transformations |= PNG_PACK;
+ png_ptr->usr_bit_depth = 8;
+ }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Turn on packed pixel swapping */
+void PNGAPI
+png_set_packswap(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_packswap");
+
+ if (png_ptr == NULL)
+ return;
+ if (png_ptr->bit_depth < 8)
+ png_ptr->transformations |= PNG_PACKSWAP;
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+void PNGAPI
+png_set_shift(png_structp png_ptr, png_color_8p true_bits)
+{
+ png_debug(1, "in png_set_shift");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->transformations |= PNG_SHIFT;
+ png_ptr->shift = *true_bits;
+}
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+int PNGAPI
+png_set_interlace_handling(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_interlace handling");
+
+ if (png_ptr && png_ptr->interlaced)
+ {
+ png_ptr->transformations |= PNG_INTERLACE;
+ return (7);
+ }
+
+ return (1);
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte on read, or remove a filler or alpha byte on write.
+ * The filler type has changed in v0.95 to allow future 2-byte fillers
+ * for 48-bit input data, as well as to avoid problems with some compilers
+ * that don't like bytes as parameters.
+ */
+void PNGAPI
+png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+{
+ png_debug(1, "in png_set_filler");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->transformations |= PNG_FILLER;
+#ifdef PNG_LEGACY_SUPPORTED
+ png_ptr->filler = (png_byte)filler;
+#else
+ png_ptr->filler = (png_uint_16)filler;
+#endif
+ if (filler_loc == PNG_FILLER_AFTER)
+ png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
+ else
+ png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
+
+ /* This should probably go in the "do_read_filler" routine.
+ * I attempted to do that in libpng-1.0.1a but that caused problems
+ * so I restored it in libpng-1.0.2a
+ */
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_ptr->usr_channels = 4;
+ }
+
+ /* Also I added this in libpng-1.0.2a (what happens when we expand
+ * a less-than-8-bit grayscale to GA? */
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
+ {
+ png_ptr->usr_channels = 2;
+ }
+}
+
+#ifndef PNG_1_0_X
+/* Added to libpng-1.2.7 */
+void PNGAPI
+png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+{
+ png_debug(1, "in png_set_add_alpha");
+
+ if (png_ptr == NULL)
+ return;
+ png_set_filler(png_ptr, filler, filler_loc);
+ png_ptr->transformations |= PNG_ADD_ALPHA;
+}
+#endif
+
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_swap_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_swap_alpha");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->transformations |= PNG_SWAP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_invert_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_invert_alpha");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->transformations |= PNG_INVERT_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+void PNGAPI
+png_set_invert_mono(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_invert_mono");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->transformations |= PNG_INVERT_MONO;
+}
+
+/* Invert monochrome grayscale data */
+void /* PRIVATE */
+png_do_invert(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_invert");
+
+ /* This test removed from libpng version 1.0.13 and 1.2.0:
+ * if (row_info->bit_depth == 1 &&
+ */
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row == NULL || row_info == NULL)
+ return;
+#endif
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(~(*rp));
+ rp++;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ row_info->bit_depth == 8)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i+=2)
+ {
+ *rp = (png_byte)(~(*rp));
+ rp+=2;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ row_info->bit_depth == 16)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i+=4)
+ {
+ *rp = (png_byte)(~(*rp));
+ *(rp+1) = (png_byte)(~(*(rp+1)));
+ rp+=4;
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swaps byte order on 16 bit depth images */
+void /* PRIVATE */
+png_do_swap(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_swap");
+
+ if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->bit_depth == 16)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop= row_info->width * row_info->channels;
+
+ for (i = 0; i < istop; i++, rp += 2)
+ {
+ png_byte t = *rp;
+ *rp = *(rp + 1);
+ *(rp + 1) = t;
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+static PNG_CONST png_byte onebppswaptable[256] = {
+ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+ 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+ 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+ 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+ 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+ 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+ 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+ 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+ 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+ 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+ 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+ 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+ 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+ 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+ 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+ 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+ 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+ 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+ 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+ 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+ 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+ 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+ 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+ 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+ 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+ 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+ 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+ 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+ 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+ 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+ 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+ 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+};
+
+static PNG_CONST png_byte twobppswaptable[256] = {
+ 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
+ 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
+ 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
+ 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
+ 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
+ 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
+ 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
+ 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
+ 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
+ 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
+ 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
+ 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
+ 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
+ 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
+ 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
+ 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
+ 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
+ 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
+ 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
+ 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
+ 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
+ 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
+ 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
+ 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
+ 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
+ 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
+ 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
+ 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
+ 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
+ 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
+ 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
+ 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
+};
+
+static PNG_CONST png_byte fourbppswaptable[256] = {
+ 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
+ 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
+ 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
+ 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
+ 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
+ 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
+ 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
+ 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
+ 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
+ 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
+ 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
+ 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
+ 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
+ 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
+ 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
+ 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
+ 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
+ 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
+ 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
+ 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
+ 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
+ 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
+ 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
+ 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
+ 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
+ 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
+ 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
+ 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
+ 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
+ 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
+ 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
+ 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
+};
+
+/* Swaps pixel packing order within bytes */
+void /* PRIVATE */
+png_do_packswap(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_packswap");
+
+ if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->bit_depth < 8)
+ {
+ png_bytep rp, end, table;
+
+ end = row + row_info->rowbytes;
+
+ if (row_info->bit_depth == 1)
+ table = (png_bytep)onebppswaptable;
+ else if (row_info->bit_depth == 2)
+ table = (png_bytep)twobppswaptable;
+ else if (row_info->bit_depth == 4)
+ table = (png_bytep)fourbppswaptable;
+ else
+ return;
+
+ for (rp = row; rp < end; rp++)
+ *rp = table[*rp];
+ }
+}
+#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+ defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+/* Remove filler or alpha byte(s) */
+void /* PRIVATE */
+png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
+{
+ png_debug(1, "in png_do_strip_filler");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ png_bytep sp=row;
+ png_bytep dp=row;
+ png_uint_32 row_width=row_info->width;
+ png_uint_32 i;
+
+ if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
+ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+ (flags & PNG_FLAG_STRIP_ALPHA))) &&
+ row_info->channels == 4)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This converts from RGBX or RGBA to RGB */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ dp+=3; sp+=4;
+ for (i = 1; i < row_width; i++)
+ {
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ sp++;
+ }
+ }
+ /* This converts from XRGB or ARGB to RGB */
+ else
+ {
+ for (i = 0; i < row_width; i++)
+ {
+ sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 24;
+ row_info->rowbytes = row_width * 3;
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
+ sp += 8; dp += 6;
+ for (i = 1; i < row_width; i++)
+ {
+ /* This could be (although png_memcpy is probably slower):
+ png_memcpy(dp, sp, 6);
+ sp += 8;
+ dp += 6;
+ */
+
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ sp += 2;
+ }
+ }
+ else
+ {
+ /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
+ for (i = 0; i < row_width; i++)
+ {
+ /* This could be (although png_memcpy is probably slower):
+ png_memcpy(dp, sp, 6);
+ sp += 8;
+ dp += 6;
+ */
+
+ sp+=2;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 48;
+ row_info->rowbytes = row_width * 6;
+ }
+ row_info->channels = 3;
+ }
+ else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
+ (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ (flags & PNG_FLAG_STRIP_ALPHA))) &&
+ row_info->channels == 2)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This converts from GX or GA to G */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ for (i = 0; i < row_width; i++)
+ {
+ *dp++ = *sp++;
+ sp++;
+ }
+ }
+ /* This converts from XG or AG to G */
+ else
+ {
+ for (i = 0; i < row_width; i++)
+ {
+ sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ /* This converts from GGXX or GGAA to GG */
+ sp += 4; dp += 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ sp += 2;
+ }
+ }
+ else
+ {
+ /* This converts from XXGG or AAGG to GG */
+ for (i = 0; i < row_width; i++)
+ {
+ sp += 2;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+ row_info->channels = 1;
+ }
+ if (flags & PNG_FLAG_STRIP_ALPHA)
+ row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+ }
+}
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Swaps red and blue bytes within a pixel */
+void /* PRIVATE */
+png_do_bgr(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_bgr");
+
+ if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 3)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 2);
+ *(rp + 2) = save;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 4)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 2);
+ *(rp + 2) = save;
+ }
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 6)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 4);
+ *(rp + 4) = save;
+ save = *(rp + 1);
+ *(rp + 1) = *(rp + 5);
+ *(rp + 5) = save;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 8)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 4);
+ *(rp + 4) = save;
+ save = *(rp + 1);
+ *(rp + 1) = *(rp + 5);
+ *(rp + 5) = save;
+ }
+ }
+ }
+ }
+}
+#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void PNGAPI
+png_set_user_transform_info(png_structp png_ptr, png_voidp
+ user_transform_ptr, int user_transform_depth, int user_transform_channels)
+{
+ png_debug(1, "in png_set_user_transform_info");
+
+ if (png_ptr == NULL)
+ return;
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+ png_ptr->user_transform_ptr = user_transform_ptr;
+ png_ptr->user_transform_depth = (png_byte)user_transform_depth;
+ png_ptr->user_transform_channels = (png_byte)user_transform_channels;
+#else
+ if (user_transform_ptr || user_transform_depth || user_transform_channels)
+ png_warning(png_ptr,
+ "This version of libpng does not support user transform info");
+#endif
+}
+#endif
+
+/* This function returns a pointer to the user_transform_ptr associated with
+ * the user transform functions. The application should free any memory
+ * associated with this pointer before png_write_destroy and png_read_destroy
+ * are called.
+ */
+png_voidp PNGAPI
+png_get_user_transform_ptr(png_structp png_ptr)
+{
+ if (png_ptr == NULL)
+ return (NULL);
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+ return ((png_voidp)png_ptr->user_transform_ptr);
+#else
+ return (NULL);
+#endif
+}
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/src/libpng/pngvcrd.c b/src/libpng/pngvcrd.c
new file mode 100644
index 0000000..ce4233e
--- /dev/null
+++ b/src/libpng/pngvcrd.c
@@ -0,0 +1 @@
+/* pnggvrd.c was removed from libpng-1.2.20. */
diff --git a/src/libpng/pngwio.c b/src/libpng/pngwio.c
new file mode 100644
index 0000000..44e5ea9
--- /dev/null
+++ b/src/libpng/pngwio.c
@@ -0,0 +1,260 @@
+
+/* pngwio.c - functions for data output
+ *
+ * Last changed in libpng 1.2.41 [December 3, 2009]
+ * Copyright (c) 1998-2009 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all output. Users who need
+ * special handling are expected to write functions that have the same
+ * arguments as these and perform similar functions, but that possibly
+ * use different output methods. Note that you shouldn't change these
+ * functions, but rather write replacement functions and then change
+ * them at run time with png_set_write_fn(...).
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Write the data to whatever output you are using. The default routine
+ * writes to a file pointer. Note that this routine sometimes gets called
+ * with very small lengths, so you should implement some kind of simple
+ * buffering if you are using unbuffered writes. This should never be asked
+ * to write more than 64K on a 16 bit machine.
+ */
+
+void /* PRIVATE */
+png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ if (png_ptr->write_data_fn != NULL )
+ (*(png_ptr->write_data_fn))(png_ptr, data, length);
+ else
+ png_error(png_ptr, "Call to NULL write function");
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+/* This is the function that does the actual writing of data. If you are
+ * not writing to a standard C stream, you should create a replacement
+ * write_data function and use it at run time with png_set_write_fn(), rather
+ * than changing the library.
+ */
+#ifndef USE_FAR_KEYWORD
+void PNGAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_uint_32 check;
+
+ if (png_ptr == NULL)
+ return;
+#ifdef _WIN32_WCE
+ if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+ check = 0;
+#else
+ check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
+#endif
+ if (check != length)
+ png_error(png_ptr, "Write Error");
+}
+#else
+/* This is the model-independent version. Since the standard I/O library
+ * can't handle far buffers in the medium and small models, we have to copy
+ * the data.
+ */
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+void PNGAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_uint_32 check;
+ png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
+ png_FILE_p io_ptr;
+
+ if (png_ptr == NULL)
+ return;
+ /* Check if data really is near. If so, use usual code. */
+ near_data = (png_byte *)CVT_PTR_NOCHECK(data);
+ io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+ if ((png_bytep)near_data == data)
+ {
+#ifdef _WIN32_WCE
+ if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
+ check = 0;
+#else
+ check = fwrite(near_data, 1, length, io_ptr);
+#endif
+ }
+ else
+ {
+ png_byte buf[NEAR_BUF_SIZE];
+ png_size_t written, remaining, err;
+ check = 0;
+ remaining = length;
+ do
+ {
+ written = MIN(NEAR_BUF_SIZE, remaining);
+ png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
+#ifdef _WIN32_WCE
+ if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
+ err = 0;
+#else
+ err = fwrite(buf, 1, written, io_ptr);
+#endif
+ if (err != written)
+ break;
+
+ else
+ check += err;
+
+ data += written;
+ remaining -= written;
+ }
+ while (remaining != 0);
+ }
+ if (check != length)
+ png_error(png_ptr, "Write Error");
+}
+
+#endif
+#endif
+
+/* This function is called to output any data pending writing (normally
+ * to disk). After png_flush is called, there should be no data pending
+ * writing in any buffers.
+ */
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+void /* PRIVATE */
+png_flush(png_structp png_ptr)
+{
+ if (png_ptr->output_flush_fn != NULL)
+ (*(png_ptr->output_flush_fn))(png_ptr);
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+void PNGAPI
+png_default_flush(png_structp png_ptr)
+{
+#ifndef _WIN32_WCE
+ png_FILE_p io_ptr;
+#endif
+ if (png_ptr == NULL)
+ return;
+#ifndef _WIN32_WCE
+ io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
+ fflush(io_ptr);
+#endif
+}
+#endif
+#endif
+
+/* This function allows the application to supply new output functions for
+ * libpng if standard C streams aren't being used.
+ *
+ * This function takes as its arguments:
+ * png_ptr - pointer to a png output data structure
+ * io_ptr - pointer to user supplied structure containing info about
+ * the output functions. May be NULL.
+ * write_data_fn - pointer to a new output function that takes as its
+ * arguments a pointer to a png_struct, a pointer to
+ * data to be written, and a 32-bit unsigned int that is
+ * the number of bytes to be written. The new write
+ * function should call png_error(png_ptr, "Error msg")
+ * to exit and output any fatal error messages. May be
+ * NULL, in which case libpng's default function will
+ * be used.
+ * flush_data_fn - pointer to a new flush function that takes as its
+ * arguments a pointer to a png_struct. After a call to
+ * the flush function, there should be no data in any buffers
+ * or pending transmission. If the output method doesn't do
+ * any buffering of output, a function prototype must still be
+ * supplied although it doesn't have to do anything. If
+ * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
+ * time, output_flush_fn will be ignored, although it must be
+ * supplied for compatibility. May be NULL, in which case
+ * libpng's default function will be used, if
+ * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not
+ * a good idea if io_ptr does not point to a standard
+ * *FILE structure.
+ */
+void PNGAPI
+png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
+ png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->io_ptr = io_ptr;
+
+#ifdef PNG_STDIO_SUPPORTED
+ if (write_data_fn != NULL)
+ png_ptr->write_data_fn = write_data_fn;
+
+ else
+ png_ptr->write_data_fn = png_default_write_data;
+#else
+ png_ptr->write_data_fn = write_data_fn;
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+#ifdef PNG_STDIO_SUPPORTED
+ if (output_flush_fn != NULL)
+ png_ptr->output_flush_fn = output_flush_fn;
+
+ else
+ png_ptr->output_flush_fn = png_default_flush;
+#else
+ png_ptr->output_flush_fn = output_flush_fn;
+#endif
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+ /* It is an error to read while writing a png file */
+ if (png_ptr->read_data_fn != NULL)
+ {
+ png_ptr->read_data_fn = NULL;
+ png_warning(png_ptr,
+ "Attempted to set both read_data_fn and write_data_fn in");
+ png_warning(png_ptr,
+ "the same structure. Resetting read_data_fn to NULL.");
+ }
+}
+
+#ifdef USE_FAR_KEYWORD
+#ifdef _MSC_VER
+void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
+{
+ void *near_ptr;
+ void FAR *far_ptr;
+ FP_OFF(near_ptr) = FP_OFF(ptr);
+ far_ptr = (void FAR *)near_ptr;
+
+ if (check != 0)
+ if (FP_SEG(ptr) != FP_SEG(far_ptr))
+ png_error(png_ptr, "segment lost in conversion");
+
+ return(near_ptr);
+}
+# else
+void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
+{
+ void *near_ptr;
+ void FAR *far_ptr;
+ near_ptr = (void FAR *)ptr;
+ far_ptr = (void FAR *)near_ptr;
+
+ if (check != 0)
+ if (far_ptr != ptr)
+ png_error(png_ptr, "segment lost in conversion");
+
+ return(near_ptr);
+}
+# endif
+# endif
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/src/libpng/pngwrite.c b/src/libpng/pngwrite.c
new file mode 100644
index 0000000..1d8c53f
--- /dev/null
+++ b/src/libpng/pngwrite.c
@@ -0,0 +1,1593 @@
+
+/* pngwrite.c - general routines to write a PNG file
+ *
+ * Last changed in libpng 1.2.45 [July 7, 2011]
+ * Copyright (c) 1998-2011 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* Get internal access to png.h */
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Writes all the PNG information. This is the suggested way to use the
+ * library. If you have a new chunk to add, make a function to write it,
+ * and put it in the correct location here. If you want the chunk written
+ * after the image data, put it in png_write_end(). I strongly encourage
+ * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
+ * the chunk, as that will keep the code from breaking if you want to just
+ * write a plain PNG file. If you have long comments, I suggest writing
+ * them in png_write_end(), and compressing them.
+ */
+void PNGAPI
+png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_write_info_before_PLTE");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+ {
+ /* Write PNG signature */
+ png_write_sig(png_ptr);
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \
+ (png_ptr->mng_features_permitted))
+ {
+ png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
+ png_ptr->mng_features_permitted = 0;
+ }
+#endif
+ /* Write IHDR information. */
+ png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
+ info_ptr->filter_type,
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ info_ptr->interlace_type);
+#else
+ 0);
+#endif
+ /* The rest of these check to see if the valid field has the appropriate
+ * flag set, and if it does, writes the chunk.
+ */
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_gAMA)
+ {
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_write_gAMA(png_ptr, info_ptr->gamma);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma);
+# endif
+#endif
+ }
+#endif
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_sRGB)
+ png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
+#endif
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_iCCP)
+ png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
+ info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
+#endif
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_sBIT)
+ png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
+#endif
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_cHRM)
+ {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_write_cHRM(png_ptr,
+ info_ptr->x_white, info_ptr->y_white,
+ info_ptr->x_red, info_ptr->y_red,
+ info_ptr->x_green, info_ptr->y_green,
+ info_ptr->x_blue, info_ptr->y_blue);
+#else
+# ifdef PNG_FIXED_POINT_SUPPORTED
+ png_write_cHRM_fixed(png_ptr,
+ info_ptr->int_x_white, info_ptr->int_y_white,
+ info_ptr->int_x_red, info_ptr->int_y_red,
+ info_ptr->int_x_green, info_ptr->int_y_green,
+ info_ptr->int_x_blue, info_ptr->int_y_blue);
+# endif
+#endif
+ }
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ if (info_ptr->unknown_chunks_num)
+ {
+ png_unknown_chunk *up;
+
+ png_debug(5, "writing extra chunks");
+
+ for (up = info_ptr->unknown_chunks;
+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+ up++)
+ {
+ int keep = png_handle_as_unknown(png_ptr, up->name);
+ if (keep != PNG_HANDLE_CHUNK_NEVER &&
+ up->location && !(up->location & PNG_HAVE_PLTE) &&
+ !(up->location & PNG_HAVE_IDAT) &&
+ ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+ {
+ if (up->size == 0)
+ png_warning(png_ptr, "Writing zero-length unknown chunk");
+ png_write_chunk(png_ptr, up->name, up->data, up->size);
+ }
+ }
+ }
+#endif
+ png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
+ }
+}
+
+void PNGAPI
+png_write_info(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+ int i;
+#endif
+
+ png_debug(1, "in png_write_info");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_write_info_before_PLTE(png_ptr, info_ptr);
+
+ if (info_ptr->valid & PNG_INFO_PLTE)
+ png_write_PLTE(png_ptr, info_ptr->palette,
+ (png_uint_32)info_ptr->num_palette);
+ else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_error(png_ptr, "Valid palette required for paletted images");
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_tRNS)
+ {
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+ /* Invert the alpha channel (in tRNS) */
+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
+ info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ int j;
+ for (j = 0; j<(int)info_ptr->num_trans; j++)
+ info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]);
+ }
+#endif
+ png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
+ info_ptr->num_trans, info_ptr->color_type);
+ }
+#endif
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_bKGD)
+ png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
+#endif
+#ifdef PNG_WRITE_hIST_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_hIST)
+ png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
+#endif
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
+ info_ptr->offset_unit_type);
+#endif
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_pCAL)
+ png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
+ info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
+ info_ptr->pcal_units, info_ptr->pcal_params);
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_sCAL)
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
+ png_write_sCAL(png_ptr, (int)info_ptr->scal_unit,
+ info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
+#else /* !FLOATING_POINT */
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
+ info_ptr->scal_s_width, info_ptr->scal_s_height);
+#endif /* FIXED_POINT */
+#endif /* FLOATING_POINT */
+#else /* !WRITE_sCAL */
+ png_warning(png_ptr,
+ "png_write_sCAL not supported; sCAL chunk not written.");
+#endif /* WRITE_sCAL */
+#endif /* sCAL */
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
+ info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
+#endif /* pHYs */
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_tIME)
+ {
+ png_write_tIME(png_ptr, &(info_ptr->mod_time));
+ png_ptr->mode |= PNG_WROTE_tIME;
+ }
+#endif /* tIME */
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_sPLT)
+ for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+ png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
+#endif /* sPLT */
+
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+ /* Check to see if we need to write text chunks */
+ for (i = 0; i < info_ptr->num_text; i++)
+ {
+ png_debug2(2, "Writing header text chunk %d, type %d", i,
+ info_ptr->text[i].compression);
+ /* An internationalized chunk? */
+ if (info_ptr->text[i].compression > 0)
+ {
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+ /* Write international chunk */
+ png_write_iTXt(png_ptr,
+ info_ptr->text[i].compression,
+ info_ptr->text[i].key,
+ info_ptr->text[i].lang,
+ info_ptr->text[i].lang_key,
+ info_ptr->text[i].text);
+#else
+ png_warning(png_ptr, "Unable to write international text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ /* If we want a compressed text chunk */
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
+ {
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+ /* Write compressed chunk */
+ png_write_zTXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0,
+ info_ptr->text[i].compression);
+#else
+ png_warning(png_ptr, "Unable to write compressed text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+ }
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+ /* Write uncompressed chunk */
+ png_write_tEXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text,
+ 0);
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+#else
+ /* Can't get here */
+ png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+ }
+ }
+#endif /* tEXt */
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ if (info_ptr->unknown_chunks_num)
+ {
+ png_unknown_chunk *up;
+
+ png_debug(5, "writing extra chunks");
+
+ for (up = info_ptr->unknown_chunks;
+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+ up++)
+ {
+ int keep = png_handle_as_unknown(png_ptr, up->name);
+ if (keep != PNG_HANDLE_CHUNK_NEVER &&
+ up->location && (up->location & PNG_HAVE_PLTE) &&
+ !(up->location & PNG_HAVE_IDAT) &&
+ !(up->location & PNG_AFTER_IDAT) &&
+ ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+ {
+ png_write_chunk(png_ptr, up->name, up->data, up->size);
+ }
+ }
+ }
+#endif
+}
+
+/* Writes the end of the PNG file. If you don't want to write comments or
+ * time information, you can pass NULL for info. If you already wrote these
+ * in png_write_info(), do not write them again here. If you have long
+ * comments, I suggest writing them here, and compressing them.
+ */
+void PNGAPI
+png_write_end(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_write_end");
+
+ if (png_ptr == NULL)
+ return;
+ if (!(png_ptr->mode & PNG_HAVE_IDAT))
+ png_error(png_ptr, "No IDATs written into file");
+
+ /* See if user wants us to write information chunks */
+ if (info_ptr != NULL)
+ {
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+ int i; /* local index variable */
+#endif
+#ifdef PNG_WRITE_tIME_SUPPORTED
+ /* Check to see if user has supplied a time chunk */
+ if ((info_ptr->valid & PNG_INFO_tIME) &&
+ !(png_ptr->mode & PNG_WROTE_tIME))
+ png_write_tIME(png_ptr, &(info_ptr->mod_time));
+#endif
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+ /* Loop through comment chunks */
+ for (i = 0; i < info_ptr->num_text; i++)
+ {
+ png_debug2(2, "Writing trailer text chunk %d, type %d", i,
+ info_ptr->text[i].compression);
+ /* An internationalized chunk? */
+ if (info_ptr->text[i].compression > 0)
+ {
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+ /* Write international chunk */
+ png_write_iTXt(png_ptr,
+ info_ptr->text[i].compression,
+ info_ptr->text[i].key,
+ info_ptr->text[i].lang,
+ info_ptr->text[i].lang_key,
+ info_ptr->text[i].text);
+#else
+ png_warning(png_ptr, "Unable to write international text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+ {
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+ /* Write compressed chunk */
+ png_write_zTXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0,
+ info_ptr->text[i].compression);
+#else
+ png_warning(png_ptr, "Unable to write compressed text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+ }
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+ /* Write uncompressed chunk */
+ png_write_tEXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0);
+#else
+ png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ }
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ if (info_ptr->unknown_chunks_num)
+ {
+ png_unknown_chunk *up;
+
+ png_debug(5, "writing extra chunks");
+
+ for (up = info_ptr->unknown_chunks;
+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+ up++)
+ {
+ int keep = png_handle_as_unknown(png_ptr, up->name);
+ if (keep != PNG_HANDLE_CHUNK_NEVER &&
+ up->location && (up->location & PNG_AFTER_IDAT) &&
+ ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+ {
+ png_write_chunk(png_ptr, up->name, up->data, up->size);
+ }
+ }
+ }
+#endif
+ }
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ /* Write end of PNG file */
+ png_write_IEND(png_ptr);
+ /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03,
+ * and restored again in libpng-1.2.30, may cause some applications that
+ * do not set png_ptr->output_flush_fn to crash. If your application
+ * experiences a problem, please try building libpng with
+ * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to
+ * png-mng-implement at lists.sf.net .
+ */
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+# ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED
+ png_flush(png_ptr);
+# endif
+#endif
+}
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+/* "tm" structure is not supported on WindowsCE */
+void PNGAPI
+png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
+{
+ png_debug(1, "in png_convert_from_struct_tm");
+
+ ptime->year = (png_uint_16)(1900 + ttime->tm_year);
+ ptime->month = (png_byte)(ttime->tm_mon + 1);
+ ptime->day = (png_byte)ttime->tm_mday;
+ ptime->hour = (png_byte)ttime->tm_hour;
+ ptime->minute = (png_byte)ttime->tm_min;
+ ptime->second = (png_byte)ttime->tm_sec;
+}
+
+void PNGAPI
+png_convert_from_time_t(png_timep ptime, time_t ttime)
+{
+ struct tm *tbuf;
+
+ png_debug(1, "in png_convert_from_time_t");
+
+ tbuf = gmtime(&ttime);
+ png_convert_from_struct_tm(ptime, tbuf);
+}
+#endif
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+png_structp PNGAPI
+png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
+ warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
+}
+
+/* Alternate initialize png_ptr structure, and allocate any memory needed */
+png_structp PNGAPI
+png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+#ifdef PNG_SETJMP_SUPPORTED
+ volatile
+#endif
+ png_structp png_ptr;
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ jmp_buf jmpbuf;
+#endif
+#endif
+ int i;
+
+ png_debug(1, "in png_create_write_struct");
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
+ (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
+#else
+ png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+#endif /* PNG_USER_MEM_SUPPORTED */
+ if (png_ptr == NULL)
+ return (NULL);
+
+ /* Added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
+ png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+#else
+ if (setjmp(png_ptr->jmpbuf))
+#endif
+ {
+ png_free(png_ptr, png_ptr->zbuf);
+ png_ptr->zbuf = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)png_ptr,
+ (png_free_ptr)free_fn, (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)png_ptr);
+#endif
+ return (NULL);
+ }
+#ifdef USE_FAR_KEYWORD
+ png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
+#endif
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
+#endif /* PNG_USER_MEM_SUPPORTED */
+ png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+ if (user_png_ver)
+ {
+ i = 0;
+ do
+ {
+ if (user_png_ver[i] != png_libpng_ver[i])
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+ } while (png_libpng_ver[i++]);
+ }
+
+ if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+ {
+ /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+ * we must recompile any applications that use any older library version.
+ * For versions after libpng 1.0, we will be compatible, so we need
+ * only check the first digit.
+ */
+ if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+ (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
+ (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+ {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+ char msg[80];
+ if (user_png_ver)
+ {
+ png_snprintf(msg, 80,
+ "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ png_snprintf(msg, 80,
+ "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+#endif
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags = 0;
+#endif
+ png_error(png_ptr,
+ "Incompatible libpng version in application and library");
+ }
+ }
+
+ /* Initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+
+ png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
+ png_flush_ptr_NULL);
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+ 1, png_doublep_NULL, png_doublep_NULL);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* Applications that neglect to set up their own setjmp() and then
+ * encounter a png_error() will longjmp here. Since the jmpbuf is
+ * then meaningless we abort instead of returning.
+ */
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+ PNG_ABORT();
+ png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
+#else
+ if (setjmp(png_ptr->jmpbuf))
+ PNG_ABORT();
+#endif
+#endif
+ return (png_ptr);
+}
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
+/* Deprecated. */
+#undef png_write_init
+void PNGAPI
+png_write_init(png_structp png_ptr)
+{
+ /* We only come here via pre-1.0.7-compiled applications */
+ png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
+}
+
+void PNGAPI
+png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size, png_size_t png_info_size)
+{
+ /* We only come here via pre-1.0.12-compiled applications */
+ if (png_ptr == NULL) return;
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+ if (png_sizeof(png_struct) > png_struct_size ||
+ png_sizeof(png_info) > png_info_size)
+ {
+ char msg[80];
+ png_ptr->warning_fn = NULL;
+ if (user_png_ver)
+ {
+ png_snprintf(msg, 80,
+ "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ png_snprintf(msg, 80,
+ "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+ }
+#endif
+ if (png_sizeof(png_struct) > png_struct_size)
+ {
+ png_ptr->error_fn = NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags = 0;
+#endif
+ png_error(png_ptr,
+ "The png struct allocated by the application for writing is"
+ " too small.");
+ }
+ if (png_sizeof(png_info) > png_info_size)
+ {
+ png_ptr->error_fn = NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags = 0;
+#endif
+ png_error(png_ptr,
+ "The info struct allocated by the application for writing is"
+ " too small.");
+ }
+ png_write_init_3(&png_ptr, user_png_ver, png_struct_size);
+}
+#endif /* PNG_1_0_X || PNG_1_2_X */
+
+
+void PNGAPI
+png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size)
+{
+ png_structp png_ptr = *ptr_ptr;
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp; /* to save current jump buffer */
+#endif
+
+ int i = 0;
+
+ if (png_ptr == NULL)
+ return;
+
+ do
+ {
+ if (user_png_ver[i] != png_libpng_ver[i])
+ {
+#ifdef PNG_LEGACY_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+ png_ptr->warning_fn = NULL;
+ png_warning(png_ptr,
+ "Application uses deprecated png_write_init() and should be recompiled.");
+#endif
+ }
+ } while (png_libpng_ver[i++]);
+
+ png_debug(1, "in png_write_init_3");
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* Save jump buffer and error functions */
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
+#endif
+
+ if (png_sizeof(png_struct) > png_struct_size)
+ {
+ png_destroy_struct(png_ptr);
+ png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+ *ptr_ptr = png_ptr;
+ }
+
+ /* Reset all variables to 0 */
+ png_memset(png_ptr, 0, png_sizeof(png_struct));
+
+ /* Added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
+ png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* Restore jump buffer */
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
+#endif
+
+ png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
+ png_flush_ptr_NULL);
+
+ /* Initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+ 1, png_doublep_NULL, png_doublep_NULL);
+#endif
+}
+
+/* Write a few rows of image data. If the image is interlaced,
+ * either you will have to write the 7 sub images, or, if you
+ * have called png_set_interlace_handling(), you will have to
+ * "write" the image seven times.
+ */
+void PNGAPI
+png_write_rows(png_structp png_ptr, png_bytepp row,
+ png_uint_32 num_rows)
+{
+ png_uint_32 i; /* row counter */
+ png_bytepp rp; /* row pointer */
+
+ png_debug(1, "in png_write_rows");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* Loop through the rows */
+ for (i = 0, rp = row; i < num_rows; i++, rp++)
+ {
+ png_write_row(png_ptr, *rp);
+ }
+}
+
+/* Write the image. You only need to call this function once, even
+ * if you are writing an interlaced image.
+ */
+void PNGAPI
+png_write_image(png_structp png_ptr, png_bytepp image)
+{
+ png_uint_32 i; /* row index */
+ int pass, num_pass; /* pass variables */
+ png_bytepp rp; /* points to current row */
+
+ if (png_ptr == NULL)
+ return;
+
+ png_debug(1, "in png_write_image");
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Initialize interlace handling. If image is not interlaced,
+ * this will set pass to 1
+ */
+ num_pass = png_set_interlace_handling(png_ptr);
+#else
+ num_pass = 1;
+#endif
+ /* Loop through passes */
+ for (pass = 0; pass < num_pass; pass++)
+ {
+ /* Loop through image */
+ for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
+ {
+ png_write_row(png_ptr, *rp);
+ }
+ }
+}
+
+/* Called by user to write a row of image data */
+void PNGAPI
+png_write_row(png_structp png_ptr, png_bytep row)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_debug2(1, "in png_write_row (row %ld, pass %d)",
+ png_ptr->row_number, png_ptr->pass);
+
+ /* Initialize transformations and other stuff if first time */
+ if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+ {
+ /* Make sure we wrote the header info */
+ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+ png_error(png_ptr,
+ "png_write_info was never called before png_write_row.");
+
+ /* Check for transforms that have been set but were defined out */
+#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_warning(png_ptr,
+ "PNG_WRITE_INVERT_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_warning(png_ptr,
+ "PNG_WRITE_FILLER_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
+ defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_warning(png_ptr,
+ "PNG_WRITE_PACKSWAP_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined.");
+#endif
+
+ png_write_start_row(png_ptr);
+ }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* If interlaced and not interested in row, return */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ switch (png_ptr->pass)
+ {
+ case 0:
+ if (png_ptr->row_number & 0x07)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 1:
+ if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 2:
+ if ((png_ptr->row_number & 0x07) != 4)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 3:
+ if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 4:
+ if ((png_ptr->row_number & 0x03) != 2)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 5:
+ if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 6:
+ if (!(png_ptr->row_number & 0x01))
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ }
+ }
+#endif
+
+ /* Set up row info for transformations */
+ png_ptr->row_info.color_type = png_ptr->color_type;
+ png_ptr->row_info.width = png_ptr->usr_width;
+ png_ptr->row_info.channels = png_ptr->usr_channels;
+ png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
+ png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+ png_ptr->row_info.channels);
+
+ png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+ png_ptr->row_info.width);
+
+ png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type);
+ png_debug1(3, "row_info->width = %lu", png_ptr->row_info.width);
+ png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels);
+ png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth);
+ png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth);
+ png_debug1(3, "row_info->rowbytes = %lu", png_ptr->row_info.rowbytes);
+
+ /* Copy user's row into buffer, leaving room for filter byte. */
+ png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
+ png_ptr->row_info.rowbytes);
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Handle interlacing */
+ if (png_ptr->interlaced && png_ptr->pass < 6 &&
+ (png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_do_write_interlace(&(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->pass);
+ /* This should always get caught above, but still ... */
+ if (!(png_ptr->row_info.width))
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ }
+#endif
+
+ /* Handle other transformations */
+ if (png_ptr->transformations)
+ png_do_write_transformations(png_ptr);
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ /* Write filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not write a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+ {
+ /* Intrapixel differencing */
+ png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+ }
+#endif
+
+ /* Find a filter if necessary, filter the row and write it out. */
+ png_write_find_filter(png_ptr, &(png_ptr->row_info));
+
+ if (png_ptr->write_row_fn != NULL)
+ (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+/* Set the automatic flush interval or 0 to turn flushing off */
+void PNGAPI
+png_set_flush(png_structp png_ptr, int nrows)
+{
+ png_debug(1, "in png_set_flush");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
+}
+
+/* Flush the current output buffers now */
+void PNGAPI
+png_write_flush(png_structp png_ptr)
+{
+ int wrote_IDAT;
+
+ png_debug(1, "in png_write_flush");
+
+ if (png_ptr == NULL)
+ return;
+ /* We have already written out all of the data */
+ if (png_ptr->row_number >= png_ptr->num_rows)
+ return;
+
+ do
+ {
+ int ret;
+
+ /* Compress the data */
+ ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+ wrote_IDAT = 0;
+
+ /* Check for compression errors */
+ if (ret != Z_OK)
+ {
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+
+ if (!(png_ptr->zstream.avail_out))
+ {
+ /* Write the IDAT and reset the zlib output buffer */
+ png_write_IDAT(png_ptr, png_ptr->zbuf,
+ png_ptr->zbuf_size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ wrote_IDAT = 1;
+ }
+ } while(wrote_IDAT == 1);
+
+ /* If there is any data left to be output, write it into a new IDAT */
+ if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
+ {
+ /* Write the IDAT and reset the zlib output buffer */
+ png_write_IDAT(png_ptr, png_ptr->zbuf,
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ png_ptr->flush_rows = 0;
+ png_flush(png_ptr);
+}
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+/* Free all memory used by the write */
+void PNGAPI
+png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
+{
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn = NULL;
+ png_voidp mem_ptr = NULL;
+#endif
+
+ png_debug(1, "in png_destroy_write_struct");
+
+ if (png_ptr_ptr != NULL)
+ {
+ png_ptr = *png_ptr_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+ mem_ptr = png_ptr->mem_ptr;
+#endif
+ }
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr != NULL)
+ {
+ free_fn = png_ptr->free_fn;
+ mem_ptr = png_ptr->mem_ptr;
+ }
+#endif
+
+ if (info_ptr_ptr != NULL)
+ info_ptr = *info_ptr_ptr;
+
+ if (info_ptr != NULL)
+ {
+ if (png_ptr != NULL)
+ {
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ if (png_ptr->num_chunk_list)
+ {
+ png_free(png_ptr, png_ptr->chunk_list);
+ png_ptr->chunk_list = NULL;
+ png_ptr->num_chunk_list = 0;
+ }
+#endif
+ }
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)info_ptr);
+#endif
+ *info_ptr_ptr = NULL;
+ }
+
+ if (png_ptr != NULL)
+ {
+ png_write_destroy(png_ptr);
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)png_ptr);
+#endif
+ *png_ptr_ptr = NULL;
+ }
+}
+
+
+/* Free any memory used in png_ptr struct (old method) */
+void /* PRIVATE */
+png_write_destroy(png_structp png_ptr)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp; /* Save jump buffer */
+#endif
+ png_error_ptr error_fn;
+ png_error_ptr warning_fn;
+ png_voidp error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn;
+#endif
+
+ png_debug(1, "in png_write_destroy");
+
+ /* Free any memory zlib uses */
+ deflateEnd(&png_ptr->zstream);
+
+ /* Free our memory. png_free checks NULL for us. */
+ png_free(png_ptr, png_ptr->zbuf);
+ png_free(png_ptr, png_ptr->row_buf);
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ png_free(png_ptr, png_ptr->prev_row);
+ png_free(png_ptr, png_ptr->sub_row);
+ png_free(png_ptr, png_ptr->up_row);
+ png_free(png_ptr, png_ptr->avg_row);
+ png_free(png_ptr, png_ptr->paeth_row);
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+ png_free(png_ptr, png_ptr->time_buffer);
+#endif
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ png_free(png_ptr, png_ptr->prev_filters);
+ png_free(png_ptr, png_ptr->filter_weights);
+ png_free(png_ptr, png_ptr->inv_filter_weights);
+ png_free(png_ptr, png_ptr->filter_costs);
+ png_free(png_ptr, png_ptr->inv_filter_costs);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* Reset structure */
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
+#endif
+
+ error_fn = png_ptr->error_fn;
+ warning_fn = png_ptr->warning_fn;
+ error_ptr = png_ptr->error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+#endif
+
+ png_memset(png_ptr, 0, png_sizeof(png_struct));
+
+ png_ptr->error_fn = error_fn;
+ png_ptr->warning_fn = warning_fn;
+ png_ptr->error_ptr = error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr->free_fn = free_fn;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
+#endif
+}
+
+/* Allow the application to select one or more row filters to use. */
+void PNGAPI
+png_set_filter(png_structp png_ptr, int method, int filters)
+{
+ png_debug(1, "in png_set_filter");
+
+ if (png_ptr == NULL)
+ return;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (method == PNG_INTRAPIXEL_DIFFERENCING))
+ method = PNG_FILTER_TYPE_BASE;
+#endif
+ if (method == PNG_FILTER_TYPE_BASE)
+ {
+ switch (filters & (PNG_ALL_FILTERS | 0x07))
+ {
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ case 5:
+ case 6:
+ case 7: png_warning(png_ptr, "Unknown row filter for method 0");
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+ case PNG_FILTER_VALUE_NONE:
+ png_ptr->do_filter = PNG_FILTER_NONE; break;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ case PNG_FILTER_VALUE_SUB:
+ png_ptr->do_filter = PNG_FILTER_SUB; break;
+ case PNG_FILTER_VALUE_UP:
+ png_ptr->do_filter = PNG_FILTER_UP; break;
+ case PNG_FILTER_VALUE_AVG:
+ png_ptr->do_filter = PNG_FILTER_AVG; break;
+ case PNG_FILTER_VALUE_PAETH:
+ png_ptr->do_filter = PNG_FILTER_PAETH; break;
+ default: png_ptr->do_filter = (png_byte)filters; break;
+#else
+ default: png_warning(png_ptr, "Unknown row filter for method 0");
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+ }
+
+ /* If we have allocated the row_buf, this means we have already started
+ * with the image and we should have allocated all of the filter buffers
+ * that have been selected. If prev_row isn't already allocated, then
+ * it is too late to start using the filters that need it, since we
+ * will be missing the data in the previous row. If an application
+ * wants to start and stop using particular filters during compression,
+ * it should start out with all of the filters, and then add and
+ * remove them after the start of compression.
+ */
+ if (png_ptr->row_buf != NULL)
+ {
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
+ {
+ png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Up filter after starting");
+ png_ptr->do_filter &= ~PNG_FILTER_UP;
+ }
+ else
+ {
+ png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+ }
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Average filter after starting");
+ png_ptr->do_filter &= ~PNG_FILTER_AVG;
+ }
+ else
+ {
+ png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+ }
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
+ png_ptr->paeth_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Paeth filter after starting");
+ png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
+ }
+ else
+ {
+ png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+ }
+ }
+
+ if (png_ptr->do_filter == PNG_NO_FILTERS)
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+ png_ptr->do_filter = PNG_FILTER_NONE;
+ }
+ }
+ else
+ png_error(png_ptr, "Unknown custom filter method");
+}
+
+/* This allows us to influence the way in which libpng chooses the "best"
+ * filter for the current scanline. While the "minimum-sum-of-absolute-
+ * differences metric is relatively fast and effective, there is some
+ * question as to whether it can be improved upon by trying to keep the
+ * filtered data going to zlib more consistent, hopefully resulting in
+ * better compression.
+ */
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */
+void PNGAPI
+png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
+ int num_weights, png_doublep filter_weights,
+ png_doublep filter_costs)
+{
+ int i;
+
+ png_debug(1, "in png_set_filter_heuristics");
+
+ if (png_ptr == NULL)
+ return;
+ if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
+ {
+ png_warning(png_ptr, "Unknown filter heuristic method");
+ return;
+ }
+
+ if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
+ {
+ heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
+ }
+
+ if (num_weights < 0 || filter_weights == NULL ||
+ heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
+ {
+ num_weights = 0;
+ }
+
+ png_ptr->num_prev_filters = (png_byte)num_weights;
+ png_ptr->heuristic_method = (png_byte)heuristic_method;
+
+ if (num_weights > 0)
+ {
+ if (png_ptr->prev_filters == NULL)
+ {
+ png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(png_sizeof(png_byte) * num_weights));
+
+ /* To make sure that the weighting starts out fairly */
+ for (i = 0; i < num_weights; i++)
+ {
+ png_ptr->prev_filters[i] = 255;
+ }
+ }
+
+ if (png_ptr->filter_weights == NULL)
+ {
+ png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
+
+ png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
+ for (i = 0; i < num_weights; i++)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+ }
+
+ for (i = 0; i < num_weights; i++)
+ {
+ if (filter_weights[i] < 0.0)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+ else
+ {
+ png_ptr->inv_filter_weights[i] =
+ (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
+ png_ptr->filter_weights[i] =
+ (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
+ }
+ }
+ }
+
+ /* If, in the future, there are other filter methods, this would
+ * need to be based on png_ptr->filter.
+ */
+ if (png_ptr->filter_costs == NULL)
+ {
+ png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+ png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+ {
+ png_ptr->inv_filter_costs[i] =
+ png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+ }
+ }
+
+ /* Here is where we set the relative costs of the different filters. We
+ * should take the desired compression level into account when setting
+ * the costs, so that Paeth, for instance, has a high relative cost at low
+ * compression levels, while it has a lower relative cost at higher
+ * compression settings. The filter types are in order of increasing
+ * relative cost, so it would be possible to do this with an algorithm.
+ */
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+ {
+ if (filter_costs == NULL || filter_costs[i] < 0.0)
+ {
+ png_ptr->inv_filter_costs[i] =
+ png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+ }
+ else if (filter_costs[i] >= 1.0)
+ {
+ png_ptr->inv_filter_costs[i] =
+ (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
+ png_ptr->filter_costs[i] =
+ (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
+ }
+ }
+}
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+void PNGAPI
+png_set_compression_level(png_structp png_ptr, int level)
+{
+ png_debug(1, "in png_set_compression_level");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
+ png_ptr->zlib_level = level;
+}
+
+void PNGAPI
+png_set_compression_mem_level(png_structp png_ptr, int mem_level)
+{
+ png_debug(1, "in png_set_compression_mem_level");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
+ png_ptr->zlib_mem_level = mem_level;
+}
+
+void PNGAPI
+png_set_compression_strategy(png_structp png_ptr, int strategy)
+{
+ png_debug(1, "in png_set_compression_strategy");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
+ png_ptr->zlib_strategy = strategy;
+}
+
+void PNGAPI
+png_set_compression_window_bits(png_structp png_ptr, int window_bits)
+{
+ if (png_ptr == NULL)
+ return;
+ if (window_bits > 15)
+ png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+ else if (window_bits < 8)
+ png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+#ifndef WBITS_8_OK
+ /* Avoid libpng bug with 256-byte windows */
+ if (window_bits == 8)
+ {
+ png_warning(png_ptr, "Compression window is being reset to 512");
+ window_bits = 9;
+ }
+#endif
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
+ png_ptr->zlib_window_bits = window_bits;
+}
+
+void PNGAPI
+png_set_compression_method(png_structp png_ptr, int method)
+{
+ png_debug(1, "in png_set_compression_method");
+
+ if (png_ptr == NULL)
+ return;
+ if (method != 8)
+ png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
+ png_ptr->zlib_method = method;
+}
+
+void PNGAPI
+png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
+{
+ if (png_ptr == NULL)
+ return;
+ png_ptr->write_row_fn = write_row_fn;
+}
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+void PNGAPI
+png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+ write_user_transform_fn)
+{
+ png_debug(1, "in png_set_write_user_transform_fn");
+
+ if (png_ptr == NULL)
+ return;
+ png_ptr->transformations |= PNG_USER_TRANSFORM;
+ png_ptr->write_user_transform_fn = write_user_transform_fn;
+}
+#endif
+
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_write_png(png_structp png_ptr, png_infop info_ptr,
+ int transforms, voidp params)
+{
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* Write the file header information. */
+ png_write_info(png_ptr, info_ptr);
+
+ /* ------ these transformations don't touch the info structure ------- */
+
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+ /* Invert monochrome pixels */
+ if (transforms & PNG_TRANSFORM_INVERT_MONO)
+ png_set_invert_mono(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+ /* Shift the pixels up to a legal bit depth and fill in
+ * as appropriate to correctly scale the image.
+ */
+ if ((transforms & PNG_TRANSFORM_SHIFT)
+ && (info_ptr->valid & PNG_INFO_sBIT))
+ png_set_shift(png_ptr, &info_ptr->sig_bit);
+#endif
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+ /* Pack pixels into bytes */
+ if (transforms & PNG_TRANSFORM_PACKING)
+ png_set_packing(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+ /* Swap location of alpha bytes from ARGB to RGBA */
+ if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+ png_set_swap_alpha(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+ /* Pack XRGB/RGBX/ARGB/RGBA into * RGB (4 channels -> 3 channels) */
+ if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER)
+ png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
+ else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
+ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+#endif
+
+#ifdef PNG_WRITE_BGR_SUPPORTED
+ /* Flip BGR pixels to RGB */
+ if (transforms & PNG_TRANSFORM_BGR)
+ png_set_bgr(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+ /* Swap bytes of 16-bit files to most significant byte first */
+ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+ png_set_swap(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+ /* Swap bits of 1, 2, 4 bit packed pixel formats */
+ if (transforms & PNG_TRANSFORM_PACKSWAP)
+ png_set_packswap(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+ /* Invert the alpha channel from opacity to transparency */
+ if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+ png_set_invert_alpha(png_ptr);
+#endif
+
+ /* ----------------------- end of transformations ------------------- */
+
+ /* Write the bits */
+ if (info_ptr->valid & PNG_INFO_IDAT)
+ png_write_image(png_ptr, info_ptr->row_pointers);
+
+ /* It is REQUIRED to call this to finish writing the rest of the file */
+ png_write_end(png_ptr, info_ptr);
+
+ transforms = transforms; /* Quiet compiler warnings */
+ params = params;
+}
+#endif
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/src/libpng/pngwtran.c b/src/libpng/pngwtran.c
new file mode 100644
index 0000000..0ce9b9b
--- /dev/null
+++ b/src/libpng/pngwtran.c
@@ -0,0 +1,582 @@
+
+/* pngwtran.c - transforms the data in a row for PNG writers
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Transform the data according to the user's wishes. The order of
+ * transformations is significant.
+ */
+void /* PRIVATE */
+png_do_write_transformations(png_structp png_ptr)
+{
+ png_debug(1, "in png_do_write_transformations");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ if (png_ptr->write_user_transform_fn != NULL)
+ (*(png_ptr->write_user_transform_fn)) /* User write transform
+ function */
+ (png_ptr, /* png_ptr */
+ &(png_ptr->row_info), /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_uint_32 rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#endif
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+ if (png_ptr->transformations & PNG_FILLER)
+ png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->flags);
+#endif
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#ifdef PNG_WRITE_PACK_SUPPORTED
+ if (png_ptr->transformations & PNG_PACK)
+ png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->bit_depth);
+#endif
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_ALPHA)
+ png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#ifdef PNG_WRITE_BGR_SUPPORTED
+ if (png_ptr->transformations & PNG_BGR)
+ png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+}
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
+ * row_info bit depth should be 8 (one pixel per byte). The channels
+ * should be 1 (this only happens on grayscale and paletted images).
+ */
+void /* PRIVATE */
+png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
+{
+ png_debug(1, "in png_do_pack");
+
+ if (row_info->bit_depth == 8 &&
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->channels == 1)
+ {
+ switch ((int)bit_depth)
+ {
+ case 1:
+ {
+ png_bytep sp, dp;
+ int mask, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ mask = 0x80;
+ v = 0;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (*sp != 0)
+ v |= mask;
+ sp++;
+ if (mask > 1)
+ mask >>= 1;
+ else
+ {
+ mask = 0x80;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+ }
+ if (mask != 0x80)
+ *dp = (png_byte)v;
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp, dp;
+ int shift, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ shift = 6;
+ v = 0;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte value;
+
+ value = (png_byte)(*sp & 0x03);
+ v |= (value << shift);
+ if (shift == 0)
+ {
+ shift = 6;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+ else
+ shift -= 2;
+ sp++;
+ }
+ if (shift != 6)
+ *dp = (png_byte)v;
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp, dp;
+ int shift, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ shift = 4;
+ v = 0;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte value;
+
+ value = (png_byte)(*sp & 0x0f);
+ v |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 4;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+ else
+ shift -= 4;
+
+ sp++;
+ }
+ if (shift != 4)
+ *dp = (png_byte)v;
+ break;
+ }
+ }
+ row_info->bit_depth = (png_byte)bit_depth;
+ row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_info->width);
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+/* Shift pixel values to take advantage of whole range. Pass the
+ * true number of bits in bit_depth. The row should be packed
+ * according to row_info->bit_depth. Thus, if you had a row of
+ * bit depth 4, but the pixels only had values from 0 to 7, you
+ * would pass 3 as bit_depth, and this routine would translate the
+ * data to 0 to 15.
+ */
+void /* PRIVATE */
+png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
+{
+ png_debug(1, "in png_do_shift");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row != NULL && row_info != NULL &&
+#else
+ if (
+#endif
+ row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ int shift_start[4], shift_dec[4];
+ int channels = 0;
+
+ if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->red;
+ shift_dec[channels] = bit_depth->red;
+ channels++;
+ shift_start[channels] = row_info->bit_depth - bit_depth->green;
+ shift_dec[channels] = bit_depth->green;
+ channels++;
+ shift_start[channels] = row_info->bit_depth - bit_depth->blue;
+ shift_dec[channels] = bit_depth->blue;
+ channels++;
+ }
+ else
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->gray;
+ shift_dec[channels] = bit_depth->gray;
+ channels++;
+ }
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
+ shift_dec[channels] = bit_depth->alpha;
+ channels++;
+ }
+
+ /* With low row depths, could only be grayscale, so one channel */
+ if (row_info->bit_depth < 8)
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_byte mask;
+ png_uint_32 row_bytes = row_info->rowbytes;
+
+ if (bit_depth->gray == 1 && row_info->bit_depth == 2)
+ mask = 0x55;
+ else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
+ mask = 0x11;
+ else
+ mask = 0xff;
+
+ for (i = 0; i < row_bytes; i++, bp++)
+ {
+ png_uint_16 v;
+ int j;
+
+ v = *bp;
+ *bp = 0;
+ for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
+ {
+ if (j > 0)
+ *bp |= (png_byte)((v << j) & 0xff);
+ else
+ *bp |= (png_byte)((v >> (-j)) & mask);
+ }
+ }
+ }
+ else if (row_info->bit_depth == 8)
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_info->width;
+
+ for (i = 0; i < istop; i++, bp++)
+ {
+
+ png_uint_16 v;
+ int j;
+ int c = (int)(i%channels);
+
+ v = *bp;
+ *bp = 0;
+ for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+ {
+ if (j > 0)
+ *bp |= (png_byte)((v << j) & 0xff);
+ else
+ *bp |= (png_byte)((v >> (-j)) & 0xff);
+ }
+ }
+ }
+ else
+ {
+ png_bytep bp;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_info->width;
+
+ for (bp = row, i = 0; i < istop; i++)
+ {
+ int c = (int)(i%channels);
+ png_uint_16 value, v;
+ int j;
+
+ v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
+ value = 0;
+ for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+ {
+ if (j > 0)
+ value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
+ else
+ value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
+ }
+ *bp++ = (png_byte)(value >> 8);
+ *bp++ = (png_byte)(value & 0xff);
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_swap_alpha");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This converts from ARGB to RGBA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save;
+ }
+ }
+ /* This converts from AARRGGBB to RRGGBBAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save[2];
+ save[0] = *(sp++);
+ save[1] = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save[0];
+ *(dp++) = save[1];
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This converts from AG to GA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save;
+ }
+ }
+ /* This converts from AAGG to GGAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save[2];
+ save[0] = *(sp++);
+ save[1] = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save[0];
+ *(dp++) = save[1];
+ }
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_invert_alpha");
+
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This inverts the alpha channel in RGBA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* Does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=3; dp = sp;
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ /* This inverts the alpha channel in RRGGBBAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* Does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=6; dp = sp;
+ *(dp++) = (png_byte)(255 - *(sp++));
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This inverts the alpha channel in GA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ /* This inverts the alpha channel in GGAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* Does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=2; dp = sp;
+ *(dp++) = (png_byte)(255 - *(sp++));
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Undoes intrapixel differencing */
+void /* PRIVATE */
+png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_intrapixel");
+
+ if (
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)((*rp - *(rp+1))&0xff);
+ *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
+ png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
+ png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
+ png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
+ png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
+ *(rp ) = (png_byte)((red >> 8) & 0xff);
+ *(rp+1) = (png_byte)(red & 0xff);
+ *(rp+4) = (png_byte)((blue >> 8) & 0xff);
+ *(rp+5) = (png_byte)(blue & 0xff);
+ }
+ }
+ }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/src/libpng/pngwutil.c b/src/libpng/pngwutil.c
new file mode 100644
index 0000000..c75f53e
--- /dev/null
+++ b/src/libpng/pngwutil.c
@@ -0,0 +1,2832 @@
+
+/* pngwutil.c - utilities to write a PNG file
+ *
+ * Last changed in libpng 1.2.43 [February 25, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Place a 32-bit number into a buffer in PNG byte order. We work
+ * with unsigned numbers for convenience, although one supported
+ * ancillary chunk uses signed (two's complement) numbers.
+ */
+void PNGAPI
+png_save_uint_32(png_bytep buf, png_uint_32 i)
+{
+ buf[0] = (png_byte)((i >> 24) & 0xff);
+ buf[1] = (png_byte)((i >> 16) & 0xff);
+ buf[2] = (png_byte)((i >> 8) & 0xff);
+ buf[3] = (png_byte)(i & 0xff);
+}
+
+/* The png_save_int_32 function assumes integers are stored in two's
+ * complement format. If this isn't the case, then this routine needs to
+ * be modified to write data in two's complement format.
+ */
+void PNGAPI
+png_save_int_32(png_bytep buf, png_int_32 i)
+{
+ buf[0] = (png_byte)((i >> 24) & 0xff);
+ buf[1] = (png_byte)((i >> 16) & 0xff);
+ buf[2] = (png_byte)((i >> 8) & 0xff);
+ buf[3] = (png_byte)(i & 0xff);
+}
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+void PNGAPI
+png_save_uint_16(png_bytep buf, unsigned int i)
+{
+ buf[0] = (png_byte)((i >> 8) & 0xff);
+ buf[1] = (png_byte)(i & 0xff);
+}
+
+/* Simple function to write the signature. If we have already written
+ * the magic bytes of the signature, or more likely, the PNG stream is
+ * being embedded into another stream and doesn't need its own signature,
+ * we should call png_set_sig_bytes() to tell libpng how many of the
+ * bytes have already been written.
+ */
+void /* PRIVATE */
+png_write_sig(png_structp png_ptr)
+{
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+ /* Write the rest of the 8 byte signature */
+ png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
+ (png_size_t)(8 - png_ptr->sig_bytes));
+ if (png_ptr->sig_bytes < 3)
+ png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+}
+
+/* Write a PNG chunk all at once. The type is an array of ASCII characters
+ * representing the chunk name. The array must be at least 4 bytes in
+ * length, and does not need to be null terminated. To be safe, pass the
+ * pre-defined chunk names here, and if you need a new one, define it
+ * where the others are defined. The length is the length of the data.
+ * All the data must be present. If that is not possible, use the
+ * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
+ * functions instead.
+ */
+void PNGAPI
+png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
+ png_bytep data, png_size_t length)
+{
+ if (png_ptr == NULL)
+ return;
+ png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
+ png_write_chunk_data(png_ptr, data, (png_size_t)length);
+ png_write_chunk_end(png_ptr);
+}
+
+/* Write the start of a PNG chunk. The type is the chunk type.
+ * The total_length is the sum of the lengths of all the data you will be
+ * passing in png_write_chunk_data().
+ */
+void PNGAPI
+png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
+ png_uint_32 length)
+{
+ png_byte buf[8];
+
+ png_debug2(0, "Writing %s chunk, length = %lu", chunk_name,
+ (unsigned long)length);
+
+ if (png_ptr == NULL)
+ return;
+
+
+ /* Write the length and the chunk name */
+ png_save_uint_32(buf, length);
+ png_memcpy(buf + 4, chunk_name, 4);
+ png_write_data(png_ptr, buf, (png_size_t)8);
+ /* Put the chunk name into png_ptr->chunk_name */
+ png_memcpy(png_ptr->chunk_name, chunk_name, 4);
+ /* Reset the crc and run it over the chunk name */
+ png_reset_crc(png_ptr);
+ png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
+}
+
+/* Write the data of a PNG chunk started with png_write_chunk_start().
+ * Note that multiple calls to this function are allowed, and that the
+ * sum of the lengths from these calls *must* add up to the total_length
+ * given to png_write_chunk_start().
+ */
+void PNGAPI
+png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ /* Write the data, and run the CRC over it */
+ if (png_ptr == NULL)
+ return;
+ if (data != NULL && length > 0)
+ {
+ png_write_data(png_ptr, data, length);
+ /* Update the CRC after writing the data,
+ * in case that the user I/O routine alters it.
+ */
+ png_calculate_crc(png_ptr, data, length);
+ }
+}
+
+/* Finish a chunk started with png_write_chunk_start(). */
+void PNGAPI
+png_write_chunk_end(png_structp png_ptr)
+{
+ png_byte buf[4];
+
+ if (png_ptr == NULL) return;
+
+ /* Write the crc in a single operation */
+ png_save_uint_32(buf, png_ptr->crc);
+
+ png_write_data(png_ptr, buf, (png_size_t)4);
+}
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)
+/* This pair of functions encapsulates the operation of (a) compressing a
+ * text string, and (b) issuing it later as a series of chunk data writes.
+ * The compression_state structure is shared context for these functions
+ * set up by the caller in order to make the whole mess thread-safe.
+ */
+
+typedef struct
+{
+ char *input; /* The uncompressed input data */
+ int input_len; /* Its length */
+ int num_output_ptr; /* Number of output pointers used */
+ int max_output_ptr; /* Size of output_ptr */
+ png_charpp output_ptr; /* Array of pointers to output */
+} compression_state;
+
+/* Compress given text into storage in the png_ptr structure */
+static int /* PRIVATE */
+png_text_compress(png_structp png_ptr,
+ png_charp text, png_size_t text_len, int compression,
+ compression_state *comp)
+{
+ int ret;
+
+ comp->num_output_ptr = 0;
+ comp->max_output_ptr = 0;
+ comp->output_ptr = NULL;
+ comp->input = NULL;
+ comp->input_len = 0;
+
+ /* We may just want to pass the text right through */
+ if (compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+ comp->input = text;
+ comp->input_len = text_len;
+ return((int)text_len);
+ }
+
+ if (compression >= PNG_TEXT_COMPRESSION_LAST)
+ {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+ char msg[50];
+ png_snprintf(msg, 50, "Unknown compression type %d", compression);
+ png_warning(png_ptr, msg);
+#else
+ png_warning(png_ptr, "Unknown compression type");
+#endif
+ }
+
+ /* We can't write the chunk until we find out how much data we have,
+ * which means we need to run the compressor first and save the
+ * output. This shouldn't be a problem, as the vast majority of
+ * comments should be reasonable, but we will set up an array of
+ * malloc'd pointers to be sure.
+ *
+ * If we knew the application was well behaved, we could simplify this
+ * greatly by assuming we can always malloc an output buffer large
+ * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
+ * and malloc this directly. The only time this would be a bad idea is
+ * if we can't malloc more than 64K and we have 64K of random input
+ * data, or if the input string is incredibly large (although this
+ * wouldn't cause a failure, just a slowdown due to swapping).
+ */
+
+ /* Set up the compression buffers */
+ png_ptr->zstream.avail_in = (uInt)text_len;
+ png_ptr->zstream.next_in = (Bytef *)text;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
+
+ /* This is the same compression loop as in png_write_row() */
+ do
+ {
+ /* Compress the data */
+ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+ if (ret != Z_OK)
+ {
+ /* Error */
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+ /* Check to see if we need more room */
+ if (!(png_ptr->zstream.avail_out))
+ {
+ /* Make sure the output array has room */
+ if (comp->num_output_ptr >= comp->max_output_ptr)
+ {
+ int old_max;
+
+ old_max = comp->max_output_ptr;
+ comp->max_output_ptr = comp->num_output_ptr + 4;
+ if (comp->output_ptr != NULL)
+ {
+ png_charpp old_ptr;
+
+ old_ptr = comp->output_ptr;
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)
+ (comp->max_output_ptr * png_sizeof(png_charpp)));
+ png_memcpy(comp->output_ptr, old_ptr, old_max
+ * png_sizeof(png_charp));
+ png_free(png_ptr, old_ptr);
+ }
+ else
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)
+ (comp->max_output_ptr * png_sizeof(png_charp)));
+ }
+
+ /* Save the data */
+ comp->output_ptr[comp->num_output_ptr] =
+ (png_charp)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+ png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+ png_ptr->zbuf_size);
+ comp->num_output_ptr++;
+
+ /* and reset the buffer */
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ }
+ /* Continue until we don't have any more to compress */
+ } while (png_ptr->zstream.avail_in);
+
+ /* Finish the compression */
+ do
+ {
+ /* Tell zlib we are finished */
+ ret = deflate(&png_ptr->zstream, Z_FINISH);
+
+ if (ret == Z_OK)
+ {
+ /* Check to see if we need more room */
+ if (!(png_ptr->zstream.avail_out))
+ {
+ /* Check to make sure our output array has room */
+ if (comp->num_output_ptr >= comp->max_output_ptr)
+ {
+ int old_max;
+
+ old_max = comp->max_output_ptr;
+ comp->max_output_ptr = comp->num_output_ptr + 4;
+ if (comp->output_ptr != NULL)
+ {
+ png_charpp old_ptr;
+
+ old_ptr = comp->output_ptr;
+ /* This could be optimized to realloc() */
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)(comp->max_output_ptr *
+ png_sizeof(png_charp)));
+ png_memcpy(comp->output_ptr, old_ptr,
+ old_max * png_sizeof(png_charp));
+ png_free(png_ptr, old_ptr);
+ }
+ else
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)(comp->max_output_ptr *
+ png_sizeof(png_charp)));
+ }
+
+ /* Save the data */
+ comp->output_ptr[comp->num_output_ptr] =
+ (png_charp)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+ png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+ png_ptr->zbuf_size);
+ comp->num_output_ptr++;
+
+ /* and reset the buffer pointers */
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ }
+ }
+ else if (ret != Z_STREAM_END)
+ {
+ /* We got an error */
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+ } while (ret != Z_STREAM_END);
+
+ /* Text length is number of buffers plus last buffer */
+ text_len = png_ptr->zbuf_size * comp->num_output_ptr;
+ if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+ text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
+
+ return((int)text_len);
+}
+
+/* Ship the compressed text out via chunk writes */
+static void /* PRIVATE */
+png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
+{
+ int i;
+
+ /* Handle the no-compression case */
+ if (comp->input)
+ {
+ png_write_chunk_data(png_ptr, (png_bytep)comp->input,
+ (png_size_t)comp->input_len);
+ return;
+ }
+
+ /* Write saved output buffers, if any */
+ for (i = 0; i < comp->num_output_ptr; i++)
+ {
+ png_write_chunk_data(png_ptr, (png_bytep)comp->output_ptr[i],
+ (png_size_t)png_ptr->zbuf_size);
+ png_free(png_ptr, comp->output_ptr[i]);
+ comp->output_ptr[i]=NULL;
+ }
+ if (comp->max_output_ptr != 0)
+ png_free(png_ptr, comp->output_ptr);
+ comp->output_ptr=NULL;
+ /* Write anything left in zbuf */
+ if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
+ png_write_chunk_data(png_ptr, png_ptr->zbuf,
+ (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
+
+ /* Reset zlib for another zTXt/iTXt or image data */
+ deflateReset(&png_ptr->zstream);
+ png_ptr->zstream.data_type = Z_BINARY;
+}
+#endif
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information. Note that the rest of this code depends upon this
+ * information being correct.
+ */
+void /* PRIVATE */
+png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
+ int bit_depth, int color_type, int compression_type, int filter_type,
+ int interlace_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IHDR;
+#endif
+ int ret;
+
+ png_byte buf[13]; /* Buffer to store the IHDR info */
+
+ png_debug(1, "in png_write_IHDR");
+
+ /* Check that we have valid input data from the application info */
+ switch (color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ switch (bit_depth)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16: png_ptr->channels = 1; break;
+ default: png_error(png_ptr,
+ "Invalid bit depth for grayscale image");
+ }
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ if (bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth for RGB image");
+ png_ptr->channels = 3;
+ break;
+ case PNG_COLOR_TYPE_PALETTE:
+ switch (bit_depth)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8: png_ptr->channels = 1; break;
+ default: png_error(png_ptr, "Invalid bit depth for paletted image");
+ }
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ if (bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
+ png_ptr->channels = 2;
+ break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ if (bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth for RGBA image");
+ png_ptr->channels = 4;
+ break;
+ default:
+ png_error(png_ptr, "Invalid image color type specified");
+ }
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Invalid compression type specified");
+ compression_type = PNG_COMPRESSION_TYPE_BASE;
+ }
+
+ /* Write filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not write a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if (
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
+ (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
+ (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
+#endif
+ filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Invalid filter type specified");
+ filter_type = PNG_FILTER_TYPE_BASE;
+ }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ if (interlace_type != PNG_INTERLACE_NONE &&
+ interlace_type != PNG_INTERLACE_ADAM7)
+ {
+ png_warning(png_ptr, "Invalid interlace type specified");
+ interlace_type = PNG_INTERLACE_ADAM7;
+ }
+#else
+ interlace_type=PNG_INTERLACE_NONE;
+#endif
+
+ /* Save the relevent information */
+ png_ptr->bit_depth = (png_byte)bit_depth;
+ png_ptr->color_type = (png_byte)color_type;
+ png_ptr->interlaced = (png_byte)interlace_type;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ png_ptr->filter_type = (png_byte)filter_type;
+#endif
+ png_ptr->compression_type = (png_byte)compression_type;
+ png_ptr->width = width;
+ png_ptr->height = height;
+
+ png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
+ /* Set the usr info, so any transformations can modify it */
+ png_ptr->usr_width = png_ptr->width;
+ png_ptr->usr_bit_depth = png_ptr->bit_depth;
+ png_ptr->usr_channels = png_ptr->channels;
+
+ /* Pack the header information into the buffer */
+ png_save_uint_32(buf, width);
+ png_save_uint_32(buf + 4, height);
+ buf[8] = (png_byte)bit_depth;
+ buf[9] = (png_byte)color_type;
+ buf[10] = (png_byte)compression_type;
+ buf[11] = (png_byte)filter_type;
+ buf[12] = (png_byte)interlace_type;
+
+ /* Write the chunk */
+ png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
+
+ /* Initialize zlib with PNG info */
+ png_ptr->zstream.zalloc = png_zalloc;
+ png_ptr->zstream.zfree = png_zfree;
+ png_ptr->zstream.opaque = (voidpf)png_ptr;
+ if (!(png_ptr->do_filter))
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+ png_ptr->bit_depth < 8)
+ png_ptr->do_filter = PNG_FILTER_NONE;
+ else
+ png_ptr->do_filter = PNG_ALL_FILTERS;
+ }
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
+ {
+ if (png_ptr->do_filter != PNG_FILTER_NONE)
+ png_ptr->zlib_strategy = Z_FILTERED;
+ else
+ png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
+ }
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
+ png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
+ png_ptr->zlib_mem_level = 8;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
+ png_ptr->zlib_window_bits = 15;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
+ png_ptr->zlib_method = 8;
+ ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
+ png_ptr->zlib_method, png_ptr->zlib_window_bits,
+ png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
+ if (ret != Z_OK)
+ {
+ if (ret == Z_VERSION_ERROR) png_error(png_ptr,
+ "zlib failed to initialize compressor -- version error");
+ if (ret == Z_STREAM_ERROR) png_error(png_ptr,
+ "zlib failed to initialize compressor -- stream error");
+ if (ret == Z_MEM_ERROR) png_error(png_ptr,
+ "zlib failed to initialize compressor -- mem error");
+ png_error(png_ptr, "zlib failed to initialize compressor");
+ }
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ /* libpng is not interested in zstream.data_type */
+ /* Set it to a predefined value, to avoid its evaluation inside zlib */
+ png_ptr->zstream.data_type = Z_BINARY;
+
+ png_ptr->mode = PNG_HAVE_IHDR;
+}
+
+/* Write the palette. We are careful not to trust png_color to be in the
+ * correct order for PNG, so people can redefine it to any convenient
+ * structure.
+ */
+void /* PRIVATE */
+png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_PLTE;
+#endif
+ png_uint_32 i;
+ png_colorp pal_ptr;
+ png_byte buf[3];
+
+ png_debug(1, "in png_write_PLTE");
+
+ if ((
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
+#endif
+ num_pal == 0) || num_pal > 256)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_error(png_ptr, "Invalid number of colors in palette");
+ }
+ else
+ {
+ png_warning(png_ptr, "Invalid number of colors in palette");
+ return;
+ }
+ }
+
+ if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
+ {
+ png_warning(png_ptr,
+ "Ignoring request to write a PLTE chunk in grayscale PNG");
+ return;
+ }
+
+ png_ptr->num_palette = (png_uint_16)num_pal;
+ png_debug1(3, "num_palette = %d", png_ptr->num_palette);
+
+ png_write_chunk_start(png_ptr, (png_bytep)png_PLTE,
+ (png_uint_32)(num_pal * 3));
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
+ {
+ buf[0] = pal_ptr->red;
+ buf[1] = pal_ptr->green;
+ buf[2] = pal_ptr->blue;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+ }
+#else
+ /* This is a little slower but some buggy compilers need to do this
+ * instead
+ */
+ pal_ptr=palette;
+ for (i = 0; i < num_pal; i++)
+ {
+ buf[0] = pal_ptr[i].red;
+ buf[1] = pal_ptr[i].green;
+ buf[2] = pal_ptr[i].blue;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+ }
+#endif
+ png_write_chunk_end(png_ptr);
+ png_ptr->mode |= PNG_HAVE_PLTE;
+}
+
+/* Write an IDAT chunk */
+void /* PRIVATE */
+png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IDAT;
+#endif
+
+ png_debug(1, "in png_write_IDAT");
+
+ /* Optimize the CMF field in the zlib stream. */
+ /* This hack of the zlib stream is compliant to the stream specification. */
+ if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
+ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+ {
+ unsigned int z_cmf = data[0]; /* zlib compression method and flags */
+ if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
+ {
+ /* Avoid memory underflows and multiplication overflows.
+ *
+ * The conditions below are practically always satisfied;
+ * however, they still must be checked.
+ */
+ if (length >= 2 &&
+ png_ptr->height < 16384 && png_ptr->width < 16384)
+ {
+ png_uint_32 uncompressed_idat_size = png_ptr->height *
+ ((png_ptr->width *
+ png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
+ unsigned int z_cinfo = z_cmf >> 4;
+ unsigned int half_z_window_size = 1 << (z_cinfo + 7);
+ while (uncompressed_idat_size <= half_z_window_size &&
+ half_z_window_size >= 256)
+ {
+ z_cinfo--;
+ half_z_window_size >>= 1;
+ }
+ z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
+ if (data[0] != (png_byte)z_cmf)
+ {
+ data[0] = (png_byte)z_cmf;
+ data[1] &= 0xe0;
+ data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
+ }
+ }
+ }
+ else
+ png_error(png_ptr,
+ "Invalid zlib compression method or flags in IDAT");
+ }
+
+ png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
+ png_ptr->mode |= PNG_HAVE_IDAT;
+}
+
+/* Write an IEND chunk */
+void /* PRIVATE */
+png_write_IEND(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IEND;
+#endif
+
+ png_debug(1, "in png_write_IEND");
+
+ png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL,
+ (png_size_t)0);
+ png_ptr->mode |= PNG_HAVE_IEND;
+}
+
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+/* Write a gAMA chunk */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_gAMA(png_structp png_ptr, double file_gamma)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_gAMA;
+#endif
+ png_uint_32 igamma;
+ png_byte buf[4];
+
+ png_debug(1, "in png_write_gAMA");
+
+ /* file_gamma is saved in 1/100,000ths */
+ igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
+ png_save_uint_32(buf, igamma);
+ png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_gAMA;
+#endif
+ png_byte buf[4];
+
+ png_debug(1, "in png_write_gAMA");
+
+ /* file_gamma is saved in 1/100,000ths */
+ png_save_uint_32(buf, (png_uint_32)file_gamma);
+ png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
+}
+#endif
+#endif
+
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+/* Write a sRGB chunk */
+void /* PRIVATE */
+png_write_sRGB(png_structp png_ptr, int srgb_intent)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sRGB;
+#endif
+ png_byte buf[1];
+
+ png_debug(1, "in png_write_sRGB");
+
+ if (srgb_intent >= PNG_sRGB_INTENT_LAST)
+ png_warning(png_ptr,
+ "Invalid sRGB rendering intent specified");
+ buf[0]=(png_byte)srgb_intent;
+ png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1);
+}
+#endif
+
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+/* Write an iCCP chunk */
+void /* PRIVATE */
+png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
+ png_charp profile, int profile_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_iCCP;
+#endif
+ png_size_t name_len;
+ png_charp new_name;
+ compression_state comp;
+ int embedded_profile_len = 0;
+
+ png_debug(1, "in png_write_iCCP");
+
+ comp.num_output_ptr = 0;
+ comp.max_output_ptr = 0;
+ comp.output_ptr = NULL;
+ comp.input = NULL;
+ comp.input_len = 0;
+
+ if ((name_len = png_check_keyword(png_ptr, name,
+ &new_name)) == 0)
+ return;
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ png_warning(png_ptr, "Unknown compression type in iCCP chunk");
+
+ if (profile == NULL)
+ profile_len = 0;
+
+ if (profile_len > 3)
+ embedded_profile_len =
+ ((*( (png_bytep)profile ))<<24) |
+ ((*( (png_bytep)profile + 1))<<16) |
+ ((*( (png_bytep)profile + 2))<< 8) |
+ ((*( (png_bytep)profile + 3)) );
+
+ if (embedded_profile_len < 0)
+ {
+ png_warning(png_ptr,
+ "Embedded profile length in iCCP chunk is negative");
+ png_free(png_ptr, new_name);
+ return;
+ }
+
+ if (profile_len < embedded_profile_len)
+ {
+ png_warning(png_ptr,
+ "Embedded profile length too large in iCCP chunk");
+ png_free(png_ptr, new_name);
+ return;
+ }
+
+ if (profile_len > embedded_profile_len)
+ {
+ png_warning(png_ptr,
+ "Truncating profile to actual length in iCCP chunk");
+ profile_len = embedded_profile_len;
+ }
+
+ if (profile_len)
+ profile_len = png_text_compress(png_ptr, profile,
+ (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp);
+
+ /* Make sure we include the NULL after the name and the compression type */
+ png_write_chunk_start(png_ptr, (png_bytep)png_iCCP,
+ (png_uint_32)(name_len + profile_len + 2));
+ new_name[name_len + 1] = 0x00;
+ png_write_chunk_data(png_ptr, (png_bytep)new_name,
+ (png_size_t)(name_len + 2));
+
+ if (profile_len)
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_name);
+}
+#endif
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+/* Write a sPLT chunk */
+void /* PRIVATE */
+png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sPLT;
+#endif
+ png_size_t name_len;
+ png_charp new_name;
+ png_byte entrybuf[10];
+ int entry_size = (spalette->depth == 8 ? 6 : 10);
+ int palette_size = entry_size * spalette->nentries;
+ png_sPLT_entryp ep;
+#ifndef PNG_POINTER_INDEXING_SUPPORTED
+ int i;
+#endif
+
+ png_debug(1, "in png_write_sPLT");
+
+ if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0)
+ return;
+
+ /* Make sure we include the NULL after the name */
+ png_write_chunk_start(png_ptr, (png_bytep)png_sPLT,
+ (png_uint_32)(name_len + 2 + palette_size));
+ png_write_chunk_data(png_ptr, (png_bytep)new_name,
+ (png_size_t)(name_len + 1));
+ png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, (png_size_t)1);
+
+ /* Loop through each palette entry, writing appropriately */
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
+ {
+ if (spalette->depth == 8)
+ {
+ entrybuf[0] = (png_byte)ep->red;
+ entrybuf[1] = (png_byte)ep->green;
+ entrybuf[2] = (png_byte)ep->blue;
+ entrybuf[3] = (png_byte)ep->alpha;
+ png_save_uint_16(entrybuf + 4, ep->frequency);
+ }
+ else
+ {
+ png_save_uint_16(entrybuf + 0, ep->red);
+ png_save_uint_16(entrybuf + 2, ep->green);
+ png_save_uint_16(entrybuf + 4, ep->blue);
+ png_save_uint_16(entrybuf + 6, ep->alpha);
+ png_save_uint_16(entrybuf + 8, ep->frequency);
+ }
+ png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
+ }
+#else
+ ep=spalette->entries;
+ for (i=0; i>spalette->nentries; i++)
+ {
+ if (spalette->depth == 8)
+ {
+ entrybuf[0] = (png_byte)ep[i].red;
+ entrybuf[1] = (png_byte)ep[i].green;
+ entrybuf[2] = (png_byte)ep[i].blue;
+ entrybuf[3] = (png_byte)ep[i].alpha;
+ png_save_uint_16(entrybuf + 4, ep[i].frequency);
+ }
+ else
+ {
+ png_save_uint_16(entrybuf + 0, ep[i].red);
+ png_save_uint_16(entrybuf + 2, ep[i].green);
+ png_save_uint_16(entrybuf + 4, ep[i].blue);
+ png_save_uint_16(entrybuf + 6, ep[i].alpha);
+ png_save_uint_16(entrybuf + 8, ep[i].frequency);
+ }
+ png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
+ }
+#endif
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_name);
+}
+#endif
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+/* Write the sBIT chunk */
+void /* PRIVATE */
+png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sBIT;
+#endif
+ png_byte buf[4];
+ png_size_t size;
+
+ png_debug(1, "in png_write_sBIT");
+
+ /* Make sure we don't depend upon the order of PNG_COLOR_8 */
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_byte maxbits;
+
+ maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
+ png_ptr->usr_bit_depth);
+ if (sbit->red == 0 || sbit->red > maxbits ||
+ sbit->green == 0 || sbit->green > maxbits ||
+ sbit->blue == 0 || sbit->blue > maxbits)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+ buf[0] = sbit->red;
+ buf[1] = sbit->green;
+ buf[2] = sbit->blue;
+ size = 3;
+ }
+ else
+ {
+ if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+ buf[0] = sbit->gray;
+ size = 1;
+ }
+
+ if (color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+ buf[size++] = sbit->alpha;
+ }
+
+ png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size);
+}
+#endif
+
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+/* Write the cHRM chunk */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
+ double red_x, double red_y, double green_x, double green_y,
+ double blue_x, double blue_y)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_cHRM;
+#endif
+ png_byte buf[32];
+
+ png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y,
+ int_green_x, int_green_y, int_blue_x, int_blue_y;
+
+ png_debug(1, "in png_write_cHRM");
+
+ int_white_x = (png_uint_32)(white_x * 100000.0 + 0.5);
+ int_white_y = (png_uint_32)(white_y * 100000.0 + 0.5);
+ int_red_x = (png_uint_32)(red_x * 100000.0 + 0.5);
+ int_red_y = (png_uint_32)(red_y * 100000.0 + 0.5);
+ int_green_x = (png_uint_32)(green_x * 100000.0 + 0.5);
+ int_green_y = (png_uint_32)(green_y * 100000.0 + 0.5);
+ int_blue_x = (png_uint_32)(blue_x * 100000.0 + 0.5);
+ int_blue_y = (png_uint_32)(blue_y * 100000.0 + 0.5);
+
+#ifdef PNG_CHECK_cHRM_SUPPORTED
+ if (png_check_cHRM_fixed(png_ptr, int_white_x, int_white_y,
+ int_red_x, int_red_y, int_green_x, int_green_y, int_blue_x, int_blue_y))
+#endif
+ {
+ /* Each value is saved in 1/100,000ths */
+
+ png_save_uint_32(buf, int_white_x);
+ png_save_uint_32(buf + 4, int_white_y);
+
+ png_save_uint_32(buf + 8, int_red_x);
+ png_save_uint_32(buf + 12, int_red_y);
+
+ png_save_uint_32(buf + 16, int_green_x);
+ png_save_uint_32(buf + 20, int_green_y);
+
+ png_save_uint_32(buf + 24, int_blue_x);
+ png_save_uint_32(buf + 28, int_blue_y);
+
+ png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
+ }
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
+ png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
+ png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
+ png_fixed_point blue_y)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_cHRM;
+#endif
+ png_byte buf[32];
+
+ png_debug(1, "in png_write_cHRM");
+
+ /* Each value is saved in 1/100,000ths */
+#ifdef PNG_CHECK_cHRM_SUPPORTED
+ if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y,
+ green_x, green_y, blue_x, blue_y))
+#endif
+ {
+ png_save_uint_32(buf, (png_uint_32)white_x);
+ png_save_uint_32(buf + 4, (png_uint_32)white_y);
+
+ png_save_uint_32(buf + 8, (png_uint_32)red_x);
+ png_save_uint_32(buf + 12, (png_uint_32)red_y);
+
+ png_save_uint_32(buf + 16, (png_uint_32)green_x);
+ png_save_uint_32(buf + 20, (png_uint_32)green_y);
+
+ png_save_uint_32(buf + 24, (png_uint_32)blue_x);
+ png_save_uint_32(buf + 28, (png_uint_32)blue_y);
+
+ png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
+ }
+}
+#endif
+#endif
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+/* Write the tRNS chunk */
+void /* PRIVATE */
+png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
+ int num_trans, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_tRNS;
+#endif
+ png_byte buf[6];
+
+ png_debug(1, "in png_write_tRNS");
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
+ {
+ png_warning(png_ptr, "Invalid number of transparent colors specified");
+ return;
+ }
+ /* Write the chunk out as it is */
+ png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans,
+ (png_size_t)num_trans);
+ }
+ else if (color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ /* One 16 bit value */
+ if (tran->gray >= (1 << png_ptr->bit_depth))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
+ return;
+ }
+ png_save_uint_16(buf, tran->gray);
+ png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2);
+ }
+ else if (color_type == PNG_COLOR_TYPE_RGB)
+ {
+ /* Three 16 bit values */
+ png_save_uint_16(buf, tran->red);
+ png_save_uint_16(buf + 2, tran->green);
+ png_save_uint_16(buf + 4, tran->blue);
+ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+ return;
+ }
+ png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6);
+ }
+ else
+ {
+ png_warning(png_ptr, "Can't write tRNS with an alpha channel");
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+/* Write the background chunk */
+void /* PRIVATE */
+png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_bKGD;
+#endif
+ png_byte buf[6];
+
+ png_debug(1, "in png_write_bKGD");
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ (png_ptr->num_palette ||
+ (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
+#endif
+ back->index >= png_ptr->num_palette)
+ {
+ png_warning(png_ptr, "Invalid background palette index");
+ return;
+ }
+ buf[0] = back->index;
+ png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1);
+ }
+ else if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_save_uint_16(buf, back->red);
+ png_save_uint_16(buf + 2, back->green);
+ png_save_uint_16(buf + 4, back->blue);
+ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
+ return;
+ }
+ png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6);
+ }
+ else
+ {
+ if (back->gray >= (1 << png_ptr->bit_depth))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
+ return;
+ }
+ png_save_uint_16(buf, back->gray);
+ png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2);
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+/* Write the histogram */
+void /* PRIVATE */
+png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_hIST;
+#endif
+ int i;
+ png_byte buf[3];
+
+ png_debug(1, "in png_write_hIST");
+
+ if (num_hist > (int)png_ptr->num_palette)
+ {
+ png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
+ png_ptr->num_palette);
+ png_warning(png_ptr, "Invalid number of histogram entries specified");
+ return;
+ }
+
+ png_write_chunk_start(png_ptr, (png_bytep)png_hIST,
+ (png_uint_32)(num_hist * 2));
+ for (i = 0; i < num_hist; i++)
+ {
+ png_save_uint_16(buf, hist[i]);
+ png_write_chunk_data(png_ptr, buf, (png_size_t)2);
+ }
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
+ * and if invalid, correct the keyword rather than discarding the entire
+ * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
+ * length, forbids leading or trailing whitespace, multiple internal spaces,
+ * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
+ *
+ * The new_key is allocated to hold the corrected keyword and must be freed
+ * by the calling routine. This avoids problems with trying to write to
+ * static keywords without having to have duplicate copies of the strings.
+ */
+png_size_t /* PRIVATE */
+png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
+{
+ png_size_t key_len;
+ png_charp kp, dp;
+ int kflag;
+ int kwarn=0;
+
+ png_debug(1, "in png_check_keyword");
+
+ *new_key = NULL;
+
+ if (key == NULL || (key_len = png_strlen(key)) == 0)
+ {
+ png_warning(png_ptr, "zero length keyword");
+ return ((png_size_t)0);
+ }
+
+ png_debug1(2, "Keyword to be checked is '%s'", key);
+
+ *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
+ if (*new_key == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while procesing keyword");
+ return ((png_size_t)0);
+ }
+
+ /* Replace non-printing characters with a blank and print a warning */
+ for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
+ {
+ if ((png_byte)*kp < 0x20 ||
+ ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1))
+ {
+#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
+ char msg[40];
+
+ png_snprintf(msg, 40,
+ "invalid keyword character 0x%02X", (png_byte)*kp);
+ png_warning(png_ptr, msg);
+#else
+ png_warning(png_ptr, "invalid character in keyword");
+#endif
+ *dp = ' ';
+ }
+ else
+ {
+ *dp = *kp;
+ }
+ }
+ *dp = '\0';
+
+ /* Remove any trailing white space. */
+ kp = *new_key + key_len - 1;
+ if (*kp == ' ')
+ {
+ png_warning(png_ptr, "trailing spaces removed from keyword");
+
+ while (*kp == ' ')
+ {
+ *(kp--) = '\0';
+ key_len--;
+ }
+ }
+
+ /* Remove any leading white space. */
+ kp = *new_key;
+ if (*kp == ' ')
+ {
+ png_warning(png_ptr, "leading spaces removed from keyword");
+
+ while (*kp == ' ')
+ {
+ kp++;
+ key_len--;
+ }
+ }
+
+ png_debug1(2, "Checking for multiple internal spaces in '%s'", kp);
+
+ /* Remove multiple internal spaces. */
+ for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
+ {
+ if (*kp == ' ' && kflag == 0)
+ {
+ *(dp++) = *kp;
+ kflag = 1;
+ }
+ else if (*kp == ' ')
+ {
+ key_len--;
+ kwarn=1;
+ }
+ else
+ {
+ *(dp++) = *kp;
+ kflag = 0;
+ }
+ }
+ *dp = '\0';
+ if (kwarn)
+ png_warning(png_ptr, "extra interior spaces removed from keyword");
+
+ if (key_len == 0)
+ {
+ png_free(png_ptr, *new_key);
+ *new_key=NULL;
+ png_warning(png_ptr, "Zero length keyword");
+ }
+
+ if (key_len > 79)
+ {
+ png_warning(png_ptr, "keyword length must be 1 - 79 characters");
+ (*new_key)[79] = '\0';
+ key_len = 79;
+ }
+
+ return (key_len);
+}
+#endif
+
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+/* Write a tEXt chunk */
+void /* PRIVATE */
+png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
+ png_size_t text_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_tEXt;
+#endif
+ png_size_t key_len;
+ png_charp new_key;
+
+ png_debug(1, "in png_write_tEXt");
+
+ if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+ return;
+
+ if (text == NULL || *text == '\0')
+ text_len = 0;
+ else
+ text_len = png_strlen(text);
+
+ /* Make sure we include the 0 after the key */
+ png_write_chunk_start(png_ptr, (png_bytep)png_tEXt,
+ (png_uint_32)(key_len + text_len + 1));
+ /*
+ * We leave it to the application to meet PNG-1.0 requirements on the
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+ */
+ png_write_chunk_data(png_ptr, (png_bytep)new_key,
+ (png_size_t)(key_len + 1));
+ if (text_len)
+ png_write_chunk_data(png_ptr, (png_bytep)text, (png_size_t)text_len);
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_key);
+}
+#endif
+
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+/* Write a compressed text chunk */
+void /* PRIVATE */
+png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
+ png_size_t text_len, int compression)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_zTXt;
+#endif
+ png_size_t key_len;
+ char buf[1];
+ png_charp new_key;
+ compression_state comp;
+
+ png_debug(1, "in png_write_zTXt");
+
+ comp.num_output_ptr = 0;
+ comp.max_output_ptr = 0;
+ comp.output_ptr = NULL;
+ comp.input = NULL;
+ comp.input_len = 0;
+
+ if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+ {
+ png_free(png_ptr, new_key);
+ return;
+ }
+
+ if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
+ {
+ png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
+ png_free(png_ptr, new_key);
+ return;
+ }
+
+ text_len = png_strlen(text);
+
+ /* Compute the compressed data; do it now for the length */
+ text_len = png_text_compress(png_ptr, text, text_len, compression,
+ &comp);
+
+ /* Write start of chunk */
+ png_write_chunk_start(png_ptr, (png_bytep)png_zTXt,
+ (png_uint_32)(key_len+text_len + 2));
+ /* Write key */
+ png_write_chunk_data(png_ptr, (png_bytep)new_key,
+ (png_size_t)(key_len + 1));
+ png_free(png_ptr, new_key);
+
+ buf[0] = (png_byte)compression;
+ /* Write compression */
+ png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
+ /* Write the compressed data */
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ /* Close the chunk */
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+/* Write an iTXt chunk */
+void /* PRIVATE */
+png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
+ png_charp lang, png_charp lang_key, png_charp text)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_iTXt;
+#endif
+ png_size_t lang_len, key_len, lang_key_len, text_len;
+ png_charp new_lang;
+ png_charp new_key = NULL;
+ png_byte cbuf[2];
+ compression_state comp;
+
+ png_debug(1, "in png_write_iTXt");
+
+ comp.num_output_ptr = 0;
+ comp.max_output_ptr = 0;
+ comp.output_ptr = NULL;
+ comp.input = NULL;
+
+ if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+ return;
+
+ if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0)
+ {
+ png_warning(png_ptr, "Empty language field in iTXt chunk");
+ new_lang = NULL;
+ lang_len = 0;
+ }
+
+ if (lang_key == NULL)
+ lang_key_len = 0;
+ else
+ lang_key_len = png_strlen(lang_key);
+
+ if (text == NULL)
+ text_len = 0;
+ else
+ text_len = png_strlen(text);
+
+ /* Compute the compressed data; do it now for the length */
+ text_len = png_text_compress(png_ptr, text, text_len, compression-2,
+ &comp);
+
+
+ /* Make sure we include the compression flag, the compression byte,
+ * and the NULs after the key, lang, and lang_key parts */
+
+ png_write_chunk_start(png_ptr, (png_bytep)png_iTXt,
+ (png_uint_32)(
+ 5 /* comp byte, comp flag, terminators for key, lang and lang_key */
+ + key_len
+ + lang_len
+ + lang_key_len
+ + text_len));
+
+ /* We leave it to the application to meet PNG-1.0 requirements on the
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+ */
+ png_write_chunk_data(png_ptr, (png_bytep)new_key,
+ (png_size_t)(key_len + 1));
+
+ /* Set the compression flag */
+ if (compression == PNG_ITXT_COMPRESSION_NONE || \
+ compression == PNG_TEXT_COMPRESSION_NONE)
+ cbuf[0] = 0;
+ else /* compression == PNG_ITXT_COMPRESSION_zTXt */
+ cbuf[0] = 1;
+ /* Set the compression method */
+ cbuf[1] = 0;
+ png_write_chunk_data(png_ptr, cbuf, (png_size_t)2);
+
+ cbuf[0] = 0;
+ png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf),
+ (png_size_t)(lang_len + 1));
+ png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf),
+ (png_size_t)(lang_key_len + 1));
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_key);
+ png_free(png_ptr, new_lang);
+}
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+/* Write the oFFs chunk */
+void /* PRIVATE */
+png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
+ int unit_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_oFFs;
+#endif
+ png_byte buf[9];
+
+ png_debug(1, "in png_write_oFFs");
+
+ if (unit_type >= PNG_OFFSET_LAST)
+ png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
+
+ png_save_int_32(buf, x_offset);
+ png_save_int_32(buf + 4, y_offset);
+ buf[8] = (png_byte)unit_type;
+
+ png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9);
+}
+#endif
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+/* Write the pCAL chunk (described in the PNG extensions document) */
+void /* PRIVATE */
+png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
+ png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_pCAL;
+#endif
+ png_size_t purpose_len, units_len, total_len;
+ png_uint_32p params_len;
+ png_byte buf[10];
+ png_charp new_purpose;
+ int i;
+
+ png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
+
+ if (type >= PNG_EQUATION_LAST)
+ png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+
+ purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
+ png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
+ units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
+ png_debug1(3, "pCAL units length = %d", (int)units_len);
+ total_len = purpose_len + units_len + 10;
+
+ params_len = (png_uint_32p)png_malloc(png_ptr,
+ (png_uint_32)(nparams * png_sizeof(png_uint_32)));
+
+ /* Find the length of each parameter, making sure we don't count the
+ null terminator for the last parameter. */
+ for (i = 0; i < nparams; i++)
+ {
+ params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
+ png_debug2(3, "pCAL parameter %d length = %lu", i,
+ (unsigned long) params_len[i]);
+ total_len += (png_size_t)params_len[i];
+ }
+
+ png_debug1(3, "pCAL total length = %d", (int)total_len);
+ png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len);
+ png_write_chunk_data(png_ptr, (png_bytep)new_purpose,
+ (png_size_t)purpose_len);
+ png_save_int_32(buf, X0);
+ png_save_int_32(buf + 4, X1);
+ buf[8] = (png_byte)type;
+ buf[9] = (png_byte)nparams;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)10);
+ png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
+
+ png_free(png_ptr, new_purpose);
+
+ for (i = 0; i < nparams; i++)
+ {
+ png_write_chunk_data(png_ptr, (png_bytep)params[i],
+ (png_size_t)params_len[i]);
+ }
+
+ png_free(png_ptr, params_len);
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+/* Write the sCAL chunk */
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
+void /* PRIVATE */
+png_write_sCAL(png_structp png_ptr, int unit, double width, double height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sCAL;
+#endif
+ char buf[64];
+ png_size_t total_len;
+
+ png_debug(1, "in png_write_sCAL");
+
+ buf[0] = (char)unit;
+#ifdef _WIN32_WCE
+/* sprintf() function is not supported on WindowsCE */
+ {
+ wchar_t wc_buf[32];
+ size_t wc_len;
+ swprintf(wc_buf, TEXT("%12.12e"), width);
+ wc_len = wcslen(wc_buf);
+ WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL,
+ NULL);
+ total_len = wc_len + 2;
+ swprintf(wc_buf, TEXT("%12.12e"), height);
+ wc_len = wcslen(wc_buf);
+ WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len,
+ NULL, NULL);
+ total_len += wc_len;
+ }
+#else
+ png_snprintf(buf + 1, 63, "%12.12e", width);
+ total_len = 1 + png_strlen(buf + 1) + 1;
+ png_snprintf(buf + total_len, 64-total_len, "%12.12e", height);
+ total_len += png_strlen(buf + total_len);
+#endif
+
+ png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
+ png_write_chunk(png_ptr, (png_bytep)png_sCAL, (png_bytep)buf, total_len);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
+ png_charp height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sCAL;
+#endif
+ png_byte buf[64];
+ png_size_t wlen, hlen, total_len;
+
+ png_debug(1, "in png_write_sCAL_s");
+
+ wlen = png_strlen(width);
+ hlen = png_strlen(height);
+ total_len = wlen + hlen + 2;
+ if (total_len > 64)
+ {
+ png_warning(png_ptr, "Can't write sCAL (buffer too small)");
+ return;
+ }
+
+ buf[0] = (png_byte)unit;
+ png_memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */
+ png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */
+
+ png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
+ png_write_chunk(png_ptr, (png_bytep)png_sCAL, buf, total_len);
+}
+#endif
+#endif
+#endif
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+/* Write the pHYs chunk */
+void /* PRIVATE */
+png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
+ png_uint_32 y_pixels_per_unit,
+ int unit_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_pHYs;
+#endif
+ png_byte buf[9];
+
+ png_debug(1, "in png_write_pHYs");
+
+ if (unit_type >= PNG_RESOLUTION_LAST)
+ png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
+
+ png_save_uint_32(buf, x_pixels_per_unit);
+ png_save_uint_32(buf + 4, y_pixels_per_unit);
+ buf[8] = (png_byte)unit_type;
+
+ png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9);
+}
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+/* Write the tIME chunk. Use either png_convert_from_struct_tm()
+ * or png_convert_from_time_t(), or fill in the structure yourself.
+ */
+void /* PRIVATE */
+png_write_tIME(png_structp png_ptr, png_timep mod_time)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_tIME;
+#endif
+ png_byte buf[7];
+
+ png_debug(1, "in png_write_tIME");
+
+ if (mod_time->month > 12 || mod_time->month < 1 ||
+ mod_time->day > 31 || mod_time->day < 1 ||
+ mod_time->hour > 23 || mod_time->second > 60)
+ {
+ png_warning(png_ptr, "Invalid time specified for tIME chunk");
+ return;
+ }
+
+ png_save_uint_16(buf, mod_time->year);
+ buf[2] = mod_time->month;
+ buf[3] = mod_time->day;
+ buf[4] = mod_time->hour;
+ buf[5] = mod_time->minute;
+ buf[6] = mod_time->second;
+
+ png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7);
+}
+#endif
+
+/* Initializes the row writing capability of libpng */
+void /* PRIVATE */
+png_write_start_row(png_structp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ png_size_t buf_size;
+
+ png_debug(1, "in png_write_start_row");
+
+ buf_size = (png_size_t)(PNG_ROWBYTES(
+ png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1);
+
+ /* Set up row buffer */
+ png_ptr->row_buf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)buf_size);
+ png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ /* Set up filtering buffer, if using this filter */
+ if (png_ptr->do_filter & PNG_FILTER_SUB)
+ {
+ png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(png_ptr->rowbytes + 1));
+ png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+ }
+
+ /* We only need to keep the previous row if we are using one of these. */
+ if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
+ {
+ /* Set up previous row buffer */
+ png_ptr->prev_row = (png_bytep)png_calloc(png_ptr,
+ (png_uint_32)buf_size);
+
+ if (png_ptr->do_filter & PNG_FILTER_UP)
+ {
+ png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(png_ptr->rowbytes + 1));
+ png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+ }
+
+ if (png_ptr->do_filter & PNG_FILTER_AVG)
+ {
+ png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(png_ptr->rowbytes + 1));
+ png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+ }
+
+ if (png_ptr->do_filter & PNG_FILTER_PAETH)
+ {
+ png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(png_ptr->rowbytes + 1));
+ png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+ }
+ }
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* If interlaced, we need to set up width and height of pass */
+ if (png_ptr->interlaced)
+ {
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+ png_pass_ystart[0]) / png_pass_yinc[0];
+ png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
+ png_pass_start[0]) / png_pass_inc[0];
+ }
+ else
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->usr_width = png_ptr->width;
+ }
+ }
+ else
+#endif
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->usr_width = png_ptr->width;
+ }
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+}
+
+/* Internal use only. Called when finished processing a row of data. */
+void /* PRIVATE */
+png_write_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ int ret;
+
+ png_debug(1, "in png_write_finish_row");
+
+ /* Next row */
+ png_ptr->row_number++;
+
+ /* See if we are done */
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* If interlaced, go to next pass */
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+ if (png_ptr->transformations & PNG_INTERLACE)
+ {
+ png_ptr->pass++;
+ }
+ else
+ {
+ /* Loop until we find a non-zero width or height pass */
+ do
+ {
+ png_ptr->pass++;
+ if (png_ptr->pass >= 7)
+ break;
+ png_ptr->usr_width = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+ if (png_ptr->transformations & PNG_INTERLACE)
+ break;
+ } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
+
+ }
+
+ /* Reset the row above the image for the next pass */
+ if (png_ptr->pass < 7)
+ {
+ if (png_ptr->prev_row != NULL)
+ png_memset(png_ptr->prev_row, 0,
+ (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
+ png_ptr->usr_bit_depth, png_ptr->width)) + 1);
+ return;
+ }
+ }
+#endif
+
+ /* If we get here, we've just written the last row, so we need
+ to flush the compressor */
+ do
+ {
+ /* Tell the compressor we are done */
+ ret = deflate(&png_ptr->zstream, Z_FINISH);
+ /* Check for an error */
+ if (ret == Z_OK)
+ {
+ /* Check to see if we need more room */
+ if (!(png_ptr->zstream.avail_out))
+ {
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ }
+ else if (ret != Z_STREAM_END)
+ {
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+ } while (ret != Z_STREAM_END);
+
+ /* Write any extra space */
+ if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+ {
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
+ png_ptr->zstream.avail_out);
+ }
+
+ deflateReset(&png_ptr->zstream);
+ png_ptr->zstream.data_type = Z_BINARY;
+}
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+/* Pick out the correct pixels for the interlace pass.
+ * The basic idea here is to go through the row with a source
+ * pointer and a destination pointer (sp and dp), and copy the
+ * correct pixels for the pass. As the row gets compacted,
+ * sp will always be >= dp, so we should never overwrite anything.
+ * See the default: case for the easiest code to understand.
+ */
+void /* PRIVATE */
+png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
+{
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ png_debug(1, "in png_do_write_interlace");
+
+ /* We don't have to do anything on the last pass (6) */
+#ifdef PNG_USELESS_TESTS_SUPPORTED
+ if (row != NULL && row_info != NULL && pass < 6)
+#else
+ if (pass < 6)
+#endif
+ {
+ /* Each pixel depth is handled separately */
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ d = 0;
+ shift = 7;
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 3);
+ value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 7;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+ else
+ shift--;
+
+ }
+ if (shift != 7)
+ *dp = (png_byte)d;
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ shift = 6;
+ d = 0;
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 2);
+ value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 6;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+ else
+ shift -= 2;
+ }
+ if (shift != 6)
+ *dp = (png_byte)d;
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ shift = 4;
+ d = 0;
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 1);
+ value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 4;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+ else
+ shift -= 4;
+ }
+ if (shift != 4)
+ *dp = (png_byte)d;
+ break;
+ }
+ default:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ png_size_t pixel_bytes;
+
+ /* Start at the beginning */
+ dp = row;
+ /* Find out how many bytes each pixel takes up */
+ pixel_bytes = (row_info->pixel_depth >> 3);
+ /* Loop through the row, only looking at the pixels that
+ matter */
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ /* Find out where the original pixel is */
+ sp = row + (png_size_t)i * pixel_bytes;
+ /* Move the pixel */
+ if (dp != sp)
+ png_memcpy(dp, sp, pixel_bytes);
+ /* Next pixel */
+ dp += pixel_bytes;
+ }
+ break;
+ }
+ }
+ /* Set new row width */
+ row_info->width = (row_info->width +
+ png_pass_inc[pass] - 1 -
+ png_pass_start[pass]) /
+ png_pass_inc[pass];
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_info->width);
+ }
+}
+#endif
+
+/* This filters the row, chooses which filter to use, if it has not already
+ * been specified by the application, and then writes the row out with the
+ * chosen filter.
+ */
+#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
+#define PNG_HISHIFT 10
+#define PNG_LOMASK ((png_uint_32)0xffffL)
+#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
+void /* PRIVATE */
+png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
+{
+ png_bytep best_row;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ png_bytep prev_row, row_buf;
+ png_uint_32 mins, bpp;
+ png_byte filter_to_do = png_ptr->do_filter;
+ png_uint_32 row_bytes = row_info->rowbytes;
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ int num_p_filters = (int)png_ptr->num_prev_filters;
+#endif
+
+ png_debug(1, "in png_write_find_filter");
+
+#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
+ {
+ /* These will never be selected so we need not test them. */
+ filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
+ }
+#endif
+
+ /* Find out how many bytes offset each pixel is */
+ bpp = (row_info->pixel_depth + 7) >> 3;
+
+ prev_row = png_ptr->prev_row;
+#endif
+ best_row = png_ptr->row_buf;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ row_buf = best_row;
+ mins = PNG_MAXSUM;
+
+ /* The prediction method we use is to find which method provides the
+ * smallest value when summing the absolute values of the distances
+ * from zero, using anything >= 128 as negative numbers. This is known
+ * as the "minimum sum of absolute differences" heuristic. Other
+ * heuristics are the "weighted minimum sum of absolute differences"
+ * (experimental and can in theory improve compression), and the "zlib
+ * predictive" method (not implemented yet), which does test compressions
+ * of lines using different filter methods, and then chooses the
+ * (series of) filter(s) that give minimum compressed data size (VERY
+ * computationally expensive).
+ *
+ * GRR 980525: consider also
+ * (1) minimum sum of absolute differences from running average (i.e.,
+ * keep running sum of non-absolute differences & count of bytes)
+ * [track dispersion, too? restart average if dispersion too large?]
+ * (1b) minimum sum of absolute differences from sliding average, probably
+ * with window size <= deflate window (usually 32K)
+ * (2) minimum sum of squared differences from zero or running average
+ * (i.e., ~ root-mean-square approach)
+ */
+
+
+ /* We don't need to test the 'no filter' case if this is the only filter
+ * that has been chosen, as it doesn't actually do anything to the data.
+ */
+ if ((filter_to_do & PNG_FILTER_NONE) &&
+ filter_to_do != PNG_FILTER_NONE)
+ {
+ png_bytep rp;
+ png_uint_32 sum = 0;
+ png_uint_32 i;
+ int v;
+
+ for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
+ {
+ v = *rp;
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ png_uint_32 sumhi, sumlo;
+ int j;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
+
+ /* Reduce the sum if we match any of the previous rows */
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ /* Factor in the cost of this filter (this is here for completeness,
+ * but it makes no sense to have a "cost" for the NONE filter, as
+ * it has the minimum possible computational cost - none).
+ */
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+ mins = sum;
+ }
+
+ /* Sub filter */
+ if (filter_to_do == PNG_FILTER_SUB)
+ /* It's the only filter so no testing is needed */
+ {
+ png_bytep rp, lp, dp;
+ png_uint_32 i;
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ *dp = *rp;
+ }
+ for (lp = row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+ }
+ best_row = png_ptr->sub_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_SUB)
+ {
+ png_bytep rp, dp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ /* We temporarily increase the "minimum sum" by the factor we
+ * would reduce the sum of this filter, so that we can do the
+ * early exit comparison without scaling the sum each time.
+ */
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ v = *dp = *rp;
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+ for (lp = row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+ {
+ sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->sub_row;
+ }
+ }
+
+ /* Up filter */
+ if (filter_to_do == PNG_FILTER_UP)
+ {
+ png_bytep rp, dp, pp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+ pp = prev_row + 1; i < row_bytes;
+ i++, rp++, pp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+ }
+ best_row = png_ptr->up_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_UP)
+ {
+ png_bytep rp, dp, pp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+ pp = prev_row + 1; i < row_bytes; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->up_row;
+ }
+ }
+
+ /* Avg filter */
+ if (filter_to_do == PNG_FILTER_AVG)
+ {
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 i;
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+ }
+ for (lp = row_buf + 1; i < row_bytes; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+ & 0xff);
+ }
+ best_row = png_ptr->avg_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_AVG)
+ {
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+ for (lp = row_buf + 1; i < row_bytes; i++)
+ {
+ v = *dp++ =
+ (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->avg_row;
+ }
+ }
+
+ /* Paeth filter */
+ if (filter_to_do == PNG_FILTER_PAETH)
+ {
+ png_bytep rp, dp, pp, cp, lp;
+ png_uint_32 i;
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+ }
+
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+ }
+ best_row = png_ptr->paeth_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_PAETH)
+ {
+ png_bytep rp, dp, pp, cp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+#ifndef PNG_SLOW_PAETH
+ p = b - c;
+ pc = a - c;
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+#else /* PNG_SLOW_PAETH */
+ p = a + b - c;
+ pa = abs(p - a);
+ pb = abs(p - b);
+ pc = abs(p - c);
+ if (pa <= pb && pa <= pc)
+ p = a;
+ else if (pb <= pc)
+ p = b;
+ else
+ p = c;
+#endif /* PNG_SLOW_PAETH */
+
+ v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ best_row = png_ptr->paeth_row;
+ }
+ }
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+ /* Do the actual writing of the filtered row data from the chosen filter. */
+
+ png_write_filtered_row(png_ptr, best_row);
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ /* Save the type of filter we picked this time for future calculations */
+ if (png_ptr->num_prev_filters > 0)
+ {
+ int j;
+ for (j = 1; j < num_p_filters; j++)
+ {
+ png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
+ }
+ png_ptr->prev_filters[j] = best_row[0];
+ }
+#endif
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+}
+
+
+/* Do the actual writing of a previously filtered row. */
+void /* PRIVATE */
+png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
+{
+ png_debug(1, "in png_write_filtered_row");
+
+ png_debug1(2, "filter = %d", filtered_row[0]);
+ /* Set up the zlib input buffer */
+
+ png_ptr->zstream.next_in = filtered_row;
+ png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
+ /* Repeat until we have compressed all the data */
+ do
+ {
+ int ret; /* Return of zlib */
+
+ /* Compress the data */
+ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+ /* Check for compression errors */
+ if (ret != Z_OK)
+ {
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+
+ /* See if it is time to write another IDAT */
+ if (!(png_ptr->zstream.avail_out))
+ {
+ /* Write the IDAT and reset the zlib output buffer */
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ /* Repeat until all data has been compressed */
+ } while (png_ptr->zstream.avail_in);
+
+ /* Swap the current and previous rows */
+ if (png_ptr->prev_row != NULL)
+ {
+ png_bytep tptr;
+
+ tptr = png_ptr->prev_row;
+ png_ptr->prev_row = png_ptr->row_buf;
+ png_ptr->row_buf = tptr;
+ }
+
+ /* Finish row - updates counters and flushes zlib if last row */
+ png_write_finish_row(png_ptr);
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+ png_ptr->flush_rows++;
+
+ if (png_ptr->flush_dist > 0 &&
+ png_ptr->flush_rows >= png_ptr->flush_dist)
+ {
+ png_write_flush(png_ptr);
+ }
+#endif
+}
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/src/main-loop.cpp b/src/main-loop.cpp
new file mode 100644
index 0000000..2bbd824
--- /dev/null
+++ b/src/main-loop.cpp
@@ -0,0 +1,333 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "options.h"
+#include "main-loop.h"
+#include "util.h"
+#include "log.h"
+
+#include <string>
+#include <sstream>
+
+/************
+ * MainLoop *
+ ************/
+
+MainLoop::MainLoop(Canvas &canvas, const std::vector<Benchmark *> &benchmarks) :
+ canvas_(canvas), benchmarks_(benchmarks)
+{
+ reset();
+}
+
+
+void
+MainLoop::reset()
+{
+ scene_ = 0;
+ scene_setup_status_ = SceneSetupStatusUnknown;
+ score_ = 0;
+ benchmarks_run_ = 0;
+ bench_iter_ = benchmarks_.begin();
+}
+
+unsigned int
+MainLoop::score()
+{
+ if (benchmarks_run_)
+ return score_ / benchmarks_run_;
+ else
+ return score_;
+}
+
+bool
+MainLoop::step()
+{
+ /* Find the next normal scene */
+ if (!scene_) {
+ /* Find a normal scene */
+ while (bench_iter_ != benchmarks_.end()) {
+ scene_ = &(*bench_iter_)->scene();
+
+ /*
+ * Scenes with empty names are option-setting scenes.
+ * Just set them up and continue with the search.
+ */
+ if (scene_->name().empty())
+ (*bench_iter_)->setup_scene();
+ else
+ break;
+
+ next_benchmark();
+ }
+
+ /* If we have found a valid scene, set it up */
+ if (bench_iter_ != benchmarks_.end()) {
+ if (!Options::reuse_context)
+ canvas_.reset();
+ before_scene_setup();
+ scene_ = &(*bench_iter_)->setup_scene();
+ if (!scene_->running()) {
+ if (!scene_->supported(false))
+ scene_setup_status_ = SceneSetupStatusUnsupported;
+ else
+ scene_setup_status_ = SceneSetupStatusFailure;
+ }
+ else {
+ scene_setup_status_ = SceneSetupStatusSuccess;
+ }
+ after_scene_setup();
+ log_scene_info();
+ }
+ else {
+ /* ... otherwise we are done */
+ return false;
+ }
+ }
+
+ bool should_quit = canvas_.should_quit();
+
+ if (scene_ ->running() && !should_quit)
+ draw();
+
+ /*
+ * Need to recheck whether the scene is still running, because code
+ * in draw() may have changed the state.
+ */
+ if (!scene_->running() || should_quit) {
+ if (scene_setup_status_ == SceneSetupStatusSuccess) {
+ score_ += scene_->average_fps();
+ benchmarks_run_++;
+ }
+ log_scene_result();
+ (*bench_iter_)->teardown_scene();
+ scene_ = 0;
+ next_benchmark();
+ }
+
+ return !should_quit;
+}
+
+void
+MainLoop::draw()
+{
+ canvas_.clear();
+
+ scene_->draw();
+ scene_->update();
+
+ canvas_.update();
+}
+
+void
+MainLoop::log_scene_info()
+{
+ Log::info("%s", scene_->info_string().c_str());
+ Log::flush();
+}
+
+void
+MainLoop::log_scene_result()
+{
+ static const std::string format_fps(Log::continuation_prefix +
+ " FPS: %u FrameTime: %.3f ms\n");
+ static const std::string format_unsupported(Log::continuation_prefix +
+ " Unsupported\n");
+ static const std::string format_fail(Log::continuation_prefix +
+ " Set up failed\n");
+
+ if (scene_setup_status_ == SceneSetupStatusSuccess) {
+ Log::info(format_fps.c_str(), scene_->average_fps(),
+ 1000.0 / scene_->average_fps());
+ }
+ else if (scene_setup_status_ == SceneSetupStatusUnsupported) {
+ Log::info(format_unsupported.c_str());
+ }
+ else {
+ Log::info(format_fail.c_str());
+ }
+}
+
+void
+MainLoop::next_benchmark()
+{
+ bench_iter_++;
+ if (bench_iter_ == benchmarks_.end() && Options::run_forever)
+ bench_iter_ = benchmarks_.begin();
+}
+
+/**********************
+ * MainLoopDecoration *
+ **********************/
+
+MainLoopDecoration::MainLoopDecoration(Canvas &canvas, const std::vector<Benchmark *> &benchmarks) :
+ MainLoop(canvas, benchmarks), show_fps_(false), show_title_(false),
+ fps_renderer_(0), title_renderer_(0), last_fps_(0)
+{
+
+}
+
+MainLoopDecoration::~MainLoopDecoration()
+{
+ delete fps_renderer_;
+ fps_renderer_ = 0;
+ delete title_renderer_;
+ title_renderer_ = 0;
+}
+
+void
+MainLoopDecoration::draw()
+{
+ static const unsigned int fps_interval = 500000;
+
+ canvas_.clear();
+
+ scene_->draw();
+ scene_->update();
+
+ if (show_fps_) {
+ uint64_t now = Util::get_timestamp_us();
+ if (now - fps_timestamp_ >= fps_interval) {
+ last_fps_ = scene_->average_fps();
+ fps_renderer_update_text(last_fps_);
+ fps_timestamp_ = now;
+ }
+ fps_renderer_->render();
+ }
+
+ if (show_title_)
+ title_renderer_->render();
+
+ canvas_.update();
+}
+
+void
+MainLoopDecoration::before_scene_setup()
+{
+ delete fps_renderer_;
+ fps_renderer_ = 0;
+ delete title_renderer_;
+ title_renderer_ = 0;
+}
+
+void
+MainLoopDecoration::after_scene_setup()
+{
+ const Scene::Option &show_fps_option(scene_->options().find("show-fps")->second);
+ const Scene::Option &title_option(scene_->options().find("title")->second);
+ show_fps_ = show_fps_option.value == "true";
+ show_title_ = !title_option.value.empty();
+
+ if (show_fps_) {
+ const Scene::Option &fps_pos_option(scene_->options().find("fps-pos")->second);
+ const Scene::Option &fps_size_option(scene_->options().find("fps-size")->second);
+ fps_renderer_ = new TextRenderer(canvas_);
+ fps_renderer_->position(vec2_from_pos_string(fps_pos_option.value));
+ fps_renderer_->size(Util::fromString<float>(fps_size_option.value));
+ fps_renderer_update_text(last_fps_);
+ fps_timestamp_ = Util::get_timestamp_us();
+ }
+
+ if (show_title_) {
+ const Scene::Option &title_pos_option(scene_->options().find("title-pos")->second);
+ const Scene::Option &title_size_option(scene_->options().find("title-size")->second);
+ title_renderer_ = new TextRenderer(canvas_);
+ title_renderer_->position(vec2_from_pos_string(title_pos_option.value));
+ title_renderer_->size(Util::fromString<float>(title_size_option.value));
+
+ if (title_option.value == "#info#")
+ title_renderer_->text(scene_->info_string());
+ else if (title_option.value == "#name#")
+ title_renderer_->text(scene_->name());
+ else if (title_option.value == "#r2d2#")
+ title_renderer_->text("Help me, Obi-Wan Kenobi. You're my only hope.");
+ else
+ title_renderer_->text(title_option.value);
+ }
+}
+
+void
+MainLoopDecoration::fps_renderer_update_text(unsigned int fps)
+{
+ std::stringstream ss;
+ ss << "FPS: " << fps;
+ fps_renderer_->text(ss.str());
+}
+
+LibMatrix::vec2
+MainLoopDecoration::vec2_from_pos_string(const std::string &s)
+{
+ LibMatrix::vec2 v(0.0, 0.0);
+ std::vector<std::string> elems;
+ Util::split(s, ',', elems, Util::SplitModeNormal);
+
+ if (elems.size() > 0)
+ v.x(Util::fromString<float>(elems[0]));
+
+ if (elems.size() > 1)
+ v.y(Util::fromString<float>(elems[1]));
+
+ return v;
+}
+
+/**********************
+ * MainLoopValidation *
+ **********************/
+
+MainLoopValidation::MainLoopValidation(Canvas &canvas, const std::vector<Benchmark *> &benchmarks) :
+ MainLoop(canvas, benchmarks)
+{
+}
+
+void
+MainLoopValidation::draw()
+{
+ /* Draw only the first frame of the scene and stop */
+ canvas_.clear();
+
+ scene_->draw();
+
+ canvas_.update();
+
+ scene_->running(false);
+}
+
+void
+MainLoopValidation::log_scene_result()
+{
+ static const std::string format(Log::continuation_prefix + " Validation: %s\n");
+ std::string result;
+
+ switch(scene_->validate()) {
+ case Scene::ValidationSuccess:
+ result = "Success";
+ break;
+ case Scene::ValidationFailure:
+ result = "Failure";
+ break;
+ case Scene::ValidationUnknown:
+ result = "Unknown";
+ break;
+ default:
+ break;
+ }
+
+ Log::info(format.c_str(), result.c_str());
+}
diff --git a/src/main-loop.h b/src/main-loop.h
new file mode 100644
index 0000000..918681e
--- /dev/null
+++ b/src/main-loop.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#ifndef GLMARK2_MAIN_LOOP_H_
+#define GLMARK2_MAIN_LOOP_H_
+
+#include "canvas.h"
+#include "benchmark.h"
+#include "text-renderer.h"
+#include "vec.h"
+#include <vector>
+
+/**
+ * Main loop for benchmarking.
+ */
+class MainLoop
+{
+public:
+ MainLoop(Canvas &canvas, const std::vector<Benchmark *> &benchmarks);
+
+ virtual ~MainLoop() {}
+
+ /**
+ * Resets the main loop.
+ *
+ * You need to call reset() if the loop has finished and
+ * you need to run it again.
+ */
+ void reset();
+
+ /**
+ * Gets the current total benchmarking score.
+ */
+ unsigned int score();
+
+ /**
+ * Perform the next main loop step.
+ *
+ * @returns whether the loop has finished
+ */
+ bool step();
+
+ /**
+ * Overridable method for drawing the canvas contents.
+ */
+ virtual void draw();
+
+ /**
+ * Overridable method for pre scene-setup customizations.
+ */
+ virtual void before_scene_setup() {}
+
+ /**
+ * Overridable method for post scene-setup customizations.
+ */
+ virtual void after_scene_setup() {}
+
+ /**
+ * Overridable method for logging scene info.
+ */
+ virtual void log_scene_info();
+
+ /**
+ * Overridable method for logging scene result.
+ */
+ virtual void log_scene_result();
+
+protected:
+ enum SceneSetupStatus {
+ SceneSetupStatusUnknown,
+ SceneSetupStatusSuccess,
+ SceneSetupStatusFailure,
+ SceneSetupStatusUnsupported
+ };
+ void next_benchmark();
+ Canvas &canvas_;
+ Scene *scene_;
+ const std::vector<Benchmark *> &benchmarks_;
+ unsigned int score_;
+ unsigned int benchmarks_run_;
+ SceneSetupStatus scene_setup_status_;
+
+ std::vector<Benchmark *>::const_iterator bench_iter_;
+};
+
+/**
+ * Main loop for benchmarking with decorations (eg FPS, demo)
+ */
+class MainLoopDecoration : public MainLoop
+{
+public:
+ MainLoopDecoration(Canvas &canvas, const std::vector<Benchmark *> &benchmarks);
+ virtual ~MainLoopDecoration();
+
+ virtual void draw();
+ virtual void before_scene_setup();
+ virtual void after_scene_setup();
+
+protected:
+ void fps_renderer_update_text(unsigned int fps);
+ LibMatrix::vec2 vec2_from_pos_string(const std::string &s);
+
+ bool show_fps_;
+ bool show_title_;
+ TextRenderer *fps_renderer_;
+ TextRenderer *title_renderer_;
+ unsigned int last_fps_;
+ uint64_t fps_timestamp_;
+};
+
+/**
+ * Main loop for validation.
+ */
+class MainLoopValidation : public MainLoop
+{
+public:
+ MainLoopValidation(Canvas &canvas, const std::vector<Benchmark *> &benchmarks);
+
+ virtual void draw();
+ virtual void log_scene_result();
+};
+
+#endif /* GLMARK2_MAIN_LOOP_H_ */
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..4402a64
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,228 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker (glmark2)
+ */
+#include "gl-headers.h"
+#include "scene.h"
+#include "benchmark.h"
+#include "options.h"
+#include "log.h"
+#include "util.h"
+#include "text-renderer.h"
+#include "main-loop.h"
+#include "benchmark-collection.h"
+
+#include <iostream>
+#include <fstream>
+
+#if USE_DRM
+#include "canvas-drm.h"
+#elif USE_GL
+#include "canvas-x11-glx.h"
+#elif USE_GLESv2
+#include "canvas-x11-egl.h"
+#endif
+
+using std::vector;
+using std::map;
+using std::string;
+
+void
+add_and_register_scenes(vector<Scene*>& scenes, Canvas& canvas)
+{
+ scenes.push_back(new SceneDefaultOptions(canvas));
+ scenes.push_back(new SceneBuild(canvas));
+ scenes.push_back(new SceneTexture(canvas));
+ scenes.push_back(new SceneShading(canvas));
+ scenes.push_back(new SceneConditionals(canvas));
+ scenes.push_back(new SceneFunction(canvas));
+ scenes.push_back(new SceneLoop(canvas));
+ scenes.push_back(new SceneBump(canvas));
+ scenes.push_back(new SceneEffect2D(canvas));
+ scenes.push_back(new ScenePulsar(canvas));
+ scenes.push_back(new SceneDesktop(canvas));
+ scenes.push_back(new SceneBuffer(canvas));
+ scenes.push_back(new SceneIdeas(canvas));
+ scenes.push_back(new SceneTerrain(canvas));
+ scenes.push_back(new SceneJellyfish(canvas));
+ scenes.push_back(new SceneShadow(canvas));
+ scenes.push_back(new SceneRefract(canvas));
+
+ for (vector<Scene*>::const_iterator iter = scenes.begin();
+ iter != scenes.end();
+ iter++)
+ {
+ Benchmark::register_scene(**iter);
+ }
+}
+
+static void
+list_scenes()
+{
+ const map<string, Scene *> &scenes = Benchmark::scenes();
+
+ for (map<string, Scene *>::const_iterator scene_iter = scenes.begin();
+ scene_iter != scenes.end();
+ scene_iter++)
+ {
+ Scene *scene = scene_iter->second;
+ if (scene->name().empty())
+ continue;
+ Log::info("[Scene] %s\n", scene->name().c_str());
+
+ const map<string, Scene::Option> &options = scene->options();
+
+ for (map<string, Scene::Option>::const_iterator opt_iter = options.begin();
+ opt_iter != options.end();
+ opt_iter++)
+ {
+ const Scene::Option &opt = opt_iter->second;
+ Log::info(" [Option] %s\n"
+ " Description : %s\n"
+ " Default Value: %s\n",
+ opt.name.c_str(),
+ opt.description.c_str(),
+ opt.default_value.c_str());
+
+ /* Display list of acceptable values (if defined) */
+ if (!opt.acceptable_values.empty()) {
+ Log::info(" Acceptable Values: ");
+ for (vector<string>::const_iterator val_iter = opt.acceptable_values.begin();
+ val_iter != opt.acceptable_values.end();
+ val_iter++)
+ {
+ std::string format_value(Log::continuation_prefix + "%s");
+ if (val_iter + 1 != opt.acceptable_values.end())
+ format_value += ",";
+ else
+ format_value += "\n";
+ Log::info(format_value.c_str(), val_iter->c_str());
+ }
+ }
+ }
+ }
+}
+
+void
+do_benchmark(Canvas &canvas)
+{
+ BenchmarkCollection benchmark_collection;
+ MainLoop *loop;
+
+ benchmark_collection.populate_from_options();
+
+ if (benchmark_collection.needs_decoration())
+ loop = new MainLoopDecoration(canvas, benchmark_collection.benchmarks());
+ else
+ loop = new MainLoop(canvas, benchmark_collection.benchmarks());
+
+ while (loop->step());
+
+ Log::info("=======================================================\n");
+ Log::info(" glmark2 Score: %u \n", loop->score());
+ Log::info("=======================================================\n");
+
+ delete loop;
+}
+
+void
+do_validation(Canvas &canvas)
+{
+ BenchmarkCollection benchmark_collection;
+
+ benchmark_collection.populate_from_options();
+
+ MainLoopValidation loop(canvas, benchmark_collection.benchmarks());
+
+ while (loop.step());
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ if (!Options::parse_args(argc, argv))
+ return 1;
+
+ /* Initialize Log class */
+ Log::init(Util::appname_from_path(argv[0]), Options::show_debug);
+
+ if (Options::show_help) {
+ Options::print_help();
+ return 0;
+ }
+
+ /* Force 800x600 output for validation */
+ if (Options::validate &&
+ Options::size != std::pair<int,int>(800, 600))
+ {
+ Log::info("Ignoring custom size %dx%d for validation. Using 800x600.\n",
+ Options::size.first, Options::size.second);
+ Options::size = std::pair<int,int>(800, 600);
+ }
+
+ // Create the canvas
+#if USE_DRM
+ CanvasDRM canvas(Options::size.first, Options::size.second);
+#elif USE_GL
+ CanvasX11GLX canvas(Options::size.first, Options::size.second);
+#elif USE_GLESv2
+ CanvasX11EGL canvas(Options::size.first, Options::size.second);
+#endif
+
+ canvas.offscreen(Options::offscreen);
+
+ canvas.visual_config(Options::visual_config);
+
+ vector<Scene*> scenes;
+
+ // Register the scenes, so they can be looked up by name
+ add_and_register_scenes(scenes, canvas);
+
+ if (Options::list_scenes) {
+ list_scenes();
+ return 0;
+ }
+
+ if (!canvas.init()) {
+ Log::error("%s: Could not initialize canvas\n", __FUNCTION__);
+ return 1;
+ }
+
+ Log::info("=======================================================\n");
+ Log::info(" glmark2 %s\n", GLMARK_VERSION);
+ Log::info("=======================================================\n");
+ canvas.print_info();
+ Log::info("=======================================================\n");
+
+ canvas.visible(true);
+
+ if (Options::validate)
+ do_validation(canvas);
+ else
+ do_benchmark(canvas);
+
+ Util::dispose_pointer_vector(scenes);
+
+ return 0;
+}
diff --git a/src/mesh.cpp b/src/mesh.cpp
new file mode 100644
index 0000000..9ccbcc6
--- /dev/null
+++ b/src/mesh.cpp
@@ -0,0 +1,639 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ */
+#include "mesh.h"
+#include "log.h"
+#include "gl-headers.h"
+
+
+Mesh::Mesh() :
+ vertex_size_(0), interleave_(false), vbo_update_method_(VBOUpdateMethodMap),
+ vbo_usage_(VBOUsageStatic)
+{
+}
+
+Mesh::~Mesh()
+{
+ reset();
+}
+
+/*
+ * Sets the vertex format for this mesh.
+ *
+ * The format consists of a vector of integers, each
+ * specifying the size in floats of each vertex attribute.
+ *
+ * e.g. {4, 3, 2} => 3 attributes vec4, vec3, vec2
+ */
+void
+Mesh::set_vertex_format(const std::vector<int> &format)
+{
+ int pos = 0;
+ vertex_format_.clear();
+
+ for (std::vector<int>::const_iterator iter = format.begin();
+ iter != format.end();
+ iter++)
+ {
+ int n = *iter;
+ vertex_format_.push_back(std::pair<int,int>(n, pos));
+
+ pos += n;
+ }
+
+ vertex_size_ = pos;
+}
+
+/*
+ * Sets the attribute locations.
+ *
+ * These are the locations used in glEnableVertexAttribArray()
+ * and other related functions.
+ */
+void
+Mesh::set_attrib_locations(const std::vector<int> &locations)
+{
+ if (locations.size() != vertex_format_.size())
+ Log::error("Trying to set attribute locations using wrong size\n");
+ attrib_locations_ = locations;
+}
+
+
+/**
+ * Checks that an attribute is of the correct dimensionality.
+ *
+ * @param pos the position/index of the attribute to check
+ * @param dim the size of the attribute (in #floats)
+ *
+ * @return whether the check succeeded
+ */
+bool
+Mesh::check_attrib(unsigned int pos, int dim)
+{
+ if (pos > vertex_format_.size()) {
+ Log::error("Trying to set non-existent attribute\n");
+ return false;
+ }
+
+ if (vertex_format_[pos].first != dim) {
+ Log::error("Trying to set attribute with value of invalid type\n");
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Ensures that we have a vertex to process.
+ *
+ * @return the vertex to process
+ */
+std::vector<float> &
+Mesh::ensure_vertex()
+{
+ if (vertices_.empty())
+ next_vertex();
+
+ return vertices_.back();
+}
+
+/*
+ * Sets the value of an attribute in the current vertex.
+ *
+ * The pos parameter refers to the position of the attribute
+ * as specified indirectly when setting the format using
+ * set_vertex_format(). e.g. 0 = first attribute, 1 = second
+ * etc
+ */
+void
+Mesh::set_attrib(unsigned int pos, const LibMatrix::vec2 &v, std::vector<float> *vertex)
+{
+ if (!check_attrib(pos, 2))
+ return;
+
+ std::vector<float> &vtx = !vertex ? ensure_vertex() : *vertex;
+
+ int offset = vertex_format_[pos].second;
+
+ vtx[offset] = v.x();
+ vtx[offset + 1] = v.y();
+}
+
+void
+Mesh::set_attrib(unsigned int pos, const LibMatrix::vec3 &v, std::vector<float> *vertex)
+{
+ if (!check_attrib(pos, 3))
+ return;
+
+ std::vector<float> &vtx = !vertex ? ensure_vertex() : *vertex;
+
+ int offset = vertex_format_[pos].second;
+
+ vtx[offset] = v.x();
+ vtx[offset + 1] = v.y();
+ vtx[offset + 2] = v.z();
+}
+
+void
+Mesh::set_attrib(unsigned int pos, const LibMatrix::vec4 &v, std::vector<float> *vertex)
+{
+ if (!check_attrib(pos, 4))
+ return;
+
+ std::vector<float> &vtx = !vertex ? ensure_vertex() : *vertex;
+
+ int offset = vertex_format_[pos].second;
+
+ vtx[offset] = v.x();
+ vtx[offset + 1] = v.y();
+ vtx[offset + 2] = v.z();
+ vtx[offset + 3] = v.w();
+}
+
+/*
+ * Adds a new vertex to the list and makes it current.
+ */
+void
+Mesh::next_vertex()
+{
+ vertices_.push_back(std::vector<float>(vertex_size_));
+}
+
+/**
+ * Gets the mesh vertices.
+ *
+ * You should use the ::set_attrib() method to manipulate
+ * the vertex data.
+ *
+ * You shouldn't resize the vector (change the number of vertices)
+ * manually. Use ::next_vertex() instead.
+ */
+std::vector<std::vector<float> >&
+Mesh::vertices()
+{
+ return vertices_;
+}
+
+/**
+ * Sets the VBO update method.
+ *
+ * The default value is VBOUpdateMethodMap.
+ */
+void
+Mesh::vbo_update_method(Mesh::VBOUpdateMethod method)
+{
+ vbo_update_method_ = method;
+}
+
+/**
+ * Sets the VBO usage hint.
+ *
+ * The usage hint takes effect in the next call to ::build_vbo().
+ *
+ * The default value is VBOUsageStatic.
+ */
+void
+Mesh::vbo_usage(Mesh::VBOUsage usage)
+{
+ vbo_usage_ = usage;
+}
+
+/**
+ * Sets the vertex attribute interleaving mode.
+ *
+ * If true the vertex attributes are going to be interleaved in a single
+ * buffer. Otherwise they will be separated into different buffers (one
+ * per attribute).
+ *
+ * Interleaving mode takes effect in the next call to ::build_array() or
+ * ::build_vbo().
+ *
+ * @param interleave whether to interleave
+ */
+void
+Mesh::interleave(bool interleave)
+{
+ interleave_ = interleave;
+}
+
+/**
+ * Resets a Mesh object to its initial, empty state.
+ */
+void
+Mesh::reset()
+{
+ delete_array();
+ delete_vbo();
+
+ vertices_.clear();
+ vertex_format_.clear();
+ attrib_locations_.clear();
+ attrib_data_ptr_.clear();
+ vertex_size_ = 0;
+ vertex_stride_ = 0;
+}
+
+/**
+ * Builds a vertex array containing the mesh vertex data.
+ *
+ * The way the vertex array is constructed is affected by the current
+ * interleave value, which can set using ::interleave().
+ */
+void
+Mesh::build_array()
+{
+ int nvertices = vertices_.size();
+
+ if (!interleave_) {
+ /* Create an array for each attribute */
+ for (std::vector<std::pair<int, int> >::const_iterator ai = vertex_format_.begin();
+ ai != vertex_format_.end();
+ ai++)
+ {
+ float *array = new float[nvertices * ai->first];
+ float *cur = array;
+
+ /* Fill in the array */
+ for (std::vector<std::vector<float> >::const_iterator vi = vertices_.begin();
+ vi != vertices_.end();
+ vi++)
+ {
+ for (int i = 0; i < ai->first; i++)
+ *cur++ = (*vi)[ai->second + i];
+ }
+
+ vertex_arrays_.push_back(array);
+ attrib_data_ptr_.push_back(array);
+ }
+ vertex_stride_ = 0;
+ }
+ else {
+ float *array = new float[nvertices * vertex_size_];
+ float *cur = array;
+
+ for (std::vector<std::vector<float> >::const_iterator vi = vertices_.begin();
+ vi != vertices_.end();
+ vi++)
+ {
+ /* Fill in the array */
+ for (int i = 0; i < vertex_size_; i++)
+ *cur++ = (*vi)[i];
+ }
+
+ for (size_t i = 0; i < vertex_format_.size(); i++)
+ attrib_data_ptr_.push_back(array + vertex_format_[i].second);
+
+ vertex_arrays_.push_back(array);
+ vertex_stride_ = vertex_size_ * sizeof(float);
+ }
+}
+
+/**
+ * Builds a vertex buffer object containing the mesh vertex data.
+ *
+ * The way the VBO is constructed is affected by the current interleave
+ * value (::interleave()) and the vbo usage hint (::vbo_usage()).
+ */
+void
+Mesh::build_vbo()
+{
+ delete_array();
+ build_array();
+
+ int nvertices = vertices_.size();
+
+ attrib_data_ptr_.clear();
+
+ GLenum buffer_usage;
+ if (vbo_usage_ == Mesh::VBOUsageStream)
+ buffer_usage = GL_STREAM_DRAW;
+ else if (vbo_usage_ == Mesh::VBOUsageDynamic)
+ buffer_usage = GL_DYNAMIC_DRAW;
+ else /* if (vbo_usage_ == Mesh::VBOUsageStatic) */
+ buffer_usage = GL_STATIC_DRAW;
+
+ if (!interleave_) {
+ /* Create a vbo for each attribute */
+ for (std::vector<std::pair<int, int> >::const_iterator ai = vertex_format_.begin();
+ ai != vertex_format_.end();
+ ai++)
+ {
+ float *data = vertex_arrays_[ai - vertex_format_.begin()];
+ GLuint vbo;
+
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, nvertices * ai->first * sizeof(float),
+ data, buffer_usage);
+
+ vbos_.push_back(vbo);
+ attrib_data_ptr_.push_back(0);
+ }
+
+ vertex_stride_ = 0;
+ }
+ else {
+ GLuint vbo;
+ /* Create a single vbo to store all attribute data */
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+
+ glBufferData(GL_ARRAY_BUFFER, nvertices * vertex_size_ * sizeof(float),
+ vertex_arrays_[0], GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ for (size_t i = 0; i < vertex_format_.size(); i++) {
+ attrib_data_ptr_.push_back(reinterpret_cast<float *>(sizeof(float) * vertex_format_[i].second));
+ vbos_.push_back(vbo);
+ }
+ vertex_stride_ = vertex_size_ * sizeof(float);
+ }
+
+ delete_array();
+}
+
+/**
+ * Updates ranges of a single vertex array.
+ *
+ * @param ranges the ranges of vertices to update
+ * @param n the index of the vertex array to update
+ * @param nfloats how many floats to update for each vertex
+ * @param offset the offset (in floats) in the vertex data to start reading from
+ */
+void
+Mesh::update_single_array(const std::vector<std::pair<size_t, size_t> >& ranges,
+ size_t n, size_t nfloats, size_t offset)
+{
+ float *array(vertex_arrays_[n]);
+
+ /* Update supplied ranges */
+ for (std::vector<std::pair<size_t, size_t> >::const_iterator ri = ranges.begin();
+ ri != ranges.end();
+ ri++)
+ {
+ /* Update the current range from the vertex data */
+ float *dest(array + nfloats * ri->first);
+ for (size_t n = ri->first; n <= ri->second; n++) {
+ for (size_t i = 0; i < nfloats; i++)
+ *dest++ = vertices_[n][offset + i];
+ }
+
+ }
+}
+
+/**
+ * Updates ranges of the vertex arrays.
+ *
+ * @param ranges the ranges of vertices to update
+ */
+void
+Mesh::update_array(const std::vector<std::pair<size_t, size_t> >& ranges)
+{
+ /* If we don't have arrays to update, create them */
+ if (vertex_arrays_.empty()) {
+ build_array();
+ return;
+ }
+
+ if (!interleave_) {
+ for (size_t i = 0; i < vertex_arrays_.size(); i++) {
+ update_single_array(ranges, i, vertex_format_[i].first,
+ vertex_format_[i].second);
+ }
+ }
+ else {
+ update_single_array(ranges, 0, vertex_size_, 0);
+ }
+
+}
+
+
+/**
+ * Updates ranges of a single VBO.
+ *
+ * This method use either glMapBuffer or glBufferSubData to perform
+ * the update. The used method can be set with ::vbo_update_method().
+ *
+ * @param ranges the ranges of vertices to update
+ * @param n the index of the vbo to update
+ * @param nfloats how many floats to update for each vertex
+ */
+void
+Mesh::update_single_vbo(const std::vector<std::pair<size_t, size_t> >& ranges,
+ size_t n, size_t nfloats)
+{
+ float *src_start(vertex_arrays_[n]);
+ float *dest_start(0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, vbos_[n]);
+
+ if (vbo_update_method_ == VBOUpdateMethodMap) {
+ dest_start = reinterpret_cast<float *>(
+ GLExtensions::MapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)
+ );
+ }
+
+ /* Update supplied ranges */
+ for (std::vector<std::pair<size_t, size_t> >::const_iterator iter = ranges.begin();
+ iter != ranges.end();
+ iter++)
+ {
+ float *src(src_start + nfloats * iter->first);
+ float *src_end(src_start + nfloats * (iter->second + 1));
+
+ if (vbo_update_method_ == VBOUpdateMethodMap) {
+ float *dest(dest_start + nfloats * iter->first);
+ std::copy(src, src_end, dest);
+ }
+ else if (vbo_update_method_ == VBOUpdateMethodSubData) {
+ glBufferSubData(GL_ARRAY_BUFFER, nfloats * iter->first * sizeof(float),
+ (src_end - src) * sizeof(float), src);
+ }
+ }
+
+ if (vbo_update_method_ == VBOUpdateMethodMap)
+ GLExtensions::UnmapBuffer(GL_ARRAY_BUFFER);
+}
+
+/**
+ * Updates ranges of the VBOs.
+ *
+ * @param ranges the ranges of vertices to update
+ */
+void
+Mesh::update_vbo(const std::vector<std::pair<size_t, size_t> >& ranges)
+{
+ /* If we don't have VBOs to update, create them */
+ if (vbos_.empty()) {
+ build_vbo();
+ return;
+ }
+
+ update_array(ranges);
+
+ if (!interleave_) {
+ for (size_t i = 0; i < vbos_.size(); i++)
+ update_single_vbo(ranges, i, vertex_format_[i].first);
+ }
+ else {
+ update_single_vbo(ranges, 0, vertex_size_);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+
+/**
+ * Deletes all resources associated with built vertex arrays.
+ */
+void
+Mesh::delete_array()
+{
+ for (size_t i = 0; i < vertex_arrays_.size(); i++) {
+ delete [] vertex_arrays_[i];
+ }
+
+ vertex_arrays_.clear();
+}
+
+/**
+ * Deletes all resources associated with built VBOs.
+ */
+void
+Mesh::delete_vbo()
+{
+ for (size_t i = 0; i < vbos_.size(); i++) {
+ GLuint vbo = vbos_[i];
+ glDeleteBuffers(1, &vbo);
+ }
+
+ vbos_.clear();
+}
+
+
+/**
+ * Renders a mesh using vertex arrays.
+ *
+ * The vertex arrays must have been previously initialized using
+ * ::build_array().
+ */
+void
+Mesh::render_array()
+{
+ for (size_t i = 0; i < vertex_format_.size(); i++) {
+ if (attrib_locations_[i] < 0)
+ continue;
+ glEnableVertexAttribArray(attrib_locations_[i]);
+ glVertexAttribPointer(attrib_locations_[i], vertex_format_[i].first,
+ GL_FLOAT, GL_FALSE, vertex_stride_,
+ attrib_data_ptr_[i]);
+ }
+
+ glDrawArrays(GL_TRIANGLES, 0, vertices_.size());
+
+ for (size_t i = 0; i < vertex_format_.size(); i++) {
+ if (attrib_locations_[i] < 0)
+ continue;
+ glDisableVertexAttribArray(attrib_locations_[i]);
+ }
+}
+
+/**
+ * Renders a mesh using vertex buffer objects.
+ *
+ * The vertex buffer objects must have been previously initialized using
+ * ::build_vbo().
+ */
+void
+Mesh::render_vbo()
+{
+ for (size_t i = 0; i < vertex_format_.size(); i++) {
+ if (attrib_locations_[i] < 0)
+ continue;
+ glEnableVertexAttribArray(attrib_locations_[i]);
+ glBindBuffer(GL_ARRAY_BUFFER, vbos_[i]);
+ glVertexAttribPointer(attrib_locations_[i], vertex_format_[i].first,
+ GL_FLOAT, GL_FALSE, vertex_stride_,
+ attrib_data_ptr_[i]);
+ }
+
+ glDrawArrays(GL_TRIANGLES, 0, vertices_.size());
+
+ for (size_t i = 0; i < vertex_format_.size(); i++) {
+ if (attrib_locations_[i] < 0)
+ continue;
+ glDisableVertexAttribArray(attrib_locations_[i]);
+ }
+}
+
+/**
+ * Creates a grid mesh.
+ *
+ * @param n_x the number of grid cells on the X axis
+ * @param n_y the number of grid cells on the Y axis
+ * @param width the width X of the grid (normalized)
+ * @param height the height Y of the grid (normalized)
+ * @param spacing the spacing between cells (normalized)
+ * @param conf_func a function to call to configure the grid (or NULL)
+ */
+void
+Mesh::make_grid(int n_x, int n_y, double width, double height,
+ double spacing, grid_configuration_func conf_func)
+{
+ double side_width = (width - (n_x - 1) * spacing) / n_x;
+ double side_height = (height - (n_y - 1) * spacing) / n_y;
+
+ for (int i = 0; i < n_x; i++) {
+ for (int j = 0; j < n_y; j++) {
+ LibMatrix::vec3 a(-width / 2 + i * (side_width + spacing),
+ height / 2 - j * (side_height + spacing), 0);
+ LibMatrix::vec3 b(a.x(), a.y() - side_height, 0);
+ LibMatrix::vec3 c(a.x() + side_width, a.y(), 0);
+ LibMatrix::vec3 d(a.x() + side_width, a.y() - side_height, 0);
+
+ if (!conf_func) {
+ std::vector<float> ul(vertex_size_);
+ std::vector<float> ur(vertex_size_);
+ std::vector<float> ll(vertex_size_);
+ std::vector<float> lr(vertex_size_);
+
+ set_attrib(0, a, &ul);
+ set_attrib(0, c, &ur);
+ set_attrib(0, b, &ll);
+ set_attrib(0, d, &lr);
+
+ next_vertex(); vertices_.back() = ul;
+ next_vertex(); vertices_.back() = ll;
+ next_vertex(); vertices_.back() = ur;
+ next_vertex(); vertices_.back() = ll;
+ next_vertex(); vertices_.back() = lr;
+ next_vertex(); vertices_.back() = ur;
+ }
+ else {
+ conf_func(*this, i, j, n_x, n_y, a, b, c, d);
+ }
+ }
+ }
+}
diff --git a/src/mesh.h b/src/mesh.h
new file mode 100644
index 0000000..99630f2
--- /dev/null
+++ b/src/mesh.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker (glmark2)
+ */
+#ifndef GLMARK2_MESH_H_
+#define GLMARK2_MESH_H_
+
+#include <vector>
+#include "vec.h"
+#include "gl-headers.h"
+
+/**
+ * A mesh of vertices.
+ */
+class Mesh
+{
+public:
+ Mesh();
+ ~Mesh();
+
+ void set_vertex_format(const std::vector<int> &format);
+ void set_attrib_locations(const std::vector<int> &locations);
+
+ void set_attrib(unsigned int pos, const LibMatrix::vec2 &v, std::vector<float> *vertex = 0);
+ void set_attrib(unsigned int pos, const LibMatrix::vec3 &v, std::vector<float> *vertex = 0);
+ void set_attrib(unsigned int pos, const LibMatrix::vec4 &v, std::vector<float> *vertex = 0);
+ void next_vertex();
+ std::vector<std::vector<float> >& vertices();
+
+ enum VBOUpdateMethod {
+ VBOUpdateMethodMap,
+ VBOUpdateMethodSubData,
+ };
+ enum VBOUsage {
+ VBOUsageStatic,
+ VBOUsageStream,
+ VBOUsageDynamic,
+ };
+
+ void vbo_update_method(VBOUpdateMethod method);
+ void vbo_usage(VBOUsage usage);
+ void interleave(bool interleave);
+
+ void reset();
+ void build_array();
+ void build_vbo();
+ void update_array(const std::vector<std::pair<size_t, size_t> >& ranges);
+ void update_vbo(const std::vector<std::pair<size_t, size_t> >& ranges);
+ void delete_array();
+ void delete_vbo();
+
+ void render_array();
+ void render_vbo();
+
+ typedef void (*grid_configuration_func)(Mesh &mesh, int x, int y, int n_x, int n_y,
+ LibMatrix::vec3 &ul,
+ LibMatrix::vec3 &ll,
+ LibMatrix::vec3 &ur,
+ LibMatrix::vec3 &lr);
+
+ void make_grid(int n_x, int n_y, double width, double height,
+ double spacing, grid_configuration_func conf_func = 0);
+
+private:
+ bool check_attrib(unsigned int pos, int dim);
+ std::vector<float> &ensure_vertex();
+ void update_single_array(const std::vector<std::pair<size_t, size_t> >& ranges,
+ size_t n, size_t nfloats, size_t offset);
+ void update_single_vbo(const std::vector<std::pair<size_t, size_t> >& ranges,
+ size_t n, size_t nfloats);
+
+ //
+ // vertex_format_ is a vector of pairs describing the attribute data.
+ // pair.first is the dimension of the attribute (vec2, vec3, vec4) and
+ // pair.second is the number of float values into the vertex data of that
+ // attribute. So, for example, if there are 3 attributes, a vec3 position
+ // a vec3 normal and a vec2 texture coordinate, you would have a
+ // vertex_format_ with 3 elements as follows: {<3, 0>, <3, 3>, <2, 6>} and
+ // the total size of each vertex would be the sum of the dimensions times
+ // the size of a float, or: 8 * sizeof(float) == 32 bytes
+ //
+ std::vector<std::pair<int, int> > vertex_format_;
+ std::vector<int> attrib_locations_;
+ int vertex_size_;
+
+ std::vector<std::vector<float> > vertices_;
+
+ std::vector<float *> vertex_arrays_;
+ std::vector<GLuint> vbos_;
+ std::vector<float *> attrib_data_ptr_;
+ int vertex_stride_;
+ bool interleave_;
+ VBOUpdateMethod vbo_update_method_;
+ VBOUsage vbo_usage_;
+};
+
+#endif
diff --git a/src/model.cpp b/src/model.cpp
new file mode 100644
index 0000000..720da67
--- /dev/null
+++ b/src/model.cpp
@@ -0,0 +1,807 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ */
+#include "mesh.h"
+#include "model.h"
+#include "vec.h"
+#include "log.h"
+#include "options.h"
+#include "util.h"
+#include "float.h"
+#include "math.h"
+#include <fstream>
+#include <sstream>
+#include <memory>
+
+using std::string;
+using std::vector;
+using LibMatrix::vec3;
+using LibMatrix::uvec3;
+
+#define read_or_fail(file, dst, size) do { \
+ file.read(reinterpret_cast<char *>((dst)), (size)); \
+ if (file.gcount() < (std::streamsize)(size)) { \
+ Log::error("%s: %d: Failed to read %zd bytes from 3ds file (read %zd)\n", \
+ __FUNCTION__, __LINE__, \
+ (size_t)(size), file.gcount()); \
+ return false; \
+ } \
+} while(0);
+
+/**
+ * Computes the bounding box for a Model::Object.
+ *
+ * @param object the Model object
+ */
+void
+Model::compute_bounding_box(const Object& object)
+{
+ float minX(FLT_MAX);
+ float maxX(FLT_MIN);
+ float minY(FLT_MAX);
+ float maxY(FLT_MIN);
+ float minZ(FLT_MAX);
+ float maxZ(FLT_MIN);
+ for (vector<Vertex>::const_iterator vIt = object.vertices.begin(); vIt != object.vertices.end(); vIt++)
+ {
+ const vec3& curVtx = vIt->v;
+ if (curVtx.x() < minX)
+ {
+ minX = curVtx.x();
+ }
+ if (curVtx.x() > maxX)
+ {
+ maxX = curVtx.x();
+ }
+ if (curVtx.y() < minY)
+ {
+ minY = curVtx.y();
+ }
+ if (curVtx.y() > maxY)
+ {
+ maxY = curVtx.y();
+ }
+ if (curVtx.z() < minZ)
+ {
+ minZ = curVtx.z();
+ }
+ if (curVtx.z() > maxZ)
+ {
+ maxZ = curVtx.z();
+ }
+ }
+ maxVec_ = vec3(maxX, maxY, maxZ);
+ minVec_ = vec3(minX, minY, minZ);
+}
+
+/**
+ * Appends the vertices of a Model::Object to a Mesh.
+ *
+ * @param object the object to append
+ * @param mesh the mesh to append to
+ * @param p_pos the attribute position to use for the 'position' attribute
+ * @param n_pos the attribute position to use for the 'normal' attribute
+ * @param t_pos the attribute position to use for the 'texcoord' attribute
+ */
+void
+Model::append_object_to_mesh(const Object &object, Mesh &mesh,
+ int p_pos, int n_pos, int t_pos,
+ int nt_pos, int nb_pos)
+{
+ size_t face_count = object.faces.size();
+
+ for(size_t i = 0; i < 3 * face_count; i += 3)
+ {
+ const Face &face = object.faces[i / 3];
+ const Vertex &a = object.vertices[face.a];
+ const Vertex &b = object.vertices[face.b];
+ const Vertex &c = object.vertices[face.c];
+
+ mesh.next_vertex();
+ if (p_pos >= 0)
+ mesh.set_attrib(p_pos, a.v);
+ if (n_pos >= 0)
+ mesh.set_attrib(n_pos, a.n);
+ if (t_pos >= 0)
+ mesh.set_attrib(t_pos, a.t);
+ if (nt_pos >= 0)
+ mesh.set_attrib(nt_pos, a.nt);
+ if (nb_pos >= 0)
+ mesh.set_attrib(nb_pos, a.nb);
+
+ mesh.next_vertex();
+ if (p_pos >= 0)
+ mesh.set_attrib(p_pos, b.v);
+ if (n_pos >= 0)
+ mesh.set_attrib(n_pos, b.n);
+ if (t_pos >= 0)
+ mesh.set_attrib(t_pos, b.t);
+ if (nt_pos >= 0)
+ mesh.set_attrib(nt_pos, b.nt);
+ if (nb_pos >= 0)
+ mesh.set_attrib(nb_pos, b.nb);
+
+ mesh.next_vertex();
+ if (p_pos >= 0)
+ mesh.set_attrib(p_pos, c.v);
+ if (n_pos >= 0)
+ mesh.set_attrib(n_pos, c.n);
+ if (t_pos >= 0)
+ mesh.set_attrib(t_pos, c.t);
+ if (nt_pos >= 0)
+ mesh.set_attrib(nt_pos, c.nt);
+ if (nb_pos >= 0)
+ mesh.set_attrib(nb_pos, c.nb);
+ }
+}
+
+/**
+ * Converts a model to a mesh using the default attributes bindings.
+ *
+ * The default attributes and their order is: Position, Normal, Texcoord
+ *
+ * @param mesh the mesh to populate
+ */
+void
+Model::convert_to_mesh(Mesh &mesh)
+{
+ std::vector<std::pair<AttribType, int> > attribs;
+
+ attribs.push_back(std::pair<AttribType, int>(AttribTypePosition, 3));
+ attribs.push_back(std::pair<AttribType, int>(AttribTypeNormal, 3));
+ attribs.push_back(std::pair<AttribType, int>(AttribTypeTexcoord, 2));
+
+ convert_to_mesh(mesh, attribs);
+}
+
+/**
+ * Converts a model to a mesh using custom attribute bindings.
+ *
+ * The attribute bindings are pairs of <AttribType, dimensionality>.
+ *
+ * @param mesh the mesh to populate
+ * @param attribs the attribute bindings to use
+ */
+void
+Model::convert_to_mesh(Mesh &mesh,
+ const std::vector<std::pair<AttribType, int> > &attribs)
+{
+ std::vector<int> format;
+ int p_pos = -1;
+ int n_pos = -1;
+ int t_pos = -1;
+ int nt_pos = -1;
+ int nb_pos = -1;
+
+ mesh.reset();
+
+ for (std::vector<std::pair<AttribType, int> >::const_iterator ai = attribs.begin();
+ ai != attribs.end();
+ ai++)
+ {
+ format.push_back(ai->second);
+ if (ai->first == AttribTypePosition)
+ p_pos = ai - attribs.begin();
+ else if (ai->first == AttribTypeNormal)
+ n_pos = ai - attribs.begin();
+ else if (ai->first == AttribTypeTexcoord)
+ t_pos = ai - attribs.begin();
+ else if (ai->first == AttribTypeTangent)
+ nt_pos = ai - attribs.begin();
+ else if (ai->first == AttribTypeBitangent)
+ nb_pos = ai - attribs.begin();
+ }
+
+ mesh.set_vertex_format(format);
+
+ for (std::vector<Object>::const_iterator iter = objects_.begin();
+ iter != objects_.end();
+ iter++)
+ {
+ append_object_to_mesh(*iter, mesh, p_pos, n_pos, t_pos, nt_pos, nb_pos);
+ }
+}
+
+void
+Model::calculate_texcoords()
+{
+ // Since the model didn't come with texcoords, and we don't actually know
+ // if it came with normals, either, we'll use positional spherical mapping
+ // to generate texcoords for the model. See:
+ // http://www.mvps.org/directx/articles/spheremap.htm for more details.
+ vec3 centerVec = maxVec_ + minVec_;
+ centerVec *= 0.5;
+
+ for (std::vector<Object>::iterator iter = objects_.begin();
+ iter != objects_.end();
+ iter++)
+ {
+ Object &object = *iter;
+ for (vector<Vertex>::iterator vertexIt = object.vertices.begin();
+ vertexIt != object.vertices.end();
+ vertexIt++)
+ {
+ Vertex& curVertex = *vertexIt;
+ vec3 vnorm(curVertex.v - centerVec);
+ vnorm.normalize();
+ curVertex.t.x(asinf(vnorm.x()) / M_PI + 0.5);
+ curVertex.t.y(asinf(vnorm.y()) / M_PI + 0.5);
+ }
+ }
+}
+
+/**
+ * Calculates the normal vectors of the model vertices.
+ */
+void
+Model::calculate_normals()
+{
+ LibMatrix::vec3 n;
+
+ for (std::vector<Object>::iterator iter = objects_.begin();
+ iter != objects_.end();
+ iter++)
+ {
+ Object &object = *iter;
+
+ for (vector<Face>::const_iterator f_iter = object.faces.begin();
+ f_iter != object.faces.end();
+ f_iter++)
+ {
+ const Face &face = *f_iter;
+ Vertex &a = object.vertices[face.a];
+ Vertex &b = object.vertices[face.b];
+ Vertex &c = object.vertices[face.c];
+
+ /* Calculate normal */
+ n = LibMatrix::vec3::cross(b.v - a.v, c.v - a.v);
+ n.normalize();
+ a.n += n;
+ b.n += n;
+ c.n += n;
+
+ LibMatrix::vec3 q1(b.v - a.v);
+ LibMatrix::vec3 q2(c.v - a.v);
+ LibMatrix::vec2 u1(b.t - a.t);
+ LibMatrix::vec2 u2(c.t - a.t);
+ float det = (u1.x() * u2.y() - u2.x() * u1.y());
+
+ /* Calculate tangent */
+ LibMatrix::vec3 nt;
+ nt.x(det * (u2.y() * q1.x() - u1.y() * q2.x()));
+ nt.y(det * (u2.y() * q1.y() - u1.y() * q2.y()));
+ nt.z(det * (u2.y() * q1.z() - u1.y() * q2.z()));
+ nt.normalize();
+ a.nt += nt;
+ b.nt += nt;
+ c.nt += nt;
+
+ /* Calculate bitangent */
+ LibMatrix::vec3 nb;
+ nb.x(det * (u1.x() * q2.x() - u2.x() * q1.x()));
+ nb.y(det * (u1.x() * q2.y() - u2.x() * q1.y()));
+ nb.z(det * (u1.x() * q2.z() - u2.x() * q1.z()));
+ nb.normalize();
+ a.nb += nb;
+ b.nb += nb;
+ c.nb += nb;
+ }
+
+ for (vector<Vertex>::iterator v_iter = object.vertices.begin();
+ v_iter != object.vertices.end();
+ v_iter++)
+ {
+ Vertex &v = *v_iter;
+ /* Orthogonalize */
+ v.nt = (v.nt - v.n * LibMatrix::vec3::dot(v.nt, v.n));
+ v.n.normalize();
+ v.nt.normalize();
+ v.nb.normalize();
+ }
+
+ }
+}
+
+/**
+ * Load a model from a 3DS file.
+ *
+ * @param filename the name of the file
+ *
+ * @return whether loading succeeded
+ */
+bool
+Model::load_3ds(const std::string &filename)
+{
+ Object *object(0);
+
+ Log::debug("Loading model from 3ds file '%s'\n", filename.c_str());
+
+ const std::auto_ptr<std::istream> input_file_ptr(Util::get_resource(filename));
+ std::istream& input_file(*input_file_ptr);
+
+ if (!input_file) {
+ Log::error("Could not open 3ds file '%s'\n", filename.c_str());
+ return false;
+ }
+
+ // Loop to scan the whole file
+ while (!input_file.eof()) {
+ uint16_t chunk_id;
+ uint32_t chunk_length;
+
+ // Read the chunk header
+ input_file.read(reinterpret_cast<char *>(&chunk_id), 2);
+ if (input_file.gcount() == 0) {
+ continue;
+ }
+ else if (input_file.gcount() < 2) {
+ Log::error("%s: %d: Failed to read %zd bytes from 3ds file (read %zd)\n",
+ __FUNCTION__, __LINE__, 2, input_file.gcount());
+ return false;
+ }
+
+ //Read the lenght of the chunk
+ read_or_fail(input_file, &chunk_length, 4);
+
+ switch (chunk_id)
+ {
+ //----------------- MAIN3DS -----------------
+ // Description: Main chunk, contains all the other chunks
+ // Chunk ID: 4d4d
+ // Chunk Lenght: 0 + sub chunks
+ //-------------------------------------------
+ case 0x4d4d:
+ break;
+
+ //----------------- EDIT3DS -----------------
+ // Description: 3D Editor chunk, objects layout info
+ // Chunk ID: 3d3d (hex)
+ // Chunk Lenght: 0 + sub chunks
+ //-------------------------------------------
+ case 0x3d3d:
+ break;
+
+ //--------------- EDIT_OBJECT ---------------
+ // Description: Object block, info for each object
+ // Chunk ID: 4000 (hex)
+ // Chunk Lenght: len(object name) + sub chunks
+ //-------------------------------------------
+ case 0x4000:
+ {
+ std::stringstream ss;
+ unsigned char c = 1;
+
+ for (int i = 0; i < 20 && c != '\0'; i++) {
+ read_or_fail(input_file, &c, 1);
+ ss << c;
+ }
+
+ objects_.push_back(Object(ss.str()));
+ object = &objects_.back();
+ }
+ break;
+
+ //--------------- OBJ_TRIMESH ---------------
+ // Description: Triangular mesh, contains chunks for 3d mesh info
+ // Chunk ID: 4100 (hex)
+ // Chunk Lenght: 0 + sub chunks
+ //-------------------------------------------
+ case 0x4100:
+ break;
+
+ //--------------- TRI_VERTEXL ---------------
+ // Description: Vertices list
+ // Chunk ID: 4110 (hex)
+ // Chunk Lenght: 1 x unsigned short (number of vertices)
+ // + 3 x float (vertex coordinates) x (number of vertices)
+ // + sub chunks
+ //-------------------------------------------
+ case 0x4110:
+ {
+ uint16_t qty;
+ read_or_fail(input_file, &qty, sizeof(uint16_t));
+ object->vertices.resize(qty);
+
+ for (uint16_t i = 0; i < qty; i++) {
+ float f[3];
+ read_or_fail(input_file, f, sizeof(float) * 3);
+ object->vertices[i].v.x(f[0]);
+ object->vertices[i].v.y(f[1]);
+ object->vertices[i].v.z(f[2]);
+ }
+ }
+ break;
+
+ //--------------- TRI_FACEL1 ----------------
+ // Description: Polygons (faces) list
+ // Chunk ID: 4120 (hex)
+ // Chunk Lenght: 1 x unsigned short (number of polygons)
+ // + 3 x unsigned short (polygon points) x (number of polygons)
+ // + sub chunks
+ //-------------------------------------------
+ case 0x4120:
+ {
+ uint16_t qty;
+ read_or_fail(input_file, &qty, sizeof(uint16_t));
+ object->faces.resize(qty);
+ for (uint16_t i = 0; i < qty; i++) {
+ read_or_fail(input_file, &object->faces[i].a, sizeof(uint16_t));
+ read_or_fail(input_file, &object->faces[i].b, sizeof(uint16_t));
+ read_or_fail(input_file, &object->faces[i].c, sizeof(uint16_t));
+ read_or_fail(input_file, &object->faces[i].face_flags, sizeof(uint16_t));
+ }
+ }
+ break;
+
+ //------------- TRI_MAPPINGCOORS ------------
+ // Description: Vertices list
+ // Chunk ID: 4140 (hex)
+ // Chunk Lenght: 1 x unsigned short (number of mapping points)
+ // + 2 x float (mapping coordinates) x (number of mapping points)
+ // + sub chunks
+ //-------------------------------------------
+ case 0x4140:
+ {
+ uint16_t qty;
+ read_or_fail(input_file, &qty, sizeof(uint16_t));
+ for (uint16_t i = 0; i < qty; i++) {
+ float f[2];
+ read_or_fail(input_file, f, sizeof(float) * 2);
+ object->vertices[i].t.x(f[0]);
+ object->vertices[i].t.y(f[1]);
+ }
+ }
+ gotTexcoords_ = true;
+ break;
+
+ //----------- Skip unknow chunks ------------
+ //We need to skip all the chunks that currently we don't use
+ //We use the chunk lenght information to set the file pointer
+ //to the same level next chunk
+ //-------------------------------------------
+ default:
+ input_file.seekg(chunk_length - 6, std::ios::cur);
+ }
+ }
+
+ // Compute bounding box for perspective projection
+ compute_bounding_box(*object);
+
+ if (Options::show_debug) {
+ for (std::vector<Object>::const_iterator iter = objects_.begin();
+ iter != objects_.end();
+ iter++)
+ {
+ Log::debug(" Object name: %s Vertex count: %d Face count: %d\n",
+ iter->name.c_str(), iter->vertices.size(), iter->faces.size());
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Parse vec3 values from an OBJ file.
+ *
+ * @param source the source line to parse
+ * @param v the vec3 to populate
+ */
+static void
+obj_get_values(const string& source, vec3& v)
+{
+ // Skip the definition type...
+ string::size_type endPos = source.find(" ");
+ string::size_type startPos(0);
+ if (endPos == string::npos)
+ {
+ Log::error("Bad element '%s'\n", source.c_str());
+ return;
+ }
+ // Find the first value...
+ startPos = endPos + 1;
+ endPos = source.find(" ", startPos);
+ if (endPos == string::npos)
+ {
+ Log::error("Bad element '%s'\n", source.c_str());
+ return;
+ }
+ string::size_type numChars(endPos - startPos);
+ string xs(source, startPos, numChars);
+ float x = Util::fromString<float>(xs);
+ // Then the second value...
+ startPos = endPos + 1;
+ endPos = source.find(" ", startPos);
+ if (endPos == string::npos)
+ {
+ Log::error("Bad element '%s'\n", source.c_str());
+ return;
+ }
+ numChars = endPos - startPos;
+ string ys(source, startPos, numChars);
+ float y = Util::fromString<float>(ys);
+ // And the third value (there might be a fourth, but we don't care)...
+ startPos = endPos + 1;
+ endPos = source.find(" ", startPos);
+ if (endPos == string::npos)
+ {
+ numChars = endPos;
+ }
+ else
+ {
+ numChars = endPos - startPos;
+ }
+ string zs(source, startPos, endPos - startPos);
+ float z = Util::fromString<float>(zs);
+ v.x(x);
+ v.y(y);
+ v.z(z);
+}
+
+/**
+ * Parse uvec3 values from an OBJ file.
+ *
+ * @param source the source line to parse
+ * @param v the uvec3 to populate
+ */
+static void
+obj_get_values(const string& source, uvec3& v)
+{
+ // Skip the definition type...
+ string::size_type endPos = source.find(" ");
+ string::size_type startPos(0);
+ if (endPos == string::npos)
+ {
+ Log::error("Bad element '%s'\n", source.c_str());
+ return;
+ }
+ // Find the first value...
+ startPos = endPos + 1;
+ endPos = source.find(" ", startPos);
+ if (endPos == string::npos)
+ {
+ Log::error("Bad element '%s'\n", source.c_str());
+ return;
+ }
+ string::size_type numChars(endPos - startPos);
+ string xs(source, startPos, numChars);
+ unsigned int x = Util::fromString<unsigned int>(xs);
+ // Then the second value...
+ startPos = endPos+1;
+ endPos = source.find(" ", startPos);
+ if (endPos == string::npos)
+ {
+ Log::error("Bad element '%s'\n", source.c_str());
+ return;
+ }
+ numChars = endPos - startPos;
+ string ys(source, startPos, numChars);
+ unsigned int y = Util::fromString<unsigned int>(ys);
+ // And the third value (there might be a fourth, but we don't care)...
+ startPos = endPos + 1;
+ endPos = source.find(" ", startPos);
+ if (endPos == string::npos)
+ {
+ numChars = endPos;
+ }
+ else
+ {
+ numChars = endPos - startPos;
+ }
+ string zs(source, startPos, numChars);
+ unsigned int z = Util::fromString<unsigned int>(zs);
+ v.x(x);
+ v.y(y);
+ v.z(z);
+}
+
+/**
+ * Load a model from an OBJ file.
+ *
+ * @param filename the name of the file
+ *
+ * @return whether loading succeeded
+ */
+bool
+Model::load_obj(const std::string &filename)
+{
+ Log::debug("Loading model from obj file '%s'\n", filename.c_str());
+
+ const std::auto_ptr<std::istream> input_file_ptr(Util::get_resource(filename));
+ std::istream& inputFile(*input_file_ptr);
+ if (!inputFile)
+ {
+ Log::error("Failed to open '%s'\n", filename.c_str());
+ return false;
+ }
+
+ vector<string> sourceVec;
+ string curLine;
+ while (getline(inputFile, curLine))
+ {
+ sourceVec.push_back(curLine);
+ }
+
+ // Give ourselves an object to populate.
+ objects_.push_back(Object(filename));
+ Object& object(objects_.back());
+
+ static const string vertex_definition("v");
+ static const string normal_definition("vn");
+ static const string texcoord_definition("vt");
+ static const string face_definition("f");
+ for (vector<string>::const_iterator lineIt = sourceVec.begin();
+ lineIt != sourceVec.end();
+ lineIt++)
+ {
+ const string& curSrc = *lineIt;
+ // Is it a vertex attribute, a face description, comment or other?
+ // We only care about the first two, we ignore comments, object names,
+ // group names, smoothing groups, etc.
+ string::size_type startPos(0);
+ string::size_type spacePos = curSrc.find(" ", startPos);
+ string definitionType(curSrc, startPos, spacePos - startPos);
+ if (definitionType == vertex_definition)
+ {
+ Vertex v;
+ obj_get_values(curSrc, v.v);
+ object.vertices.push_back(v);
+ }
+ else if (definitionType == normal_definition)
+ {
+ // If we encounter an OBJ model with normals, we can update this
+ // to update object.vertices.n directly
+ Log::debug("We got a normal...\n");
+ }
+ else if (definitionType == texcoord_definition)
+ {
+ // If we encounter an OBJ model with normals, we can update this
+ // to update object.vertices.t directly
+ Log::debug("We got a texcoord...\n");
+ }
+ else if (definitionType == face_definition)
+ {
+ uvec3 v;
+ obj_get_values(curSrc, v);
+ Face f;
+ // OBJ models index from '1'.
+ f.a = v.x() - 1;
+ f.b = v.y() - 1;
+ f.c = v.z() - 1;
+ object.faces.push_back(f);
+ }
+ }
+ // Compute bounding box for perspective projection
+ compute_bounding_box(object);
+
+ Log::debug("Object populated with %u vertices and %u faces.\n",
+ object.vertices.size(), object.faces.size());
+ return true;
+}
+
+namespace ModelPrivate
+{
+ModelMap modelMap;
+}
+
+/**
+ * Locate all available models.
+ *
+ * This method scans the built-in data paths and build a database of usable
+ * models available to scenes. Map is available on a read-only basis to scenes
+ * that might find it useful for listing models, etc.
+ *
+ * @return a map containing information about the located models
+ */
+const ModelMap&
+Model::find_models()
+{
+ if (!ModelPrivate::modelMap.empty())
+ {
+ return ModelPrivate::modelMap;
+ }
+ vector<string> pathVec;
+ string dataDir(GLMARK_DATA_PATH"/models");
+ Util::list_files(dataDir, pathVec);
+#ifdef GLMARK_EXTRAS_PATH
+ string extrasDir(GLMARK_EXTRAS_PATH"/models");
+ Util::list_files(extrasDir, pathVec);
+#endif
+
+ // Now that we have a list of all of the model files available to us,
+ // let's go through and pull out the names and what format they're in
+ // so the scene can decide which ones to use.
+ for(vector<string>::const_iterator pathIt = pathVec.begin();
+ pathIt != pathVec.end();
+ pathIt++)
+ {
+ const string& curPath = *pathIt;
+ string::size_type namePos(0);
+ string::size_type slashPos = curPath.rfind("/");
+ if (slashPos != string::npos)
+ {
+ // Advance to the first character after the last slash
+ namePos = slashPos + 1;
+ }
+
+ ModelFormat format(MODEL_INVALID);
+ string::size_type extPos = curPath.rfind(".3ds");
+ if (extPos == string::npos)
+ {
+ // It's not a 3ds model
+ extPos = curPath.rfind(".obj");
+ if (extPos == string::npos)
+ {
+ // It's not an obj model either, so skip it.
+ continue;
+ }
+ format = MODEL_OBJ;
+ }
+ else
+ {
+ // It's a 3ds model
+ format = MODEL_3DS;
+ }
+
+ string name(curPath, namePos, extPos - namePos);
+ ModelDescriptor* desc = new ModelDescriptor(name, format, curPath);
+ ModelPrivate::modelMap.insert(std::make_pair(name, desc));
+ }
+
+ return ModelPrivate::modelMap;
+}
+
+/**
+ * Load a model by name.
+ *
+ * You must initialize the available model collection using
+ * Model::find_models() before using this method.
+ *
+ * @param modelName the model name
+ *
+ * @return whether the operation succeeded
+ */
+bool
+Model::load(const string& modelName)
+{
+ bool retVal(false);
+ ModelMap::const_iterator modelIt = ModelPrivate::modelMap.find(modelName);
+ if (modelIt == ModelPrivate::modelMap.end())
+ {
+ return retVal;
+ }
+
+ ModelDescriptor* desc = modelIt->second;
+ switch (desc->format())
+ {
+ case MODEL_INVALID:
+ break;
+ case MODEL_3DS:
+ retVal = load_3ds(desc->pathname());
+ break;
+ case MODEL_OBJ:
+ retVal = load_obj(desc->pathname());
+ break;
+ }
+
+ return retVal;
+}
diff --git a/src/model.h b/src/model.h
new file mode 100644
index 0000000..0d7d4b9
--- /dev/null
+++ b/src/model.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ */
+#ifndef GLMARK2_MODEL_H_
+#define GLMARK2_MODEL_H_
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <map>
+#include "vec.h"
+
+// Forward declare the mesh object. We don't need the whole header here.
+class Mesh;
+
+enum ModelFormat
+{
+ MODEL_INVALID,
+ MODEL_3DS,
+ MODEL_OBJ
+};
+
+/**
+ * A descriptor for a model file.
+ */
+class ModelDescriptor
+{
+ std::string name_;
+ std::string pathname_;
+ ModelFormat format_;
+ ModelDescriptor();
+public:
+ ModelDescriptor(const std::string& name, ModelFormat format,
+ const std::string& pathname) :
+ name_(name),
+ pathname_(pathname),
+ format_(format) {}
+ ~ModelDescriptor() {}
+ const std::string& pathname() const { return pathname_; }
+ ModelFormat format() const { return format_; }
+};
+
+typedef std::map<std::string, ModelDescriptor*> ModelMap;
+
+/**
+ * A model as loaded from a 3D object data file.
+ */
+class Model
+{
+public:
+
+ typedef enum {
+ AttribTypePosition = 1,
+ AttribTypeNormal,
+ AttribTypeTexcoord,
+ AttribTypeTangent,
+ AttribTypeBitangent,
+ AttribTypeCustom
+ } AttribType;
+
+ Model() : gotTexcoords_(false) {}
+ ~Model() {}
+
+ bool load(const std::string& name);
+
+ bool needTexcoords() const { return !gotTexcoords_; }
+ void calculate_texcoords();
+ void calculate_normals();
+ void convert_to_mesh(Mesh &mesh);
+ void convert_to_mesh(Mesh &mesh,
+ const std::vector<std::pair<AttribType, int> > &attribs);
+ const LibMatrix::vec3& minVec() const { return minVec_; }
+ const LibMatrix::vec3& maxVec() const { return maxVec_; }
+ static const ModelMap& find_models();
+private:
+ // If the model we loaded contained texcoord data...
+ bool gotTexcoords_;
+ struct Face {
+ uint32_t a, b, c;
+ uint16_t face_flags;
+ };
+
+ struct Vertex {
+ LibMatrix::vec3 v;
+ LibMatrix::vec3 n;
+ LibMatrix::vec2 t;
+ LibMatrix::vec3 nt;
+ LibMatrix::vec3 nb;
+ };
+
+ struct Object {
+ Object(const std::string &name) : name(name) {}
+ std::string name;
+ std::vector<Vertex> vertices;
+ std::vector<Face> faces;
+ };
+
+ void append_object_to_mesh(const Object &object, Mesh &mesh,
+ int p_pos, int n_pos, int t_pos,
+ int nt_pos, int nb_pos);
+ bool load_3ds(const std::string &filename);
+ bool load_obj(const std::string &filename);
+
+ // For vertices of the bounding box for this model.
+ void compute_bounding_box(const Object& object);
+ LibMatrix::vec3 minVec_;
+ LibMatrix::vec3 maxVec_;
+ std::vector<Object> objects_;
+};
+
+#endif
diff --git a/src/options.cpp b/src/options.cpp
new file mode 100644
index 0000000..2ff1540
--- /dev/null
+++ b/src/options.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright © 2011-2012 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * glcompbench 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 glcompbench. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ * Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#include <cstring>
+#include <cstdlib>
+#include <cstdio>
+#include <getopt.h>
+#include <sstream>
+
+#include "options.h"
+#include "util.h"
+
+std::vector<std::string> Options::benchmarks;
+std::vector<std::string> Options::benchmark_files;
+bool Options::validate = false;
+Options::FrameEnd Options::frame_end = Options::FrameEndDefault;
+std::pair<int,int> Options::size(800, 600);
+bool Options::list_scenes = false;
+bool Options::show_all_options = false;
+bool Options::show_debug = false;
+bool Options::show_help = false;
+bool Options::reuse_context = false;
+bool Options::run_forever = false;
+bool Options::annotate = false;
+bool Options::offscreen = false;
+GLVisualConfig Options::visual_config;
+
+static struct option long_options[] = {
+ {"annotate", 0, 0, 0},
+ {"benchmark", 1, 0, 0},
+ {"benchmark-file", 1, 0, 0},
+ {"validate", 0, 0, 0},
+ {"frame-end", 1, 0, 0},
+ {"off-screen", 0, 0, 0},
+ {"visual-config", 1, 0, 0},
+ {"reuse-context", 0, 0, 0},
+ {"run-forever", 0, 0, 0},
+ {"size", 1, 0, 0},
+ {"fullscreen", 0, 0, 0},
+ {"list-scenes", 0, 0, 0},
+ {"show-all-options", 0, 0, 0},
+ {"debug", 0, 0, 0},
+ {"help", 0, 0, 0},
+ {0, 0, 0, 0}
+};
+
+/**
+ * Parses a size string of the form WxH
+ *
+ * @param str the string to parse
+ * @param size the parsed size (width, height)
+ */
+static void
+parse_size(const std::string &str, std::pair<int,int> &size)
+{
+ std::vector<std::string> d;
+ Util::split(str, 'x', d, Util::SplitModeNormal);
+
+ size.first = Util::fromString<int>(d[0]);
+
+ /*
+ * Parse the second element (height). If there is none, use the value
+ * of the first element for the second (width = height)
+ */
+ if (d.size() > 1)
+ size.second = Util::fromString<int>(d[1]);
+ else
+ size.second = size.first;
+}
+
+/**
+ * Parses a frame-end method string
+ *
+ * @param str the string to parse
+ *
+ * @return the parsed frame end method
+ */
+static Options::FrameEnd
+frame_end_from_str(const std::string &str)
+{
+ Options::FrameEnd m = Options::FrameEndDefault;
+
+ if (str == "swap")
+ m = Options::FrameEndSwap;
+ else if (str == "finish")
+ m = Options::FrameEndFinish;
+ else if (str == "readpixels")
+ m = Options::FrameEndReadPixels;
+ else if (str == "none")
+ m = Options::FrameEndNone;
+
+ return m;
+}
+
+void
+Options::print_help()
+{
+ printf("A benchmark for Open GL (ES) 2.0\n"
+ "\n"
+ "Options:\n"
+ " -b, --benchmark BENCH A benchmark to run: 'scene(:opt1=val1)*'\n"
+ " (the option can be used multiple times)\n"
+ " -f, --benchmark-file F Load benchmarks to run from a file containing a\n"
+ " list of benchmark descriptions (one per line)\n"
+ " (the option can be used multiple times)\n"
+ " --validate Run a quick output validation test instead of \n"
+ " running the benchmarks\n"
+ " --frame-end METHOD How to end a frame [default,none,swap,finish,readpixels]\n"
+ " --off-screen Render to an off-screen surface\n"
+ " --visual-config C The visual configuration to use for the rendering\n"
+ " target: 'red=R:green=G:blue=B:alpha=A:buffer=BUF'.\n"
+ " The parameters may be defined in any order, and any\n"
+ " omitted parameters assume a default value of '1'\n"
+ " --reuse-context Use a single context for all scenes\n"
+ " (by default, each scene gets its own context)\n"
+ " -s, --size WxH Size of the output window (default: 800x600)\n"
+ " --fullscreen Run in fullscreen mode (equivalent to --size -1x-1)\n"
+ " -l, --list-scenes Display information about the available scenes\n"
+ " and their options\n"
+ " --show-all-options Show all scene option values used for benchmarks\n"
+ " (only explicitly set options are shown by default)\n"
+ " --run-forever Run indefinitely, looping from the last benchmark\n"
+ " back to the first\n"
+ " --annotate Annotate the benchmarks with on-screen information\n"
+ " (same as -b :show-fps=true:title=#info#)\n"
+ " -d, --debug Display debug messages\n"
+ " -h, --help Display help\n");
+}
+
+bool
+Options::parse_args(int argc, char **argv)
+{
+ while (1) {
+ int option_index = -1;
+ int c;
+ const char *optname = "";
+
+ c = getopt_long(argc, argv, "b:f:s:ldh",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+ if (c == ':' || c == '?')
+ return false;
+
+ if (option_index != -1)
+ optname = long_options[option_index].name;
+
+ if (!strcmp(optname, "annotate"))
+ Options::annotate = true;
+ if (c == 'b' || !strcmp(optname, "benchmark"))
+ Options::benchmarks.push_back(optarg);
+ else if (c == 'f' || !strcmp(optname, "benchmark-file"))
+ Options::benchmark_files.push_back(optarg);
+ else if (!strcmp(optname, "validate"))
+ Options::validate = true;
+ else if (!strcmp(optname, "frame-end"))
+ Options::frame_end = frame_end_from_str(optarg);
+ else if (!strcmp(optname, "off-screen"))
+ Options::offscreen = true;
+ else if (!strcmp(optname, "visual-config"))
+ Options::visual_config = GLVisualConfig(optarg);
+ else if (!strcmp(optname, "reuse-context"))
+ Options::reuse_context = true;
+ else if (c == 's' || !strcmp(optname, "size"))
+ parse_size(optarg, Options::size);
+ else if (!strcmp(optname, "fullscreen"))
+ Options::size = std::pair<int,int>(-1, -1);
+ else if (c == 'l' || !strcmp(optname, "list-scenes"))
+ Options::list_scenes = true;
+ else if (!strcmp(optname, "show-all-options"))
+ Options::show_all_options = true;
+ else if (!strcmp(optname, "run-forever"))
+ Options::run_forever = true;
+ else if (c == 'd' || !strcmp(optname, "debug"))
+ Options::show_debug = true;
+ else if (c == 'h' || !strcmp(optname, "help"))
+ Options::show_help = true;
+ }
+
+ return true;
+}
diff --git a/src/options.h b/src/options.h
new file mode 100644
index 0000000..f62e02a
--- /dev/null
+++ b/src/options.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * glcompbench 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 glcompbench. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ * Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#ifndef OPTIONS_H_
+#define OPTIONS_H_
+
+#include <string>
+#include <vector>
+#include "gl-visual-config.h"
+
+struct Options {
+ enum FrameEnd {
+ FrameEndDefault,
+ FrameEndNone,
+ FrameEndSwap,
+ FrameEndFinish,
+ FrameEndReadPixels
+ };
+
+ static bool parse_args(int argc, char **argv);
+ static void print_help();
+
+ static std::vector<std::string> benchmarks;
+ static std::vector<std::string> benchmark_files;
+ static bool validate;
+ static FrameEnd frame_end;
+ static std::pair<int,int> size;
+ static bool list_scenes;
+ static bool show_all_options;
+ static bool show_debug;
+ static bool show_help;
+ static bool reuse_context;
+ static bool run_forever;
+ static bool annotate;
+ static bool offscreen;
+ static GLVisualConfig visual_config;
+};
+
+#endif /* OPTIONS_H_ */
diff --git a/src/scene-buffer.cpp b/src/scene-buffer.cpp
new file mode 100644
index 0000000..ef3a0b9
--- /dev/null
+++ b/src/scene-buffer.cpp
@@ -0,0 +1,472 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker
+ */
+#include "scene.h"
+#include "log.h"
+#include "mat.h"
+#include "stack.h"
+#include "shader-source.h"
+#include "util.h"
+#include "gl-headers.h"
+#include <cmath>
+
+/***********************
+ * Wave implementation *
+ ***********************/
+
+/**
+ * A callback used to set up the grid by the Wave class.
+ * It is called for each "quad" of the grid.
+ */
+static void
+wave_grid_conf(Mesh &mesh, int x, int y, int n_x, int n_y,
+ LibMatrix::vec3 &ul,
+ LibMatrix::vec3 &ll,
+ LibMatrix::vec3 &ur,
+ LibMatrix::vec3 &lr)
+{
+ // These parameters are unused in this instance of a virtual callback
+ // function.
+ static_cast<void>(x);
+ static_cast<void>(y);
+ static_cast<void>(n_x);
+ static_cast<void>(n_y);
+
+ /*
+ * Order matters here, so that Wave::vertex_length_index() can work.
+ * Vertices of the triangles at index i that belong to length index i
+ * are even, those that belong to i + 1 are odd.
+ */
+ const LibMatrix::vec3* t[] = {
+ &ll, &ur, &ul, &ur, &ll, &lr
+ };
+
+ for (int i = 0; i < 6; i++) {
+ mesh.next_vertex();
+ /*
+ * Set the vertex position and the three vertex positions
+ * of the triangle this vertex belongs to.
+ */
+ mesh.set_attrib(0, *t[i]);
+ mesh.set_attrib(1, *t[3 * (i / 3)]);
+ mesh.set_attrib(2, *t[3 * (i / 3) + 1]);
+ mesh.set_attrib(3, *t[3 * (i / 3) + 2]);
+ }
+}
+
+/**
+ * Renders a grid mesh modulated by a sine wave
+ */
+class WaveMesh
+{
+public:
+ /**
+ * Creates a wave mesh.
+ *
+ * @param length the total length of the grid (in model coordinates)
+ * @param width the total width of the grid (in model coordinates)
+ * @param nlength the number of length-wise grid subdivisions
+ * @param nwidth the number of width-wise grid subdivisions
+ * @param wavelength the wave length as a proportion of the length
+ * @param duty_cycle the duty cycle ()
+ */
+ WaveMesh(double length, double width, size_t nlength, size_t nwidth,
+ double wavelength, double duty_cycle) :
+ length_(length), width_(width), nlength_(nlength), nwidth_(nwidth),
+ wave_k_(2 * M_PI / (wavelength * length)),
+ wave_period_(2.0 * M_PI / wave_k_),
+ wave_full_period_(wave_period_ / duty_cycle),
+ wave_velocity_(0.1 * length), displacement_(nlength + 1)
+ {
+ create_program();
+ create_mesh();
+ }
+
+
+ ~WaveMesh() { reset(); }
+
+ /**
+ * Updates the state of a wave mesh.
+ *
+ * @param elapsed the time elapsed since the beginning of the rendering
+ */
+ void update(double elapsed)
+ {
+ std::vector<std::vector<float> >& vertices(mesh_.vertices());
+
+ /* Figure out which length index ranges need update */
+ std::vector<std::pair<size_t, size_t> > ranges;
+
+ for (size_t n = 0; n <= nlength_; n++) {
+ double d(displacement(n, elapsed));
+
+ if (d != displacement_[n]) {
+ if (ranges.size() > 0 && ranges.back().second == n - 1) {
+ ranges.back().second = n;
+ }
+ else {
+ ranges.push_back(
+ std::pair<size_t, size_t>(n > 0 ? n - 1 : 0, n)
+ );
+ }
+ }
+
+ displacement_[n] = d;
+ }
+
+ /* Update the vertex data of the changed ranges */
+ for (std::vector<std::pair<size_t, size_t> >::iterator iter = ranges.begin();
+ iter != ranges.end();
+ iter++)
+ {
+ /* First vertex of length index range */
+ size_t vstart(iter->first * nwidth_ * 6 + (iter->first % 2));
+ /*
+ * First vertex not included in the range. We should also update all
+ * vertices of triangles touching index i.
+ */
+ size_t vend((iter->second + (iter->second < nlength_)) * nwidth_ * 6);
+
+ for (size_t v = vstart; v < vend; v++) {
+ size_t vt = 3 * (v / 3);
+ vertices[v][0 * 3 + 2] = displacement_[vertex_length_index(v)];
+ vertices[v][1 * 3 + 2] = displacement_[vertex_length_index(vt)];
+ vertices[v][2 * 3 + 2] = displacement_[vertex_length_index(vt + 1)];
+ vertices[v][3 * 3 + 2] = displacement_[vertex_length_index(vt + 2)];
+ }
+
+ /* Update pair with actual vertex range */
+ iter->first = vstart;
+ iter->second = vend - 1;
+ }
+
+ mesh_.update_vbo(ranges);
+ }
+
+ Mesh& mesh() { return mesh_; }
+ Program& program() { return program_; }
+
+ void reset()
+ {
+ program_.stop();
+ program_.release();
+ mesh_.reset();
+ }
+
+private:
+ Mesh mesh_;
+ Program program_;
+ double length_;
+ double width_;
+ size_t nlength_;
+ size_t nwidth_;
+ /* Wave parameters */
+ double wave_k_;
+ double wave_period_;
+ double wave_full_period_;
+ double wave_fill_;
+ double wave_velocity_;
+
+ std::vector<double> displacement_;
+
+ /**
+ * Calculates the length index of a vertex.
+ */
+ size_t vertex_length_index(size_t v)
+ {
+ return v / (6 * nwidth_) + (v % 2);
+ }
+
+ /**
+ * The sine wave function with duty-cycle.
+ *
+ * @param x the space coordinate
+ *
+ * @return the operation error code
+ */
+ double wave_func(double x)
+ {
+ double r(fmod(x, wave_full_period_));
+ if (r < 0)
+ r += wave_full_period_;
+
+ /*
+ * Return either the sine value or 0.0, depending on the
+ * wave duty cycle.
+ */
+ if (r > wave_period_)
+ {
+ return 0;
+ }
+ else
+ {
+ return 0.2 * std::sin(wave_k_ * r);
+ }
+ }
+
+ /**
+ * Calculates the displacement of the wave.
+ *
+ * @param n the length index
+ * @param elapsed the time elapsed since the beginning of the rendering
+ *
+ * @return the displacement at point n at time elapsed
+ */
+ double displacement(size_t n, double elapsed)
+ {
+ double x(n * length_ / nlength_);
+
+ return wave_func(x - wave_velocity_ * elapsed);
+ }
+
+ /**
+ * Creates the GL shader program.
+ */
+ void create_program()
+ {
+ /* Set up shaders */
+ static const std::string vtx_shader_filename(
+ GLMARK_DATA_PATH"/shaders/buffer-wireframe.vert");
+ static const std::string frg_shader_filename(
+ GLMARK_DATA_PATH"/shaders/buffer-wireframe.frag");
+
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return;
+ }
+ }
+
+ /**
+ * Creates the grid mesh.
+ */
+ void create_mesh()
+ {
+ /*
+ * We need to pass the positions of all vertex of the triangle
+ * in order to draw the wireframe.
+ */
+ std::vector<int> vertex_format;
+ vertex_format.push_back(3); // Position of vertex
+ vertex_format.push_back(3); // Position of triangle vertex 0
+ vertex_format.push_back(3); // Position of triangle vertex 1
+ vertex_format.push_back(3); // Position of triangle vertex 2
+ mesh_.set_vertex_format(vertex_format);
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["tvertex0"].location());
+ attrib_locations.push_back(program_["tvertex1"].location());
+ attrib_locations.push_back(program_["tvertex2"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ mesh_.make_grid(nlength_, nwidth_, length_, width_,
+ 0.0, wave_grid_conf);
+ }
+
+};
+
+/******************************
+ * SceneBuffer implementation *
+ ******************************/
+
+struct SceneBufferPrivate {
+ WaveMesh *wave;
+ SceneBufferPrivate() : wave(0) {}
+ ~SceneBufferPrivate() { delete wave; }
+};
+
+SceneBuffer::SceneBuffer(Canvas &pCanvas) :
+ Scene(pCanvas, "buffer")
+{
+ priv_ = new SceneBufferPrivate();
+ options_["interleave"] = Scene::Option("interleave", "false",
+ "Whether to interleave vertex attribute data",
+ "false,true");
+ options_["update-method"] = Scene::Option("update-method", "map",
+ "Which method to use to update vertex data",
+ "map,subdata");
+ options_["update-fraction"] = Scene::Option("update-fraction", "1.0",
+ "The fraction of the mesh length that is updated at every iteration (0.0-1.0)");
+ options_["update-dispersion"] = Scene::Option("update-dispersion", "0.0",
+ "How dispersed the updates are [0.0 - 1.0]");
+ options_["columns"] = Scene::Option("columns", "100",
+ "The number of mesh subdivisions length-wise");
+ options_["rows"] = Scene::Option("rows", "20",
+ "The number of mesh subdisivisions width-wise");
+ options_["buffer-usage"] = Scene::Option("buffer-usage", "static",
+ "How the buffer will be used",
+ "static,stream,dynamic");
+}
+
+SceneBuffer::~SceneBuffer()
+{
+ delete priv_;
+}
+
+bool
+SceneBuffer::supported(bool show_errors)
+{
+ if (options_["update-method"].value != "subdata" &&
+ (GLExtensions::MapBuffer == 0 || GLExtensions::UnmapBuffer == 0))
+ {
+ if (show_errors) {
+ Log::error("Requested MapBuffer VBO update method but GL_OES_mapbuffer"
+ " is not supported!\n");
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool
+SceneBuffer::load()
+{
+ running_ = false;
+
+ return true;
+}
+
+void
+SceneBuffer::unload()
+{
+}
+
+bool
+SceneBuffer::setup()
+{
+ using LibMatrix::vec3;
+
+ if (!Scene::setup())
+ return false;
+
+ bool interleave = (options_["interleave"].value == "true");
+ Mesh::VBOUpdateMethod update_method;
+ Mesh::VBOUsage usage;
+ double update_fraction;
+ double update_dispersion;
+ size_t nlength;
+ size_t nwidth;
+
+ if (options_["update-method"].value == "map")
+ update_method = Mesh::VBOUpdateMethodMap;
+ else if (options_["update-method"].value == "subdata")
+ update_method = Mesh::VBOUpdateMethodSubData;
+ else
+ update_method = Mesh::VBOUpdateMethodMap;
+
+ if (options_["buffer-usage"].value == "static")
+ usage = Mesh::VBOUsageStatic;
+ else if (options_["buffer-usage"].value == "stream")
+ usage = Mesh::VBOUsageStream;
+ else
+ usage = Mesh::VBOUsageDynamic;
+
+ update_fraction = Util::fromString<double>(options_["update-fraction"].value);
+ update_dispersion = Util::fromString<double>(options_["update-dispersion"].value);
+ nlength = Util::fromString<size_t>(options_["columns"].value);
+ nwidth = Util::fromString<size_t>(options_["rows"].value);
+
+
+ priv_->wave = new WaveMesh(5.0, 2.0, nlength, nwidth,
+ update_fraction * (1.0 - update_dispersion + 0.0001),
+ update_fraction);
+
+ priv_->wave->mesh().interleave(interleave);
+ priv_->wave->mesh().vbo_update_method(update_method);
+ priv_->wave->mesh().vbo_usage(usage);
+ priv_->wave->mesh().build_vbo();
+
+ priv_->wave->program().start();
+ priv_->wave->program()["Viewport"] = LibMatrix::vec2(canvas_.width(), canvas_.height());
+
+ glDisable(GL_CULL_FACE);
+
+ currentFrame_ = 0;
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+void
+SceneBuffer::teardown()
+{
+ delete priv_->wave;
+ priv_->wave = 0;
+
+ glEnable(GL_CULL_FACE);
+
+ Scene::teardown();
+}
+
+void
+SceneBuffer::update()
+{
+ Scene::update();
+
+ double elapsed_time = lastUpdateTime_ - startTime_;
+
+ priv_->wave->update(elapsed_time);
+}
+
+void
+SceneBuffer::draw()
+{
+ LibMatrix::Stack4 model_view;
+
+ // Load the ModelViewProjectionMatrix uniform in the shader
+ LibMatrix::mat4 model_view_proj(canvas_.projection());
+ model_view.translate(0.0, 0.0, -4.0);
+ model_view.rotate(45.0, -1.0, 0.0, 0.0);
+ model_view_proj *= model_view.getCurrent();
+
+ priv_->wave->program()["ModelViewProjectionMatrix"] = model_view_proj;
+
+ priv_->wave->mesh().render_vbo();
+}
+
+Scene::ValidationResult
+SceneBuffer::validate()
+{
+ static const double radius_3d(std::sqrt(3.0 * 2.0 * 2.0));
+
+ Canvas::Pixel ref(0x34, 0x99, 0xd7, 0xff);
+ Canvas::Pixel pixel = canvas_.read_pixel(402, 189);
+
+ double dist = pixel.distance_rgb(ref);
+ if (dist < radius_3d + 0.01) {
+ return Scene::ValidationSuccess;
+ }
+ else {
+ Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+ ref.to_le32(), pixel.to_le32(), dist);
+ return Scene::ValidationFailure;
+ }
+
+ return Scene::ValidationUnknown;
+}
diff --git a/src/scene-build.cpp b/src/scene-build.cpp
new file mode 100644
index 0000000..22c948a
--- /dev/null
+++ b/src/scene-build.cpp
@@ -0,0 +1,268 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker (glmark2)
+ */
+#include "scene.h"
+#include "log.h"
+#include "mat.h"
+#include "stack.h"
+#include "shader-source.h"
+#include "model.h"
+#include "util.h"
+#include <cmath>
+
+SceneBuild::SceneBuild(Canvas &pCanvas) :
+ Scene(pCanvas, "build"),
+ orientModel_(false)
+{
+ const ModelMap& modelMap = Model::find_models();
+ std::string optionValues;
+ for (ModelMap::const_iterator modelIt = modelMap.begin();
+ modelIt != modelMap.end();
+ modelIt++)
+ {
+ static bool doSeparator(false);
+ if (doSeparator)
+ {
+ optionValues += ",";
+ }
+ const std::string& curName = modelIt->first;
+ optionValues += curName;
+ doSeparator = true;
+ }
+ options_["use-vbo"] = Scene::Option("use-vbo", "true",
+ "Whether to use VBOs for rendering",
+ "false,true");
+ options_["interleave"] = Scene::Option("interleave", "false",
+ "Whether to interleave vertex attribute data",
+ "false,true");
+ options_["model"] = Scene::Option("model", "horse", "Which model to use",
+ optionValues);
+}
+
+SceneBuild::~SceneBuild()
+{
+}
+
+bool
+SceneBuild::load()
+{
+ rotationSpeed_ = 36.0f;
+
+ running_ = false;
+
+ return true;
+}
+
+void
+SceneBuild::unload()
+{
+ mesh_.reset();
+}
+
+bool
+SceneBuild::setup()
+{
+ using LibMatrix::vec3;
+
+ if (!Scene::setup())
+ return false;
+
+ /* Set up shaders */
+ static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.vert");
+ static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.frag");
+ static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
+ static const LibMatrix::vec4 materialDiffuse(1.0f, 1.0f, 1.0f, 1.0f);
+
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ vtx_source.add_const("LightSourcePosition", lightPosition);
+ vtx_source.add_const("MaterialDiffuse", materialDiffuse);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return false;
+ }
+
+ Model model;
+ const std::string& whichModel(options_["model"].value);
+ bool modelLoaded = model.load(whichModel);
+
+ if(!modelLoaded)
+ return false;
+
+ // Now that we're successfully loaded, there are a few quirks about
+ // some of the known models that we need to account for. The draw
+ // logic for the scene wants to rotate the model around the Y axis.
+ // Most of our models are described this way. Some need adjustment
+ // (an additional rotation that gets the model into the correct
+ // orientation).
+ //
+ // Here's a summary:
+ //
+ // Angel rotates around the Y axis
+ // Armadillo rotates around the Y axis
+ // Buddha rotates around the X axis
+ // Bunny rotates around the Y axis
+ // Dragon rotates around the X axis
+ // Horse rotates around the Y axis
+ if (whichModel == "buddha" || whichModel == "dragon")
+ {
+ orientModel_ = true;
+ orientationAngle_ = -90.0;
+ orientationVec_ = vec3(1.0, 0.0, 0.0);
+ }
+ else if (whichModel == "armadillo")
+ {
+ orientModel_ = true;
+ orientationAngle_ = 180.0;
+ orientationVec_ = vec3(0.0, 1.0, 0.0);
+ }
+
+ model.calculate_normals();
+
+ /* Tell the converter that we only care about position and normal attributes */
+ std::vector<std::pair<Model::AttribType, int> > attribs;
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
+
+ model.convert_to_mesh(mesh_, attribs);
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["normal"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ useVbo_ = (options_["use-vbo"].value == "true");
+ bool interleave = (options_["interleave"].value == "true");
+
+ mesh_.vbo_update_method(Mesh::VBOUpdateMethodMap);
+ mesh_.interleave(interleave);
+
+ if (useVbo_)
+ mesh_.build_vbo();
+ else
+ mesh_.build_array();
+
+ /* Calculate a projection matrix that is a good fit for the model */
+ vec3 maxVec = model.maxVec();
+ vec3 minVec = model.minVec();
+ vec3 diffVec = maxVec - minVec;
+ centerVec_ = maxVec + minVec;
+ centerVec_ /= 2.0;
+ float diameter = diffVec.length();
+ radius_ = diameter / 2;
+ float fovy = 2.0 * atanf(radius_ / (2.0 + radius_));
+ fovy /= M_PI;
+ fovy *= 180.0;
+ float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height()));
+ perspective_.setIdentity();
+ perspective_ *= LibMatrix::Mat4::perspective(fovy, aspect, 2.0, 2.0 + diameter);
+
+ program_.start();
+
+ currentFrame_ = 0;
+ rotation_ = 0.0;
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+void
+SceneBuild::teardown()
+{
+ program_.stop();
+ program_.release();
+
+ mesh_.reset();
+
+ Scene::teardown();
+}
+
+void
+SceneBuild::update()
+{
+ Scene::update();
+
+ double elapsed_time = lastUpdateTime_ - startTime_;
+
+ rotation_ = rotationSpeed_ * elapsed_time;
+}
+
+void
+SceneBuild::draw()
+{
+ LibMatrix::Stack4 model_view;
+
+ // Load the ModelViewProjectionMatrix uniform in the shader
+ LibMatrix::mat4 model_view_proj(perspective_);
+ model_view.translate(-centerVec_.x(), -centerVec_.y(), -(centerVec_.z() + 2.0 + radius_));
+ model_view.rotate(rotation_, 0.0f, 1.0f, 0.0f);
+ if (orientModel_)
+ {
+ model_view.rotate(orientationAngle_, orientationVec_.x(), orientationVec_.y(), orientationVec_.z());
+ }
+ model_view_proj *= model_view.getCurrent();
+
+ program_["ModelViewProjectionMatrix"] = model_view_proj;
+
+ // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
+ // inverse transpose of the model view matrix.
+ LibMatrix::mat4 normal_matrix(model_view.getCurrent());
+ normal_matrix.inverse().transpose();
+ program_["NormalMatrix"] = normal_matrix;
+
+ if (useVbo_) {
+ mesh_.render_vbo();
+ }
+ else {
+ mesh_.render_array();
+ }
+}
+
+Scene::ValidationResult
+SceneBuild::validate()
+{
+ static const double radius_3d(std::sqrt(3.0));
+
+ if (rotation_ != 0)
+ return Scene::ValidationUnknown;
+
+ Canvas::Pixel ref(0xa7, 0xa7, 0xa7, 0xff);
+ Canvas::Pixel pixel = canvas_.read_pixel(canvas_.width() / 2,
+ canvas_.height() / 2);
+
+ double dist = pixel.distance_rgb(ref);
+ if (dist < radius_3d + 0.01) {
+ return Scene::ValidationSuccess;
+ }
+ else {
+ Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+ ref.to_le32(), pixel.to_le32(), dist);
+ return Scene::ValidationFailure;
+ }
+}
diff --git a/src/scene-bump.cpp b/src/scene-bump.cpp
new file mode 100644
index 0000000..2b6c01f
--- /dev/null
+++ b/src/scene-bump.cpp
@@ -0,0 +1,414 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker (glmark2)
+ */
+#include "scene.h"
+#include "log.h"
+#include "mat.h"
+#include "stack.h"
+#include "shader-source.h"
+#include "model.h"
+#include "texture.h"
+#include "util.h"
+#include <cmath>
+
+SceneBump::SceneBump(Canvas &pCanvas) :
+ Scene(pCanvas, "bump"),
+ texture_(0), rotation_(0.0f), rotationSpeed_(0.0f)
+{
+ options_["bump-render"] = Scene::Option("bump-render", "off",
+ "How to render bumps",
+ "off,normals,normals-tangent,height,high-poly");
+}
+
+SceneBump::~SceneBump()
+{
+}
+
+bool
+SceneBump::load()
+{
+ rotationSpeed_ = 36.0f;
+
+ running_ = false;
+
+ return true;
+}
+
+void
+SceneBump::unload()
+{
+}
+
+bool
+SceneBump::setup_model_plain(const std::string &type)
+{
+ static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/bump-poly.vert");
+ static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/bump-poly.frag");
+ static const std::string low_poly_filename("asteroid-low");
+ static const std::string high_poly_filename("asteroid-high");
+ static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
+ Model model;
+
+ /* Calculate the half vector */
+ LibMatrix::vec3 halfVector(lightPosition.x(), lightPosition.y(), lightPosition.z());
+ halfVector.normalize();
+ halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
+ halfVector.normalize();
+
+ std::string poly_filename = type == "high-poly" ?
+ high_poly_filename : low_poly_filename;
+
+ if(!model.load(poly_filename))
+ return false;
+
+ model.calculate_normals();
+
+ /* Tell the converter that we only care about position and normal attributes */
+ std::vector<std::pair<Model::AttribType, int> > attribs;
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
+
+ model.convert_to_mesh(mesh_, attribs);
+
+ /* Load shaders */
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ /* Add constants to shaders */
+ frg_source.add_const("LightSourcePosition", lightPosition);
+ frg_source.add_const("LightSourceHalfVector", halfVector);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return false;
+ }
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["normal"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ return true;
+}
+
+bool
+SceneBump::setup_model_normals()
+{
+ static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/bump-normals.vert");
+ static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/bump-normals.frag");
+ static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
+ Model model;
+
+ if(!model.load("asteroid-low"))
+ return false;
+
+ /* Calculate the half vector */
+ LibMatrix::vec3 halfVector(lightPosition.x(), lightPosition.y(), lightPosition.z());
+ halfVector.normalize();
+ halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
+ halfVector.normalize();
+
+ /*
+ * We don't care about the vertex normals. We are using a per-fragment
+ * normal map (in object space coordinates).
+ */
+ std::vector<std::pair<Model::AttribType, int> > attribs;
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeTexcoord, 2));
+
+ model.convert_to_mesh(mesh_, attribs);
+
+ /* Load shaders */
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ /* Add constants to shaders */
+ frg_source.add_const("LightSourcePosition", lightPosition);
+ frg_source.add_const("LightSourceHalfVector", halfVector);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return false;
+ }
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["texcoord"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ if (!Texture::load("asteroid-normal-map", &texture_,
+ GL_NEAREST, GL_NEAREST, 0))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+SceneBump::setup_model_normals_tangent()
+{
+ static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/bump-normals-tangent.vert");
+ static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/bump-normals-tangent.frag");
+ static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
+ Model model;
+
+ if(!model.load("asteroid-low"))
+ return false;
+
+ model.calculate_normals();
+
+ /* Calculate the half vector */
+ LibMatrix::vec3 halfVector(lightPosition.x(), lightPosition.y(), lightPosition.z());
+ halfVector.normalize();
+ halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
+ halfVector.normalize();
+
+ std::vector<std::pair<Model::AttribType, int> > attribs;
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeTexcoord, 2));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeTangent, 3));
+
+ model.convert_to_mesh(mesh_, attribs);
+
+ /* Load shaders */
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ /* Add constants to shaders */
+ frg_source.add_const("LightSourcePosition", lightPosition);
+ frg_source.add_const("LightSourceHalfVector", halfVector);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return false;
+ }
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["normal"].location());
+ attrib_locations.push_back(program_["texcoord"].location());
+ attrib_locations.push_back(program_["tangent"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ if (!Texture::load("asteroid-normal-map-tangent", &texture_,
+ GL_NEAREST, GL_NEAREST, 0))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+SceneBump::setup_model_height()
+{
+ static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/bump-height.vert");
+ static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/bump-height.frag");
+ static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
+ Model model;
+
+ if(!model.load("asteroid-low"))
+ return false;
+
+ model.calculate_normals();
+
+ /* Calculate the half vector */
+ LibMatrix::vec3 halfVector(lightPosition.x(), lightPosition.y(), lightPosition.z());
+ halfVector.normalize();
+ halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
+ halfVector.normalize();
+
+ std::vector<std::pair<Model::AttribType, int> > attribs;
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeTexcoord, 2));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeTangent, 3));
+
+ model.convert_to_mesh(mesh_, attribs);
+
+ /* Load shaders */
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ /* Add constants to shaders */
+ frg_source.add_const("LightSourcePosition", lightPosition);
+ frg_source.add_const("LightSourceHalfVector", halfVector);
+ frg_source.add_const("TextureStepX", 1.0 / 1024.0);
+ frg_source.add_const("TextureStepY", 1.0 / 1024.0);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return false;
+ }
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["normal"].location());
+ attrib_locations.push_back(program_["texcoord"].location());
+ attrib_locations.push_back(program_["tangent"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ if (!Texture::load("asteroid-height-map", &texture_,
+ GL_NEAREST, GL_NEAREST, 0))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+SceneBump::setup()
+{
+ if (!Scene::setup())
+ return false;
+
+ const std::string &bump_render = options_["bump-render"].value;
+ Texture::find_textures();
+ Model::find_models();
+
+ bool setup_succeeded = false;
+
+ if (bump_render == "normals")
+ setup_succeeded = setup_model_normals();
+ else if (bump_render == "normals-tangent")
+ setup_succeeded = setup_model_normals_tangent();
+ else if (bump_render == "height")
+ setup_succeeded = setup_model_height();
+ else if (bump_render == "off" || bump_render == "high-poly")
+ setup_succeeded = setup_model_plain(bump_render);
+
+ if (!setup_succeeded)
+ return false;
+
+ mesh_.build_vbo();
+
+ program_.start();
+
+ // Load texture sampler value
+ program_["NormalMap"] = 0;
+ program_["HeightMap"] = 0;
+
+ currentFrame_ = 0;
+ rotation_ = 0.0;
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+void
+SceneBump::teardown()
+{
+ mesh_.reset();
+
+ program_.stop();
+ program_.release();
+
+ glDeleteTextures(1, &texture_);
+ texture_ = 0;
+
+ Scene::teardown();
+}
+
+void
+SceneBump::update()
+{
+ Scene::update();
+
+ double elapsed_time = lastUpdateTime_ - startTime_;
+
+ rotation_ = rotationSpeed_ * elapsed_time;
+}
+
+void
+SceneBump::draw()
+{
+ LibMatrix::Stack4 model_view;
+
+ // Load the ModelViewProjectionMatrix uniform in the shader
+ LibMatrix::mat4 model_view_proj(canvas_.projection());
+
+ model_view.translate(0.0f, 0.0f, -3.5f);
+ model_view.rotate(rotation_, 0.0f, 1.0f, 0.0f);
+ model_view_proj *= model_view.getCurrent();
+
+ program_["ModelViewProjectionMatrix"] = model_view_proj;
+
+ // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
+ // inverse transpose of the model view matrix.
+ LibMatrix::mat4 normal_matrix(model_view.getCurrent());
+ normal_matrix.inverse().transpose();
+ program_["NormalMatrix"] = normal_matrix;
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_);
+
+ mesh_.render_vbo();
+}
+
+Scene::ValidationResult
+SceneBump::validate()
+{
+ static const double radius_3d(std::sqrt(3.0));
+
+ if (rotation_ != 0)
+ return Scene::ValidationUnknown;
+
+ Canvas::Pixel ref;
+
+ Canvas::Pixel pixel = canvas_.read_pixel(canvas_.width() / 2,
+ canvas_.height() / 2);
+
+ const std::string &bump_render = options_["bump-render"].value;
+
+ if (bump_render == "off")
+ ref = Canvas::Pixel(0x81, 0x81, 0x81, 0xff);
+ else if (bump_render == "high-poly")
+ ref = Canvas::Pixel(0x9c, 0x9c, 0x9c, 0xff);
+ else if (bump_render == "normals")
+ ref = Canvas::Pixel(0xa4, 0xa4, 0xa4, 0xff);
+ else if (bump_render == "normals-tangent")
+ ref = Canvas::Pixel(0x99, 0x99, 0x99, 0xff);
+ else if (bump_render == "height")
+ ref = Canvas::Pixel(0x9d, 0x9d, 0x9d, 0xff);
+ else
+ return Scene::ValidationUnknown;
+
+ double dist = pixel.distance_rgb(ref);
+
+ if (dist < radius_3d + 0.01) {
+ return Scene::ValidationSuccess;
+ }
+ else {
+ Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+ ref.to_le32(), pixel.to_le32(), dist);
+ return Scene::ValidationFailure;
+ }
+}
diff --git a/src/scene-conditionals.cpp b/src/scene-conditionals.cpp
new file mode 100644
index 0000000..778cb33
--- /dev/null
+++ b/src/scene-conditionals.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "shader-source.h"
+#include "util.h"
+
+#include <cmath>
+
+static const std::string shader_file_base(GLMARK_DATA_PATH"/shaders/conditionals");
+
+static const std::string vtx_file(shader_file_base + ".vert");
+static const std::string frg_file(shader_file_base + ".frag");
+static const std::string step_conditional_file(shader_file_base + "-step-conditional.all");
+static const std::string step_simple_file(shader_file_base + "-step-simple.all");
+
+SceneConditionals::SceneConditionals(Canvas &pCanvas) :
+ SceneGrid(pCanvas, "conditionals")
+{
+ options_["fragment-steps"] = Scene::Option("fragment-steps", "1",
+ "The number of computational steps in the fragment shader");
+ options_["fragment-conditionals"] = Scene::Option("fragment-conditionals", "true",
+ "Whether each computational step includes an if-else clause", "false,true");
+ options_["vertex-steps"] = Scene::Option("vertex-steps", "1",
+ "The number of computational steps in the vertex shader");
+ options_["vertex-conditionals"] = Scene::Option("vertex-conditionals", "true",
+ "Whether each computational step includes an if-else clause", "false,true");
+}
+
+SceneConditionals::~SceneConditionals()
+{
+}
+
+static std::string
+get_vertex_shader_source(int steps, bool conditionals)
+{
+ ShaderSource source(vtx_file);
+ ShaderSource source_main;
+
+ for (int i = 0; i < steps; i++) {
+ if (conditionals)
+ source_main.append_file(step_conditional_file);
+ else
+ source_main.append_file(step_simple_file);
+ }
+
+ source.replace("$MAIN$", source_main.str());
+
+ return source.str();
+}
+
+static std::string
+get_fragment_shader_source(int steps, bool conditionals)
+{
+ ShaderSource source(frg_file);
+ ShaderSource source_main;
+
+ for (int i = 0; i < steps; i++) {
+ if (conditionals)
+ source_main.append_file(step_conditional_file);
+ else
+ source_main.append_file(step_simple_file);
+ }
+
+ source.replace("$MAIN$", source_main.str());
+
+ return source.str();
+}
+
+bool
+SceneConditionals::setup()
+{
+ if (!SceneGrid::setup())
+ return false;
+
+ /* Parse options */
+ bool vtx_conditionals = options_["vertex-conditionals"].value == "true";
+ bool frg_conditionals = options_["fragment-conditionals"].value == "true";
+ int vtx_steps(Util::fromString<int>(options_["vertex-steps"].value));
+ int frg_steps(Util::fromString<int>(options_["fragment-steps"].value));
+ /* Load shaders */
+ std::string vtx_shader(get_vertex_shader_source(vtx_steps, vtx_conditionals));
+ std::string frg_shader(get_fragment_shader_source(frg_steps, frg_conditionals));
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_shader, frg_shader))
+ return false;
+
+ program_.start();
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+Scene::ValidationResult
+SceneConditionals::validate()
+{
+ static const double radius_3d(std::sqrt(3.0 * 5.0 * 5.0));
+
+ bool frg_conditionals = options_["fragment-conditionals"].value == "true";
+ int frg_steps(Util::fromString<int>(options_["fragment-steps"].value));
+
+ if (!frg_conditionals)
+ return Scene::ValidationUnknown;
+
+ Canvas::Pixel ref;
+
+ if (frg_steps == 0)
+ ref = Canvas::Pixel(0xa0, 0xa0, 0xa0, 0xff);
+ else if (frg_steps == 5)
+ ref = Canvas::Pixel(0x25, 0x25, 0x25, 0xff);
+ else
+ return Scene::ValidationUnknown;
+
+ Canvas::Pixel pixel = canvas_.read_pixel(293, 89);
+
+ double dist = pixel.distance_rgb(ref);
+ if (dist < radius_3d + 0.01) {
+ return Scene::ValidationSuccess;
+ }
+ else {
+ Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+ ref.to_le32(), pixel.to_le32(), dist);
+ return Scene::ValidationFailure;
+ }
+
+ return Scene::ValidationUnknown;
+}
diff --git a/src/scene-default-options.cpp b/src/scene-default-options.cpp
new file mode 100644
index 0000000..0cc8c89
--- /dev/null
+++ b/src/scene-default-options.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#include "scene.h"
+#include "benchmark.h"
+#include "log.h"
+
+bool
+SceneDefaultOptions::setup()
+{
+ const std::map<std::string, Scene *> &scenes = Benchmark::scenes();
+
+ for (std::list<std::pair<std::string, std::string> >::const_iterator iter = defaultOptions_.begin();
+ iter != defaultOptions_.end();
+ iter++)
+ {
+ for (std::map<std::string, Scene *>::const_iterator scene_iter = scenes.begin();
+ scene_iter != scenes.end();
+ scene_iter++)
+ {
+ Scene &scene(*(scene_iter->second));
+
+ /*
+ * Display warning only if the option value is unsupported, not if
+ * the scene doesn't support the option at all.
+ */
+ if (!scene.set_option_default(iter->first, iter->second) &&
+ scene.options().find(iter->first) != scene.options().end())
+ {
+ Log::info("Warning: Scene '%s' doesn't accept default value '%s' for option '%s'\n",
+ scene.name().c_str(), iter->second.c_str(), iter->first.c_str());
+ }
+ }
+ }
+
+ return true;
+}
+
+bool
+SceneDefaultOptions::set_option(const std::string &opt, const std::string &val)
+{
+ defaultOptions_.push_back(std::pair<std::string, std::string>(opt, val));
+ return true;
+}
diff --git a/src/scene-desktop.cpp b/src/scene-desktop.cpp
new file mode 100644
index 0000000..b1431f8
--- /dev/null
+++ b/src/scene-desktop.cpp
@@ -0,0 +1,1017 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker (glmark2)
+ */
+#include <cmath>
+#include <cstdlib>
+
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "program.h"
+#include "shader-source.h"
+#include "util.h"
+#include "texture.h"
+
+enum BlurDirection {
+ BlurDirectionHorizontal,
+ BlurDirectionVertical,
+ BlurDirectionBoth
+};
+
+static void
+create_blur_shaders(ShaderSource& vtx_source, ShaderSource& frg_source,
+ unsigned int radius, float sigma, BlurDirection direction)
+{
+ vtx_source.append_file(GLMARK_DATA_PATH"/shaders/desktop.vert");
+ frg_source.append_file(GLMARK_DATA_PATH"/shaders/desktop-blur.frag");
+
+ /* Don't let the gaussian curve become too narrow */
+ if (sigma < 1.0)
+ sigma = 1.0;
+
+ unsigned int side = 2 * radius + 1;
+
+ for (unsigned int i = 0; i < radius + 1; i++) {
+ float s2 = 2.0 * sigma * sigma;
+ float k = 1.0 / std::sqrt(M_PI * s2) * std::exp( - (static_cast<float>(i) * i) / s2);
+ std::stringstream ss_tmp;
+ ss_tmp << "Kernel" << i;
+ frg_source.add_const(ss_tmp.str(), k);
+ }
+
+ std::stringstream ss;
+ ss << "result = " << std::endl;
+
+ if (direction == BlurDirectionHorizontal) {
+ for (unsigned int i = 0; i < side; i++) {
+ int offset = static_cast<int>(i - radius);
+ ss << "texture2D(Texture0, TextureCoord + vec2(" <<
+ offset << ".0 * TextureStepX, 0.0)) * Kernel" <<
+ std::abs(offset) << " +" << std::endl;
+ }
+ ss << "0.0 ;" << std::endl;
+ }
+ else if (direction == BlurDirectionVertical) {
+ for (unsigned int i = 0; i < side; i++) {
+ int offset = static_cast<int>(i - radius);
+ ss << "texture2D(Texture0, TextureCoord + vec2(0.0, " <<
+ offset << ".0 * TextureStepY)) * Kernel" <<
+ std::abs(offset) << " +" << std::endl;
+ }
+ ss << "0.0 ;" << std::endl;
+ }
+ else if (direction == BlurDirectionBoth) {
+ for (unsigned int i = 0; i < side; i++) {
+ int ioffset = static_cast<int>(i - radius);
+ for (unsigned int j = 0; j < side; j++) {
+ int joffset = static_cast<int>(j - radius);
+ ss << "texture2D(Texture0, TextureCoord + vec2(" <<
+ ioffset << ".0 * TextureStepX, " <<
+ joffset << ".0 * TextureStepY))" <<
+ " * Kernel" << std::abs(ioffset) <<
+ " * Kernel" << std::abs(joffset) << " +" << std::endl;
+ }
+ }
+ ss << " 0.0;" << std::endl;
+ }
+
+ frg_source.replace("$CONVOLUTION$", ss.str());
+}
+
+/**
+ * A RenderObject represents a source and target of rendering
+ * operations.
+ */
+class RenderObject
+{
+public:
+ RenderObject() :
+ texture_(0), fbo_(0), rotation_rad_(0),
+ texture_contents_invalid_(true) { }
+
+ virtual ~RenderObject() {}
+
+ virtual void init()
+ {
+ /* Create a texture to draw to */
+ glGenTextures(1, &texture_);
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0);
+
+ /* Create a FBO */
+ glGenFramebuffers(1, &fbo_);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, texture_, 0);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ /* Load the shader program when this class if first used */
+ if (RenderObject::use_count == 0) {
+ ShaderSource vtx_source(GLMARK_DATA_PATH"/shaders/desktop.vert");
+ ShaderSource frg_source(GLMARK_DATA_PATH"/shaders/desktop.frag");
+ Scene::load_shaders_from_strings(main_program, vtx_source.str(),
+ frg_source.str());
+ }
+
+ texture_contents_invalid_ = true;
+ RenderObject::use_count++;
+ }
+
+ virtual void release()
+ {
+ /* Release resources */
+ if (texture_ != 0)
+ {
+ glDeleteTextures(1, &texture_);
+ texture_ = 0;
+ }
+ if (fbo_ != 0)
+ {
+ glDeleteFramebuffers(1, &fbo_);
+ fbo_ = 0;
+ }
+
+ /*
+ * Release the shader program when object of this class
+ * are no longer in use.
+ */
+ RenderObject::use_count--;
+ if (RenderObject::use_count == 0)
+ RenderObject::main_program.release();
+ }
+
+ void make_current()
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ glViewport(0, 0, size_.x(), size_.y());
+ }
+
+ void position(const LibMatrix::vec2& pos) { pos_ = pos; }
+ const LibMatrix::vec2& position() { return pos_; }
+
+
+ virtual void size(const LibMatrix::vec2& size)
+ {
+ /* Recreate the backing texture with correct size */
+ if (size_.x() != size.x() || size_.y() != size.y()) {
+ size_ = size;
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ texture_contents_invalid_ = true;
+ }
+
+ if (texture_contents_invalid_) {
+ clear();
+ texture_contents_invalid_ = false;
+ }
+ }
+
+ const LibMatrix::vec2& size() { return size_; }
+
+ const LibMatrix::vec2& speed() { return speed_; }
+ void speed(const LibMatrix::vec2& speed) { speed_ = speed; }
+
+ GLuint texture() { return texture_; }
+
+ virtual void clear()
+ {
+ make_current();
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ virtual void render_to(RenderObject& target)
+ {
+ render_to(target, main_program);
+ }
+
+ virtual void render_to(RenderObject& target, Program& program)
+ {
+ LibMatrix::vec2 anchor(pos_);
+ LibMatrix::vec2 ll(pos_ - anchor);
+ LibMatrix::vec2 ur(pos_ + size_ - anchor);
+
+ /* Calculate new position according to rotation value */
+ GLfloat position[2 * 4] = {
+ rotate_x(ll.x(), ll.y()) + anchor.x(), rotate_y(ll.x(), ll.y()) + anchor.y(),
+ rotate_x(ur.x(), ll.y()) + anchor.x(), rotate_y(ur.x(), ll.y()) + anchor.y(),
+ rotate_x(ll.x(), ur.y()) + anchor.x(), rotate_y(ll.x(), ur.y()) + anchor.y(),
+ rotate_x(ur.x(), ur.y()) + anchor.x(), rotate_y(ur.x(), ur.y()) + anchor.y(),
+ };
+
+ /* Normalize position and write back to array */
+ for (int i = 0; i < 4; i++) {
+ const LibMatrix::vec2& v2(
+ target.normalize_position(
+ LibMatrix::vec2(position[2 * i], position[2 * i + 1])
+ )
+ );
+ position[2 * i] = v2.x();
+ position[2 * i + 1] = v2.y();
+ }
+
+ static const GLfloat texcoord[2 * 4] = {
+ 0.0, 0.0,
+ 1.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 1.0,
+ };
+
+ target.make_current();
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ draw_quad_with_program(position, texcoord, program);
+ }
+
+ virtual void render_from(RenderObject& target, Program& program = main_program)
+ {
+ LibMatrix::vec2 final_pos(pos_ + size_);
+ LibMatrix::vec2 ll_tex(target.normalize_texcoord(pos_));
+ LibMatrix::vec2 ur_tex(target.normalize_texcoord(final_pos));
+
+ static const GLfloat position_blur[2 * 4] = {
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0,
+ };
+ GLfloat texcoord_blur[2 * 4] = {
+ ll_tex.x(), ll_tex.y(),
+ ur_tex.x(), ll_tex.y(),
+ ll_tex.x(), ur_tex.y(),
+ ur_tex.x(), ur_tex.y(),
+ };
+
+ make_current();
+ glBindTexture(GL_TEXTURE_2D, target.texture());
+ draw_quad_with_program(position_blur, texcoord_blur, program);
+ }
+
+ /**
+ * Normalizes a position from [0, size] to [-1.0, 1.0]
+ */
+ LibMatrix::vec2 normalize_position(const LibMatrix::vec2& pos)
+ {
+ return pos * 2.0 / size_ - 1.0;
+ }
+
+ /**
+ * Normalizes a position from [0, size] to [0.0, 1.0]
+ */
+ LibMatrix::vec2 normalize_texcoord(const LibMatrix::vec2& pos)
+ {
+ return pos / size_;
+ }
+
+ void rotation(float degrees)
+ {
+ rotation_rad_ = (M_PI * degrees / 180.0);
+ }
+
+protected:
+ void draw_quad_with_program(const GLfloat *position, const GLfloat *texcoord,
+ Program &program)
+ {
+ int pos_index = program["position"].location();
+ int tex_index = program["texcoord"].location();
+
+ program.start();
+
+ glEnableVertexAttribArray(pos_index);
+ glEnableVertexAttribArray(tex_index);
+ glVertexAttribPointer(pos_index, 2,
+ GL_FLOAT, GL_FALSE, 0, position);
+ glVertexAttribPointer(tex_index, 2,
+ GL_FLOAT, GL_FALSE, 0, texcoord);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glDisableVertexAttribArray(tex_index);
+ glDisableVertexAttribArray(pos_index);
+
+ program.stop();
+ }
+
+ static Program main_program;
+
+ LibMatrix::vec2 pos_;
+ LibMatrix::vec2 size_;
+ LibMatrix::vec2 speed_;
+ GLuint texture_;
+ GLuint fbo_;
+
+private:
+ float rotate_x(float x, float y)
+ {
+ return x * cos(rotation_rad_) - y * sin(rotation_rad_);
+ }
+
+ float rotate_y(float x, float y)
+ {
+ return x * sin(rotation_rad_) + y * cos(rotation_rad_);
+ }
+
+ float rotation_rad_;
+ bool texture_contents_invalid_;
+ static int use_count;
+
+};
+
+int RenderObject::use_count = 0;
+Program RenderObject::main_program;
+
+/**
+ * A RenderObject representing the screen.
+ *
+ * Rendering to this objects renders to the screen framebuffer.
+ */
+class RenderScreen : public RenderObject
+{
+public:
+ RenderScreen(Canvas &canvas) { fbo_ = canvas.fbo(); }
+ virtual void init() {}
+ virtual void release() {}
+};
+
+/**
+ * A RenderObject with a background image.
+ *
+ * The image is drawn to the RenderObject automatically when the
+ * object is cleared, resized etc
+ */
+class RenderClearImage : public RenderObject
+{
+public:
+ RenderClearImage(const std::string& texture) :
+ RenderObject(), background_texture_name(texture),
+ background_texture_(0) {}
+
+ virtual void init()
+ {
+ RenderObject::init();
+
+ /* Load the image into a texture */
+ Texture::load(background_texture_name,
+ &background_texture_, GL_LINEAR, GL_LINEAR, 0);
+
+ }
+
+ virtual void release()
+ {
+ glDeleteTextures(1, &background_texture_);
+ background_texture_ = 0;
+
+ RenderObject::release();
+ }
+
+ virtual void clear()
+ {
+ static const GLfloat position[2 * 4] = {
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0,
+ };
+ static const GLfloat texcoord[2 * 4] = {
+ 0.0, 0.0,
+ 1.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 1.0,
+ };
+
+ make_current();
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, background_texture_);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ draw_quad_with_program(position, texcoord, main_program);
+ glDisable(GL_BLEND);
+ }
+
+private:
+ std::string background_texture_name;
+ GLuint background_texture_;
+};
+
+/**
+ * A RenderObject that blurs the target it is drawn to.
+ */
+class RenderWindowBlur : public RenderObject
+{
+public:
+ RenderWindowBlur(unsigned int passes, unsigned int radius, bool separable,
+ bool draw_contents = true) :
+ RenderObject(), passes_(passes), radius_(radius), separable_(separable),
+ draw_contents_(draw_contents) {}
+
+ virtual void init()
+ {
+ RenderObject::init();
+
+ /* Only have one instance of the window contents data */
+ if (draw_contents_ && RenderWindowBlur::use_count == 0)
+ window_contents_.init();
+
+ RenderWindowBlur::use_count++;
+ }
+
+ virtual void release()
+ {
+ RenderWindowBlur::use_count--;
+
+ /* Only have one instance of the window contents data */
+ if (draw_contents_ && RenderWindowBlur::use_count == 0)
+ window_contents_.release();
+
+ RenderObject::release();
+ }
+
+ virtual void size(const LibMatrix::vec2& size)
+ {
+ RenderObject::size(size);
+ if (draw_contents_)
+ window_contents_.size(size);
+ }
+
+ virtual void render_to(RenderObject& target)
+ {
+ if (separable_) {
+ Program& blur_program_h1 = blur_program_h(target.size().x());
+ Program& blur_program_v1 = blur_program_v(target.size().y());
+
+ for (unsigned int i = 0; i < passes_; i++) {
+ render_from(target, blur_program_h1);
+ RenderObject::render_to(target, blur_program_v1);
+ }
+ }
+ else {
+ Program& blur_program1 = blur_program(target.size().x(), target.size().y());
+
+ for (unsigned int i = 0; i < passes_; i++) {
+ if (i % 2 == 0)
+ render_from(target, blur_program1);
+ else
+ RenderObject::render_to(target, blur_program1);
+ }
+
+ if (passes_ % 2 == 1)
+ RenderObject::render_to(target);
+ }
+
+ /*
+ * Blend the window contents with the target texture.
+ */
+ if (draw_contents_) {
+ glEnable(GL_BLEND);
+ /*
+ * Blend the colors normally, but don't change the
+ * destination alpha value.
+ */
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
+ GL_ZERO, GL_ONE);
+ window_contents_.position(position());
+ window_contents_.render_to(target);
+ glDisable(GL_BLEND);
+ }
+ }
+
+private:
+ Program& blur_program(unsigned int w, unsigned int h)
+ {
+ /*
+ * If the size of the window has changed we must recreate
+ * the shader to contain the correct texture step values.
+ */
+ if (blur_program_dim_.x() != w || blur_program_dim_.y() != h ||
+ !blur_program_.ready())
+ {
+ blur_program_dim_.x(w);
+ blur_program_dim_.y(h);
+
+ blur_program_.release();
+
+ ShaderSource vtx_source;
+ ShaderSource frg_source;
+ create_blur_shaders(vtx_source, frg_source, radius_,
+ radius_ / 3.0, BlurDirectionBoth);
+ frg_source.add_const("TextureStepX", 1.0 / w);
+ frg_source.add_const("TextureStepY", 1.0 / h);
+ Scene::load_shaders_from_strings(blur_program_, vtx_source.str(),
+ frg_source.str());
+ }
+
+ return blur_program_;
+ }
+
+ Program& blur_program_h(unsigned int w)
+ {
+ /*
+ * If the size of the window has changed we must recreate
+ * the shader to contain the correct texture step values.
+ */
+ if (blur_program_dim_.x() != w ||
+ !blur_program_h_.ready())
+ {
+ blur_program_dim_.x(w);
+
+ blur_program_h_.release();
+
+ ShaderSource vtx_source;
+ ShaderSource frg_source;
+ create_blur_shaders(vtx_source, frg_source, radius_,
+ radius_ / 3.0, BlurDirectionHorizontal);
+ frg_source.add_const("TextureStepX", 1.0 / w);
+ Scene::load_shaders_from_strings(blur_program_h_, vtx_source.str(),
+ frg_source.str());
+ }
+
+ return blur_program_h_;
+ }
+
+ Program& blur_program_v(unsigned int h)
+ {
+ /*
+ * If the size of the window has changed we must recreate
+ * the shader to contain the correct texture step values.
+ */
+ if (blur_program_dim_.y() != h ||
+ !blur_program_v_.ready())
+ {
+ blur_program_dim_.y(h);
+
+ blur_program_v_.release();
+
+ ShaderSource vtx_source;
+ ShaderSource frg_source;
+ create_blur_shaders(vtx_source, frg_source, radius_,
+ radius_ / 3.0, BlurDirectionVertical);
+ frg_source.add_const("TextureStepY", 1.0 / h);
+ Scene::load_shaders_from_strings(blur_program_v_, vtx_source.str(),
+ frg_source.str());
+ }
+
+ return blur_program_v_;
+ }
+
+ LibMatrix::uvec2 blur_program_dim_;
+ Program blur_program_;
+ Program blur_program_h_;
+ Program blur_program_v_;
+ unsigned int passes_;
+ unsigned int radius_;
+ bool separable_;
+ bool draw_contents_;
+
+ static int use_count;
+ static RenderClearImage window_contents_;
+
+};
+
+/**
+ * A RenderObject that draws a drop shadow around the window.
+ */
+class RenderWindowShadow : public RenderObject
+{
+public:
+ using RenderObject::size;
+
+ RenderWindowShadow(unsigned int shadow_size, bool draw_contents = true) :
+ RenderObject(), shadow_size_(shadow_size), draw_contents_(draw_contents) {}
+
+ virtual void init()
+ {
+ RenderObject::init();
+
+ /*
+ * Only have one instance of the resources.
+ * This works only if all windows have the same size, which
+ * is currently the case for this scene. If this condition
+ * ceases to be true we will need to create the resources per
+ * object.
+ */
+ if (RenderWindowShadow::use_count == 0) {
+ shadow_h_.init();
+ shadow_v_.init();
+ shadow_corner_.init();
+ if (draw_contents_)
+ window_contents_.init();
+ }
+
+ RenderWindowShadow::use_count++;
+ }
+
+ virtual void release()
+ {
+ RenderWindowShadow::use_count--;
+
+ /* Only have one instance of the data */
+ if (RenderWindowShadow::use_count == 0) {
+ shadow_h_.release();
+ shadow_v_.release();
+ shadow_corner_.release();
+ if (draw_contents_)
+ window_contents_.release();
+ }
+
+ RenderObject::release();
+ }
+
+ virtual void size(const LibMatrix::vec2& size)
+ {
+ RenderObject::size(size);
+ shadow_h_.size(LibMatrix::vec2(size.x() - shadow_size_,
+ static_cast<double>(shadow_size_)));
+ shadow_v_.size(LibMatrix::vec2(size.y() - shadow_size_,
+ static_cast<double>(shadow_size_)));
+ shadow_corner_.size(LibMatrix::vec2(static_cast<double>(shadow_size_),
+ static_cast<double>(shadow_size_)));
+ if (draw_contents_)
+ window_contents_.size(size);
+ }
+
+ virtual void render_to(RenderObject& target)
+ {
+ glEnable(GL_BLEND);
+ /*
+ * Blend the colors normally, but don't change the
+ * destination alpha value.
+ */
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
+ GL_ZERO, GL_ONE);
+
+ /* Bottom shadow */
+ shadow_h_.rotation(0.0);
+ shadow_h_.position(position() +
+ LibMatrix::vec2(shadow_size_,
+ -shadow_h_.size().y()));
+ shadow_h_.render_to(target);
+
+ /* Right shadow */
+ shadow_v_.rotation(90.0);
+ shadow_v_.position(position() +
+ LibMatrix::vec2(size().x() + shadow_v_.size().y(), 0.0));
+ shadow_v_.render_to(target);
+
+ /* Bottom right shadow */
+ shadow_corner_.rotation(0.0);
+ shadow_corner_.position(position() +
+ LibMatrix::vec2(size().x(),
+ -shadow_corner_.size().y()));
+ shadow_corner_.render_to(target);
+
+ /* Top right shadow */
+ shadow_corner_.rotation(90.0);
+ shadow_corner_.position(position() + size() +
+ LibMatrix::vec2(shadow_corner_.size().x(),
+ -shadow_corner_.size().y()));
+ shadow_corner_.render_to(target);
+
+ /* Bottom left shadow */
+ shadow_corner_.rotation(-90.0);
+ shadow_corner_.position(position());
+ shadow_corner_.render_to(target);
+
+ /*
+ * Blend the window contents with the target texture.
+ */
+ if (draw_contents_) {
+ window_contents_.position(position());
+ window_contents_.render_to(target);
+ }
+
+ glDisable(GL_BLEND);
+ }
+
+private:
+ unsigned int shadow_size_;
+ bool draw_contents_;
+
+ static int use_count;
+ static RenderClearImage window_contents_;
+ static RenderClearImage shadow_h_;
+ static RenderClearImage shadow_v_;
+ static RenderClearImage shadow_corner_;
+
+};
+
+int RenderWindowBlur::use_count = 0;
+RenderClearImage RenderWindowBlur::window_contents_("desktop-window");
+int RenderWindowShadow::use_count = 0;
+RenderClearImage RenderWindowShadow::window_contents_("desktop-window");
+RenderClearImage RenderWindowShadow::shadow_h_("desktop-shadow");
+RenderClearImage RenderWindowShadow::shadow_v_("desktop-shadow");
+RenderClearImage RenderWindowShadow::shadow_corner_("desktop-shadow-corner");
+
+/*******************************
+ * SceneDesktop implementation *
+ *******************************/
+
+/**
+ * Private structure used to avoid contaminating scene.h with all of the
+ * SceneDesktop internal classes.
+ */
+struct SceneDesktopPrivate
+{
+ RenderScreen screen;
+ RenderClearImage desktop;
+ std::vector<RenderObject *> windows;
+
+ SceneDesktopPrivate(Canvas &canvas) :
+ screen(canvas), desktop("effect-2d") {}
+
+ ~SceneDesktopPrivate() { Util::dispose_pointer_vector(windows); }
+
+};
+
+
+SceneDesktop::SceneDesktop(Canvas &canvas) :
+ Scene(canvas, "desktop")
+{
+ priv_ = new SceneDesktopPrivate(canvas);
+ options_["effect"] = Scene::Option("effect", "blur", "The effect to use",
+ "blur,shadow");
+ options_["windows"] = Scene::Option("windows", "4",
+ "the number of windows");
+ options_["window-size"] = Scene::Option("window-size", "0.35",
+ "the window size as a percentage of the minimum screen dimension [0.0 - 0.5]");
+ options_["passes"] = Scene::Option("passes", "1",
+ "the number of effect passes (effect dependent)");
+ options_["blur-radius"] = Scene::Option("blur-radius", "5",
+ "the blur effect radius (in pixels)");
+ options_["separable"] = Scene::Option("separable", "true",
+ "use separable convolution for the blur effect",
+ "false,true");
+ options_["shadow-size"] = Scene::Option("shadow-size", "20",
+ "the size of the shadow (in pixels)");
+}
+
+SceneDesktop::~SceneDesktop()
+{
+ delete priv_;
+}
+
+bool
+SceneDesktop::load()
+{
+ return true;
+}
+
+void
+SceneDesktop::unload()
+{
+}
+
+bool
+SceneDesktop::setup()
+{
+ if (!Scene::setup())
+ return false;
+
+ /* Parse the options */
+ unsigned int windows(0);
+ unsigned int passes(0);
+ unsigned int blur_radius(0);
+ float window_size_factor(0.0);
+ unsigned int shadow_size(0);
+ bool separable(options_["separable"].value == "true");
+
+ windows = Util::fromString<unsigned int>(options_["windows"].value);
+ window_size_factor = Util::fromString<float>(options_["window-size"].value);
+ passes = Util::fromString<unsigned int>(options_["passes"].value);
+ blur_radius = Util::fromString<unsigned int>(options_["blur-radius"].value);
+ shadow_size = Util::fromString<unsigned int>(options_["shadow-size"].value);
+
+ // Make sure the Texture object knows where to find our images.
+ Texture::find_textures();
+
+ /* Ensure we get a transparent clear color for all following operations */
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+
+ /* Set up the screen and desktop RenderObjects */
+ priv_->screen.init();
+ priv_->desktop.init();
+ priv_->screen.size(LibMatrix::vec2(canvas_.width(), canvas_.height()));
+ priv_->desktop.size(LibMatrix::vec2(canvas_.width(), canvas_.height()));
+
+ /* Create the windows */
+ const float angular_step(2.0 * M_PI / windows);
+ unsigned int min_dimension = std::min(canvas_.width(), canvas_.height());
+ float window_size(min_dimension * window_size_factor);
+ static const LibMatrix::vec2 corner_offset(window_size / 2.0,
+ window_size / 2.0);
+
+ for (unsigned int i = 0; i < windows; i++) {
+ LibMatrix::vec2 center(canvas_.width() * (0.5 + 0.25 * cos(i * angular_step)),
+ canvas_.height() * (0.5 + 0.25 * sin(i * angular_step)));
+ RenderObject* win;
+ if (options_["effect"].value == "shadow")
+ win = new RenderWindowShadow(shadow_size);
+ else
+ win = new RenderWindowBlur(passes, blur_radius, separable);
+
+ win->init();
+ win->position(center - corner_offset);
+ win->size(LibMatrix::vec2(window_size, window_size));
+ /*
+ * Set the speed in increments of about 30 degrees (but not exactly,
+ * so we don't get windows moving just on the X axis or Y axis).
+ */
+ win->speed(LibMatrix::vec2(cos(0.1 + i * M_PI / 6.0) * canvas_.width() / 3,
+ sin(0.1 + i * M_PI / 6.0) * canvas_.height() / 3));
+ /*
+ * Perform a dummy rendering to ensure internal shaders are initialized
+ * now, in order not to affect the benchmarking.
+ */
+ win->render_to(priv_->desktop);
+ priv_->windows.push_back(win);
+ }
+
+ /*
+ * Ensure the screen is the current rendering target (it might have changed
+ * to a FBO in the previous steps).
+ */
+ priv_->screen.make_current();
+
+ currentFrame_ = 0;
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+void
+SceneDesktop::teardown()
+{
+ for (std::vector<RenderObject*>::iterator winIt = priv_->windows.begin();
+ winIt != priv_->windows.end();
+ winIt++)
+ {
+ RenderObject* curObj = *winIt;
+ curObj->release();
+ delete curObj;
+ }
+ priv_->windows.clear();
+ priv_->screen.make_current();
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+
+ priv_->desktop.release();
+ priv_->screen.release();
+
+ Scene::teardown();
+}
+
+void
+SceneDesktop::update()
+{
+ double current_time = Util::get_timestamp_us() / 1000000.0;
+ double dt = current_time - lastUpdateTime_;
+
+ Scene::update();
+
+ std::vector<RenderObject *>& windows(priv_->windows);
+
+ /*
+ * Move the windows around the screen, bouncing them back when
+ * they reach the edge.
+ */
+ for (std::vector<RenderObject *>::const_iterator iter = windows.begin();
+ iter != windows.end();
+ iter++)
+ {
+ bool should_update = true;
+ RenderObject *win = *iter;
+ LibMatrix::vec2 new_pos(
+ win->position().x() + win->speed().x() * dt,
+ win->position().y() + win->speed().y() * dt);
+
+ if (new_pos.x() < 0.0 ||
+ new_pos.x() + win->size().x() > static_cast<float>(canvas_.width()))
+ {
+ win->speed(LibMatrix::vec2(-win->speed().x(), win->speed().y()));
+ should_update = false;
+ }
+
+ if (new_pos.y() < 0.0 ||
+ new_pos.y() + win->size().y() > static_cast<float>(canvas_.height()))
+ {
+ win->speed(LibMatrix::vec2(win->speed().x(), -win->speed().y()));
+ should_update = false;
+ }
+
+ if (should_update)
+ win->position(new_pos);
+ }
+}
+
+void
+SceneDesktop::draw()
+{
+ std::vector<RenderObject *>& windows(priv_->windows);
+
+ /* Ensure we get a transparent clear color for all following operations */
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+
+ priv_->desktop.clear();
+
+ for (std::vector<RenderObject *>::const_iterator iter = windows.begin();
+ iter != windows.end();
+ iter++)
+ {
+ RenderObject *win = *iter;
+ win->render_to(priv_->desktop);
+ }
+
+ priv_->desktop.render_to(priv_->screen);
+
+}
+
+Scene::ValidationResult
+SceneDesktop::validate()
+{
+ static const double radius_3d(std::sqrt(3.0 * 2.0 * 2.0));
+
+ Canvas::Pixel ref;
+
+ /* Parse the options */
+ unsigned int windows(0);
+ unsigned int passes(0);
+ unsigned int blur_radius(0);
+ float window_size_factor(0.0);
+ unsigned int shadow_size(0);
+
+ windows = Util::fromString<unsigned int>(options_["windows"].value);
+ window_size_factor = Util::fromString<float>(options_["window-size"].value);
+ passes = Util::fromString<unsigned int>(options_["passes"].value);
+ blur_radius = Util::fromString<unsigned int>(options_["blur-radius"].value);
+ shadow_size = Util::fromString<unsigned int>(options_["shadow-size"].value);
+
+ if (options_["effect"].value == "blur")
+ {
+ if (windows == 4 && passes == 1 && blur_radius == 5)
+ ref = Canvas::Pixel(0x89, 0xa3, 0x53, 0xff);
+ else
+ return Scene::ValidationUnknown;
+ }
+ else if (options_["effect"].value == "shadow")
+ {
+ if (windows == 4 && fabs(window_size_factor - 0.35) < 0.0001 &&
+ shadow_size == 20)
+ {
+ ref = Canvas::Pixel(0x1f, 0x27, 0x0d, 0xff);
+ }
+ else
+ {
+ return Scene::ValidationUnknown;
+ }
+ }
+
+ Canvas::Pixel pixel = canvas_.read_pixel(512, 209);
+
+ double dist = pixel.distance_rgb(ref);
+ if (dist < radius_3d + 0.01) {
+ return Scene::ValidationSuccess;
+ }
+ else {
+ Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+ ref.to_le32(), pixel.to_le32(), dist);
+ return Scene::ValidationFailure;
+ }
+
+ return Scene::ValidationUnknown;
+}
diff --git a/src/scene-effect-2d.cpp b/src/scene-effect-2d.cpp
new file mode 100644
index 0000000..9185d7b
--- /dev/null
+++ b/src/scene-effect-2d.cpp
@@ -0,0 +1,444 @@
+/*
+ * Copyright © 2010-2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker (glmark2)
+ */
+#include <cmath>
+#include <climits>
+#include <numeric>
+
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "program.h"
+#include "shader-source.h"
+#include "util.h"
+#include "texture.h"
+
+SceneEffect2D::SceneEffect2D(Canvas &pCanvas) :
+ Scene(pCanvas, "effect2d")
+{
+ options_["kernel"] = Scene::Option("kernel",
+ "0,0,0;0,1,0;0,0,0",
+ "The convolution kernel matrix to use [format: \"a,b,c...;d,e,f...\"");;
+ options_["normalize"] = Scene::Option("normalize", "true",
+ "Whether to normalize the supplied convolution kernel matrix",
+ "false,true");
+}
+
+SceneEffect2D::~SceneEffect2D()
+{
+}
+
+/*
+ * Calculates the offset of the coefficient with index i
+ * from the center of the kernel matrix. Note that we are
+ * using the standard OpenGL texture coordinate system
+ * (x grows rightwards, y grows upwards).
+ */
+static LibMatrix::vec2
+calc_offset(unsigned int i, unsigned int width, unsigned int height)
+{
+ int x = i % width - (width - 1) / 2;
+ int y = -(i / width - (height - 1) / 2);
+
+ return LibMatrix::vec2(static_cast<float>(x),
+ static_cast<float>(y));
+
+}
+
+/**
+ * Creates a fragment shader implementing 2D image convolution.
+ *
+ * In the mathematical definition of 2D convolution, the kernel/filter (2D
+ * impulse response) is essentially mirrored in both directions (that is,
+ * rotated 180 degrees) when being applied on a 2D block of data (eg pixels).
+ *
+ * Most image manipulation programs, however, use the term kernel/filter to
+ * describe a 180 degree rotation of the 2D impulse response. This is more
+ * intuitive from a human understanding perspective because this rotated matrix
+ * can be regarded as a stencil that can be directly applied by just "placing"
+ * it on the image.
+ *
+ * In order to be compatible with image manipulation programs, we will
+ * use the same definition of kernel/filter (180 degree rotation of impulse
+ * response). This also means that we don't need to perform the (implicit)
+ * rotation of the kernel in our convolution implementation.
+ *
+ * @param canvas the destination Canvas for this shader
+ * @param array the array holding the filter coefficients in row-major
+ * order
+ * @param width the width of the filter
+ * @param width the height of the filter
+ *
+ * @return a string containing the frament source code
+ */
+static std::string
+create_convolution_fragment_shader(Canvas &canvas, std::vector<float> &array,
+ unsigned int width, unsigned int height)
+{
+ static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/effect-2d-convolution.frag");
+ ShaderSource source(frg_shader_filename);
+
+ if (width * height != array.size()) {
+ Log::error("Convolution filter size doesn't match supplied dimensions\n");
+ return "";
+ }
+
+ /* Steps are needed to be able to access nearby pixels */
+ source.add_const("TextureStepX", 1.0f/canvas.width());
+ source.add_const("TextureStepY", 1.0f/canvas.height());
+
+ std::stringstream ss_def;
+ std::stringstream ss_convolution;
+
+ /* Set up stringstream floating point options */
+ ss_def << std::fixed;
+ ss_convolution.precision(1);
+ ss_convolution << std::fixed;
+
+ ss_convolution << "result = ";
+
+ for(std::vector<float>::const_iterator iter = array.begin();
+ iter != array.end();
+ iter++)
+ {
+ unsigned int i = iter - array.begin();
+
+ /* Add Filter coefficient const definitions */
+ ss_def << "const float Kernel" << i << " = "
+ << *iter << ";" << std::endl;
+
+ /* Add convolution term using the current filter coefficient */
+ LibMatrix::vec2 offset(calc_offset(i, width, height));
+ ss_convolution << "texture2D(Texture0, TextureCoord + vec2("
+ << offset.x() << " * TextureStepX, "
+ << offset.y() << " * TextureStepY)) * Kernel" << i;
+ if (iter + 1 != array.end())
+ ss_convolution << " +" << std::endl;
+ }
+
+ ss_convolution << ";" << std::endl;
+
+ source.add(ss_def.str());
+ source.replace("$CONVOLUTION$", ss_convolution.str());
+
+ return source.str();
+}
+
+/**
+ * Creates a string containing a printout of a kernel matrix.
+ *
+ * @param filter the vector containing the filter coefficients
+ * @param width the width of the filter
+ *
+ * @return the printout
+ */
+static std::string
+kernel_printout(const std::vector<float> &kernel,
+ unsigned int width)
+{
+ std::stringstream ss;
+ ss << std::fixed;
+
+ for (std::vector<float>::const_iterator iter = kernel.begin();
+ iter != kernel.end();
+ iter++)
+ {
+ ss << *iter << " ";
+ if ((iter - kernel.begin()) % width == width - 1)
+ ss << std::endl;
+ }
+
+ return ss.str();
+}
+
+/**
+ * Parses a string representation of a matrix and returns it
+ * in row-major format.
+ *
+ * In the string representation, elements are delimited using
+ * commas (',') and rows are delimited using semi-colons (';').
+ * eg 0,0,0;0,1.0,0;0,0,0
+ *
+ * @param str the matrix string representation to parse
+ * @param matrix the float vector to populate
+ * @param[out] width the width of the matrix
+ * @param[out] height the height of the matrix
+ *
+ * @return whether parsing succeeded
+ */
+static bool
+parse_matrix(const std::string &str, std::vector<float> &matrix,
+ unsigned int &width, unsigned int &height)
+{
+ std::vector<std::string> rows;
+ unsigned int w = UINT_MAX;
+
+ Util::split(str, ';', rows, Util::SplitModeNormal);
+
+ Log::debug("Parsing kernel matrix:\n");
+ static const std::string format("%f ");
+ static const std::string format_cont(Log::continuation_prefix + format);
+ static const std::string newline(Log::continuation_prefix + "\n");
+
+ for (std::vector<std::string>::const_iterator iter = rows.begin();
+ iter != rows.end();
+ iter++)
+ {
+ std::vector<std::string> elems;
+ Util::split(*iter, ',', elems, Util::SplitModeNormal);
+
+ if (w != UINT_MAX && elems.size() != w) {
+ Log::error("Matrix row %u contains %u elements, whereas previous"
+ " rows had %u\n",
+ iter - rows.begin(), elems.size(), w);
+ return false;
+ }
+
+ w = elems.size();
+
+ for (std::vector<std::string>::const_iterator iter_el = elems.begin();
+ iter_el != elems.end();
+ iter_el++)
+ {
+ float f(Util::fromString<float>(*iter_el));
+ matrix.push_back(f);
+ if (iter_el == elems.begin())
+ Log::debug(format.c_str(), f);
+ else
+ Log::debug(format_cont.c_str(), f);
+ }
+
+ Log::debug(newline.c_str());
+ }
+
+ width = w;
+ height = rows.size();
+
+ return true;
+}
+
+/**
+ * Normalizes a convolution kernel matrix.
+ *
+ * @param filter the filter to normalize
+ */
+static void
+normalize(std::vector<float> &kernel)
+{
+ float sum = std::accumulate(kernel.begin(), kernel.end(), 0.0);
+
+ /*
+ * If sum is essentially zero, perform a zero-sum normalization.
+ * This normalizes positive and negative values separately,
+ */
+ if (fabs(sum) < 0.00000001) {
+ sum = 0.0;
+ for (std::vector<float>::iterator iter = kernel.begin();
+ iter != kernel.end();
+ iter++)
+ {
+ if (*iter > 0.0)
+ sum += *iter;
+ }
+ }
+
+ /*
+ * We can simply compare with 0.0f here, because we just care about
+ * avoiding division-by-zero.
+ */
+ if (sum == 0.0)
+ return;
+
+ for (std::vector<float>::iterator iter = kernel.begin();
+ iter != kernel.end();
+ iter++)
+ {
+ *iter /= sum;
+ }
+
+}
+
+bool
+SceneEffect2D::load()
+{
+ Texture::load("effect-2d", &texture_,
+ GL_NEAREST, GL_NEAREST, 0);
+ running_ = false;
+
+ return true;
+}
+
+void
+SceneEffect2D::unload()
+{
+ glDeleteTextures(1, &texture_);
+}
+
+bool
+SceneEffect2D::setup()
+{
+ if (!Scene::setup())
+ return false;
+
+ Texture::find_textures();
+
+ static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/effect-2d.vert");
+
+ std::vector<float> kernel;
+ unsigned int kernel_width = 0;
+ unsigned int kernel_height = 0;
+
+ /* Parse the kernel matrix from the options */
+ if (!parse_matrix(options_["kernel"].value, kernel,
+ kernel_width, kernel_height))
+ {
+ return false;
+ }
+
+ /* Normalize the kernel matrix if needed */
+ if (options_["normalize"].value == "true") {
+ normalize(kernel);
+ Log::debug("Normalized kernel matrix:\n%s",
+ kernel_printout(kernel, kernel_width).c_str());
+ }
+
+ /* Create and load the shaders */
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source;
+ frg_source.append(create_convolution_fragment_shader(canvas_, kernel,
+ kernel_width,
+ kernel_height));
+
+ if (frg_source.str().empty())
+ return false;
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return false;
+ }
+
+ std::vector<int> vertex_format;
+ vertex_format.push_back(3);
+ mesh_.set_vertex_format(vertex_format);
+
+ mesh_.make_grid(1, 1, 2.0, 2.0, 0.0);
+ mesh_.build_vbo();
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ program_.start();
+
+ // Load texture sampler value
+ program_["Texture0"] = 0;
+
+ currentFrame_ = 0;
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+void
+SceneEffect2D::teardown()
+{
+ mesh_.reset();
+
+ program_.stop();
+ program_.release();
+
+ Scene::teardown();
+}
+
+void
+SceneEffect2D::update()
+{
+ Scene::update();
+}
+
+void
+SceneEffect2D::draw()
+{
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_);
+
+ mesh_.render_vbo();
+}
+
+Scene::ValidationResult
+SceneEffect2D::validate()
+{
+ static const double radius_3d(std::sqrt(3.0));
+
+ std::vector<float> kernel;
+ std::vector<float> kernel_edge;
+ std::vector<float> kernel_blur;
+ unsigned int kernel_width = 0;
+ unsigned int kernel_height = 0;
+
+ if (!parse_matrix("0,1,0;1,-4,1;0,1,0;", kernel_edge,
+ kernel_width, kernel_height))
+ {
+ return Scene::ValidationUnknown;
+ }
+
+ if (!parse_matrix("1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;",
+ kernel_blur,
+ kernel_width, kernel_height))
+ {
+ return Scene::ValidationUnknown;
+ }
+
+ if (!parse_matrix(options_["kernel"].value, kernel,
+ kernel_width, kernel_height))
+ {
+ return Scene::ValidationUnknown;
+ }
+
+ Canvas::Pixel ref;
+
+ if (kernel == kernel_edge)
+ ref = Canvas::Pixel(0x17, 0x0c, 0x2f, 0xff);
+ else if (kernel == kernel_blur)
+ ref = Canvas::Pixel(0xc7, 0xe1, 0x8d, 0xff);
+ else
+ return Scene::ValidationUnknown;
+
+ Canvas::Pixel pixel = canvas_.read_pixel(452, 237);
+
+ double dist = pixel.distance_rgb(ref);
+ if (dist < radius_3d + 0.01) {
+ return Scene::ValidationSuccess;
+ }
+ else {
+ Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+ ref.to_le32(), pixel.to_le32(), dist);
+ return Scene::ValidationFailure;
+ }
+
+ return Scene::ValidationUnknown;
+}
diff --git a/src/scene-function.cpp b/src/scene-function.cpp
new file mode 100644
index 0000000..0bd9468
--- /dev/null
+++ b/src/scene-function.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#include <cmath>
+
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "shader-source.h"
+#include "util.h"
+
+static const std::string shader_file_base(GLMARK_DATA_PATH"/shaders/function");
+
+static const std::string vtx_file(shader_file_base + ".vert");
+static const std::string frg_file(shader_file_base + ".frag");
+static const std::string call_file(shader_file_base + "-call.all");
+static const std::string step_low_file(shader_file_base + "-step-low.all");
+static const std::string step_medium_file(shader_file_base + "-step-medium.all");
+
+SceneFunction::SceneFunction(Canvas &pCanvas) :
+ SceneGrid(pCanvas, "function")
+{
+ options_["fragment-steps"] = Scene::Option("fragment-steps", "1",
+ "The number of computational steps in the fragment shader");
+ options_["fragment-function"] = Scene::Option("fragment-function", "true",
+ "Whether each computational step includes a function call", "false,true");
+ options_["vertex-steps"] = Scene::Option("vertex-steps", "1",
+ "The number of computational steps in the vertex shader");
+ options_["vertex-function"] = Scene::Option("vertex-function", "true",
+ "Whether each computational step includes an if-else clause", "false,true");
+ options_["vertex-complexity"] = Scene::Option("vertex-complexity", "low",
+ "The complexity of each computational step in the vertex shader", "low,medium");
+ options_["fragment-complexity"] = Scene::Option("fragment-complexity", "low",
+ "The complexity of each computational step in the fragment shader", "low,medium");
+}
+
+SceneFunction::~SceneFunction()
+{
+}
+
+static std::string
+get_vertex_shader_source(int steps, bool function, std::string &complexity)
+{
+ ShaderSource source(vtx_file);
+ ShaderSource source_main;
+ std::string step_file;
+
+ if (complexity == "low")
+ step_file = step_low_file;
+ else if (complexity == "medium")
+ step_file = step_medium_file;
+
+ for (int i = 0; i < steps; i++) {
+ if (function)
+ source_main.append_file(call_file);
+ else
+ source_main.append_file(step_file);
+ }
+
+ if (function)
+ source.replace_with_file("$PROCESS$", step_file);
+ else
+ source.replace("$PROCESS$", "");
+
+ source.replace("$MAIN$", source_main.str());
+
+ return source.str();
+}
+
+static std::string
+get_fragment_shader_source(int steps, bool function, std::string &complexity)
+{
+ ShaderSource source(frg_file);
+ ShaderSource source_main;
+ std::string step_file;
+
+ if (complexity == "low")
+ step_file = step_low_file;
+ else if (complexity == "medium")
+ step_file = step_medium_file;
+
+ for (int i = 0; i < steps; i++) {
+ if (function)
+ source_main.append_file(call_file);
+ else
+ source_main.append_file(step_file);
+ }
+
+ if (function)
+ source.replace_with_file("$PROCESS$", step_file);
+ else
+ source.replace("$PROCESS$", "");
+
+ source.replace("$MAIN$", source_main.str());
+
+ return source.str();
+}
+
+bool
+SceneFunction::setup()
+{
+ if (!SceneGrid::setup())
+ return false;
+
+ /* Parse options */
+ bool vtx_function = options_["vertex-function"].value == "true";
+ bool frg_function = options_["fragment-function"].value == "true";
+ std::string vtx_complexity = options_["vertex-complexity"].value;
+ std::string frg_complexity = options_["fragment-complexity"].value;
+ int vtx_steps = Util::fromString<int>(options_["vertex-steps"].value);
+ int frg_steps = Util::fromString<int>(options_["fragment-steps"].value);
+
+ /* Load shaders */
+ std::string vtx_shader(get_vertex_shader_source(vtx_steps, vtx_function,
+ vtx_complexity));
+ std::string frg_shader(get_fragment_shader_source(frg_steps, frg_function,
+ frg_complexity));
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_shader, frg_shader))
+ return false;
+
+ program_.start();
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+Scene::ValidationResult
+SceneFunction::validate()
+{
+ static const double radius_3d(std::sqrt(3.0 * 15.0 * 15.0));
+
+ int frg_steps = Util::fromString<int>(options_["fragment-steps"].value);
+
+ Canvas::Pixel ref;
+
+ if (frg_steps == 5)
+ ref = Canvas::Pixel(0x5e, 0x5e, 0x5e, 0xff);
+ else
+ return Scene::ValidationUnknown;
+
+ Canvas::Pixel pixel = canvas_.read_pixel(293, 89);
+
+ double dist = pixel.distance_rgb(ref);
+ if (dist < radius_3d + 0.01) {
+ return Scene::ValidationSuccess;
+ }
+ else {
+ Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+ ref.to_le32(), pixel.to_le32(), dist);
+ return Scene::ValidationFailure;
+ }
+
+ return Scene::ValidationUnknown;
+}
diff --git a/src/scene-grid.cpp b/src/scene-grid.cpp
new file mode 100644
index 0000000..a9d07e0
--- /dev/null
+++ b/src/scene-grid.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "util.h"
+
+SceneGrid::SceneGrid(Canvas &pCanvas, const std::string &name) :
+ Scene(pCanvas, name)
+{
+ options_["grid-size"] = Scene::Option("grid-size", "32",
+ "The number of squares per side of the grid (controls the number of vertices)");
+ options_["grid-length"] = Scene::Option("grid-length", "5.0",
+ "The length of each side of the grid (normalized) (controls the area drawn to)");
+}
+
+SceneGrid::~SceneGrid()
+{
+}
+
+bool
+SceneGrid::load()
+{
+ rotationSpeed_ = 36.0f;
+ running_ = false;
+
+ return true;
+}
+
+void
+SceneGrid::unload()
+{
+}
+
+bool
+SceneGrid::setup()
+{
+ if (!Scene::setup())
+ return false;
+
+ int grid_size(Util::fromString<int>(options_["grid-size"].value));
+ double grid_length(Util::fromString<double>(options_["grid-length"].value));
+
+ /* Create and configure the grid mesh */
+ std::vector<int> vertex_format;
+ vertex_format.push_back(3);
+ mesh_.set_vertex_format(vertex_format);
+
+ /*
+ * The spacing needed in order for the area of the requested grid
+ * to be the same as the area of a grid with size 32 and spacing 0.02.
+ */
+ double spacing = grid_length * (1 - 4.38 / 5.0) / (grid_size - 1.0);
+
+ mesh_.make_grid(grid_size, grid_size, grid_length, grid_length,
+ grid_size > 1 ? spacing : 0);
+ mesh_.build_vbo();
+
+ currentFrame_ = 0;
+ rotation_ = 0.0f;
+
+ return true;
+}
+
+void
+SceneGrid::teardown()
+{
+ program_.stop();
+ program_.release();
+ mesh_.reset();
+
+ Scene::teardown();
+}
+
+void
+SceneGrid::update()
+{
+ Scene::update();
+
+ double elapsed_time = lastUpdateTime_ - startTime_;
+
+ rotation_ = rotationSpeed_ * elapsed_time;
+}
+
+void
+SceneGrid::draw()
+{
+ // Load the ModelViewProjectionMatrix uniform in the shader
+ LibMatrix::Stack4 model_view;
+ LibMatrix::mat4 model_view_proj(canvas_.projection());
+
+ model_view.translate(0.0f, 0.0f, -5.0f);
+ model_view.rotate(rotation_, 0.0f, 0.0f, 1.0f);
+ model_view_proj *= model_view.getCurrent();
+
+ program_["ModelViewProjectionMatrix"] = model_view_proj;
+
+ mesh_.render_vbo();
+}
+
+Scene::ValidationResult
+SceneGrid::validate()
+{
+ return Scene::ValidationUnknown;
+}
diff --git a/src/scene-ideas.cpp b/src/scene-ideas.cpp
new file mode 100644
index 0000000..af716bd
--- /dev/null
+++ b/src/scene-ideas.cpp
@@ -0,0 +1,414 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "scene.h"
+#include "stack.h"
+#include "splines.h"
+#include "table.h"
+#include "logo.h"
+#include "lamp.h"
+#include "util.h"
+#include "log.h"
+#include <sys/time.h>
+
+using LibMatrix::Stack4;
+using LibMatrix::mat4;
+using LibMatrix::vec3;
+using LibMatrix::vec4;
+using LibMatrix::uvec3;
+using std::string;
+using std::map;
+
+class SceneIdeasPrivate
+{
+public:
+ SceneIdeasPrivate() :
+ valid_(false),
+ currentSpeed_(1.0), // Real time.
+ currentTime_(START_TIME_),
+ timeOffset_(START_TIME_)
+ {
+ startTime_.tv_sec = 0;
+ startTime_.tv_usec = 0;
+ }
+ ~SceneIdeasPrivate()
+ {
+ }
+ void initialize(map<string, Scene::Option>& options);
+ void reset_time();
+ void update_time();
+ void update_projection(const mat4& proj);
+ void draw();
+ bool valid() { return valid_; }
+
+private:
+ void postIdle();
+ void initLights();
+ bool valid_;
+ Stack4 projection_;
+ Stack4 modelview_;
+ float currentSpeed_;
+ float currentTime_;
+ float timeOffset_;
+ struct timeval startTime_;
+ static const float CYCLE_TIME_;
+ static const float TIME_;
+ static const float START_TIME_;
+ // Table
+ Table table_;
+ // Logo
+ SGILogo logo_;
+ // Lamp
+ Lamp lamp_;
+ // Light constants
+ static const vec4 light0_position_;
+ static const vec4 light1_position_;
+ static const vec4 light2_position_;
+ // Object constants
+ ViewFromSpline viewFromSpline_;
+ ViewToSpline viewToSpline_;
+ LightPositionSpline lightPosSpline_;
+ LogoPositionSpline logoPosSpline_;
+ LogoRotationSpline logoRotSpline_;
+ vec3 viewFrom_;
+ vec3 viewTo_;
+ vec3 lightPos_;
+ vec3 logoPos_;
+ vec3 logoRot_;
+ vec4 lightPositions_[3];
+};
+
+const float SceneIdeasPrivate::TIME_(15.0);
+const float SceneIdeasPrivate::CYCLE_TIME_(TIME_ * 1.0 - 3.0);
+const float SceneIdeasPrivate::START_TIME_(0.6);
+const vec4 SceneIdeasPrivate::light0_position_(0.0, 1.0, 0.0, 0.0);
+const vec4 SceneIdeasPrivate::light1_position_(-1.0, 0.0, 0.0, 0.0);
+const vec4 SceneIdeasPrivate::light2_position_(0.0, -1.0, 0.0, 0.0);
+
+void
+SceneIdeasPrivate::initLights()
+{
+ const mat4& curMV(modelview_.getCurrent());
+ lightPositions_[0] = curMV * light0_position_;
+ lightPositions_[1] = curMV * light1_position_;
+ lightPositions_[2] = curMV * light2_position_;
+}
+
+void
+SceneIdeasPrivate::initialize(map<string, Scene::Option>& options)
+{
+ // Initialize the positions for the lights we'll use.
+ initLights();
+
+ // Tell the objects in the scene to initialize themselves.
+ table_.init();
+ if (!table_.valid())
+ {
+ Log::debug("SceneIdeas: table object not properly initialized!\n");
+ return;
+ }
+ logo_.init();
+ if (!logo_.valid())
+ {
+ Log::debug("SceneIdeas: logo object not properly initialized!\n");
+ return;
+ }
+ lamp_.init();
+ if (!lamp_.valid())
+ {
+ Log::debug("SceneIdeas: lamp object not properly initialized!\n");
+ return;
+ }
+
+ reset_time();
+
+ // If the option string tells us the user wants the speed to be a function
+ // of the scene duration, do it. Otherwise, take the value explicitly.
+ static const string durationLabel("duration");
+ static const string speedLabel("speed");
+ if (options[speedLabel].value == durationLabel)
+ {
+ float duration = Util::fromString<float>(options[durationLabel].value);
+ currentSpeed_ = (CYCLE_TIME_ - START_TIME_) / duration;
+ }
+ else
+ {
+ currentSpeed_ = Util::fromString<float>(options[speedLabel].value);
+ }
+
+ // If we're here, we're okay to run.
+ valid_ = true;
+}
+
+void
+SceneIdeasPrivate::reset_time()
+{
+ timeOffset_ = START_TIME_;
+ gettimeofday(&startTime_, NULL);
+}
+
+void
+SceneIdeasPrivate::update_time()
+{
+ // Compute new time
+ struct timeval current = {0, 0};
+ gettimeofday(&current, NULL);
+ float timediff = (current.tv_sec - startTime_.tv_sec) +
+ static_cast<double>(current.tv_usec - startTime_.tv_usec) / 1000000.0;
+ float sceneTime = timediff * currentSpeed_ + timeOffset_;
+
+ // Keep the current time in [START_TIME_..CYCLE_TIME_)
+ // Every other cycle starting with 0 start at the beginning and goes
+ // forward in time. Other cycles start at the end and go backwards.
+ currentTime_ = std::fmod(sceneTime, CYCLE_TIME_);
+ unsigned int cycle = sceneTime/CYCLE_TIME_;
+ if (cycle % 2)
+ {
+ currentTime_ = CYCLE_TIME_ - currentTime_;
+ }
+}
+
+void
+SceneIdeasPrivate::update_projection(const mat4& proj)
+{
+ // Projection hasn't changed since last frame.
+ if (projection_.getCurrent() == proj)
+ {
+ return;
+ }
+
+ projection_.loadIdentity();
+ projection_ *= proj;
+}
+
+SceneIdeas::SceneIdeas(Canvas& canvas) :
+ Scene(canvas, "ideas"), priv_(0)
+{
+ options_["speed"] = Scene::Option("speed", "duration",
+ "Time coefficient (1.0 is \"wall clock\" speed, <1.0 is slower, >1.0 is faster). A special value of \"duration\" computes this as a function of the \"duration\" option");
+}
+
+SceneIdeas::~SceneIdeas()
+{
+ delete priv_;
+}
+
+bool
+SceneIdeas::load()
+{
+ running_ = false;
+ return true;
+}
+
+void
+SceneIdeas::unload()
+{
+}
+
+bool
+SceneIdeas::setup()
+{
+ if (!Scene::setup())
+ return false;
+
+ priv_ = new SceneIdeasPrivate();
+ priv_->initialize(options_);
+ if (!priv_->valid())
+ return false;
+
+ priv_->update_projection(canvas_.projection());
+
+ // Core Scene state
+ currentFrame_ = 0;
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+void
+SceneIdeas::update()
+{
+ Scene::update();
+ priv_->update_time();
+ priv_->update_projection(canvas_.projection());
+}
+
+void
+SceneIdeasPrivate::draw()
+{
+ viewFromSpline_.getCurrentVec(currentTime_, viewFrom_);
+ viewToSpline_.getCurrentVec(currentTime_, viewTo_);
+ lightPosSpline_.getCurrentVec(currentTime_, lightPos_);
+ logoPosSpline_.getCurrentVec(currentTime_, logoPos_);
+ logoRotSpline_.getCurrentVec(currentTime_, logoRot_);
+
+ // Tell the logo its new position
+ logo_.setPosition(logoPos_);
+
+ vec4 lp4(lightPos_.x(), lightPos_.y(), lightPos_.z(), 0.0);
+
+ //
+ // SHADOW
+ //
+ modelview_.loadIdentity();
+ modelview_.lookAt(viewFrom_.x(), viewFrom_.y(), viewFrom_.z(),
+ viewTo_.x(), viewTo_.y(), viewTo_.z(),
+ 0.0, 1.0, 0.0);
+
+ float pca(0.0);
+ if (viewFrom_.y() > 0.0)
+ {
+ table_.draw(modelview_, projection_, lightPos_, logoPos_, currentTime_, pca);
+ }
+
+ glEnable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+
+ if (logoPos_.y() < 0.0)
+ {
+ // Set the color assuming we're still under the table.
+ uvec3 flatColor(128 / 2, 102 / 2, 179 / 2);
+ if (logoPos_.y() > -0.33)
+ {
+ // We're emerging from the table
+ float c(1.0 - logoPos_.y() / -0.33);
+ pca /= 4.0;
+ flatColor.x(static_cast<unsigned int>(128.0 * (1.0 - c) * 0.5 + 255.0 * pca * c));
+ flatColor.y(static_cast<unsigned int>(102.0 * (1.0 - c) * 0.5 + 255.0 * pca * c));
+ flatColor.z(static_cast<unsigned int>(179.0 * (1.0 - c) * 0.5 + 200.0 * pca * c));
+ }
+
+ modelview_.push();
+ modelview_.scale(0.04, 0.0, 0.04);
+ modelview_.rotate(-90.0, 1.0, 0.0, 0.0);
+ modelview_.rotate(0.1 * static_cast<int>(10.0 * logoRot_.z()), 0.0, 0.0, 1.0);
+ modelview_.rotate(0.1 * static_cast<int>(10.0 * logoRot_.y()), 0.0, 1.0, 0.0);
+ modelview_.rotate(0.1 * static_cast<int>(10.0 * logoRot_.x()), 1.0, 0.0, 0.0);
+ modelview_.rotate(0.1 * 353, 1.0, 0.0, 0.0);
+ modelview_.rotate(0.1 * 450, 0.0, 1.0, 0.0);
+
+ logo_.draw(modelview_, projection_, lightPositions_[0], SGILogo::LOGO_FLAT, flatColor);
+
+ modelview_.pop();
+ }
+
+ if (logoPos_.y() > 0.0)
+ {
+ modelview_.push();
+ modelview_.translate(lightPos_.x(), lightPos_.y(), lightPos_.z());
+ mat4 tv;
+ tv[3][1] = -1.0;
+ tv[3][3] = 0.0;
+ tv[0][0] = tv[1][1] = tv[2][2] = lightPos_.y();
+ modelview_ *= tv;
+ modelview_.translate(-lightPos_.x() + logoPos_.x(),
+ -lightPos_.y() + logoPos_.y(),
+ -lightPos_.z() + logoPos_.z());
+ modelview_.scale(0.04, 0.04, 0.04);
+ modelview_.rotate(-90.0, 1.0, 0.0, 0.0);
+ modelview_.rotate(0.1 * static_cast<int>(10.0 * logoRot_.z()), 0.0, 0.0, 1.0);
+ modelview_.rotate(0.1 * static_cast<int>(10.0 * logoRot_.y()), 0.0, 1.0, 0.0);
+ modelview_.rotate(0.1 * static_cast<int>(10.0 * logoRot_.x()), 1.0, 0.0, 0.0);
+ modelview_.rotate(35.3, 1.0, 0.0, 0.0);
+ modelview_.rotate(45.0, 0.0, 1.0, 0.0);
+
+ logo_.draw(modelview_, projection_, lightPositions_[0], SGILogo::LOGO_SHADOW);
+
+ modelview_.pop();
+ }
+ //
+ // DONE SHADOW
+ //
+
+ glEnable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+
+ modelview_.loadIdentity();
+ modelview_.lookAt(viewFrom_.x(), viewFrom_.y(), viewFrom_.z(),
+ viewTo_.x(), viewTo_.y(), viewTo_.z(),
+ 0.0, 1.0, 0.0);
+ modelview_.push();
+ modelview_.translate(lightPos_.x(), lightPos_.y(), lightPos_.z());
+ modelview_.scale(0.1, 0.1, 0.1);
+ float x(lightPos_.x() - logoPos_.x());
+ float y(lightPos_.y() - logoPos_.y());
+ float z(lightPos_.z() - logoPos_.z());
+ double a3(0.0);
+ if (x != 0.0)
+ {
+ a3 = -atan2(z, x) * 10.0 * 180.0 / M_PI;
+ }
+ double a4(-atan2(sqrt(x * x + z * z), y) * 10.0 * 180.0 / M_PI);
+ modelview_.rotate(0.1 * static_cast<int>(a3), 0.0, 1.0, 0.0);
+ modelview_.rotate(0.1 * static_cast<int>(a4), 0.0, 0.0, 1.0);
+ modelview_.rotate(-90.0, 1.0, 0.0, 0.0);
+
+ lamp_.draw(modelview_, projection_, lightPositions_);
+
+ modelview_.pop();
+
+ lightPositions_[0] = modelview_.getCurrent() * lp4;
+
+ if (logoPos_.y() > -0.33)
+ {
+ modelview_.push();
+ modelview_.translate(logoPos_.x(), logoPos_.y(), logoPos_.z());
+ modelview_.scale(0.04, 0.04, 0.04);
+ modelview_.rotate(-90.0, 1.0, 0.0, 0.0);
+ modelview_.rotate(0.1 * static_cast<int>(10.0 * logoRot_.z()), 0.0, 0.0, 1.0);
+ modelview_.rotate(0.1 * static_cast<int>(10.0 * logoRot_.y()), 0.0, 1.0, 0.0);
+ modelview_.rotate(0.1 * static_cast<int>(10.0 * logoRot_.x()), 1.0, 0.0, 0.0);
+ modelview_.rotate(35.3, 1.0, 0.0, 0.0);
+ modelview_.rotate(45.0, 0.0, 1.0, 0.0);
+
+ logo_.draw(modelview_, projection_, lightPositions_[0], SGILogo::LOGO_NORMAL);
+
+ modelview_.pop();
+ }
+
+ if (viewFrom_.y() < 0.0)
+ {
+ table_.drawUnder(modelview_, projection_);
+ }
+}
+
+void
+SceneIdeas::draw()
+{
+ priv_->draw();
+}
+
+Scene::ValidationResult
+SceneIdeas::validate()
+{
+ return Scene::ValidationUnknown;
+}
+
+void
+SceneIdeas::teardown()
+{
+ delete priv_;
+ priv_ = 0;
+ Scene::teardown();
+}
diff --git a/src/scene-ideas/a.cc b/src/scene-ideas/a.cc
new file mode 100644
index 0000000..6a0ab15
--- /dev/null
+++ b/src/scene-ideas/a.cc
@@ -0,0 +1,179 @@
+/*
+ * Vertex position data describing the letter 'a'
+ *
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "characters.h"
+
+using LibMatrix::vec2;
+
+LetterA::LetterA()
+{
+ // Vertex data...
+ vertexData_.push_back(vec2(5.618949, 10.261048));
+ vertexData_.push_back(vec2(5.322348, 9.438848));
+ vertexData_.push_back(vec2(5.124614, 10.030832));
+ vertexData_.push_back(vec2(4.860968, 9.488181));
+ vertexData_.push_back(vec2(4.811534, 9.932169));
+ vertexData_.push_back(vec2(3.938208, 9.438848));
+ vertexData_.push_back(vec2(3.658084, 9.685509));
+ vertexData_.push_back(vec2(2.784758, 8.994862));
+ vertexData_.push_back(vec2(2.801236, 9.175745));
+ vertexData_.push_back(vec2(1.960865, 8.172662));
+ vertexData_.push_back(vec2(1.186406, 7.761562));
+ vertexData_.push_back(vec2(1.252317, 6.561151));
+ vertexData_.push_back(vec2(0.576725, 6.610483));
+ vertexData_.push_back(vec2(0.939238, 5.525180));
+ vertexData_.push_back(vec2(0.164779, 4.883864));
+ vertexData_.push_back(vec2(0.840371, 4.818089));
+ vertexData_.push_back(vec2(0.230690, 3.963001));
+ vertexData_.push_back(vec2(0.939238, 4.242549));
+ vertexData_.push_back(vec2(0.609681, 3.255909));
+ vertexData_.push_back(vec2(1.268795, 3.963001));
+ vertexData_.push_back(vec2(1.021627, 3.075026));
+ vertexData_.push_back(vec2(1.861998, 4.045221));
+ vertexData_.push_back(vec2(1.829042, 3.535457));
+ vertexData_.push_back(vec2(2.817714, 4.818089));
+ vertexData_.push_back(vec2(3.163749, 4.998972));
+ vertexData_.push_back(vec2(3.971164, 6.643371));
+ vertexData_.push_back(vec2(4.267765, 6.725591));
+ vertexData_.push_back(vec2(4.663234, 7.630010));
+ vertexData_.push_back(vec2(5.404737, 9.734840));
+ vertexData_.push_back(vec2(4.646756, 9.669065));
+ vertexData_.push_back(vec2(5.108136, 8.731757));
+ vertexData_.push_back(vec2(4.679712, 8.600205));
+ vertexData_.push_back(vec2(4.926879, 7.564234));
+ vertexData_.push_back(vec2(4.366632, 6.692703));
+ vertexData_.push_back(vec2(4.663234, 5.344296));
+ vertexData_.push_back(vec2(3.888774, 4.850976));
+ vertexData_.push_back(vec2(4.630278, 4.094553));
+ vertexData_.push_back(vec2(3.954686, 3.963001));
+ vertexData_.push_back(vec2(4.828012, 3.798561));
+ vertexData_.push_back(vec2(4.168898, 3.321686));
+ vertexData_.push_back(vec2(5.157569, 3.864337));
+ vertexData_.push_back(vec2(4.514933, 3.091470));
+ vertexData_.push_back(vec2(5.553038, 4.045221));
+ vertexData_.push_back(vec2(5.305870, 3.634121));
+ vertexData_.push_back(vec2(5.932029, 4.176773));
+
+ // Index data...
+ indexData_.push_back(0);
+ indexData_.push_back(1);
+ indexData_.push_back(2);
+ indexData_.push_back(3);
+ indexData_.push_back(4);
+ indexData_.push_back(5);
+ indexData_.push_back(6);
+ indexData_.push_back(7);
+ indexData_.push_back(8);
+ indexData_.push_back(9);
+ indexData_.push_back(10);
+ indexData_.push_back(11);
+ indexData_.push_back(12);
+ indexData_.push_back(13);
+ indexData_.push_back(14);
+ indexData_.push_back(15);
+ indexData_.push_back(16);
+ indexData_.push_back(17);
+ indexData_.push_back(18);
+ indexData_.push_back(19);
+ indexData_.push_back(20);
+ indexData_.push_back(21);
+ indexData_.push_back(22);
+ indexData_.push_back(23);
+ indexData_.push_back(24);
+ indexData_.push_back(25);
+ indexData_.push_back(26);
+ indexData_.push_back(27);
+ indexData_.push_back(28);
+ indexData_.push_back(29);
+ indexData_.push_back(30);
+ indexData_.push_back(31);
+ indexData_.push_back(32);
+ indexData_.push_back(33);
+ indexData_.push_back(34);
+ indexData_.push_back(35);
+ indexData_.push_back(36);
+ indexData_.push_back(37);
+ indexData_.push_back(38);
+ indexData_.push_back(39);
+ indexData_.push_back(40);
+ indexData_.push_back(41);
+ indexData_.push_back(42);
+ indexData_.push_back(43);
+ indexData_.push_back(44);
+ indexData_.push_back(0);
+ indexData_.push_back(2);
+ indexData_.push_back(4);
+ indexData_.push_back(6);
+ indexData_.push_back(8);
+ indexData_.push_back(10);
+ indexData_.push_back(12);
+ indexData_.push_back(14);
+ indexData_.push_back(16);
+ indexData_.push_back(18);
+ indexData_.push_back(20);
+ indexData_.push_back(22);
+ indexData_.push_back(24);
+ indexData_.push_back(26);
+ indexData_.push_back(27);
+ indexData_.push_back(25);
+ indexData_.push_back(23);
+ indexData_.push_back(21);
+ indexData_.push_back(19);
+ indexData_.push_back(17);
+ indexData_.push_back(15);
+ indexData_.push_back(13);
+ indexData_.push_back(11);
+ indexData_.push_back(9);
+ indexData_.push_back(7);
+ indexData_.push_back(5);
+ indexData_.push_back(3);
+ indexData_.push_back(1);
+ indexData_.push_back(28);
+ indexData_.push_back(30);
+ indexData_.push_back(32);
+ indexData_.push_back(34);
+ indexData_.push_back(36);
+ indexData_.push_back(38);
+ indexData_.push_back(40);
+ indexData_.push_back(42);
+ indexData_.push_back(44);
+ indexData_.push_back(43);
+ indexData_.push_back(41);
+ indexData_.push_back(39);
+ indexData_.push_back(37);
+ indexData_.push_back(35);
+ indexData_.push_back(33);
+ indexData_.push_back(31);
+ indexData_.push_back(29);
+
+ // Primitive state so that the draw call can issue the primitives we want.
+ unsigned int curOffset(0);
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 28, curOffset));
+ curOffset += (28 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 17, curOffset));
+ curOffset += (17 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 28, curOffset));
+ curOffset += (28 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 17, curOffset));
+}
diff --git a/src/scene-ideas/characters.h b/src/scene-ideas/characters.h
new file mode 100644
index 0000000..ea56c57
--- /dev/null
+++ b/src/scene-ideas/characters.h
@@ -0,0 +1,157 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#ifndef CHARACTERS_H_
+#define CHARACTERS_H_
+
+#include <vector>
+#include "vec.h"
+#include "gl-headers.h"
+
+class PrimitiveState
+{
+public:
+ PrimitiveState(unsigned int type, unsigned int count, unsigned int offset) :
+ type_(type),
+ count_(count),
+ bufferOffset_(offset) {}
+ ~PrimitiveState() {}
+ void issue() const
+ {
+ glDrawElements(type_, count_, GL_UNSIGNED_SHORT,
+ reinterpret_cast<const GLvoid*>(bufferOffset_));
+ }
+private:
+ PrimitiveState();
+ unsigned int type_; // Primitive type (e.g. GL_TRIANGLE_STRIP)
+ unsigned int count_; // Number of primitives
+ unsigned int bufferOffset_; // Offset into the element array buffer
+};
+
+struct Character
+{
+ void draw()
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]);
+ glVertexAttribPointer(vertexIndex_, 2, GL_FLOAT, GL_FALSE, 0, 0);
+ glEnableVertexAttribArray(vertexIndex_);
+ for (std::vector<PrimitiveState>::const_iterator primIt = primVec_.begin();
+ primIt != primVec_.end();
+ primIt++)
+ {
+ primIt->issue();
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ }
+ void init(int vertexAttribIndex)
+ {
+ vertexIndex_ = vertexAttribIndex;
+
+ // We need 2 buffers for our work here. One for the vertex data.
+ // and one for the index data.
+ glGenBuffers(2, &bufferObjects_[0]);
+
+ // First, setup the vertex data by binding the first buffer object,
+ // allocating its data store, and filling it in with our vertex data.
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]);
+ glBufferData(GL_ARRAY_BUFFER, vertexData_.size() * sizeof(LibMatrix::vec2),
+ &vertexData_.front(), GL_STATIC_DRAW);
+
+ // Finally, setup the pointer to our vertex data and enable this
+ // attribute array.
+ glVertexAttribPointer(vertexIndex_, 2, GL_FLOAT, GL_FALSE, 0, 0);
+ glEnableVertexAttribArray(vertexIndex_);
+
+ // Now repeat for our index data.
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+ indexData_.size() * sizeof(unsigned short), &indexData_.front(),
+ GL_STATIC_DRAW);
+
+ // Unbind our vertex buffer objects so that their state isn't affected
+ // by other objects.
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ }
+ ~Character()
+ {
+ glDeleteBuffers(2, &bufferObjects_[0]);
+ }
+ Character() :
+ vertexIndex_(0),
+ vertexArray_(0) {}
+ unsigned int bufferObjects_[2];
+ std::vector<LibMatrix::vec2> vertexData_;
+ std::vector<unsigned short> indexData_;
+ int vertexIndex_;
+ unsigned int vertexArray_;
+ std::vector<PrimitiveState> primVec_;
+};
+
+struct LetterI : Character
+{
+ LetterI();
+};
+
+struct LetterD : Character
+{
+ LetterD();
+};
+
+struct LetterE : Character
+{
+ LetterE();
+};
+
+struct LetterA : Character
+{
+ LetterA();
+};
+
+struct LetterS : Character
+{
+ LetterS();
+};
+
+struct LetterN : Character
+{
+ LetterN();
+};
+
+struct LetterM : Character
+{
+ LetterM();
+};
+
+struct LetterO : Character
+{
+ LetterO();
+};
+
+struct LetterT : Character
+{
+ LetterT();
+};
+
+#endif // CHARACTERS_H_
diff --git a/src/scene-ideas/d.cc b/src/scene-ideas/d.cc
new file mode 100644
index 0000000..0d8f7d7
--- /dev/null
+++ b/src/scene-ideas/d.cc
@@ -0,0 +1,142 @@
+/*
+ * Vertex position data describing the letter 'd'
+ *
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "characters.h"
+
+using LibMatrix::vec2;
+
+LetterD::LetterD()
+{
+ // Vertex data...
+ vertexData_.push_back(vec2(4.714579, 9.987679));
+ vertexData_.push_back(vec2(2.841889, 9.429158));
+ vertexData_.push_back(vec2(2.825462, 9.166325));
+ vertexData_.push_back(vec2(1.856263, 8.722793));
+ vertexData_.push_back(vec2(2.004107, 8.000000));
+ vertexData_.push_back(vec2(0.969199, 7.605750));
+ vertexData_.push_back(vec2(1.494866, 6.636550));
+ vertexData_.push_back(vec2(0.607803, 6.028748));
+ vertexData_.push_back(vec2(1.527721, 4.960986));
+ vertexData_.push_back(vec2(0.772074, 4.254620));
+ vertexData_.push_back(vec2(1.774127, 4.139630));
+ vertexData_.push_back(vec2(1.445585, 3.186858));
+ vertexData_.push_back(vec2(2.266940, 3.843942));
+ vertexData_.push_back(vec2(2.250513, 3.022587));
+ vertexData_.push_back(vec2(2.776181, 3.843942));
+ vertexData_.push_back(vec2(3.137577, 3.383984));
+ vertexData_.push_back(vec2(3.351129, 4.008214));
+ vertexData_.push_back(vec2(3.909651, 4.451746));
+ vertexData_.push_back(vec2(4.090349, 4.960986));
+ vertexData_.push_back(vec2(4.862423, 5.946612));
+ vertexData_.push_back(vec2(4.763860, 6.652977));
+ vertexData_.push_back(vec2(5.388090, 7.572895));
+ vertexData_.push_back(vec2(4.862423, 8.492813));
+ vertexData_.push_back(vec2(5.618070, 9.921971));
+ vertexData_.push_back(vec2(4.698152, 10.940452));
+ vertexData_.push_back(vec2(5.338809, 12.303902));
+ vertexData_.push_back(vec2(4.238193, 12.960985));
+ vertexData_.push_back(vec2(4.451746, 14.554415));
+ vertexData_.push_back(vec2(3.581109, 14.291581));
+ vertexData_.push_back(vec2(3.613963, 15.342916));
+ vertexData_.push_back(vec2(2.677618, 15.145790));
+ vertexData_.push_back(vec2(2.480493, 15.540041));
+ vertexData_.push_back(vec2(2.036961, 15.211499));
+ vertexData_.push_back(vec2(1.281314, 15.112936));
+
+ // Index data...
+ indexData_.push_back(0);
+ indexData_.push_back(1);
+ indexData_.push_back(2);
+ indexData_.push_back(3);
+ indexData_.push_back(4);
+ indexData_.push_back(5);
+ indexData_.push_back(6);
+ indexData_.push_back(7);
+ indexData_.push_back(8);
+ indexData_.push_back(9);
+ indexData_.push_back(10);
+ indexData_.push_back(11);
+ indexData_.push_back(12);
+ indexData_.push_back(13);
+ indexData_.push_back(14);
+ indexData_.push_back(15);
+ indexData_.push_back(16);
+ indexData_.push_back(17);
+ indexData_.push_back(18);
+ indexData_.push_back(19);
+ indexData_.push_back(20);
+ indexData_.push_back(21);
+ indexData_.push_back(22);
+ indexData_.push_back(23);
+ indexData_.push_back(24);
+ indexData_.push_back(25);
+ indexData_.push_back(26);
+ indexData_.push_back(27);
+ indexData_.push_back(28);
+ indexData_.push_back(29);
+ indexData_.push_back(30);
+ indexData_.push_back(31);
+ indexData_.push_back(32);
+ indexData_.push_back(33);
+ indexData_.push_back(0);
+ indexData_.push_back(2);
+ indexData_.push_back(4);
+ indexData_.push_back(6);
+ indexData_.push_back(8);
+ indexData_.push_back(10);
+ indexData_.push_back(12);
+ indexData_.push_back(14);
+ indexData_.push_back(16);
+ indexData_.push_back(18);
+ indexData_.push_back(20);
+ indexData_.push_back(22);
+ indexData_.push_back(24);
+ indexData_.push_back(26);
+ indexData_.push_back(28);
+ indexData_.push_back(30);
+ indexData_.push_back(32);
+ indexData_.push_back(33);
+ indexData_.push_back(31);
+ indexData_.push_back(29);
+ indexData_.push_back(27);
+ indexData_.push_back(25);
+ indexData_.push_back(23);
+ indexData_.push_back(21);
+ indexData_.push_back(19);
+ indexData_.push_back(17);
+ indexData_.push_back(15);
+ indexData_.push_back(13);
+ indexData_.push_back(11);
+ indexData_.push_back(9);
+ indexData_.push_back(7);
+ indexData_.push_back(5);
+ indexData_.push_back(3);
+ indexData_.push_back(1);
+
+ // Primitive state so that the draw call can issue the primitives we want.
+ unsigned int curOffset(0);
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 34, curOffset));
+ curOffset += (34 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 34, curOffset));
+}
diff --git a/src/scene-ideas/e.cc b/src/scene-ideas/e.cc
new file mode 100644
index 0000000..2330468
--- /dev/null
+++ b/src/scene-ideas/e.cc
@@ -0,0 +1,139 @@
+/*
+ * Vertex position data describing the letter 'e'
+ *
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "characters.h"
+
+using LibMatrix::vec2;
+
+LetterE::LetterE()
+{
+ // Vertex data...
+ vertexData_.push_back(vec2(1.095436, 6.190871));
+ vertexData_.push_back(vec2(2.107884, 6.970954));
+ vertexData_.push_back(vec2(2.556017, 7.020747));
+ vertexData_.push_back(vec2(3.020747, 7.867220));
+ vertexData_.push_back(vec2(3.518672, 8.033195));
+ vertexData_.push_back(vec2(3.269710, 8.531120));
+ vertexData_.push_back(vec2(4.165975, 8.929461));
+ vertexData_.push_back(vec2(3.302905, 9.062241));
+ vertexData_.push_back(vec2(4.331950, 9.626556));
+ vertexData_.push_back(vec2(3.286307, 9.344398));
+ vertexData_.push_back(vec2(4.116183, 9.958507));
+ vertexData_.push_back(vec2(3.004149, 9.510373));
+ vertexData_.push_back(vec2(3.518672, 9.991701));
+ vertexData_.push_back(vec2(2.705394, 9.493776));
+ vertexData_.push_back(vec2(2.091286, 9.311203));
+ vertexData_.push_back(vec2(2.041494, 9.062241));
+ vertexData_.push_back(vec2(1.178423, 8.514523));
+ vertexData_.push_back(vec2(1.443983, 8.165976));
+ vertexData_.push_back(vec2(0.481328, 7.535270));
+ vertexData_.push_back(vec2(1.045643, 6.904564));
+ vertexData_.push_back(vec2(0.149378, 6.091286));
+ vertexData_.push_back(vec2(1.095436, 5.410789));
+ vertexData_.push_back(vec2(0.464730, 4.232365));
+ vertexData_.push_back(vec2(1.377593, 4.497925));
+ vertexData_.push_back(vec2(1.261411, 3.136930));
+ vertexData_.push_back(vec2(1.925311, 3.950207));
+ vertexData_.push_back(vec2(2.240664, 3.037344));
+ vertexData_.push_back(vec2(2.589212, 3.834025));
+ vertexData_.push_back(vec2(3.087137, 3.269710));
+ vertexData_.push_back(vec2(3.236515, 3.867220));
+ vertexData_.push_back(vec2(3.684647, 3.867220));
+ vertexData_.push_back(vec2(3.867220, 4.448133));
+ vertexData_.push_back(vec2(4.398340, 5.128631));
+
+ // Index data...
+ indexData_.push_back(0);
+ indexData_.push_back(1);
+ indexData_.push_back(2);
+ indexData_.push_back(3);
+ indexData_.push_back(4);
+ indexData_.push_back(5);
+ indexData_.push_back(6);
+ indexData_.push_back(7);
+ indexData_.push_back(8);
+ indexData_.push_back(9);
+ indexData_.push_back(10);
+ indexData_.push_back(11);
+ indexData_.push_back(12);
+ indexData_.push_back(13);
+ indexData_.push_back(14);
+ indexData_.push_back(15);
+ indexData_.push_back(16);
+ indexData_.push_back(17);
+ indexData_.push_back(18);
+ indexData_.push_back(19);
+ indexData_.push_back(20);
+ indexData_.push_back(21);
+ indexData_.push_back(22);
+ indexData_.push_back(23);
+ indexData_.push_back(24);
+ indexData_.push_back(25);
+ indexData_.push_back(26);
+ indexData_.push_back(27);
+ indexData_.push_back(28);
+ indexData_.push_back(29);
+ indexData_.push_back(30);
+ indexData_.push_back(31);
+ indexData_.push_back(32);
+ indexData_.push_back(0);
+ indexData_.push_back(2);
+ indexData_.push_back(4);
+ indexData_.push_back(6);
+ indexData_.push_back(8);
+ indexData_.push_back(10);
+ indexData_.push_back(12);
+ indexData_.push_back(14);
+ indexData_.push_back(16);
+ indexData_.push_back(18);
+ indexData_.push_back(20);
+ indexData_.push_back(22);
+ indexData_.push_back(24);
+ indexData_.push_back(26);
+ indexData_.push_back(28);
+ indexData_.push_back(30);
+ indexData_.push_back(32);
+ indexData_.push_back(31);
+ indexData_.push_back(29);
+ indexData_.push_back(27);
+ indexData_.push_back(25);
+ indexData_.push_back(23);
+ indexData_.push_back(21);
+ indexData_.push_back(19);
+ indexData_.push_back(17);
+ indexData_.push_back(15);
+ indexData_.push_back(13);
+ indexData_.push_back(11);
+ indexData_.push_back(9);
+ indexData_.push_back(7);
+ indexData_.push_back(5);
+ indexData_.push_back(3);
+ indexData_.push_back(1);
+
+ // Primitive state so that the draw call can issue the primitives we want.
+ unsigned int curOffset(0);
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 33, curOffset));
+ curOffset += (33 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 33, curOffset));
+}
diff --git a/src/scene-ideas/i.cc b/src/scene-ideas/i.cc
new file mode 100644
index 0000000..25e8a1e
--- /dev/null
+++ b/src/scene-ideas/i.cc
@@ -0,0 +1,116 @@
+/*
+ * Vertex position data describing the letter 'i'
+ *
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "characters.h"
+
+using LibMatrix::vec2;
+
+LetterI::LetterI()
+{
+ // Vertex data...
+ vertexData_.push_back(vec2(0.548767, 9.414791));
+ vertexData_.push_back(vec2(2.795284, 9.757771));
+ vertexData_.push_back(vec2(1.457663, 9.311897));
+ vertexData_.push_back(vec2(2.503751, 9.157557));
+ vertexData_.push_back(vec2(1.714898, 8.986067));
+ vertexData_.push_back(vec2(2.109325, 7.785638));
+ vertexData_.push_back(vec2(1.286174, 7.013934));
+ vertexData_.push_back(vec2(1.800643, 6.070740));
+ vertexData_.push_back(vec2(0.994641, 5.161843));
+ vertexData_.push_back(vec2(1.783494, 4.767417));
+ vertexData_.push_back(vec2(0.943194, 4.167202));
+ vertexData_.push_back(vec2(1.852090, 4.304394));
+ vertexData_.push_back(vec2(1.063237, 3.549839));
+ vertexData_.push_back(vec2(2.023580, 3.978564));
+ vertexData_.push_back(vec2(1.406217, 3.172562));
+ vertexData_.push_back(vec2(2.315113, 3.875670));
+ vertexData_.push_back(vec2(2.006431, 3.018221));
+ vertexData_.push_back(vec2(2.812433, 3.944266));
+ vertexData_.push_back(vec2(2.726688, 3.429796));
+ vertexData_.push_back(vec2(3.258307, 4.132905));
+ vertexData_.push_back(vec2(1.989282, 10.923902));
+ vertexData_.push_back(vec2(2.778135, 12.295820));
+ vertexData_.push_back(vec2(2.966774, 11.678456));
+ vertexData_.push_back(vec2(3.687031, 12.947481));
+
+ // Index data...
+ indexData_.push_back(0);
+ indexData_.push_back(1);
+ indexData_.push_back(2);
+ indexData_.push_back(3);
+ indexData_.push_back(4);
+ indexData_.push_back(5);
+ indexData_.push_back(6);
+ indexData_.push_back(7);
+ indexData_.push_back(8);
+ indexData_.push_back(9);
+ indexData_.push_back(10);
+ indexData_.push_back(11);
+ indexData_.push_back(12);
+ indexData_.push_back(13);
+ indexData_.push_back(14);
+ indexData_.push_back(15);
+ indexData_.push_back(16);
+ indexData_.push_back(17);
+ indexData_.push_back(18);
+ indexData_.push_back(19);
+ indexData_.push_back(20);
+ indexData_.push_back(21);
+ indexData_.push_back(22);
+ indexData_.push_back(23);
+ indexData_.push_back(0);
+ indexData_.push_back(2);
+ indexData_.push_back(4);
+ indexData_.push_back(6);
+ indexData_.push_back(8);
+ indexData_.push_back(10);
+ indexData_.push_back(12);
+ indexData_.push_back(14);
+ indexData_.push_back(16);
+ indexData_.push_back(18);
+ indexData_.push_back(19);
+ indexData_.push_back(17);
+ indexData_.push_back(15);
+ indexData_.push_back(13);
+ indexData_.push_back(11);
+ indexData_.push_back(9);
+ indexData_.push_back(7);
+ indexData_.push_back(5);
+ indexData_.push_back(3);
+ indexData_.push_back(1);
+ indexData_.push_back(20);
+ indexData_.push_back(22);
+ indexData_.push_back(23);
+ indexData_.push_back(21);
+
+ // Primitive state so that the draw call can issue the primitives we want.
+ unsigned int curOffset(0);
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 20, curOffset));
+ curOffset += (20 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 4, curOffset));
+ curOffset += (4 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 20, curOffset));
+ curOffset += (20 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 4, curOffset));
+}
diff --git a/src/scene-ideas/lamp.cc b/src/scene-ideas/lamp.cc
new file mode 100644
index 0000000..aaf3b10
--- /dev/null
+++ b/src/scene-ideas/lamp.cc
@@ -0,0 +1,258 @@
+/*
+ * Vertex position data describing the lamp
+ *
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "lamp.h"
+#include "shader-source.h"
+#include "log.h"
+#include "scene.h"
+
+using std::string;
+using LibMatrix::vec3;
+using LibMatrix::vec4;
+using LibMatrix::Stack4;
+
+const string Lamp::modelviewName_("modelview");
+const string Lamp::projectionName_("projection");
+const string Lamp::light0PositionName_("light0Position");
+const string Lamp::light1PositionName_("light1Position");
+const string Lamp::light2PositionName_("light2Position");
+const string Lamp::vertexAttribName_("vertex");
+const string Lamp::normalAttribName_("normal");
+const string Lamp::normalMatrixName_("normalMatrix");
+
+Lamp::Lamp() :
+ valid_(false)
+{
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ vertexData_.push_back(vec3(0.438371, 0.000000, 0.898794));
+ vertexData_.push_back(vec3(0.379641, 0.219186, 0.898794));
+ vertexData_.push_back(vec3(0.219186, 0.379641, 0.898794));
+ vertexData_.push_back(vec3(0.000000, 0.438371, 0.898794));
+ vertexData_.push_back(vec3(-0.219186, 0.379641, 0.898794));
+ vertexData_.push_back(vec3(-0.379641, 0.219186, 0.898794));
+ vertexData_.push_back(vec3(-0.438371, 0.000000, 0.898794));
+ vertexData_.push_back(vec3(-0.379641, -0.219186, 0.898794));
+ vertexData_.push_back(vec3(-0.219186, -0.379641, 0.898794));
+ vertexData_.push_back(vec3(0.000000, -0.438371, 0.898794));
+ vertexData_.push_back(vec3(0.219186, -0.379641, 0.898794));
+ vertexData_.push_back(vec3(0.379641, -0.219186, 0.898794));
+ vertexData_.push_back(vec3(0.438371, 0.000000, 0.898794));
+ vertexData_.push_back(vec3(0.788011, 0.000000, 0.615662));
+ vertexData_.push_back(vec3(0.682437, 0.394005, 0.615662));
+ vertexData_.push_back(vec3(0.394005, 0.682437, 0.615662));
+ vertexData_.push_back(vec3(0.000000, 0.788011, 0.615662));
+ vertexData_.push_back(vec3(-0.394005, 0.682437, 0.615662));
+ vertexData_.push_back(vec3(-0.682437, 0.394005, 0.615662));
+ vertexData_.push_back(vec3(-0.788011, 0.000000, 0.615662));
+ vertexData_.push_back(vec3(-0.682437, -0.394005, 0.615662));
+ vertexData_.push_back(vec3(-0.394005, -0.682437, 0.615662));
+ vertexData_.push_back(vec3(0.000000, -0.788011, 0.615662));
+ vertexData_.push_back(vec3(0.394005, -0.682437, 0.615662));
+ vertexData_.push_back(vec3(0.682437, -0.394005, 0.615662));
+ vertexData_.push_back(vec3(0.788011, 0.000000, 0.615662));
+ vertexData_.push_back(vec3(0.978148, 0.000000, 0.207912));
+ vertexData_.push_back(vec3(0.847101, 0.489074, 0.207912));
+ vertexData_.push_back(vec3(0.489074, 0.847101, 0.207912));
+ vertexData_.push_back(vec3(0.000000, 0.978148, 0.207912));
+ vertexData_.push_back(vec3(-0.489074, 0.847101, 0.207912));
+ vertexData_.push_back(vec3(-0.847101, 0.489074, 0.207912));
+ vertexData_.push_back(vec3(-0.978148, 0.000000, 0.207912));
+ vertexData_.push_back(vec3(-0.847101, -0.489074, 0.207912));
+ vertexData_.push_back(vec3(-0.489074, -0.847101, 0.207912));
+ vertexData_.push_back(vec3(0.000000, -0.978148, 0.207912));
+ vertexData_.push_back(vec3(0.489074, -0.847101, 0.207912));
+ vertexData_.push_back(vec3(0.847101, -0.489074, 0.207912));
+ vertexData_.push_back(vec3(0.978148, 0.000000, 0.207912));
+ vertexData_.push_back(vec3(0.970296, 0.000000, -0.241922));
+ vertexData_.push_back(vec3(0.840301, 0.485148, -0.241922));
+ vertexData_.push_back(vec3(0.485148, 0.840301, -0.241922));
+ vertexData_.push_back(vec3(0.000000, 0.970296, -0.241922));
+ vertexData_.push_back(vec3(-0.485148, 0.840301, -0.241922));
+ vertexData_.push_back(vec3(-0.840301, 0.485148, -0.241922));
+ vertexData_.push_back(vec3(-0.970296, 0.000000, -0.241922));
+ vertexData_.push_back(vec3(-0.840301, -0.485148, -0.241922));
+ vertexData_.push_back(vec3(-0.485148, -0.840301, -0.241922));
+ vertexData_.push_back(vec3(0.000000, -0.970296, -0.241922));
+ vertexData_.push_back(vec3(0.485148, -0.840301, -0.241922));
+ vertexData_.push_back(vec3(0.840301, -0.485148, -0.241922));
+ vertexData_.push_back(vec3(0.970296, 0.000000, -0.241922));
+ vertexData_.push_back(vec3(0.766044, 0.000000, -0.642788));
+ vertexData_.push_back(vec3(0.663414, 0.383022, -0.642788));
+ vertexData_.push_back(vec3(0.383022, 0.663414, -0.642788));
+ vertexData_.push_back(vec3(0.000000, 0.766044, -0.642788));
+ vertexData_.push_back(vec3(-0.383022, 0.663414, -0.642788));
+ vertexData_.push_back(vec3(-0.663414, 0.383022, -0.642788));
+ vertexData_.push_back(vec3(-0.766044, 0.000000, -0.642788));
+ vertexData_.push_back(vec3(-0.663414, -0.383022, -0.642788));
+ vertexData_.push_back(vec3(-0.383022, -0.663414, -0.642788));
+ vertexData_.push_back(vec3(0.000000, -0.766044, -0.642788));
+ vertexData_.push_back(vec3(0.383022, -0.663414, -0.642788));
+ vertexData_.push_back(vec3(0.663414, -0.383022, -0.642788));
+ vertexData_.push_back(vec3(0.766044, 0.000000, -0.642788));
+
+ //
+ // The original implementation of both the logo and the lamp represented
+ // the vertex and normal data in a triply-dimensioned array of floats and
+ // all of the calls referenced double-indexed arrays of vector data.
+ // To my mind, this made the code look clunky and overly verbose.
+ // Representing the data as a STL vector of vec3 (itself a 3-float vector
+ // quantity) provides both an efficient container and allows for more
+ // concise looking code. The slightly goofy loops (using the original 2
+ // dimensional indices to compute a single offset into the STL vector) are
+ // a compromise to avoid rearranging the original data.
+ //
+ // - jesse 2010/10/04
+ //
+ for (unsigned int i = 0; i < 5; i++)
+ {
+ for (unsigned int j = 0; j < 13; j++)
+ {
+ indexData_.push_back(i * 13 + j);
+ indexData_.push_back((i + 1) * 13 + j);
+ }
+ }
+ unsigned int curIndex(5 * 13);
+ for (unsigned int i = 0; i < 12; i++)
+ {
+ indexData_.push_back(curIndex + i);
+ }
+}
+
+Lamp::~Lamp()
+{
+ if (valid_)
+ {
+ glDeleteBuffers(2, &bufferObjects_[0]);
+ }
+}
+
+void
+Lamp::init()
+{
+ // Make sure we don't re-initialize...
+ if (valid_)
+ {
+ return;
+ }
+
+ // Initialize shader sources from input files and create programs from them
+ // The program for handling lighting...
+ string lit_vtx_filename(GLMARK_DATA_PATH"/shaders/ideas-lamp-lit.vert");
+ string lit_frg_filename(GLMARK_DATA_PATH"/shaders/ideas-lamp-lit.frag");
+ ShaderSource lit_vtx_source(lit_vtx_filename);
+ ShaderSource lit_frg_source(lit_frg_filename);
+ if (!Scene::load_shaders_from_strings(litProgram_, lit_vtx_source.str(),
+ lit_frg_source.str()))
+ {
+ Log::error("No valid program for lit lamp rendering\n");
+ return;
+ }
+
+ // The simple program with no lighting...
+ string unlit_vtx_filename(GLMARK_DATA_PATH"/shaders/ideas-lamp-unlit.vert");
+ string unlit_frg_filename(GLMARK_DATA_PATH"/shaders/ideas-lamp-unlit.frag");
+ ShaderSource unlit_vtx_source(unlit_vtx_filename);
+ ShaderSource unlit_frg_source(unlit_frg_filename);
+ if (!Scene::load_shaders_from_strings(unlitProgram_, unlit_vtx_source.str(),
+ unlit_frg_source.str()))
+ {
+ Log::error("No valid program for unlit lamp rendering.\n");
+ return;
+ }
+
+ // We need 2 buffers for our work here. One for the vertex data.
+ // and one for the index data.
+ glGenBuffers(2, &bufferObjects_[0]);
+
+ // First, setup the vertex data by binding the first buffer object,
+ // allocating its data store, and filling it in with our vertex data.
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]);
+ glBufferData(GL_ARRAY_BUFFER, vertexData_.size() * sizeof(vec3), &vertexData_.front(), GL_STATIC_DRAW);
+
+ // Now repeat for our index data.
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexData_.size() * sizeof(unsigned short), &indexData_.front(), GL_STATIC_DRAW);
+
+ // We're ready to go.
+ valid_ = true;
+}
+
+void
+Lamp::draw(Stack4& modelview, Stack4& projection, const vec4* lightPositions)
+{
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]);
+
+ litProgram_.start();
+ int vertexIndex(litProgram_[vertexAttribName_].location());
+ int normalIndex(litProgram_[normalAttribName_].location());
+ glVertexAttribPointer(vertexIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
+ glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
+ glEnableVertexAttribArray(vertexIndex);
+ glEnableVertexAttribArray(normalIndex);
+ const LibMatrix::mat4& mv = modelview.getCurrent();
+ LibMatrix::mat3 normalMatrix(mv[0][0], mv[1][0], mv[2][0],
+ mv[0][1], mv[1][1], mv[2][1],
+ mv[0][2], mv[1][2], mv[2][2]);
+ normalMatrix.transpose().inverse();
+ litProgram_[normalMatrixName_] = normalMatrix;
+ litProgram_[modelviewName_] = mv;
+ litProgram_[projectionName_] = projection.getCurrent();
+ litProgram_[light0PositionName_] = lightPositions[0];
+ litProgram_[light1PositionName_] = lightPositions[1];
+ litProgram_[light2PositionName_] = lightPositions[2];
+ static const unsigned int sus(sizeof(unsigned short));
+ for (unsigned int i = 0; i < 5; i++)
+ {
+ glDrawElements(GL_TRIANGLE_STRIP, 26, GL_UNSIGNED_SHORT, reinterpret_cast<const GLvoid*>(i * 26 * sus));
+ }
+ glDisableVertexAttribArray(normalIndex);
+ glDisableVertexAttribArray(vertexIndex);
+ litProgram_.stop();
+
+ unlitProgram_.start();
+ vertexIndex = unlitProgram_[vertexAttribName_].location();
+ glVertexAttribPointer(vertexIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
+ glEnableVertexAttribArray(vertexIndex);
+ unlitProgram_[modelviewName_] = mv;
+ unlitProgram_[projectionName_] = projection.getCurrent();
+ glDrawElements(GL_TRIANGLE_FAN, 12, GL_UNSIGNED_SHORT, reinterpret_cast<const GLvoid*>(5 * 26 * sus));
+ glDisableVertexAttribArray(vertexIndex);
+ unlitProgram_.stop();
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+}
diff --git a/src/scene-ideas/lamp.h b/src/scene-ideas/lamp.h
new file mode 100644
index 0000000..7253942
--- /dev/null
+++ b/src/scene-ideas/lamp.h
@@ -0,0 +1,64 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#ifndef LAMP_H_
+#define LAMP_H_
+
+#include <string>
+#include <vector>
+#include "vec.h"
+#include "stack.h"
+#include "gl-headers.h"
+#include "program.h"
+
+class Lamp
+{
+public:
+ Lamp();
+ ~Lamp();
+
+ void init();
+ bool valid() const { return valid_; }
+ void draw(LibMatrix::Stack4& modelview, LibMatrix::Stack4& projection,
+ const LibMatrix::vec4* lightPositions);
+private:
+ Program litProgram_;
+ Program unlitProgram_;
+ std::string litVertexShader_;
+ std::string litFragmentShader_;
+ std::string unlitVertexShader_;
+ std::string unlitFragmentShader_;
+ static const std::string modelviewName_;
+ static const std::string projectionName_;
+ static const std::string light0PositionName_;
+ static const std::string light1PositionName_;
+ static const std::string light2PositionName_;
+ static const std::string vertexAttribName_;
+ static const std::string normalAttribName_;
+ static const std::string normalMatrixName_;
+ std::vector<LibMatrix::vec3> vertexData_;
+ std::vector<unsigned short> indexData_;
+ unsigned int bufferObjects_[2];
+ bool valid_;
+};
+
+#endif // LAMP_H_
diff --git a/src/scene-ideas/logo.cc b/src/scene-ideas/logo.cc
new file mode 100644
index 0000000..59158ce
--- /dev/null
+++ b/src/scene-ideas/logo.cc
@@ -0,0 +1,788 @@
+/*
+ * Vertex position data describing the old Silicon Graphics logo
+ *
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "logo.h"
+#include "scene.h"
+#include "shader-source.h"
+#include "log.h"
+
+using std::string;
+using LibMatrix::vec3;
+using LibMatrix::uvec3;
+using LibMatrix::vec4;
+using LibMatrix::Stack4;
+using LibMatrix::mat4;
+
+const unsigned int SGILogo::textureResolution_(32);
+const string SGILogo::modelviewName_("modelview");
+const string SGILogo::projectionName_("projection");
+const string SGILogo::lightPositionName_("light0Position");
+const string SGILogo::logoColorName_("logoColor");
+const string SGILogo::vertexAttribName_("vertex");
+const string SGILogo::normalAttribName_("normal");
+const string SGILogo::normalMatrixName_("normalMatrix");
+
+SGILogo::SGILogo(void) :
+ normalNormalIndex_(0),
+ normalVertexIndex_(0),
+ flatVertexIndex_(0),
+ shadowVertexIndex_(0),
+ vertexIndex_(0),
+ valid_(false),
+ drawStyle_(LOGO_NORMAL)
+{
+ // Single cylinder data...
+ singleCylinderVertices_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ singleCylinderVertices_.push_back(vec3(1.000000, 0.000000, 5.000000));
+ singleCylinderVertices_.push_back(vec3(0.707107, 0.707107, 0.000000));
+ singleCylinderVertices_.push_back(vec3(0.707107, 0.707107, 5.000000));
+ singleCylinderVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ singleCylinderVertices_.push_back(vec3(0.000000, 1.000000, 5.000000));
+ singleCylinderVertices_.push_back(vec3(-0.707107, 0.707107, 0.000000));
+ singleCylinderVertices_.push_back(vec3(-0.707107, 0.707107, 5.000000));
+ singleCylinderVertices_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ singleCylinderVertices_.push_back(vec3(-1.000000, 0.000000, 5.000000));
+ singleCylinderVertices_.push_back(vec3(-0.707107, -0.707107, 0.000000));
+ singleCylinderVertices_.push_back(vec3(-0.707107, -0.707107, 5.000000));
+ singleCylinderVertices_.push_back(vec3(0.000000, -1.000000, 0.000000));
+ singleCylinderVertices_.push_back(vec3(0.000000, -1.000000, 5.000000));
+ singleCylinderVertices_.push_back(vec3(0.707107, -0.707107, 0.000000));
+ singleCylinderVertices_.push_back(vec3(0.707107, -0.707107, 5.000000));
+ singleCylinderVertices_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ singleCylinderVertices_.push_back(vec3(1.000000, 0.000000, 5.000000));
+
+ singleCylinderNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ singleCylinderNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ singleCylinderNormals_.push_back(vec3(0.707107, 0.707107, 0.000000));
+ singleCylinderNormals_.push_back(vec3(0.707107, 0.707107, 0.000000));
+ singleCylinderNormals_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ singleCylinderNormals_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ singleCylinderNormals_.push_back(vec3(-0.707107, 0.707107, 0.000000));
+ singleCylinderNormals_.push_back(vec3(-0.707107, 0.707107, 0.000000));
+ singleCylinderNormals_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ singleCylinderNormals_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ singleCylinderNormals_.push_back(vec3(-0.707107, -0.707107, 0.000000));
+ singleCylinderNormals_.push_back(vec3(-0.707107, -0.707107, 0.000000));
+ singleCylinderNormals_.push_back(vec3(0.000000, -1.000000, 0.000000));
+ singleCylinderNormals_.push_back(vec3(0.000000, -1.000000, 0.000000));
+ singleCylinderNormals_.push_back(vec3(0.707107, -0.707107, 0.000000));
+ singleCylinderNormals_.push_back(vec3(0.707107, -0.707107, 0.000000));
+ singleCylinderNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ singleCylinderNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+
+ // Double cylinder data...
+ doubleCylinderVertices_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ doubleCylinderVertices_.push_back(vec3(1.000000, 0.000000, 7.000000));
+ doubleCylinderVertices_.push_back(vec3(0.707107, 0.707107, 0.000000));
+ doubleCylinderVertices_.push_back(vec3(0.707107, 0.707107, 7.000000));
+ doubleCylinderVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ doubleCylinderVertices_.push_back(vec3(0.000000, 1.000000, 7.000000));
+ doubleCylinderVertices_.push_back(vec3(-0.707107, 0.707107, 0.000000));
+ doubleCylinderVertices_.push_back(vec3(-0.707107, 0.707107, 7.000000));
+ doubleCylinderVertices_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ doubleCylinderVertices_.push_back(vec3(-1.000000, 0.000000, 7.000000));
+ doubleCylinderVertices_.push_back(vec3(-0.707107, -0.707107, 0.000000));
+ doubleCylinderVertices_.push_back(vec3(-0.707107, -0.707107, 7.000000));
+ doubleCylinderVertices_.push_back(vec3(0.000000, -1.000000, 0.000000));
+ doubleCylinderVertices_.push_back(vec3(0.000000, -1.000000, 7.000000));
+ doubleCylinderVertices_.push_back(vec3(0.707107, -0.707107, 0.000000));
+ doubleCylinderVertices_.push_back(vec3(0.707107, -0.707107, 7.000000));
+ doubleCylinderVertices_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ doubleCylinderVertices_.push_back(vec3(1.000000, 0.000000, 7.000000));
+
+ doubleCylinderNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(0.707107, 0.707107, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(0.707107, 0.707107, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(-0.707107, 0.707107, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(-0.707107, 0.707107, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(-0.707107, -0.707107, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(-0.707107, -0.707107, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(0.000000, -1.000000, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(0.000000, -1.000000, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(0.707107, -0.707107, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(0.707107, -0.707107, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ doubleCylinderNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+
+ // Elbow data...
+ elbowVertices_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowVertices_.push_back(vec3(0.707107, 0.707107, 0.000000));
+ elbowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowVertices_.push_back(vec3(-0.707107, 0.707107, 0.000000));
+ elbowVertices_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ elbowVertices_.push_back(vec3(-0.707107, -0.707107, 0.000000));
+ elbowVertices_.push_back(vec3(0.000000, -1.000000, 0.000000));
+ elbowVertices_.push_back(vec3(0.707107, -0.707107, 0.000000));
+ elbowVertices_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowVertices_.push_back(vec3(1.000000, 0.034074, 0.258819));
+ elbowVertices_.push_back(vec3(0.707107, 0.717087, 0.075806));
+ elbowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowVertices_.push_back(vec3(-0.707107, 0.717087, 0.075806));
+ elbowVertices_.push_back(vec3(-1.000000, 0.034074, 0.258819));
+ elbowVertices_.push_back(vec3(-0.707107, -0.648939, 0.441832));
+ elbowVertices_.push_back(vec3(0.000000, -0.931852, 0.517638));
+ elbowVertices_.push_back(vec3(0.707107, -0.648939, 0.441832));
+ elbowVertices_.push_back(vec3(1.000000, 0.034074, 0.258819));
+ elbowVertices_.push_back(vec3(1.000000, 0.133975, 0.500000));
+ elbowVertices_.push_back(vec3(0.707107, 0.746347, 0.146447));
+ elbowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowVertices_.push_back(vec3(-0.707107, 0.746347, 0.146447));
+ elbowVertices_.push_back(vec3(-1.000000, 0.133975, 0.500000));
+ elbowVertices_.push_back(vec3(-0.707107, -0.478398, 0.853553));
+ elbowVertices_.push_back(vec3(0.000000, -0.732051, 1.000000));
+ elbowVertices_.push_back(vec3(0.707107, -0.478398, 0.853553));
+ elbowVertices_.push_back(vec3(1.000000, 0.133975, 0.500000));
+ elbowVertices_.push_back(vec3(1.000000, 0.292893, 0.707107));
+ elbowVertices_.push_back(vec3(0.707107, 0.792893, 0.207107));
+ elbowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowVertices_.push_back(vec3(-0.707107, 0.792893, 0.207107));
+ elbowVertices_.push_back(vec3(-1.000000, 0.292893, 0.707107));
+ elbowVertices_.push_back(vec3(-0.707107, -0.207107, 1.207107));
+ elbowVertices_.push_back(vec3(0.000000, -0.414214, 1.414214));
+ elbowVertices_.push_back(vec3(0.707107, -0.207107, 1.207107));
+ elbowVertices_.push_back(vec3(1.000000, 0.292893, 0.707107));
+ elbowVertices_.push_back(vec3(1.000000, 0.500000, 0.866025));
+ elbowVertices_.push_back(vec3(0.707107, 0.853553, 0.253653));
+ elbowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowVertices_.push_back(vec3(-0.707107, 0.853553, 0.253653));
+ elbowVertices_.push_back(vec3(-1.000000, 0.500000, 0.866025));
+ elbowVertices_.push_back(vec3(-0.707107, 0.146447, 1.478398));
+ elbowVertices_.push_back(vec3(0.000000, 0.000000, 1.732051));
+ elbowVertices_.push_back(vec3(0.707107, 0.146447, 1.478398));
+ elbowVertices_.push_back(vec3(1.000000, 0.500000, 0.866025));
+ elbowVertices_.push_back(vec3(1.000000, 0.741181, 0.965926));
+ elbowVertices_.push_back(vec3(0.707107, 0.924194, 0.282913));
+ elbowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowVertices_.push_back(vec3(-0.707107, 0.924194, 0.282913));
+ elbowVertices_.push_back(vec3(-1.000000, 0.741181, 0.965926));
+ elbowVertices_.push_back(vec3(-0.707107, 0.558168, 1.648939));
+ elbowVertices_.push_back(vec3(0.000000, 0.482362, 1.931852));
+ elbowVertices_.push_back(vec3(0.707107, 0.558168, 1.648939));
+ elbowVertices_.push_back(vec3(1.000000, 0.741181, 0.965926));
+ elbowVertices_.push_back(vec3(1.000000, 1.000000, 1.000000));
+ elbowVertices_.push_back(vec3(0.707107, 1.000000, 0.292893));
+ elbowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowVertices_.push_back(vec3(-0.707107, 1.000000, 0.292893));
+ elbowVertices_.push_back(vec3(-1.000000, 1.000000, 1.000000));
+ elbowVertices_.push_back(vec3(-0.707107, 1.000000, 1.707107));
+ elbowVertices_.push_back(vec3(0.000000, 1.000000, 2.000000));
+ elbowVertices_.push_back(vec3(0.707107, 1.000000, 1.707107));
+ elbowVertices_.push_back(vec3(1.000000, 1.000000, 1.000000));
+
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(0.707107, 0.707107, 0.000000));
+ elbowNormals_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowNormals_.push_back(vec3(-0.707107, 0.707107, 0.000000));
+ elbowNormals_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(-0.707107, -0.707107, 0.000000));
+ elbowNormals_.push_back(vec3(0.000000, -1.000000, 0.000000));
+ elbowNormals_.push_back(vec3(0.707107, -0.707107, 0.000000));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(0.707107, 0.683013, -0.183013));
+ elbowNormals_.push_back(vec3(0.000000, 0.965926, -0.258819));
+ elbowNormals_.push_back(vec3(-0.707107, 0.683013, -0.183013));
+ elbowNormals_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(-0.707107, -0.683013, 0.183013));
+ elbowNormals_.push_back(vec3(0.000000, -0.965926, 0.258819));
+ elbowNormals_.push_back(vec3(0.707107, -0.683013, 0.183013));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(0.707107, 0.612372, -0.353553));
+ elbowNormals_.push_back(vec3(0.000000, 0.866025, -0.500000));
+ elbowNormals_.push_back(vec3(-0.707107, 0.612372, -0.353553));
+ elbowNormals_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(-0.707107, -0.612372, 0.353553));
+ elbowNormals_.push_back(vec3(0.000000, -0.866025, 0.500000));
+ elbowNormals_.push_back(vec3(0.707107, -0.612372, 0.353553));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(0.707107, 0.500000, -0.500000));
+ elbowNormals_.push_back(vec3(0.000000, 0.707107, -0.707107));
+ elbowNormals_.push_back(vec3(-0.707107, 0.500000, -0.500000));
+ elbowNormals_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(-0.707107, -0.500000, 0.500000));
+ elbowNormals_.push_back(vec3(0.000000, -0.707107, 0.707107));
+ elbowNormals_.push_back(vec3(0.707107, -0.500000, 0.500000));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(0.707107, 0.353553, -0.612372));
+ elbowNormals_.push_back(vec3(0.000000, 0.500000, -0.866025));
+ elbowNormals_.push_back(vec3(-0.707107, 0.353553, -0.612372));
+ elbowNormals_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(-0.707107, -0.353553, 0.612372));
+ elbowNormals_.push_back(vec3(0.000000, -0.500000, 0.866025));
+ elbowNormals_.push_back(vec3(0.707107, -0.353553, 0.612372));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(0.707107, 0.183013, -0.683013));
+ elbowNormals_.push_back(vec3(0.000000, 0.258819, -0.965926));
+ elbowNormals_.push_back(vec3(-0.707107, 0.183013, -0.683013));
+ elbowNormals_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(-0.707107, -0.183013, 0.683013));
+ elbowNormals_.push_back(vec3(0.000000, -0.258819, 0.965926));
+ elbowNormals_.push_back(vec3(0.707107, -0.183013, 0.683013));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(0.707107, 0.000000, -0.707107));
+ elbowNormals_.push_back(vec3(0.000000, 0.000000, -1.000000));
+ elbowNormals_.push_back(vec3(-0.707107, 0.000000, -0.707107));
+ elbowNormals_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ elbowNormals_.push_back(vec3(-0.707107, 0.000000, 0.707107));
+ elbowNormals_.push_back(vec3(0.000000, 0.000000, 1.000000));
+ elbowNormals_.push_back(vec3(0.707107, 0.000000, 0.707107));
+ elbowNormals_.push_back(vec3(1.000000, 0.000000, 0.000000));
+
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(0.707107, 0.707107, 0.000000));
+ elbowShadowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 0.707107, 0.000000));
+ elbowShadowVertices_.push_back(vec3(-1.000000, 0.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(-0.707107, -0.707107, 0.000000));
+ elbowShadowVertices_.push_back(vec3(0.000000, -1.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(0.707107, -0.707107, 0.000000));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.019215, 0.195090));
+ elbowShadowVertices_.push_back(vec3(0.707107, 0.712735, 0.057141));
+ elbowShadowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 0.712735, 0.057141));
+ elbowShadowVertices_.push_back(vec3(-1.000000, 0.019215, 0.195090));
+ elbowShadowVertices_.push_back(vec3(-0.707107, -0.674305, 0.333040));
+ elbowShadowVertices_.push_back(vec3(0.000000, -0.961571, 0.390181));
+ elbowShadowVertices_.push_back(vec3(0.707107, -0.674305, 0.333040));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.019215, 0.195090));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.076120, 0.382683));
+ elbowShadowVertices_.push_back(vec3(0.707107, 0.729402, 0.112085));
+ elbowShadowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 0.729402, 0.112085));
+ elbowShadowVertices_.push_back(vec3(-1.000000, 0.076120, 0.382683));
+ elbowShadowVertices_.push_back(vec3(-0.707107, -0.577161, 0.653282));
+ elbowShadowVertices_.push_back(vec3(0.000000, -0.847759, 0.765367));
+ elbowShadowVertices_.push_back(vec3(0.707107, -0.577161, 0.653282));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.076120, 0.382683));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.168530, 0.555570));
+ elbowShadowVertices_.push_back(vec3(0.707107, 0.756468, 0.162723));
+ elbowShadowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 0.756468, 0.162723));
+ elbowShadowVertices_.push_back(vec3(-1.000000, 0.168530, 0.555570));
+ elbowShadowVertices_.push_back(vec3(-0.707107, -0.419407, 0.948418));
+ elbowShadowVertices_.push_back(vec3(0.000000, -0.662939, 1.111140));
+ elbowShadowVertices_.push_back(vec3(0.707107, -0.419407, 0.948418));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.168530, 0.555570));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.292893, 0.707107));
+ elbowShadowVertices_.push_back(vec3(0.707107, 0.792893, 0.207107));
+ elbowShadowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 0.792893, 0.207107));
+ elbowShadowVertices_.push_back(vec3(-1.000000, 0.292893, 0.707107));
+ elbowShadowVertices_.push_back(vec3(-0.707107, -0.207107, 1.207107));
+ elbowShadowVertices_.push_back(vec3(0.000000, -0.414214, 1.414214));
+ elbowShadowVertices_.push_back(vec3(0.707107, -0.207107, 1.207107));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.292893, 0.707107));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.444430, 0.831470));
+ elbowShadowVertices_.push_back(vec3(0.707107, 0.837277, 0.243532));
+ elbowShadowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 0.837277, 0.243532));
+ elbowShadowVertices_.push_back(vec3(-1.000000, 0.444430, 0.831470));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 0.051582, 1.419407));
+ elbowShadowVertices_.push_back(vec3(0.000000, -0.111140, 1.662939));
+ elbowShadowVertices_.push_back(vec3(0.707107, 0.051582, 1.419407));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.444430, 0.831470));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.617317, 0.923880));
+ elbowShadowVertices_.push_back(vec3(0.707107, 0.887915, 0.270598));
+ elbowShadowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 0.887915, 0.270598));
+ elbowShadowVertices_.push_back(vec3(-1.000000, 0.617317, 0.923880));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 0.346719, 1.577161));
+ elbowShadowVertices_.push_back(vec3(0.000000, 0.234633, 1.847759));
+ elbowShadowVertices_.push_back(vec3(0.707107, 0.346719, 1.577161));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.617317, 0.923880));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.804910, 0.980785));
+ elbowShadowVertices_.push_back(vec3(0.707107, 0.942859, 0.287265));
+ elbowShadowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 0.942859, 0.287265));
+ elbowShadowVertices_.push_back(vec3(-1.000000, 0.804910, 0.980785));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 0.666960, 1.674305));
+ elbowShadowVertices_.push_back(vec3(0.000000, 0.609819, 1.961571));
+ elbowShadowVertices_.push_back(vec3(0.707107, 0.666960, 1.674305));
+ elbowShadowVertices_.push_back(vec3(1.000000, 0.804910, 0.980785));
+ elbowShadowVertices_.push_back(vec3(1.000000, 1.000000, 1.000000));
+ elbowShadowVertices_.push_back(vec3(0.707107, 1.000000, 0.292893));
+ elbowShadowVertices_.push_back(vec3(0.000000, 1.000000, 0.000000));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 1.000000, 0.292893));
+ elbowShadowVertices_.push_back(vec3(-1.000000, 1.000000, 1.000000));
+ elbowShadowVertices_.push_back(vec3(-0.707107, 1.000000, 1.707107));
+ elbowShadowVertices_.push_back(vec3(0.000000, 1.000000, 2.000000));
+ elbowShadowVertices_.push_back(vec3(0.707107, 1.000000, 1.707107));
+ elbowShadowVertices_.push_back(vec3(1.000000, 1.000000, 1.000000));
+
+ // Now that we've setup the vertex data, we can setup the map of how
+ // that data will be laid out in the buffer object.
+ static const unsigned int sv3(sizeof(vec3));
+ dataMap_.scvOffset = 0;
+ dataMap_.scvSize = singleCylinderVertices_.size() * sv3;
+ dataMap_.totalSize = dataMap_.scvSize;
+ dataMap_.scnOffset = dataMap_.scvOffset + dataMap_.scvSize;
+ dataMap_.scnSize = singleCylinderNormals_.size() * sv3;
+ dataMap_.totalSize += dataMap_.scnSize;
+ dataMap_.dcvOffset = dataMap_.scnOffset + dataMap_.scnSize;
+ dataMap_.dcvSize = doubleCylinderVertices_.size() * sv3;
+ dataMap_.totalSize += dataMap_.dcvSize;
+ dataMap_.dcnOffset = dataMap_.dcvOffset + dataMap_.dcvSize;
+ dataMap_.dcnSize = doubleCylinderNormals_.size() * sv3;
+ dataMap_.totalSize += dataMap_.dcnSize;
+ dataMap_.evOffset = dataMap_.dcnOffset + dataMap_.dcnSize;
+ dataMap_.evSize = elbowVertices_.size() * sv3;
+ dataMap_.totalSize += dataMap_.evSize;
+ dataMap_.enOffset = dataMap_.evOffset + dataMap_.evSize;
+ dataMap_.enSize = elbowNormals_.size() * sv3;
+ dataMap_.totalSize += dataMap_.enSize;
+ dataMap_.esvOffset = dataMap_.enOffset + dataMap_.enSize;
+ dataMap_.esvSize = elbowShadowVertices_.size() * sv3;
+ dataMap_.totalSize += dataMap_.esvSize;
+
+ //
+ // The original implementation of both the logo and the lamp represented
+ // the vertex and normal data in a triply-dimensioned array of floats and
+ // all of the calls referenced double-indexed arrays of vector data.
+ // To my mind, this made the code look clunky and overly verbose.
+ // Representing the data as a STL vector of vec3 (itself a 3-float vector
+ // quantity) provides both an efficient container and allows for more
+ // concise looking code. The slightly goofy loops (using the original 2
+ // dimensional indices to compute a single offset into the STL vector) are
+ // a compromise to avoid rearranging the original data.
+ //
+ // - jesse 2010/10/04
+ //
+ for (unsigned int i = 0; i < 8; i++)
+ {
+ for (unsigned int j = 0; j < 9; j++)
+ {
+ unsigned int index1(i * 9 + j);
+ unsigned int index2((i + 1) * 9 + j);
+ indexData_.push_back(index1);
+ indexData_.push_back(index2);
+ }
+ }
+
+ // Initialize the stipple pattern
+ static const unsigned int patterns[] = { 0xaaaaaaaa, 0x55555555 };
+ for (unsigned int i = 0; i < textureResolution_; i++)
+ {
+ for (unsigned int j = 0; j < textureResolution_; j++)
+ {
+ // Alternate the pattern every other line.
+ unsigned int curMask(1 << j);
+ unsigned int curPattern(patterns[i % 2]);
+ textureImage_[i][j] = ((curPattern & curMask) >> j) * 255;
+ }
+ }
+}
+
+SGILogo::~SGILogo()
+{
+ if (valid_)
+ {
+ glDeleteBuffers(2, &bufferObjects_[0]);
+ }
+}
+
+void
+SGILogo::init()
+{
+ // Make sure we don't re-initialize...
+ if (valid_)
+ {
+ return;
+ }
+
+ // Initialize shader sources from input files and create programs from them
+ // The program for handling the main object with lighting...
+ string logo_vtx_filename(GLMARK_DATA_PATH"/shaders/ideas-logo.vert");
+ string logo_frg_filename(GLMARK_DATA_PATH"/shaders/ideas-logo.frag");
+ ShaderSource logo_vtx_source(logo_vtx_filename);
+ ShaderSource logo_frg_source(logo_frg_filename);
+ if (!Scene::load_shaders_from_strings(normalProgram_, logo_vtx_source.str(),
+ logo_frg_source.str()))
+ {
+ Log::error("No valid program for normal logo rendering\n");
+ return;
+ }
+ normalVertexIndex_ = normalProgram_[vertexAttribName_].location();
+ normalNormalIndex_ = normalProgram_[normalAttribName_].location();
+
+ // The program for handling the flat object...
+ string logo_flat_vtx_filename(GLMARK_DATA_PATH"/shaders/ideas-logo-flat.vert");
+ string logo_flat_frg_filename(GLMARK_DATA_PATH"/shaders/ideas-logo-flat.frag");
+ ShaderSource logo_flat_vtx_source(logo_flat_vtx_filename);
+ ShaderSource logo_flat_frg_source(logo_flat_frg_filename);
+ if (!Scene::load_shaders_from_strings(flatProgram_, logo_flat_vtx_source.str(),
+ logo_flat_frg_source.str()))
+ {
+ Log::error("No valid program for flat logo rendering\n");
+ return;
+ }
+ flatVertexIndex_ = flatProgram_[vertexAttribName_].location();
+
+ // The program for handling the shadow object with texturing...
+ string logo_shadow_vtx_filename(GLMARK_DATA_PATH"/shaders/ideas-logo-shadow.vert");
+ string logo_shadow_frg_filename(GLMARK_DATA_PATH"/shaders/ideas-logo-shadow.frag");
+ ShaderSource logo_shadow_vtx_source(logo_shadow_vtx_filename);
+ ShaderSource logo_shadow_frg_source(logo_shadow_frg_filename);
+ if (!Scene::load_shaders_from_strings(shadowProgram_, logo_shadow_vtx_source.str(),
+ logo_shadow_frg_source.str()))
+ {
+ Log::error("No valid program for shadow logo rendering\n");
+ return;
+ }
+ shadowVertexIndex_ = shadowProgram_[vertexAttribName_].location();
+
+ // We need 2 buffers for our work here. One for the vertex data.
+ // and one for the index data.
+ glGenBuffers(2, &bufferObjects_[0]);
+
+ // First, setup the vertex data by binding the first buffer object,
+ // allocating its data store, and filling it in with our vertex data.
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]);
+ glBufferData(GL_ARRAY_BUFFER, dataMap_.totalSize, 0, GL_STATIC_DRAW);
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.scvOffset, dataMap_.scvSize,
+ &singleCylinderVertices_.front());
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.scnOffset, dataMap_.scnSize,
+ &singleCylinderNormals_.front());
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.dcvOffset, dataMap_.dcvSize,
+ &doubleCylinderVertices_.front());
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.dcnOffset, dataMap_.dcnSize,
+ &doubleCylinderNormals_.front());
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.evOffset, dataMap_.evSize,
+ &elbowVertices_.front());
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.enOffset, dataMap_.enSize,
+ &elbowNormals_.front());
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.esvOffset, dataMap_.esvSize,
+ &elbowShadowVertices_.front());
+
+ // Now repeat for our index data.
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexData_.size() * sizeof(unsigned short),
+ &indexData_.front(), GL_STATIC_DRAW);
+
+ // Setup our the texture that the shadow program will use...
+ glGenTextures(1, &textureName_);
+ glBindTexture(GL_TEXTURE_2D, textureName_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
+ textureResolution_, textureResolution_,
+ 0, GL_ALPHA, GL_UNSIGNED_BYTE, textureImage_);
+
+ // We're ready to go.
+ valid_ = true;
+}
+
+void
+SGILogo::bendForward(Stack4& ms)
+{
+ ms.translate(0.0, 1.0, 0.0);
+ ms.rotate(90.0, 1.0, 0.0, 0.0);
+ ms.translate(0.0, -1.0, 0.0);
+}
+
+void
+SGILogo::bendLeft(Stack4& ms)
+{
+ ms.rotate(-90.0, 0.0, 0.0, 1.0);
+ ms.translate(0.0, 1.0, 0.0);
+ ms.rotate(90.0, 1.0, 0.0, 0.0);
+ ms.translate(0.0, -1.0, 0.0);
+}
+
+void
+SGILogo::bendRight(Stack4& ms)
+{
+ ms.rotate(90.0, 0.0, 0.0, 1.0);
+ ms.translate(0.0, 1.0, 0.0);
+ ms.rotate(90.0, 1.0, 0.0, 0.0);
+ ms.translate(0.0, -1.0, 0.0);
+}
+
+void
+SGILogo::drawDoubleCylinder(void)
+{
+ glVertexAttribPointer(vertexIndex_, 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.dcvOffset));
+ if (drawStyle_ == LOGO_NORMAL)
+ {
+ glVertexAttribPointer(normalNormalIndex_, 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.dcnOffset));
+ }
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 18);
+}
+
+void
+SGILogo::drawSingleCylinder(void)
+{
+ glVertexAttribPointer(vertexIndex_, 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.scvOffset));
+ if (drawStyle_ == LOGO_NORMAL)
+ {
+ glVertexAttribPointer(normalNormalIndex_, 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.scnOffset));
+ }
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 18);
+}
+
+void
+SGILogo::drawElbow(void)
+{
+ unsigned int startIdx(0);
+ unsigned int endIdx(6);
+ if (drawStyle_ == LOGO_NORMAL)
+ {
+ glVertexAttribPointer(vertexIndex_, 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.evOffset));
+ glVertexAttribPointer(normalNormalIndex_, 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.enOffset));
+ }
+ else
+ {
+ endIdx = 8;
+ glVertexAttribPointer(vertexIndex_, 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.esvOffset));
+ }
+
+ for (unsigned int i = startIdx; i < endIdx; i++)
+ {
+ unsigned int curOffset(i * 18 * sizeof(unsigned short));
+ glDrawElements(GL_TRIANGLE_STRIP, 18, GL_UNSIGNED_SHORT,
+ reinterpret_cast<const GLvoid*>(curOffset));
+ }
+}
+
+// Generate a normal matrix from a modelview matrix
+//
+// Since we can't universally handle the normal matrix inside the
+// vertex shader (inverse() and transpose() built-ins not supported by
+// GLSL ES, for example), we'll generate it here, and load it as a
+// uniform.
+void
+SGILogo::updateXform(const mat4& mv, Program& program)
+{
+ if (drawStyle_ == LOGO_NORMAL)
+ {
+ LibMatrix::mat3 normalMatrix(mv[0][0], mv[1][0], mv[2][0],
+ mv[0][1], mv[1][1], mv[2][1],
+ mv[0][2], mv[1][2], mv[2][2]);
+ normalMatrix.transpose().inverse();
+ program[normalMatrixName_] = normalMatrix;
+ }
+ program[modelviewName_] = mv;
+}
+
+Program&
+SGILogo::getProgram()
+{
+ switch (drawStyle_)
+ {
+ case LOGO_NORMAL:
+ return normalProgram_;
+ break;
+ case LOGO_FLAT:
+ return flatProgram_;
+ break;
+ case LOGO_SHADOW:
+ return shadowProgram_;
+ break;
+ }
+
+ return normalProgram_;
+}
+
+void
+SGILogo::draw(Stack4& modelview,
+ Stack4& projection,
+ const vec4& lightPosition,
+ DrawStyle style,
+ const uvec3& currentColor)
+{
+ if (!valid_)
+ {
+ return;
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]);
+
+ // Setup the program to use based upon draw style and set it running.
+ drawStyle_ = style;
+ vec4 logoColor(currentColor.x() / 255.0, currentColor.y() / 255.0, currentColor.z() / 255.0, 1.0);
+ Program& curProgram = getProgram();
+ curProgram.start();
+ switch (drawStyle_)
+ {
+ case LOGO_NORMAL:
+ curProgram[lightPositionName_] = lightPosition;
+ vertexIndex_ = normalVertexIndex_;
+ glEnableVertexAttribArray(normalNormalIndex_);
+ break;
+ case LOGO_FLAT:
+ curProgram[logoColorName_] = logoColor;
+ vertexIndex_ = flatVertexIndex_;
+ break;
+ case LOGO_SHADOW:
+ vertexIndex_ = shadowVertexIndex_;
+ break;
+ }
+
+ glEnableVertexAttribArray(vertexIndex_);
+ curProgram[projectionName_] = projection.getCurrent();
+ modelview.translate(5.500000, -3.500000, 4.500000);
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -5.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawSingleCylinder();
+ bendRight(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -5.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawSingleCylinder();
+ bendLeft(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -5.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawSingleCylinder();
+ bendRight(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -5.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawSingleCylinder();
+ bendLeft(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -5.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawSingleCylinder();
+ bendRight(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -7.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawDoubleCylinder();
+ bendForward(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ modelview.translate(0.0, 0.0, -5.000000);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawSingleCylinder();
+ bendLeft(modelview);
+ updateXform(modelview.getCurrent(), curProgram);
+ drawElbow();
+ glDisableVertexAttribArray(vertexIndex_);
+ switch (drawStyle_)
+ {
+ case LOGO_NORMAL:
+ glDisableVertexAttribArray(normalNormalIndex_);
+ break;
+ case LOGO_FLAT:
+ break;
+ case LOGO_SHADOW:
+ break;
+ }
+ curProgram.stop();
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+}
diff --git a/src/scene-ideas/logo.h b/src/scene-ideas/logo.h
new file mode 100644
index 0000000..43d9fe5
--- /dev/null
+++ b/src/scene-ideas/logo.h
@@ -0,0 +1,126 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#ifndef LOGO_H_
+#define LOGO_H_
+
+#include <string>
+#include <vector>
+#include "vec.h"
+#include "stack.h"
+#include "gl-headers.h"
+#include "program.h"
+
+class SGILogo
+{
+public:
+ SGILogo();
+ ~SGILogo();
+
+ // Initialize the logo
+ void init();
+ bool valid() const { return valid_; }
+ void setPosition(const LibMatrix::vec3& position) { currentPosition_ = position; }
+ // Tell the logo to draw itself. DrawStyle tells it how.
+ // - LOGO_NORMAL renders the logo lit and shaded.
+ // - LOGO_FLAT renders the logo as if flattened onto a surface.
+ // - LOGO_SHADOW renders a stippled-looking shadow of the object.
+ enum DrawStyle
+ {
+ LOGO_NORMAL,
+ LOGO_FLAT,
+ LOGO_SHADOW
+ };
+ void draw(LibMatrix::Stack4& modelview, LibMatrix::Stack4& projection,
+ const LibMatrix::vec4& lightPosition, DrawStyle style,
+ const LibMatrix::uvec3& color = LibMatrix::uvec3());
+
+private:
+ void drawElbow();
+ void drawSingleCylinder();
+ void drawDoubleCylinder();
+ void bendLeft(LibMatrix::Stack4& ms);
+ void bendRight(LibMatrix::Stack4& ms);
+ void bendForward(LibMatrix::Stack4& ms);
+ void updateXform(const LibMatrix::mat4& mv, Program& program);
+ Program& getProgram();
+ LibMatrix::vec3 currentPosition_;
+ std::vector<LibMatrix::vec3> singleCylinderVertices_;
+ std::vector<LibMatrix::vec3> singleCylinderNormals_;
+ std::vector<LibMatrix::vec3> doubleCylinderVertices_;
+ std::vector<LibMatrix::vec3> doubleCylinderNormals_;
+ std::vector<LibMatrix::vec3> elbowVertices_;
+ std::vector<LibMatrix::vec3> elbowNormals_;
+ std::vector<LibMatrix::vec3> elbowShadowVertices_;
+ std::vector<unsigned short> indexData_;
+ // A simple map so we know where each section of our data starts within
+ // our vertex buffer object.
+ struct VertexDataMap
+ {
+ unsigned int scvOffset;
+ unsigned int scvSize;
+ unsigned int scnOffset;
+ unsigned int scnSize;
+ unsigned int dcvOffset;
+ unsigned int dcvSize;
+ unsigned int dcnOffset;
+ unsigned int dcnSize;
+ unsigned int evOffset;
+ unsigned int evSize;
+ unsigned int enOffset;
+ unsigned int enSize;
+ unsigned int esvOffset;
+ unsigned int esvSize;
+ unsigned int totalSize;
+ } dataMap_;
+ unsigned int bufferObjects_[2];
+ Program normalProgram_;
+ Program flatProgram_;
+ Program shadowProgram_;
+ std::string normalVertexShader_;
+ std::string normalFragmentShader_;
+ std::string flatVertexShader_;
+ std::string flatFragmentShader_;
+ std::string shadowVertexShader_;
+ std::string shadowFragmentShader_;
+ int normalNormalIndex_;
+ int normalVertexIndex_;
+ int flatVertexIndex_;
+ int shadowVertexIndex_;
+ int vertexIndex_;
+ static const std::string modelviewName_;
+ static const std::string projectionName_;
+ static const std::string lightPositionName_;
+ static const std::string logoColorName_;
+ static const std::string vertexAttribName_;
+ static const std::string normalAttribName_;
+ static const std::string normalMatrixName_;
+ // "Shadow" state
+ GLuint textureName_;
+ GLubyte textureImage_[32][32];
+ // This is the size in each direction of our texture image
+ static const unsigned int textureResolution_;
+ bool valid_;
+ DrawStyle drawStyle_;
+};
+
+#endif // LOGO_H_
diff --git a/src/scene-ideas/m.cc b/src/scene-ideas/m.cc
new file mode 100644
index 0000000..47bdb0d
--- /dev/null
+++ b/src/scene-ideas/m.cc
@@ -0,0 +1,210 @@
+/*
+ * Vertex position data describing the letter 'm'
+ *
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "characters.h"
+
+using LibMatrix::vec2;
+
+LetterM::LetterM()
+{
+ // Vertex data...
+ vertexData_.push_back(vec2(0.590769, 9.449335));
+ vertexData_.push_back(vec2(2.116923, 9.842375));
+ vertexData_.push_back(vec2(1.362051, 9.383828));
+ vertexData_.push_back(vec2(2.527179, 9.825998));
+ vertexData_.push_back(vec2(1.591795, 9.072672));
+ vertexData_.push_back(vec2(2.789744, 9.514841));
+ vertexData_.push_back(vec2(1.690256, 8.663255));
+ vertexData_.push_back(vec2(2.658462, 8.335722));
+ vertexData_.push_back(vec2(1.575385, 7.222108));
+ vertexData_.push_back(vec2(2.067692, 6.255886));
+ vertexData_.push_back(vec2(0.918974, 4.028659));
+ vertexData_.push_back(vec2(1.050256, 3.013306));
+ vertexData_.push_back(vec2(0.705641, 3.013306));
+ vertexData_.push_back(vec2(2.018461, 6.386899));
+ vertexData_.push_back(vec2(1.788718, 5.617196));
+ vertexData_.push_back(vec2(2.921026, 7.991812));
+ vertexData_.push_back(vec2(3.167180, 8.008188));
+ vertexData_.push_back(vec2(3.544615, 8.827022));
+ vertexData_.push_back(vec2(3.872821, 8.843398));
+ vertexData_.push_back(vec2(4.414359, 9.547595));
+ vertexData_.push_back(vec2(4.447179, 9.056294));
+ vertexData_.push_back(vec2(5.120000, 9.891504));
+ vertexData_.push_back(vec2(4.841026, 8.843398));
+ vertexData_.push_back(vec2(5.825641, 9.809621));
+ vertexData_.push_back(vec2(5.005128, 8.040941));
+ vertexData_.push_back(vec2(5.989744, 8.761515));
+ vertexData_.push_back(vec2(4.906667, 6.714432));
+ vertexData_.push_back(vec2(5.595897, 7.123848));
+ vertexData_.push_back(vec2(3.987692, 2.996929));
+ vertexData_.push_back(vec2(4.348718, 2.996929));
+ vertexData_.push_back(vec2(5.218462, 5.977482));
+ vertexData_.push_back(vec2(5.251282, 6.354146));
+ vertexData_.push_back(vec2(6.449231, 7.893552));
+ vertexData_.push_back(vec2(6.400000, 8.221085));
+ vertexData_.push_back(vec2(7.302564, 8.843398));
+ vertexData_.push_back(vec2(7.351795, 9.334698));
+ vertexData_.push_back(vec2(7.827693, 9.154554));
+ vertexData_.push_back(vec2(8.008205, 9.842375));
+ vertexData_.push_back(vec2(8.139487, 9.121801));
+ vertexData_.push_back(vec2(8.795897, 9.973388));
+ vertexData_.push_back(vec2(8.402051, 8.728762));
+ vertexData_.push_back(vec2(9.337436, 9.531218));
+ vertexData_.push_back(vec2(8.402051, 8.040941));
+ vertexData_.push_back(vec2(9.288205, 8.433982));
+ vertexData_.push_back(vec2(7.745641, 5.813715));
+ vertexData_.push_back(vec2(8.320000, 5.928352));
+ vertexData_.push_back(vec2(7.286154, 4.012282));
+ vertexData_.push_back(vec2(7.991795, 4.126919));
+ vertexData_.push_back(vec2(7.499487, 3.357216));
+ vertexData_.push_back(vec2(8.533334, 3.766633));
+ vertexData_.push_back(vec2(8.123077, 3.062436));
+ vertexData_.push_back(vec2(8.927179, 3.832139));
+ vertexData_.push_back(vec2(8.910769, 3.340839));
+ vertexData_.push_back(vec2(9.550769, 4.126919));
+
+ // Index data...
+ indexData_.push_back(0);
+ indexData_.push_back(2);
+ indexData_.push_back(4);
+ indexData_.push_back(6);
+ indexData_.push_back(8);
+ indexData_.push_back(10);
+ indexData_.push_back(12);
+ indexData_.push_back(11);
+ indexData_.push_back(9);
+ indexData_.push_back(7);
+ indexData_.push_back(5);
+ indexData_.push_back(3);
+ indexData_.push_back(1);
+ indexData_.push_back(14);
+ indexData_.push_back(16);
+ indexData_.push_back(18);
+ indexData_.push_back(20);
+ indexData_.push_back(22);
+ indexData_.push_back(24);
+ indexData_.push_back(26);
+ indexData_.push_back(28);
+ indexData_.push_back(29);
+ indexData_.push_back(27);
+ indexData_.push_back(25);
+ indexData_.push_back(23);
+ indexData_.push_back(21);
+ indexData_.push_back(19);
+ indexData_.push_back(17);
+ indexData_.push_back(15);
+ indexData_.push_back(13);
+ indexData_.push_back(30);
+ indexData_.push_back(32);
+ indexData_.push_back(34);
+ indexData_.push_back(36);
+ indexData_.push_back(38);
+ indexData_.push_back(40);
+ indexData_.push_back(42);
+ indexData_.push_back(44);
+ indexData_.push_back(46);
+ indexData_.push_back(48);
+ indexData_.push_back(50);
+ indexData_.push_back(52);
+ indexData_.push_back(53);
+ indexData_.push_back(51);
+ indexData_.push_back(49);
+ indexData_.push_back(47);
+ indexData_.push_back(45);
+ indexData_.push_back(43);
+ indexData_.push_back(41);
+ indexData_.push_back(39);
+ indexData_.push_back(37);
+ indexData_.push_back(35);
+ indexData_.push_back(33);
+ indexData_.push_back(31);
+ indexData_.push_back(0);
+ indexData_.push_back(1);
+ indexData_.push_back(2);
+ indexData_.push_back(3);
+ indexData_.push_back(4);
+ indexData_.push_back(5);
+ indexData_.push_back(6);
+ indexData_.push_back(7);
+ indexData_.push_back(8);
+ indexData_.push_back(9);
+ indexData_.push_back(10);
+ indexData_.push_back(11);
+ indexData_.push_back(12);
+ indexData_.push_back(13);
+ indexData_.push_back(14);
+ indexData_.push_back(15);
+ indexData_.push_back(16);
+ indexData_.push_back(17);
+ indexData_.push_back(18);
+ indexData_.push_back(19);
+ indexData_.push_back(20);
+ indexData_.push_back(21);
+ indexData_.push_back(22);
+ indexData_.push_back(23);
+ indexData_.push_back(24);
+ indexData_.push_back(25);
+ indexData_.push_back(26);
+ indexData_.push_back(27);
+ indexData_.push_back(28);
+ indexData_.push_back(29);
+ indexData_.push_back(30);
+ indexData_.push_back(31);
+ indexData_.push_back(32);
+ indexData_.push_back(33);
+ indexData_.push_back(34);
+ indexData_.push_back(35);
+ indexData_.push_back(36);
+ indexData_.push_back(37);
+ indexData_.push_back(38);
+ indexData_.push_back(39);
+ indexData_.push_back(40);
+ indexData_.push_back(41);
+ indexData_.push_back(42);
+ indexData_.push_back(43);
+ indexData_.push_back(44);
+ indexData_.push_back(45);
+ indexData_.push_back(46);
+ indexData_.push_back(47);
+ indexData_.push_back(48);
+ indexData_.push_back(49);
+ indexData_.push_back(50);
+ indexData_.push_back(51);
+ indexData_.push_back(52);
+ indexData_.push_back(53);
+
+ // Primitive state so that the draw call can issue the primitives we want.
+ unsigned int curOffset(0);
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 13, curOffset));
+ curOffset += (13 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 17, curOffset));
+ curOffset += (17 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 24, curOffset));
+ curOffset += (24 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 13, curOffset));
+ curOffset += (13 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 17, curOffset));
+ curOffset += (17 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 24, curOffset));
+}
diff --git a/src/scene-ideas/n.cc b/src/scene-ideas/n.cc
new file mode 100644
index 0000000..1ca7490
--- /dev/null
+++ b/src/scene-ideas/n.cc
@@ -0,0 +1,146 @@
+/*
+ * Vertex position data describing the letter 'o'
+ *
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "characters.h"
+
+using LibMatrix::vec2;
+
+LetterN::LetterN()
+{
+ // Vertex data...
+ vertexData_.push_back(vec2(1.009307, 9.444788));
+ vertexData_.push_back(vec2(2.548087, 9.742002));
+ vertexData_.push_back(vec2(1.737332, 9.213622));
+ vertexData_.push_back(vec2(2.994829, 9.659443));
+ vertexData_.push_back(vec2(1.985522, 8.751290));
+ vertexData_.push_back(vec2(3.127198, 9.180598));
+ vertexData_.push_back(vec2(1.935884, 7.975232));
+ vertexData_.push_back(vec2(2.481903, 6.571723));
+ vertexData_.push_back(vec2(1.472596, 5.019608));
+ vertexData_.push_back(vec2(1.439504, 2.988648));
+ vertexData_.push_back(vec2(1.025853, 2.988648));
+ vertexData_.push_back(vec2(2.283350, 6.059855));
+ vertexData_.push_back(vec2(2.035160, 5.366357));
+ vertexData_.push_back(vec2(3.292658, 7.711042));
+ vertexData_.push_back(vec2(3.540848, 7.744066));
+ vertexData_.push_back(vec2(4.384695, 9.031992));
+ vertexData_.push_back(vec2(4.699069, 8.916409));
+ vertexData_.push_back(vec2(5.609100, 9.808049));
+ vertexData_.push_back(vec2(5.145812, 8.982456));
+ vertexData_.push_back(vec2(6.155119, 9.791537));
+ vertexData_.push_back(vec2(5.410548, 8.635707));
+ vertexData_.push_back(vec2(6.337125, 9.312694));
+ vertexData_.push_back(vec2(5.360910, 7.991744));
+ vertexData_.push_back(vec2(6.088935, 8.090816));
+ vertexData_.push_back(vec2(4.947259, 5.977296));
+ vertexData_.push_back(vec2(5.261634, 4.804954));
+ vertexData_.push_back(vec2(4.616339, 4.028896));
+ vertexData_.push_back(vec2(5.211996, 3.962848));
+ vertexData_.push_back(vec2(4.732162, 3.318886));
+ vertexData_.push_back(vec2(5.559462, 3.814241));
+ vertexData_.push_back(vec2(5.228542, 3.038184));
+ vertexData_.push_back(vec2(5.940021, 3.814241));
+ vertexData_.push_back(vec2(5.906929, 3.335397));
+ vertexData_.push_back(vec2(6.684591, 4.094943));
+
+ // Index data...
+ indexData_.push_back(0);
+ indexData_.push_back(1);
+ indexData_.push_back(2);
+ indexData_.push_back(3);
+ indexData_.push_back(4);
+ indexData_.push_back(5);
+ indexData_.push_back(6);
+ indexData_.push_back(7);
+ indexData_.push_back(8);
+ indexData_.push_back(9);
+ indexData_.push_back(10);
+ indexData_.push_back(11);
+ indexData_.push_back(12);
+ indexData_.push_back(13);
+ indexData_.push_back(14);
+ indexData_.push_back(15);
+ indexData_.push_back(16);
+ indexData_.push_back(17);
+ indexData_.push_back(18);
+ indexData_.push_back(19);
+ indexData_.push_back(20);
+ indexData_.push_back(21);
+ indexData_.push_back(22);
+ indexData_.push_back(23);
+ indexData_.push_back(24);
+ indexData_.push_back(25);
+ indexData_.push_back(26);
+ indexData_.push_back(27);
+ indexData_.push_back(28);
+ indexData_.push_back(29);
+ indexData_.push_back(30);
+ indexData_.push_back(31);
+ indexData_.push_back(32);
+ indexData_.push_back(33);
+ indexData_.push_back(0);
+ indexData_.push_back(2);
+ indexData_.push_back(4);
+ indexData_.push_back(6);
+ indexData_.push_back(8);
+ indexData_.push_back(10);
+ indexData_.push_back(9);
+ indexData_.push_back(7);
+ indexData_.push_back(5);
+ indexData_.push_back(3);
+ indexData_.push_back(1);
+ indexData_.push_back(12);
+ indexData_.push_back(14);
+ indexData_.push_back(16);
+ indexData_.push_back(18);
+ indexData_.push_back(20);
+ indexData_.push_back(22);
+ indexData_.push_back(24);
+ indexData_.push_back(26);
+ indexData_.push_back(28);
+ indexData_.push_back(30);
+ indexData_.push_back(32);
+ indexData_.push_back(33);
+ indexData_.push_back(31);
+ indexData_.push_back(29);
+ indexData_.push_back(27);
+ indexData_.push_back(25);
+ indexData_.push_back(23);
+ indexData_.push_back(21);
+ indexData_.push_back(19);
+ indexData_.push_back(17);
+ indexData_.push_back(15);
+ indexData_.push_back(13);
+ indexData_.push_back(11);
+
+ // Primitive state so that the draw call can issue the primitives we want.
+ unsigned int curOffset(0);
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 11, curOffset));
+ curOffset += (11 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 23, curOffset));
+ curOffset += (23 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 11, curOffset));
+ curOffset += (11 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 23, curOffset));
+}
diff --git a/src/scene-ideas/o.cc b/src/scene-ideas/o.cc
new file mode 100644
index 0000000..372743c
--- /dev/null
+++ b/src/scene-ideas/o.cc
@@ -0,0 +1,139 @@
+/*
+ * Vertex position data describing the letter 'o'
+ *
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "characters.h"
+
+using LibMatrix::vec2;
+
+LetterO::LetterO()
+{
+ // Vertex data...
+ vertexData_.push_back(vec2(2.975610, 9.603255));
+ vertexData_.push_back(vec2(2.878049, 9.342828));
+ vertexData_.push_back(vec2(2.292683, 9.131231));
+ vertexData_.push_back(vec2(2.048780, 8.691760));
+ vertexData_.push_back(vec2(1.707317, 8.528993));
+ vertexData_.push_back(vec2(1.658537, 7.731434));
+ vertexData_.push_back(vec2(0.878049, 7.047813));
+ vertexData_.push_back(vec2(1.349594, 5.550356));
+ vertexData_.push_back(vec2(0.569106, 5.029501));
+ vertexData_.push_back(vec2(1.528455, 4.443540));
+ vertexData_.push_back(vec2(0.991870, 3.434385));
+ vertexData_.push_back(vec2(1.967480, 3.955239));
+ vertexData_.push_back(vec2(1.772358, 2.994914));
+ vertexData_.push_back(vec2(2.422764, 3.825025));
+ vertexData_.push_back(vec2(2.829268, 3.092574));
+ vertexData_.push_back(vec2(3.154472, 3.971516));
+ vertexData_.push_back(vec2(3.512195, 3.727365));
+ vertexData_.push_back(vec2(3.772358, 4.264496));
+ vertexData_.push_back(vec2(4.130081, 4.524924));
+ vertexData_.push_back(vec2(4.162601, 4.996948));
+ vertexData_.push_back(vec2(4.699187, 5.403866));
+ vertexData_.push_back(vec2(4.471545, 6.461852));
+ vertexData_.push_back(vec2(5.219512, 7.243133));
+ vertexData_.push_back(vec2(4.439024, 8.105799));
+ vertexData_.push_back(vec2(5.235772, 8.756866));
+ vertexData_.push_back(vec2(4.065041, 8.870804));
+ vertexData_.push_back(vec2(4.991870, 9.391658));
+ vertexData_.push_back(vec2(3.853658, 9.228891));
+ vertexData_.push_back(vec2(4.390244, 9.912513));
+ vertexData_.push_back(vec2(3.463415, 9.407935));
+ vertexData_.push_back(vec2(3.674797, 9.912513));
+ vertexData_.push_back(vec2(2.829268, 9.342828));
+ vertexData_.push_back(vec2(2.959350, 9.603255));
+
+ // Index data...
+ indexData_.push_back(0);
+ indexData_.push_back(1);
+ indexData_.push_back(2);
+ indexData_.push_back(3);
+ indexData_.push_back(4);
+ indexData_.push_back(5);
+ indexData_.push_back(6);
+ indexData_.push_back(7);
+ indexData_.push_back(8);
+ indexData_.push_back(9);
+ indexData_.push_back(10);
+ indexData_.push_back(11);
+ indexData_.push_back(12);
+ indexData_.push_back(13);
+ indexData_.push_back(14);
+ indexData_.push_back(15);
+ indexData_.push_back(16);
+ indexData_.push_back(17);
+ indexData_.push_back(18);
+ indexData_.push_back(19);
+ indexData_.push_back(20);
+ indexData_.push_back(21);
+ indexData_.push_back(22);
+ indexData_.push_back(23);
+ indexData_.push_back(24);
+ indexData_.push_back(25);
+ indexData_.push_back(26);
+ indexData_.push_back(27);
+ indexData_.push_back(28);
+ indexData_.push_back(29);
+ indexData_.push_back(30);
+ indexData_.push_back(31);
+ indexData_.push_back(32);
+ indexData_.push_back(0);
+ indexData_.push_back(2);
+ indexData_.push_back(4);
+ indexData_.push_back(6);
+ indexData_.push_back(8);
+ indexData_.push_back(10);
+ indexData_.push_back(12);
+ indexData_.push_back(14);
+ indexData_.push_back(16);
+ indexData_.push_back(18);
+ indexData_.push_back(20);
+ indexData_.push_back(22);
+ indexData_.push_back(24);
+ indexData_.push_back(26);
+ indexData_.push_back(28);
+ indexData_.push_back(30);
+ indexData_.push_back(32);
+ indexData_.push_back(31);
+ indexData_.push_back(29);
+ indexData_.push_back(27);
+ indexData_.push_back(25);
+ indexData_.push_back(23);
+ indexData_.push_back(21);
+ indexData_.push_back(19);
+ indexData_.push_back(17);
+ indexData_.push_back(15);
+ indexData_.push_back(13);
+ indexData_.push_back(11);
+ indexData_.push_back(9);
+ indexData_.push_back(7);
+ indexData_.push_back(5);
+ indexData_.push_back(3);
+ indexData_.push_back(1);
+
+ // Primitive state so that the draw call can issue the primitives we want.
+ unsigned int curOffset(0);
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 33, curOffset));
+ curOffset += (33 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 33, curOffset));
+}
diff --git a/src/scene-ideas/s.cc b/src/scene-ideas/s.cc
new file mode 100644
index 0000000..e67c9b6
--- /dev/null
+++ b/src/scene-ideas/s.cc
@@ -0,0 +1,130 @@
+/*
+ * Vertex position data describing the letter 's'
+ *
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "characters.h"
+
+using LibMatrix::vec2;
+
+LetterS::LetterS()
+{
+ // Vertex data...
+ vertexData_.push_back(vec2(0.860393, 5.283798));
+ vertexData_.push_back(vec2(0.529473, 3.550052));
+ vertexData_.push_back(vec2(0.992761, 4.491228));
+ vertexData_.push_back(vec2(0.910031, 3.368421));
+ vertexData_.push_back(vec2(1.240951, 3.830753));
+ vertexData_.push_back(vec2(1.456050, 3.104231));
+ vertexData_.push_back(vec2(1.935884, 3.517028));
+ vertexData_.push_back(vec2(2.002068, 2.988648));
+ vertexData_.push_back(vec2(2.763185, 3.533540));
+ vertexData_.push_back(vec2(3.061013, 3.120743));
+ vertexData_.push_back(vec2(3.391934, 3.748194));
+ vertexData_.push_back(vec2(4.053774, 3.632611));
+ vertexData_.push_back(vec2(3.822130, 4.540764));
+ vertexData_.push_back(vec2(4.550155, 4.590299));
+ vertexData_.push_back(vec2(3.656670, 5.465428));
+ vertexData_.push_back(vec2(4.517063, 5.713106));
+ vertexData_.push_back(vec2(3.276112, 5.894737));
+ vertexData_.push_back(vec2(3.921407, 6.538700));
+ vertexData_.push_back(vec2(2.299896, 6.736842));
+ vertexData_.push_back(vec2(3.044467, 7.430341));
+ vertexData_.push_back(vec2(1.886246, 7.496388));
+ vertexData_.push_back(vec2(2.581179, 8.222910));
+ vertexData_.push_back(vec2(1.902792, 8.751290));
+ vertexData_.push_back(vec2(2.680455, 8.883385));
+ vertexData_.push_back(vec2(2.283350, 9.312694));
+ vertexData_.push_back(vec2(3.358842, 9.609907));
+ vertexData_.push_back(vec2(3.507756, 9.907121));
+ vertexData_.push_back(vec2(4.285419, 9.758514));
+ vertexData_.push_back(vec2(5.112720, 9.973168));
+ vertexData_.push_back(vec2(4.748707, 9.593395));
+
+ // Index data...
+ indexData_.push_back(0);
+ indexData_.push_back(1);
+ indexData_.push_back(2);
+ indexData_.push_back(3);
+ indexData_.push_back(4);
+ indexData_.push_back(5);
+ indexData_.push_back(6);
+ indexData_.push_back(7);
+ indexData_.push_back(8);
+ indexData_.push_back(9);
+ indexData_.push_back(10);
+ indexData_.push_back(11);
+ indexData_.push_back(12);
+ indexData_.push_back(13);
+ indexData_.push_back(14);
+ indexData_.push_back(15);
+ indexData_.push_back(16);
+ indexData_.push_back(17);
+ indexData_.push_back(18);
+ indexData_.push_back(19);
+ indexData_.push_back(20);
+ indexData_.push_back(21);
+ indexData_.push_back(22);
+ indexData_.push_back(23);
+ indexData_.push_back(24);
+ indexData_.push_back(25);
+ indexData_.push_back(26);
+ indexData_.push_back(27);
+ indexData_.push_back(28);
+ indexData_.push_back(29);
+ indexData_.push_back(0);
+ indexData_.push_back(2);
+ indexData_.push_back(4);
+ indexData_.push_back(6);
+ indexData_.push_back(8);
+ indexData_.push_back(10);
+ indexData_.push_back(12);
+ indexData_.push_back(14);
+ indexData_.push_back(16);
+ indexData_.push_back(18);
+ indexData_.push_back(20);
+ indexData_.push_back(22);
+ indexData_.push_back(24);
+ indexData_.push_back(26);
+ indexData_.push_back(28);
+ indexData_.push_back(29);
+ indexData_.push_back(27);
+ indexData_.push_back(25);
+ indexData_.push_back(23);
+ indexData_.push_back(21);
+ indexData_.push_back(19);
+ indexData_.push_back(17);
+ indexData_.push_back(15);
+ indexData_.push_back(13);
+ indexData_.push_back(11);
+ indexData_.push_back(9);
+ indexData_.push_back(7);
+ indexData_.push_back(5);
+ indexData_.push_back(3);
+ indexData_.push_back(1);
+
+ // Primitive state so that the draw call can issue the primitives we want.
+ unsigned int curOffset(0);
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 30, curOffset));
+ curOffset += (30 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 30, curOffset));
+}
diff --git a/src/scene-ideas/splines.cc b/src/scene-ideas/splines.cc
new file mode 100644
index 0000000..7027144
--- /dev/null
+++ b/src/scene-ideas/splines.cc
@@ -0,0 +1,200 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "splines.h"
+
+using LibMatrix::vec3;
+
+void
+Spline::calcParams()
+{
+ unsigned int numParams(controlData_.size() - 3);
+ paramData_ = new param[numParams];
+ for (unsigned int i = 0; i < numParams; i++)
+ {
+ float x3(controlData_[i + 1].x());
+ float x2(controlData_[i + 2].x() - controlData_[i].x());
+ float x1(2.0 * controlData_[i].x() +
+ -2.0 * controlData_[i+1].x() +
+ 1.0 * controlData_[i+2].x() +
+ -1.0 * controlData_[i+3].x());
+ float x0(-1.0 * controlData_[i].x() +
+ 1.0 * controlData_[i+1].x() +
+ -1.0 * controlData_[i+2].x() +
+ 1.0 * controlData_[i+3].x());
+ float y3(controlData_[i + 1].y());
+ float y2(controlData_[i + 2].y() - controlData_[i].y());
+ float y1(2.0 * controlData_[i].y() +
+ -2.0 * controlData_[i+1].y() +
+ 1.0 * controlData_[i+2].y() +
+ -1.0 * controlData_[i+3].y());
+ float y0(-1.0 * controlData_[i].y() +
+ 1.0 * controlData_[i+1].y() +
+ -1.0 * controlData_[i+2].y() +
+ 1.0 * controlData_[i+3].y());
+ float z3(controlData_[i + 1].z());
+ float z2(controlData_[i + 2].z() - controlData_[i].z());
+ float z1(2.0 * controlData_[i].z() +
+ -2.0 * controlData_[i+1].z() +
+ 1.0 * controlData_[i+2].z() +
+ -1.0 * controlData_[i+3].z());
+ float z0(-1.0 * controlData_[i].z() +
+ 1.0 * controlData_[i+1].z() +
+ -1.0 * controlData_[i+2].z() +
+ 1.0 * controlData_[i+3].z());
+ paramData_[i][3].x(x3);
+ paramData_[i][2].x(x2);
+ paramData_[i][1].x(x1);
+ paramData_[i][0].x(x0);
+ paramData_[i][3].y(y3);
+ paramData_[i][2].y(y2);
+ paramData_[i][1].y(y1);
+ paramData_[i][0].y(y0);
+ paramData_[i][3].z(z3);
+ paramData_[i][2].z(z2);
+ paramData_[i][1].z(z1);
+ paramData_[i][0].z(z0);
+ }
+}
+
+void
+Spline::getCurrentVec(float currentTime, vec3& v) const
+{
+ unsigned int integerTime(static_cast<unsigned int>(currentTime));
+ float t(currentTime - static_cast<float>(integerTime));
+ v.x(paramData_[integerTime][3].x() +
+ paramData_[integerTime][2].x() * t +
+ paramData_[integerTime][1].x() * t * t +
+ paramData_[integerTime][0].x() * t * t * t);
+ v.y(paramData_[integerTime][3].y() +
+ paramData_[integerTime][2].y() * t +
+ paramData_[integerTime][1].y() * t * t +
+ paramData_[integerTime][0].y() * t * t * t);
+ v.z(paramData_[integerTime][3].z() +
+ paramData_[integerTime][2].z() * t +
+ paramData_[integerTime][1].z() * t * t +
+ paramData_[integerTime][0].z() * t * t * t);
+}
+
+ViewFromSpline::ViewFromSpline()
+{
+ addControlPoint(vec3(-1.0, 1.0, -4.0));
+ addControlPoint(vec3(-1.0, -3.0, -4.0));
+ addControlPoint(vec3(-3.0, 1.0, -3.0));
+ addControlPoint(vec3(-1.8, 2.0, 5.4));
+ addControlPoint(vec3(-0.4, 2.0, 1.2));
+ addControlPoint(vec3(-0.2, 1.5, 0.6));
+ addControlPoint(vec3(-0.2, 1.2, 0.6));
+ addControlPoint(vec3(-0.8, 1.0, 2.4));
+ addControlPoint(vec3(-1.0, 2.0, 3.0));
+ addControlPoint(vec3(0.0, 4.0, 3.6));
+ addControlPoint(vec3(-0.8, 4.0, 1.2));
+ addControlPoint(vec3(-0.2, 3.0, 0.6));
+ addControlPoint(vec3(-0.1, 2.0, 0.3));
+ addControlPoint(vec3(-0.1, 2.0, 0.3));
+ addControlPoint(vec3(-0.1, 2.0, 0.3));
+ addControlPoint(vec3(-0.1, 2.0, 0.3));
+ calcParams();
+}
+
+ViewToSpline::ViewToSpline()
+{
+ addControlPoint(vec3(-1.0, 1.0, 0.0));
+ addControlPoint(vec3(-1.0, -3.0, 0.0));
+ addControlPoint(vec3(-1.0, 1.0, 0.0));
+ addControlPoint(vec3(0.1, 0.0, -0.3));
+ addControlPoint(vec3(0.1, 0.0, -0.3));
+ addControlPoint(vec3(0.1, 0.0, -0.3));
+ addControlPoint(vec3(0.0, 0.2, 0.0));
+ addControlPoint(vec3(0.0, 0.6, 0.0));
+ addControlPoint(vec3(0.0, 0.8, 0.0));
+ addControlPoint(vec3(0.0, 0.8, 0.0));
+ addControlPoint(vec3(0.0, 0.8, 0.0));
+ addControlPoint(vec3(0.0, 0.8, 0.0));
+ addControlPoint(vec3(0.0, 0.8, 0.0));
+ addControlPoint(vec3(0.0, 0.8, 0.0));
+ addControlPoint(vec3(0.0, 0.8, 0.0));
+ addControlPoint(vec3(0.0, 0.8, 0.0));
+ calcParams();
+}
+
+LightPositionSpline::LightPositionSpline()
+{
+ addControlPoint(vec3(0.0, 1.8, 0.0));
+ addControlPoint(vec3(0.0, 1.8, 0.0));
+ addControlPoint(vec3(0.0, 1.6, 0.0));
+ addControlPoint(vec3(0.0, 1.6, 0.0));
+ addControlPoint(vec3(0.0, 1.6, 0.0));
+ addControlPoint(vec3(0.0, 1.6, 0.0));
+ addControlPoint(vec3(0.0, 1.4, 0.0));
+ addControlPoint(vec3(0.0, 1.3, 0.0));
+ addControlPoint(vec3(-0.2, 1.5, 2.0));
+ addControlPoint(vec3(0.8, 1.5, -0.4));
+ addControlPoint(vec3(-0.8, 1.5, -0.4));
+ addControlPoint(vec3(0.8, 2.0, 1.0));
+ addControlPoint(vec3(1.8, 5.0, -1.8));
+ addControlPoint(vec3(8.0, 10.0, -4.0));
+ addControlPoint(vec3(8.0, 10.0, -4.0));
+ addControlPoint(vec3(8.0, 10.0, -4.0));
+ calcParams();
+}
+
+LogoPositionSpline::LogoPositionSpline()
+{
+ addControlPoint(vec3(0.0, -0.5, 0.0));
+ addControlPoint(vec3(0.0, -0.5, 0.0));
+ addControlPoint(vec3(0.0, -0.5, 0.0));
+ addControlPoint(vec3(0.0, -0.5, 0.0));
+ addControlPoint(vec3(0.0, -0.5, 0.0));
+ addControlPoint(vec3(0.0, -0.5, 0.0));
+ addControlPoint(vec3(0.0, 0.0, 0.0));
+ addControlPoint(vec3(0.0, 0.6, 0.0));
+ addControlPoint(vec3(0.0, 0.75, 0.0));
+ addControlPoint(vec3(0.0, 0.8, 0.0));
+ addControlPoint(vec3(0.0, 0.8, 0.0));
+ addControlPoint(vec3(0.0, 0.5, 0.0));
+ addControlPoint(vec3(0.0, 0.5, 0.0));
+ addControlPoint(vec3(0.0, 0.5, 0.0));
+ addControlPoint(vec3(0.0, 0.5, 0.0));
+ addControlPoint(vec3(0.0, 0.5, 0.0));
+ calcParams();
+}
+
+LogoRotationSpline::LogoRotationSpline()
+{
+ addControlPoint(vec3(0.0, 0.0, -18.4));
+ addControlPoint(vec3(0.0, 0.0, -18.4));
+ addControlPoint(vec3(0.0, 0.0, -18.4));
+ addControlPoint(vec3(0.0, 0.0, -18.4));
+ addControlPoint(vec3(0.0, 0.0, -18.4));
+ addControlPoint(vec3(0.0, 0.0, -18.4));
+ addControlPoint(vec3(0.0, 0.0, -18.4));
+ addControlPoint(vec3(0.0, 0.0, -18.4));
+ addControlPoint(vec3(240.0, 360.0, 180.0));
+ addControlPoint(vec3(90.0, 180.0, 90.0));
+ addControlPoint(vec3(11.9, 0.0, -18.4));
+ addControlPoint(vec3(11.9, 0.0, -18.4));
+ addControlPoint(vec3(11.9, 0.0, -18.4));
+ addControlPoint(vec3(11.9, 0.0, -18.4));
+ addControlPoint(vec3(11.9, 0.0, -18.4));
+ calcParams();
+}
diff --git a/src/scene-ideas/splines.h b/src/scene-ideas/splines.h
new file mode 100644
index 0000000..6e30fdd
--- /dev/null
+++ b/src/scene-ideas/splines.h
@@ -0,0 +1,83 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#ifndef SPLINES_H_
+#define SPLINES_H_
+
+#include <vector>
+#include "vec.h"
+
+class Spline
+{
+public:
+ Spline() :
+ paramData_(0) {}
+ ~Spline()
+ {
+ delete [] paramData_;
+ }
+ void addControlPoint(const LibMatrix::vec3& point) { controlData_.push_back(point); }
+ void getCurrentVec(float currentTime, LibMatrix::vec3& v) const;
+ void calcParams();
+
+private:
+ std::vector<LibMatrix::vec3> controlData_;
+ typedef LibMatrix::vec3 param[4];
+ param* paramData_;
+};
+
+class ViewFromSpline : public Spline
+{
+public:
+ ViewFromSpline();
+ ~ViewFromSpline() {}
+};
+
+class ViewToSpline : public Spline
+{
+public:
+ ViewToSpline();
+ ~ViewToSpline() {}
+};
+
+class LightPositionSpline : public Spline
+{
+public:
+ LightPositionSpline();
+ ~LightPositionSpline() {}
+};
+
+class LogoPositionSpline : public Spline
+{
+public:
+ LogoPositionSpline();
+ ~LogoPositionSpline() {}
+};
+
+class LogoRotationSpline : public Spline
+{
+public:
+ LogoRotationSpline();
+ ~LogoRotationSpline() {}
+};
+
+#endif // SPLINES_H_
diff --git a/src/scene-ideas/t.cc b/src/scene-ideas/t.cc
new file mode 100644
index 0000000..314a38e
--- /dev/null
+++ b/src/scene-ideas/t.cc
@@ -0,0 +1,147 @@
+/*
+ * Vertex position data describing the letter 't'
+ *
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "characters.h"
+
+using LibMatrix::vec2;
+
+LetterT::LetterT()
+{
+ // Vertex data...
+ vertexData_.push_back(vec2(2.986667, 14.034801));
+ vertexData_.push_back(vec2(2.445128, 10.088024));
+ vertexData_.push_back(vec2(1.788718, 9.236438));
+ vertexData_.push_back(vec2(2.264615, 7.664279));
+ vertexData_.push_back(vec2(1.165128, 5.666326));
+ vertexData_.push_back(vec2(2.034872, 4.945752));
+ vertexData_.push_back(vec2(1.132308, 3.766633));
+ vertexData_.push_back(vec2(2.182564, 3.570113));
+ vertexData_.push_back(vec2(1.411282, 2.309109));
+ vertexData_.push_back(vec2(2.510769, 2.341863));
+ vertexData_.push_back(vec2(2.149744, 1.048106));
+ vertexData_.push_back(vec2(3.364103, 1.375640));
+ vertexData_.push_back(vec2(3.167180, 0.327533));
+ vertexData_.push_back(vec2(4.381538, 0.736950));
+ vertexData_.push_back(vec2(5.005128, 0.032753));
+ vertexData_.push_back(vec2(5.612308, 0.638690));
+ vertexData_.push_back(vec2(6.235898, 0.540430));
+ vertexData_.push_back(vec2(7.187692, 1.162743));
+ vertexData_.push_back(vec2(1.985641, 9.039918));
+ vertexData_.push_back(vec2(2.133333, 10.186285));
+ vertexData_.push_back(vec2(1.509744, 9.023541));
+ vertexData_.push_back(vec2(1.608205, 9.662231));
+ vertexData_.push_back(vec2(1.050256, 9.023541));
+ vertexData_.push_back(vec2(1.050256, 9.334698));
+ vertexData_.push_back(vec2(0.196923, 9.007165));
+ vertexData_.push_back(vec2(2.363077, 9.711361));
+ vertexData_.push_back(vec2(2.264615, 9.023541));
+ vertexData_.push_back(vec2(3.282051, 9.563972));
+ vertexData_.push_back(vec2(3.446154, 9.023541));
+ vertexData_.push_back(vec2(4.069744, 9.531218));
+ vertexData_.push_back(vec2(4.299487, 9.236438));
+ vertexData_.push_back(vec2(4.644103, 9.613101));
+ vertexData_.push_back(vec2(5.251282, 9.875128));
+
+ // Index data...
+ indexData_.push_back(0);
+ indexData_.push_back(1);
+ indexData_.push_back(2);
+ indexData_.push_back(3);
+ indexData_.push_back(4);
+ indexData_.push_back(5);
+ indexData_.push_back(6);
+ indexData_.push_back(7);
+ indexData_.push_back(8);
+ indexData_.push_back(9);
+ indexData_.push_back(10);
+ indexData_.push_back(11);
+ indexData_.push_back(12);
+ indexData_.push_back(13);
+ indexData_.push_back(14);
+ indexData_.push_back(15);
+ indexData_.push_back(16);
+ indexData_.push_back(17);
+ indexData_.push_back(18);
+ indexData_.push_back(19);
+ indexData_.push_back(20);
+ indexData_.push_back(21);
+ indexData_.push_back(22);
+ indexData_.push_back(23);
+ indexData_.push_back(24);
+ indexData_.push_back(25);
+ indexData_.push_back(26);
+ indexData_.push_back(27);
+ indexData_.push_back(28);
+ indexData_.push_back(29);
+ indexData_.push_back(30);
+ indexData_.push_back(31);
+ indexData_.push_back(32);
+ indexData_.push_back(0);
+ indexData_.push_back(2);
+ indexData_.push_back(4);
+ indexData_.push_back(6);
+ indexData_.push_back(8);
+ indexData_.push_back(10);
+ indexData_.push_back(12);
+ indexData_.push_back(14);
+ indexData_.push_back(16);
+ indexData_.push_back(17);
+ indexData_.push_back(15);
+ indexData_.push_back(13);
+ indexData_.push_back(11);
+ indexData_.push_back(9);
+ indexData_.push_back(7);
+ indexData_.push_back(5);
+ indexData_.push_back(3);
+ indexData_.push_back(1);
+ indexData_.push_back(18);
+ indexData_.push_back(20);
+ indexData_.push_back(22);
+ indexData_.push_back(24);
+ indexData_.push_back(23);
+ indexData_.push_back(21);
+ indexData_.push_back(19);
+ indexData_.push_back(26);
+ indexData_.push_back(28);
+ indexData_.push_back(30);
+ indexData_.push_back(32);
+ indexData_.push_back(31);
+ indexData_.push_back(29);
+ indexData_.push_back(27);
+ indexData_.push_back(25);
+
+ // Primitive state so that the draw call can issue the primitives we want.
+ unsigned int curOffset(0);
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 18, curOffset));
+ curOffset += (18 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 7, curOffset));
+ curOffset += (7 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_TRIANGLE_STRIP, 8, curOffset));
+ curOffset += (8 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 18, curOffset));
+ curOffset += (18 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 7, curOffset));
+ curOffset += (7 * sizeof(unsigned short));
+ primVec_.push_back(PrimitiveState(GL_LINE_STRIP, 8, curOffset));
+}
diff --git a/src/scene-ideas/table.cc b/src/scene-ideas/table.cc
new file mode 100644
index 0000000..baa156e
--- /dev/null
+++ b/src/scene-ideas/table.cc
@@ -0,0 +1,353 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#include "table.h"
+#include "scene.h"
+#include "shader-source.h"
+#include "log.h"
+
+using std::string;
+using LibMatrix::vec3;
+using LibMatrix::Stack4;
+
+const string Table::modelviewName_("modelview");
+const string Table::projectionName_("projection");
+const string Table::lightPositionName_("lightPosition");
+const string Table::logoDirectionName_("logoDirection");
+const string Table::curTimeName_("currentTime");
+const string Table::vertexAttribName_("vertex");
+const unsigned int Table::TABLERES_(12);
+const vec3 Table::paperVertices_[4] = {
+ vec3(-0.8, 0.0, 0.4),
+ vec3(-0.2, 0.0, -1.4),
+ vec3(0.4, 0.0, 0.8),
+ vec3(1.0, 0.0, -1.0),
+};
+
+Table::Table() :
+ tableVertexIndex_(0),
+ paperVertexIndex_(0),
+ textVertexIndex_(0),
+ underVertexIndex_(0),
+ valid_(false)
+{
+ tableVertices_.reserve((TABLERES_ + 1) * (TABLERES_ + 1));
+ for (unsigned int i = 0; i <= TABLERES_; i++)
+ {
+ for (unsigned int j = 0; j <= TABLERES_; j++)
+ {
+ float x((static_cast<float>(i) - static_cast<float>(TABLERES_) * 1.0 / 2.0) / 2.0);
+ float z((static_cast<float>(j) - static_cast<float>(TABLERES_) * 1.0 / 2.0) / 2.0);
+ tableVertices_.push_back(vec3(x, 0.0, z));
+ }
+ }
+
+ // Now that we've setup the vertex data, we can setup the map of how
+ // that data will be laid out in the buffer object.
+ dataMap_.tvOffset = 0;
+ dataMap_.tvSize = tableVertices_.size() * sizeof(vec3);
+ dataMap_.totalSize = dataMap_.tvSize;
+ dataMap_.pvOffset = dataMap_.tvOffset + dataMap_.tvSize;
+ dataMap_.pvSize = 4 * sizeof(vec3);
+ dataMap_.totalSize += dataMap_.pvSize;
+
+ for (unsigned int i = 0; i < TABLERES_; i++)
+ {
+ for (unsigned int j = 0; j <= TABLERES_; j++)
+ {
+ unsigned int curIndex1(i * (TABLERES_ + 1) + j);
+ unsigned int curIndex2((i + 1) * (TABLERES_ + 1) + j);
+ indexData_.push_back(curIndex1);
+ indexData_.push_back(curIndex2);
+ }
+ }
+}
+
+Table::~Table(void)
+{
+ if (valid_)
+ {
+ glDeleteBuffers(2, &bufferObjects_[0]);
+ }
+}
+
+void
+Table::init(void)
+{
+ // Make sure we don't re-initialize...
+ if (valid_)
+ {
+ return;
+ }
+
+ // Initialize shader sources from input files and create programs from them
+ // Program to render the table with lighting and a time-based fade...
+ string table_vtx_filename(GLMARK_DATA_PATH"/shaders/ideas-table.vert");
+ string table_frg_filename(GLMARK_DATA_PATH"/shaders/ideas-table.frag");
+ ShaderSource table_vtx_source(table_vtx_filename);
+ ShaderSource table_frg_source(table_frg_filename);
+ if (!Scene::load_shaders_from_strings(tableProgram_, table_vtx_source.str(),
+ table_frg_source.str()))
+ {
+ Log::error("No valid program for table rendering.\n");
+ return;
+ }
+ textVertexIndex_ = tableProgram_[vertexAttribName_].location();
+
+ // Program to render the paper with lighting and a time-based fade...
+ string paper_vtx_filename(GLMARK_DATA_PATH"/shaders/ideas-paper.vert");
+ string paper_frg_filename(GLMARK_DATA_PATH"/shaders/ideas-paper.frag");
+ ShaderSource paper_vtx_source(paper_vtx_filename);
+ ShaderSource paper_frg_source(paper_frg_filename);
+ if (!Scene::load_shaders_from_strings(paperProgram_, paper_vtx_source.str(),
+ paper_frg_source.str()))
+ {
+ Log::error("No valid program for paper rendering.\n");
+ return;
+ }
+ paperVertexIndex_ = paperProgram_[vertexAttribName_].location();
+
+ // Program to handle the text (time-based color fade)...
+ string text_vtx_filename(GLMARK_DATA_PATH"/shaders/ideas-text.vert");
+ string text_frg_filename(GLMARK_DATA_PATH"/shaders/ideas-text.frag");
+ ShaderSource text_vtx_source(text_vtx_filename);
+ ShaderSource text_frg_source(text_frg_filename);
+ if (!Scene::load_shaders_from_strings(textProgram_, text_vtx_source.str(),
+ text_frg_source.str()))
+ {
+ Log::error("No valid program for text rendering.\n");
+ return;
+ }
+ textVertexIndex_ = textProgram_[vertexAttribName_].location();
+
+ // Program for the drawUnder functionality (just paint it black)...
+ string under_table_vtx_filename(GLMARK_DATA_PATH"/shaders/ideas-under-table.vert");
+ string under_table_frg_filename(GLMARK_DATA_PATH"/shaders/ideas-under-table.frag");
+ ShaderSource under_table_vtx_source(under_table_vtx_filename);
+ ShaderSource under_table_frg_source(under_table_frg_filename);
+ if (!Scene::load_shaders_from_strings(underProgram_, under_table_vtx_source.str(),
+ under_table_frg_source.str()))
+ {
+ Log::error("No valid program for under table rendering.\n");
+ return;
+ }
+ underVertexIndex_ = underProgram_[vertexAttribName_].location();
+
+ // Tell all of the characters to initialize themselves...
+ i_.init(textVertexIndex_);
+ d_.init(textVertexIndex_);
+ e_.init(textVertexIndex_);
+ a_.init(textVertexIndex_);
+ s_.init(textVertexIndex_);
+ n_.init(textVertexIndex_);
+ m_.init(textVertexIndex_);
+ o_.init(textVertexIndex_);
+ t_.init(textVertexIndex_);
+
+ // We need 2 buffers for our work here. One for the vertex data.
+ // and one for the index data.
+ glGenBuffers(2, &bufferObjects_[0]);
+
+ // First, setup the vertex data by binding the first buffer object,
+ // allocating its data store, and filling it in with our vertex data.
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]);
+ glBufferData(GL_ARRAY_BUFFER, dataMap_.totalSize, 0, GL_STATIC_DRAW);
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.tvOffset, dataMap_.tvSize,
+ &tableVertices_.front());
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.pvOffset, dataMap_.pvSize,
+ &paperVertices_[0]);
+
+ // Now repeat for our index data.
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexData_.size() * sizeof(unsigned short),
+ &indexData_.front(), GL_STATIC_DRAW);
+
+ // We're ready to go.
+ valid_ = true;
+}
+
+void
+Table::draw(Stack4& modelview,
+ Stack4& projection,
+ const vec3& lightPos,
+ const vec3& logoPos,
+ const float& currentTime,
+ float& paperAlpha_out)
+{
+ glDisable(GL_DEPTH_TEST);
+
+ // Compute the light direction with respect to the logo...
+ vec3 logoDirection(lightPos.x() - logoPos.x(), lightPos.y() - logoPos.y(),
+ lightPos.z() - logoPos.z());
+ logoDirection.normalize();
+
+ // Compute the alpha component based upon drawing the paper (all of this will
+ // be done in the shader, but we need to pass this back so that the logo's
+ // shadow will look right).
+ for (unsigned int i = 0; i < 4; i++)
+ {
+ vec3 lightDirection(lightPos.x() - paperVertices_[i].x(),
+ lightPos.y() - paperVertices_[i].y(),
+ lightPos.z() - paperVertices_[i].z());
+ lightDirection.normalize();
+ float c = vec3::dot(lightDirection, logoDirection);
+ if (c < 0.0)
+ {
+ c = 0.0;
+ }
+ c = c * c * c * lightDirection.y();
+ if ((currentTime > 10.0) && (currentTime < 12.0))
+ {
+ c *= 1.0 - (currentTime - 10.0) * 0.5;
+ }
+ paperAlpha_out += c;
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]);
+
+ // Draw the table top
+ tableProgram_.start();
+ tableProgram_[projectionName_] = projection.getCurrent();
+ tableProgram_[modelviewName_] = modelview.getCurrent();
+ tableProgram_[lightPositionName_] = lightPos;
+ tableProgram_[logoDirectionName_] = logoDirection;
+ tableProgram_[curTimeName_] = currentTime;
+ glVertexAttribPointer(tableVertexIndex_, 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.tvOffset));
+ glEnableVertexAttribArray(tableVertexIndex_);
+ static const unsigned int twiceRes(2 * (TABLERES_ + 1));
+ for (unsigned int i = 0; i < TABLERES_; i++)
+ {
+ glDrawElements(GL_TRIANGLE_STRIP, twiceRes, GL_UNSIGNED_SHORT,
+ reinterpret_cast<const GLvoid*>(i * twiceRes * sizeof(unsigned short)));
+ }
+ glDisableVertexAttribArray(tableVertexIndex_);
+ tableProgram_.stop();
+
+ if (logoPos.y() > -0.33 && logoPos.y() < 0.33)
+ {
+ glEnable(GL_DEPTH_TEST);
+ }
+
+ // Draw the paper lying on the table top
+ paperProgram_.start();
+ paperProgram_[projectionName_] = projection.getCurrent();
+ paperProgram_[modelviewName_] = modelview.getCurrent();
+ paperProgram_[lightPositionName_] = lightPos;
+ paperProgram_[logoDirectionName_] = logoDirection;
+ paperProgram_[curTimeName_] = currentTime;
+ glVertexAttribPointer(paperVertexIndex_, 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.pvOffset));
+ glEnableVertexAttribArray(paperVertexIndex_);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glDisableVertexAttribArray(paperVertexIndex_);
+ paperProgram_.stop();
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ glDisable(GL_DEPTH_TEST);
+
+ modelview.push();
+ modelview.rotate(-18.4, 0.0, 1.0, 0.0);
+ modelview.translate(-0.3, 0.0, -0.8);
+ modelview.rotate(-90.0, 1.0, 0.0, 0.0);
+ modelview.scale(0.015, 0.015, 0.015);
+
+ // Draw the text on the paper lying on the table top.
+ // Each character has its own array and element buffers, and they have
+ // been initialized with the vertex attrib location for this program.
+ textProgram_.start();
+ textProgram_[projectionName_] = projection.getCurrent();
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ textProgram_[curTimeName_] = currentTime;
+ i_.draw();
+ modelview.translate(3.0, 0.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ d_.draw();
+ modelview.translate(6.0, 0.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ e_.draw();
+ modelview.translate(5.0, 0.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ a_.draw();
+ modelview.translate(6.0, 0.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ s_.draw();
+ modelview.translate(10.0, 0.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ i_.draw();
+ modelview.translate(3.0, 0.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ n_.draw();
+ modelview.translate(-31.0, -13.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ m_.draw();
+ modelview.translate(10.0, 0.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ o_.draw();
+ modelview.translate(5.0, 0.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ t_.draw();
+ modelview.translate(4.0, 0.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ i_.draw();
+ modelview.translate(3.5, 0.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ o_.draw();
+ modelview.translate(5.0, 0.0, 0.0);
+ textProgram_[modelviewName_] = modelview.getCurrent();
+ n_.draw();
+ textProgram_.stop();
+
+ modelview.pop();
+}
+
+void
+Table::drawUnder(Stack4& modelview, Stack4& projection)
+{
+ glDisable(GL_DEPTH_TEST);
+
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]);
+
+ underProgram_.start();
+ underProgram_[modelviewName_] = modelview.getCurrent();
+ underProgram_[projectionName_] = projection.getCurrent();
+ glVertexAttribPointer(underVertexIndex_, 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.tvOffset));
+ glEnableVertexAttribArray(underVertexIndex_);
+ static const unsigned int twiceRes(2 * (TABLERES_ + 1));
+ for (unsigned int i = 0; i < TABLERES_; i++)
+ {
+ glDrawElements(GL_TRIANGLE_STRIP, twiceRes, GL_UNSIGNED_SHORT,
+ reinterpret_cast<const GLvoid*>(i * twiceRes * sizeof(unsigned short)));
+ }
+ glDisableVertexAttribArray(underVertexIndex_);
+ underProgram_.stop();
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ glEnable(GL_DEPTH_TEST);
+}
diff --git a/src/scene-ideas/table.h b/src/scene-ideas/table.h
new file mode 100644
index 0000000..1ede1bc
--- /dev/null
+++ b/src/scene-ideas/table.h
@@ -0,0 +1,94 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Jesse Barker
+ */
+#ifndef TABLE_H_
+#define TABLE_H_
+
+#include <string>
+#include <vector>
+#include "characters.h"
+#include "program.h"
+#include "stack.h"
+
+class Table
+{
+public:
+ Table();
+ ~Table();
+
+ void init();
+ bool valid() const { return valid_; }
+ void draw(LibMatrix::Stack4& modelview, LibMatrix::Stack4& projection,
+ const LibMatrix::vec3& lightPosition, const LibMatrix::vec3& logoPosition,
+ const float& currentTime, float& paperAlpha_out);
+ void drawUnder(LibMatrix::Stack4& modelview, LibMatrix::Stack4& projection);
+
+private:
+ // Text
+ LetterI i_;
+ LetterD d_;
+ LetterE e_;
+ LetterA a_;
+ LetterS s_;
+ LetterN n_;
+ LetterM m_;
+ LetterO o_;
+ LetterT t_;
+ Program tableProgram_;
+ Program paperProgram_;
+ Program textProgram_;
+ Program underProgram_;
+ std::string tableVertexShader_;
+ std::string tableFragmentShader_;
+ std::string paperVertexShader_;
+ std::string paperFragmentShader_;
+ std::string textVertexShader_;
+ std::string textFragmentShader_;
+ std::string underVertexShader_;
+ std::string underFragmentShader_;
+ static const std::string modelviewName_;
+ static const std::string projectionName_;
+ static const std::string lightPositionName_;
+ static const std::string logoDirectionName_;
+ static const std::string curTimeName_;
+ static const std::string vertexAttribName_;
+ static const unsigned int TABLERES_;
+ std::vector<LibMatrix::vec3> tableVertices_;
+ static const LibMatrix::vec3 paperVertices_[4];
+ struct VertexDataMap
+ {
+ unsigned int tvOffset;
+ unsigned int tvSize;
+ unsigned int pvOffset;
+ unsigned int pvSize;
+ unsigned int totalSize;
+ } dataMap_;
+ unsigned int bufferObjects_[2];
+ std::vector<unsigned short> indexData_;
+ int tableVertexIndex_;
+ int paperVertexIndex_;
+ int textVertexIndex_;
+ int underVertexIndex_;
+ bool valid_;
+};
+
+#endif // TABLE_H_
diff --git a/src/scene-jellyfish.cpp b/src/scene-jellyfish.cpp
new file mode 100644
index 0000000..bc18ee3
--- /dev/null
+++ b/src/scene-jellyfish.cpp
@@ -0,0 +1,631 @@
+//
+// Copyright © 2012 Linaro Limited
+//
+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+//
+// glmark2 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 3 of the License, or (at your option) any later
+// version.
+//
+// glmark2 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
+// glmark2. If not, see <http://www.gnu.org/licenses/>.
+//
+// Authors:
+// Aleksandar Rodic - Creator and WebGL implementation
+// Jesse Barker - glmark2 port
+//
+#include <string>
+#include <fstream>
+#include <memory>
+#include <iomanip>
+#include "scene.h"
+#include "scene-jellyfish.h"
+#include "log.h"
+#include "util.h"
+#include "texture.h"
+#include "shader-source.h"
+
+SceneJellyfish::SceneJellyfish(Canvas& canvas) :
+ Scene(canvas, "jellyfish"), priv_(0)
+{
+
+}
+
+SceneJellyfish::~SceneJellyfish()
+{
+ delete priv_;
+}
+
+bool
+SceneJellyfish::load()
+{
+ running_ = false;
+ return true;
+}
+
+void
+SceneJellyfish::unload()
+{
+}
+
+bool
+SceneJellyfish::setup()
+{
+ if (!Scene::setup())
+ return false;
+
+ // Set up our private object that does all of the lifting
+ priv_ = new JellyfishPrivate();
+ if (!priv_->initialize())
+ return false;
+
+ // Set core scene timing after actual initialization so we don't measure
+ // set up time.
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+ running_ = true;
+
+ return true;
+}
+
+void
+SceneJellyfish::teardown()
+{
+ priv_->cleanup();
+ Scene::teardown();
+}
+
+void
+SceneJellyfish::update()
+{
+ Scene::update();
+ priv_->update_viewport(LibMatrix::vec2(canvas_.width(), canvas_.height()));
+ priv_->update_time();
+}
+
+void
+SceneJellyfish::draw()
+{
+ priv_->draw();
+}
+
+Scene::ValidationResult
+SceneJellyfish::validate()
+{
+ return Scene::ValidationUnknown;
+}
+
+
+//
+// JellyfishPrivate implementation
+//
+using LibMatrix::mat4;
+using LibMatrix::vec3;
+using LibMatrix::vec2;
+using std::string;
+using std::vector;
+
+bool
+GradientRenderer::init()
+{
+ // Program set up
+ static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/gradient.vert");
+ static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/gradient.frag");
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return false;
+ }
+ positionLocation_ = program_["position"].location();
+ uvLocation_ = program_["uvIn"].location();
+
+ // Set up the position data for our "quad".
+ vertices_.push_back(vec2(-1.0, -1.0));
+ vertices_.push_back(vec2(1.0, -1.0));
+ vertices_.push_back(vec2(-1.0, 1.0));
+ vertices_.push_back(vec2(1.0, 1.0));
+ uvs_.push_back(vec2(1.0, 1.0));
+ uvs_.push_back(vec2(1.0, 1.0));
+ uvs_.push_back(vec2(0.0, 0.0));
+ uvs_.push_back(vec2(0.0, 0.0));
+ uvOffset_ = vertices_.size() * sizeof(vec2);
+
+ // Set up the VBO and stash our position data in it.
+ glGenBuffers(1, &bufferObject_);
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObject_);
+ glBufferData(GL_ARRAY_BUFFER, (vertices_.size() + uvs_.size()) * sizeof(vec2),
+ 0, GL_STATIC_DRAW);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, vertices_.size() * sizeof(vec2),
+ &vertices_.front());
+ glBufferSubData(GL_ARRAY_BUFFER, uvOffset_, uvs_.size() * sizeof(vec2),
+ &uvs_.front());
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ return true;
+}
+
+void
+GradientRenderer::cleanup()
+{
+ program_.stop();
+ program_.release();
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glDeleteBuffers(1, &bufferObject_);
+}
+
+void
+GradientRenderer::draw()
+{
+ static const vec3 lightBlue(0.360784314, 0.584313725, 1.0);
+ static const vec3 darkBlue(0.074509804, 0.156862745, 0.619607843);
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObject_);
+ program_.start();
+ program_["color1"] = lightBlue;
+ program_["color2"] = darkBlue;
+ glEnableVertexAttribArray(positionLocation_);
+ glEnableVertexAttribArray(uvLocation_);
+ glVertexAttribPointer(positionLocation_, 2, GL_FLOAT, GL_FALSE, 0, 0);
+ glVertexAttribPointer(uvLocation_, 2, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<GLvoid*>(uvOffset_));
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glDisableVertexAttribArray(positionLocation_);
+ glDisableVertexAttribArray(uvLocation_);
+ program_.stop();
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+//!
+// Parse index values from an OBJ file.
+//
+// @param source the source line to parse
+// @param idx the unsigned short to populate
+//
+static void
+obj_get_index(const string& source, unsigned short& idx)
+{
+ // Skip the definition type...
+ string::size_type endPos = source.find(" ");
+ string::size_type startPos(0);
+ if (endPos == string::npos)
+ {
+ Log::error("Bad element '%s'\n", source.c_str());
+ return;
+ }
+ // Find the first value...
+ startPos = endPos + 1;
+ string is(source, startPos);
+ idx = Util::fromString<unsigned short>(is);
+}
+
+//!
+// Parse vec3 values from an OBJ file.
+//
+// @param source the source line to parse
+// @param v the vec3 to populate
+//
+static void
+obj_get_values(const string& source, vec3& v)
+{
+ // Skip the definition type...
+ string::size_type endPos = source.find(" ");
+ string::size_type startPos(0);
+ if (endPos == string::npos)
+ {
+ Log::error("Bad element '%s'\n", source.c_str());
+ return;
+ }
+ // Find the first value...
+ startPos = endPos + 1;
+ endPos = source.find(" ", startPos);
+ if (endPos == string::npos)
+ {
+ Log::error("Bad element '%s'\n", source.c_str());
+ return;
+ }
+ string::size_type numChars(endPos - startPos);
+ string xs(source, startPos, numChars);
+ float x = Util::fromString<float>(xs);
+ // Then the second value...
+ startPos = endPos + 1;
+ endPos = source.find(" ", startPos);
+ if (endPos == string::npos)
+ {
+ Log::error("Bad element '%s'\n", source.c_str());
+ return;
+ }
+ numChars = endPos - startPos;
+ string ys(source, startPos, numChars);
+ float y = Util::fromString<float>(ys);
+ // And the third value (there might be a fourth, but we don't care)...
+ startPos = endPos + 1;
+ endPos = source.find(" ", startPos);
+ if (endPos == string::npos)
+ {
+ numChars = endPos;
+ }
+ else
+ {
+ numChars = endPos - startPos;
+ }
+ string zs(source, startPos, endPos - startPos);
+ float z = Util::fromString<float>(zs);
+ v.x(x);
+ v.y(y);
+ v.z(z);
+}
+
+// Custom OBJ loader.
+//
+// To support the jellyfish model, some amendments to the OBJ format are
+// necessary. In particular, a vertex color attribute is required, and
+// it contains an index list rather than a face list.
+bool
+JellyfishPrivate::load_obj(const std::string &filename)
+{
+ Log::debug("Loading model from file '%s'\n", filename.c_str());
+
+ const std::auto_ptr<std::istream> input_file_ptr(Util::get_resource(filename));
+ std::istream& inputFile(*input_file_ptr);
+ if (!inputFile)
+ {
+ Log::error("Failed to open '%s'\n", filename.c_str());
+ return false;
+ }
+
+ vector<string> sourceVec;
+ string curLine;
+ while (getline(inputFile, curLine))
+ {
+ sourceVec.push_back(curLine);
+ }
+
+ static const string vertex_definition("v");
+ static const string normal_definition("vn");
+ static const string texcoord_definition("vt");
+ static const string color_definition("vc");
+ static const string index_definition("i");
+ for (vector<string>::const_iterator lineIt = sourceVec.begin();
+ lineIt != sourceVec.end();
+ lineIt++)
+ {
+ const string& curSrc = *lineIt;
+ // Is it a vertex attribute, a face description, comment or other?
+ // We only care about the first two, we ignore comments, object names,
+ // group names, smoothing groups, etc.
+ string::size_type startPos(0);
+ string::size_type spacePos = curSrc.find(" ", startPos);
+ string definitionType(curSrc, startPos, spacePos - startPos);
+ if (definitionType == vertex_definition)
+ {
+ vec3 v;
+ obj_get_values(curSrc, v);
+ positions_.push_back(v);
+ }
+ else if (definitionType == normal_definition)
+ {
+ vec3 v;
+ obj_get_values(curSrc, v);
+ normals_.push_back(v);
+ }
+ else if (definitionType == color_definition)
+ {
+ vec3 v;
+ obj_get_values(curSrc, v);
+ colors_.push_back(v);
+ }
+ else if (definitionType == texcoord_definition)
+ {
+ vec3 v;
+ obj_get_values(curSrc, v);
+ texcoords_.push_back(v);
+ }
+ else if (definitionType == index_definition)
+ {
+ unsigned short idx(0);
+ obj_get_index(curSrc, idx);
+ indices_.push_back(idx);
+ }
+ }
+
+ Log::debug("Object populated with %u vertices %u normals %u colors %u texcoords and %u indices.\n",
+ positions_.size(), normals_.size(), colors_.size(), texcoords_.size(), indices_.size());
+ return true;
+}
+
+JellyfishPrivate::JellyfishPrivate() :
+ positionLocation_(0),
+ normalLocation_(0),
+ colorLocation_(0),
+ texcoordLocation_(0),
+ viewport_(512.0, 512.0),
+ lightPosition_(10.0, 40.0, -60.0),
+ lightColor_(0.8, 1.3, 1.1, 1.0),
+ lightRadius_(200.0),
+ ambientColor_(0.3, 0.2, 1.0, 1.0),
+ fresnelColor_(0.8, 0.7, 0.6, 1.1),
+ fresnelPower_(1.0),
+ rotation_(0.0),
+ currentTime_(0.0),
+ lastUpdateTime_(0.0),
+ cullFace_(0),
+ depthTest_(0),
+ blend_(0),
+ blendFuncSrc_(0),
+ blendFuncDst_(0)
+{
+}
+
+JellyfishPrivate::~JellyfishPrivate()
+{
+ positions_.clear();
+ normals_.clear();
+ colors_.clear();
+ texcoords_.clear();
+ indices_.clear();
+}
+
+bool
+JellyfishPrivate::initialize()
+{
+ static const string modelFilename(GLMARK_DATA_PATH"/models/jellyfish.jobj");
+ if (!load_obj(modelFilename))
+ {
+ return false;
+ }
+
+ // Now that we've setup the vertex data, we can setup the map of how
+ // that data will be laid out in the buffer object.
+ static const unsigned int sv3(sizeof(vec3));
+ dataMap_.positionOffset = 0;
+ dataMap_.positionSize = positions_.size() * sv3;
+ dataMap_.totalSize = dataMap_.positionSize;
+ dataMap_.normalOffset = dataMap_.positionOffset + dataMap_.positionSize;
+ dataMap_.normalSize = normals_.size() * sv3;
+ dataMap_.totalSize += dataMap_.normalSize;
+ dataMap_.colorOffset = dataMap_.normalOffset + dataMap_.normalSize;
+ dataMap_.colorSize = colors_.size() * sv3;
+ dataMap_.totalSize += dataMap_.colorSize;
+ dataMap_.texcoordOffset = dataMap_.colorOffset + dataMap_.colorSize;
+ dataMap_.texcoordSize = texcoords_.size() * sv3;
+ dataMap_.totalSize += dataMap_.texcoordSize;
+
+ lastUpdateTime_ = Util::get_timestamp_us() / 1000.0;
+ currentTime_ = static_cast<uint64_t>(lastUpdateTime_) % 100000000 / 1000.0;
+ whichCaustic_ = static_cast<uint64_t>(currentTime_ * 30) % 32 + 1;
+ rotation_ = 0.0;
+
+ if (!gradient_.init())
+ {
+ return false;
+ }
+
+ // Set up program first so we can store attribute and uniform locations
+ // away for the
+ using std::string;
+ static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/jellyfish.vert");
+ static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/jellyfish.frag");
+
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return false;
+ }
+
+ // Stash away attribute and uniform locations for handy use.
+ positionLocation_ = program_["aVertexPosition"].location();
+ normalLocation_ = program_["aVertexNormal"].location();
+ colorLocation_ = program_["aVertexColor"].location();
+ texcoordLocation_ = program_["aTextureCoord"].location();
+
+ // We need 2 buffers for our work here. One for the vertex data.
+ // and one for the index data.
+ glGenBuffers(2, &bufferObjects_[0]);
+
+ // First, setup the vertex data by binding the first buffer object,
+ // allocating its data store, and filling it in with our vertex data.
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]);
+ glBufferData(GL_ARRAY_BUFFER, dataMap_.totalSize, 0, GL_STATIC_DRAW);
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.positionOffset,
+ dataMap_.positionSize, &positions_.front());
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.normalOffset,
+ dataMap_.normalSize, &normals_.front());
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.colorOffset,
+ dataMap_.colorSize, &colors_.front());
+ glBufferSubData(GL_ARRAY_BUFFER, dataMap_.texcoordOffset,
+ dataMap_.texcoordSize, &texcoords_.front());
+
+ // Now repeat for our index data.
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_.size() * sizeof(unsigned short),
+ &indices_.front(), GL_STATIC_DRAW);
+
+ // "Unbind" our buffer objects to make sure the state is consistent.
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ // Finally, set up our textures.
+ //
+ // First, the main jellyfish texture
+ bool gotTex = Texture::load("jellyfish256", &textureObjects_[0], GL_LINEAR,
+ GL_LINEAR, 0);
+ if (!gotTex || textureObjects_[0] == 0)
+ {
+ Log::error("Jellyfish texture set up failed!!!\n");
+ return false;
+ }
+ glBindTexture(GL_TEXTURE_2D, 0);
+ // Then, the caustics textures
+ static const string baseName("jellyfish-caustics-");
+ for (unsigned int i = 1; i < 33; i++)
+ {
+ std::stringstream ss;
+ ss << std::setw(2) << std::setfill('0') << i;
+ string curName(baseName);
+ curName += ss.str();
+ gotTex = Texture::load(curName, &textureObjects_[i], GL_LINEAR,
+ GL_LINEAR, 0);
+ if (!gotTex || textureObjects_[i] == 0)
+ {
+ Log::error("Caustics texture[%u] set up failed!!!\n", i);
+ return false;
+ }
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+
+ // Save the GL state we are changing so we can restore it later.
+ cullFace_ = glIsEnabled(GL_CULL_FACE);
+ depthTest_ = glIsEnabled(GL_DEPTH_TEST);
+ blend_ = glIsEnabled(GL_BLEND);
+ glGetIntegerv(GL_BLEND_SRC_RGB, &blendFuncSrc_);
+ glGetIntegerv(GL_BLEND_DST_RGB, &blendFuncDst_);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+
+ return true;
+}
+
+void
+JellyfishPrivate::update_viewport(const vec2& vp)
+{
+ if (viewport_.x() == vp.x() && viewport_.y() == vp.y())
+ {
+ return;
+ }
+ viewport_ = vp;
+ projection_.loadIdentity();
+ projection_.perspective(30.0, viewport_.x()/viewport_.y(), 20.0, 120.0);
+}
+
+void
+JellyfishPrivate::update_time()
+{
+ double now = Util::get_timestamp_us() / 1000.0;
+ double elapsedTime = now - lastUpdateTime_;
+ rotation_ += (2.0 * elapsedTime) / 1000.0;
+ currentTime_ = static_cast<uint64_t>(now) % 100000000 / 1000.0;
+ whichCaustic_ = static_cast<uint64_t>(currentTime_ * 30) % 32 + 1;
+ lastUpdateTime_ = now;
+}
+
+void
+JellyfishPrivate::cleanup()
+{
+ // Restore the GL state we changed for the scene.
+ glBlendFunc(blendFuncSrc_, blendFuncDst_);
+ if (GL_FALSE == blend_)
+ {
+ glDisable(GL_BLEND);
+ }
+ if (GL_TRUE == cullFace_)
+ {
+ glEnable(GL_CULL_FACE);
+ }
+ if (GL_TRUE == depthTest_)
+ {
+ glEnable(GL_DEPTH_TEST);
+ }
+
+ program_.stop();
+ program_.release();
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ glDeleteTextures(33, &textureObjects_[0]);
+ glDeleteBuffers(2, &bufferObjects_[0]);
+
+ gradient_.cleanup();
+}
+
+void
+JellyfishPrivate::draw()
+{
+ // "Clear" the background to the desired gradient.
+ gradient_.draw();
+
+ // We need "world", "world view projection", and "world inverse transpose"
+ // matrix uniforms for the current shader.
+ //
+ // NOTE: Some of this seems a bit of a no-op (e.g., multipying by and
+ // inverting identity matrices), but leave it like the original
+ // WebGL files for the time being. Worth revisiting not doing all
+ // of that math every draw call (might even be good to be doing
+ // some of it in the shader as well).
+ world_.push();
+ world_.translate(0.0, 5.0, -75.0);
+ world_.rotate(sin(rotation_ / 10.0) * 30.0, 0.0, 1.0, 0.0);
+ world_.rotate(sin(rotation_ / 20.0) * 30.0, 1.0, 0.0, 0.0);
+ world_.scale(5.0, 5.0, 5.0);
+ world_.translate(0.0, sin(rotation_ / 10.0) * 2.5, 0.0);
+ mat4 worldViewProjection(projection_.getCurrent());
+ worldViewProjection *= world_.getCurrent();;
+ mat4 worldInverseTranspose(world_.getCurrent());
+ worldInverseTranspose.inverse().transpose();
+
+ // Load up the uniforms
+ program_.start();
+ program_["uWorld"] = world_.getCurrent();
+ program_["uWorldViewProj"] = worldViewProjection;
+ program_["uWorldInvTranspose"] = worldInverseTranspose;
+ program_["uCurrentTime"] = currentTime_;
+ // Revisit making these constants rather than uniforms as they appear never
+ // to change
+ program_["uLightPos"] = lightPosition_;
+ program_["uLightRadius"] = lightRadius_;
+ program_["uLightCol"] = lightColor_;
+ program_["uAmbientCol"] = ambientColor_;
+ program_["uFresnelCol"] = fresnelColor_;
+ program_["uFresnelPower"] = fresnelPower_;
+ // Set up textures for this frame.
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, textureObjects_[0]);
+ program_["uSampler"] = 0;
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, textureObjects_[whichCaustic_]);
+ program_["uSampler1"] = 1;
+
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]);
+
+ glEnableVertexAttribArray(positionLocation_);
+ glEnableVertexAttribArray(normalLocation_);
+ glEnableVertexAttribArray(colorLocation_);
+ glEnableVertexAttribArray(texcoordLocation_);
+ glVertexAttribPointer(positionLocation_ , 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.positionOffset));
+ glVertexAttribPointer(normalLocation_ , 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.normalOffset));
+ glVertexAttribPointer(colorLocation_ , 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.colorOffset));
+ glVertexAttribPointer(texcoordLocation_ , 3, GL_FLOAT, GL_FALSE, 0,
+ reinterpret_cast<const GLvoid*>(dataMap_.texcoordOffset));
+
+ glDrawElements(GL_TRIANGLES, indices_.size(), GL_UNSIGNED_SHORT, 0);
+
+ glDisableVertexAttribArray(positionLocation_);
+ glDisableVertexAttribArray(normalLocation_);
+ glDisableVertexAttribArray(colorLocation_);
+ glDisableVertexAttribArray(texcoordLocation_);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ program_.stop();
+ world_.pop();
+}
diff --git a/src/scene-jellyfish.h b/src/scene-jellyfish.h
new file mode 100644
index 0000000..1e0db3a
--- /dev/null
+++ b/src/scene-jellyfish.h
@@ -0,0 +1,124 @@
+//
+// Copyright © 2012 Linaro Limited
+//
+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+//
+// glmark2 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 3 of the License, or (at your option) any later
+// version.
+//
+// glmark2 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
+// glmark2. If not, see <http://www.gnu.org/licenses/>.
+//
+// Authors:
+// Aleksandar Rodic - Creator and WebGL implementation
+// Jesse Barker - glmark2 port
+//
+#ifndef SCENE_JELLYFISH_
+#define SCENE_JELLYFISH_
+#include <vector>
+#include "vec.h"
+#include "stack.h"
+#include "program.h"
+
+class GradientRenderer
+{
+ Program program_;
+ int positionLocation_;
+ int uvLocation_;
+ unsigned int uvOffset_;
+ unsigned int bufferObject_;
+ std::vector<LibMatrix::vec2> vertices_;
+ std::vector<LibMatrix::vec2> uvs_;
+
+public:
+ GradientRenderer() :
+ positionLocation_(0),
+ uvLocation_(0),
+ uvOffset_(0),
+ bufferObject_(0) {}
+ ~GradientRenderer()
+ {
+ vertices_.clear();
+ uvs_.clear();
+ }
+ bool init();
+ void cleanup();
+ void draw();
+};
+
+class JellyfishPrivate
+{
+ bool load_obj(const std::string& filename);
+
+ // For the background gradient.
+ GradientRenderer gradient_;
+
+ // Vertex data.
+ std::vector<LibMatrix::vec3> positions_;
+ std::vector<LibMatrix::vec3> normals_;
+ std::vector<LibMatrix::vec3> colors_;
+ std::vector<LibMatrix::vec3> texcoords_;
+ std::vector<unsigned short> indices_;
+ // A simple map so we know where each section of our data starts within
+ // our vertex buffer object.
+ struct VertexDataMap
+ {
+ unsigned int positionOffset;
+ unsigned int positionSize;
+ unsigned int normalOffset;
+ unsigned int normalSize;
+ unsigned int colorOffset;
+ unsigned int colorSize;
+ unsigned int texcoordOffset;
+ unsigned int texcoordSize;
+ unsigned int totalSize;
+ } dataMap_;
+ // Object handles
+ unsigned int bufferObjects_[2];
+ unsigned int textureObjects_[33];
+ unsigned int whichCaustic_;
+ std::map<std::string, unsigned int> causticMap_;
+
+ // Program state, including attributes, uniforms, and, locations.
+ Program program_;
+ int positionLocation_;
+ int normalLocation_;
+ int colorLocation_;
+ int texcoordLocation_;
+ LibMatrix::vec2 viewport_;
+ LibMatrix::Stack4 world_;
+ LibMatrix::Stack4 projection_;
+ LibMatrix::vec3 lightPosition_;
+ LibMatrix::vec4 lightColor_;
+ float lightRadius_;
+ LibMatrix::vec4 ambientColor_;
+ LibMatrix::vec4 fresnelColor_;
+ float fresnelPower_;
+ float rotation_;
+ float currentTime_;
+ double lastUpdateTime_;
+ // GL state we plan to override, so we can restore it cleanly.
+ unsigned int cullFace_;
+ unsigned int depthTest_;
+ unsigned int blend_;
+ int blendFuncSrc_;
+ int blendFuncDst_;
+
+public:
+ JellyfishPrivate();
+ ~JellyfishPrivate();
+ bool initialize();
+ void update_viewport(const LibMatrix::vec2& viewport);
+ void update_time();
+ void cleanup();
+ void draw();
+};
+
+#endif // SCENE_JELLYFISH_
diff --git a/src/scene-loop.cpp b/src/scene-loop.cpp
new file mode 100644
index 0000000..564a2fe
--- /dev/null
+++ b/src/scene-loop.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#include <cmath>
+
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "shader-source.h"
+#include "util.h"
+
+static const std::string shader_file_base(GLMARK_DATA_PATH"/shaders/loop");
+
+static const std::string vtx_file(shader_file_base + ".vert");
+static const std::string frg_file(shader_file_base + ".frag");
+static const std::string step_simple_file(shader_file_base + "-step-simple.all");
+static const std::string step_loop_file(shader_file_base + "-step-loop.all");
+
+SceneLoop::SceneLoop(Canvas &pCanvas) :
+ SceneGrid(pCanvas, "loop")
+{
+ options_["fragment-steps"] = Scene::Option("fragment-steps", "1",
+ "The number of computational steps in the fragment shader");
+ options_["fragment-loop"] = Scene::Option("fragment-function", "true",
+ "Whether to execute the steps in the vertex shader using a for loop", "false,true");
+ options_["vertex-steps"] = Scene::Option("vertex-steps", "1",
+ "The number of computational steps in the vertex shader");
+ options_["vertex-loop"] = Scene::Option("vertex-function", "true",
+ "Whether to execute the steps in the vertex shader using a for loop", "false,true");
+ options_["vertex-uniform"] = Scene::Option("vertex-uniform", "true",
+ "Whether to use a uniform in the vertex shader for the number of loop iterations to perform (i.e. vertex-steps)",
+ "false,true");
+ options_["fragment-uniform"] = Scene::Option("fragment-uniform", "true",
+ "Whether to use a uniform in the fragment shader for the number of loop iterations to perform (i.e. fragment-steps)",
+ "false,true");
+}
+
+SceneLoop::~SceneLoop()
+{
+}
+
+static std::string
+get_fragment_shader_source(int steps, bool loop, bool uniform)
+{
+ ShaderSource source(frg_file);
+ ShaderSource source_main;
+
+ if (loop) {
+ source_main.append_file(step_loop_file);
+ if (uniform) {
+ source_main.replace("$NLOOPS$", "FragmentLoops");
+ }
+ else {
+ source_main.replace("$NLOOPS$", Util::toString(steps));
+ }
+ }
+ else {
+ for (int i = 0; i < steps; i++)
+ source_main.append_file(step_simple_file);
+ }
+
+ source.replace("$MAIN$", source_main.str());
+
+ return source.str();
+}
+
+static std::string
+get_vertex_shader_source(int steps, bool loop, bool uniform)
+{
+ ShaderSource source(vtx_file);
+ ShaderSource source_main;
+
+ if (loop) {
+ source_main.append_file(step_loop_file);
+ if (uniform) {
+ source_main.replace("$NLOOPS$", "VertexLoops");
+ }
+ else {
+ source_main.replace("$NLOOPS$", Util::toString(steps));
+ }
+ }
+ else {
+ for (int i = 0; i < steps; i++)
+ source_main.append_file(step_simple_file);
+ }
+
+ source.replace("$MAIN$", source_main.str());
+
+ return source.str();
+}
+
+
+bool
+SceneLoop::setup()
+{
+ if (!SceneGrid::setup())
+ return false;
+
+ /* Parse options */
+ bool vtx_loop = options_["vertex-loop"].value == "true";
+ bool frg_loop = options_["fragment-loop"].value == "true";
+ bool vtx_uniform = options_["vertex-uniform"].value == "true";
+ bool frg_uniform = options_["fragment-uniform"].value == "true";
+ int vtx_steps = Util::fromString<int>(options_["vertex-steps"].value);
+ int frg_steps = Util::fromString<int>(options_["fragment-steps"].value);
+
+ /* Load shaders */
+ std::string vtx_shader(get_vertex_shader_source(vtx_steps, vtx_loop,
+ vtx_uniform));
+ std::string frg_shader(get_fragment_shader_source(frg_steps, frg_loop,
+ frg_uniform));
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_shader, frg_shader))
+ return false;
+
+ program_.start();
+
+ program_["VertexLoops"] = vtx_steps;
+ program_["FragmentLoops"] = frg_steps;
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+Scene::ValidationResult
+SceneLoop::validate()
+{
+ static const double radius_3d(std::sqrt(3.0 * 15.0 * 15.0));
+
+ int frg_steps = Util::fromString<int>(options_["fragment-steps"].value);
+
+ Canvas::Pixel ref;
+
+ if (frg_steps == 5)
+ ref = Canvas::Pixel(0x5e, 0x5e, 0x5e, 0xff);
+ else
+ return Scene::ValidationUnknown;
+
+ Canvas::Pixel pixel = canvas_.read_pixel(293, 89);
+
+ double dist = pixel.distance_rgb(ref);
+ if (dist < radius_3d + 0.01) {
+ return Scene::ValidationSuccess;
+ }
+ else {
+ Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+ ref.to_le32(), pixel.to_le32(), dist);
+ return Scene::ValidationFailure;
+ }
+
+ return Scene::ValidationUnknown;
+}
diff --git a/src/scene-pulsar.cpp b/src/scene-pulsar.cpp
new file mode 100644
index 0000000..6ab661c
--- /dev/null
+++ b/src/scene-pulsar.cpp
@@ -0,0 +1,331 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ * Marc Ordinas i Llopis, Collabora Ltd. (pulsar scene)
+ * Jesse Barker (glmark2)
+ */
+#include <stdlib.h>
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "shader-source.h"
+#include "util.h"
+#include "texture.h"
+#include <cmath>
+
+using LibMatrix::vec2;
+using LibMatrix::vec3;
+using LibMatrix::vec4;
+using LibMatrix::mat4;
+using LibMatrix::Stack4;
+
+ScenePulsar::ScenePulsar(Canvas &pCanvas) :
+ Scene(pCanvas, "pulsar"),
+ numQuads_(0),
+ texture_(0)
+{
+ options_["quads"] = Scene::Option("quads", "5", "Number of quads to render");
+ options_["texture"] = Scene::Option("texture", "false", "Enable texturing",
+ "false,true");
+ options_["light"] = Scene::Option("light", "false", "Enable lighting",
+ "false,true");
+ options_["random"] = Scene::Option("random", "false", "Enable random rotation speeds",
+ "false,true");
+}
+
+ScenePulsar::~ScenePulsar()
+{
+}
+
+bool
+ScenePulsar::load()
+{
+ scale_ = vec3(1.0, 1.0, 1.0);
+
+ running_ = false;
+
+ return true;
+}
+
+void
+ScenePulsar::unload()
+{
+}
+
+bool
+ScenePulsar::setup()
+{
+ if (!Scene::setup())
+ return false;
+
+ // Disable back-face culling
+ glDisable(GL_CULL_FACE);
+ // Enable alpha blending
+ glEnable(GL_BLEND);
+ // Blend the colors normally, but don't change the destination alpha value.
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
+
+ // Create a rotation for each quad.
+ numQuads_ = Util::fromString<int>(options_["quads"].value);
+
+ srand((unsigned)time(0));
+ for (int i = 0; i < numQuads_; i++) {
+ rotations_.push_back(vec3());
+ if (options_["random"].value == "true") {
+ rotationSpeeds_.push_back(vec3((static_cast<float>(rand()) / static_cast<float>(RAND_MAX)) * 5.0,
+ (static_cast<float>(rand()) / static_cast<float>(RAND_MAX)) * 5.0,
+ 0.0));
+ }
+ else {
+ float integral;
+ float x_rot = std::modf((i + 1) * M_PI, &integral);
+ float y_rot = std::modf((i + 1) * M_E, &integral);
+ rotationSpeeds_.push_back(vec3(x_rot * 5.0,
+ y_rot * 5.0,
+ 0.0));
+ }
+ }
+
+ // Load shaders
+ std::string vtx_shader_filename;
+ std::string frg_shader_filename;
+ static const vec4 lightPosition(-20.0f, 20.0f,-20.0f, 1.0f);
+ if (options_["light"].value == "true") {
+ vtx_shader_filename = GLMARK_DATA_PATH"/shaders/pulsar-light.vert";
+ } else {
+ vtx_shader_filename = GLMARK_DATA_PATH"/shaders/pulsar.vert";
+ }
+
+ if (options_["texture"].value == "true") {
+ frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic-tex.frag";
+ Texture::find_textures();
+ if (!Texture::load("crate-base", &texture_, GL_NEAREST, GL_NEAREST, 0))
+ return false;
+
+ } else {
+ frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.frag";
+ }
+
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+ if (options_["light"].value == "true") {
+ // Load the light position constant
+ vtx_source.add_const("LightSourcePosition", lightPosition);
+ }
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return false;
+ }
+
+ create_and_setup_mesh();
+
+ program_.start();
+
+ currentFrame_ = 0;
+
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+void
+ScenePulsar::teardown()
+{
+ program_.stop();
+ program_.release();
+
+ if (options_["texture"].value == "true") {
+ glDeleteTextures(1, &texture_);
+ texture_ = 0;
+ }
+
+ // Re-enable back-face culling
+ glEnable(GL_CULL_FACE);
+ // Disable alpha blending
+ glDisable(GL_BLEND);
+
+ mesh_.reset();
+
+ Scene::teardown();
+}
+
+void
+ScenePulsar::update()
+{
+ Scene::update();
+
+ double elapsed_time = lastUpdateTime_ - startTime_;
+
+ for (int i = 0; i < numQuads_; i++) {
+ rotations_[i] = rotationSpeeds_[i] * (elapsed_time * 60);
+ }
+
+ scale_ = vec3(cos(elapsed_time / 3.60) * 10.0, sin(elapsed_time / 3.60) * 10.0, 1.0);
+}
+
+void
+ScenePulsar::draw()
+{
+ if (options_["texture"].value == "true") {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ }
+
+ for (int i = 0; i < numQuads_; i++) {
+ // Load the ModelViewProjectionMatrix uniform in the shader
+ Stack4 model_view;
+ mat4 model_view_proj(canvas_.projection());
+ model_view.scale(scale_.x(), scale_.y(), scale_.z());
+ model_view.translate(0.0f, 0.0f, -10.0f);
+ model_view.rotate(rotations_[i].x(), 1.0f, 0.0f, 0.0f);
+ model_view.rotate(rotations_[i].y(), 0.0f, 1.0f, 0.0f);
+ model_view.rotate(rotations_[i].z(), 0.0f, 0.0f, 1.0f);
+ model_view_proj *= model_view.getCurrent();
+ program_["ModelViewProjectionMatrix"] = model_view_proj;
+
+ if (options_["light"].value == "true") {
+ // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
+ // inverse transpose of the model view matrix.
+ mat4 normal_matrix(model_view.getCurrent());
+ normal_matrix.inverse().transpose();
+ program_["NormalMatrix"] = normal_matrix;
+ }
+
+ mesh_.render_vbo();
+ }
+}
+
+Scene::ValidationResult
+ScenePulsar::validate()
+{
+ static const double radius_3d(std::sqrt(3.0));
+
+ int quads = Util::fromString<int>(options_["quads"].value);
+
+ if (options_["texture"].value != "false" ||
+ options_["light"].value != "false" ||
+ quads != 5)
+ {
+ return Scene::ValidationUnknown;
+ }
+
+ Canvas::Pixel ref(0x77, 0x02, 0x77, 0xff);
+ Canvas::Pixel pixel = canvas_.read_pixel(400, 299);
+
+ double dist = pixel.distance_rgb(ref);
+ if (dist < radius_3d + 0.01) {
+ return Scene::ValidationSuccess;
+ }
+ else {
+ Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+ ref.to_le32(), pixel.to_le32(), dist);
+ return Scene::ValidationFailure;
+ }
+
+ return Scene::ValidationUnknown;
+}
+
+void
+ScenePulsar::create_and_setup_mesh()
+{
+ bool texture = options_["texture"].value == "true";
+ bool light = options_["light"].value == "true";
+
+ struct PlaneMeshVertex {
+ vec3 position;
+ vec4 color;
+ vec2 texcoord;
+ vec3 normal;
+ };
+
+ PlaneMeshVertex plane_vertices[] = {
+ {
+ vec3(-1.0, -1.0, 0.0),
+ vec4(1.0, 0.0, 0.0, 0.4),
+ vec2(0.0, 0.0),
+ vec3(0.0, 0.0, 1.0)
+ },
+ {
+ vec3(-1.0, 1.0, 0.0),
+ vec4(0.0, 1.0, 0.0, 0.4),
+ vec2(0.0, 1.0),
+ vec3(0.0, 0.0, 1.0)
+ },
+ {
+ vec3(1.0, 1.0, 0.0),
+ vec4(0.0, 0.0, 1.0, 0.4),
+ vec2(1.0, 1.0),
+ vec3(0.0, 0.0, 1.0)
+ },
+ {
+ vec3(1.0, -1.0, 0.0),
+ vec4(1.0, 1.0, 1.0, 1.0),
+ vec2(1.0, 0.0),
+ vec3(0.0, 0.0, 1.0)
+ }
+ };
+
+ unsigned int vertex_index[] = {0, 1, 2, 0, 2, 3};
+
+ // Set vertex format
+ std::vector<int> vertex_format;
+ vertex_format.push_back(3); // Position
+ vertex_format.push_back(4); // Color
+ if (texture)
+ vertex_format.push_back(2); // Texcoord
+ if (light)
+ vertex_format.push_back(3); // Normal
+
+ mesh_.set_vertex_format(vertex_format);
+
+ // Build the plane mesh
+ for (size_t i = 0; i < sizeof(vertex_index) / sizeof(*vertex_index); i++) {
+ PlaneMeshVertex& vertex = plane_vertices[vertex_index[i]];
+
+ mesh_.next_vertex();
+ mesh_.set_attrib(0, vertex.position);
+ mesh_.set_attrib(1, vertex.color);
+ if (texture)
+ mesh_.set_attrib(2, vertex.texcoord);
+ if (light)
+ mesh_.set_attrib(2 + static_cast<int>(texture), vertex.normal);
+ }
+
+ mesh_.build_vbo();
+
+ // Set attribute locations
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["vtxcolor"].location());
+ if (texture)
+ attrib_locations.push_back(program_["texcoord"].location());
+ if (light)
+ attrib_locations.push_back(program_["normal"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+}
+
diff --git a/src/scene-refract.cpp b/src/scene-refract.cpp
new file mode 100644
index 0000000..db0aec8
--- /dev/null
+++ b/src/scene-refract.cpp
@@ -0,0 +1,469 @@
+//
+// Copyright © 2012 Linaro Limited
+//
+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+//
+// glmark2 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 3 of the License, or (at your option) any later
+// version.
+//
+// glmark2 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
+// glmark2. If not, see <http://www.gnu.org/licenses/>.
+//
+// Authors:
+// Jesse Barker
+//
+#include "scene-refract.h"
+#include "model.h"
+#include "texture.h"
+#include "util.h"
+#include "log.h"
+#include "shader-source.h"
+
+using std::string;
+using std::vector;
+using std::map;
+using LibMatrix::mat4;
+using LibMatrix::vec4;
+using LibMatrix::vec3;
+
+static const vec4 lightPosition(1.0f, 1.0f, 2.0f, 1.0f);
+
+//
+// Public interfaces
+//
+
+SceneRefract::SceneRefract(Canvas& canvas) :
+ Scene(canvas, "refract"),
+ priv_(0)
+{
+ const ModelMap& modelMap = Model::find_models();
+ string optionValues;
+ for (ModelMap::const_iterator modelIt = modelMap.begin();
+ modelIt != modelMap.end();
+ modelIt++)
+ {
+ static bool doSeparator(false);
+ if (doSeparator)
+ {
+ optionValues += ",";
+ }
+ const string& curName = modelIt->first;
+ optionValues += curName;
+ doSeparator = true;
+ }
+ options_["model"] = Scene::Option("model", "bunny", "Which model to use",
+ optionValues);
+ optionValues = "";
+ const TextureMap& textureMap = Texture::find_textures();
+ for (TextureMap::const_iterator textureIt = textureMap.begin();
+ textureIt != textureMap.end();
+ textureIt++)
+ {
+ static bool doSeparator(false);
+ if (doSeparator)
+ {
+ optionValues += ",";
+ }
+ const string& curName = textureIt->first;
+ optionValues += curName;
+ doSeparator = true;
+ }
+ options_["texture"] = Scene::Option("texture", "nasa1", "Which texture to use",
+ optionValues);
+ options_["index"] = Scene::Option("index", "1.2",
+ "Index of refraction of the medium to simulate");
+ options_["use-vbo"] = Scene::Option("use-vbo", "true",
+ "Whether to use VBOs for rendering",
+ "false,true");
+ options_["interleave"] = Scene::Option("interleave", "false",
+ "Whether to interleave vertex attribute data",
+ "false,true");
+}
+
+bool
+SceneRefract::supported(bool show_errors)
+{
+ static const string oes_depth_texture("GL_OES_depth_texture");
+ static const string arb_depth_texture("GL_ARB_depth_texture");
+ if (!GLExtensions::support(oes_depth_texture) &&
+ !GLExtensions::support(arb_depth_texture)) {
+ if (show_errors) {
+ Log::error("We do not have the depth texture extension!!!\n");
+ }
+
+ return false;
+ }
+ return true;
+}
+
+bool
+SceneRefract::load()
+{
+ running_ = false;
+ return true;
+}
+
+void
+SceneRefract::unload()
+{
+}
+
+bool
+SceneRefract::setup()
+{
+ // If the scene isn't supported, don't bother to go through setup.
+ if (!supported(false) || !Scene::setup())
+ {
+ return false;
+ }
+
+ priv_ = new RefractPrivate(canvas_);
+ if (!priv_->setup(options_)) {
+ delete priv_;
+ priv_ = 0;
+ return false;
+ }
+
+ // Set core scene timing after actual initialization so we don't measure
+ // set up time.
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+ running_ = true;
+
+ return true;
+}
+
+void
+SceneRefract::teardown()
+{
+ // Add scene-specific teardown here
+ priv_->teardown();
+ delete priv_;
+ Scene::teardown();
+}
+
+void
+SceneRefract::update()
+{
+ Scene::update();
+ // Add scene-specific update here
+ priv_->update(lastUpdateTime_ - startTime_);
+}
+
+void
+SceneRefract::draw()
+{
+ priv_->draw();
+}
+
+Scene::ValidationResult
+SceneRefract::validate()
+{
+ return Scene::ValidationUnknown;
+}
+
+//
+// Private interfaces
+//
+
+bool
+DistanceRenderTarget::setup(unsigned int width, unsigned int height)
+{
+ canvas_width_ = width;
+ canvas_height_ = height;
+ width_ = canvas_width_ * 2;
+ height_ = canvas_height_ * 2;
+
+ static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/depth.vert");
+ static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/depth.frag");
+
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(), frg_source.str())) {
+ return false;
+ }
+
+ glGenTextures(2, &tex_[0]);
+ glBindTexture(GL_TEXTURE_2D, tex_[DEPTH]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width_, height_, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
+ glBindTexture(GL_TEXTURE_2D, tex_[COLOR]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ glGenerateMipmap(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glGenFramebuffers(1, &fbo_);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
+ tex_[DEPTH], 0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ tex_[COLOR], 0);
+ unsigned int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ Log::error("DepthRenderState::setup: glCheckFramebufferStatus failed (0x%x)\n", status);
+ return false;
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ return true;
+}
+
+void
+DistanceRenderTarget::teardown()
+{
+ program_.stop();
+ program_.release();
+ if (tex_) {
+ glDeleteTextures(2, &tex_[0]);
+ tex_[DEPTH] = tex_[COLOR] = 0;
+ }
+ if (fbo_) {
+ glDeleteFramebuffers(1, &fbo_);
+ fbo_ = 0;
+ }
+}
+
+void
+DistanceRenderTarget::enable(const mat4& mvp)
+{
+ program_.start();
+ program_["ModelViewProjectionMatrix"] = mvp;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
+ tex_[DEPTH], 0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ tex_[COLOR], 0);
+ glViewport(0, 0, width_, height_);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ glCullFace(GL_FRONT);
+}
+
+void DistanceRenderTarget::disable()
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glViewport(0, 0, canvas_width_, canvas_height_);
+ glCullFace(GL_BACK);
+}
+
+bool
+RefractPrivate::setup(map<string, Scene::Option>& options)
+{
+ // Program object setup
+ static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-refract.vert");
+ static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-refract.frag");
+ static const vec4 lightColor(0.4, 0.4, 0.4, 1.0);
+
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ frg_source.add_const("LightColor", lightColor);
+ frg_source.add_const("LightSourcePosition", lightPosition);
+ float refractive_index(Util::fromString<float>(options["index"].value));
+ frg_source.add_const("RefractiveIndex", refractive_index);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(), frg_source.str())) {
+ return false;
+ }
+
+ const string& whichTexture(options["texture"].value);
+ if (!Texture::load(whichTexture, &texture_, GL_LINEAR, GL_LINEAR, 0))
+ return false;
+
+ // Model setup
+ Model model;
+ const string& whichModel(options["model"].value);
+ bool modelLoaded = model.load(whichModel);
+
+ if(!modelLoaded)
+ return false;
+
+ // Now that we're successfully loaded, there are a few quirks about
+ // some of the known models that we need to account for. The draw
+ // logic for the scene wants to rotate the model around the Y axis.
+ // Most of our models are described this way. Some need adjustment
+ // (an additional rotation that gets the model into the correct
+ // orientation).
+ //
+ // Here's a summary:
+ //
+ // Angel rotates around the Y axis
+ // Armadillo rotates around the Y axis
+ // Buddha rotates around the X axis
+ // Bunny rotates around the Y axis
+ // Dragon rotates around the X axis
+ // Horse rotates around the Y axis
+ if (whichModel == "buddha" || whichModel == "dragon")
+ {
+ orientModel_ = true;
+ orientationAngle_ = -90.0;
+ orientationVec_ = vec3(1.0, 0.0, 0.0);
+ }
+ else if (whichModel == "armadillo")
+ {
+ orientModel_ = true;
+ orientationAngle_ = 180.0;
+ orientationVec_ = vec3(0.0, 1.0, 0.0);
+ }
+
+ model.calculate_normals();
+
+ // Mesh setup
+ vector<std::pair<Model::AttribType, int> > attribs;
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
+ model.convert_to_mesh(mesh_, attribs);
+
+ useVbo_ = (options["use-vbo"].value == "true");
+ bool interleave = (options["interleave"].value == "true");
+ mesh_.vbo_update_method(Mesh::VBOUpdateMethodMap);
+ mesh_.interleave(interleave);
+
+ if (useVbo_) {
+ mesh_.build_vbo();
+ }
+ else {
+ mesh_.build_array();
+ }
+
+ // Calculate a projection matrix that is a good fit for the model
+ vec3 maxVec = model.maxVec();
+ vec3 minVec = model.minVec();
+ vec3 diffVec = maxVec - minVec;
+ centerVec_ = maxVec + minVec;
+ centerVec_ /= 2.0;
+ float diameter = diffVec.length();
+ radius_ = diameter / 2;
+ float fovy = 2.0 * atanf(radius_ / (2.0 + radius_));
+ fovy /= M_PI;
+ fovy *= 180.0;
+ float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height()));
+ projection_.perspective(fovy, aspect, 2.0, 2.0 + diameter);
+
+ // Set up the light matrix with a bias that will convert values
+ // in the range of [-1, 1] to [0, 1)], then add in the projection
+ // and the "look at" matrix from the light position.
+ light_ *= LibMatrix::Mat4::translate(0.5, 0.5, 0.5);
+ light_ *= LibMatrix::Mat4::scale(0.5, 0.5, 0.5);
+ light_ *= projection_.getCurrent();
+ light_ *= LibMatrix::Mat4::lookAt(lightPosition.x(), lightPosition.y(), lightPosition.z(),
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0);
+
+ if (!depthTarget_.setup(canvas_.width(), canvas_.height())) {
+ Log::error("Failed to set up the render target for the depth pass\n");
+ return false;
+ }
+
+ return true;
+}
+void
+RefractPrivate::teardown()
+{
+ depthTarget_.teardown();
+ program_.stop();
+ program_.release();
+ mesh_.reset();
+}
+
+void
+RefractPrivate::update(double elapsedTime)
+{
+ rotation_ = rotationSpeed_ * elapsedTime;
+}
+
+void
+RefractPrivate::draw()
+{
+ // To perform the depth pass, set up the model-view transformation so
+ // that we're looking at the horse from the light position. That will
+ // give us the appropriate view for the shadow.
+ modelview_.push();
+ modelview_.loadIdentity();
+ modelview_.lookAt(lightPosition.x(), lightPosition.y(), lightPosition.z(),
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0);
+ modelview_.rotate(rotation_, 0.0f, 1.0f, 0.0f);
+ if (orientModel_)
+ {
+ modelview_.rotate(orientationAngle_, orientationVec_.x(), orientationVec_.y(), orientationVec_.z());
+ }
+ mat4 mvp(projection_.getCurrent());
+ mvp *= modelview_.getCurrent();
+ modelview_.pop();
+
+ // Enable the depth render target with our transformation and render.
+ depthTarget_.enable(mvp);
+ vector<GLint> attrib_locations;
+ attrib_locations.push_back(depthTarget_.program()["position"].location());
+ attrib_locations.push_back(depthTarget_.program()["normal"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+ if (useVbo_) {
+ mesh_.render_vbo();
+ }
+ else {
+ mesh_.render_array();
+ }
+ depthTarget_.disable();
+
+ // Draw the "normal" view of the horse
+ modelview_.push();
+ modelview_.translate(-centerVec_.x(), -centerVec_.y(), -(centerVec_.z() + 2.0 + radius_));
+ modelview_.rotate(rotation_, 0.0f, 1.0f, 0.0f);
+ if (orientModel_)
+ {
+ modelview_.rotate(orientationAngle_, orientationVec_.x(), orientationVec_.y(), orientationVec_.z());
+ }
+ mvp = projection_.getCurrent();
+ mvp *= modelview_.getCurrent();
+
+ program_.start();
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, depthTarget_.depthTexture());
+ program_["DistanceMap"] = 0;
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, depthTarget_.colorTexture());
+ program_["NormalMap"] = 1;
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ program_["ImageMap"] = 2;
+ // Load both the modelview*projection as well as the modelview matrix itself
+ program_["ModelViewProjectionMatrix"] = mvp;
+ program_["ModelViewMatrix"] = modelview_.getCurrent();
+ // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
+ // inverse transpose of the model view matrix.
+ mat4 normal_matrix(modelview_.getCurrent());
+ normal_matrix.inverse().transpose();
+ program_["NormalMatrix"] = normal_matrix;
+ program_["LightMatrix"] = light_;
+ attrib_locations.clear();
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["normal"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+ if (useVbo_) {
+ mesh_.render_vbo();
+ }
+ else {
+ mesh_.render_array();
+ }
+
+ // Per-frame cleanup
+ modelview_.pop();
+}
+
diff --git a/src/scene-refract.h b/src/scene-refract.h
new file mode 100644
index 0000000..660678b
--- /dev/null
+++ b/src/scene-refract.h
@@ -0,0 +1,106 @@
+//
+// Copyright © 2012 Linaro Limited
+//
+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+//
+// glmark2 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 3 of the License, or (at your option) any later
+// version.
+//
+// glmark2 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
+// glmark2. If not, see <http://www.gnu.org/licenses/>.
+//
+// Authors:
+// Jesse Barker
+//
+#ifndef SCENE_REFRACT_
+#define SCENE_REFRACT_
+
+#include "scene.h"
+#include "stack.h"
+
+//
+// To create a shadow map, we need a framebuffer object set up for a
+// depth-only pass. The render target can then be bound as a texture,
+// and the depth values sampled from that texture can be used in the
+// distance-from-light computations when rendering the shadow on the
+// ground below the rendered object.
+//
+class DistanceRenderTarget
+{
+ enum
+ {
+ DEPTH = 0,
+ COLOR
+ };
+ Program program_;
+ unsigned int canvas_width_;
+ unsigned int canvas_height_;
+ unsigned int width_;
+ unsigned int height_;
+ unsigned int tex_[2];
+ unsigned int fbo_;
+public:
+ DistanceRenderTarget() :
+ canvas_width_(0),
+ canvas_height_(0),
+ width_(0),
+ height_(0),
+ fbo_(0)
+ {
+ tex_[DEPTH] = tex_[COLOR] = 0;
+ }
+ ~DistanceRenderTarget() {}
+ bool setup(unsigned int width, unsigned int height);
+ void teardown();
+ void enable(const LibMatrix::mat4& mvp);
+ void disable();
+ unsigned int depthTexture() { return tex_[DEPTH]; }
+ unsigned int colorTexture() { return tex_[COLOR]; }
+ Program& program() { return program_; }
+};
+
+class RefractPrivate
+{
+ Canvas& canvas_;
+ DistanceRenderTarget depthTarget_;
+ Program program_;
+ LibMatrix::Stack4 modelview_;
+ LibMatrix::Stack4 projection_;
+ LibMatrix::mat4 light_;
+ Mesh mesh_;
+ LibMatrix::vec3 centerVec_;
+ bool orientModel_;
+ float orientationAngle_;
+ LibMatrix::vec3 orientationVec_;
+ float radius_;
+ float rotation_;
+ float rotationSpeed_;
+ unsigned int texture_;
+ bool useVbo_;
+
+public:
+ RefractPrivate(Canvas& canvas) :
+ canvas_(canvas),
+ orientModel_(false),
+ orientationAngle_(0.0),
+ radius_(0.0),
+ rotation_(0.0),
+ rotationSpeed_(36.0),
+ texture_(0),
+ useVbo_(true) {}
+ ~RefractPrivate() {}
+
+ bool setup(std::map<std::string, Scene::Option>& options);
+ void teardown();
+ void update(double elapsedTime);
+ void draw();
+};
+
+#endif // SCENE_REFRACT_
diff --git a/src/scene-shading.cpp b/src/scene-shading.cpp
new file mode 100644
index 0000000..22b5ad5
--- /dev/null
+++ b/src/scene-shading.cpp
@@ -0,0 +1,346 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker (glmark2)
+ */
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "util.h"
+#include "shader-source.h"
+#include "model.h"
+
+#include <cmath>
+#include <sstream>
+
+using LibMatrix::vec3;
+using std::string;
+using std::endl;
+
+SceneShading::SceneShading(Canvas &pCanvas) :
+ Scene(pCanvas, "shading"),
+ orientModel_(false)
+{
+ const ModelMap& modelMap = Model::find_models();
+ std::string optionValues;
+ for (ModelMap::const_iterator modelIt = modelMap.begin();
+ modelIt != modelMap.end();
+ modelIt++)
+ {
+ static bool doSeparator(false);
+ if (doSeparator)
+ {
+ optionValues += ",";
+ }
+ const std::string& curName = modelIt->first;
+ optionValues += curName;
+ doSeparator = true;
+ }
+ options_["shading"] = Scene::Option("shading", "gouraud",
+ "Which shading method to use",
+ "gouraud,blinn-phong-inf,phong");
+ options_["num-lights"] = Scene::Option("num-lights", "1",
+ "The number of lights applied to the scene (phong only)");
+ options_["model"] = Scene::Option("model", "cat", "Which model to use",
+ optionValues);
+}
+
+SceneShading::~SceneShading()
+{
+}
+
+bool
+SceneShading::load()
+{
+ rotationSpeed_ = 36.0f;
+
+ running_ = false;
+
+ return true;
+}
+
+void
+SceneShading::unload()
+{
+ mesh_.reset();
+}
+
+static string
+get_fragment_shader_source(const string& frg_file, unsigned int lights)
+{
+ ShaderSource source(frg_file);
+
+ static const string lightPositionName("LightSourcePosition");
+ static const string lightColorName("LightColor");
+ static const string callCompute(" gl_FragColor += compute_color(");
+ static const string commaString(", ");
+ static const string rParenString(");");
+ std::stringstream doLightSS;
+ doLightSS << string(" gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);");
+ doLightSS << endl;
+ float theta(2.0 * M_PI / lights);
+ float phi(theta / 2.0);
+ float intensity(0.8 / lights);
+ LibMatrix::vec4 lightCol(intensity, intensity, intensity, 1.0);
+ for (unsigned int l = 0; l < lights; l++)
+ {
+ // Construct constant names for the light position and color and add it
+ // to the list of constants for the shader.
+ string indexString(Util::toString(l));
+ string curLightPosition(lightPositionName + indexString);
+ string curLightColor(lightColorName + indexString);
+ float sin_theta(sin(theta * l));
+ float cos_theta(cos(theta * l));
+ float sin_phi(sin(phi * l));
+ float cos_phi(cos(phi * l));
+ LibMatrix::vec4 lightPos(cos_phi * sin_theta, cos_phi * cos_theta, sin_phi, 1.0);
+ source.add_const(curLightPosition, lightPos);
+ source.add_const(curLightColor, lightCol);
+
+ // Add the section of source to the substantive...
+ doLightSS << callCompute;
+ doLightSS << curLightPosition;
+ doLightSS << commaString;
+ doLightSS << curLightColor;
+ doLightSS << rParenString;
+ doLightSS << endl;
+ }
+
+ source.replace("$DO_LIGHTS$", doLightSS.str());
+
+ return source.str();
+}
+
+bool
+SceneShading::setup()
+{
+ if (!Scene::setup())
+ return false;
+
+ static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
+ static const LibMatrix::vec4 materialDiffuse(0.0f, 0.0f, 1.0f, 1.0f);
+
+ // Calculate half vector for blinn-phong shading model
+ LibMatrix::vec3 halfVector(lightPosition[0], lightPosition[1], lightPosition[2]);
+ halfVector.normalize();
+ halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
+ halfVector.normalize();
+
+ // Load and add constants to shaders
+ std::string vtx_shader_filename;
+ std::string frg_shader_filename;
+ const std::string &shading = options_["shading"].value;
+ ShaderSource vtx_source;
+ ShaderSource frg_source;
+ if (shading == "gouraud") {
+ vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.vert";
+ frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.frag";
+ frg_source.append_file(frg_shader_filename);
+ vtx_source.append_file(vtx_shader_filename);
+ vtx_source.add_const("LightSourcePosition", lightPosition);
+ vtx_source.add_const("MaterialDiffuse", materialDiffuse);
+ }
+ else if (shading == "blinn-phong-inf") {
+ vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-advanced.vert";
+ frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-advanced.frag";
+ frg_source.append_file(frg_shader_filename);
+ frg_source.add_const("LightSourcePosition", lightPosition);
+ frg_source.add_const("LightSourceHalfVector", halfVector);
+ vtx_source.append_file(vtx_shader_filename);
+ }
+ else if (shading == "phong") {
+ vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-phong.vert";
+ frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-phong.frag";
+ unsigned int num_lights = Util::fromString<unsigned int>(options_["num-lights"].value);
+ string fragsource = get_fragment_shader_source(frg_shader_filename, num_lights);
+ frg_source.append(fragsource);
+ frg_source.add_const("MaterialDiffuse", materialDiffuse);
+ vtx_source.append_file(vtx_shader_filename);
+ }
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return false;
+ }
+
+ Model model;
+ const std::string& whichModel(options_["model"].value);
+ bool modelLoaded = model.load(whichModel);
+
+ if(!modelLoaded)
+ return false;
+
+ // Now that we're successfully loaded, there are a few quirks about
+ // some of the known models that we need to account for. The draw
+ // logic for the scene wants to rotate the model around the Y axis.
+ // Most of our models are described this way. Some need adjustment
+ // (an additional rotation that gets the model into the correct
+ // orientation).
+ //
+ // Here's a summary:
+ //
+ // Angel rotates around the Y axis
+ // Armadillo rotates around the Y axis
+ // Buddha rotates around the X axis
+ // Bunny rotates around the Y axis
+ // Dragon rotates around the X axis
+ // Horse rotates around the Y axis
+ if (whichModel == "buddha" || whichModel == "dragon")
+ {
+ orientModel_ = true;
+ orientationAngle_ = -90.0;
+ orientationVec_ = vec3(1.0, 0.0, 0.0);
+ }
+ else if (whichModel == "armadillo")
+ {
+ orientModel_ = true;
+ orientationAngle_ = 180.0;
+ orientationVec_ = vec3(0.0, 1.0, 0.0);
+ }
+
+ model.calculate_normals();
+
+ /* Tell the converter that we only care about position and normal attributes */
+ std::vector<std::pair<Model::AttribType, int> > attribs;
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
+
+ model.convert_to_mesh(mesh_, attribs);
+
+ mesh_.build_vbo();
+
+ /* Calculate a projection matrix that is a good fit for the model */
+ vec3 maxVec = model.maxVec();
+ vec3 minVec = model.minVec();
+ vec3 diffVec = maxVec - minVec;
+ centerVec_ = maxVec + minVec;
+ centerVec_ /= 2.0;
+ float diameter = diffVec.length();
+ radius_ = diameter / 2;
+ float fovy = 2.0 * atanf(radius_ / (2.0 + radius_));
+ fovy /= M_PI;
+ fovy *= 180.0;
+ float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height()));
+ perspective_.setIdentity();
+ perspective_ *= LibMatrix::Mat4::perspective(fovy, aspect, 2.0, 2.0 + diameter);
+
+ program_.start();
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["normal"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ currentFrame_ = 0;
+ rotation_ = 0.0f;
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+void
+SceneShading::teardown()
+{
+ program_.stop();
+ program_.release();
+
+ Scene::teardown();
+}
+
+void
+SceneShading::update()
+{
+ Scene::update();
+
+ double elapsed_time = lastUpdateTime_ - startTime_;
+
+ rotation_ = rotationSpeed_ * elapsed_time;
+}
+
+void
+SceneShading::draw()
+{
+ // Load the ModelViewProjectionMatrix uniform in the shader
+ LibMatrix::Stack4 model_view;
+ model_view.translate(-centerVec_.x(), -centerVec_.y(), -(centerVec_.z() + 2.0 + radius_));
+ model_view.rotate(rotation_, 0.0f, 1.0f, 0.0f);
+ if (orientModel_)
+ {
+ model_view.rotate(orientationAngle_, orientationVec_.x(), orientationVec_.y(), orientationVec_.z());
+ }
+ LibMatrix::mat4 model_view_proj(perspective_);
+ model_view_proj *= model_view.getCurrent();
+
+ program_["ModelViewProjectionMatrix"] = model_view_proj;
+
+ // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
+ // inverse transpose of the model view matrix.
+ LibMatrix::mat4 normal_matrix(model_view.getCurrent());
+ normal_matrix.inverse().transpose();
+ program_["NormalMatrix"] = normal_matrix;
+
+ // Load the modelview matrix itself
+ program_["ModelViewMatrix"] = model_view.getCurrent();
+
+ mesh_.render_vbo();
+}
+
+Scene::ValidationResult
+SceneShading::validate()
+{
+ static const double radius_3d(std::sqrt(3.0));
+
+ if (rotation_ != 0)
+ return Scene::ValidationUnknown;
+
+ Canvas::Pixel ref;
+
+ Canvas::Pixel pixel = canvas_.read_pixel(canvas_.width() / 3,
+ canvas_.height() / 3);
+
+ const std::string &filter = options_["shading"].value;
+
+ if (filter == "gouraud")
+ ref = Canvas::Pixel(0x00, 0x00, 0x2d, 0xff);
+ else if (filter == "blinn-phong-inf")
+ ref = Canvas::Pixel(0x1a, 0x1a, 0x3e, 0xff);
+ else if (filter == "phong" && options_["num-lights"].value == "1")
+ ref = Canvas::Pixel(0x05, 0x05, 0xad, 0xff);
+ else
+ return Scene::ValidationUnknown;
+
+ double dist = pixel.distance_rgb(ref);
+
+ if (dist < radius_3d + 0.01) {
+ return Scene::ValidationSuccess;
+ }
+ else {
+ Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+ ref.to_le32(), pixel.to_le32(), dist);
+ return Scene::ValidationFailure;
+ }
+}
diff --git a/src/scene-shadow.cpp b/src/scene-shadow.cpp
new file mode 100644
index 0000000..dbad8a4
--- /dev/null
+++ b/src/scene-shadow.cpp
@@ -0,0 +1,546 @@
+//
+// Copyright © 2012 Linaro Limited
+//
+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+//
+// glmark2 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 3 of the License, or (at your option) any later
+// version.
+//
+// glmark2 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
+// glmark2. If not, see <http://www.gnu.org/licenses/>.
+//
+// Authors:
+// Jesse Barker
+//
+#include "scene.h"
+#include "model.h"
+#include "util.h"
+#include "log.h"
+#include "shader-source.h"
+#include "stack.h"
+
+using std::string;
+using std::vector;
+using std::map;
+using LibMatrix::Stack4;
+using LibMatrix::mat4;
+using LibMatrix::vec4;
+using LibMatrix::vec3;
+using LibMatrix::vec2;
+
+static const vec4 lightPosition(0.0f, 3.0f, 2.0f, 1.0f);
+
+//
+// To create a shadow map, we need a framebuffer object set up for a
+// depth-only pass. The render target can then be bound as a texture,
+// and the depth values sampled from that texture can be used in the
+// distance-from-light computations when rendering the shadow on the
+// ground below the rendered object.
+//
+class DepthRenderTarget
+{
+ Program program_;
+ unsigned int canvas_width_;
+ unsigned int canvas_height_;
+ unsigned int width_;
+ unsigned int height_;
+ unsigned int tex_;
+ unsigned int fbo_;
+public:
+ DepthRenderTarget() :
+ canvas_width_(0),
+ canvas_height_(0),
+ width_(0),
+ height_(0),
+ tex_(0),
+ fbo_(0) {}
+ ~DepthRenderTarget() {}
+ bool setup(unsigned int width, unsigned int height);
+ void teardown();
+ void enable(const mat4& mvp);
+ void disable();
+ unsigned int texture() { return tex_; }
+ Program& program() { return program_; }
+};
+
+bool
+DepthRenderTarget::setup(unsigned int width, unsigned int height)
+{
+ canvas_width_ = width;
+ canvas_height_ = height;
+ width_ = canvas_width_ * 2;
+ height_ = canvas_height_ * 2;
+
+ static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/depth.vert");
+ static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/depth.frag");
+
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(), frg_source.str())) {
+ return false;
+ }
+
+ glGenTextures(1, &tex_);
+ glBindTexture(GL_TEXTURE_2D, tex_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width_, height_, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glGenFramebuffers(1, &fbo_);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
+ tex_, 0);
+ unsigned int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ Log::error("DepthRenderState::setup: glCheckFramebufferStatus failed (0x%x)\n", status);
+ return false;
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ return true;
+}
+
+void
+DepthRenderTarget::teardown()
+{
+ program_.stop();
+ program_.release();
+ if (tex_) {
+ glDeleteTextures(1, &tex_);
+ tex_ = 0;
+ }
+ if (fbo_) {
+ glDeleteFramebuffers(1, &fbo_);
+ fbo_ = 0;
+ }
+}
+
+void
+DepthRenderTarget::enable(const mat4& mvp)
+{
+ program_.start();
+ program_["ModelViewProjectionMatrix"] = mvp;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
+ tex_, 0);
+ glViewport(0, 0, width_, height_);
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ glClear(GL_DEPTH_BUFFER_BIT);
+}
+
+void DepthRenderTarget::disable()
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glViewport(0, 0, canvas_width_, canvas_height_);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+}
+
+//
+// The actual shadow pass is really just a quad projected into the scene
+// with the horse's shadow cast upon it. In the vertex stage, we compute
+// a texture coordinate for the depth texture look-up by transforming the
+// current vertex position using a matrix describing the light's view point.
+// In the fragment stage, that coordinate is perspective corrected, and
+// used to sample the depth texture. If the depth value for that fragment
+// (effectively the distance from the light to the object at that point)
+// is less than the Z component of that coordinate (effectively the distance
+// from the light to the ground at that point) then that location is in shadow.
+//
+class GroundRenderer
+{
+ Program program_;
+ mat4 light_;
+ Stack4 modelview_;
+ mat4 projection_;
+ int positionLocation_;
+ unsigned int bufferObject_;
+ unsigned int texture_;
+ vector<vec2> vertices_;
+ vector<vec2> texcoords_;
+
+public:
+ GroundRenderer() :
+ positionLocation_(0),
+ bufferObject_(0) {}
+ ~GroundRenderer() {}
+ bool setup(const mat4& projection, unsigned int texture);
+ void teardown();
+ void draw();
+};
+
+bool
+GroundRenderer::setup(const mat4& projection, unsigned int texture)
+{
+ projection_ = projection;
+ texture_ = texture;
+
+ // Program set up
+ static const vec4 materialDiffuse(0.3f, 0.3f, 0.3f, 1.0f);
+ static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/shadow.vert");
+ static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/shadow.frag");
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ vtx_source.add_const("MaterialDiffuse", materialDiffuse);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(), frg_source.str())) {
+ return false;
+ }
+ positionLocation_ = program_["position"].location();
+
+ // Set up the position data for our "quad".
+ vertices_.push_back(vec2(-1.0, -1.0));
+ vertices_.push_back(vec2(1.0, -1.0));
+ vertices_.push_back(vec2(-1.0, 1.0));
+ vertices_.push_back(vec2(1.0, 1.0));
+
+ // Set up the VBO and stash our position data in it.
+ glGenBuffers(1, &bufferObject_);
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObject_);
+ glBufferData(GL_ARRAY_BUFFER, vertices_.size() * sizeof(vec2),
+ &vertices_.front(), GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ // Set up the light matrix with a bias that will convert values
+ // in the range of [-1, 1] to [0, 1)], then add in the projection
+ // and the "look at" matrix from the light position.
+ light_ *= LibMatrix::Mat4::translate(0.5, 0.5, 0.5);
+ light_ *= LibMatrix::Mat4::scale(0.5, 0.5, 0.5);
+ light_ *= projection_;
+ light_ *= LibMatrix::Mat4::lookAt(lightPosition.x(), lightPosition.y(), lightPosition.z(),
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0);
+
+ return true;
+}
+
+void
+GroundRenderer::teardown()
+{
+ program_.stop();
+ program_.release();
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glDeleteBuffers(1, &bufferObject_);
+ bufferObject_ = 0;
+ texture_= 0;
+ vertices_.clear();
+}
+
+void
+GroundRenderer::draw()
+{
+ // Need to add uniforms for the shadow texture, and transformation to
+ // "lay the quad down".
+ modelview_.push();
+ modelview_.translate(projection_[0][3], projection_[1][3] - 0.8, projection_[2][3] - 0.5);
+ modelview_.rotate(-85.0, 1.0, 0.0, 0.0);
+ modelview_.scale(2.0, 2.0, 2.0);
+ mat4 mvp(projection_);
+ mvp *= modelview_.getCurrent();
+
+ glBindBuffer(GL_ARRAY_BUFFER, bufferObject_);
+ program_.start();
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ program_["ShadowMap"] = 0;
+ program_["LightMatrix"] = light_;
+ program_["ModelViewProjectionMatrix"] = mvp;
+
+ glEnableVertexAttribArray(positionLocation_);
+ glVertexAttribPointer(positionLocation_, 2, GL_FLOAT, GL_FALSE, 0, 0);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glDisableVertexAttribArray(positionLocation_);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ modelview_.pop();
+}
+
+class ShadowPrivate
+{
+ Canvas& canvas_;
+ DepthRenderTarget depthTarget_;
+ GroundRenderer ground_;
+ Program program_;
+ Stack4 modelview_;
+ Stack4 projection_;
+ Mesh mesh_;
+ vec3 centerVec_;
+ float radius_;
+ float rotation_;
+ float rotationSpeed_;
+ bool useVbo_;
+
+public:
+ ShadowPrivate(Canvas& canvas) :
+ canvas_(canvas),
+ radius_(0.0),
+ rotation_(0.0),
+ rotationSpeed_(36.0),
+ useVbo_(true) {}
+ ~ShadowPrivate() {}
+
+ bool setup(map<string, Scene::Option>& options);
+ void teardown();
+ void update(double elapsedTime);
+ void draw();
+};
+
+bool
+ShadowPrivate::setup(map<string, Scene::Option>& options)
+{
+ // Program object setup
+ static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.vert");
+ static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.frag");
+ static const vec4 materialDiffuse(1.0f, 1.0f, 1.0f, 1.0f);
+
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ vtx_source.add_const("LightSourcePosition", lightPosition);
+ vtx_source.add_const("MaterialDiffuse", materialDiffuse);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(), frg_source.str())) {
+ return false;
+ }
+
+ // Model setup
+ Model::find_models();
+ Model model;
+ bool modelLoaded = model.load("horse");
+
+ if(!modelLoaded) {
+ return false;
+ }
+
+ model.calculate_normals();
+
+ // Mesh setup
+ vector<std::pair<Model::AttribType, int> > attribs;
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
+ model.convert_to_mesh(mesh_, attribs);
+
+ useVbo_ = (options["use-vbo"].value == "true");
+ bool interleave = (options["interleave"].value == "true");
+ mesh_.vbo_update_method(Mesh::VBOUpdateMethodMap);
+ mesh_.interleave(interleave);
+
+ if (useVbo_) {
+ mesh_.build_vbo();
+ }
+ else {
+ mesh_.build_array();
+ }
+
+ // Calculate a projection matrix that is a good fit for the model
+ vec3 maxVec = model.maxVec();
+ vec3 minVec = model.minVec();
+ vec3 diffVec = maxVec - minVec;
+ centerVec_ = maxVec + minVec;
+ centerVec_ /= 2.0;
+ float diameter = diffVec.length();
+ radius_ = diameter / 2;
+ float fovy = 2.0 * atanf(radius_ / (2.0 + radius_));
+ fovy /= M_PI;
+ fovy *= 180.0;
+ float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height()));
+ projection_.perspective(fovy, aspect, 2.0, 50.0);
+
+ if (!depthTarget_.setup(canvas_.width(), canvas_.height())) {
+ Log::error("Failed to set up the render target for the depth pass\n");
+ return false;
+ }
+
+ if (!ground_.setup(projection_.getCurrent(), depthTarget_.texture())) {
+ Log::error("Failed to set up the ground renderer\n");
+ return false;
+ }
+
+ return true;
+}
+
+
+void
+ShadowPrivate::teardown()
+{
+ depthTarget_.teardown();
+ ground_.teardown();
+ program_.stop();
+ program_.release();
+ mesh_.reset();
+}
+
+void
+ShadowPrivate::update(double elapsedTime)
+{
+ rotation_ = rotationSpeed_ * elapsedTime;
+}
+
+void
+ShadowPrivate::draw()
+{
+ // To perform the depth pass, set up the model-view transformation so
+ // that we're looking at the horse from the light position. That will
+ // give us the appropriate view for the shadow.
+ modelview_.push();
+ modelview_.loadIdentity();
+ modelview_.lookAt(lightPosition.x(), lightPosition.y(), lightPosition.z(),
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0);
+ modelview_.rotate(rotation_, 0.0f, 1.0f, 0.0f);
+ mat4 mvp(projection_.getCurrent());
+ mvp *= modelview_.getCurrent();
+ modelview_.pop();
+
+ // Enable the depth render target with our transformation and render.
+ depthTarget_.enable(mvp);
+ vector<GLint> attrib_locations;
+ attrib_locations.push_back(depthTarget_.program()["position"].location());
+ attrib_locations.push_back(depthTarget_.program()["normal"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+ if (useVbo_) {
+ mesh_.render_vbo();
+ }
+ else {
+ mesh_.render_array();
+ }
+ depthTarget_.disable();
+
+ // Ground rendering using the above generated texture...
+ ground_.draw();
+
+ // Draw the "normal" view of the horse
+ modelview_.push();
+ modelview_.translate(-centerVec_.x(), -centerVec_.y(), -(centerVec_.z() + 2.0 + radius_));
+ modelview_.rotate(rotation_, 0.0f, 1.0f, 0.0f);
+ mvp = projection_.getCurrent();
+ mvp *= modelview_.getCurrent();
+
+ program_.start();
+ program_["ModelViewProjectionMatrix"] = mvp;
+
+ // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
+ // inverse transpose of the model view matrix.
+ LibMatrix::mat4 normal_matrix(modelview_.getCurrent());
+ normal_matrix.inverse().transpose();
+ program_["NormalMatrix"] = normal_matrix;
+ attrib_locations.clear();
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["normal"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+ if (useVbo_) {
+ mesh_.render_vbo();
+ }
+ else {
+ mesh_.render_array();
+ }
+
+ // Per-frame cleanup
+ modelview_.pop();
+}
+
+SceneShadow::SceneShadow(Canvas& canvas) :
+ Scene(canvas, "shadow"),
+ priv_(0)
+{
+ options_["use-vbo"] = Scene::Option("use-vbo", "true",
+ "Whether to use VBOs for rendering",
+ "false,true");
+ options_["interleave"] = Scene::Option("interleave", "false",
+ "Whether to interleave vertex attribute data",
+ "false,true");
+}
+
+bool
+SceneShadow::supported(bool show_errors)
+{
+ static const string oes_depth_texture("GL_OES_depth_texture");
+ static const string arb_depth_texture("GL_ARB_depth_texture");
+ if (!GLExtensions::support(oes_depth_texture) &&
+ !GLExtensions::support(arb_depth_texture)) {
+ if (show_errors) {
+ Log::error("We do not have the depth texture extension!!!\n");
+ }
+
+ return false;
+ }
+ return true;
+}
+
+bool
+SceneShadow::load()
+{
+ running_ = false;
+ return true;
+}
+
+void
+SceneShadow::unload()
+{
+}
+
+bool
+SceneShadow::setup()
+{
+ // If the scene isn't supported, don't bother to go through setup.
+ if (!supported(false) || !Scene::setup())
+ {
+ return false;
+ }
+
+ priv_ = new ShadowPrivate(canvas_);
+ if (!priv_->setup(options_)) {
+ delete priv_;
+ priv_ = 0;
+ return false;
+ }
+
+ // Set core scene timing after actual initialization so we don't measure
+ // set up time.
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+ running_ = true;
+
+ return true;
+}
+
+void
+SceneShadow::teardown()
+{
+ // Add scene-specific teardown here
+ priv_->teardown();
+ delete priv_;
+ Scene::teardown();
+}
+
+void
+SceneShadow::update()
+{
+ Scene::update();
+ // Add scene-specific update here
+ priv_->update(lastUpdateTime_ - startTime_);
+}
+
+void
+SceneShadow::draw()
+{
+ priv_->draw();
+}
+
+Scene::ValidationResult
+SceneShadow::validate()
+{
+ return Scene::ValidationUnknown;
+}
diff --git a/src/scene-terrain.cpp b/src/scene-terrain.cpp
new file mode 100644
index 0000000..bf8e18b
--- /dev/null
+++ b/src/scene-terrain.cpp
@@ -0,0 +1,362 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "mesh.h"
+#include "util.h"
+#include "texture.h"
+#include "shader-source.h"
+#include "renderer.h"
+
+using LibMatrix::vec2;
+using LibMatrix::vec3;
+using LibMatrix::vec4;
+using LibMatrix::mat4;
+
+class SceneTerrainPrivate
+{
+public:
+ SceneTerrainPrivate(Canvas &canvas, const LibMatrix::vec2 &repeat_overlay,
+ bool use_bloom, bool use_tilt_shift) :
+ canvas(canvas), repeat_overlay(repeat_overlay),
+ use_bloom(use_bloom), use_tilt_shift(use_tilt_shift),
+ terrain_renderer(0), bloom_v_renderer(0), bloom_h_renderer(0),
+ overlay_renderer(0), tilt_v_renderer(0), tilt_h_renderer(0),
+ copy_renderer(0), height_map_renderer(0), normal_map_renderer(0),
+ specular_map_renderer(0),
+ height_normal_chain(0), bloom_chain(0), tilt_chain(0), terrain_chain(0)
+ {
+ init_renderers();
+ }
+
+ ~SceneTerrainPrivate()
+ {
+ release_renderers();
+ }
+
+ void init_renderers()
+ {
+ /* Create and set up renderers */
+ const vec2 map_res(256.0f, 256.0f);
+ const vec2 screen_res(canvas.width(), canvas.height());
+ const vec2 bloom_res(256.0f, 256.0f);
+ const vec2 grass_res(512.0f, 512.0f);
+
+ height_map_renderer = new SimplexNoiseRenderer(map_res);
+ height_map_renderer->setup(height_map_renderer->size(), false, false);
+
+ normal_map_renderer = new NormalFromHeightRenderer(map_res);
+ normal_map_renderer->setup(normal_map_renderer->size(), false, false);
+
+ specular_map_renderer = new LuminanceRenderer(grass_res);
+ specular_map_renderer->setup_texture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
+ GL_REPEAT, GL_REPEAT);
+ specular_map_renderer->setup(specular_map_renderer->size(), false, false);
+
+ terrain_renderer = new TerrainRenderer(screen_res, repeat_overlay);
+ terrain_renderer->setup(terrain_renderer->size(),
+ !use_bloom && !use_tilt_shift,
+ true);
+ terrain_renderer->setup_texture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
+ GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+
+ /* Bloom */
+ if (use_bloom) {
+ bloom_h_renderer = new BlurRenderer(bloom_res, 2, 4.0,
+ BlurRenderer::BlurDirectionHorizontal,
+ vec2(1.0, 1.0) / screen_res,
+ 0.0);
+ bloom_h_renderer->setup_texture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
+ GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+ bloom_h_renderer->setup(bloom_h_renderer->size(), false, false);
+
+ bloom_v_renderer = new BlurRenderer(bloom_res, 2, 4.0,
+ BlurRenderer::BlurDirectionVertical,
+ vec2(1.0, 1.0) / bloom_res,
+ 0.0);
+ bloom_v_renderer->setup_texture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
+ GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+ bloom_v_renderer->setup(bloom_v_renderer->size(), false, false);
+ overlay_renderer = new OverlayRenderer(*terrain_renderer, 0.6);
+ }
+
+ /* Tilt-shift */
+ if (use_tilt_shift) {
+ tilt_h_renderer = new BlurRenderer(screen_res, 4, 2.7,
+ BlurRenderer::BlurDirectionHorizontal,
+ vec2(1.0, 1.0) / screen_res,
+ 0.5);
+ tilt_h_renderer->setup_texture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
+ GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+ tilt_h_renderer->setup(tilt_h_renderer->size(), false, false);
+
+ tilt_v_renderer = new BlurRenderer(screen_res, 4, 2.7,
+ BlurRenderer::BlurDirectionVertical,
+ vec2(1.0, 1.0) / screen_res,
+ 0.5);
+ }
+
+ /* Copy renderer */
+ if (use_bloom && !use_tilt_shift)
+ copy_renderer = new CopyRenderer(screen_res);
+
+ /* Height normal chain */
+ height_normal_chain = new RendererChain();
+ height_normal_chain->append(*height_map_renderer);
+ height_normal_chain->append(*normal_map_renderer);
+
+ /* Bloom effect chain */
+ if (use_bloom) {
+ bloom_chain = new RendererChain();
+ bloom_chain->append(*bloom_h_renderer);
+ bloom_chain->append(*bloom_v_renderer);
+ bloom_chain->append(*overlay_renderer);
+ }
+
+ /* Tilt-shift effect chain */
+ if (use_tilt_shift) {
+ tilt_chain = new RendererChain();
+ tilt_chain->append(*tilt_h_renderer);
+ tilt_chain->append(*tilt_v_renderer);
+ }
+
+ /* Terrain chain */
+ terrain_chain = new RendererChain();
+ terrain_chain->append(*terrain_renderer);
+ if (use_bloom)
+ terrain_chain->append(*bloom_chain);
+ if (use_tilt_shift)
+ terrain_chain->append(*tilt_chain);
+
+ /*
+ * If are just using bloom, the terrain is rendered to a texture and
+ * bloom applied on that texture. We need to "copy" that texture's
+ * contents to the screen to make the scene visible.
+ */
+ if (use_bloom && !use_tilt_shift)
+ terrain_chain->append(*copy_renderer);
+
+ /*
+ * Set up renderer textures.
+ */
+ terrain_renderer->height_map_texture(height_map_renderer->texture());
+ terrain_renderer->normal_map_texture(normal_map_renderer->texture());
+ terrain_renderer->specular_map_texture(specular_map_renderer->texture());
+
+ specular_map_renderer->input_texture(terrain_renderer->diffuse1_texture());
+ }
+
+ void release_renderers()
+ {
+ delete terrain_chain;
+ delete bloom_chain;
+ delete tilt_chain;
+ delete height_normal_chain;
+
+ delete height_map_renderer;
+ delete normal_map_renderer;
+ delete specular_map_renderer;
+ delete terrain_renderer;
+ delete bloom_v_renderer;
+ delete bloom_h_renderer;
+ delete overlay_renderer;
+ delete tilt_v_renderer;
+ delete tilt_h_renderer;
+ delete copy_renderer;
+ }
+
+ Canvas &canvas;
+ LibMatrix::vec2 repeat_overlay;
+ bool use_bloom;
+ bool use_tilt_shift;
+
+ /* Renderers */
+ TerrainRenderer *terrain_renderer;
+ BlurRenderer *bloom_v_renderer;
+ BlurRenderer *bloom_h_renderer;
+ OverlayRenderer *overlay_renderer;
+ BlurRenderer *tilt_v_renderer;
+ BlurRenderer *tilt_h_renderer;
+ CopyRenderer *copy_renderer;
+
+ SimplexNoiseRenderer *height_map_renderer;
+ NormalFromHeightRenderer *normal_map_renderer;
+ LuminanceRenderer *specular_map_renderer;
+
+ /* Chains */
+ RendererChain *height_normal_chain;
+ RendererChain *bloom_chain;
+ RendererChain *tilt_chain;
+ RendererChain *terrain_chain;
+};
+
+SceneTerrain::SceneTerrain(Canvas &pCanvas) :
+ Scene(pCanvas, "terrain"), priv_(0)
+{
+ options_["repeat-overlay"] = Scene::Option("repeat-overlay", "6.0",
+ "How many times to repeat the terrain texture on the terrain plane (per side)");
+ options_["bloom"] = Scene::Option("bloom", "true",
+ "Use bloom post-processing effect",
+ "false,true");
+ options_["tilt-shift"] = Scene::Option("tilt-shift", "true",
+ "Use tilt-shift post-processing effect",
+ "false,true");
+}
+
+SceneTerrain::~SceneTerrain()
+{
+ delete priv_;
+}
+
+bool
+SceneTerrain::supported(bool show_errors)
+{
+ GLint vertex_textures;
+ glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &vertex_textures);
+
+ if (show_errors && vertex_textures <= 0) {
+ Log::error("SceneTerrain requires Vertex Texture Fetch support, "
+ "but GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS is %d\n",
+ vertex_textures);
+ }
+
+ return vertex_textures > 0;
+}
+
+bool
+SceneTerrain::load()
+{
+ Scene::load();
+
+ running_ = false;
+
+ return true;
+}
+
+void
+SceneTerrain::unload()
+{
+ Scene::unload();
+}
+
+bool
+SceneTerrain::setup()
+{
+ if (!Scene::setup())
+ return false;
+
+ /* Parse options */
+ float repeat = Util::fromString<double>(options_["repeat-overlay"].value);
+ LibMatrix::vec2 repeat_overlay(repeat, repeat);
+ bool use_bloom = options_["bloom"].value == "true";
+ bool use_tilt_shift = options_["tilt-shift"].value == "true";
+
+ priv_ = new SceneTerrainPrivate(canvas_, repeat_overlay,
+ use_bloom, use_tilt_shift);
+
+ /* Set up terrain rendering program */
+ LibMatrix::Stack4 model;
+ LibMatrix::Stack4 camera;
+ LibMatrix::mat4 projection = LibMatrix::Mat4::perspective(
+ 40.0, canvas_.width() / static_cast<float>(canvas_.height()),
+ 2.0, 4000.0);
+
+ /* Place camera */
+ camera.lookAt(-1200.0f, 800.0f, 1200.0f,
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0);
+
+ /* Move and rotate plane */
+ model.translate(0.0f, -125.0f, 0.0f);
+ model.rotate(-90.0, 1.0f, 0.0f, 0.0f);
+
+ LibMatrix::mat4 view_matrix(camera.getCurrent());
+ LibMatrix::mat4 model_matrix(model.getCurrent());
+
+ LibMatrix::mat4 model_view_matrix(view_matrix * model_matrix);
+
+ LibMatrix::mat4 normal_matrix(model_view_matrix);
+ normal_matrix.inverse().transpose();
+
+ /* Set up terrain renderer program */
+ priv_->terrain_renderer->program().start();
+ priv_->terrain_renderer->program()["viewMatrix"] = view_matrix;
+ priv_->terrain_renderer->program()["modelViewMatrix"] = model_view_matrix;
+ priv_->terrain_renderer->program()["normalMatrix"] = normal_matrix;
+ priv_->terrain_renderer->program()["projectionMatrix"] = projection;
+
+ /* Create the specular map */
+ priv_->specular_map_renderer->render();
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glViewport(0, 0, canvas_.width(), canvas_.height());
+
+ currentFrame_ = 0;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ running_ = true;
+
+ return true;
+}
+
+void
+SceneTerrain::teardown()
+{
+ delete priv_;
+ priv_ = 0;
+ Scene::teardown();
+}
+
+void
+SceneTerrain::update()
+{
+ Scene::update();
+
+ double now = Util::get_timestamp_us() / 1000000.0;
+ float diff = now - startTime_;
+ float scale = priv_->terrain_renderer->repeat_overlay().x() /
+ priv_->height_map_renderer->uv_scale().x();
+
+ /* Update height map */
+ priv_->height_map_renderer->program().start();
+ priv_->height_map_renderer->program()["uvOffset"] = vec2(diff * 0.05f, 0.0f);
+ priv_->terrain_renderer->program().start();
+ priv_->terrain_renderer->program()["uOffset"] = vec2(scale * diff * 0.05f, 0.0f);
+}
+
+void
+SceneTerrain::draw()
+{
+ /* Render the height and normal maps used by the terrain */
+ priv_->height_normal_chain->render();
+
+ /* Render the terrain plus any post-processing effects */
+ priv_->terrain_chain->render();
+}
+
+Scene::ValidationResult
+SceneTerrain::validate()
+{
+ return Scene::ValidationUnknown;
+}
diff --git a/src/scene-terrain/base-renderer.cpp b/src/scene-terrain/base-renderer.cpp
new file mode 100644
index 0000000..b00c3d5
--- /dev/null
+++ b/src/scene-terrain/base-renderer.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "renderer.h"
+
+BaseRenderer::BaseRenderer(const LibMatrix::vec2 &size) :
+ texture_(0), input_texture_(0), fbo_(0), depth_renderbuffer_(0),
+ min_filter_(GL_LINEAR), mag_filter_(GL_LINEAR),
+ wrap_s_(GL_CLAMP_TO_EDGE), wrap_t_(GL_CLAMP_TO_EDGE)
+{
+ setup(size, true, true);
+}
+
+BaseRenderer::~BaseRenderer()
+{
+ glDeleteTextures(1, &texture_);
+ glDeleteRenderbuffers(1, &depth_renderbuffer_);
+ glDeleteFramebuffers(1, &fbo_);
+}
+
+void
+BaseRenderer::setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth)
+{
+ size_ = size;
+ recreate(onscreen, has_depth);
+}
+
+void
+BaseRenderer::setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t)
+{
+ min_filter_ = min_filter;
+ mag_filter_ = mag_filter;
+ wrap_s_ = wrap_s;
+ wrap_t_ = wrap_t;
+ update_texture_parameters();
+}
+
+void
+BaseRenderer::make_current()
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ glViewport(0, 0, size_.x(), size_.y());
+ if (!fbo_ || depth_renderbuffer_) {
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+ }
+ else {
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ }
+}
+
+void
+BaseRenderer::update_mipmap()
+{
+ if (texture_ && min_filter_ != GL_NEAREST && min_filter_ != GL_LINEAR) {
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ glGenerateMipmap(GL_TEXTURE_2D);
+ }
+}
+
+void
+BaseRenderer::recreate(bool onscreen, bool has_depth)
+{
+ if (texture_) {
+ glDeleteTextures(1, &texture_);
+ texture_ = 0;
+ }
+ if (fbo_) {
+ glDeleteRenderbuffers(1, &depth_renderbuffer_);
+ depth_renderbuffer_ = 0;
+ glDeleteFramebuffers(1, &fbo_);
+ fbo_ = 0;
+ }
+ if (!onscreen) {
+ create_texture();
+ create_fbo(has_depth);
+ }
+}
+
+void
+BaseRenderer::create_texture()
+{
+ glGenTextures(1, &texture_);
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ update_texture_parameters();
+}
+
+void
+BaseRenderer::update_texture_parameters()
+{
+ if (texture_) {
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t_);
+ }
+ update_mipmap();
+}
+
+void
+BaseRenderer::create_fbo(bool has_depth)
+{
+ if (has_depth) {
+ /* Create a renderbuffer for depth storage */
+ glGenRenderbuffers(1, &depth_renderbuffer_);
+ glBindRenderbuffer(GL_RENDERBUFFER, depth_renderbuffer_);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
+ size_.x(), size_.y());
+ }
+
+ /* Create the FBO and attach the texture and the renderebuffer */
+ glGenFramebuffers(1, &fbo_);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, texture_, 0);
+ if (has_depth) {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, depth_renderbuffer_);
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
diff --git a/src/scene-terrain/blur-renderer.cpp b/src/scene-terrain/blur-renderer.cpp
new file mode 100644
index 0000000..65fb441
--- /dev/null
+++ b/src/scene-terrain/blur-renderer.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+void
+create_blur_shaders(ShaderSource& vtx_source, ShaderSource& frg_source,
+ unsigned int radius, float sigma, BlurRenderer::BlurDirection direction,
+ float tilt_shift);
+
+BlurRenderer::BlurRenderer(const LibMatrix::vec2 &size, int radius, float sigma,
+ BlurDirection dir, const LibMatrix::vec2 &step, float tilt_shift) :
+ TextureRenderer(size, *blur_program(true, radius, sigma, dir, step, tilt_shift))
+{
+ blur_program_ = blur_program(false, radius, sigma, dir, step, tilt_shift);
+}
+
+Program *
+BlurRenderer::blur_program(bool create_new, int radius, float sigma,
+ BlurDirection dir, const LibMatrix::vec2 &step,
+ float tilt_shift)
+{
+ static Program *blur_program(0);
+ if (create_new)
+ blur_program = 0;
+
+ if (!blur_program) {
+ blur_program = new Program();
+ ShaderSource blur_vtx_shader;
+ ShaderSource blur_frg_shader;
+ create_blur_shaders(blur_vtx_shader, blur_frg_shader, radius,
+ sigma, dir, tilt_shift);
+
+ if (dir == BlurDirectionHorizontal || dir == BlurDirectionBoth)
+ blur_frg_shader.add_const("TextureStepX", step.x());
+ if (dir == BlurDirectionVertical || dir == BlurDirectionBoth)
+ blur_frg_shader.add_const("TextureStepY", step.y());
+
+ Scene::load_shaders_from_strings(*blur_program,
+ blur_vtx_shader.str(),
+ blur_frg_shader.str());
+ blur_program->start();
+ (*blur_program)["Texture0"] = 0;
+ (*blur_program)["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ (*blur_program)["uvScale"] = LibMatrix::vec2(1.0f, 1.0f);
+ blur_program->stop();
+ }
+
+ return blur_program;
+}
+
+void
+create_blur_shaders(ShaderSource& vtx_source, ShaderSource& frg_source,
+ unsigned int radius, float sigma, BlurRenderer::BlurDirection direction,
+ float tilt_shift)
+{
+ vtx_source.append_file(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ frg_source.append_file(GLMARK_DATA_PATH"/shaders/terrain-blur.frag");
+
+ /* Don't let the gaussian curve become too narrow */
+ if (sigma < 1.0)
+ sigma = 1.0;
+
+ unsigned int side = 2 * radius + 1;
+ float values[radius];
+ float sum = 0.0;
+
+ for (unsigned int i = 0; i < radius + 1; i++) {
+ float s2 = 2.0 * sigma * sigma;
+ float k = 1.0 / std::sqrt(M_PI * s2) * std::exp( - (static_cast<float>(i) * i) / s2);
+ values[i] = k;
+ sum += k;
+ }
+
+ sum += sum - values[0];
+
+ for (unsigned int i = 0; i < radius + 1; i++) {
+ std::stringstream ss_tmp;
+ ss_tmp << "Kernel" << i;
+ frg_source.add_const(ss_tmp.str(), values[i] / sum);
+ }
+
+ frg_source.add_const("TiltShift", tilt_shift);
+
+ std::stringstream ss;
+
+ if (direction == BlurRenderer::BlurDirectionHorizontal ||
+ direction == BlurRenderer::BlurDirectionBoth)
+ {
+ if (tilt_shift == 1.0)
+ ss << "const float stepX = TextureStepX;" << std::endl;
+ else
+ ss << "float stepX = TextureStepX * abs(TiltShift - TextureCoord.y) / abs(1.0 - TiltShift);" << std::endl;
+ }
+
+ if (direction == BlurRenderer::BlurDirectionVertical ||
+ direction == BlurRenderer::BlurDirectionBoth)
+ {
+ if (tilt_shift == 1.0)
+ ss << "const float stepY = TextureStepY;" << std::endl;
+ else
+ ss << "float stepY = TextureStepY * abs(TiltShift - TextureCoord.y) / abs(1.0 - TiltShift);" << std::endl;
+ }
+
+ ss << "result = " << std::endl;
+
+ if (direction == BlurRenderer::BlurDirectionHorizontal) {
+ for (unsigned int i = 0; i < side; i++) {
+ int offset = static_cast<int>(i - radius);
+ ss << "texture2D(Texture0, TextureCoord + vec2(" <<
+ offset << ".0 * stepX, 0.0)) * Kernel" <<
+ std::abs(offset) << " +" << std::endl;
+ }
+ ss << "0.0 ;" << std::endl;
+ }
+ else if (direction == BlurRenderer::BlurDirectionVertical) {
+ for (unsigned int i = 0; i < side; i++) {
+ int offset = static_cast<int>(i - radius);
+ ss << "texture2D(Texture0, TextureCoord + vec2(0.0, " <<
+ offset << ".0 * stepY)) * Kernel" <<
+ std::abs(offset) << " +" << std::endl;
+ }
+ ss << "0.0 ;" << std::endl;
+ }
+ else if (direction == BlurRenderer::BlurDirectionBoth) {
+ for (unsigned int i = 0; i < side; i++) {
+ int ioffset = static_cast<int>(i - radius);
+ for (unsigned int j = 0; j < side; j++) {
+ int joffset = static_cast<int>(j - radius);
+ ss << "texture2D(Texture0, TextureCoord + vec2(" <<
+ ioffset << ".0 * stepX, " <<
+ joffset << ".0 * stepY))" <<
+ " * Kernel" << std::abs(ioffset) <<
+ " * Kernel" << std::abs(joffset) << " +" << std::endl;
+ }
+ }
+ ss << " 0.0;" << std::endl;
+ }
+
+ frg_source.replace("$CONVOLUTION$", ss.str());
+}
diff --git a/src/scene-terrain/copy-renderer.cpp b/src/scene-terrain/copy-renderer.cpp
new file mode 100644
index 0000000..1c91e66
--- /dev/null
+++ b/src/scene-terrain/copy-renderer.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+CopyRenderer::CopyRenderer(const LibMatrix::vec2 &size) :
+ TextureRenderer(size, *copy_program(true))
+{
+ copy_program_ = copy_program(false);
+}
+
+Program *
+CopyRenderer::copy_program(bool create_new)
+{
+ static Program *copy_program(0);
+ if (create_new)
+ copy_program = 0;
+
+ if (!copy_program) {
+ copy_program = new Program();
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain-overlay.frag");
+
+ Scene::load_shaders_from_strings(*copy_program, vtx_shader.str(), frg_shader.str());
+
+ copy_program->start();
+ (*copy_program)["tDiffuse"] = 0;
+ (*copy_program)["opacity"] = 1.0f;
+ (*copy_program)["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ (*copy_program)["uvScale"] = LibMatrix::vec2(1.0f, 1.0f);
+ copy_program->stop();
+ }
+
+ return copy_program;
+}
diff --git a/src/scene-terrain/luminance-renderer.cpp b/src/scene-terrain/luminance-renderer.cpp
new file mode 100644
index 0000000..2a88417
--- /dev/null
+++ b/src/scene-terrain/luminance-renderer.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+LuminanceRenderer::LuminanceRenderer(const LibMatrix::vec2 &size) :
+ TextureRenderer(size, *luminance_program(true))
+{
+ luminance_program_ = luminance_program(false);
+}
+
+Program *
+LuminanceRenderer::luminance_program(bool create_new)
+{
+ static Program *luminance_program(0);
+ if (create_new)
+ luminance_program = 0;
+
+ if (!luminance_program) {
+ luminance_program = new Program();
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain-luminance.frag");
+
+ Scene::load_shaders_from_strings(*luminance_program,
+ vtx_shader.str(), frg_shader.str());
+
+ luminance_program->start();
+ (*luminance_program)["tDiffuse"] = 0;
+ (*luminance_program)["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ (*luminance_program)["uvScale"] = LibMatrix::vec2(1.0f, 1.0f);
+ luminance_program->stop();
+ }
+
+ return luminance_program;
+}
+
+
diff --git a/src/scene-terrain/normal-from-height-renderer.cpp b/src/scene-terrain/normal-from-height-renderer.cpp
new file mode 100644
index 0000000..7a264c6
--- /dev/null
+++ b/src/scene-terrain/normal-from-height-renderer.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+NormalFromHeightRenderer::NormalFromHeightRenderer(const LibMatrix::vec2 &size) :
+ TextureRenderer(size, *normal_from_height_program(size, true))
+{
+ normal_from_height_program_ = normal_from_height_program(size, false);
+}
+
+Program *
+NormalFromHeightRenderer::normal_from_height_program(const LibMatrix::vec2 &size,
+ bool create_new)
+{
+ static Program *normal_from_height_program(0);
+ if (create_new)
+ normal_from_height_program = 0;
+
+ if (!normal_from_height_program) {
+ normal_from_height_program = new Program();
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain-normalmap.frag");
+
+ Scene::load_shaders_from_strings(*normal_from_height_program,
+ vtx_shader.str(), frg_shader.str());
+
+ normal_from_height_program->start();
+ (*normal_from_height_program)["heightMap"] = 0;
+ (*normal_from_height_program)["resolution"] = size;
+ (*normal_from_height_program)["height"] = 0.05f;
+ (*normal_from_height_program)["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ (*normal_from_height_program)["uvScale"] = LibMatrix::vec2(1.0f, 1.0f);
+ normal_from_height_program->stop();
+ }
+
+ return normal_from_height_program;
+}
+
diff --git a/src/scene-terrain/overlay-renderer.cpp b/src/scene-terrain/overlay-renderer.cpp
new file mode 100644
index 0000000..8fea325
--- /dev/null
+++ b/src/scene-terrain/overlay-renderer.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+OverlayRenderer::OverlayRenderer(IRenderer &target, GLfloat opacity) :
+ target_renderer_(target), opacity_(opacity)
+
+{
+ create_program();
+ create_mesh();
+}
+
+
+void
+OverlayRenderer::setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth)
+{
+ static_cast<void>(size);
+ static_cast<void>(onscreen);
+ static_cast<void>(has_depth);
+}
+
+void
+OverlayRenderer::setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t)
+{
+ static_cast<void>(min_filter);
+ static_cast<void>(mag_filter);
+ static_cast<void>(wrap_s);
+ static_cast<void>(wrap_t);
+}
+
+void
+OverlayRenderer::make_current()
+{
+ target_renderer_.make_current();
+}
+
+void
+OverlayRenderer::update_mipmap()
+{
+ target_renderer_.update_mipmap();
+}
+
+void
+OverlayRenderer::render()
+{
+ target_renderer_.make_current();
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, input_texture_);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ program_.start();
+
+ mesh_.render_vbo();
+
+ program_.stop();
+
+ glDisable(GL_BLEND);
+
+ target_renderer_.update_mipmap();
+}
+
+void
+OverlayRenderer::create_mesh()
+{
+ // Set vertex format
+ std::vector<int> vertex_format;
+ vertex_format.push_back(3); // Position
+ mesh_.set_vertex_format(vertex_format);
+
+ mesh_.make_grid(1, 1, 2.0, 2.0, 0);
+ mesh_.build_vbo();
+
+ program_.start();
+
+ // Set attribute locations
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ program_.stop();
+}
+
+void
+OverlayRenderer::create_program()
+{
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain-overlay.frag");
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_shader.str(), frg_shader.str()))
+ return;
+
+ program_.start();
+ program_["tDiffuse"] = 0;
+ program_["opacity"] = opacity_;
+ program_["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ program_["uvScale"] = LibMatrix::vec2(1.0f, 1.0f);
+ program_.stop();
+}
diff --git a/src/scene-terrain/renderer-chain.cpp b/src/scene-terrain/renderer-chain.cpp
new file mode 100644
index 0000000..54057e4
--- /dev/null
+++ b/src/scene-terrain/renderer-chain.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "renderer.h"
+
+void
+RendererChain::setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth)
+{
+ static_cast<void>(size);
+ static_cast<void>(onscreen);
+ static_cast<void>(has_depth);
+}
+
+void
+RendererChain::setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t)
+{
+ static_cast<void>(min_filter);
+ static_cast<void>(mag_filter);
+ static_cast<void>(wrap_s);
+ static_cast<void>(wrap_t);
+}
+
+void
+RendererChain::input_texture(GLuint t)
+{
+ if (!renderers_.empty()) {
+ IRenderer &renderer(*renderers_.front());
+ renderer.input_texture(t);
+ }
+}
+
+GLuint
+RendererChain::texture()
+{
+ GLuint t(0);
+
+ if (!renderers_.empty()) {
+ IRenderer &renderer(*renderers_.back());
+ t = renderer.texture();
+ }
+
+ return t;
+}
+
+LibMatrix::vec2
+RendererChain::size()
+{
+ LibMatrix::vec2 s;
+
+ if (!renderers_.empty()) {
+ IRenderer &renderer(*renderers_.back());
+ s = renderer.size();
+ }
+
+ return s;
+}
+
+void
+RendererChain::make_current()
+{
+ if (!renderers_.empty()) {
+ IRenderer &renderer(*renderers_.back());
+ renderer.make_current();
+ }
+}
+
+void
+RendererChain::update_mipmap()
+{
+ if (!renderers_.empty()) {
+ IRenderer &renderer(*renderers_.back());
+ renderer.update_mipmap();
+ }
+}
+
+void
+RendererChain::render()
+{
+ for(std::vector<IRenderer *>::iterator iter = renderers_.begin();
+ iter != renderers_.end();
+ iter++)
+ {
+ (*iter)->render();
+ }
+}
+
+void
+RendererChain::append(IRenderer &renderer)
+{
+ if (!renderers_.empty()) {
+ IRenderer &prev_renderer(*renderers_.back());
+ renderer.input_texture(prev_renderer.texture());
+ }
+
+ renderers_.push_back(&renderer);
+}
diff --git a/src/scene-terrain/renderer.h b/src/scene-terrain/renderer.h
new file mode 100644
index 0000000..5f2bfa0
--- /dev/null
+++ b/src/scene-terrain/renderer.h
@@ -0,0 +1,348 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include <stdint.h>
+#include <vector>
+
+#include "mesh.h"
+#include "vec.h"
+#include "program.h"
+#include "gl-headers.h"
+
+/**
+ * Renderer interface.
+ */
+class IRenderer
+{
+public:
+ /**
+ * Sets up the renderer's target.
+ */
+ virtual void setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth) = 0;
+ /**
+ * Sets up the renderer's target texture (if any).
+ */
+ virtual void setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t) = 0;
+ /**
+ * Sets the renderer's input texture.
+ */
+ virtual void input_texture(GLuint t) = 0;
+ /**
+ * Gets the renderer's target texture (if any).
+ */
+ virtual GLuint texture() = 0;
+ /**
+ * Gets the size of the renderer's target.
+ */
+ virtual LibMatrix::vec2 size() = 0;
+ /**
+ * Makes the renderer current i.e. the rendering target.
+ */
+ virtual void make_current() = 0;
+ /**
+ * Updates the mipmap of the texture backing the renderer (if any).
+ */
+ virtual void update_mipmap() = 0;
+ /**
+ * Renders to the renderer's target.
+ */
+ virtual void render() = 0;
+
+protected:
+ virtual ~IRenderer() {}
+};
+
+/**
+ * A chain of renderers, which implements IRenderer
+ */
+class RendererChain : public IRenderer
+{
+public:
+ RendererChain() {}
+ virtual ~RendererChain() {}
+
+ /* IRenderer methods */
+ void setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth);
+ void setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t);
+ void input_texture(GLuint t);
+ GLuint texture();
+ LibMatrix::vec2 size();
+ void make_current();
+ void update_mipmap();
+ void render();
+
+ /**
+ * Appends a renderer to the chain.
+ *
+ * @param renderer the renderer to append
+ */
+ void append(IRenderer &renderer);
+
+private:
+ std::vector<IRenderer *> renderers_;
+};
+
+/**
+ * A base implementation of the IRenderer interface.
+ */
+class BaseRenderer : public IRenderer
+{
+public:
+ BaseRenderer(const LibMatrix::vec2 &size);
+ virtual ~BaseRenderer();
+
+ /* IRenderer methods */
+ virtual void setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth);
+ virtual void setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t);
+ virtual void input_texture(GLuint t) { input_texture_ = t; }
+ virtual GLuint texture() { return texture_; }
+ virtual LibMatrix::vec2 size() { return size_; }
+ virtual void make_current();
+ virtual void update_mipmap();
+ virtual void render() = 0;
+
+protected:
+ void recreate(bool onscreen, bool has_depth);
+ void create_texture();
+ void update_texture_parameters();
+ void create_fbo(bool has_depth);
+
+ LibMatrix::vec2 size_;
+ GLuint texture_;
+ GLuint input_texture_;
+ GLuint fbo_;
+ GLuint depth_renderbuffer_;
+ GLint min_filter_;
+ GLint mag_filter_;
+ GLint wrap_s_;
+ GLint wrap_t_;
+};
+
+/**
+ * A renderer that renders its input texture to its target,
+ * according to the supplied GL Program.
+ */
+class TextureRenderer : public BaseRenderer
+{
+public:
+ TextureRenderer(const LibMatrix::vec2 &size, Program &program);
+ virtual ~TextureRenderer() { }
+
+ /* IRenderer/BaseRenderer methods */
+ virtual void render();
+
+ /**
+ * Gets the program associated with the renderer.
+ */
+ Program &program() { return program_; }
+
+private:
+ void create_mesh();
+
+ Mesh mesh_;
+ Program &program_;
+};
+
+/**
+ * A renderer that copies the input texture to its target.
+ */
+class CopyRenderer : public TextureRenderer
+{
+public:
+ CopyRenderer(const LibMatrix::vec2 &size);
+
+ virtual ~CopyRenderer() { delete copy_program_; }
+
+private:
+ static Program *copy_program(bool create_new);
+
+ Program *copy_program_;
+};
+
+/**
+ * A renderer that renders simplex noise to its target.
+ */
+class SimplexNoiseRenderer : public TextureRenderer
+{
+public:
+ SimplexNoiseRenderer(const LibMatrix::vec2 &size);
+ virtual ~SimplexNoiseRenderer() { delete noise_program_; }
+
+ LibMatrix::vec2 uv_scale() { return uv_scale_; }
+private:
+ static Program *noise_program(bool create_new);
+ static LibMatrix::vec2 uv_scale_;
+
+ Program *noise_program_;
+};
+
+/**
+ * A renderer that renders a normal map to its target from a
+ * height map in its input texture.
+ */
+class NormalFromHeightRenderer : public TextureRenderer
+{
+public:
+ NormalFromHeightRenderer(const LibMatrix::vec2 &size);
+ virtual ~NormalFromHeightRenderer() { delete normal_from_height_program_; }
+
+private:
+ static Program *normal_from_height_program(const LibMatrix::vec2 &size,
+ bool create_new);
+
+ Program *normal_from_height_program_;
+};
+
+/**
+ * A renderer that renders the luminance of its input texture to its target.
+ */
+class LuminanceRenderer : public TextureRenderer
+{
+public:
+ LuminanceRenderer(const LibMatrix::vec2 &size);
+ virtual ~LuminanceRenderer() { delete luminance_program_; }
+
+private:
+ static Program *luminance_program(bool create_new);
+
+ Program *luminance_program_;
+};
+
+
+/**
+ * A renderer that renders a blurred version of the input texture to its target.
+ */
+class BlurRenderer : public TextureRenderer
+{
+public:
+ enum BlurDirection {
+ BlurDirectionHorizontal,
+ BlurDirectionVertical,
+ BlurDirectionBoth
+ };
+
+ BlurRenderer(const LibMatrix::vec2 &size, int radius, float sigma,
+ BlurDirection dir, const LibMatrix::vec2 &step, float tilt_shift);
+ virtual ~BlurRenderer() { delete blur_program_; }
+
+private:
+ static Program *blur_program(bool create_new, int radius, float sigma,
+ BlurDirection dir, const LibMatrix::vec2 &step,
+ float tilt_shift);
+
+ Program *blur_program_;
+};
+
+/**
+ * A renderer that renders with opacity (overlays) it's input texture over
+ * the target of another renderer.
+ */
+class OverlayRenderer : public IRenderer
+{
+public:
+ OverlayRenderer(IRenderer &target, GLfloat opacity);
+ virtual ~OverlayRenderer() { }
+
+ /* IRenderable Methods */
+ void setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth);
+ void setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t);
+ void input_texture(GLuint t) { input_texture_ = t; }
+ virtual GLuint texture() { return target_renderer_.texture(); }
+ virtual LibMatrix::vec2 size() { return target_renderer_.size(); }
+ virtual void render();
+ void make_current();
+ void update_mipmap();
+
+private:
+ void create_mesh();
+ void create_program();
+
+ Mesh mesh_;
+ Program program_;
+ IRenderer &target_renderer_;
+ GLfloat opacity_;
+ GLuint input_texture_;
+};
+
+/**
+ * A renderer that renders a dynamic terrain as per the WebGL
+ * dynamic terrain demo.
+ */
+class TerrainRenderer : public BaseRenderer
+{
+public:
+ TerrainRenderer(const LibMatrix::vec2 &size, const LibMatrix::vec2 &repeat_overlay);
+ virtual ~TerrainRenderer();
+
+ /* IRenderable Methods */
+ virtual void render();
+
+ /**
+ * Gets the program associated with the renderer.
+ */
+ Program &program() { return program_; }
+ /**
+ * Sets the height map texture to use.
+ */
+ void height_map_texture(GLuint tex) { height_map_tex_ = tex; }
+ /**
+ * Sets the normal map texture to use.
+ */
+ void normal_map_texture(GLuint tex) { normal_map_tex_ = tex; }
+ /**
+ * Sets the specular map texture to use.
+ */
+ void specular_map_texture(GLuint tex) { specular_map_tex_ = tex; }
+ /**
+ * Returns the main diffuse texture.
+ */
+ GLuint diffuse1_texture() { return diffuse1_tex_; }
+ LibMatrix::vec2 repeat_overlay() { return repeat_overlay_; }
+
+private:
+ void create_mesh();
+ void init_textures();
+ void init_program();
+ void bind_textures();
+ void deinit_textures();
+
+ LibMatrix::vec3 color_to_vec3(uint32_t c)
+ {
+ return LibMatrix::vec3(((c >> 0) & 0xff) / 255.0,
+ ((c >> 8) & 0xff) / 255.0,
+ ((c >> 16) & 0xff) / 255.0);
+ }
+
+ Mesh mesh_;
+ Program program_;
+
+ GLuint height_map_tex_;
+ GLuint normal_map_tex_;
+ GLuint specular_map_tex_;
+ GLuint diffuse1_tex_;
+ GLuint diffuse2_tex_;
+ GLuint detail_tex_;
+ LibMatrix::vec2 repeat_overlay_;
+};
diff --git a/src/scene-terrain/simplex-noise-renderer.cpp b/src/scene-terrain/simplex-noise-renderer.cpp
new file mode 100644
index 0000000..42cc816
--- /dev/null
+++ b/src/scene-terrain/simplex-noise-renderer.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+LibMatrix::vec2 SimplexNoiseRenderer::uv_scale_(1.5f, 1.5);
+
+SimplexNoiseRenderer::SimplexNoiseRenderer(const LibMatrix::vec2 &size) :
+ TextureRenderer(size, *noise_program(true))
+{
+ noise_program_ = noise_program(false);
+}
+
+Program *
+SimplexNoiseRenderer::noise_program(bool create_new)
+{
+ static Program *noise_program(0);
+ if (create_new)
+ noise_program = 0;
+
+ if (!noise_program) {
+ noise_program = new Program();
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain-noise.frag");
+
+ Scene::load_shaders_from_strings(*noise_program, vtx_shader.str(), frg_shader.str());
+
+ noise_program->start();
+ (*noise_program)["time"] = 1.0f;
+ (*noise_program)["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ (*noise_program)["uvScale"] = uv_scale_;
+ noise_program->stop();
+ }
+
+ return noise_program;
+}
diff --git a/src/scene-terrain/terrain-renderer.cpp b/src/scene-terrain/terrain-renderer.cpp
new file mode 100644
index 0000000..536401a
--- /dev/null
+++ b/src/scene-terrain/terrain-renderer.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "texture.h"
+#include "shader-source.h"
+
+TerrainRenderer::TerrainRenderer(const LibMatrix::vec2 &size,
+ const LibMatrix::vec2 &repeat_overlay) :
+ BaseRenderer(size), height_map_tex_(0), normal_map_tex_(0),
+ specular_map_tex_(0), repeat_overlay_(repeat_overlay)
+{
+ create_mesh();
+ init_textures();
+ init_program();
+}
+
+TerrainRenderer::~TerrainRenderer()
+{
+ deinit_textures();
+}
+
+void
+TerrainRenderer::render()
+{
+ make_current();
+ glClearColor(0.825f, 0.7425f, 0.61875f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+ program_.start();
+
+ bind_textures();
+ mesh_.render_vbo();
+
+ program_.stop();
+
+ update_mipmap();
+}
+
+void
+TerrainRenderer::init_textures()
+{
+ /* Create textures */
+ Texture::load("terrain-grasslight-512", &diffuse1_tex_,
+ GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, 0);
+ Texture::load("terrain-backgrounddetailed6", &diffuse2_tex_,
+ GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, 0);
+ Texture::load("terrain-grasslight-512-nm", &detail_tex_,
+ GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, 0);
+
+ /* Set REPEAT wrap mode */
+ glBindTexture(GL_TEXTURE_2D, diffuse1_tex_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ glBindTexture(GL_TEXTURE_2D, diffuse2_tex_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ glBindTexture(GL_TEXTURE_2D, detail_tex_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+}
+
+
+void
+TerrainRenderer::init_program()
+{
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain.frag");
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_shader.str(), frg_shader.str()))
+ return;
+
+ program_.start();
+ /* Fog */
+ program_["fogDensity"] = 0.00025f;
+ program_["fogNear"] = 1.0f;
+ program_["fogFar"] = 2000.0f;
+ program_["fogColor"] = LibMatrix::vec3(0.825, 0.7425, 0.61875);
+
+ /* Lights */
+ program_["ambientLightColor"] = color_to_vec3(0xffffff);
+
+ program_["pointLightColor[0]"] = color_to_vec3(0xffffff);
+ program_["pointLightPosition[0]"] = LibMatrix::vec3(0.0, 0.0, 0.0);
+ program_["pointLightDistance[0]"] = 0.0f;
+
+ /* Textures */
+ program_["tDiffuse1"] = 0;
+ program_["tDiffuse2"] = 1;
+ program_["tDetail"] = 2;
+ program_["tNormal"] = 3;
+ program_["tSpecular"] = 4;
+ program_["tDisplacement"] = 5;
+
+ program_["uNormalScale"] = 3.5f;
+
+ program_["uDisplacementBias"] = 0.0f;
+ program_["uDisplacementScale"] = 375.0f;
+
+ program_["uDiffuseColor"] = color_to_vec3(0xffffff);
+ program_["uSpecularColor"] = color_to_vec3(0xffffff);
+ program_["uAmbientColor"] = color_to_vec3(0x888888);
+ program_["uShininess"] = 30.0f;
+ program_["uOpacity"] = 1.0f;
+
+ program_["uRepeatOverlay"] = repeat_overlay_;
+
+ program_["uOffset"] = LibMatrix::vec2(0.0, 0.0);
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["normal"].location());
+ attrib_locations.push_back(program_["tangent"].location());
+ attrib_locations.push_back(program_["uv"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ program_.stop();
+}
+
+void
+TerrainRenderer::bind_textures()
+{
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, diffuse1_tex_);
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, diffuse2_tex_);
+
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, detail_tex_);
+
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(GL_TEXTURE_2D, normal_map_tex_);
+
+ glActiveTexture(GL_TEXTURE4);
+ glBindTexture(GL_TEXTURE_2D, specular_map_tex_);
+
+ glActiveTexture(GL_TEXTURE5);
+ glBindTexture(GL_TEXTURE_2D, height_map_tex_);
+}
+
+void
+TerrainRenderer::deinit_textures()
+{
+ glDeleteTextures(1, &diffuse1_tex_);
+ glDeleteTextures(1, &diffuse2_tex_);
+ glDeleteTextures(1, &detail_tex_);
+}
+
+static void
+grid_conf(Mesh &mesh, int x, int y, int n_x, int n_y,
+ LibMatrix::vec3 &ul,
+ LibMatrix::vec3 &ll,
+ LibMatrix::vec3 &ur,
+ LibMatrix::vec3 &lr)
+{
+ struct PlaneMeshVertex {
+ LibMatrix::vec3 position;
+ LibMatrix::vec2 texcoord;
+ LibMatrix::vec3 normal;
+ LibMatrix::vec3 tangent;
+ };
+
+ LibMatrix::vec2 uv_ul(static_cast<float>(x) / n_x,
+ 1.0 - static_cast<float>(y) / n_y);
+ LibMatrix::vec2 uv_lr(static_cast<float>(x + 1) / n_x,
+ 1.0 - static_cast<float>(y + 1) / n_y);
+
+ LibMatrix::vec3 normal(0.0, 0.0, 1.0);
+ LibMatrix::vec3 tangent(1.0, 0.0, 0.0);
+
+ PlaneMeshVertex cell_vertices[] = {
+ {
+ ll,
+ LibMatrix::vec2(uv_ul.x(), uv_lr.y()),
+ normal,
+ tangent
+ },
+ {
+ lr,
+ LibMatrix::vec2(uv_lr.x(), uv_lr.y()),
+ normal,
+ tangent
+ },
+ {
+ ur,
+ LibMatrix::vec2(uv_lr.x(), uv_ul.y()),
+ normal,
+ tangent
+ },
+ {
+ ul,
+ LibMatrix::vec2(uv_ul.x(), uv_ul.y()),
+ normal,
+ tangent
+ }
+ };
+
+ unsigned int vertex_index[] = {0, 1, 2, 0, 2, 3};
+
+ for (size_t i = 0; i < sizeof(vertex_index) / sizeof(*vertex_index); i++) {
+ PlaneMeshVertex& vertex = cell_vertices[vertex_index[i]];
+
+ mesh.next_vertex();
+ mesh.set_attrib(0, vertex.position);
+ mesh.set_attrib(1, vertex.normal);
+ mesh.set_attrib(2, vertex.tangent);
+ mesh.set_attrib(3, vertex.texcoord);
+ }
+}
+
+void
+TerrainRenderer::create_mesh()
+{
+ std::vector<int> vertex_format;
+ vertex_format.push_back(3);
+ vertex_format.push_back(3);
+ vertex_format.push_back(3);
+ vertex_format.push_back(2);
+ mesh_.set_vertex_format(vertex_format);
+
+ mesh_.make_grid(256, 256, 6000, 6000, 0, grid_conf);
+ mesh_.build_vbo();
+}
+
diff --git a/src/scene-terrain/texture-renderer.cpp b/src/scene-terrain/texture-renderer.cpp
new file mode 100644
index 0000000..93d61db
--- /dev/null
+++ b/src/scene-terrain/texture-renderer.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "renderer.h"
+
+TextureRenderer::TextureRenderer(const LibMatrix::vec2 &size, Program &program) :
+ BaseRenderer(size), program_(program)
+{
+ /* Create the mesh (quad) used for rendering */
+ create_mesh();
+}
+
+void
+TextureRenderer::create_mesh()
+{
+ // Set vertex format
+ std::vector<int> vertex_format;
+ vertex_format.push_back(3); // Position
+ mesh_.set_vertex_format(vertex_format);
+
+ mesh_.make_grid(1, 1, 2.0, 2.0, 0);
+ mesh_.build_vbo();
+
+ program_.start();
+
+ // Set attribute locations
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ program_.stop();
+}
+
+void
+TextureRenderer::render()
+{
+ make_current();
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, input_texture_);
+
+ program_.start();
+
+ mesh_.render_vbo();
+
+ program_.stop();
+
+ update_mipmap();
+}
diff --git a/src/scene-texture.cpp b/src/scene-texture.cpp
new file mode 100644
index 0000000..12aec1b
--- /dev/null
+++ b/src/scene-texture.cpp
@@ -0,0 +1,346 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ * Jesse Barker (glmark2)
+ */
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "program.h"
+#include "shader-source.h"
+#include "texture.h"
+#include "model.h"
+#include "util.h"
+#include <cmath>
+
+using LibMatrix::vec3;
+using std::string;
+
+SceneTexture::SceneTexture(Canvas &pCanvas) :
+ Scene(pCanvas, "texture"), radius_(0.0),
+ orientModel_(false), orientationAngle_(0.0)
+{
+ const ModelMap& modelMap = Model::find_models();
+ string optionValues;
+ for (ModelMap::const_iterator modelIt = modelMap.begin();
+ modelIt != modelMap.end();
+ modelIt++)
+ {
+ static bool doSeparator(false);
+ if (doSeparator)
+ {
+ optionValues += ",";
+ }
+ const std::string& curName = modelIt->first;
+ optionValues += curName;
+ doSeparator = true;
+ }
+ options_["model"] = Scene::Option("model", "cube", "Which model to use",
+ optionValues);
+ options_["texture-filter"] = Scene::Option("texture-filter", "nearest",
+ "The texture filter to use",
+ "nearest,linear,linear-shader,mipmap");
+ optionValues = "";
+ const TextureMap& textureMap = Texture::find_textures();
+ for (TextureMap::const_iterator textureIt = textureMap.begin();
+ textureIt != textureMap.end();
+ textureIt++)
+ {
+ static bool doSeparator(false);
+ if (doSeparator)
+ {
+ optionValues += ",";
+ }
+ const std::string& curName = textureIt->first;
+ optionValues += curName;
+ doSeparator = true;
+ }
+ options_["texture"] = Scene::Option("texture", "crate-base", "Which texture to use",
+ optionValues);
+ options_["texgen"] = Scene::Option("texgen", "false",
+ "Whether to generate texcoords in the shader",
+ "false,true");
+}
+
+SceneTexture::~SceneTexture()
+{
+}
+
+bool
+SceneTexture::load()
+{
+ rotationSpeed_ = LibMatrix::vec3(36.0f, 36.0f, 36.0f);
+
+ running_ = false;
+
+ return true;
+}
+
+void
+SceneTexture::unload()
+{
+ mesh_.reset();
+}
+
+bool
+SceneTexture::setup()
+{
+ if (!Scene::setup())
+ return false;
+
+ static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.vert");
+ static const std::string vtx_shader_texgen_filename(GLMARK_DATA_PATH"/shaders/light-basic-texgen.vert");
+ static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic-tex.frag");
+ static const std::string frg_shader_bilinear_filename(GLMARK_DATA_PATH"/shaders/light-basic-tex-bilinear.frag");
+ static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
+ static const LibMatrix::vec4 materialDiffuse(1.0f, 1.0f, 1.0f, 1.0f);
+
+ // Create texture according to selected filtering
+ GLint min_filter = GL_NONE;
+ GLint mag_filter = GL_NONE;
+ const std::string &filter = options_["texture-filter"].value;
+
+ if (filter == "nearest") {
+ min_filter = GL_NEAREST;
+ mag_filter = GL_NEAREST;
+ }
+ else if (filter == "linear") {
+ min_filter = GL_LINEAR;
+ mag_filter = GL_LINEAR;
+ }
+ else if (filter == "linear-shader") {
+ min_filter = GL_NEAREST;
+ mag_filter = GL_NEAREST;
+ }
+ else if (filter == "mipmap") {
+ min_filter = GL_LINEAR_MIPMAP_LINEAR;
+ mag_filter = GL_LINEAR;
+ }
+
+ const string& whichTexture(options_["texture"].value);
+ if (!Texture::load(whichTexture, &texture_, min_filter, mag_filter, 0))
+ return false;
+
+ // Load shaders
+ bool doTexGen(options_["texgen"].value == "true");
+ ShaderSource vtx_source;
+ if (doTexGen) {
+ vtx_source.append_file(vtx_shader_texgen_filename);
+ vtx_source.add_const("PI", static_cast<float>(M_PI));
+ }
+ else {
+ vtx_source.append_file(vtx_shader_filename);
+ }
+ ShaderSource frg_source;
+ if (filter == "linear-shader") {
+ frg_source.append_file(frg_shader_bilinear_filename);
+ LibMatrix::vec2 texture_size(512, 512);
+ frg_source.add_const("TextureSize", texture_size);
+ }
+ else {
+ frg_source.append_file(frg_shader_filename);
+ }
+
+ // Add constants to shaders
+ vtx_source.add_const("LightSourcePosition", lightPosition);
+ vtx_source.add_const("MaterialDiffuse", materialDiffuse);
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return false;
+ }
+
+ Model model;
+ const string& whichModel(options_["model"].value);
+ bool modelLoaded = model.load(whichModel);
+ if(!modelLoaded)
+ return false;
+
+ // Now that we're successfully loaded, there are a few quirks about
+ // some of the known models that we need to account for. The draw
+ // logic for the scene wants to rotate the model around the Y axis.
+ // Most of our models are described this way. Some need adjustment
+ // (an additional rotation that gets the model into the correct
+ // orientation).
+ //
+ // Here's a summary:
+ //
+ // Angel rotates around the Y axis
+ // Armadillo rotates around the Y axis
+ // Buddha rotates around the X axis
+ // Bunny rotates around the Y axis
+ // Dragon rotates around the X axis
+ // Horse rotates around the Y axis
+ if (whichModel == "buddha" || whichModel == "dragon")
+ {
+ orientModel_ = true;
+ orientationAngle_ = -90.0;
+ orientationVec_ = vec3(1.0, 0.0, 0.0);
+ }
+ else if (whichModel == "armadillo")
+ {
+ orientModel_ = true;
+ orientationAngle_ = 180.0;
+ orientationVec_ = vec3(0.0, 1.0, 0.0);
+ }
+
+ if (model.needTexcoords())
+ model.calculate_texcoords();
+ model.calculate_normals();
+ // Tell the converter which attributes we care about
+ std::vector<std::pair<Model::AttribType, int> > attribs;
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
+ if (!doTexGen) {
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeTexcoord, 2));
+ }
+ model.convert_to_mesh(mesh_, attribs);
+ mesh_.build_vbo();
+
+ // Calculate a projection matrix that is a good fit for the model
+ vec3 maxVec = model.maxVec();
+ vec3 minVec = model.minVec();
+ vec3 diffVec = maxVec - minVec;
+ centerVec_ = maxVec + minVec;
+ centerVec_ /= 2.0;
+ float diameter = diffVec.length();
+ radius_ = diameter / 2;
+ float fovy = 2.0 * atanf(radius_ / (2.0 + radius_));
+ fovy /= M_PI;
+ fovy *= 180.0;
+ float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height()));
+ perspective_.setIdentity();
+ perspective_ *= LibMatrix::Mat4::perspective(fovy, aspect, 2.0, 2.0 + diameter);
+
+ program_.start();
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["normal"].location());
+ if (doTexGen) {
+ program_["CenterPoint"] = centerVec_;
+ }
+ else {
+ attrib_locations.push_back(program_["texcoord"].location());
+ }
+ mesh_.set_attrib_locations(attrib_locations);
+
+ currentFrame_ = 0;
+ rotation_ = LibMatrix::vec3();
+ running_ = true;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return true;
+}
+
+void
+SceneTexture::teardown()
+{
+ program_.stop();
+ program_.release();
+
+ glDeleteTextures(1, &texture_);
+
+ Scene::teardown();
+}
+
+void
+SceneTexture::update()
+{
+ Scene::update();
+
+ double elapsed_time = lastUpdateTime_ - startTime_;
+
+ rotation_ = rotationSpeed_ * elapsed_time;
+}
+
+void
+SceneTexture::draw()
+{
+ // Load the ModelViewProjectionMatrix uniform in the shader
+ LibMatrix::Stack4 model_view;
+ model_view.translate(-centerVec_.x(), -centerVec_.y(), -(centerVec_.z() + 2.5 + radius_));
+ model_view.rotate(rotation_.x(), 1.0f, 0.0f, 0.0f);
+ model_view.rotate(rotation_.y(), 0.0f, 1.0f, 0.0f);
+ model_view.rotate(rotation_.z(), 0.0f, 0.0f, 1.0f);
+ if (orientModel_)
+ {
+ model_view.rotate(orientationAngle_, orientationVec_.x(), orientationVec_.y(), orientationVec_.z());
+ }
+ LibMatrix::mat4 model_view_proj(perspective_);
+ model_view_proj *= model_view.getCurrent();
+
+ program_["ModelViewProjectionMatrix"] = model_view_proj;
+
+ // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
+ // inverse transpose of the model view matrix.
+ LibMatrix::mat4 normal_matrix(model_view.getCurrent());
+ normal_matrix.inverse().transpose();
+ program_["NormalMatrix"] = normal_matrix;
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_);
+
+ mesh_.render_vbo();
+}
+
+Scene::ValidationResult
+SceneTexture::validate()
+{
+ static const double radius_3d(std::sqrt(3 * 2.0 * 2.0));
+
+ if (rotation_.x() != 0 || rotation_.y() != 0 || rotation_.z() != 0)
+ return Scene::ValidationUnknown;
+
+ Canvas::Pixel ref;
+
+ Canvas::Pixel pixel = canvas_.read_pixel(canvas_.width() / 2 + 3,
+ canvas_.height() / 2 + 3);
+
+ const std::string &filter = options_["texture-filter"].value;
+
+ if (filter == "nearest")
+ ref = Canvas::Pixel(0x2b, 0x2a, 0x28, 0xff);
+ else if (filter == "linear")
+ ref = Canvas::Pixel(0x2b, 0x2a, 0x28, 0xff);
+ else if (filter == "linear-shader")
+ ref = Canvas::Pixel(0x2d, 0x2c, 0x2a, 0xff);
+ else if (filter == "mipmap")
+ ref = Canvas::Pixel(0x2c, 0x2d, 0x2a, 0xff);
+ else
+ return Scene::ValidationUnknown;
+
+ double dist = pixel.distance_rgb(ref);
+
+ if (dist < radius_3d + 0.01) {
+ return Scene::ValidationSuccess;
+ }
+ else {
+ Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+ ref.to_le32(), pixel.to_le32(), dist);
+ return Scene::ValidationFailure;
+ }
+}
diff --git a/src/scene.cpp b/src/scene.cpp
new file mode 100644
index 0000000..975537d
--- /dev/null
+++ b/src/scene.cpp
@@ -0,0 +1,288 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ */
+#include "scene.h"
+#include "log.h"
+#include "shader-source.h"
+#include "options.h"
+#include "util.h"
+#include <sstream>
+#include <cmath>
+#include <algorithm>
+
+using std::stringstream;
+using std::string;
+using std::map;
+
+Scene::Option::Option(const std::string &nam, const std::string &val, const std::string &desc,
+ const std::string &values) :
+name(nam), value(val), default_value(val), description(desc), set(false)
+{
+ Util::split(values, ',', acceptable_values, Util::SplitModeNormal);
+}
+
+Scene::Scene(Canvas &pCanvas, const string &name) :
+ canvas_(pCanvas), name_(name),
+ startTime_(0), lastUpdateTime_(0), currentFrame_(0),
+ running_(0), duration_(0)
+{
+ options_["duration"] = Scene::Option("duration", "10.0",
+ "The duration of each benchmark in seconds");
+ options_["vertex-precision"] = Scene::Option("vertex-precision",
+ "default,default,default,default",
+ "The precision values for the vertex shader (\"int,float,sampler2d,samplercube\")");
+ options_["fragment-precision"] = Scene::Option("fragment-precision",
+ "default,default,default,default",
+ "The precision values for the fragment shader (\"int,float,sampler2d,samplercube\")");
+ /* FPS options */
+ options_["show-fps"] = Scene::Option("show-fps", "false",
+ "Show live FPS counter",
+ "false,true");
+ options_["fps-pos"] = Scene::Option("fps-pos", "-1.0,-1.0",
+ "The position on screen where to show FPS");
+ options_["fps-size"] = Scene::Option("fps-size", "0.03",
+ "The width of each glyph for the FPS");
+ /* Title options */
+ options_["title"] = Scene::Option("title", "",
+ "The scene title to show");
+ options_["title-pos"] = Scene::Option("title-pos", "-0.7,-1.0",
+ "The position on screen where to show the title");
+ options_["title-size"] = Scene::Option("title-size", "0.03",
+ "The width of each glyph in the title");
+}
+
+Scene::~Scene()
+{
+}
+
+bool
+Scene::supported(bool show_errors)
+{
+ static_cast<void>(show_errors);
+ return true;
+}
+
+bool
+Scene::load()
+{
+ return true;
+}
+
+void
+Scene::unload()
+{
+}
+
+bool
+Scene::setup()
+{
+ duration_ = Util::fromString<double>(options_["duration"].value);
+
+ ShaderSource::default_precision(
+ ShaderSource::Precision(options_["vertex-precision"].value),
+ ShaderSource::ShaderTypeVertex
+ );
+
+ ShaderSource::default_precision(
+ ShaderSource::Precision(options_["fragment-precision"].value),
+ ShaderSource::ShaderTypeFragment
+ );
+
+ currentFrame_ = 0;
+ running_ = false;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ lastUpdateTime_ = startTime_;
+
+ return supported(true);
+}
+
+void
+Scene::teardown()
+{
+}
+
+void
+Scene::update()
+{
+ double current_time = Util::get_timestamp_us() / 1000000.0;
+ double elapsed_time = current_time - startTime_;
+
+ currentFrame_++;
+
+ lastUpdateTime_ = current_time;
+
+ if (elapsed_time >= duration_)
+ running_ = false;
+}
+
+void
+Scene::draw()
+{
+}
+
+string
+Scene::info_string(const string &title)
+{
+ stringstream ss;
+
+ ss << "[" << name_ << "] " << Scene::construct_title(title);
+
+ return ss.str();
+}
+
+unsigned
+Scene::average_fps()
+{
+ double elapsed_time = lastUpdateTime_ - startTime_;
+ return currentFrame_ / elapsed_time;
+}
+
+bool
+Scene::set_option(const string &opt, const string &val)
+{
+ map<string, Option>::iterator iter = options_.find(opt);
+
+ if (iter == options_.end())
+ return false;
+
+ std::vector<std::string> &values(iter->second.acceptable_values);
+
+ if (!values.empty() &&
+ std::find(values.begin(), values.end(), val) == values.end())
+ {
+ return false;
+ }
+
+ iter->second.value = val;
+ iter->second.set = true;
+
+ return true;
+}
+
+void
+Scene::reset_options()
+{
+ for (map<string, Option>::iterator iter = options_.begin();
+ iter != options_.end();
+ iter++)
+ {
+ Option &opt = iter->second;
+
+ opt.value = opt.default_value;
+ opt.set = false;
+ }
+}
+
+bool
+Scene::set_option_default(const string &opt, const string &val)
+{
+ map<string, Option>::iterator iter = options_.find(opt);
+
+ if (iter == options_.end())
+ return false;
+
+ std::vector<std::string> &values(iter->second.acceptable_values);
+
+ if (!values.empty() &&
+ std::find(values.begin(), values.end(), val) == values.end())
+ {
+ return false;
+ }
+
+ iter->second.default_value = val;
+
+ return true;
+}
+
+
+string
+Scene::construct_title(const string &title)
+{
+ stringstream ss;
+
+ if (title == "") {
+ for (map<string, Option>::iterator iter = options_.begin();
+ iter != options_.end();
+ iter++)
+ {
+ if (Options::show_all_options || iter->second.set)
+ {
+ ss << iter->first << "=" << iter->second.value << ":";
+ }
+ }
+
+ if (ss.str().empty())
+ ss << "<default>:";
+ }
+ else
+ ss << title;
+
+ return ss.str();
+
+}
+
+bool
+Scene::load_shaders_from_strings(Program &program,
+ const std::string &vtx_shader,
+ const std::string &frg_shader,
+ const std::string &vtx_shader_filename,
+ const std::string &frg_shader_filename)
+{
+ program.init();
+
+ Log::debug("Loading vertex shader from file %s:\n%s",
+ vtx_shader_filename.c_str(), vtx_shader.c_str());
+
+ program.addShader(GL_VERTEX_SHADER, vtx_shader);
+ if (!program.valid()) {
+ Log::error("Failed to add vertex shader from file %s:\n %s\n",
+ vtx_shader_filename.c_str(),
+ program.errorMessage().c_str());
+ program.release();
+ return false;
+ }
+
+ Log::debug("Loading fragment shader from file %s:\n%s",
+ frg_shader_filename.c_str(), frg_shader.c_str());
+
+ program.addShader(GL_FRAGMENT_SHADER, frg_shader);
+ if (!program.valid()) {
+ Log::error("Failed to add fragment shader from file %s:\n %s\n",
+ frg_shader_filename.c_str(),
+ program.errorMessage().c_str());
+ program.release();
+ return false;
+ }
+
+ program.build();
+ if (!program.ready()) {
+ Log::error("Failed to link program created from files %s and %s: %s\n",
+ vtx_shader_filename.c_str(),
+ frg_shader_filename.c_str(),
+ program.errorMessage().c_str());
+ program.release();
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/scene.h b/src/scene.h
new file mode 100644
index 0000000..8c4d752
--- /dev/null
+++ b/src/scene.h
@@ -0,0 +1,592 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ * Marc Ordinas i Llopis, Collabora Ltd. (pulsar scene)
+ * Jesse Barker (glmark2)
+ */
+#ifndef GLMARK2_SCENE_H_
+#define GLMARK2_SCENE_H_
+
+#include "gl-headers.h"
+
+#include "mesh.h"
+#include "vec.h"
+#include "program.h"
+
+#include <math.h>
+
+#include <string>
+#include <map>
+#include <list>
+#include <vector>
+#include "canvas.h"
+
+/**
+ * A configurable scene used for creating benchmarks.
+ */
+class Scene
+{
+public:
+ virtual ~Scene();
+
+ /**
+ * Scene options.
+ */
+ struct Option {
+ Option(const std::string &nam, const std::string &val, const std::string &desc,
+ const std::string &values = "");
+
+ Option() {}
+ std::string name;
+ std::string value;
+ std::string default_value;
+ std::string description;
+ std::vector<std::string> acceptable_values;
+ bool set;
+ };
+
+ /**
+ * The result of a validation check.
+ */
+ enum ValidationResult {
+ ValidationFailure,
+ ValidationSuccess,
+ ValidationUnknown
+ };
+
+ /**
+ * Checks whether this scene (in its current configuration) is supported.
+ *
+ * @param show_errors whether to log errors about unsupported features
+ *
+ * @return whether the scene is supported
+ */
+ virtual bool supported(bool show_errors);
+
+ /**
+ * Performs option-independent resource loading and configuration.
+ *
+ * It should be safe to call ::load() (and the corresponding ::unload())
+ * only once per program execution, although you may choose to do so more
+ * times to better manage resource consumption.
+ *
+ * @return whether loading succeeded
+ */
+ virtual bool load();
+
+ /**
+ * Performs option-independent resource unloading.
+ */
+ virtual void unload();
+
+ /**
+ * Performs option-dependent resource loading and configuration.
+ *
+ * This method also prepares a scene for a benchmark run.
+ * It should be called just before running a scene/benchmark.
+ *
+ * The base Scene::setup() method also checks whether a scene
+ * configuration is supported by calling ::supported(true).
+ *
+ * @return whether setting the scene up succeeded
+ */
+ virtual bool setup();
+
+ /**
+ * Performs option-dependent resource unloading.
+ *
+ * This method should be called just after running a scene/benchmark.
+ *
+ * @return the operation status
+ */
+ virtual void teardown();
+
+ /**
+ * Updates the scene state.
+ */
+ virtual void update();
+
+ /**
+ * Draws the current scene state.
+ */
+ virtual void draw();
+
+ /**
+ * Gets an informational string describing the scene.
+ *
+ * @param title if specified, a custom title to use, instead of the default
+ */
+ virtual std::string info_string(const std::string &title = "");
+
+ /**
+ * Sets the value of an option for this scene.
+ *
+ * @param opt the option to set
+ * @param val the value to set the option to
+ *
+ * @return whether the option value was set successfully
+ */
+ virtual bool set_option(const std::string &opt, const std::string &val);
+
+ /**
+ * Validates the current output of this scene.
+ *
+ * This method should be called after having called ::draw() once.
+ *
+ * @return the validation result
+ */
+ virtual ValidationResult validate() { return ValidationUnknown; }
+
+ /**
+ * Gets whether this scene is running.
+ *
+ * @return true if running, false otherwise
+ */
+ bool running() { return running_; }
+
+ /**
+ * Sets whether this scene is running.
+ *
+ * @return true if running, false otherwise
+ */
+ void running(bool r) { running_ = r; }
+
+ /**
+ * Gets the average FPS value for this scene.
+ *
+ * @return the average FPS value
+ */
+ unsigned average_fps();
+
+ /**
+ * Gets the name of the scene.
+ * @return the name of the scene
+ */
+ const std::string &name() { return name_; }
+
+ /**
+ * Resets all scene options to their default values.
+ */
+ void reset_options();
+
+ /**
+ * Sets the default value of a scene option.
+ */
+ bool set_option_default(const std::string &opt, const std::string &val);
+
+ /**
+ * Gets the scene options.
+ *
+ * @return the scene options
+ */
+ const std::map<std::string, Option> &options() { return options_; }
+
+ /**
+ * Gets a dummy scene object reference.
+ *
+ * @return the dummy Scene
+ */
+ static Scene &dummy()
+ {
+ static Scene dummy_scene(Canvas::dummy(), "");
+ return dummy_scene;
+ }
+
+ /**
+ * Loads a shader program from a pair of vertex and fragment shader strings.
+ *
+ * @return whether the operation succeeded
+ */
+ static bool load_shaders_from_strings(Program &program,
+ const std::string &vtx_shader,
+ const std::string &frg_shader,
+ const std::string &vtx_shader_filename = "None",
+ const std::string &frg_shader_filename = "None");
+
+protected:
+ Scene(Canvas &pCanvas, const std::string &name);
+ std::string construct_title(const std::string &title);
+
+ Canvas &canvas_;
+ std::string name_;
+ std::map<std::string, Option> options_;
+ double startTime_;
+ double lastUpdateTime_;
+ unsigned currentFrame_;
+ bool running_;
+ double duration_; // Duration of run in seconds
+};
+
+/*
+ * Special Scene used for setting the default options
+ */
+class SceneDefaultOptions : public Scene
+{
+public:
+ SceneDefaultOptions(Canvas &pCanvas) : Scene(pCanvas, "") {}
+ bool set_option(const std::string &opt, const std::string &val);
+ bool setup();
+
+private:
+ std::list<std::pair<std::string, std::string> > defaultOptions_;
+};
+
+class SceneBuild : public Scene
+{
+public:
+ SceneBuild(Canvas &pCanvas);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~SceneBuild();
+
+protected:
+ Program program_;
+ LibMatrix::mat4 perspective_;
+ LibMatrix::vec3 centerVec_;
+ float radius_;
+ Mesh mesh_;
+ bool orientModel_;
+ float orientationAngle_;
+ LibMatrix::vec3 orientationVec_;
+ float rotation_;
+ float rotationSpeed_;
+ bool useVbo_;
+};
+
+class SceneTexture : public Scene
+{
+public:
+ SceneTexture(Canvas &pCanvas);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~SceneTexture();
+
+protected:
+ Program program_;
+ Mesh mesh_;
+ GLuint texture_;
+ float radius_;
+ bool orientModel_;
+ float orientationAngle_;
+ LibMatrix::vec3 orientationVec_;
+ LibMatrix::mat4 perspective_;
+ LibMatrix::vec3 centerVec_;
+ LibMatrix::vec3 rotation_;
+ LibMatrix::vec3 rotationSpeed_;
+};
+
+class SceneShading : public Scene
+{
+public:
+ SceneShading(Canvas &pCanvas);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~SceneShading();
+
+protected:
+ Program program_;
+ float radius_;
+ bool orientModel_;
+ float orientationAngle_;
+ LibMatrix::vec3 orientationVec_;
+ LibMatrix::vec3 centerVec_;
+ LibMatrix::mat4 perspective_;
+ Mesh mesh_;
+ float rotation_;
+ float rotationSpeed_;
+};
+
+class SceneGrid : public Scene
+{
+public:
+ SceneGrid(Canvas &pCanvas, const std::string &name);
+ virtual bool load();
+ virtual void unload();
+ virtual bool setup();
+ virtual void teardown();
+ virtual void update();
+ virtual void draw();
+ virtual ValidationResult validate();
+
+ ~SceneGrid();
+
+protected:
+ Program program_;
+ Mesh mesh_;
+ float rotation_;
+ float rotationSpeed_;
+};
+
+class SceneConditionals : public SceneGrid
+{
+public:
+ SceneConditionals(Canvas &pCanvas);
+ bool setup();
+ ValidationResult validate();
+
+ ~SceneConditionals();
+};
+
+class SceneFunction : public SceneGrid
+{
+public:
+ SceneFunction(Canvas &pCanvas);
+ bool setup();
+ ValidationResult validate();
+
+ ~SceneFunction();
+};
+
+class SceneLoop : public SceneGrid
+{
+public:
+ SceneLoop(Canvas &pCanvas);
+ bool setup();
+ ValidationResult validate();
+
+ ~SceneLoop();
+};
+
+class SceneBump : public Scene
+{
+public:
+ SceneBump(Canvas &pCanvas);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~SceneBump();
+
+protected:
+ Program program_;
+ Mesh mesh_;
+ GLuint texture_;
+ float rotation_;
+ float rotationSpeed_;
+private:
+ bool setup_model_plain(const std::string &type);
+ bool setup_model_normals();
+ bool setup_model_normals_tangent();
+ bool setup_model_height();
+};
+
+class SceneEffect2D : public Scene
+{
+public:
+ SceneEffect2D(Canvas &pCanvas);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~SceneEffect2D();
+
+protected:
+ Program program_;
+
+ Mesh mesh_;
+ GLuint texture_;
+};
+
+class ScenePulsar : public Scene
+{
+public:
+ ScenePulsar(Canvas &pCanvas);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~ScenePulsar();
+
+protected:
+ int numQuads_;
+ Program program_;
+ Mesh mesh_;
+ LibMatrix::vec3 scale_;
+ std::vector<LibMatrix::vec3> rotations_;
+ std::vector<LibMatrix::vec3> rotationSpeeds_;
+ GLuint texture_;
+
+private:
+ void create_and_setup_mesh();
+};
+
+struct SceneDesktopPrivate;
+
+class SceneDesktop : public Scene
+{
+public:
+ SceneDesktop(Canvas &canvas);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~SceneDesktop();
+
+private:
+ SceneDesktopPrivate *priv_;
+};
+
+struct SceneBufferPrivate;
+
+class SceneBuffer : public Scene
+{
+public:
+ SceneBuffer(Canvas &canvas);
+ bool supported(bool show_errors);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~SceneBuffer();
+
+private:
+ SceneBufferPrivate *priv_;
+};
+
+class SceneIdeasPrivate;
+
+class SceneIdeas : public Scene
+{
+public:
+ SceneIdeas(Canvas &pCanvas);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~SceneIdeas();
+
+private:
+ SceneIdeasPrivate* priv_;
+};
+
+class SceneTerrainPrivate;
+
+class SceneTerrain : public Scene
+{
+public:
+ SceneTerrain(Canvas &pCanvas);
+ bool supported(bool show_errors);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~SceneTerrain();
+
+private:
+ SceneTerrainPrivate* priv_;
+};
+
+class JellyfishPrivate;
+class SceneJellyfish : public Scene
+{
+ JellyfishPrivate* priv_;
+public:
+ SceneJellyfish(Canvas &pCanvas);
+ ~SceneJellyfish();
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+};
+
+class ShadowPrivate;
+class SceneShadow : public Scene
+{
+ ShadowPrivate* priv_;
+public:
+ SceneShadow(Canvas& canvas);
+ bool supported(bool show_errors);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+};
+
+class RefractPrivate;
+class SceneRefract : public Scene
+{
+ RefractPrivate* priv_;
+public:
+ SceneRefract(Canvas& canvas);
+ bool supported(bool show_errors);
+ bool load();
+ void unload();
+ bool setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+};
+
+#endif
diff --git a/src/text-renderer.cpp b/src/text-renderer.cpp
new file mode 100644
index 0000000..93d87fb
--- /dev/null
+++ b/src/text-renderer.cpp
@@ -0,0 +1,292 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#include "text-renderer.h"
+#include "gl-headers.h"
+#include "scene.h"
+#include "shader-source.h"
+#include "vec.h"
+#include "mat.h"
+#include "texture.h"
+
+using LibMatrix::vec2;
+using LibMatrix::mat4;
+
+/* These are specific to the glyph texture atlas we are using */
+static const unsigned int texture_size(512);
+static const vec2 glyph_size_pixels(29.0, 57.0);
+static const vec2 glyph_size(glyph_size_pixels/texture_size);
+
+/******************
+ * Public methods *
+ ******************/
+
+/**
+ * TextRenderer default constructor.
+ */
+TextRenderer::TextRenderer(Canvas& canvas) :
+ canvas_(canvas), dirty_(false), position_(-1.0, -1.0),
+ texture_(0)
+{
+ size(0.03);
+
+ glGenBuffers(2, vbo_);
+ ShaderSource vtx_source(GLMARK_DATA_PATH"/shaders/text-renderer.vert");
+ ShaderSource frg_source(GLMARK_DATA_PATH"/shaders/text-renderer.frag");
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
+ frg_source.str()))
+ {
+ return;
+ }
+
+ GLint prev_program;
+ glGetIntegerv(GL_CURRENT_PROGRAM, &prev_program);
+
+ program_.start();
+ program_["Texture0"] = 0;
+
+ glUseProgram(prev_program);
+
+ /* Load the glyph texture atlas */
+ Texture::find_textures();
+ Texture::load("glyph-atlas", &texture_,
+ GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,0);
+}
+
+TextRenderer::~TextRenderer()
+{
+ glDeleteBuffers(2, vbo_);
+ glDeleteTextures(1, &texture_);
+}
+
+/**
+ * Sets the text string to render.
+ *
+ * @param t the text string
+ */
+void
+TextRenderer::text(const std::string& t)
+{
+ if (text_ != t) {
+ text_ = t;
+ dirty_ = true;
+ }
+}
+
+/**
+ * Sets the screen position to render at.
+ *
+ * @param t the position
+ */
+void
+TextRenderer::position(const LibMatrix::vec2& p)
+{
+ if (position_ != p) {
+ position_ = p;
+ dirty_ = true;
+ }
+}
+
+/**
+ * Sets the size of each rendered glyph.
+ *
+ * The size corresponds to the width of each glyph
+ * in normalized screen coordinates.
+ *
+ * @param s the size of each glyph
+ */
+void
+TextRenderer::size(float s)
+{
+ if (size_.x() != s) {
+ /* Take into account the glyph and canvas aspect ratio */
+ double canvas_aspect =
+ static_cast<double>(canvas_.width()) / canvas_.height();
+ double glyph_aspect_rev = glyph_size.y() / glyph_size.x();
+ size_ = vec2(s, s * canvas_aspect * glyph_aspect_rev);
+ dirty_ = true;
+ }
+}
+
+/**
+ * Renders the text.
+ */
+void
+TextRenderer::render()
+{
+ /* Save state */
+ GLint prev_program = 0;
+ GLint prev_array_buffer = 0;
+ GLint prev_elem_array_buffer = 0;
+ GLint prev_blend_src_rgb = 0;
+ GLint prev_blend_dst_rgb = 0;
+ GLint prev_blend_src_alpha = 0;
+ GLint prev_blend_dst_alpha = 0;
+ GLboolean prev_blend = GL_FALSE;
+ GLboolean prev_depth_test = GL_FALSE;
+ glGetIntegerv(GL_CURRENT_PROGRAM, &prev_program);
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prev_array_buffer);
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prev_elem_array_buffer);
+ glGetIntegerv(GL_BLEND_SRC_RGB, &prev_blend_src_rgb);
+ glGetIntegerv(GL_BLEND_DST_RGB, &prev_blend_dst_rgb);
+ glGetIntegerv(GL_BLEND_SRC_ALPHA, &prev_blend_src_alpha);
+ glGetIntegerv(GL_BLEND_DST_ALPHA, &prev_blend_dst_alpha);
+ glGetBooleanv(GL_BLEND, &prev_blend);
+ glGetBooleanv(GL_DEPTH_TEST, &prev_depth_test);
+
+ /* Set new state */
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_[1]);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDisable(GL_DEPTH_TEST);
+
+ if (dirty_) {
+ create_geometry();
+ dirty_ = false;
+ }
+
+ program_.start();
+ GLint position_loc = program_["position"].location();
+ GLint texcoord_loc = program_["texcoord"].location();
+
+ /* Render */
+ glEnableVertexAttribArray(position_loc);
+ glEnableVertexAttribArray(texcoord_loc);
+ glVertexAttribPointer(position_loc, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
+ glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
+ reinterpret_cast<const GLvoid *>(2 * sizeof(float)));
+
+ glDrawElements(GL_TRIANGLES, 6 * text_.length(), GL_UNSIGNED_SHORT, 0);
+
+ glDisableVertexAttribArray(texcoord_loc);
+ glDisableVertexAttribArray(position_loc);
+
+ /* Restore state */
+ if (prev_depth_test == GL_TRUE)
+ glEnable(GL_DEPTH_TEST);
+ if (prev_blend == GL_FALSE)
+ glDisable(GL_BLEND);
+ glBlendFuncSeparate(prev_blend_src_rgb, prev_blend_dst_rgb,
+ prev_blend_src_alpha, prev_blend_dst_alpha);
+ glBindBuffer(GL_ARRAY_BUFFER, prev_array_buffer);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_elem_array_buffer);
+ glUseProgram(prev_program);
+}
+
+/*******************
+ * Private methods *
+ *******************/
+
+/**
+ * Creates the geometry needed to render the text.
+ *
+ * This method assumes that the text VBOs are properly bound.
+ */
+void
+TextRenderer::create_geometry()
+{
+ std::vector<float> array;
+ std::vector<GLushort> elem_array;
+ vec2 pos(position_);
+
+ for (size_t i = 0; i < text_.size(); i++) {
+ vec2 texcoord = get_glyph_coords(text_[i]);
+
+ /* Emit the elements for this glyph quad */
+ /* Lower left */
+ array.push_back(pos.x());
+ array.push_back(pos.y());
+ array.push_back(texcoord.x());
+ array.push_back(texcoord.y());
+
+ /* Lower right */
+ pos.x(pos.x() + size_.x());
+ texcoord.x(texcoord.x() + glyph_size.x());
+ array.push_back(pos.x());
+ array.push_back(pos.y());
+ array.push_back(texcoord.x());
+ array.push_back(texcoord.y());
+
+ /* Upper left */
+ pos.x(pos.x() - size_.x());
+ pos.y(pos.y() + size_.y());
+ texcoord.x(texcoord.x() - glyph_size.x());
+ texcoord.y(texcoord.y() + glyph_size.y());
+ array.push_back(pos.x());
+ array.push_back(pos.y());
+ array.push_back(texcoord.x());
+ array.push_back(texcoord.y());
+
+ /* Upper right */
+ pos.x(pos.x() + size_.x());
+ texcoord.x(texcoord.x() + glyph_size.x());
+ array.push_back(pos.x());
+ array.push_back(pos.y());
+ array.push_back(texcoord.x());
+ array.push_back(texcoord.y());
+
+ /* Prepare for the next glyph */
+ pos.y(pos.y() - size_.y());
+
+ /* Emit the element indices for this glyph quad */
+ elem_array.push_back(4 * i);
+ elem_array.push_back(4 * i + 1);
+ elem_array.push_back(4 * i + 2);
+ elem_array.push_back(4 * i + 2);
+ elem_array.push_back(4 * i + 1);
+ elem_array.push_back(4 * i + 3);
+ }
+
+ /* Load the data into the corresponding VBOs */
+ glBufferData(GL_ARRAY_BUFFER, array.size() * sizeof(float),
+ &array[0], GL_DYNAMIC_DRAW);
+
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, elem_array.size() * sizeof(GLushort),
+ &elem_array[0], GL_DYNAMIC_DRAW);
+}
+
+/**
+ * Gets the texcoords of a glyph in the glyph texture atlas.
+ *
+ * @param c the character to get the glyph texcoords of
+ *
+ * @return the texcoords
+ */
+vec2
+TextRenderer::get_glyph_coords(char c)
+{
+ static const unsigned int glyphs_per_row(texture_size / glyph_size_pixels.x());
+
+ /* We only support the ASCII printable characters */
+ if (c < 32 || c >= 127)
+ c = 32;
+
+ int n = c - 32;
+ int row = n / glyphs_per_row;
+ int col = n % glyphs_per_row;
+
+ return vec2(col * glyph_size.x(), 1.0 - (row + 1) * glyph_size.y());
+}
+
diff --git a/src/text-renderer.h b/src/text-renderer.h
new file mode 100644
index 0000000..d5b2dfb
--- /dev/null
+++ b/src/text-renderer.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis (glmark2)
+ */
+#ifndef GLMARK2_TEXT_RENDERER_H_
+#define GLMARK2_TEXT_RENDERER_H_
+
+#include <string>
+#include "gl-headers.h"
+#include "vec.h"
+#include "program.h"
+#include "canvas.h"
+
+/**
+ * Renders text using OpenGL textures.
+ */
+class TextRenderer
+{
+public:
+ TextRenderer(Canvas& canvas);
+ ~TextRenderer();
+
+ void text(const std::string& t);
+ void position(const LibMatrix::vec2& p);
+ void size(float s);
+
+ void render();
+
+private:
+ void create_geometry();
+ LibMatrix::vec2 get_glyph_coords(char c);
+
+ Canvas& canvas_;
+ bool dirty_;
+ std::string text_;
+ LibMatrix::vec2 position_;
+ LibMatrix::vec2 size_;
+ Program program_;
+ GLuint vbo_[2];
+ GLuint texture_;
+};
+
+#endif
diff --git a/src/texture.cpp b/src/texture.cpp
new file mode 100644
index 0000000..a3c503a
--- /dev/null
+++ b/src/texture.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ */
+#include "texture.h"
+#include "log.h"
+#include "util.h"
+#include "image-reader.h"
+
+#include <cstdarg>
+#include <vector>
+
+class ImageData {
+ void resize(unsigned int w, unsigned int h, unsigned int b)
+ {
+ width = w;
+ height = h;
+ bpp = b;
+ delete [] pixels;
+ pixels = new unsigned char[bpp * width * height];
+ }
+
+public:
+ ImageData() : pixels(0), width(0), height(0), bpp(0) {}
+ ~ImageData() { delete [] pixels; }
+ bool load(ImageReader &reader);
+
+ unsigned char *pixels;
+ unsigned int width;
+ unsigned int height;
+ unsigned int bpp;
+};
+
+bool
+ImageData::load(ImageReader &reader)
+{
+ if (reader.error())
+ return false;
+
+ resize(reader.width(), reader.height(), reader.pixelBytes());
+
+ Log::debug(" Height: %d Width: %d Bpp: %d\n", width, height, bpp);
+
+ /*
+ * Copy the row data to the image buffer in reverse Y order, suitable
+ * for texture upload.
+ */
+ unsigned char *ptr = &pixels[bpp * width * (height - 1)];
+
+ while (reader.nextRow(ptr))
+ ptr -= bpp * width;
+
+ return !reader.error();
+}
+
+static void
+setup_texture(GLuint *tex, ImageData &image, GLint min_filter, GLint mag_filter)
+{
+ GLenum format = image.bpp == 3 ? GL_RGB : GL_RGBA;
+
+ glGenTextures(1, tex);
+ glBindTexture(GL_TEXTURE_2D, *tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, format, image.width, image.height, 0,
+ format, GL_UNSIGNED_BYTE, image.pixels);
+
+ if ((min_filter != GL_NEAREST && min_filter != GL_LINEAR) ||
+ (mag_filter != GL_NEAREST && mag_filter != GL_LINEAR))
+ {
+ glGenerateMipmap(GL_TEXTURE_2D);
+ }
+}
+
+namespace TexturePrivate
+{
+TextureMap textureMap;
+}
+
+bool
+Texture::load(const std::string &textureName, GLuint *pTexture, ...)
+{
+ // Make sure the named texture is in the map.
+ TextureMap::const_iterator textureIt = TexturePrivate::textureMap.find(textureName);
+ if (textureIt == TexturePrivate::textureMap.end())
+ {
+ return false;
+ }
+
+ // Pull the pathname out of the descriptor and use it for the PNG load.
+ TextureDescriptor* desc = textureIt->second;
+ const std::string& filename = desc->pathname();
+ ImageData image;
+
+ if (desc->filetype() == TextureDescriptor::FileTypePNG) {
+ PNGReader reader(filename);
+ if (!image.load(reader))
+ return false;
+ }
+ else if (desc->filetype() == TextureDescriptor::FileTypeJPEG) {
+ JPEGReader reader(filename);
+ if (!image.load(reader))
+ return false;
+ }
+
+ va_list ap;
+ va_start(ap, pTexture);
+ GLint arg;
+
+ while ((arg = va_arg(ap, GLint)) != 0) {
+ GLint arg2 = va_arg(ap, GLint);
+ setup_texture(pTexture, image, arg, arg2);
+ pTexture++;
+ }
+
+ va_end(ap);
+
+ return true;
+}
+
+const TextureMap&
+Texture::find_textures()
+{
+ using std::vector;
+ using std::string;
+ if (!TexturePrivate::textureMap.empty())
+ {
+ return TexturePrivate::textureMap;
+ }
+ vector<string> pathVec;
+ string dataDir(GLMARK_DATA_PATH"/textures");
+ Util::list_files(dataDir, pathVec);
+ // Now that we have a list of all of the image files available to us,
+ // let's go through and pull out the names and what format they're in
+ // so the scene can decide which ones to use.
+ for(vector<string>::const_iterator pathIt = pathVec.begin();
+ pathIt != pathVec.end();
+ pathIt++)
+ {
+ const string& curPath = *pathIt;
+ string::size_type namePos(0);
+ string::size_type slashPos = curPath.rfind("/");
+ if (slashPos != string::npos)
+ {
+ // Advance to the first character after the last slash
+ namePos = slashPos + 1;
+ }
+
+ // Find the position of the extension
+ string::size_type pngExtPos = curPath.rfind(".png");
+ string::size_type jpgExtPos = curPath.rfind(".jpg");
+ string::size_type extPos(string::npos);
+
+ // Select the extension that's closer to the end of the file name
+ if (pngExtPos == string::npos)
+ {
+ extPos = jpgExtPos;
+ }
+ else if (jpgExtPos == string::npos)
+ {
+ extPos = pngExtPos;
+ }
+ else
+ {
+ extPos = std::max(pngExtPos, jpgExtPos);
+ }
+
+ if (extPos == string::npos)
+ {
+ // We can't trivially determine it's an image file so skip it...
+ continue;
+ }
+
+ // Set the file type based on the extension
+ TextureDescriptor::FileType type(TextureDescriptor::FileTypeUnknown);
+ if (extPos == pngExtPos)
+ {
+ type = TextureDescriptor::FileTypePNG;
+ }
+ else if (extPos == jpgExtPos)
+ {
+ type = TextureDescriptor::FileTypeJPEG;
+ }
+
+ string name(curPath, namePos, extPos - namePos);
+ TextureDescriptor* desc = new TextureDescriptor(name, curPath, type);
+ TexturePrivate::textureMap.insert(std::make_pair(name, desc));
+ }
+
+ return TexturePrivate::textureMap;
+}
diff --git a/src/texture.h b/src/texture.h
new file mode 100644
index 0000000..17623ef
--- /dev/null
+++ b/src/texture.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 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 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ */
+#ifndef GLMARK2_TEXTURE_H_
+#define GLMARK2_TEXTURE_H_
+
+#include "gl-headers.h"
+
+#include <string>
+#include <map>
+
+/**
+ * A descriptor for a texture file.
+ */
+class TextureDescriptor
+{
+public:
+ enum FileType {
+ FileTypeUnknown,
+ FileTypePNG,
+ FileTypeJPEG,
+ };
+
+ TextureDescriptor(const std::string& name, const std::string& pathname,
+ FileType filetype) :
+ name_(name),
+ pathname_(pathname),
+ filetype_(filetype) {}
+ ~TextureDescriptor() {}
+ const std::string& pathname() const { return pathname_; }
+ FileType filetype() const { return filetype_; }
+private:
+ std::string name_;
+ std::string pathname_;
+ FileType filetype_;
+ TextureDescriptor();
+};
+
+typedef std::map<std::string, TextureDescriptor*> TextureMap;
+
+class Texture
+{
+public:
+ /**
+ * Load a texture by name.
+ *
+ * You must initialize the available texture collection using
+ * Texture::find_textures() before using this method.
+ *
+ * @name: the texture name
+ *
+ * @return: true if the operation succeeded, false otherwise
+ */
+ static bool load(const std::string &name, GLuint *pTexture, ...);
+ /**
+ * Locate all available textures.
+ *
+ * This method scans the built-in data paths and builds a database of usable
+ * textures available to scenes. Map is available on a read-only basis to
+ * scenes that might find it useful for listing textures, etc.
+ *
+ * @return: a map containing information about the located textures
+ */
+ static const TextureMap& find_textures();
+};
+
+#endif
diff --git a/src/wscript_build b/src/wscript_build
new file mode 100644
index 0000000..b742b48
--- /dev/null
+++ b/src/wscript_build
@@ -0,0 +1,92 @@
+all_sources = bld.path.ant_glob('*.cpp scene-ideas/*.cc scene-terrain/*.cpp')
+common_sources = [f for f in all_sources if f.name.find('canvas-') == -1 and
+ f.name.find('android') == -1 and
+ f.name.find('egl-') == -1]
+gl_sources = ['canvas-x11.cpp', 'canvas-x11-glx.cpp']
+glesv2_sources = ['canvas-x11.cpp', 'canvas-x11-egl.cpp', 'egl-state.cpp']
+gl_drm_sources = ['canvas-drm.cpp', 'egl-state.cpp']
+glesv2_drm_sources = ['canvas-drm.cpp', 'egl-state.cpp']
+libmatrix_sources = [f for f in bld.path.ant_glob('libmatrix/*.cc')
+ if not f.name.endswith('test.cc')]
+includes = ['.', 'scene-ideas', 'scene-terrain']
+
+if bld.env.USE_GL:
+ bld(
+ features = ['cxx', 'cxxstlib'],
+ source = libmatrix_sources,
+ target = 'matrix',
+ lib = ['m'],
+ includes = ['.'],
+ export_includes = 'libmatrix',
+ defines = ['USE_GL', 'USE_EXCEPTIONS']
+ )
+ bld(
+ features = ['cxx', 'cprogram'],
+ source = common_sources + gl_sources,
+ target = 'glmark2',
+ use = ['x11', 'gl', 'matrix', 'libpng12'],
+ lib = ['m', 'jpeg'],
+ includes = includes,
+ defines = ['USE_GL', 'USE_EXCEPTIONS']
+ )
+
+if bld.env.USE_GLESv2:
+ bld(
+ features = ['cxx', 'cxxstlib'],
+ source = libmatrix_sources,
+ target = 'matrix-es2',
+ lib = ['m'],
+ includes = ['.'],
+ export_includes = 'libmatrix',
+ defines = ['USE_GLESv2', 'USE_EXCEPTIONS']
+ )
+ bld(
+ features = ['cxx', 'cprogram'],
+ source = common_sources + glesv2_sources,
+ target = 'glmark2-es2',
+ use = ['x11', 'egl', 'glesv2', 'matrix-es2', 'libpng12'],
+ lib = ['m', 'dl', 'jpeg'],
+ includes = includes,
+ defines = ['USE_GLESv2', 'USE_EXCEPTIONS']
+ )
+
+if bld.env.USE_GL_DRM:
+ bld(
+ features = ['cxx', 'cxxstlib'],
+ source = libmatrix_sources,
+ target = 'matrix-drm',
+ lib = ['m'],
+ includes = ['.'],
+ export_includes = 'libmatrix',
+ defines = ['USE_DRM', '__GBM__', 'USE_GL', 'USE_EXCEPTIONS']
+ )
+ bld(
+ features = ['cxx', 'cprogram'],
+ source = common_sources + gl_drm_sources,
+ target = 'glmark2-drm',
+ use = ['egl', 'gl', 'matrix-drm', 'libpng12', 'drm', 'gbm'],
+ lib = ['m', 'jpeg', 'dl'],
+ includes = includes,
+ defines = ['USE_DRM', '__GBM__', 'USE_GL']
+ )
+
+if bld.env.USE_GLESv2_DRM:
+ bld(
+ features = ['cxx', 'cxxstlib'],
+ source = libmatrix_sources,
+ target = 'matrix-es2-drm',
+ lib = ['m'],
+ includes = ['.'],
+ export_includes = 'libmatrix',
+ defines = ['USE_DRM', '__GBM__', 'USE_GLESv2', 'USE_EXCEPTIONS']
+ )
+ bld(
+ features = ['cxx', 'cprogram'],
+ source = common_sources + glesv2_drm_sources,
+ target = 'glmark2-es2-drm',
+ use = ['egl', 'glesv2', 'matrix-es2-drm', 'libpng12', 'drm',
+ 'gbm'],
+ lib = ['m', 'jpeg', 'dl'],
+ includes = includes,
+ defines = ['USE_DRM', '__GBM__', 'USE_GLESv2']
+ )
diff --git a/waf b/waf
new file mode 100755
index 0000000..3d52896
--- /dev/null
+++ b/waf
@@ -0,0 +1,162 @@
+#!/usr/bin/env python
+# encoding: ISO8859-1
+# Thomas Nagy, 2005-2011
+
+"""
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+"""
+
+import os, sys
+
+VERSION="1.6.11"
+REVISION="30618c54883417962c38f5d395f83584"
+INSTALL=''
+C1='#*'
+C2='#%'
+cwd = os.getcwd()
+join = os.path.join
+
+
+WAF='waf'
+def b(x):
+ return x
+if sys.hexversion>0x300000f:
+ WAF='waf3'
+ def b(x):
+ return x.encode()
+
+def err(m):
+ print(('\033[91mError: %s\033[0m' % m))
+ sys.exit(1)
+
+def unpack_wafdir(dir):
+ f = open(sys.argv[0],'rb')
+ c = 'corrupt archive (%d)'
+ while 1:
+ line = f.readline()
+ if not line: err('run waf-light from a folder containing waflib')
+ if line == b('#==>\n'):
+ txt = f.readline()
+ if not txt: err(c % 1)
+ if f.readline() != b('#<==\n'): err(c % 2)
+ break
+ if not txt: err(c % 3)
+ txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r'))
+
+ import shutil, tarfile
+ try: shutil.rmtree(dir)
+ except OSError: pass
+ try:
+ for x in ['Tools', 'extras']:
+ os.makedirs(join(dir, 'waflib', x))
+ except OSError:
+ err("Cannot unpack waf lib into %s\nMove waf into a writeable directory" % dir)
+
+ os.chdir(dir)
+ tmp = 't.bz2'
+ t = open(tmp,'wb')
+ t.write(txt)
+ t.close()
+
+ try:
+ t = tarfile.open(tmp)
+ except:
+ try:
+ os.system('bunzip2 t.bz2')
+ t = tarfile.open('t')
+ tmp = 't'
+ except:
+ os.chdir(cwd)
+ try: shutil.rmtree(dir)
+ except OSError: pass
+ err("Waf cannot be unpacked, check that bzip2 support is present")
+
+ for x in t: t.extract(x)
+ t.close()
+
+ for x in ['Tools', 'extras']:
+ os.chmod(join('waflib',x), 493)
+
+ if sys.hexversion<0x300000f:
+ sys.path = [join(dir, 'waflib')] + sys.path
+ import fixpy2
+ fixpy2.fixdir(dir)
+
+ os.unlink(tmp)
+ os.chdir(cwd)
+
+ try: dir = unicode(dir, 'mbcs')
+ except: pass
+ try:
+ from ctypes import windll
+ windll.kernel32.SetFileAttributesW(dir, 2)
+ except:
+ pass
+
+def test(dir):
+ try:
+ os.stat(join(dir, 'waflib'))
+ return os.path.abspath(dir)
+ except OSError:
+ pass
+
+def find_lib():
+ name = sys.argv[0]
+ base = os.path.dirname(os.path.abspath(name))
+
+ #devs use $WAFDIR
+ w=test(os.environ.get('WAFDIR', ''))
+ if w: return w
+
+ #waf-light
+ if name.endswith('waf-light'):
+ w = test(base)
+ if w: return w
+ err('waf-light requires waflib -> export WAFDIR=/folder')
+
+ dirname = '%s-%s-%s' % (WAF, VERSION, REVISION)
+ for i in [INSTALL,'/usr','/usr/local','/opt']:
+ w = test(i + '/lib/' + dirname)
+ if w: return w
+
+ #waf-local
+ dir = join(base, (sys.platform != 'win32' and '.' or '') + dirname)
+ w = test(dir)
+ if w: return w
+
+ #unpack
+ unpack_wafdir(dir)
+ return dir
+
+wafdir = find_lib()
+sys.path.insert(0, wafdir)
+
+if __name__ == '__main__':
+ import waflib.extras.compat15
+ from waflib import Scripting
+ Scripting.waf_entry_point(cwd, VERSION, wafdir)
+
diff --git a/waflib/Build.py b/waflib/Build.py
new file mode 100644
index 0000000..58d781b
--- /dev/null
+++ b/waflib/Build.py
@@ -0,0 +1,731 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,errno,re,shutil
+try:import cPickle
+except:import pickle as cPickle
+from waflib import Runner,TaskGen,Utils,ConfigSet,Task,Logs,Options,Context,Errors
+import waflib.Node
+CACHE_DIR='c4che'
+CACHE_SUFFIX='_cache.py'
+INSTALL=1337
+UNINSTALL=-1337
+SAVED_ATTRS='root node_deps raw_deps task_sigs'.split()
+CFG_FILES='cfg_files'
+POST_AT_ONCE=0
+POST_LAZY=1
+POST_BOTH=2
+class BuildContext(Context.Context):
+ '''executes the build'''
+ cmd='build'
+ variant=''
+ def __init__(self,**kw):
+ super(BuildContext,self).__init__(**kw)
+ self.is_install=0
+ self.top_dir=kw.get('top_dir',Context.top_dir)
+ self.run_dir=kw.get('run_dir',Context.run_dir)
+ self.post_mode=POST_AT_ONCE
+ self.out_dir=kw.get('out_dir',Context.out_dir)
+ self.cache_dir=kw.get('cache_dir',None)
+ if not self.cache_dir:
+ self.cache_dir=self.out_dir+os.sep+CACHE_DIR
+ self.all_envs={}
+ self.task_sigs={}
+ self.node_deps={}
+ self.raw_deps={}
+ self.cache_dir_contents={}
+ self.task_gen_cache_names={}
+ self.launch_dir=Context.launch_dir
+ self.jobs=Options.options.jobs
+ self.targets=Options.options.targets
+ self.keep=Options.options.keep
+ self.cache_global=Options.cache_global
+ self.nocache=Options.options.nocache
+ self.progress_bar=Options.options.progress_bar
+ self.deps_man=Utils.defaultdict(list)
+ self.current_group=0
+ self.groups=[]
+ self.group_names={}
+ def get_variant_dir(self):
+ if not self.variant:
+ return self.out_dir
+ return os.path.join(self.out_dir,self.variant)
+ variant_dir=property(get_variant_dir,None)
+ def __call__(self,*k,**kw):
+ kw['bld']=self
+ ret=TaskGen.task_gen(*k,**kw)
+ self.task_gen_cache_names={}
+ self.add_to_group(ret,group=kw.get('group',None))
+ return ret
+ def __copy__(self):
+ raise Errors.WafError('build contexts are not supposed to be copied')
+ def install_files(self,*k,**kw):
+ pass
+ def install_as(self,*k,**kw):
+ pass
+ def symlink_as(self,*k,**kw):
+ pass
+ def load_envs(self):
+ node=self.root.find_node(self.cache_dir)
+ if not node:
+ raise Errors.WafError('The project was not configured: run "waf configure" first!')
+ lst=node.ant_glob('**/*%s'%CACHE_SUFFIX,quiet=True)
+ if not lst:
+ raise Errors.WafError('The cache directory is empty: reconfigure the project')
+ for x in lst:
+ name=x.path_from(node).replace(CACHE_SUFFIX,'').replace('\\','/')
+ env=ConfigSet.ConfigSet(x.abspath())
+ self.all_envs[name]=env
+ for f in env[CFG_FILES]:
+ newnode=self.root.find_resource(f)
+ try:
+ h=Utils.h_file(newnode.abspath())
+ except(IOError,AttributeError):
+ Logs.error('cannot find %r'%f)
+ h=Utils.SIG_NIL
+ newnode.sig=h
+ def init_dirs(self):
+ if not(os.path.isabs(self.top_dir)and os.path.isabs(self.out_dir)):
+ raise Errors.WafError('The project was not configured: run "waf configure" first!')
+ self.path=self.srcnode=self.root.find_dir(self.top_dir)
+ self.bldnode=self.root.make_node(self.variant_dir)
+ self.bldnode.mkdir()
+ def execute(self):
+ self.restore()
+ if not self.all_envs:
+ self.load_envs()
+ self.execute_build()
+ def execute_build(self):
+ Logs.info("Waf: Entering directory `%s'"%self.variant_dir)
+ self.recurse([self.run_dir])
+ self.pre_build()
+ self.timer=Utils.Timer()
+ if self.progress_bar:
+ sys.stderr.write(Logs.colors.cursor_off)
+ try:
+ self.compile()
+ finally:
+ if self.progress_bar==1:
+ c=len(self.returned_tasks)or 1
+ self.to_log(self.progress_line(c,c,Logs.colors.BLUE,Logs.colors.NORMAL))
+ print('')
+ sys.stdout.flush()
+ sys.stderr.write(Logs.colors.cursor_on)
+ Logs.info("Waf: Leaving directory `%s'"%self.variant_dir)
+ self.post_build()
+ def restore(self):
+ try:
+ env=ConfigSet.ConfigSet(os.path.join(self.cache_dir,'build.config.py'))
+ except(IOError,OSError):
+ pass
+ else:
+ if env['version']<Context.HEXVERSION:
+ raise Errors.WafError('Version mismatch! reconfigure the project')
+ for t in env['tools']:
+ self.setup(**t)
+ f=None
+ try:
+ dbfn=os.path.join(self.variant_dir,Context.DBFILE)
+ try:
+ f=open(dbfn,'rb')
+ except(IOError,EOFError):
+ Logs.debug('build: could not load the build cache %s (missing)'%dbfn)
+ else:
+ try:
+ waflib.Node.pickle_lock.acquire()
+ waflib.Node.Nod3=self.node_class
+ try:
+ data=cPickle.load(f)
+ except Exception ,e:
+ Logs.debug('build: could not pickle the build cache %s: %r'%(dbfn,e))
+ else:
+ for x in SAVED_ATTRS:
+ setattr(self,x,data[x])
+ finally:
+ waflib.Node.pickle_lock.release()
+ finally:
+ if f:
+ f.close()
+ self.init_dirs()
+ def store(self):
+ data={}
+ for x in SAVED_ATTRS:
+ data[x]=getattr(self,x)
+ db=os.path.join(self.variant_dir,Context.DBFILE)
+ try:
+ waflib.Node.pickle_lock.acquire()
+ waflib.Node.Nod3=self.node_class
+ f=None
+ try:
+ f=open(db+'.tmp','wb')
+ cPickle.dump(data,f)
+ finally:
+ if f:
+ f.close()
+ finally:
+ waflib.Node.pickle_lock.release()
+ try:
+ st=os.stat(db)
+ os.unlink(db)
+ if not Utils.is_win32:
+ os.chown(db+'.tmp',st.st_uid,st.st_gid)
+ except(AttributeError,OSError):
+ pass
+ os.rename(db+'.tmp',db)
+ def compile(self):
+ Logs.debug('build: compile()')
+ self.producer=Runner.Parallel(self,self.jobs)
+ self.producer.biter=self.get_build_iterator()
+ self.returned_tasks=[]
+ try:
+ self.producer.start()
+ except KeyboardInterrupt:
+ self.store()
+ raise
+ else:
+ if self.producer.dirty:
+ self.store()
+ if self.producer.error:
+ raise Errors.BuildError(self.producer.error)
+ def setup(self,tool,tooldir=None,funs=None):
+ if isinstance(tool,list):
+ for i in tool:self.setup(i,tooldir)
+ return
+ module=Context.load_tool(tool,tooldir)
+ if hasattr(module,"setup"):module.setup(self)
+ def get_env(self):
+ try:
+ return self.all_envs[self.variant]
+ except KeyError:
+ return self.all_envs['']
+ def set_env(self,val):
+ self.all_envs[self.variant]=val
+ env=property(get_env,set_env)
+ def add_manual_dependency(self,path,value):
+ if isinstance(path,waflib.Node.Node):
+ node=path
+ elif os.path.isabs(path):
+ node=self.root.find_resource(path)
+ else:
+ node=self.path.find_resource(path)
+ self.deps_man[id(node)].append(value)
+ def launch_node(self):
+ try:
+ return self.p_ln
+ except AttributeError:
+ self.p_ln=self.root.find_dir(self.launch_dir)
+ return self.p_ln
+ def hash_env_vars(self,env,vars_lst):
+ if not env.table:
+ env=env.parent
+ if not env:
+ return Utils.SIG_NIL
+ idx=str(id(env))+str(vars_lst)
+ try:
+ cache=self.cache_env
+ except AttributeError:
+ cache=self.cache_env={}
+ else:
+ try:
+ return self.cache_env[idx]
+ except KeyError:
+ pass
+ lst=[env[a]for a in vars_lst]
+ ret=Utils.h_list(lst)
+ Logs.debug('envhash: %s %r',Utils.to_hex(ret),lst)
+ cache[idx]=ret
+ return ret
+ def get_tgen_by_name(self,name):
+ cache=self.task_gen_cache_names
+ if not cache:
+ for g in self.groups:
+ for tg in g:
+ try:
+ cache[tg.name]=tg
+ except AttributeError:
+ pass
+ try:
+ return cache[name]
+ except KeyError:
+ raise Errors.WafError('Could not find a task generator for the name %r'%name)
+ def progress_line(self,state,total,col1,col2):
+ n=len(str(total))
+ Utils.rot_idx+=1
+ ind=Utils.rot_chr[Utils.rot_idx%4]
+ pc=(100.*state)/total
+ eta=str(self.timer)
+ fs="[%%%dd/%%%dd][%%s%%2d%%%%%%s][%s]["%(n,n,ind)
+ left=fs%(state,total,col1,pc,col2)
+ right='][%s%s%s]'%(col1,eta,col2)
+ cols=Logs.get_term_cols()-len(left)-len(right)+2*len(col1)+2*len(col2)
+ if cols<7:cols=7
+ ratio=((cols*state)//total)-1
+ bar=('='*ratio+'>').ljust(cols)
+ msg=Utils.indicator%(left,bar,right)
+ return msg
+ def declare_chain(self,*k,**kw):
+ return TaskGen.declare_chain(*k,**kw)
+ def pre_build(self):
+ for m in getattr(self,'pre_funs',[]):
+ m(self)
+ def post_build(self):
+ for m in getattr(self,'post_funs',[]):
+ m(self)
+ def add_pre_fun(self,meth):
+ try:
+ self.pre_funs.append(meth)
+ except AttributeError:
+ self.pre_funs=[meth]
+ def add_post_fun(self,meth):
+ try:
+ self.post_funs.append(meth)
+ except AttributeError:
+ self.post_funs=[meth]
+ def get_group(self,x):
+ if not self.groups:
+ self.add_group()
+ if x is None:
+ return self.groups[self.current_group]
+ if x in self.group_names:
+ return self.group_names[x]
+ return self.groups[x]
+ def add_to_group(self,tgen,group=None):
+ assert(isinstance(tgen,TaskGen.task_gen)or isinstance(tgen,Task.TaskBase))
+ tgen.bld=self
+ self.get_group(group).append(tgen)
+ def get_group_name(self,g):
+ if not isinstance(g,list):
+ g=self.groups[g]
+ for x in self.group_names:
+ if id(self.group_names[x])==id(g):
+ return x
+ return''
+ def get_group_idx(self,tg):
+ se=id(tg)
+ for i in range(len(self.groups)):
+ for t in self.groups[i]:
+ if id(t)==se:
+ return i
+ return None
+ def add_group(self,name=None,move=True):
+ if name and name in self.group_names:
+ Logs.error('add_group: name %s already present'%name)
+ g=[]
+ self.group_names[name]=g
+ self.groups.append(g)
+ if move:
+ self.current_group=len(self.groups)-1
+ def set_group(self,idx):
+ if isinstance(idx,str):
+ g=self.group_names[idx]
+ for i in range(len(self.groups)):
+ if id(g)==id(self.groups[i]):
+ self.current_group=i
+ else:
+ self.current_group=idx
+ def total(self):
+ total=0
+ for group in self.groups:
+ for tg in group:
+ try:
+ total+=len(tg.tasks)
+ except AttributeError:
+ total+=1
+ return total
+ def get_targets(self):
+ to_post=[]
+ min_grp=0
+ for name in self.targets.split(','):
+ tg=self.get_tgen_by_name(name)
+ if not tg:
+ raise Errors.WafError('target %r does not exist'%name)
+ m=self.get_group_idx(tg)
+ if m>min_grp:
+ min_grp=m
+ to_post=[tg]
+ elif m==min_grp:
+ to_post.append(tg)
+ return(min_grp,to_post)
+ def post_group(self):
+ if self.targets=='*':
+ for tg in self.groups[self.cur]:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ f()
+ elif self.targets:
+ if self.cur<self._min_grp:
+ for tg in self.groups[self.cur]:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ f()
+ else:
+ for tg in self._exact_tg:
+ tg.post()
+ else:
+ ln=self.launch_node()
+ for tg in self.groups[self.cur]:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ if tg.path.is_child_of(ln):
+ f()
+ def get_tasks_group(self,idx):
+ tasks=[]
+ for tg in self.groups[idx]:
+ if isinstance(tg,Task.TaskBase):
+ tasks.append(tg)
+ else:
+ tasks.extend(tg.tasks)
+ return tasks
+ def get_build_iterator(self):
+ self.cur=0
+ if self.targets and self.targets!='*':
+ (self._min_grp,self._exact_tg)=self.get_targets()
+ global lazy_post
+ if self.post_mode!=POST_LAZY:
+ while self.cur<len(self.groups):
+ self.post_group()
+ self.cur+=1
+ self.cur=0
+ while self.cur<len(self.groups):
+ if self.post_mode!=POST_AT_ONCE:
+ self.post_group()
+ tasks=self.get_tasks_group(self.cur)
+ Task.set_file_constraints(tasks)
+ Task.set_precedence_constraints(tasks)
+ self.cur_tasks=tasks
+ self.cur+=1
+ if not tasks:
+ continue
+ yield tasks
+ while 1:
+ yield[]
+class inst(Task.Task):
+ color='CYAN'
+ def post(self):
+ buf=[]
+ for x in self.source:
+ if isinstance(x,waflib.Node.Node):
+ y=x
+ else:
+ y=self.path.find_resource(x)
+ if not y:
+ if Logs.verbose:
+ Logs.warn('Could not find %s immediately (may cause broken builds)'%x)
+ idx=self.generator.bld.get_group_idx(self)
+ for tg in self.generator.bld.groups[idx]:
+ if not isinstance(tg,inst)and id(tg)!=id(self):
+ tg.post()
+ y=self.path.find_resource(x)
+ if y:
+ break
+ else:
+ raise Errors.WafError('could not find %r in %r'%(x,self.path))
+ buf.append(y)
+ self.inputs=buf
+ def runnable_status(self):
+ ret=super(inst,self).runnable_status()
+ if ret==Task.SKIP_ME:
+ return Task.RUN_ME
+ return ret
+ def __str__(self):
+ return''
+ def run(self):
+ return self.generator.exec_task()
+ def get_install_path(self,destdir=True):
+ dest=Utils.subst_vars(self.dest,self.env)
+ dest=dest.replace('/',os.sep)
+ if destdir and Options.options.destdir:
+ dest=os.path.join(Options.options.destdir,os.path.splitdrive(dest)[1].lstrip(os.sep))
+ return dest
+ def exec_install_files(self):
+ destpath=self.get_install_path()
+ if not destpath:
+ raise Errors.WafError('unknown installation path %r'%self.generator)
+ for x,y in zip(self.source,self.inputs):
+ if self.relative_trick:
+ destfile=os.path.join(destpath,y.path_from(self.path))
+ Utils.check_dir(os.path.dirname(destfile))
+ else:
+ destfile=os.path.join(destpath,y.name)
+ self.generator.bld.do_install(y.abspath(),destfile,self.chmod)
+ def exec_install_as(self):
+ destfile=self.get_install_path()
+ self.generator.bld.do_install(self.inputs[0].abspath(),destfile,self.chmod)
+ def exec_symlink_as(self):
+ destfile=self.get_install_path()
+ self.generator.bld.do_link(self.link,destfile)
+class InstallContext(BuildContext):
+ '''installs the targets on the system'''
+ cmd='install'
+ def __init__(self,**kw):
+ super(InstallContext,self).__init__(**kw)
+ self.uninstall=[]
+ self.is_install=INSTALL
+ def do_install(self,src,tgt,chmod=Utils.O644):
+ d,_=os.path.split(tgt)
+ if not d:
+ raise Errors.WafError('Invalid installation given %r->%r'%(src,tgt))
+ Utils.check_dir(d)
+ srclbl=src.replace(self.srcnode.abspath()+os.sep,'')
+ if not Options.options.force:
+ try:
+ st1=os.stat(tgt)
+ st2=os.stat(src)
+ except OSError:
+ pass
+ else:
+ if st1.st_mtime+2>=st2.st_mtime and st1.st_size==st2.st_size:
+ if not self.progress_bar:
+ Logs.info('- install %s (from %s)'%(tgt,srclbl))
+ return False
+ if not self.progress_bar:
+ Logs.info('+ install %s (from %s)'%(tgt,srclbl))
+ try:
+ os.remove(tgt)
+ except OSError:
+ pass
+ try:
+ shutil.copy2(src,tgt)
+ os.chmod(tgt,chmod)
+ except IOError:
+ try:
+ os.stat(src)
+ except(OSError,IOError):
+ Logs.error('File %r does not exist'%src)
+ raise Errors.WafError('Could not install the file %r'%tgt)
+ def do_link(self,src,tgt):
+ d,_=os.path.split(tgt)
+ Utils.check_dir(d)
+ link=False
+ if not os.path.islink(tgt):
+ link=True
+ elif os.readlink(tgt)!=src:
+ link=True
+ if link:
+ try:os.remove(tgt)
+ except OSError:pass
+ if not self.progress_bar:
+ Logs.info('+ symlink %s (to %s)'%(tgt,src))
+ os.symlink(src,tgt)
+ else:
+ if not self.progress_bar:
+ Logs.info('- symlink %s (to %s)'%(tgt,src))
+ def run_task_now(self,tsk,postpone):
+ tsk.post()
+ if not postpone:
+ if tsk.runnable_status()==Task.ASK_LATER:
+ raise self.WafError('cannot post the task %r'%tsk)
+ tsk.run()
+ def install_files(self,dest,files,env=None,chmod=Utils.O644,relative_trick=False,cwd=None,add=True,postpone=True):
+ tsk=inst(env=env or self.env)
+ tsk.bld=self
+ tsk.path=cwd or self.path
+ tsk.chmod=chmod
+ if isinstance(files,waflib.Node.Node):
+ tsk.source=[files]
+ else:
+ tsk.source=Utils.to_list(files)
+ tsk.dest=dest
+ tsk.exec_task=tsk.exec_install_files
+ tsk.relative_trick=relative_trick
+ if add:self.add_to_group(tsk)
+ self.run_task_now(tsk,postpone)
+ return tsk
+ def install_as(self,dest,srcfile,env=None,chmod=Utils.O644,cwd=None,add=True,postpone=True):
+ tsk=inst(env=env or self.env)
+ tsk.bld=self
+ tsk.path=cwd or self.path
+ tsk.chmod=chmod
+ tsk.source=[srcfile]
+ tsk.dest=dest
+ tsk.exec_task=tsk.exec_install_as
+ if add:self.add_to_group(tsk)
+ self.run_task_now(tsk,postpone)
+ return tsk
+ def symlink_as(self,dest,src,env=None,cwd=None,add=True,postpone=True):
+ if Utils.is_win32:
+ return
+ tsk=inst(env=env or self.env)
+ tsk.bld=self
+ tsk.dest=dest
+ tsk.path=cwd or self.path
+ tsk.source=[]
+ tsk.link=src
+ tsk.exec_task=tsk.exec_symlink_as
+ if add:self.add_to_group(tsk)
+ self.run_task_now(tsk,postpone)
+ return tsk
+class UninstallContext(InstallContext):
+ '''removes the targets installed'''
+ cmd='uninstall'
+ def __init__(self,**kw):
+ super(UninstallContext,self).__init__(**kw)
+ self.is_install=UNINSTALL
+ def do_install(self,src,tgt,chmod=Utils.O644):
+ if not self.progress_bar:
+ Logs.info('- remove %s'%tgt)
+ self.uninstall.append(tgt)
+ try:
+ os.remove(tgt)
+ except OSError ,e:
+ if e.errno!=errno.ENOENT:
+ if not getattr(self,'uninstall_error',None):
+ self.uninstall_error=True
+ Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)')
+ if Logs.verbose>1:
+ Logs.warn('could not remove %s (error code %r)'%(e.filename,e.errno))
+ while tgt:
+ tgt=os.path.dirname(tgt)
+ try:
+ os.rmdir(tgt)
+ except OSError:
+ break
+ def do_link(self,src,tgt):
+ try:
+ if not self.progress_bar:
+ Logs.info('- unlink %s'%tgt)
+ os.remove(tgt)
+ except OSError:
+ pass
+ while tgt:
+ tgt=os.path.dirname(tgt)
+ try:
+ os.rmdir(tgt)
+ except OSError:
+ break
+ def execute(self):
+ try:
+ def runnable_status(self):
+ return Task.SKIP_ME
+ setattr(Task.Task,'runnable_status_back',Task.Task.runnable_status)
+ setattr(Task.Task,'runnable_status',runnable_status)
+ super(UninstallContext,self).execute()
+ finally:
+ setattr(Task.Task,'runnable_status',Task.Task.runnable_status_back)
+class CleanContext(BuildContext):
+ '''cleans the project'''
+ cmd='clean'
+ def execute(self):
+ self.restore()
+ if not self.all_envs:
+ self.load_envs()
+ self.recurse([self.run_dir])
+ try:
+ self.clean()
+ finally:
+ self.store()
+ def clean(self):
+ Logs.debug('build: clean called')
+ if self.bldnode!=self.srcnode:
+ lst=[self.root.find_or_declare(f)for f in self.env[CFG_FILES]]
+ for n in self.bldnode.ant_glob('**/*',excl='lock* *conf_check_*/** config.log c4che/*',quiet=True):
+ if n in lst:
+ continue
+ n.delete()
+ self.root.children={}
+ for v in'node_deps task_sigs raw_deps'.split():
+ setattr(self,v,{})
+class ListContext(BuildContext):
+ '''lists the targets to execute'''
+ cmd='list'
+ def execute(self):
+ self.restore()
+ if not self.all_envs:
+ self.load_envs()
+ self.recurse([self.run_dir])
+ self.pre_build()
+ self.timer=Utils.Timer()
+ for g in self.groups:
+ for tg in g:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ f()
+ try:
+ self.get_tgen_by_name('')
+ except:
+ pass
+ lst=list(self.task_gen_cache_names.keys())
+ lst.sort()
+ for k in lst:
+ Logs.pprint('GREEN',k)
+class StepContext(BuildContext):
+ '''executes tasks in a step-by-step fashion, for debugging'''
+ cmd='step'
+ def __init__(self,**kw):
+ super(StepContext,self).__init__(**kw)
+ self.files=Options.options.files
+ def compile(self):
+ if not self.files:
+ Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"')
+ BuildContext.compile(self)
+ return
+ for g in self.groups:
+ for tg in g:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ f()
+ for pat in self.files.split(','):
+ matcher=self.get_matcher(pat)
+ for tg in g:
+ if isinstance(tg,Task.TaskBase):
+ lst=[tg]
+ else:
+ lst=tg.tasks
+ for tsk in lst:
+ do_exec=False
+ for node in getattr(tsk,'inputs',[]):
+ if matcher(node,output=False):
+ do_exec=True
+ break
+ for node in getattr(tsk,'outputs',[]):
+ if matcher(node,output=True):
+ do_exec=True
+ break
+ if do_exec:
+ ret=tsk.run()
+ Logs.info('%s -> exit %r'%(str(tsk),ret))
+ def get_matcher(self,pat):
+ inn=True
+ out=True
+ if pat.startswith('in:'):
+ out=False
+ pat=pat.replace('in:','')
+ elif pat.startswith('out:'):
+ inn=False
+ pat=pat.replace('out:','')
+ anode=self.root.find_node(pat)
+ pattern=None
+ if not anode:
+ if not pat.startswith('^'):
+ pat='^.+?%s'%pat
+ if not pat.endswith('$'):
+ pat='%s$'%pat
+ pattern=re.compile(pat)
+ def match(node,output):
+ if output==True and not out:
+ return False
+ if output==False and not inn:
+ return False
+ if anode:
+ return anode==node
+ else:
+ return pattern.match(node.abspath())
+ return match
+BuildContext.store=Utils.nogc(BuildContext.store)
+BuildContext.restore=Utils.nogc(BuildContext.restore)
diff --git a/waflib/ConfigSet.py b/waflib/ConfigSet.py
new file mode 100644
index 0000000..fa55135
--- /dev/null
+++ b/waflib/ConfigSet.py
@@ -0,0 +1,151 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+import copy,re,os
+from waflib import Logs,Utils
+re_imp=re.compile('^(#)*?([^#=]*?)\ =\ (.*?)$',re.M)
+class ConfigSet(object):
+ __slots__=('table','parent')
+ def __init__(self,filename=None):
+ self.table={}
+ if filename:
+ self.load(filename)
+ def __contains__(self,key):
+ if key in self.table:return True
+ try:return self.parent.__contains__(key)
+ except AttributeError:return False
+ def keys(self):
+ keys=set()
+ cur=self
+ while cur:
+ keys.update(cur.table.keys())
+ cur=getattr(cur,'parent',None)
+ keys=list(keys)
+ keys.sort()
+ return keys
+ def __str__(self):
+ return"\n".join(["%r %r"%(x,self.__getitem__(x))for x in self.keys()])
+ def __getitem__(self,key):
+ try:
+ while 1:
+ x=self.table.get(key,None)
+ if not x is None:
+ return x
+ self=self.parent
+ except AttributeError:
+ return[]
+ def __setitem__(self,key,value):
+ self.table[key]=value
+ def __delitem__(self,key):
+ self[key]=[]
+ def __getattr__(self,name):
+ if name in self.__slots__:
+ return object.__getattr__(self,name)
+ else:
+ return self[name]
+ def __setattr__(self,name,value):
+ if name in self.__slots__:
+ object.__setattr__(self,name,value)
+ else:
+ self[name]=value
+ def __delattr__(self,name):
+ if name in self.__slots__:
+ object.__delattr__(self,name)
+ else:
+ del self[name]
+ def derive(self):
+ newenv=ConfigSet()
+ newenv.parent=self
+ return newenv
+ def detach(self):
+ tbl=self.get_merged_dict()
+ try:
+ delattr(self,'parent')
+ except AttributeError:
+ pass
+ else:
+ keys=tbl.keys()
+ for x in keys:
+ tbl[x]=copy.deepcopy(tbl[x])
+ self.table=tbl
+ def get_flat(self,key):
+ s=self[key]
+ if isinstance(s,str):return s
+ return' '.join(s)
+ def _get_list_value_for_modification(self,key):
+ try:
+ value=self.table[key]
+ except KeyError:
+ try:value=self.parent[key]
+ except AttributeError:value=[]
+ if isinstance(value,list):
+ value=value[:]
+ else:
+ value=[value]
+ else:
+ if not isinstance(value,list):
+ value=[value]
+ self.table[key]=value
+ return value
+ def append_value(self,var,val):
+ current_value=self._get_list_value_for_modification(var)
+ if isinstance(val,str):
+ val=[val]
+ current_value.extend(val)
+ def prepend_value(self,var,val):
+ if isinstance(val,str):
+ val=[val]
+ self.table[var]=val+self._get_list_value_for_modification(var)
+ def append_unique(self,var,val):
+ if isinstance(val,str):
+ val=[val]
+ current_value=self._get_list_value_for_modification(var)
+ for x in val:
+ if x not in current_value:
+ current_value.append(x)
+ def get_merged_dict(self):
+ table_list=[]
+ env=self
+ while 1:
+ table_list.insert(0,env.table)
+ try:env=env.parent
+ except AttributeError:break
+ merged_table={}
+ for table in table_list:
+ merged_table.update(table)
+ return merged_table
+ def store(self,filename):
+ try:
+ os.makedirs(os.path.split(filename)[0])
+ except OSError:
+ pass
+ f=None
+ try:
+ f=open(filename,'w')
+ merged_table=self.get_merged_dict()
+ keys=list(merged_table.keys())
+ keys.sort()
+ for k in keys:
+ if k!='undo_stack':
+ f.write('%s = %r\n'%(k,merged_table[k]))
+ finally:
+ if f:
+ f.close()
+ def load(self,filename):
+ tbl=self.table
+ code=Utils.readf(filename)
+ for m in re_imp.finditer(code):
+ g=m.group
+ tbl[g(2)]=eval(g(3))
+ Logs.debug('env: %s'%str(self.table))
+ def update(self,d):
+ for k,v in d.items():
+ self[k]=v
+ def stash(self):
+ self.undo_stack=self.undo_stack+[self.table]
+ self.table=self.table.copy()
+ def revert(self):
+ self.table=self.undo_stack.pop(-1)
diff --git a/waflib/Configure.py b/waflib/Configure.py
new file mode 100644
index 0000000..bd004c6
--- /dev/null
+++ b/waflib/Configure.py
@@ -0,0 +1,315 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,shlex,sys,time
+from waflib import ConfigSet,Utils,Options,Logs,Context,Build,Errors
+try:
+ from urllib import request
+except:
+ from urllib import urlopen
+else:
+ urlopen=request.urlopen
+BREAK='break'
+CONTINUE='continue'
+WAF_CONFIG_LOG='config.log'
+autoconfig=False
+conf_template='''# project %(app)s configured on %(now)s by
+# waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s)
+# using %(args)s
+#'''
+def download_check(node):
+ pass
+def download_tool(tool,force=False,ctx=None):
+ for x in Utils.to_list(Context.remote_repo):
+ for sub in Utils.to_list(Context.remote_locs):
+ url='/'.join((x,sub,tool+'.py'))
+ try:
+ web=urlopen(url)
+ try:
+ if web.getcode()!=200:
+ continue
+ except AttributeError:
+ pass
+ except Exception:
+ continue
+ else:
+ tmp=ctx.root.make_node(os.sep.join((Context.waf_dir,'waflib','extras',tool+'.py')))
+ tmp.write(web.read())
+ Logs.warn('Downloaded %s from %s'%(tool,url))
+ download_check(tmp)
+ try:
+ module=Context.load_tool(tool)
+ except:
+ Logs.warn('The tool %s from %s is unusable'%(tool,url))
+ try:
+ tmp.delete()
+ except:
+ pass
+ continue
+ return module
+ raise Errors.WafError('Could not load the Waf tool')
+class ConfigurationContext(Context.Context):
+ '''configures the project'''
+ cmd='configure'
+ error_handlers=[]
+ def __init__(self,**kw):
+ super(ConfigurationContext,self).__init__(**kw)
+ self.environ=dict(os.environ)
+ self.all_envs={}
+ self.top_dir=None
+ self.out_dir=None
+ self.tools=[]
+ self.hash=0
+ self.files=[]
+ self.tool_cache=[]
+ self.setenv('')
+ def setenv(self,name,env=None):
+ if name not in self.all_envs or env:
+ if not env:
+ env=ConfigSet.ConfigSet()
+ self.prepare_env(env)
+ else:
+ env=env.derive()
+ self.all_envs[name]=env
+ self.variant=name
+ def get_env(self):
+ return self.all_envs[self.variant]
+ def set_env(self,val):
+ self.all_envs[self.variant]=val
+ env=property(get_env,set_env)
+ def init_dirs(self):
+ top=self.top_dir
+ if not top:
+ top=Options.options.top
+ if not top:
+ top=getattr(Context.g_module,Context.TOP,None)
+ if not top:
+ top=self.path.abspath()
+ top=os.path.abspath(top)
+ self.srcnode=(os.path.isabs(top)and self.root or self.path).find_dir(top)
+ assert(self.srcnode)
+ out=self.out_dir
+ if not out:
+ out=Options.options.out
+ if not out:
+ out=getattr(Context.g_module,Context.OUT,None)
+ if not out:
+ out=Options.lockfile.replace('.lock-waf_%s_'%sys.platform,'').replace('.lock-waf','')
+ self.bldnode=(os.path.isabs(out)and self.root or self.path).make_node(out)
+ self.bldnode.mkdir()
+ if not os.path.isdir(self.bldnode.abspath()):
+ conf.fatal('could not create the build directory %s'%self.bldnode.abspath())
+ def execute(self):
+ self.init_dirs()
+ self.cachedir=self.bldnode.make_node(Build.CACHE_DIR)
+ self.cachedir.mkdir()
+ path=os.path.join(self.bldnode.abspath(),WAF_CONFIG_LOG)
+ self.logger=Logs.make_logger(path,'cfg')
+ app=getattr(Context.g_module,'APPNAME','')
+ if app:
+ ver=getattr(Context.g_module,'VERSION','')
+ if ver:
+ app="%s (%s)"%(app,ver)
+ now=time.ctime()
+ pyver=sys.hexversion
+ systype=sys.platform
+ args=" ".join(sys.argv)
+ wafver=Context.WAFVERSION
+ abi=Context.ABI
+ self.to_log(conf_template%vars())
+ self.msg('Setting top to',self.srcnode.abspath())
+ self.msg('Setting out to',self.bldnode.abspath())
+ if id(self.srcnode)==id(self.bldnode):
+ Logs.warn('Setting top == out (remember to use "update_outputs")')
+ elif id(self.path)!=id(self.srcnode):
+ if self.srcnode.is_child_of(self.path):
+ Logs.warn('Are you certain that you do not want to set top="." ?')
+ super(ConfigurationContext,self).execute()
+ self.store()
+ Context.top_dir=self.srcnode.abspath()
+ Context.out_dir=self.bldnode.abspath()
+ env=ConfigSet.ConfigSet()
+ env['argv']=sys.argv
+ env['options']=Options.options.__dict__
+ env.run_dir=Context.run_dir
+ env.top_dir=Context.top_dir
+ env.out_dir=Context.out_dir
+ env['hash']=self.hash
+ env['files']=self.files
+ env['environ']=dict(self.environ)
+ if not self.env.NO_LOCK_IN_RUN:
+ env.store(Context.run_dir+os.sep+Options.lockfile)
+ if not self.env.NO_LOCK_IN_TOP:
+ env.store(Context.top_dir+os.sep+Options.lockfile)
+ if not self.env.NO_LOCK_IN_OUT:
+ env.store(Context.out_dir+os.sep+Options.lockfile)
+ def prepare_env(self,env):
+ if not env.PREFIX:
+ env.PREFIX=os.path.abspath(os.path.expanduser(Options.options.prefix))
+ if not env.BINDIR:
+ env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env)
+ if not env.LIBDIR:
+ env.LIBDIR=Utils.subst_vars('${PREFIX}/lib',env)
+ def store(self):
+ n=self.cachedir.make_node('build.config.py')
+ n.write('version = 0x%x\ntools = %r\n'%(Context.HEXVERSION,self.tools))
+ if not self.all_envs:
+ self.fatal('nothing to store in the configuration context!')
+ for key in self.all_envs:
+ tmpenv=self.all_envs[key]
+ tmpenv.store(os.path.join(self.cachedir.abspath(),key+Build.CACHE_SUFFIX))
+ def load(self,input,tooldir=None,funs=None,download=True):
+ tools=Utils.to_list(input)
+ if tooldir:tooldir=Utils.to_list(tooldir)
+ for tool in tools:
+ mag=(tool,id(self.env),funs)
+ if mag in self.tool_cache:
+ self.to_log('(tool %s is already loaded, skipping)'%tool)
+ continue
+ self.tool_cache.append(mag)
+ module=None
+ try:
+ module=Context.load_tool(tool,tooldir)
+ except ImportError ,e:
+ if Options.options.download:
+ module=download_tool(tool,ctx=self)
+ if not module:
+ self.fatal('Could not load the Waf tool %r or download a suitable replacement from the repository (sys.path %r)\n%s'%(tool,sys.path,e))
+ else:
+ self.fatal('Could not load the Waf tool %r from %r (try the --download option?):\n%s'%(tool,sys.path,e))
+ except Exception ,e:
+ self.to_log('imp %r (%r & %r)'%(tool,tooldir,funs))
+ self.to_log(Utils.ex_stack())
+ raise
+ if funs is not None:
+ self.eval_rules(funs)
+ else:
+ func=getattr(module,'configure',None)
+ if func:
+ if type(func)is type(Utils.readf):func(self)
+ else:self.eval_rules(func)
+ self.tools.append({'tool':tool,'tooldir':tooldir,'funs':funs})
+ def post_recurse(self,node):
+ super(ConfigurationContext,self).post_recurse(node)
+ self.hash=hash((self.hash,node.read('rb')))
+ self.files.append(node.abspath())
+ def eval_rules(self,rules):
+ self.rules=Utils.to_list(rules)
+ for x in self.rules:
+ f=getattr(self,x)
+ if not f:self.fatal("No such method '%s'."%x)
+ try:
+ f()
+ except Exception ,e:
+ ret=self.err_handler(x,e)
+ if ret==BREAK:
+ break
+ elif ret==CONTINUE:
+ continue
+ else:
+ raise
+ def err_handler(self,fun,error):
+ pass
+def conf(f):
+ def fun(*k,**kw):
+ mandatory=True
+ if'mandatory'in kw:
+ mandatory=kw['mandatory']
+ del kw['mandatory']
+ try:
+ return f(*k,**kw)
+ except Errors.ConfigurationError ,e:
+ if mandatory:
+ raise e
+ setattr(ConfigurationContext,f.__name__,fun)
+ setattr(Build.BuildContext,f.__name__,fun)
+ return f
+def add_os_flags(self,var,dest=None):
+ try:self.env.append_value(dest or var,shlex.split(self.environ[var]))
+ except KeyError:pass
+def cmd_to_list(self,cmd):
+ if isinstance(cmd,str)and cmd.find(' '):
+ try:
+ os.stat(cmd)
+ except OSError:
+ return shlex.split(cmd)
+ else:
+ return[cmd]
+ return cmd
+def check_waf_version(self,mini='1.6.0',maxi='1.7.0'):
+ self.start_msg('Checking for waf version in %s-%s'%(str(mini),str(maxi)))
+ ver=Context.HEXVERSION
+ if Utils.num2ver(mini)>ver:
+ self.fatal('waf version should be at least %r (%r found)'%(Utils.num2ver(mini),ver))
+ if Utils.num2ver(maxi)<ver:
+ self.fatal('waf version should be at most %r (%r found)'%(Utils.num2ver(maxi),ver))
+ self.end_msg('ok')
+def find_file(self,filename,path_list=[]):
+ for n in Utils.to_list(filename):
+ for d in Utils.to_list(path_list):
+ p=os.path.join(d,n)
+ if os.path.exists(p):
+ return p
+ self.fatal('Could not find %r'%filename)
+def find_program(self,filename,**kw):
+ exts=kw.get('exts',Utils.is_win32 and'.exe,.com,.bat,.cmd'or',.sh,.pl,.py')
+ environ=kw.get('environ',os.environ)
+ ret=''
+ filename=Utils.to_list(filename)
+ var=kw.get('var','')
+ if not var:
+ var=filename[0].upper()
+ if self.env[var]:
+ ret=self.env[var]
+ elif var in environ:
+ ret=environ[var]
+ path_list=kw.get('path_list','')
+ if not ret:
+ if path_list:
+ path_list=Utils.to_list(path_list)
+ else:
+ path_list=environ.get('PATH','').split(os.pathsep)
+ if not isinstance(filename,list):
+ filename=[filename]
+ for a in exts.split(','):
+ if ret:
+ break
+ for b in filename:
+ if ret:
+ break
+ for c in path_list:
+ if ret:
+ break
+ x=os.path.expanduser(os.path.join(c,b+a))
+ if os.path.isfile(x):
+ ret=x
+ if not ret and Utils.winreg:
+ ret=Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER,filename)
+ if not ret and Utils.winreg:
+ ret=Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE,filename)
+ self.msg('Checking for program '+','.join(filename),ret or False)
+ self.to_log('find program=%r paths=%r var=%r -> %r'%(filename,path_list,var,ret))
+ if not ret:
+ self.fatal(kw.get('errmsg','')or'Could not find the program %s'%','.join(filename))
+ if var:
+ self.env[var]=ret
+ return ret
+def find_perl_program(self,filename,path_list=[],var=None,environ=None,exts=''):
+ try:
+ app=self.find_program(filename,path_list=path_list,var=var,environ=environ,exts=exts)
+ except:
+ self.find_program('perl',var='PERL')
+ app=self.find_file(filename,os.environ['PATH'].split(os.pathsep))
+ if not app:
+ raise
+ if var:
+ self.env[var]=Utils.to_list(self.env['PERL'])+[app]
+ self.msg('Checking for %r'%filename,app)
+
+conf(add_os_flags)
+conf(cmd_to_list)
+conf(check_waf_version)
+conf(find_file)
+conf(find_program)
+conf(find_perl_program) \ No newline at end of file
diff --git a/waflib/Context.py b/waflib/Context.py
new file mode 100644
index 0000000..a16af30
--- /dev/null
+++ b/waflib/Context.py
@@ -0,0 +1,299 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,imp,sys
+from waflib import Utils,Errors,Logs
+import waflib.Node
+HEXVERSION=0x1060b00
+WAFVERSION="1.6.11"
+WAFREVISION="a7e69d6b81b04729804754c4d5214da063779a65"
+ABI=98
+DBFILE='.wafpickle-%d'%ABI
+APPNAME='APPNAME'
+VERSION='VERSION'
+TOP='top'
+OUT='out'
+WSCRIPT_FILE='wscript'
+launch_dir=''
+run_dir=''
+top_dir=''
+out_dir=''
+waf_dir=''
+local_repo=''
+remote_repo='http://waf.googlecode.com/git/'
+remote_locs=['waflib/extras','waflib/Tools']
+g_module=None
+STDOUT=1
+STDERR=-1
+BOTH=0
+classes=[]
+def create_context(cmd_name,*k,**kw):
+ global classes
+ for x in classes:
+ if x.cmd==cmd_name:
+ return x(*k,**kw)
+ ctx=Context(*k,**kw)
+ ctx.fun=cmd_name
+ return ctx
+class store_context(type):
+ def __init__(cls,name,bases,dict):
+ super(store_context,cls).__init__(name,bases,dict)
+ name=cls.__name__
+ if name=='ctx'or name=='Context':
+ return
+ try:
+ cls.cmd
+ except AttributeError:
+ raise Errors.WafError('Missing command for the context class %r (cmd)'%name)
+ if not getattr(cls,'fun',None):
+ cls.fun=cls.cmd
+ global classes
+ classes.insert(0,cls)
+ctx=store_context('ctx',(object,),{})
+class Context(ctx):
+ errors=Errors
+ tools={}
+ def __init__(self,**kw):
+ try:
+ rd=kw['run_dir']
+ except KeyError:
+ global run_dir
+ rd=run_dir
+ class node_class(waflib.Node.Node):
+ pass
+ self.node_class=node_class
+ self.node_class.__module__="waflib.Node"
+ self.node_class.__name__="Nod3"
+ self.node_class.ctx=self
+ self.root=self.node_class('',None)
+ self.cur_script=None
+ self.path=self.root.find_dir(rd)
+ self.stack_path=[]
+ self.exec_dict={'ctx':self,'conf':self,'bld':self,'opt':self}
+ self.logger=None
+ def __hash__(self):
+ return id(self)
+ def load(self,tool_list,*k,**kw):
+ tools=Utils.to_list(tool_list)
+ path=Utils.to_list(kw.get('tooldir',''))
+ for t in tools:
+ module=load_tool(t,path)
+ fun=getattr(module,kw.get('name',self.fun),None)
+ if fun:
+ fun(self)
+ def execute(self):
+ global g_module
+ self.recurse([os.path.dirname(g_module.root_path)])
+ def pre_recurse(self,node):
+ self.stack_path.append(self.cur_script)
+ self.cur_script=node
+ self.path=node.parent
+ def post_recurse(self,node):
+ self.cur_script=self.stack_path.pop()
+ if self.cur_script:
+ self.path=self.cur_script.parent
+ def recurse(self,dirs,name=None,mandatory=True,once=True):
+ try:
+ cache=self.recurse_cache
+ except:
+ cache=self.recurse_cache={}
+ for d in Utils.to_list(dirs):
+ if not os.path.isabs(d):
+ d=os.path.join(self.path.abspath(),d)
+ WSCRIPT=os.path.join(d,WSCRIPT_FILE)
+ WSCRIPT_FUN=WSCRIPT+'_'+(name or self.fun)
+ node=self.root.find_node(WSCRIPT_FUN)
+ if node and(not once or node not in cache):
+ cache[node]=True
+ self.pre_recurse(node)
+ try:
+ function_code=node.read('rU')
+ exec(compile(function_code,node.abspath(),'exec'),self.exec_dict)
+ finally:
+ self.post_recurse(node)
+ elif not node:
+ node=self.root.find_node(WSCRIPT)
+ tup=(node,name or self.fun)
+ if node and(not once or tup not in cache):
+ cache[tup]=True
+ self.pre_recurse(node)
+ try:
+ wscript_module=load_module(node.abspath())
+ user_function=getattr(wscript_module,(name or self.fun),None)
+ if not user_function:
+ if not mandatory:
+ continue
+ raise Errors.WafError('No function %s defined in %s'%(name or self.fun,node.abspath()))
+ user_function(self)
+ finally:
+ self.post_recurse(node)
+ elif not node:
+ if not mandatory:
+ continue
+ raise Errors.WafError('No wscript file in directory %s'%d)
+ def exec_command(self,cmd,**kw):
+ subprocess=Utils.subprocess
+ kw['shell']=isinstance(cmd,str)
+ Logs.debug('runner: %r'%cmd)
+ Logs.debug('runner_env: kw=%s'%kw)
+ try:
+ if self.logger:
+ self.logger.info(cmd)
+ kw['stdout']=kw['stderr']=subprocess.PIPE
+ p=subprocess.Popen(cmd,**kw)
+ (out,err)=p.communicate()
+ if out:
+ self.logger.debug('out: %s'%out.decode(sys.stdout.encoding or'iso8859-1'))
+ if err:
+ self.logger.error('err: %s'%err.decode(sys.stdout.encoding or'iso8859-1'))
+ return p.returncode
+ else:
+ p=subprocess.Popen(cmd,**kw)
+ return p.wait()
+ except OSError:
+ return-1
+ def cmd_and_log(self,cmd,**kw):
+ subprocess=Utils.subprocess
+ kw['shell']=isinstance(cmd,str)
+ Logs.debug('runner: %r'%cmd)
+ if'quiet'in kw:
+ quiet=kw['quiet']
+ del kw['quiet']
+ else:
+ quiet=None
+ if'output'in kw:
+ to_ret=kw['output']
+ del kw['output']
+ else:
+ to_ret=STDOUT
+ kw['stdout']=kw['stderr']=subprocess.PIPE
+ if quiet is None:
+ self.to_log(cmd)
+ try:
+ p=subprocess.Popen(cmd,**kw)
+ (out,err)=p.communicate()
+ except Exception ,e:
+ raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
+ if not isinstance(out,str):
+ out=out.decode(sys.stdout.encoding or'iso8859-1')
+ if not isinstance(err,str):
+ err=err.decode(sys.stdout.encoding or'iso8859-1')
+ if out and quiet!=STDOUT and quiet!=BOTH:
+ self.to_log('out: %s'%out)
+ if err and quiet!=STDERR and quiet!=BOTH:
+ self.to_log('err: %s'%err)
+ if p.returncode:
+ e=Errors.WafError('Command %r returned %r'%(cmd,p.returncode))
+ e.returncode=p.returncode
+ e.stderr=err
+ e.stdout=out
+ raise e
+ if to_ret==BOTH:
+ return(out,err)
+ elif to_ret==STDERR:
+ return err
+ return out
+ def fatal(self,msg,ex=None):
+ if self.logger:
+ self.logger.info('from %s: %s'%(self.path.abspath(),msg))
+ try:
+ msg='%s\n(complete log in %s)'%(msg,self.logger.handlers[0].baseFilename)
+ except:
+ pass
+ raise self.errors.ConfigurationError(msg,ex=ex)
+ def to_log(self,msg):
+ if not msg:
+ return
+ if self.logger:
+ self.logger.info(msg)
+ else:
+ sys.stderr.write(str(msg))
+ sys.stderr.flush()
+ def msg(self,msg,result,color=None):
+ self.start_msg(msg)
+ if not isinstance(color,str):
+ color=result and'GREEN'or'YELLOW'
+ self.end_msg(result,color)
+ def start_msg(self,msg):
+ try:
+ if self.in_msg:
+ self.in_msg+=1
+ return
+ except:
+ self.in_msg=0
+ self.in_msg+=1
+ try:
+ self.line_just=max(self.line_just,len(msg))
+ except AttributeError:
+ self.line_just=max(40,len(msg))
+ for x in(self.line_just*'-',msg):
+ self.to_log(x)
+ Logs.pprint('NORMAL',"%s :"%msg.ljust(self.line_just),sep='')
+ def end_msg(self,result,color=None):
+ self.in_msg-=1
+ if self.in_msg:
+ return
+ defcolor='GREEN'
+ if result==True:
+ msg='ok'
+ elif result==False:
+ msg='not found'
+ defcolor='YELLOW'
+ else:
+ msg=str(result)
+ self.to_log(msg)
+ Logs.pprint(color or defcolor,msg)
+ def load_special_tools(self,var,ban=[]):
+ global waf_dir
+ lst=self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var)
+ for x in lst:
+ if not x.name in ban:
+ load_tool(x.name.replace('.py',''))
+cache_modules={}
+def load_module(path):
+ try:
+ return cache_modules[path]
+ except KeyError:
+ pass
+ module=imp.new_module(WSCRIPT_FILE)
+ try:
+ code=Utils.readf(path,m='rU')
+ except(IOError,OSError):
+ raise Errors.WafError('Could not read the file %r'%path)
+ module_dir=os.path.dirname(path)
+ sys.path.insert(0,module_dir)
+ exec(compile(code,path,'exec'),module.__dict__)
+ sys.path.remove(module_dir)
+ cache_modules[path]=module
+ return module
+def load_tool(tool,tooldir=None):
+ tool=tool.replace('++','xx')
+ tool=tool.replace('java','javaw')
+ tool=tool.replace('compiler_cc','compiler_c')
+ if tooldir:
+ assert isinstance(tooldir,list)
+ sys.path=tooldir+sys.path
+ try:
+ __import__(tool)
+ ret=sys.modules[tool]
+ Context.tools[tool]=ret
+ return ret
+ finally:
+ for d in tooldir:
+ sys.path.remove(d)
+ else:
+ global waf_dir
+ try:
+ os.stat(os.path.join(waf_dir,'waflib','extras',tool+'.py'))
+ d='waflib.extras.%s'%tool
+ except:
+ try:
+ os.stat(os.path.join(waf_dir,'waflib','Tools',tool+'.py'))
+ d='waflib.Tools.%s'%tool
+ except:
+ d=tool
+ __import__(d)
+ ret=sys.modules[d]
+ Context.tools[tool]=ret
+ return ret
diff --git a/waflib/Errors.py b/waflib/Errors.py
new file mode 100644
index 0000000..aacc1a9
--- /dev/null
+++ b/waflib/Errors.py
@@ -0,0 +1,37 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import traceback,sys
+class WafError(Exception):
+ def __init__(self,msg='',ex=None):
+ self.msg=msg
+ assert not isinstance(msg,Exception)
+ self.stack=[]
+ if ex:
+ if not msg:
+ self.msg=str(ex)
+ if isinstance(ex,WafError):
+ self.stack=ex.stack
+ else:
+ self.stack=traceback.extract_tb(sys.exc_info()[2])
+ self.stack+=traceback.extract_stack()[:-1]
+ self.verbose_msg=''.join(traceback.format_list(self.stack))
+ def __str__(self):
+ return str(self.msg)
+class BuildError(WafError):
+ def __init__(self,error_tasks=[]):
+ self.tasks=error_tasks
+ WafError.__init__(self,self.format_error())
+ def format_error(self):
+ lst=['Build failed']
+ for tsk in self.tasks:
+ txt=tsk.format_error()
+ if txt:lst.append(txt)
+ return'\n'.join(lst)
+class ConfigurationError(WafError):
+ pass
+class TaskRescan(WafError):
+ pass
+class TaskNotReady(WafError):
+ pass
diff --git a/waflib/Logs.py b/waflib/Logs.py
new file mode 100644
index 0000000..2ba46d2
--- /dev/null
+++ b/waflib/Logs.py
@@ -0,0 +1,149 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re,traceback,sys
+_nocolor=os.environ.get('NOCOLOR','no')not in('no','0','false')
+try:
+ if not _nocolor:
+ import waflib.ansiterm
+except:
+ pass
+import logging
+LOG_FORMAT="%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s"
+HOUR_FORMAT="%H:%M:%S"
+zones=''
+verbose=0
+colors_lst={'USE':True,'BOLD':'\x1b[01;1m','RED':'\x1b[01;31m','GREEN':'\x1b[32m','YELLOW':'\x1b[33m','PINK':'\x1b[35m','BLUE':'\x1b[01;34m','CYAN':'\x1b[36m','NORMAL':'\x1b[0m','cursor_on':'\x1b[?25h','cursor_off':'\x1b[?25l',}
+got_tty=not os.environ.get('TERM','dumb')in['dumb','emacs']
+if got_tty:
+ try:
+ got_tty=sys.stderr.isatty()
+ except AttributeError:
+ got_tty=False
+if(not got_tty and os.environ.get('TERM','dumb')!='msys')or _nocolor:
+ colors_lst['USE']=False
+def get_term_cols():
+ return 80
+try:
+ import struct,fcntl,termios
+except ImportError:
+ pass
+else:
+ if got_tty:
+ def get_term_cols_real():
+ dummy_lines,cols=struct.unpack("HHHH",fcntl.ioctl(sys.stderr.fileno(),termios.TIOCGWINSZ,struct.pack("HHHH",0,0,0,0)))[:2]
+ return cols
+ try:
+ get_term_cols_real()
+ except:
+ pass
+ else:
+ get_term_cols=get_term_cols_real
+get_term_cols.__doc__="""
+ Get the console width in characters.
+
+ :return: the number of characters per line
+ :rtype: int
+ """
+def get_color(cl):
+ if not colors_lst['USE']:return''
+ return colors_lst.get(cl,'')
+class color_dict(object):
+ def __getattr__(self,a):
+ return get_color(a)
+ def __call__(self,a):
+ return get_color(a)
+colors=color_dict()
+re_log=re.compile(r'(\w+): (.*)',re.M)
+class log_filter(logging.Filter):
+ def __init__(self,name=None):
+ pass
+ def filter(self,rec):
+ rec.c1=colors.PINK
+ rec.c2=colors.NORMAL
+ rec.zone=rec.module
+ if rec.levelno>=logging.INFO:
+ if rec.levelno>=logging.ERROR:
+ rec.c1=colors.RED
+ elif rec.levelno>=logging.WARNING:
+ rec.c1=colors.YELLOW
+ else:
+ rec.c1=colors.GREEN
+ return True
+ m=re_log.match(rec.msg)
+ if m:
+ rec.zone=m.group(1)
+ rec.msg=m.group(2)
+ if zones:
+ return getattr(rec,'zone','')in zones or'*'in zones
+ elif not verbose>2:
+ return False
+ return True
+class formatter(logging.Formatter):
+ def __init__(self):
+ logging.Formatter.__init__(self,LOG_FORMAT,HOUR_FORMAT)
+ def format(self,rec):
+ if rec.levelno>=logging.WARNING or rec.levelno==logging.INFO:
+ try:
+ msg=rec.msg.decode('utf-8')
+ except:
+ msg=rec.msg
+ return'%s%s%s'%(rec.c1,msg,rec.c2)
+ return logging.Formatter.format(self,rec)
+log=None
+def debug(*k,**kw):
+ if verbose:
+ k=list(k)
+ k[0]=k[0].replace('\n',' ')
+ global log
+ log.debug(*k,**kw)
+def error(*k,**kw):
+ global log
+ log.error(*k,**kw)
+ if verbose>2:
+ st=traceback.extract_stack()
+ if st:
+ st=st[:-1]
+ buf=[]
+ for filename,lineno,name,line in st:
+ buf.append(' File "%s", line %d, in %s'%(filename,lineno,name))
+ if line:
+ buf.append(' %s'%line.strip())
+ if buf:log.error("\n".join(buf))
+def warn(*k,**kw):
+ global log
+ log.warn(*k,**kw)
+def info(*k,**kw):
+ global log
+ log.info(*k,**kw)
+def init_log():
+ global log
+ log=logging.getLogger('waflib')
+ log.handlers=[]
+ log.filters=[]
+ hdlr=logging.StreamHandler()
+ hdlr.setFormatter(formatter())
+ log.addHandler(hdlr)
+ log.addFilter(log_filter())
+ log.setLevel(logging.DEBUG)
+def make_logger(path,name):
+ logger=logging.getLogger(name)
+ hdlr=logging.FileHandler(path,'w')
+ formatter=logging.Formatter('%(message)s')
+ hdlr.setFormatter(formatter)
+ logger.addHandler(hdlr)
+ logger.setLevel(logging.DEBUG)
+ return logger
+def make_mem_logger(name,to_log,size=10000):
+ from logging.handlers import MemoryHandler
+ logger=logging.getLogger(name)
+ hdlr=MemoryHandler(size,target=to_log)
+ formatter=logging.Formatter('%(message)s')
+ hdlr.setFormatter(formatter)
+ logger.addHandler(hdlr)
+ logger.memhandler=hdlr
+ logger.setLevel(logging.DEBUG)
+ return logger
+def pprint(col,str,label='',sep='\n'):
+ sys.stderr.write("%s%s%s %s%s"%(colors(col),str,colors.NORMAL,label,sep))
diff --git a/waflib/Node.py b/waflib/Node.py
new file mode 100644
index 0000000..9a86b22
--- /dev/null
+++ b/waflib/Node.py
@@ -0,0 +1,506 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+import os,re,sys,shutil
+from waflib import Utils,Errors
+exclude_regs='''
+**/*~
+**/#*#
+**/.#*
+**/%*%
+**/._*
+**/CVS
+**/CVS/**
+**/.cvsignore
+**/SCCS
+**/SCCS/**
+**/vssver.scc
+**/.svn
+**/.svn/**
+**/BitKeeper
+**/.git
+**/.git/**
+**/.gitignore
+**/.bzr
+**/.bzrignore
+**/.bzr/**
+**/.hg
+**/.hg/**
+**/_MTN
+**/_MTN/**
+**/.arch-ids
+**/{arch}
+**/_darcs
+**/_darcs/**
+**/.DS_Store'''
+def split_path(path):
+ return path.split('/')
+def split_path_cygwin(path):
+ if path.startswith('//'):
+ ret=path.split('/')[2:]
+ ret[0]='/'+ret[0]
+ return ret
+ return path.split('/')
+re_sp=re.compile('[/\\\\]')
+def split_path_win32(path):
+ if path.startswith('\\\\'):
+ ret=re.split(re_sp,path)[2:]
+ ret[0]='\\'+ret[0]
+ return ret
+ return re.split(re_sp,path)
+if sys.platform=='cygwin':
+ split_path=split_path_cygwin
+elif Utils.is_win32:
+ split_path=split_path_win32
+class Node(object):
+ __slots__=('name','sig','children','parent','cache_abspath','cache_isdir')
+ def __init__(self,name,parent):
+ self.name=name
+ self.parent=parent
+ if parent:
+ if name in parent.children:
+ raise Errors.WafError('node %s exists in the parent files %r already'%(name,parent))
+ parent.children[name]=self
+ def __setstate__(self,data):
+ self.name=data[0]
+ self.parent=data[1]
+ if data[2]is not None:
+ self.children=data[2]
+ if data[3]is not None:
+ self.sig=data[3]
+ def __getstate__(self):
+ return(self.name,self.parent,getattr(self,'children',None),getattr(self,'sig',None))
+ def __str__(self):
+ return self.name
+ def __repr__(self):
+ return self.abspath()
+ def __hash__(self):
+ return id(self)
+ def __eq__(self,node):
+ return id(self)==id(node)
+ def __copy__(self):
+ raise Errors.WafError('nodes are not supposed to be copied')
+ def read(self,flags='r'):
+ return Utils.readf(self.abspath(),flags)
+ def write(self,data,flags='w'):
+ f=None
+ try:
+ f=open(self.abspath(),flags)
+ f.write(data)
+ finally:
+ if f:
+ f.close()
+ def chmod(self,val):
+ os.chmod(self.abspath(),val)
+ def delete(self):
+ try:
+ if getattr(self,'children',None):
+ shutil.rmtree(self.abspath())
+ else:
+ os.unlink(self.abspath())
+ except:
+ pass
+ try:
+ delattr(self,'children')
+ except:
+ pass
+ def suffix(self):
+ k=max(0,self.name.rfind('.'))
+ return self.name[k:]
+ def height(self):
+ d=self
+ val=-1
+ while d:
+ d=d.parent
+ val+=1
+ return val
+ def listdir(self):
+ lst=Utils.listdir(self.abspath())
+ lst.sort()
+ return lst
+ def mkdir(self):
+ if getattr(self,'cache_isdir',None):
+ return
+ try:
+ self.parent.mkdir()
+ except:
+ pass
+ if self.name:
+ try:
+ os.makedirs(self.abspath())
+ except OSError:
+ pass
+ if not os.path.isdir(self.abspath()):
+ raise Errors.WafError('Could not create the directory %s'%self.abspath())
+ try:
+ self.children
+ except:
+ self.children={}
+ self.cache_isdir=True
+ def find_node(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ cur=self
+ for x in lst:
+ if x=='..':
+ cur=cur.parent or cur
+ continue
+ try:
+ if x in cur.children:
+ cur=cur.children[x]
+ continue
+ except:
+ cur.children={}
+ cur=self.__class__(x,cur)
+ try:
+ os.stat(cur.abspath())
+ except:
+ del cur.parent.children[x]
+ return None
+ ret=cur
+ try:
+ os.stat(ret.abspath())
+ except:
+ del ret.parent.children[ret.name]
+ return None
+ try:
+ while not getattr(cur.parent,'cache_isdir',None):
+ cur=cur.parent
+ cur.cache_isdir=True
+ except AttributeError:
+ pass
+ return ret
+ def make_node(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ cur=self
+ for x in lst:
+ if x=='..':
+ cur=cur.parent or cur
+ continue
+ if getattr(cur,'children',{}):
+ if x in cur.children:
+ cur=cur.children[x]
+ continue
+ else:
+ cur.children={}
+ cur=self.__class__(x,cur)
+ return cur
+ def search(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ cur=self
+ try:
+ for x in lst:
+ if x=='..':
+ cur=cur.parent or cur
+ else:
+ cur=cur.children[x]
+ return cur
+ except:
+ pass
+ def path_from(self,node):
+ c1=self
+ c2=node
+ c1h=c1.height()
+ c2h=c2.height()
+ lst=[]
+ up=0
+ while c1h>c2h:
+ lst.append(c1.name)
+ c1=c1.parent
+ c1h-=1
+ while c2h>c1h:
+ up+=1
+ c2=c2.parent
+ c2h-=1
+ while id(c1)!=id(c2):
+ lst.append(c1.name)
+ up+=1
+ c1=c1.parent
+ c2=c2.parent
+ for i in range(up):
+ lst.append('..')
+ lst.reverse()
+ return os.sep.join(lst)or'.'
+ def abspath(self):
+ try:
+ return self.cache_abspath
+ except:
+ pass
+ if os.sep=='/':
+ if not self.parent:
+ val=os.sep
+ elif not self.parent.name:
+ val=os.sep+self.name
+ else:
+ val=self.parent.abspath()+os.sep+self.name
+ else:
+ if not self.parent:
+ val=''
+ elif not self.parent.name:
+ val=self.name+os.sep
+ else:
+ val=self.parent.abspath().rstrip(os.sep)+os.sep+self.name
+ self.cache_abspath=val
+ return val
+ def is_child_of(self,node):
+ p=self
+ diff=self.height()-node.height()
+ while diff>0:
+ diff-=1
+ p=p.parent
+ return id(p)==id(node)
+ def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True):
+ dircont=self.listdir()
+ dircont.sort()
+ try:
+ lst=set(self.children.keys())
+ if remove:
+ for x in lst-set(dircont):
+ del self.children[x]
+ except:
+ self.children={}
+ for name in dircont:
+ npats=accept(name,pats)
+ if npats and npats[0]:
+ accepted=[]in npats[0]
+ node=self.make_node([name])
+ isdir=os.path.isdir(node.abspath())
+ if accepted:
+ if isdir:
+ if dir:
+ yield node
+ else:
+ if src:
+ yield node
+ if getattr(node,'cache_isdir',None)or isdir:
+ node.cache_isdir=True
+ if maxdepth:
+ for k in node.ant_iter(accept=accept,maxdepth=maxdepth-1,pats=npats,dir=dir,src=src,remove=remove):
+ yield k
+ raise StopIteration
+ def ant_glob(self,*k,**kw):
+ src=kw.get('src',True)
+ dir=kw.get('dir',False)
+ excl=kw.get('excl',exclude_regs)
+ incl=k and k[0]or kw.get('incl','**')
+ def to_pat(s):
+ lst=Utils.to_list(s)
+ ret=[]
+ for x in lst:
+ x=x.replace('\\','/').replace('//','/')
+ if x.endswith('/'):
+ x+='**'
+ lst2=x.split('/')
+ accu=[]
+ for k in lst2:
+ if k=='**':
+ accu.append(k)
+ else:
+ k=k.replace('.','[.]').replace('*','.*').replace('?','.').replace('+','\\+')
+ k='^%s$'%k
+ try:
+ accu.append(re.compile(k))
+ except Exception ,e:
+ raise Errors.WafError("Invalid pattern: %s"%k,e)
+ ret.append(accu)
+ return ret
+ def filtre(name,nn):
+ ret=[]
+ for lst in nn:
+ if not lst:
+ pass
+ elif lst[0]=='**':
+ ret.append(lst)
+ if len(lst)>1:
+ if lst[1].match(name):
+ ret.append(lst[2:])
+ else:
+ ret.append([])
+ elif lst[0].match(name):
+ ret.append(lst[1:])
+ return ret
+ def accept(name,pats):
+ nacc=filtre(name,pats[0])
+ nrej=filtre(name,pats[1])
+ if[]in nrej:
+ nacc=[]
+ return[nacc,nrej]
+ ret=[x for x in self.ant_iter(accept=accept,pats=[to_pat(incl),to_pat(excl)],maxdepth=25,dir=dir,src=src,remove=kw.get('remove',True))]
+ if kw.get('flat',False):
+ return' '.join([x.path_from(self)for x in ret])
+ return ret
+ def find_nodes(self,find_dirs=True,find_files=True,match_fun=lambda x:True):
+ x="""
+ Recursively finds nodes::
+
+ def configure(cnf):
+ cnf.find_nodes()
+
+ :param find_dirs: whether to return directories
+ :param find_files: whether to return files
+ :param match_fun: matching function, taking a node as parameter
+ :rtype generator
+ :return: a generator that iterates over all the requested files
+ """
+ files=self.listdir()
+ for f in files:
+ node=self.make_node([f])
+ if os.path.isdir(node.abspath()):
+ if find_dirs and match_fun(node):
+ yield node
+ gen=node.find_nodes(find_dirs,find_files,match_fun)
+ for g in gen:
+ yield g
+ else:
+ if find_files and match_fun(node):
+ yield node
+ def is_src(self):
+ cur=self
+ x=id(self.ctx.srcnode)
+ y=id(self.ctx.bldnode)
+ while cur.parent:
+ if id(cur)==y:
+ return False
+ if id(cur)==x:
+ return True
+ cur=cur.parent
+ return False
+ def is_bld(self):
+ cur=self
+ y=id(self.ctx.bldnode)
+ while cur.parent:
+ if id(cur)==y:
+ return True
+ cur=cur.parent
+ return False
+ def get_src(self):
+ cur=self
+ x=id(self.ctx.srcnode)
+ y=id(self.ctx.bldnode)
+ lst=[]
+ while cur.parent:
+ if id(cur)==y:
+ lst.reverse()
+ return self.ctx.srcnode.make_node(lst)
+ if id(cur)==x:
+ return self
+ lst.append(cur.name)
+ cur=cur.parent
+ return self
+ def get_bld(self):
+ cur=self
+ x=id(self.ctx.srcnode)
+ y=id(self.ctx.bldnode)
+ lst=[]
+ while cur.parent:
+ if id(cur)==y:
+ return self
+ if id(cur)==x:
+ lst.reverse()
+ return self.ctx.bldnode.make_node(lst)
+ lst.append(cur.name)
+ cur=cur.parent
+ lst.reverse()
+ if lst and Utils.is_win32 and len(lst[0])==2 and lst[0].endswith(':'):
+ lst[0]=lst[0][0]
+ return self.ctx.bldnode.make_node(['__root__']+lst)
+ def find_resource(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ node=self.get_bld().search(lst)
+ if not node:
+ self=self.get_src()
+ node=self.find_node(lst)
+ try:
+ pat=node.abspath()
+ if os.path.isdir(pat):
+ return None
+ except:
+ pass
+ return node
+ def find_or_declare(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ node=self.get_bld().search(lst)
+ if node:
+ if not os.path.isfile(node.abspath()):
+ node.sig=None
+ try:
+ node.parent.mkdir()
+ except:
+ pass
+ return node
+ self=self.get_src()
+ node=self.find_node(lst)
+ if node:
+ if not os.path.isfile(node.abspath()):
+ node.sig=None
+ try:
+ node.parent.mkdir()
+ except:
+ pass
+ return node
+ node=self.get_bld().make_node(lst)
+ node.parent.mkdir()
+ return node
+ def find_dir(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ node=self.find_node(lst)
+ try:
+ if not os.path.isdir(node.abspath()):
+ return None
+ except(OSError,AttributeError):
+ return None
+ return node
+ def change_ext(self,ext,ext_in=None):
+ name=self.name
+ if ext_in is None:
+ k=name.rfind('.')
+ if k>=0:
+ name=name[:k]+ext
+ else:
+ name=name+ext
+ else:
+ name=name[:-len(ext_in)]+ext
+ return self.parent.find_or_declare([name])
+ def nice_path(self,env=None):
+ return self.path_from(self.ctx.launch_node())
+ def bldpath(self):
+ return self.path_from(self.ctx.bldnode)
+ def srcpath(self):
+ return self.path_from(self.ctx.srcnode)
+ def relpath(self):
+ cur=self
+ x=id(self.ctx.bldnode)
+ while cur.parent:
+ if id(cur)==x:
+ return self.bldpath()
+ cur=cur.parent
+ return self.srcpath()
+ def bld_dir(self):
+ return self.parent.bldpath()
+ def bld_base(self):
+ s=os.path.splitext(self.name)[0]
+ return self.bld_dir()+os.sep+s
+ def get_bld_sig(self):
+ try:
+ ret=self.ctx.hash_cache[id(self)]
+ except KeyError:
+ pass
+ except AttributeError:
+ self.ctx.hash_cache={}
+ else:
+ return ret
+ if not self.is_bld()or self.ctx.bldnode is self.ctx.srcnode:
+ self.sig=Utils.h_file(self.abspath())
+ self.ctx.hash_cache[id(self)]=ret=self.sig
+ return ret
+pickle_lock=Utils.threading.Lock()
+class Nod3(Node):
+ pass
diff --git a/waflib/Options.py b/waflib/Options.py
new file mode 100644
index 0000000..2149b1b
--- /dev/null
+++ b/waflib/Options.py
@@ -0,0 +1,134 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,tempfile,optparse,sys,re
+from waflib import Logs,Utils,Context
+cmds='distclean configure build install clean uninstall check dist distcheck'.split()
+options={}
+commands=[]
+lockfile=os.environ.get('WAFLOCK','.lock-waf_%s_build'%sys.platform)
+try:cache_global=os.path.abspath(os.environ['WAFCACHE'])
+except KeyError:cache_global=''
+platform=Utils.unversioned_sys_platform()
+class opt_parser(optparse.OptionParser):
+ def __init__(self,ctx):
+ optparse.OptionParser.__init__(self,conflict_handler="resolve",version='waf %s (%s)'%(Context.WAFVERSION,Context.WAFREVISION))
+ self.formatter.width=Logs.get_term_cols()
+ p=self.add_option
+ self.ctx=ctx
+ jobs=ctx.jobs()
+ p('-j','--jobs',dest='jobs',default=jobs,type='int',help='amount of parallel jobs (%r)'%jobs)
+ p('-k','--keep',dest='keep',default=0,action='count',help='keep running happily even if errors are found')
+ p('-v','--verbose',dest='verbose',default=0,action='count',help='verbosity level -v -vv or -vvv [default: 0]')
+ p('--nocache',dest='nocache',default=False,action='store_true',help='ignore the WAFCACHE (if set)')
+ p('--zones',dest='zones',default='',action='store',help='debugging zones (task_gen, deps, tasks, etc)')
+ gr=optparse.OptionGroup(self,'configure options')
+ self.add_option_group(gr)
+ gr.add_option('-o','--out',action='store',default='',help='build dir for the project',dest='out')
+ gr.add_option('-t','--top',action='store',default='',help='src dir for the project',dest='top')
+ default_prefix=os.environ.get('PREFIX')
+ if not default_prefix:
+ if platform=='win32':
+ d=tempfile.gettempdir()
+ default_prefix=d[0].upper()+d[1:]
+ else:
+ default_prefix='/usr/local/'
+ gr.add_option('--prefix',dest='prefix',default=default_prefix,help='installation prefix [default: %r]'%default_prefix)
+ gr.add_option('--download',dest='download',default=False,action='store_true',help='try to download the tools if missing')
+ gr=optparse.OptionGroup(self,'build and install options')
+ self.add_option_group(gr)
+ gr.add_option('-p','--progress',dest='progress_bar',default=0,action='count',help='-p: progress bar; -pp: ide output')
+ gr.add_option('--targets',dest='targets',default='',action='store',help='task generators, e.g. "target1,target2"')
+ gr=optparse.OptionGroup(self,'step options')
+ self.add_option_group(gr)
+ gr.add_option('--files',dest='files',default='',action='store',help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"')
+ default_destdir=os.environ.get('DESTDIR','')
+ gr=optparse.OptionGroup(self,'install/uninstall options')
+ self.add_option_group(gr)
+ gr.add_option('--destdir',help='installation root [default: %r]'%default_destdir,default=default_destdir,dest='destdir')
+ gr.add_option('-f','--force',dest='force',default=False,action='store_true',help='force file installation')
+ def get_usage(self):
+ cmds_str={}
+ for cls in Context.classes:
+ if not cls.cmd or cls.cmd=='options':
+ continue
+ s=cls.__doc__ or''
+ cmds_str[cls.cmd]=s
+ if Context.g_module:
+ for(k,v)in Context.g_module.__dict__.items():
+ if k in['options','init','shutdown']:
+ continue
+ if type(v)is type(Context.create_context):
+ if v.__doc__ and not k.startswith('_'):
+ cmds_str[k]=v.__doc__
+ just=0
+ for k in cmds_str:
+ just=max(just,len(k))
+ lst=[' %s: %s'%(k.ljust(just),v)for(k,v)in cmds_str.items()]
+ lst.sort()
+ ret='\n'.join(lst)
+ return'''waf [commands] [options]
+
+Main commands (example: ./waf build -j4)
+%s
+'''%ret
+class OptionsContext(Context.Context):
+ cmd='options'
+ fun='options'
+ def __init__(self,**kw):
+ super(OptionsContext,self).__init__(**kw)
+ self.parser=opt_parser(self)
+ self.option_groups={}
+ def jobs(self):
+ count=int(os.environ.get('JOBS',0))
+ if count<1:
+ if'NUMBER_OF_PROCESSORS'in os.environ:
+ count=int(os.environ.get('NUMBER_OF_PROCESSORS',1))
+ else:
+ if hasattr(os,'sysconf_names'):
+ if'SC_NPROCESSORS_ONLN'in os.sysconf_names:
+ count=int(os.sysconf('SC_NPROCESSORS_ONLN'))
+ elif'SC_NPROCESSORS_CONF'in os.sysconf_names:
+ count=int(os.sysconf('SC_NPROCESSORS_CONF'))
+ if not count and os.name not in('nt','java'):
+ try:
+ tmp=self.cmd_and_log(['sysctl','-n','hw.ncpu'],quiet=0)
+ except Exception:
+ pass
+ else:
+ if re.match('^[0-9]+$',tmp):
+ count=int(tmp)
+ if count<1:
+ count=1
+ elif count>1024:
+ count=1024
+ return count
+ def add_option(self,*k,**kw):
+ self.parser.add_option(*k,**kw)
+ def add_option_group(self,*k,**kw):
+ try:
+ gr=self.option_groups[k[0]]
+ except:
+ gr=self.parser.add_option_group(*k,**kw)
+ self.option_groups[k[0]]=gr
+ return gr
+ def get_option_group(self,opt_str):
+ try:
+ return self.option_groups[opt_str]
+ except KeyError:
+ for group in self.parser.option_groups:
+ if group.title==opt_str:
+ return group
+ return None
+ def parse_args(self,_args=None):
+ global options,commands
+ (options,leftover_args)=self.parser.parse_args(args=_args)
+ commands=leftover_args
+ if options.destdir:
+ options.destdir=os.path.abspath(os.path.expanduser(options.destdir))
+ if options.verbose>=1:
+ self.load('errcheck')
+ def execute(self):
+ super(OptionsContext,self).execute()
+ self.parse_args()
diff --git a/waflib/Runner.py b/waflib/Runner.py
new file mode 100644
index 0000000..6f64fed
--- /dev/null
+++ b/waflib/Runner.py
@@ -0,0 +1,197 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import random,atexit
+try:
+ from queue import Queue
+except:
+ from Queue import Queue
+from waflib import Utils,Task,Errors,Logs
+GAP=10
+class TaskConsumer(Utils.threading.Thread):
+ def __init__(self):
+ Utils.threading.Thread.__init__(self)
+ self.ready=Queue()
+ self.setDaemon(1)
+ self.start()
+ def run(self):
+ try:
+ self.loop()
+ except:
+ pass
+ def loop(self):
+ while 1:
+ tsk=self.ready.get()
+ if not isinstance(tsk,Task.TaskBase):
+ tsk(self)
+ else:
+ tsk.process()
+pool=Queue()
+def get_pool():
+ try:
+ return pool.get(False)
+ except:
+ return TaskConsumer()
+def put_pool(x):
+ pool.put(x)
+def _free_resources():
+ global pool
+ lst=[]
+ while pool.qsize():
+ lst.append(pool.get())
+ for x in lst:
+ x.ready.put(None)
+ for x in lst:
+ x.join()
+ pool=None
+atexit.register(_free_resources)
+class Parallel(object):
+ def __init__(self,bld,j=2):
+ self.numjobs=j
+ self.bld=bld
+ self.outstanding=[]
+ self.frozen=[]
+ self.out=Queue(0)
+ self.count=0
+ self.processed=1
+ self.stop=False
+ self.error=[]
+ self.biter=None
+ self.dirty=False
+ def get_next_task(self):
+ if not self.outstanding:
+ return None
+ return self.outstanding.pop(0)
+ def postpone(self,tsk):
+ if random.randint(0,1):
+ self.frozen.insert(0,tsk)
+ else:
+ self.frozen.append(tsk)
+ def refill_task_list(self):
+ while self.count>self.numjobs*GAP:
+ self.get_out()
+ while not self.outstanding:
+ if self.count:
+ self.get_out()
+ elif self.frozen:
+ try:
+ cond=self.deadlock==self.processed
+ except:
+ pass
+ else:
+ if cond:
+ msg='check the build order for the tasks'
+ for tsk in self.frozen:
+ if not tsk.run_after:
+ msg='check the methods runnable_status'
+ break
+ lst=[]
+ for tsk in self.frozen:
+ lst.append('%s\t-> %r'%(repr(tsk),[id(x)for x in tsk.run_after]))
+ raise Errors.WafError('Deadlock detected: %s%s'%(msg,''.join(lst)))
+ self.deadlock=self.processed
+ if self.frozen:
+ self.outstanding+=self.frozen
+ self.frozen=[]
+ elif not self.count:
+ self.outstanding.extend(self.biter.next())
+ self.total=self.bld.total()
+ break
+ def add_more_tasks(self,tsk):
+ if getattr(tsk,'more_tasks',None):
+ self.outstanding+=tsk.more_tasks
+ self.total+=len(tsk.more_tasks)
+ def get_out(self):
+ tsk=self.out.get()
+ if not self.stop:
+ self.add_more_tasks(tsk)
+ self.count-=1
+ self.dirty=True
+ return tsk
+ def error_handler(self,tsk):
+ if not self.bld.keep:
+ self.stop=True
+ self.error.append(tsk)
+ def add_task(self,tsk):
+ try:
+ self.pool
+ except AttributeError:
+ self.init_task_pool()
+ self.ready.put(tsk)
+ def init_task_pool(self):
+ pool=self.pool=[get_pool()for i in range(self.numjobs)]
+ self.ready=Queue(0)
+ def setq(consumer):
+ consumer.ready=self.ready
+ for x in pool:
+ x.ready.put(setq)
+ return pool
+ def free_task_pool(self):
+ def setq(consumer):
+ consumer.ready=Queue(0)
+ self.out.put(self)
+ try:
+ pool=self.pool
+ except:
+ pass
+ else:
+ for x in pool:
+ self.ready.put(setq)
+ for x in pool:
+ self.get_out()
+ for x in pool:
+ put_pool(x)
+ self.pool=[]
+ def start(self):
+ self.total=self.bld.total()
+ while not self.stop:
+ self.refill_task_list()
+ tsk=self.get_next_task()
+ if not tsk:
+ if self.count:
+ continue
+ else:
+ break
+ if tsk.hasrun:
+ self.processed+=1
+ continue
+ if self.stop:
+ break
+ try:
+ st=tsk.runnable_status()
+ except Exception:
+ self.processed+=1
+ tsk.err_msg=Utils.ex_stack()
+ if not self.stop and self.bld.keep:
+ tsk.hasrun=Task.SKIPPED
+ if self.bld.keep==1:
+ if Logs.verbose>1 or not self.error:
+ self.error.append(tsk)
+ self.stop=True
+ else:
+ if Logs.verbose>1:
+ self.error.append(tsk)
+ continue
+ tsk.hasrun=Task.EXCEPTION
+ self.error_handler(tsk)
+ continue
+ if st==Task.ASK_LATER:
+ self.postpone(tsk)
+ elif st==Task.SKIP_ME:
+ self.processed+=1
+ tsk.hasrun=Task.SKIPPED
+ self.add_more_tasks(tsk)
+ else:
+ tsk.position=(self.processed,self.total)
+ self.count+=1
+ tsk.master=self
+ self.processed+=1
+ if self.numjobs==1:
+ tsk.process()
+ else:
+ self.add_task(tsk)
+ while self.error and self.count:
+ self.get_out()
+ assert(self.count==0 or self.stop)
+ self.free_task_pool()
diff --git a/waflib/Scripting.py b/waflib/Scripting.py
new file mode 100644
index 0000000..9a5d2e9
--- /dev/null
+++ b/waflib/Scripting.py
@@ -0,0 +1,367 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,shutil,traceback,errno,sys,stat
+from waflib import Utils,Configure,Logs,Options,ConfigSet,Context,Errors,Build,Node
+build_dir_override=None
+no_climb_commands=['configure']
+default_cmd="build"
+def waf_entry_point(current_directory,version,wafdir):
+ Logs.init_log()
+ if Context.WAFVERSION!=version:
+ Logs.error('Waf script %r and library %r do not match (directory %r)'%(version,Context.WAFVERSION,wafdir))
+ sys.exit(1)
+ if'--version'in sys.argv:
+ Context.run_dir=current_directory
+ ctx=Context.create_context('options')
+ ctx.curdir=current_directory
+ ctx.parse_args()
+ sys.exit(0)
+ Context.waf_dir=wafdir
+ Context.launch_dir=current_directory
+ no_climb=os.environ.get('NOCLIMB',None)
+ if not no_climb:
+ for k in no_climb_commands:
+ if k in sys.argv:
+ no_climb=True
+ break
+ cur=current_directory
+ while cur:
+ lst=os.listdir(cur)
+ if Options.lockfile in lst:
+ env=ConfigSet.ConfigSet()
+ try:
+ env.load(os.path.join(cur,Options.lockfile))
+ ino=os.stat(cur)[stat.ST_INO]
+ except Exception:
+ pass
+ else:
+ for x in[env.run_dir,env.top_dir,env.out_dir]:
+ if Utils.is_win32:
+ if cur==x:
+ load=True
+ break
+ else:
+ try:
+ ino2=os.stat(x)[stat.ST_INO]
+ except:
+ pass
+ else:
+ if ino==ino2:
+ load=True
+ break
+ else:
+ Logs.warn('invalid lock file in %s'%cur)
+ load=False
+ if load:
+ Context.run_dir=env.run_dir
+ Context.top_dir=env.top_dir
+ Context.out_dir=env.out_dir
+ break
+ if not Context.run_dir:
+ if Context.WSCRIPT_FILE in lst:
+ Context.run_dir=cur
+ next=os.path.dirname(cur)
+ if next==cur:
+ break
+ cur=next
+ if no_climb:
+ break
+ if not Context.run_dir:
+ if'-h'in sys.argv or'--help'in sys.argv:
+ Logs.warn('No wscript file found: the help message may be incomplete')
+ Context.run_dir=current_directory
+ ctx=Context.create_context('options')
+ ctx.curdir=current_directory
+ ctx.parse_args()
+ sys.exit(0)
+ Logs.error('Waf: Run from a directory containing a file named %r'%Context.WSCRIPT_FILE)
+ sys.exit(1)
+ try:
+ os.chdir(Context.run_dir)
+ except OSError:
+ Logs.error('Waf: The folder %r is unreadable'%Context.run_dir)
+ sys.exit(1)
+ try:
+ set_main_module(Context.run_dir+os.sep+Context.WSCRIPT_FILE)
+ except Errors.WafError ,e:
+ Logs.pprint('RED',e.verbose_msg)
+ Logs.error(str(e))
+ sys.exit(1)
+ except Exception ,e:
+ Logs.error('Waf: The wscript in %r is unreadable'%Context.run_dir,e)
+ traceback.print_exc(file=sys.stdout)
+ sys.exit(2)
+ try:
+ run_commands()
+ except Errors.WafError ,e:
+ if Logs.verbose>1:
+ Logs.pprint('RED',e.verbose_msg)
+ Logs.error(e.msg)
+ sys.exit(1)
+ except Exception ,e:
+ traceback.print_exc(file=sys.stdout)
+ sys.exit(2)
+ except KeyboardInterrupt:
+ Logs.pprint('RED','Interrupted')
+ sys.exit(68)
+def set_main_module(file_path):
+ Context.g_module=Context.load_module(file_path)
+ Context.g_module.root_path=file_path
+ def set_def(obj):
+ name=obj.__name__
+ if not name in Context.g_module.__dict__:
+ setattr(Context.g_module,name,obj)
+ for k in[update,dist,distclean,distcheck,update]:
+ set_def(k)
+ if not'init'in Context.g_module.__dict__:
+ Context.g_module.init=Utils.nada
+ if not'shutdown'in Context.g_module.__dict__:
+ Context.g_module.shutdown=Utils.nada
+ if not'options'in Context.g_module.__dict__:
+ Context.g_module.options=Utils.nada
+def parse_options():
+ Context.create_context('options').execute()
+ if not Options.commands:
+ Options.commands=[default_cmd]
+ Options.commands=[x for x in Options.commands if x!='options']
+ Logs.verbose=Options.options.verbose
+ Logs.init_log()
+ if Options.options.zones:
+ Logs.zones=Options.options.zones.split(',')
+ if not Logs.verbose:
+ Logs.verbose=1
+ elif Logs.verbose>0:
+ Logs.zones=['runner']
+ if Logs.verbose>2:
+ Logs.zones=['*']
+def run_command(cmd_name):
+ ctx=Context.create_context(cmd_name)
+ ctx.options=Options.options
+ ctx.cmd=cmd_name
+ ctx.execute()
+ return ctx
+def run_commands():
+ parse_options()
+ run_command('init')
+ while Options.commands:
+ cmd_name=Options.commands.pop(0)
+ timer=Utils.Timer()
+ run_command(cmd_name)
+ if not Options.options.progress_bar:
+ elapsed=' (%s)'%str(timer)
+ Logs.info('%r finished successfully%s'%(cmd_name,elapsed))
+ run_command('shutdown')
+def _can_distclean(name):
+ for k in'.o .moc .exe'.split():
+ if name.endswith(k):
+ return True
+ return False
+def distclean_dir(dirname):
+ for(root,dirs,files)in os.walk(dirname):
+ for f in files:
+ if _can_distclean(f):
+ fname=root+os.sep+f
+ try:
+ os.unlink(fname)
+ except:
+ Logs.warn('could not remove %r'%fname)
+ for x in[Context.DBFILE,'config.log']:
+ try:
+ os.unlink(x)
+ except:
+ pass
+ try:
+ shutil.rmtree('c4che')
+ except:
+ pass
+def distclean(ctx):
+ '''removes the build directory'''
+ lst=os.listdir('.')
+ for f in lst:
+ if f==Options.lockfile:
+ try:
+ proj=ConfigSet.ConfigSet(f)
+ except:
+ Logs.warn('could not read %r'%f)
+ continue
+ if proj['out_dir']!=proj['top_dir']:
+ try:
+ shutil.rmtree(proj['out_dir'])
+ except IOError:
+ pass
+ except OSError ,e:
+ if e.errno!=errno.ENOENT:
+ Logs.warn('project %r cannot be removed'%proj[Context.OUT])
+ else:
+ distclean_dir(proj['out_dir'])
+ for k in(proj['out_dir'],proj['top_dir'],proj['run_dir']):
+ try:
+ os.remove(os.path.join(k,Options.lockfile))
+ except OSError ,e:
+ if e.errno!=errno.ENOENT:
+ Logs.warn('file %r cannot be removed'%f)
+ if f.startswith('.waf')and not Options.commands:
+ shutil.rmtree(f,ignore_errors=True)
+class Dist(Context.Context):
+ cmd='dist'
+ fun='dist'
+ algo='tar.bz2'
+ ext_algo={}
+ def execute(self):
+ self.recurse([os.path.dirname(Context.g_module.root_path)])
+ self.archive()
+ def archive(self):
+ import tarfile
+ arch_name=self.get_arch_name()
+ try:
+ self.base_path
+ except:
+ self.base_path=self.path
+ node=self.base_path.make_node(arch_name)
+ try:
+ node.delete()
+ except:
+ pass
+ files=self.get_files()
+ if self.algo.startswith('tar.'):
+ tar=tarfile.open(arch_name,'w:'+self.algo.replace('tar.',''))
+ for x in files:
+ self.add_tar_file(x,tar)
+ tar.close()
+ elif self.algo=='zip':
+ import zipfile
+ zip=zipfile.ZipFile(arch_name,'w',compression=zipfile.ZIP_DEFLATED)
+ for x in files:
+ archive_name=self.get_base_name()+'/'+x.path_from(self.base_path)
+ zip.write(x.abspath(),archive_name,zipfile.ZIP_DEFLATED)
+ zip.close()
+ else:
+ self.fatal('Valid algo types are tar.bz2, tar.gz or zip')
+ try:
+ from hashlib import sha1 as sha
+ except ImportError:
+ from sha import sha
+ try:
+ digest=" (sha=%r)"%sha(node.read()).hexdigest()
+ except:
+ digest=''
+ Logs.info('New archive created: %s%s'%(self.arch_name,digest))
+ def get_tar_path(self,node):
+ return node.abspath()
+ def add_tar_file(self,x,tar):
+ p=self.get_tar_path(x)
+ tinfo=tar.gettarinfo(name=p,arcname=self.get_tar_prefix()+'/'+x.path_from(self.base_path))
+ tinfo.uid=0
+ tinfo.gid=0
+ tinfo.uname='root'
+ tinfo.gname='root'
+ fu=None
+ try:
+ fu=open(p,'rb')
+ tar.addfile(tinfo,fileobj=fu)
+ finally:
+ if fu:
+ fu.close()
+ def get_tar_prefix(self):
+ try:
+ return self.tar_prefix
+ except:
+ return self.get_base_name()
+ def get_arch_name(self):
+ try:
+ self.arch_name
+ except:
+ self.arch_name=self.get_base_name()+'.'+self.ext_algo.get(self.algo,self.algo)
+ return self.arch_name
+ def get_base_name(self):
+ try:
+ self.base_name
+ except:
+ appname=getattr(Context.g_module,Context.APPNAME,'noname')
+ version=getattr(Context.g_module,Context.VERSION,'1.0')
+ self.base_name=appname+'-'+version
+ return self.base_name
+ def get_excl(self):
+ try:
+ return self.excl
+ except:
+ self.excl=Node.exclude_regs+' **/waf-1.6.* **/.waf-1.6* **/waf3-1.6.* **/.waf3-1.6* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*'
+ nd=self.root.find_node(Context.out_dir)
+ if nd:
+ self.excl+=' '+nd.path_from(self.base_path)
+ return self.excl
+ def get_files(self):
+ try:
+ files=self.files
+ except:
+ files=self.base_path.ant_glob('**/*',excl=self.get_excl())
+ return files
+def dist(ctx):
+ '''makes a tarball for redistributing the sources'''
+ pass
+class DistCheck(Dist):
+ fun='distcheck'
+ cmd='distcheck'
+ def execute(self):
+ self.recurse([os.path.dirname(Context.g_module.root_path)])
+ self.archive()
+ self.check()
+ def check(self):
+ import tempfile,tarfile
+ t=None
+ try:
+ t=tarfile.open(self.get_arch_name())
+ for x in t:
+ t.extract(x)
+ finally:
+ if t:
+ t.close()
+ instdir=tempfile.mkdtemp('.inst',self.get_base_name())
+ ret=Utils.subprocess.Popen([sys.argv[0],'configure','install','uninstall','--destdir='+instdir],cwd=self.get_base_name()).wait()
+ if ret:
+ raise Errors.WafError('distcheck failed with code %i'%ret)
+ if os.path.exists(instdir):
+ raise Errors.WafError('distcheck succeeded, but files were left in %s'%instdir)
+ shutil.rmtree(self.get_base_name())
+def distcheck(ctx):
+ '''checks if the project compiles (tarball from 'dist')'''
+ pass
+def update(ctx):
+ '''updates the plugins from the *waflib/extras* directory'''
+ lst=Options.options.files.split(',')
+ if not lst:
+ lst=[x for x in Utils.listdir(Context.waf_dir+'/waflib/extras')if x.endswith('.py')]
+ for x in lst:
+ tool=x.replace('.py','')
+ try:
+ Configure.download_tool(tool,force=True,ctx=ctx)
+ except Errors.WafError:
+ Logs.error('Could not find the tool %s in the remote repository'%x)
+def autoconfigure(execute_method):
+ def execute(self):
+ if not Configure.autoconfig:
+ return execute_method(self)
+ env=ConfigSet.ConfigSet()
+ do_config=False
+ try:
+ env.load(os.path.join(Context.top_dir,Options.lockfile))
+ except Exception:
+ Logs.warn('Configuring the project')
+ do_config=True
+ else:
+ if env.run_dir!=Context.run_dir:
+ do_config=True
+ else:
+ h=0
+ for f in env['files']:
+ h=hash((h,Utils.readf(f,'rb')))
+ do_config=h!=env.hash
+ if do_config:
+ Options.commands.insert(0,self.cmd)
+ Options.commands.insert(0,'configure')
+ return
+ return execute_method(self)
+ return execute
+Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute)
diff --git a/waflib/Task.py b/waflib/Task.py
new file mode 100644
index 0000000..1678a10
--- /dev/null
+++ b/waflib/Task.py
@@ -0,0 +1,672 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+import os,shutil,re,tempfile
+from waflib import Utils,Logs,Errors
+NOT_RUN=0
+MISSING=1
+CRASHED=2
+EXCEPTION=3
+SKIPPED=8
+SUCCESS=9
+ASK_LATER=-1
+SKIP_ME=-2
+RUN_ME=-3
+COMPILE_TEMPLATE_SHELL='''
+def f(tsk):
+ env = tsk.env
+ gen = tsk.generator
+ bld = gen.bld
+ wd = getattr(tsk, 'cwd', None)
+ p = env.get_flat
+ tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s
+ return tsk.exec_command(cmd, cwd=wd, env=env.env or None)
+'''
+COMPILE_TEMPLATE_NOSHELL='''
+def f(tsk):
+ env = tsk.env
+ gen = tsk.generator
+ bld = gen.bld
+ wd = getattr(tsk, 'cwd', None)
+ def to_list(xx):
+ if isinstance(xx, str): return [xx]
+ return xx
+ tsk.last_cmd = lst = []
+ %s
+ lst = [x for x in lst if x]
+ return tsk.exec_command(lst, cwd=wd, env=env.env or None)
+'''
+def cache_outputs(cls):
+ m1=cls.run
+ def run(self):
+ bld=self.generator.bld
+ if bld.cache_global and not bld.nocache:
+ if self.can_retrieve_cache():
+ return 0
+ return m1(self)
+ cls.run=run
+ m2=cls.post_run
+ def post_run(self):
+ bld=self.generator.bld
+ ret=m2(self)
+ if bld.cache_global and not bld.nocache:
+ self.put_files_cache()
+ return ret
+ cls.post_run=post_run
+ return cls
+classes={}
+class store_task_type(type):
+ def __init__(cls,name,bases,dict):
+ super(store_task_type,cls).__init__(name,bases,dict)
+ name=cls.__name__
+ if name.endswith('_task'):
+ name=name.replace('_task','')
+ if name!='evil'and name!='TaskBase':
+ global classes
+ if getattr(cls,'run_str',None):
+ (f,dvars)=compile_fun(cls.run_str,cls.shell)
+ cls.hcode=cls.run_str
+ cls.run_str=None
+ cls.run=f
+ cls.vars=list(set(cls.vars+dvars))
+ cls.vars.sort()
+ elif getattr(cls,'run',None)and not'hcode'in cls.__dict__:
+ cls.hcode=Utils.h_fun(cls.run)
+ if not getattr(cls,'nocache',None):
+ cls=cache_outputs(cls)
+ classes[name]=cls
+evil=store_task_type('evil',(object,),{})
+class TaskBase(evil):
+ color='GREEN'
+ ext_in=[]
+ ext_out=[]
+ before=[]
+ after=[]
+ hcode=''
+ def __init__(self,*k,**kw):
+ self.hasrun=NOT_RUN
+ try:
+ self.generator=kw['generator']
+ except KeyError:
+ self.generator=self
+ def __repr__(self):
+ return'\n\t{task %r: %s %s}'%(self.__class__.__name__,id(self),str(getattr(self,'fun','')))
+ def __str__(self):
+ if hasattr(self,'fun'):
+ return'executing: %s\n'%self.fun.__name__
+ return self.__class__.__name__+'\n'
+ def __hash__(self):
+ return id(self)
+ def exec_command(self,cmd,**kw):
+ bld=self.generator.bld
+ try:
+ if not kw.get('cwd',None):
+ kw['cwd']=bld.cwd
+ except AttributeError:
+ bld.cwd=kw['cwd']=bld.variant_dir
+ return bld.exec_command(cmd,**kw)
+ def runnable_status(self):
+ return RUN_ME
+ def process(self):
+ m=self.master
+ if m.stop:
+ m.out.put(self)
+ return
+ try:
+ del self.generator.bld.task_sigs[self.uid()]
+ except:
+ pass
+ try:
+ self.generator.bld.returned_tasks.append(self)
+ self.log_display(self.generator.bld)
+ ret=self.run()
+ except Exception:
+ self.err_msg=Utils.ex_stack()
+ self.hasrun=EXCEPTION
+ m.error_handler(self)
+ m.out.put(self)
+ return
+ if ret:
+ self.err_code=ret
+ self.hasrun=CRASHED
+ else:
+ try:
+ self.post_run()
+ except Errors.WafError:
+ pass
+ except Exception:
+ self.err_msg=Utils.ex_stack()
+ self.hasrun=EXCEPTION
+ else:
+ self.hasrun=SUCCESS
+ if self.hasrun!=SUCCESS:
+ m.error_handler(self)
+ m.out.put(self)
+ def run(self):
+ if hasattr(self,'fun'):
+ return self.fun(self)
+ return 0
+ def post_run(self):
+ pass
+ def log_display(self,bld):
+ bld.to_log(self.display())
+ def display(self):
+ col1=Logs.colors(self.color)
+ col2=Logs.colors.NORMAL
+ master=self.master
+ def cur():
+ tmp=-1
+ if hasattr(master,'ready'):
+ tmp-=master.ready.qsize()
+ return master.processed+tmp
+ if self.generator.bld.progress_bar==1:
+ return self.generator.bld.progress_line(cur(),master.total,col1,col2)
+ if self.generator.bld.progress_bar==2:
+ ela=str(self.generator.bld.timer)
+ try:
+ ins=','.join([n.name for n in self.inputs])
+ except AttributeError:
+ ins=''
+ try:
+ outs=','.join([n.name for n in self.outputs])
+ except AttributeError:
+ outs=''
+ return'|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n'%(master.total,cur(),ins,outs,ela)
+ s=str(self)
+ if not s:
+ return None
+ total=master.total
+ n=len(str(total))
+ fs='[%%%dd/%%%dd] %%s%%s%%s'%(n,n)
+ return fs%(cur(),total,col1,s,col2)
+ def attr(self,att,default=None):
+ ret=getattr(self,att,self)
+ if ret is self:return getattr(self.__class__,att,default)
+ return ret
+ def hash_constraints(self):
+ cls=self.__class__
+ tup=(str(cls.before),str(cls.after),str(cls.ext_in),str(cls.ext_out),cls.__name__,cls.hcode)
+ h=hash(tup)
+ return h
+ def format_error(self):
+ msg=getattr(self,'last_cmd','')
+ name=getattr(self.generator,'name','')
+ if getattr(self,"err_msg",None):
+ return self.err_msg
+ elif not self.hasrun:
+ return'task in %r was not executed for some reason: %r'%(name,self)
+ elif self.hasrun==CRASHED:
+ try:
+ return' -> task in %r failed (exit status %r): %r\n%r'%(name,self.err_code,self,msg)
+ except AttributeError:
+ return' -> task in %r failed: %r\n%r'%(name,self,msg)
+ elif self.hasrun==MISSING:
+ return' -> missing files in %r: %r\n%r'%(name,self,msg)
+ else:
+ return'invalid status for task in %r: %r'%(name,self.hasrun)
+ def colon(self,var1,var2):
+ tmp=self.env[var1]
+ if isinstance(var2,str):
+ it=self.env[var2]
+ else:
+ it=var2
+ if isinstance(tmp,str):
+ return[tmp%x for x in it]
+ else:
+ if Logs.verbose and not tmp and it:
+ Logs.warn('Missing env variable %r for task %r (generator %r)'%(var1,self,self.generator))
+ lst=[]
+ for y in it:
+ lst.extend(tmp)
+ lst.append(y)
+ return lst
+class Task(TaskBase):
+ vars=[]
+ shell=False
+ def __init__(self,*k,**kw):
+ TaskBase.__init__(self,*k,**kw)
+ self.env=kw['env']
+ self.inputs=[]
+ self.outputs=[]
+ self.dep_nodes=[]
+ self.run_after=set([])
+ def __str__(self):
+ env=self.env
+ src_str=' '.join([a.nice_path(env)for a in self.inputs])
+ tgt_str=' '.join([a.nice_path(env)for a in self.outputs])
+ if self.outputs:sep=' -> '
+ else:sep=''
+ return'%s: %s%s%s\n'%(self.__class__.__name__.replace('_task',''),src_str,sep,tgt_str)
+ def __repr__(self):
+ return"".join(['\n\t{task %r: '%id(self),self.__class__.__name__," ",",".join([x.name for x in self.inputs])," -> ",",".join([x.name for x in self.outputs]),'}'])
+ def uid(self):
+ try:
+ return self.uid_
+ except AttributeError:
+ m=Utils.md5()
+ up=m.update
+ up(self.__class__.__name__)
+ for x in self.inputs+self.outputs:
+ up(x.abspath())
+ self.uid_=m.digest()
+ return self.uid_
+ def set_inputs(self,inp):
+ if isinstance(inp,list):self.inputs+=inp
+ else:self.inputs.append(inp)
+ def set_outputs(self,out):
+ if isinstance(out,list):self.outputs+=out
+ else:self.outputs.append(out)
+ def set_run_after(self,task):
+ assert isinstance(task,TaskBase)
+ self.run_after.add(task)
+ def signature(self):
+ try:return self.cache_sig
+ except AttributeError:pass
+ self.m=Utils.md5()
+ self.m.update(self.hcode)
+ self.sig_explicit_deps()
+ self.sig_vars()
+ if self.scan:
+ try:
+ self.sig_implicit_deps()
+ except Errors.TaskRescan:
+ return self.signature()
+ ret=self.cache_sig=self.m.digest()
+ return ret
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return ASK_LATER
+ bld=self.generator.bld
+ try:
+ new_sig=self.signature()
+ except Errors.TaskNotReady:
+ return ASK_LATER
+ key=self.uid()
+ try:
+ prev_sig=bld.task_sigs[key]
+ except KeyError:
+ Logs.debug("task: task %r must run as it was never run before or the task code changed"%self)
+ return RUN_ME
+ for node in self.outputs:
+ try:
+ if node.sig!=new_sig:
+ return RUN_ME
+ except AttributeError:
+ Logs.debug("task: task %r must run as the output nodes do not exist"%self)
+ return RUN_ME
+ if new_sig!=prev_sig:
+ return RUN_ME
+ return SKIP_ME
+ def post_run(self):
+ bld=self.generator.bld
+ sig=self.signature()
+ for node in self.outputs:
+ try:
+ os.stat(node.abspath())
+ except OSError:
+ self.hasrun=MISSING
+ self.err_msg='-> missing file: %r'%node.abspath()
+ raise Errors.WafError(self.err_msg)
+ node.sig=sig
+ bld.task_sigs[self.uid()]=self.cache_sig
+ def sig_explicit_deps(self):
+ bld=self.generator.bld
+ upd=self.m.update
+ for x in self.inputs+self.dep_nodes:
+ try:
+ upd(x.get_bld_sig())
+ except(AttributeError,TypeError):
+ raise Errors.WafError('Missing node signature for %r (required by %r)'%(x,self))
+ if bld.deps_man:
+ additional_deps=bld.deps_man
+ for x in self.inputs+self.outputs:
+ try:
+ d=additional_deps[id(x)]
+ except KeyError:
+ continue
+ for v in d:
+ if isinstance(v,bld.root.__class__):
+ try:
+ v=v.get_bld_sig()
+ except AttributeError:
+ raise Errors.WafError('Missing node signature for %r (required by %r)'%(v,self))
+ elif hasattr(v,'__call__'):
+ v=v()
+ upd(v)
+ return self.m.digest()
+ def sig_vars(self):
+ bld=self.generator.bld
+ env=self.env
+ upd=self.m.update
+ act_sig=bld.hash_env_vars(env,self.__class__.vars)
+ upd(act_sig)
+ dep_vars=getattr(self,'dep_vars',None)
+ if dep_vars:
+ upd(bld.hash_env_vars(env,dep_vars))
+ return self.m.digest()
+ scan=None
+ def sig_implicit_deps(self):
+ bld=self.generator.bld
+ key=self.uid()
+ prev=bld.task_sigs.get((key,'imp'),[])
+ if prev:
+ try:
+ if prev==self.compute_sig_implicit_deps():
+ return prev
+ except:
+ for x in bld.node_deps.get(self.uid(),[]):
+ if x.is_child_of(bld.srcnode):
+ try:
+ os.stat(x.abspath())
+ except:
+ try:
+ del x.parent.children[x.name]
+ except:
+ pass
+ del bld.task_sigs[(key,'imp')]
+ raise Errors.TaskRescan('rescan')
+ (nodes,names)=self.scan()
+ if Logs.verbose:
+ Logs.debug('deps: scanner for %s returned %s %s'%(str(self),str(nodes),str(names)))
+ bld.node_deps[key]=nodes
+ bld.raw_deps[key]=names
+ self.are_implicit_nodes_ready()
+ try:
+ bld.task_sigs[(key,'imp')]=sig=self.compute_sig_implicit_deps()
+ except:
+ if Logs.verbose:
+ for k in bld.node_deps.get(self.uid(),[]):
+ try:
+ k.get_bld_sig()
+ except:
+ Logs.warn('Missing signature for node %r (may cause rebuilds)'%k)
+ else:
+ return sig
+ def compute_sig_implicit_deps(self):
+ upd=self.m.update
+ bld=self.generator.bld
+ self.are_implicit_nodes_ready()
+ for k in bld.node_deps.get(self.uid(),[]):
+ upd(k.get_bld_sig())
+ return self.m.digest()
+ def are_implicit_nodes_ready(self):
+ bld=self.generator.bld
+ try:
+ cache=bld.dct_implicit_nodes
+ except:
+ bld.dct_implicit_nodes=cache={}
+ try:
+ dct=cache[bld.cur]
+ except KeyError:
+ dct=cache[bld.cur]={}
+ for tsk in bld.cur_tasks:
+ for x in tsk.outputs:
+ dct[x]=tsk
+ modified=False
+ for x in bld.node_deps.get(self.uid(),[]):
+ if x in dct:
+ self.run_after.add(dct[x])
+ modified=True
+ if modified:
+ for tsk in self.run_after:
+ if not tsk.hasrun:
+ raise Errors.TaskNotReady('not ready')
+ def can_retrieve_cache(self):
+ if not getattr(self,'outputs',None):
+ return None
+ sig=self.signature()
+ ssig=Utils.to_hex(self.uid())+Utils.to_hex(sig)
+ dname=os.path.join(self.generator.bld.cache_global,ssig)
+ try:
+ t1=os.stat(dname).st_mtime
+ except OSError:
+ return None
+ for node in self.outputs:
+ orig=os.path.join(dname,node.name)
+ try:
+ shutil.copy2(orig,node.abspath())
+ os.utime(orig,None)
+ except(OSError,IOError):
+ Logs.debug('task: failed retrieving file')
+ return None
+ try:
+ t2=os.stat(dname).st_mtime
+ except OSError:
+ return None
+ if t1!=t2:
+ return None
+ for node in self.outputs:
+ node.sig=sig
+ if self.generator.bld.progress_bar<1:
+ self.generator.bld.to_log('restoring from cache %r\n'%node.abspath())
+ self.cached=True
+ return True
+ def put_files_cache(self):
+ if getattr(self,'cached',None):
+ return None
+ if not getattr(self,'outputs',None):
+ return None
+ sig=self.signature()
+ ssig=Utils.to_hex(self.uid())+Utils.to_hex(sig)
+ dname=os.path.join(self.generator.bld.cache_global,ssig)
+ tmpdir=tempfile.mkdtemp(prefix=self.generator.bld.cache_global+os.sep+'waf')
+ try:
+ shutil.rmtree(dname)
+ except:
+ pass
+ try:
+ for node in self.outputs:
+ dest=os.path.join(tmpdir,node.name)
+ shutil.copy2(node.abspath(),dest)
+ except(OSError,IOError):
+ try:
+ shutil.rmtree(tmpdir)
+ except:
+ pass
+ else:
+ try:
+ os.rename(tmpdir,dname)
+ except OSError:
+ try:
+ shutil.rmtree(tmpdir)
+ except:
+ pass
+ else:
+ try:
+ os.chmod(dname,Utils.O755)
+ except:
+ pass
+def is_before(t1,t2):
+ to_list=Utils.to_list
+ for k in to_list(t2.ext_in):
+ if k in to_list(t1.ext_out):
+ return 1
+ if t1.__class__.__name__ in to_list(t2.after):
+ return 1
+ if t2.__class__.__name__ in to_list(t1.before):
+ return 1
+ return 0
+def set_file_constraints(tasks):
+ ins=Utils.defaultdict(set)
+ outs=Utils.defaultdict(set)
+ for x in tasks:
+ for a in getattr(x,'inputs',[])+getattr(x,'dep_nodes',[]):
+ ins[id(a)].add(x)
+ for a in getattr(x,'outputs',[]):
+ outs[id(a)].add(x)
+ links=set(ins.keys()).intersection(outs.keys())
+ for k in links:
+ for a in ins[k]:
+ a.run_after.update(outs[k])
+def set_precedence_constraints(tasks):
+ cstr_groups=Utils.defaultdict(list)
+ for x in tasks:
+ h=x.hash_constraints()
+ cstr_groups[h].append(x)
+ keys=list(cstr_groups.keys())
+ maxi=len(keys)
+ for i in range(maxi):
+ t1=cstr_groups[keys[i]][0]
+ for j in range(i+1,maxi):
+ t2=cstr_groups[keys[j]][0]
+ if is_before(t1,t2):
+ a=i
+ b=j
+ elif is_before(t2,t1):
+ a=j
+ b=i
+ else:
+ continue
+ for x in cstr_groups[keys[b]]:
+ x.run_after.update(cstr_groups[keys[a]])
+def funex(c):
+ dc={}
+ exec(c,dc)
+ return dc['f']
+reg_act=re.compile(r"(?P<backslash>\\)|(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})",re.M)
+def compile_fun_shell(line):
+ extr=[]
+ def repl(match):
+ g=match.group
+ if g('dollar'):return"$"
+ elif g('backslash'):return'\\\\'
+ elif g('subst'):extr.append((g('var'),g('code')));return"%s"
+ return None
+ line=reg_act.sub(repl,line)or line
+ parm=[]
+ dvars=[]
+ app=parm.append
+ for(var,meth)in extr:
+ if var=='SRC':
+ if meth:app('tsk.inputs%s'%meth)
+ else:app('" ".join([a.path_from(bld.bldnode) for a in tsk.inputs])')
+ elif var=='TGT':
+ if meth:app('tsk.outputs%s'%meth)
+ else:app('" ".join([a.path_from(bld.bldnode) for a in tsk.outputs])')
+ elif meth:
+ if meth.startswith(':'):
+ m=meth[1:]
+ if m=='SRC':
+ m='[a.path_from(bld.bldnode) for a in tsk.inputs]'
+ elif m=='TGT':
+ m='[a.path_from(bld.bldnode) for a in tsk.outputs]'
+ elif m[:3]not in('tsk','gen','bld'):
+ dvars.extend([var,meth[1:]])
+ m='%r'%m
+ app('" ".join(tsk.colon(%r, %s))'%(var,m))
+ else:
+ app('%s%s'%(var,meth))
+ else:
+ if not var in dvars:dvars.append(var)
+ app("p('%s')"%var)
+ if parm:parm="%% (%s) "%(',\n\t\t'.join(parm))
+ else:parm=''
+ c=COMPILE_TEMPLATE_SHELL%(line,parm)
+ Logs.debug('action: %s'%c)
+ return(funex(c),dvars)
+def compile_fun_noshell(line):
+ extr=[]
+ def repl(match):
+ g=match.group
+ if g('dollar'):return"$"
+ elif g('subst'):extr.append((g('var'),g('code')));return"<<|@|>>"
+ return None
+ line2=reg_act.sub(repl,line)
+ params=line2.split('<<|@|>>')
+ assert(extr)
+ buf=[]
+ dvars=[]
+ app=buf.append
+ for x in range(len(extr)):
+ params[x]=params[x].strip()
+ if params[x]:
+ app("lst.extend(%r)"%params[x].split())
+ (var,meth)=extr[x]
+ if var=='SRC':
+ if meth:app('lst.append(tsk.inputs%s)'%meth)
+ else:app("lst.extend([a.path_from(bld.bldnode) for a in tsk.inputs])")
+ elif var=='TGT':
+ if meth:app('lst.append(tsk.outputs%s)'%meth)
+ else:app("lst.extend([a.path_from(bld.bldnode) for a in tsk.outputs])")
+ elif meth:
+ if meth.startswith(':'):
+ m=meth[1:]
+ if m=='SRC':
+ m='[a.path_from(bld.bldnode) for a in tsk.inputs]'
+ elif m=='TGT':
+ m='[a.path_from(bld.bldnode) for a in tsk.outputs]'
+ elif m[:3]not in('tsk','gen','bld'):
+ dvars.extend([var,m])
+ m='%r'%m
+ app('lst.extend(tsk.colon(%r, %s))'%(var,m))
+ else:
+ app('lst.extend(gen.to_list(%s%s))'%(var,meth))
+ else:
+ app('lst.extend(to_list(env[%r]))'%var)
+ if not var in dvars:dvars.append(var)
+ if extr:
+ if params[-1]:
+ app("lst.extend(%r)"%params[-1].split())
+ fun=COMPILE_TEMPLATE_NOSHELL%"\n\t".join(buf)
+ Logs.debug('action: %s'%fun)
+ return(funex(fun),dvars)
+def compile_fun(line,shell=False):
+ if line.find('<')>0 or line.find('>')>0 or line.find('&&')>0:
+ shell=True
+ if shell:
+ return compile_fun_shell(line)
+ else:
+ return compile_fun_noshell(line)
+def task_factory(name,func=None,vars=None,color='GREEN',ext_in=[],ext_out=[],before=[],after=[],shell=False,scan=None):
+ params={'vars':vars or[],'color':color,'name':name,'ext_in':Utils.to_list(ext_in),'ext_out':Utils.to_list(ext_out),'before':Utils.to_list(before),'after':Utils.to_list(after),'shell':shell,'scan':scan,}
+ if isinstance(func,str):
+ params['run_str']=func
+ else:
+ params['run']=func
+ cls=type(Task)(name,(Task,),params)
+ global classes
+ classes[name]=cls
+ return cls
+def always_run(cls):
+ old=cls.runnable_status
+ def always(self):
+ ret=old(self)
+ if ret==SKIP_ME:
+ ret=RUN_ME
+ return ret
+ cls.runnable_status=always
+ return cls
+def update_outputs(cls):
+ old_post_run=cls.post_run
+ def post_run(self):
+ old_post_run(self)
+ for node in self.outputs:
+ node.sig=Utils.h_file(node.abspath())
+ self.generator.bld.task_sigs[node.abspath()]=self.uid()
+ cls.post_run=post_run
+ old_runnable_status=cls.runnable_status
+ def runnable_status(self):
+ status=old_runnable_status(self)
+ if status!=RUN_ME:
+ return status
+ try:
+ bld=self.generator.bld
+ prev_sig=bld.task_sigs[self.uid()]
+ if prev_sig==self.signature():
+ for x in self.outputs:
+ if not x.sig or bld.task_sigs[x.abspath()]!=self.uid():
+ return RUN_ME
+ return SKIP_ME
+ except KeyError:
+ pass
+ except IndexError:
+ pass
+ except AttributeError:
+ pass
+ return RUN_ME
+ cls.runnable_status=runnable_status
+ return cls
diff --git a/waflib/TaskGen.py b/waflib/TaskGen.py
new file mode 100644
index 0000000..8d8f26d
--- /dev/null
+++ b/waflib/TaskGen.py
@@ -0,0 +1,353 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+import copy,re,os
+from waflib import Task,Utils,Logs,Errors,ConfigSet
+feats=Utils.defaultdict(set)
+class task_gen(object):
+ mappings={}
+ prec=Utils.defaultdict(list)
+ def __init__(self,*k,**kw):
+ self.source=''
+ self.target=''
+ self.meths=[]
+ self.prec=Utils.defaultdict(list)
+ self.mappings={}
+ self.features=[]
+ self.tasks=[]
+ if not'bld'in kw:
+ self.env=ConfigSet.ConfigSet()
+ self.idx=0
+ self.path=None
+ else:
+ self.bld=kw['bld']
+ self.env=self.bld.env.derive()
+ self.path=self.bld.path
+ try:
+ self.idx=self.bld.idx[id(self.path)]=self.bld.idx.get(id(self.path),0)+1
+ except AttributeError:
+ self.bld.idx={}
+ self.idx=self.bld.idx[id(self.path)]=1
+ for key,val in kw.items():
+ setattr(self,key,val)
+ def __str__(self):
+ return"<task_gen %r declared in %s>"%(self.name,self.path.abspath())
+ def __repr__(self):
+ lst=[]
+ for x in self.__dict__.keys():
+ if x not in['env','bld','compiled_tasks','tasks']:
+ lst.append("%s=%s"%(x,repr(getattr(self,x))))
+ return"bld(%s) in %s"%(", ".join(lst),self.path.abspath())
+ def get_name(self):
+ try:
+ return self._name
+ except AttributeError:
+ if isinstance(self.target,list):
+ lst=[str(x)for x in self.target]
+ name=self._name=','.join(lst)
+ else:
+ name=self._name=str(self.target)
+ return name
+ def set_name(self,name):
+ self._name=name
+ name=property(get_name,set_name)
+ def to_list(self,val):
+ if isinstance(val,str):return val.split()
+ else:return val
+ def post(self):
+ if getattr(self,'posted',None):
+ return False
+ self.posted=True
+ keys=set(self.meths)
+ self.features=Utils.to_list(self.features)
+ for x in self.features+['*']:
+ st=feats[x]
+ if not st:
+ if not x in Task.classes:
+ Logs.warn('feature %r does not exist - bind at least one method to it'%x)
+ keys.update(list(st))
+ prec={}
+ prec_tbl=self.prec or task_gen.prec
+ for x in prec_tbl:
+ if x in keys:
+ prec[x]=prec_tbl[x]
+ tmp=[]
+ for a in keys:
+ for x in prec.values():
+ if a in x:break
+ else:
+ tmp.append(a)
+ out=[]
+ while tmp:
+ e=tmp.pop()
+ if e in keys:out.append(e)
+ try:
+ nlst=prec[e]
+ except KeyError:
+ pass
+ else:
+ del prec[e]
+ for x in nlst:
+ for y in prec:
+ if x in prec[y]:
+ break
+ else:
+ tmp.append(x)
+ if prec:
+ raise Errors.WafError('Cycle detected in the method execution %r'%prec)
+ out.reverse()
+ self.meths=out
+ Logs.debug('task_gen: posting %s %d'%(self,id(self)))
+ for x in out:
+ try:
+ v=getattr(self,x)
+ except AttributeError:
+ raise Errors.WafError('%r is not a valid task generator method'%x)
+ Logs.debug('task_gen: -> %s (%d)'%(x,id(self)))
+ v()
+ Logs.debug('task_gen: posted %s'%self.name)
+ return True
+ def get_hook(self,node):
+ name=node.name
+ for k in self.mappings:
+ if name.endswith(k):
+ return self.mappings[k]
+ for k in task_gen.mappings:
+ if name.endswith(k):
+ return task_gen.mappings[k]
+ raise Errors.WafError("File %r has no mapping in %r (did you forget to load a waf tool?)"%(node,task_gen.mappings.keys()))
+ def create_task(self,name,src=None,tgt=None):
+ task=Task.classes[name](env=self.env.derive(),generator=self)
+ if src:
+ task.set_inputs(src)
+ if tgt:
+ task.set_outputs(tgt)
+ self.tasks.append(task)
+ return task
+ def clone(self,env):
+ newobj=self.bld()
+ for x in self.__dict__:
+ if x in['env','bld']:
+ continue
+ elif x in['path','features']:
+ setattr(newobj,x,getattr(self,x))
+ else:
+ setattr(newobj,x,copy.copy(getattr(self,x)))
+ newobj.posted=False
+ if isinstance(env,str):
+ newobj.env=self.bld.all_envs[env].derive()
+ else:
+ newobj.env=env.derive()
+ return newobj
+def declare_chain(name='',rule=None,reentrant=None,color='BLUE',ext_in=[],ext_out=[],before=[],after=[],decider=None,scan=None,install_path=None,shell=False):
+ ext_in=Utils.to_list(ext_in)
+ ext_out=Utils.to_list(ext_out)
+ if not name:
+ name=rule
+ cls=Task.task_factory(name,rule,color=color,ext_in=ext_in,ext_out=ext_out,before=before,after=after,scan=scan,shell=shell)
+ def x_file(self,node):
+ ext=decider and decider(self,node)or cls.ext_out
+ if ext_in:
+ _ext_in=ext_in[0]
+ tsk=self.create_task(name,node)
+ cnt=0
+ keys=self.mappings.keys()+self.__class__.mappings.keys()
+ for x in ext:
+ k=node.change_ext(x,ext_in=_ext_in)
+ tsk.outputs.append(k)
+ if reentrant!=None:
+ if cnt<int(reentrant):
+ self.source.append(k)
+ else:
+ for y in keys:
+ if k.name.endswith(y):
+ self.source.append(k)
+ break
+ cnt+=1
+ if install_path:
+ self.bld.install_files(install_path,tsk.outputs)
+ return tsk
+ for x in cls.ext_in:
+ task_gen.mappings[x]=x_file
+ return x_file
+def taskgen_method(func):
+ setattr(task_gen,func.__name__,func)
+ return func
+def feature(*k):
+ def deco(func):
+ setattr(task_gen,func.__name__,func)
+ for name in k:
+ feats[name].update([func.__name__])
+ return func
+ return deco
+def before_method(*k):
+ def deco(func):
+ setattr(task_gen,func.__name__,func)
+ for fun_name in k:
+ if not func.__name__ in task_gen.prec[fun_name]:
+ task_gen.prec[fun_name].append(func.__name__)
+ return func
+ return deco
+before=before_method
+def after_method(*k):
+ def deco(func):
+ setattr(task_gen,func.__name__,func)
+ for fun_name in k:
+ if not fun_name in task_gen.prec[func.__name__]:
+ task_gen.prec[func.__name__].append(fun_name)
+ return func
+ return deco
+after=after_method
+def extension(*k):
+ def deco(func):
+ setattr(task_gen,func.__name__,func)
+ for x in k:
+ task_gen.mappings[x]=func
+ return func
+ return deco
+def to_nodes(self,lst,path=None):
+ tmp=[]
+ path=path or self.path
+ find=path.find_resource
+ if isinstance(lst,self.path.__class__):
+ lst=[lst]
+ for x in Utils.to_list(lst):
+ if isinstance(x,str):
+ node=find(x)
+ else:
+ node=x
+ if not node:
+ raise Errors.WafError("source not found: %r in %r"%(x,self))
+ tmp.append(node)
+ return tmp
+def process_source(self):
+ self.source=self.to_nodes(getattr(self,'source',[]))
+ for node in self.source:
+ self.get_hook(node)(self,node)
+def process_rule(self):
+ if not getattr(self,'rule',None):
+ return
+ name=str(getattr(self,'name',None)or self.target or self.rule)
+ cls=Task.task_factory(name,self.rule,getattr(self,'vars',[]),shell=getattr(self,'shell',True),color=getattr(self,'color','BLUE'))
+ tsk=self.create_task(name)
+ if getattr(self,'target',None):
+ if isinstance(self.target,str):
+ self.target=self.target.split()
+ if not isinstance(self.target,list):
+ self.target=[self.target]
+ for x in self.target:
+ if isinstance(x,str):
+ tsk.outputs.append(self.path.find_or_declare(x))
+ else:
+ x.parent.mkdir()
+ tsk.outputs.append(x)
+ if getattr(self,'install_path',None):
+ self.bld.install_files(self.install_path,tsk.outputs)
+ if getattr(self,'source',None):
+ tsk.inputs=self.to_nodes(self.source)
+ self.source=[]
+ if getattr(self,'scan',None):
+ cls.scan=self.scan
+ elif getattr(self,'deps',None):
+ def scan(self):
+ nodes=[]
+ for x in self.generator.to_list(self.generator.deps):
+ node=self.generator.path.find_resource(x)
+ if not node:
+ self.generator.bld.fatal('Could not find %r (was it declared?)'%x)
+ nodes.append(node)
+ return[nodes,[]]
+ cls.scan=scan
+ if getattr(self,'cwd',None):
+ tsk.cwd=self.cwd
+ if getattr(self,'update_outputs',None)or getattr(self,'on_results',None):
+ Task.update_outputs(cls)
+ if getattr(self,'always',None):
+ Task.always_run(cls)
+ for x in['after','before','ext_in','ext_out']:
+ setattr(cls,x,getattr(self,x,[]))
+def sequence_order(self):
+ if self.meths and self.meths[-1]!='sequence_order':
+ self.meths.append('sequence_order')
+ return
+ if getattr(self,'seq_start',None):
+ return
+ if getattr(self.bld,'prev',None):
+ self.bld.prev.post()
+ for x in self.bld.prev.tasks:
+ for y in self.tasks:
+ y.set_run_after(x)
+ self.bld.prev=self
+re_m4=re.compile('@(\w+)@',re.M)
+class subst_pc(Task.Task):
+ def run(self):
+ code=self.inputs[0].read()
+ code=code.replace('%','%%')
+ lst=[]
+ def repl(match):
+ g=match.group
+ if g(1):
+ lst.append(g(1))
+ return"%%(%s)s"%g(1)
+ return''
+ code=re_m4.sub(repl,code)
+ try:
+ d=self.generator.dct
+ except AttributeError:
+ d={}
+ for x in lst:
+ tmp=getattr(self.generator,x,'')or self.env.get_flat(x)or self.env.get_flat(x.upper())
+ d[x]=str(tmp)
+ self.outputs[0].write(code%d)
+ self.generator.bld.raw_deps[self.uid()]=self.dep_vars=lst
+ try:delattr(self,'cache_sig')
+ except AttributeError:pass
+ if getattr(self.generator,'chmod',None):
+ os.chmod(self.outputs[0].abspath(),self.generator.chmod)
+ def sig_vars(self):
+ bld=self.generator.bld
+ env=self.env
+ upd=self.m.update
+ vars=self.generator.bld.raw_deps.get(self.uid(),[])
+ act_sig=bld.hash_env_vars(env,vars)
+ upd(act_sig)
+ lst=[getattr(self.generator,x,'')for x in vars]
+ upd(Utils.h_list(lst))
+ return self.m.digest()
+def add_pcfile(self,node):
+ tsk=self.create_task('subst_pc',node,node.change_ext('.pc','.pc.in'))
+ self.bld.install_files(getattr(self,'install_path','${LIBDIR}/pkgconfig/'),tsk.outputs)
+class subst(subst_pc):
+ pass
+def process_subst(self):
+ src=self.to_nodes(getattr(self,'source',[]))
+ tgt=getattr(self,'target',[])
+ if isinstance(tgt,self.path.__class__):
+ tgt=[tgt]
+ tgt=[isinstance(x,self.path.__class__)and x or self.path.find_or_declare(x)for x in Utils.to_list(tgt)]
+ if len(src)!=len(tgt):
+ raise Errors.WafError('invalid source or target for %r'%self)
+ for x,y in zip(src,tgt):
+ if not(x and y):
+ raise Errors.WafError('invalid source or target for %r'%self)
+ tsk=self.create_task('subst',x,y)
+ for a in('after','before','ext_in','ext_out'):
+ val=getattr(self,a,None)
+ if val:
+ setattr(tsk,a,val)
+ inst_to=getattr(self,'install_path',None)
+ if inst_to:
+ self.bld.install_files(inst_to,tgt,chmod=getattr(self,'chmod',Utils.O644))
+ self.source=[]
+
+taskgen_method(to_nodes)
+feature('*')(process_source)
+feature('*')(process_rule)
+before_method('process_source')(process_rule)
+feature('seq')(sequence_order)
+extension('.pc.in')(add_pcfile)
+feature('subst')(process_subst)
+before_method('process_source','process_rule')(process_subst) \ No newline at end of file
diff --git a/waflib/Tools/__init__.py b/waflib/Tools/__init__.py
new file mode 100644
index 0000000..efeed79
--- /dev/null
+++ b/waflib/Tools/__init__.py
@@ -0,0 +1,4 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
diff --git a/waflib/Tools/ar.py b/waflib/Tools/ar.py
new file mode 100644
index 0000000..fd0b7d5
--- /dev/null
+++ b/waflib/Tools/ar.py
@@ -0,0 +1,12 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.Configure import conf
+def find_ar(conf):
+ conf.load('ar')
+def configure(conf):
+ conf.find_program('ar',var='AR')
+ conf.env.ARFLAGS='rcs'
+
+conf(find_ar) \ No newline at end of file
diff --git a/waflib/Tools/asm.py b/waflib/Tools/asm.py
new file mode 100644
index 0000000..d78dff5
--- /dev/null
+++ b/waflib/Tools/asm.py
@@ -0,0 +1,25 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Task,Utils
+import waflib.Task
+from waflib.Tools.ccroot import link_task,stlink_task
+from waflib.TaskGen import extension,feature
+class asm(Task.Task):
+ color='BLUE'
+ run_str='${AS} ${ASFLAGS} ${CPPPATH_ST:INCPATHS} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}'
+def asm_hook(self,node):
+ return self.create_compiled_task('asm',node)
+class asmprogram(link_task):
+ run_str='${ASLINK} ${ASLINKFLAGS} ${ASLNK_TGT_F}${TGT} ${ASLNK_SRC_F}${SRC}'
+ ext_out=['.bin']
+ inst_to='${BINDIR}'
+ chmod=Utils.O755
+class asmshlib(asmprogram):
+ inst_to='${LIBDIR}'
+class asmstlib(stlink_task):
+ pass
+
+extension('.s','.S','.asm','.ASM','.spp','.SPP')(asm_hook) \ No newline at end of file
diff --git a/waflib/Tools/bison.py b/waflib/Tools/bison.py
new file mode 100644
index 0000000..a354e3e
--- /dev/null
+++ b/waflib/Tools/bison.py
@@ -0,0 +1,29 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Task
+from waflib.TaskGen import extension
+class bison(Task.Task):
+ color='BLUE'
+ run_str='${BISON} ${BISONFLAGS} ${SRC[0].abspath()} -o ${TGT[0].name}'
+ ext_out=['.h']
+def big_bison(self,node):
+ has_h='-d'in self.env['BISONFLAGS']
+ outs=[]
+ if node.name.endswith('.yc'):
+ outs.append(node.change_ext('.tab.cc'))
+ if has_h:
+ outs.append(node.change_ext('.tab.hh'))
+ else:
+ outs.append(node.change_ext('.tab.c'))
+ if has_h:
+ outs.append(node.change_ext('.tab.h'))
+ tsk=self.create_task('bison',node,outs)
+ tsk.cwd=node.parent.get_bld().abspath()
+ self.source.append(outs[0])
+def configure(conf):
+ conf.find_program('bison',var='BISON')
+ conf.env.BISONFLAGS=['-d']
+
+extension('.y','.yc','.yy')(big_bison) \ No newline at end of file
diff --git a/waflib/Tools/c.py b/waflib/Tools/c.py
new file mode 100644
index 0000000..3c941de
--- /dev/null
+++ b/waflib/Tools/c.py
@@ -0,0 +1,27 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import TaskGen,Task,Utils
+from waflib.Tools import c_preproc
+from waflib.Tools.ccroot import link_task,stlink_task
+def c_hook(self,node):
+ return self.create_compiled_task('c',node)
+class c(Task.Task):
+ run_str='${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT}'
+ vars=['CCDEPS']
+ ext_in=['.h']
+ scan=c_preproc.scan
+Task.classes['cc']=cc=c
+class cprogram(link_task):
+ run_str='${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}'
+ ext_out=['.bin']
+ vars=['LINKDEPS']
+ inst_to='${BINDIR}'
+ chmod=Utils.O755
+class cshlib(cprogram):
+ inst_to='${LIBDIR}'
+class cstlib(stlink_task):
+ pass
+
+TaskGen.extension('.c')(c_hook) \ No newline at end of file
diff --git a/waflib/Tools/c_aliases.py b/waflib/Tools/c_aliases.py
new file mode 100644
index 0000000..f21fb9e
--- /dev/null
+++ b/waflib/Tools/c_aliases.py
@@ -0,0 +1,56 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,re
+from waflib import Utils,Build
+from waflib.Configure import conf
+def get_extensions(lst):
+ ret=[]
+ for x in Utils.to_list(lst):
+ try:
+ if not isinstance(x,str):
+ x=x.name
+ ret.append(x[x.rfind('.')+1:])
+ except:
+ pass
+ return ret
+def sniff_features(**kw):
+ exts=get_extensions(kw['source'])
+ type=kw['_type']
+ feats=[]
+ if'cxx'in exts or'cpp'in exts or'c++'in exts or'cc'in exts or'C'in exts:
+ feats.append('cxx')
+ if'c'in exts or'vala'in exts:
+ feats.append('c')
+ if'd'in exts:
+ feats.append('d')
+ if'java'in exts:
+ feats.append('java')
+ if'java'in exts:
+ return'java'
+ if type in['program','shlib','stlib']:
+ for x in feats:
+ if x in['cxx','d','c']:
+ feats.append(x+type)
+ return feats
+def set_features(kw,_type):
+ kw['_type']=_type
+ kw['features']=Utils.to_list(kw.get('features',[]))+Utils.to_list(sniff_features(**kw))
+def program(bld,*k,**kw):
+ set_features(kw,'program')
+ return bld(*k,**kw)
+def shlib(bld,*k,**kw):
+ set_features(kw,'shlib')
+ return bld(*k,**kw)
+def stlib(bld,*k,**kw):
+ set_features(kw,'stlib')
+ return bld(*k,**kw)
+def objects(bld,*k,**kw):
+ set_features(kw,'objects')
+ return bld(*k,**kw)
+
+conf(program)
+conf(shlib)
+conf(stlib)
+conf(objects) \ No newline at end of file
diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py
new file mode 100644
index 0000000..d10e630
--- /dev/null
+++ b/waflib/Tools/c_config.py
@@ -0,0 +1,713 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+import os,imp,sys,re,shlex,shutil
+from waflib import Build,Utils,Configure,Task,Options,Logs,TaskGen,Errors,ConfigSet,Runner
+from waflib.TaskGen import before_method,after_method,feature
+from waflib.Configure import conf
+WAF_CONFIG_H='config.h'
+DEFKEYS='define_key'
+INCKEYS='include_key'
+cfg_ver={'atleast-version':'>=','exact-version':'==','max-version':'<=',}
+SNIP_FUNCTION='''
+ int main() {
+ void *p;
+ p=(void*)(%s);
+ return 0;
+}
+'''
+SNIP_TYPE='''
+int main() {
+ if ((%(type_name)s *) 0) return 0;
+ if (sizeof (%(type_name)s)) return 0;
+}
+'''
+SNIP_CLASS='''
+int main() {
+ if (
+}
+'''
+SNIP_EMPTY_PROGRAM='''
+int main() {
+ return 0;
+}
+'''
+SNIP_FIELD='''
+int main() {
+ char *off;
+ off = (char*) &((%(type_name)s*)0)->%(field_name)s;
+ return (size_t) off < sizeof(%(type_name)s);
+}
+'''
+MACRO_TO_DESTOS={'__linux__':'linux','__GNU__':'gnu','__FreeBSD__':'freebsd','__NetBSD__':'netbsd','__OpenBSD__':'openbsd','__sun':'sunos','__hpux':'hpux','__sgi':'irix','_AIX':'aix','__CYGWIN__':'cygwin','__MSYS__':'msys','_UWIN':'uwin','_WIN64':'win32','_WIN32':'win32','__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__':'darwin','__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__':'darwin','__QNX__':'qnx','__native_client__':'nacl'}
+MACRO_TO_DEST_CPU={'__x86_64__':'x86_64','__i386__':'x86','__ia64__':'ia','__mips__':'mips','__sparc__':'sparc','__alpha__':'alpha','__arm__':'arm','__hppa__':'hppa','__powerpc__':'powerpc',}
+def parse_flags(self,line,uselib,env=None,force_static=False):
+ assert(isinstance(line,str))
+ env=env or self.env
+ app=env.append_value
+ appu=env.append_unique
+ lex=shlex.shlex(line,posix=False)
+ lex.whitespace_split=True
+ lex.commenters=''
+ lst=list(lex)
+ while lst:
+ x=lst.pop(0)
+ st=x[:2]
+ ot=x[2:]
+ if st=='-I'or st=='/I':
+ if not ot:ot=lst.pop(0)
+ appu('INCLUDES_'+uselib,[ot])
+ elif st=='-include':
+ tmp=[x,lst.pop(0)]
+ app('CFLAGS',tmp)
+ app('CXXFLAGS',tmp)
+ elif st=='-D'or(self.env.CXX_NAME=='msvc'and st=='/D'):
+ if not ot:ot=lst.pop(0)
+ app('DEFINES_'+uselib,[ot])
+ elif st=='-l':
+ if not ot:ot=lst.pop(0)
+ prefix=force_static and'STLIB_'or'LIB_'
+ appu(prefix+uselib,[ot])
+ elif st=='-L':
+ if not ot:ot=lst.pop(0)
+ appu('LIBPATH_'+uselib,[ot])
+ elif x=='-pthread'or x.startswith('+')or x.startswith('-std'):
+ app('CFLAGS_'+uselib,[x])
+ app('CXXFLAGS_'+uselib,[x])
+ app('LINKFLAGS_'+uselib,[x])
+ elif x=='-framework':
+ appu('FRAMEWORK_'+uselib,[lst.pop(0)])
+ elif x.startswith('-F'):
+ appu('FRAMEWORKPATH_'+uselib,[x[2:]])
+ elif x.startswith('-Wl'):
+ app('LINKFLAGS_'+uselib,[x])
+ elif x.startswith('-m')or x.startswith('-f')or x.startswith('-dynamic'):
+ app('CFLAGS_'+uselib,[x])
+ app('CXXFLAGS_'+uselib,[x])
+ elif x.startswith('-bundle'):
+ app('LINKFLAGS_'+uselib,[x])
+ elif x.startswith('-undefined'):
+ arg=lst.pop(0)
+ app('LINKFLAGS_'+uselib,[x,arg])
+ elif x.startswith('-arch')or x.startswith('-isysroot'):
+ tmp=[x,lst.pop(0)]
+ app('CFLAGS_'+uselib,tmp)
+ app('CXXFLAGS_'+uselib,tmp)
+ app('LINKFLAGS_'+uselib,tmp)
+ elif x.endswith('.a')or x.endswith('.so')or x.endswith('.dylib'):
+ appu('LINKFLAGS_'+uselib,[x])
+def ret_msg(self,f,kw):
+ if isinstance(f,str):
+ return f
+ return f(kw)
+def validate_cfg(self,kw):
+ if not'path'in kw:
+ if not self.env.PKGCONFIG:
+ self.find_program('pkg-config',var='PKGCONFIG')
+ kw['path']=self.env.PKGCONFIG
+ if'atleast_pkgconfig_version'in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for pkg-config version >= %r'%kw['atleast_pkgconfig_version']
+ return
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ if not'errmsg'in kw:
+ kw['errmsg']='not found'
+ if'modversion'in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for %r version'%kw['modversion']
+ return
+ for x in cfg_ver.keys():
+ y=x.replace('-','_')
+ if y in kw:
+ if not'package'in kw:
+ raise ValueError('%s requires a package'%x)
+ if not'msg'in kw:
+ kw['msg']='Checking for %r %s %s'%(kw['package'],cfg_ver[x],kw[y])
+ return
+ if not'msg'in kw:
+ kw['msg']='Checking for %r'%(kw['package']or kw['path'])
+def exec_cfg(self,kw):
+ if'atleast_pkgconfig_version'in kw:
+ cmd=[kw['path'],'--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
+ self.cmd_and_log(cmd)
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ return
+ for x in cfg_ver:
+ y=x.replace('-','_')
+ if y in kw:
+ self.cmd_and_log([kw['path'],'--%s=%s'%(x,kw[y]),kw['package']])
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0)
+ break
+ if'modversion'in kw:
+ version=self.cmd_and_log([kw['path'],'--modversion',kw['modversion']]).strip()
+ self.define('%s_VERSION'%Utils.quote_define_name(kw.get('uselib_store',kw['modversion'])),version)
+ return version
+ lst=[kw['path']]
+ defi=kw.get('define_variable',None)
+ if not defi:
+ defi=self.env.PKG_CONFIG_DEFINES or{}
+ for key,val in defi.items():
+ lst.append('--define-variable=%s=%s'%(key,val))
+ if kw['package']:
+ lst.extend(Utils.to_list(kw['package']))
+ if'variables'in kw:
+ env=kw.get('env',self.env)
+ uselib=kw.get('uselib_store',kw['package'].upper())
+ vars=Utils.to_list(kw['variables'])
+ for v in vars:
+ val=self.cmd_and_log(lst+['--variable='+v]).strip()
+ var='%s_%s'%(uselib,v)
+ env[var]=val
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ return
+ static=False
+ if'args'in kw:
+ args=Utils.to_list(kw['args'])
+ if'--static'in args or'--static-libs'in args:
+ static=True
+ lst+=args
+ ret=self.cmd_and_log(lst)
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0)
+ self.parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env),force_static=static)
+ return ret
+def check_cfg(self,*k,**kw):
+ if k:
+ lst=k[0].split()
+ kw['package']=lst[0]
+ kw['args']=' '.join(lst[1:])
+ self.validate_cfg(kw)
+ if'msg'in kw:
+ self.start_msg(kw['msg'])
+ ret=None
+ try:
+ ret=self.exec_cfg(kw)
+ except self.errors.WafError ,e:
+ if'errmsg'in kw:
+ self.end_msg(kw['errmsg'],'YELLOW')
+ if Logs.verbose>1:
+ raise
+ else:
+ self.fatal('The configuration failed')
+ else:
+ kw['success']=ret
+ if'okmsg'in kw:
+ self.end_msg(self.ret_msg(kw['okmsg'],kw))
+ return ret
+def validate_c(self,kw):
+ if not'env'in kw:
+ kw['env']=self.env.derive()
+ env=kw['env']
+ if not'compiler'in kw and not'features'in kw:
+ kw['compiler']='c'
+ if env['CXX_NAME']and Task.classes.get('cxx',None):
+ kw['compiler']='cxx'
+ if not self.env['CXX']:
+ self.fatal('a c++ compiler is required')
+ else:
+ if not self.env['CC']:
+ self.fatal('a c compiler is required')
+ if not'compile_mode'in kw:
+ kw['compile_mode']='c'
+ if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler','')=='cxx':
+ kw['compile_mode']='cxx'
+ if not'type'in kw:
+ kw['type']='cprogram'
+ if not'features'in kw:
+ kw['features']=[kw['compile_mode'],kw['type']]
+ else:
+ kw['features']=Utils.to_list(kw['features'])
+ if not'compile_filename'in kw:
+ kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'')
+ def to_header(dct):
+ if'header_name'in dct:
+ dct=Utils.to_list(dct['header_name'])
+ return''.join(['#include <%s>\n'%x for x in dct])
+ return''
+ if'framework_name'in kw:
+ fwkname=kw['framework_name']
+ if not'uselib_store'in kw:
+ kw['uselib_store']=fwkname.upper()
+ if not kw.get('no_header',False):
+ if not'header_name'in kw:
+ kw['header_name']=[]
+ fwk='%s/%s.h'%(fwkname,fwkname)
+ if kw.get('remove_dot_h',None):
+ fwk=fwk[:-2]
+ kw['header_name']=Utils.to_list(kw['header_name'])+[fwk]
+ kw['msg']='Checking for framework %s'%fwkname
+ kw['framework']=fwkname
+ if'function_name'in kw:
+ fu=kw['function_name']
+ if not'msg'in kw:
+ kw['msg']='Checking for function %s'%fu
+ kw['code']=to_header(kw)+SNIP_FUNCTION%fu
+ if not'uselib_store'in kw:
+ kw['uselib_store']=fu.upper()
+ if not'define_name'in kw:
+ kw['define_name']=self.have_define(fu)
+ elif'type_name'in kw:
+ tu=kw['type_name']
+ if not'header_name'in kw:
+ kw['header_name']='stdint.h'
+ if'field_name'in kw:
+ field=kw['field_name']
+ kw['code']=to_header(kw)+SNIP_FIELD%{'type_name':tu,'field_name':field}
+ if not'msg'in kw:
+ kw['msg']='Checking for field %s in %s'%(field,tu)
+ if not'define_name'in kw:
+ kw['define_name']=self.have_define((tu+'_'+field).upper())
+ else:
+ kw['code']=to_header(kw)+SNIP_TYPE%{'type_name':tu}
+ if not'msg'in kw:
+ kw['msg']='Checking for type %s'%tu
+ if not'define_name'in kw:
+ kw['define_name']=self.have_define(tu.upper())
+ elif'header_name'in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for header %s'%kw['header_name']
+ l=Utils.to_list(kw['header_name'])
+ assert len(l)>0,'list of headers in header_name is empty'
+ kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM
+ if not'uselib_store'in kw:
+ kw['uselib_store']=l[0].upper()
+ if not'define_name'in kw:
+ kw['define_name']=self.have_define(l[0])
+ if'lib'in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for library %s'%kw['lib']
+ if not'uselib_store'in kw:
+ kw['uselib_store']=kw['lib'].upper()
+ if'stlib'in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for static library %s'%kw['stlib']
+ if not'uselib_store'in kw:
+ kw['uselib_store']=kw['stlib'].upper()
+ if'fragment'in kw:
+ kw['code']=kw['fragment']
+ if not'msg'in kw:
+ kw['msg']='Checking for code snippet'
+ if not'errmsg'in kw:
+ kw['errmsg']='no'
+ for(flagsname,flagstype)in[('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')]:
+ if flagsname in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname])
+ if not'errmsg'in kw:
+ kw['errmsg']='no'
+ if not'execute'in kw:
+ kw['execute']=False
+ if kw['execute']:
+ kw['features'].append('test_exec')
+ if not'errmsg'in kw:
+ kw['errmsg']='not found'
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ if not'code'in kw:
+ kw['code']=SNIP_EMPTY_PROGRAM
+ if self.env[INCKEYS]:
+ kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code']
+ if not kw.get('success'):kw['success']=None
+ if'define_name'in kw:
+ self.undefine(kw['define_name'])
+ assert'msg'in kw,'invalid parameters, read http://freehackers.org/~tnagy/wafbook/single.html#config_helpers_c'
+def post_check(self,*k,**kw):
+ is_success=0
+ if kw['execute']:
+ if kw['success']is not None:
+ if kw.get('define_ret',False):
+ is_success=kw['success']
+ else:
+ is_success=(kw['success']==0)
+ else:
+ is_success=(kw['success']==0)
+ if'define_name'in kw:
+ if'header_name'in kw or'function_name'in kw or'type_name'in kw or'fragment'in kw:
+ nm=kw['define_name']
+ if kw['execute']and kw.get('define_ret',None)and isinstance(is_success,str):
+ self.define(kw['define_name'],is_success,quote=kw.get('quote',1))
+ else:
+ self.define_cond(kw['define_name'],is_success)
+ else:
+ self.define_cond(kw['define_name'],is_success)
+ if'header_name'in kw:
+ if kw.get('auto_add_header_name',False):
+ self.env.append_value(INCKEYS,Utils.to_list(kw['header_name']))
+ if is_success and'uselib_store'in kw:
+ from waflib.Tools import ccroot
+ _vars=set([])
+ for x in kw['features']:
+ if x in ccroot.USELIB_VARS:
+ _vars|=ccroot.USELIB_VARS[x]
+ for k in _vars:
+ lk=k.lower()
+ if k=='INCLUDES':lk='includes'
+ if k=='DEFINES':lk='defines'
+ if lk in kw:
+ val=kw[lk]
+ if isinstance(val,str):
+ val=val.rstrip(os.path.sep)
+ self.env.append_unique(k+'_'+kw['uselib_store'],val)
+ return is_success
+def check(self,*k,**kw):
+ self.validate_c(kw)
+ self.start_msg(kw['msg'])
+ ret=None
+ try:
+ ret=self.run_c_code(*k,**kw)
+ except self.errors.ConfigurationError ,e:
+ self.end_msg(kw['errmsg'],'YELLOW')
+ if Logs.verbose>1:
+ raise
+ else:
+ self.fatal('The configuration failed')
+ else:
+ kw['success']=ret
+ self.end_msg(self.ret_msg(kw['okmsg'],kw))
+ ret=self.post_check(*k,**kw)
+ if not ret:
+ self.fatal('The configuration failed %r'%ret)
+ return ret
+class test_exec(Task.Task):
+ color='PINK'
+ def run(self):
+ if getattr(self.generator,'rpath',None):
+ if getattr(self.generator,'define_ret',False):
+ self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()])
+ else:
+ self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()])
+ else:
+ env=self.env.env or{}
+ env.update(dict(os.environ))
+ for var in('LD_LIBRARY_PATH','DYLD_LIBRARY_PATH','PATH'):
+ env[var]=self.inputs[0].parent.abspath()+os.path.pathsep+env.get(var,'')
+ if getattr(self.generator,'define_ret',False):
+ self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()],env=env)
+ else:
+ self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()],env=env)
+def test_exec_fun(self):
+ self.create_task('test_exec',self.link_task.outputs[0])
+CACHE_RESULTS=1
+COMPILE_ERRORS=2
+def run_c_code(self,*k,**kw):
+ lst=[str(v)for(p,v)in kw.items()if p!='env']
+ h=Utils.h_list(lst)
+ dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
+ try:
+ os.makedirs(dir)
+ except:
+ pass
+ try:
+ os.stat(dir)
+ except:
+ self.fatal('cannot use the configuration test folder %r'%dir)
+ cachemode=getattr(Options.options,'confcache',None)
+ if cachemode==CACHE_RESULTS:
+ try:
+ proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_c_code'))
+ ret=proj['cache_run_c_code']
+ except:
+ pass
+ else:
+ if isinstance(ret,str)and ret.startswith('Test does not build'):
+ self.fatal(ret)
+ return ret
+ bdir=os.path.join(dir,'testbuild')
+ if not os.path.exists(bdir):
+ os.makedirs(bdir)
+ self.test_bld=bld=Build.BuildContext(top_dir=dir,out_dir=bdir)
+ bld.init_dirs()
+ bld.progress_bar=0
+ bld.targets='*'
+ if kw['compile_filename']:
+ node=bld.srcnode.make_node(kw['compile_filename'])
+ node.write(kw['code'])
+ bld.logger=self.logger
+ bld.all_envs.update(self.all_envs)
+ bld.env=kw['env']
+ o=bld(features=kw['features'],source=kw['compile_filename'],target='testprog')
+ for k,v in kw.items():
+ setattr(o,k,v)
+ self.to_log("==>\n%s\n<=="%kw['code'])
+ bld.targets='*'
+ ret=-1
+ try:
+ try:
+ bld.compile()
+ except Errors.WafError:
+ ret='Test does not build: %s'%Utils.ex_stack()
+ self.fatal(ret)
+ else:
+ ret=getattr(bld,'retval',0)
+ finally:
+ proj=ConfigSet.ConfigSet()
+ proj['cache_run_c_code']=ret
+ proj.store(os.path.join(dir,'cache_run_c_code'))
+ return ret
+def check_cxx(self,*k,**kw):
+ kw['compiler']='cxx'
+ return self.check(*k,**kw)
+def check_cc(self,*k,**kw):
+ kw['compiler']='c'
+ return self.check(*k,**kw)
+def define(self,key,val,quote=True):
+ assert key and isinstance(key,str)
+ if isinstance(val,int)or isinstance(val,float):
+ s='%s=%s'
+ else:
+ s=quote and'%s="%s"'or'%s=%s'
+ app=s%(key,str(val))
+ ban=key+'='
+ lst=self.env['DEFINES']
+ for x in lst:
+ if x.startswith(ban):
+ lst[lst.index(x)]=app
+ break
+ else:
+ self.env.append_value('DEFINES',app)
+ self.env.append_unique(DEFKEYS,key)
+def undefine(self,key):
+ assert key and isinstance(key,str)
+ ban=key+'='
+ lst=[x for x in self.env['DEFINES']if not x.startswith(ban)]
+ self.env['DEFINES']=lst
+ self.env.append_unique(DEFKEYS,key)
+def define_cond(self,key,val):
+ assert key and isinstance(key,str)
+ if val:
+ self.define(key,1)
+ else:
+ self.undefine(key)
+def is_defined(self,key):
+ assert key and isinstance(key,str)
+ ban=key+'='
+ for x in self.env['DEFINES']:
+ if x.startswith(ban):
+ return True
+ return False
+def get_define(self,key):
+ assert key and isinstance(key,str)
+ ban=key+'='
+ for x in self.env['DEFINES']:
+ if x.startswith(ban):
+ return x[len(ban):]
+ return None
+def have_define(self,key):
+ return self.__dict__.get('HAVE_PAT','HAVE_%s')%Utils.quote_define_name(key)
+def write_config_header(self,configfile='',guard='',top=False,env=None,defines=True,headers=False,remove=True):
+ if not configfile:configfile=WAF_CONFIG_H
+ waf_guard=guard or'_%s_WAF'%Utils.quote_define_name(configfile)
+ node=top and self.bldnode or self.path.get_bld()
+ node=node.make_node(configfile)
+ node.parent.mkdir()
+ lst=['/* WARNING! All changes made to this file will be lost! */\n']
+ lst.append('#ifndef %s\n#define %s\n'%(waf_guard,waf_guard))
+ lst.append(self.get_config_header(defines,headers))
+ lst.append('\n#endif /* %s */\n'%waf_guard)
+ node.write('\n'.join(lst))
+ env=env or self.env
+ env.append_unique(Build.CFG_FILES,[node.abspath()])
+ if remove:
+ for key in self.env[DEFKEYS]:
+ self.undefine(key)
+ self.env[DEFKEYS]=[]
+def get_config_header(self,defines=True,headers=False):
+ lst=[]
+ if headers:
+ for x in self.env[INCKEYS]:
+ lst.append('#include <%s>'%x)
+ if defines:
+ for x in self.env[DEFKEYS]:
+ if self.is_defined(x):
+ val=self.get_define(x)
+ lst.append('#define %s %s'%(x,val))
+ else:
+ lst.append('/* #undef %s */'%x)
+ return"\n".join(lst)
+def cc_add_flags(conf):
+ conf.add_os_flags('CPPFLAGS','CFLAGS')
+ conf.add_os_flags('CFLAGS')
+def cxx_add_flags(conf):
+ conf.add_os_flags('CPPFLAGS','CXXFLAGS')
+ conf.add_os_flags('CXXFLAGS')
+def link_add_flags(conf):
+ conf.add_os_flags('LINKFLAGS')
+ conf.add_os_flags('LDFLAGS','LINKFLAGS')
+def cc_load_tools(conf):
+ if not conf.env.DEST_OS:
+ conf.env.DEST_OS=Utils.unversioned_sys_platform()
+ conf.load('c')
+def cxx_load_tools(conf):
+ if not conf.env.DEST_OS:
+ conf.env.DEST_OS=Utils.unversioned_sys_platform()
+ conf.load('cxx')
+def get_cc_version(conf,cc,gcc=False,icc=False):
+ cmd=cc+['-dM','-E','-']
+ env=conf.env.env or None
+ try:
+ p=Utils.subprocess.Popen(cmd,stdin=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
+ p.stdin.write('\n')
+ out=p.communicate()[0]
+ except:
+ conf.fatal('Could not determine the compiler version %r'%cmd)
+ if not isinstance(out,str):
+ out=out.decode(sys.stdout.encoding)
+ if gcc:
+ if out.find('__INTEL_COMPILER')>=0:
+ conf.fatal('The intel compiler pretends to be gcc')
+ if out.find('__GNUC__')<0:
+ conf.fatal('Could not determine the compiler type')
+ if icc and out.find('__INTEL_COMPILER')<0:
+ conf.fatal('Not icc/icpc')
+ k={}
+ if icc or gcc:
+ out=out.split('\n')
+ for line in out:
+ lst=shlex.split(line)
+ if len(lst)>2:
+ key=lst[1]
+ val=lst[2]
+ k[key]=val
+ def isD(var):
+ return var in k
+ def isT(var):
+ return var in k and k[var]!='0'
+ if not conf.env.DEST_OS:
+ conf.env.DEST_OS=''
+ for i in MACRO_TO_DESTOS:
+ if isD(i):
+ conf.env.DEST_OS=MACRO_TO_DESTOS[i]
+ break
+ else:
+ if isD('__APPLE__')and isD('__MACH__'):
+ conf.env.DEST_OS='darwin'
+ elif isD('__unix__'):
+ conf.env.DEST_OS='generic'
+ if isD('__ELF__'):
+ conf.env.DEST_BINFMT='elf'
+ elif isD('__WINNT__')or isD('__CYGWIN__'):
+ conf.env.DEST_BINFMT='pe'
+ conf.env.LIBDIR=conf.env['PREFIX']+'/bin'
+ elif isD('__APPLE__'):
+ conf.env.DEST_BINFMT='mac-o'
+ if not conf.env.DEST_BINFMT:
+ conf.env.DEST_BINFMT=Utils.destos_to_binfmt(conf.env.DEST_OS)
+ for i in MACRO_TO_DEST_CPU:
+ if isD(i):
+ conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i]
+ break
+ Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')]))
+ if icc:
+ ver=k['__INTEL_COMPILER']
+ conf.env['CC_VERSION']=(ver[:-2],ver[-2],ver[-1])
+ else:
+ conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
+ return k
+def get_xlc_version(conf,cc):
+ version_re=re.compile(r"IBM XL C/C\+\+.*, V(?P<major>\d*)\.(?P<minor>\d*)",re.I).search
+ cmd=cc+['-qversion']
+ try:
+ out,err=conf.cmd_and_log(cmd,output=0)
+ except Errors.WafError:
+ conf.fatal('Could not find xlc %r'%cmd)
+ if out:match=version_re(out)
+ else:match=version_re(err)
+ if not match:
+ conf.fatal('Could not determine the XLC version.')
+ k=match.groupdict()
+ conf.env['CC_VERSION']=(k['major'],k['minor'])
+def add_as_needed(self):
+ if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME):
+ self.env.append_unique('LINKFLAGS','--as-needed')
+class cfgtask(Task.TaskBase):
+ def display(self):
+ return''
+ def runnable_status(self):
+ return Task.RUN_ME
+ def run(self):
+ conf=self.conf
+ bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath())
+ bld.env=conf.env
+ bld.init_dirs()
+ bld.in_msg=1
+ bld.logger=self.logger
+ try:
+ bld.check(**self.args)
+ except:
+ return 1
+def multicheck(self,*k,**kw):
+ self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)))
+ class par(object):
+ def __init__(self):
+ self.keep=False
+ self.cache_global=Options.cache_global
+ self.nocache=Options.options.nocache
+ self.returned_tasks=[]
+ def total(self):
+ return len(tasks)
+ def to_log(self,*k,**kw):
+ return
+ bld=par()
+ tasks=[]
+ for dct in k:
+ x=cfgtask(bld=bld)
+ tasks.append(x)
+ x.args=dct
+ x.bld=bld
+ x.conf=self
+ x.args=dct
+ x.logger=Logs.make_mem_logger(str(id(x)),self.logger)
+ def it():
+ yield tasks
+ while 1:
+ yield[]
+ p=Runner.Parallel(bld,Options.options.jobs)
+ p.biter=it()
+ p.start()
+ for x in tasks:
+ x.logger.memhandler.flush()
+ for x in tasks:
+ if x.hasrun!=Task.SUCCESS:
+ self.end_msg(kw.get('errmsg','no'),color='YELLOW')
+ self.fatal(kw.get('fatalmsg',None)or'One of the tests has failed, see the config.log for more information')
+ self.end_msg('ok')
+
+conf(parse_flags)
+conf(ret_msg)
+conf(validate_cfg)
+conf(exec_cfg)
+conf(check_cfg)
+conf(validate_c)
+conf(post_check)
+conf(check)
+feature('test_exec')(test_exec_fun)
+after_method('apply_link')(test_exec_fun)
+conf(run_c_code)
+conf(check_cxx)
+conf(check_cc)
+conf(define)
+conf(undefine)
+conf(define_cond)
+conf(is_defined)
+conf(get_define)
+conf(have_define)
+conf(write_config_header)
+conf(get_config_header)
+conf(cc_add_flags)
+conf(cxx_add_flags)
+conf(link_add_flags)
+conf(cc_load_tools)
+conf(cxx_load_tools)
+conf(get_cc_version)
+conf(get_xlc_version)
+conf(add_as_needed)
+conf(multicheck) \ No newline at end of file
diff --git a/waflib/Tools/c_osx.py b/waflib/Tools/c_osx.py
new file mode 100644
index 0000000..92e39c5
--- /dev/null
+++ b/waflib/Tools/c_osx.py
@@ -0,0 +1,121 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,shutil,sys,platform
+from waflib import TaskGen,Task,Build,Options,Utils,Errors
+from waflib.TaskGen import taskgen_method,feature,after_method,before_method
+app_info='''
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Waf</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>NOTE</key>
+ <string>THIS IS A GENERATED FILE, DO NOT MODIFY</string>
+ <key>CFBundleExecutable</key>
+ <string>%s</string>
+</dict>
+</plist>
+'''
+def set_macosx_deployment_target(self):
+ if self.env['MACOSX_DEPLOYMENT_TARGET']:
+ os.environ['MACOSX_DEPLOYMENT_TARGET']=self.env['MACOSX_DEPLOYMENT_TARGET']
+ elif'MACOSX_DEPLOYMENT_TARGET'not in os.environ:
+ if Utils.unversioned_sys_platform()=='darwin':
+ os.environ['MACOSX_DEPLOYMENT_TARGET']='.'.join(platform.mac_ver()[0].split('.')[:2])
+def create_bundle_dirs(self,name,out):
+ bld=self.bld
+ dir=out.parent.find_or_declare(name)
+ dir.mkdir()
+ macos=dir.find_or_declare(['Contents','MacOS'])
+ macos.mkdir()
+ return dir
+def bundle_name_for_output(out):
+ name=out.name
+ k=name.rfind('.')
+ if k>=0:
+ name=name[:k]+'.app'
+ else:
+ name=name+'.app'
+ return name
+def create_task_macapp(self):
+ if self.env['MACAPP']or getattr(self,'mac_app',False):
+ out=self.link_task.outputs[0]
+ name=bundle_name_for_output(out)
+ dir=self.create_bundle_dirs(name,out)
+ n1=dir.find_or_declare(['Contents','MacOS',out.name])
+ self.apptask=self.create_task('macapp',self.link_task.outputs,n1)
+ inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/MacOS/'%name
+ self.bld.install_files(inst_to,n1,chmod=Utils.O755)
+ if getattr(self,'mac_resources',None):
+ res_dir=n1.parent.parent.make_node('Resources')
+ inst_to=getattr(self,'install_path','/Applications')+'/%s/Resources'%name
+ for x in self.to_list(self.mac_resources):
+ node=self.path.find_node(x)
+ if not node:
+ raise Errors.WafError('Missing mac_resource %r in %r'%(x,self))
+ parent=node.parent
+ if os.path.isdir(node.abspath()):
+ nodes=node.ant_glob('**')
+ else:
+ nodes=[node]
+ for node in nodes:
+ rel=node.path_from(parent)
+ tsk=self.create_task('macapp',node,res_dir.make_node(rel))
+ self.bld.install_as(inst_to+'/%s'%rel,node)
+ if getattr(self.bld,'is_install',None):
+ self.install_task.hasrun=Task.SKIP_ME
+def create_task_macplist(self):
+ if self.env['MACAPP']or getattr(self,'mac_app',False):
+ out=self.link_task.outputs[0]
+ name=bundle_name_for_output(out)
+ dir=self.create_bundle_dirs(name,out)
+ n1=dir.find_or_declare(['Contents','Info.plist'])
+ self.plisttask=plisttask=self.create_task('macplist',[],n1)
+ if getattr(self,'mac_plist',False):
+ node=self.path.find_resource(self.mac_plist)
+ if node:
+ plisttask.inputs.append(node)
+ else:
+ plisttask.code=self.mac_plist
+ else:
+ plisttask.code=app_info%self.link_task.outputs[0].name
+ inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/'%name
+ self.bld.install_files(inst_to,n1)
+def apply_bundle(self):
+ if self.env['MACBUNDLE']or getattr(self,'mac_bundle',False):
+ self.env['LINKFLAGS_cshlib']=self.env['LINKFLAGS_cxxshlib']=[]
+ self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['macbundle_PATTERN']
+ use=self.use=self.to_list(getattr(self,'use',[]))
+ if not'MACBUNDLE'in use:
+ use.append('MACBUNDLE')
+app_dirs=['Contents','Contents/MacOS','Contents/Resources']
+class macapp(Task.Task):
+ color='PINK'
+ def run(self):
+ self.outputs[0].parent.mkdir()
+ shutil.copy2(self.inputs[0].srcpath(),self.outputs[0].abspath())
+class macplist(Task.Task):
+ color='PINK'
+ ext_in=['.bin']
+ def run(self):
+ if getattr(self,'code',None):
+ txt=self.code
+ else:
+ txt=self.inputs[0].read()
+ self.outputs[0].write(txt)
+
+feature('c','cxx')(set_macosx_deployment_target)
+taskgen_method(create_bundle_dirs)
+feature('cprogram','cxxprogram')(create_task_macapp)
+after_method('apply_link')(create_task_macapp)
+feature('cprogram','cxxprogram')(create_task_macplist)
+after_method('apply_link')(create_task_macplist)
+feature('cshlib','cxxshlib')(apply_bundle)
+before_method('apply_link','propagate_uselib_vars')(apply_bundle) \ No newline at end of file
diff --git a/waflib/Tools/c_preproc.py b/waflib/Tools/c_preproc.py
new file mode 100644
index 0000000..4cb99ef
--- /dev/null
+++ b/waflib/Tools/c_preproc.py
@@ -0,0 +1,606 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+import re,sys,os,string,traceback
+from waflib import Logs,Build,Utils,Errors
+from waflib.Logs import debug,error
+class PreprocError(Errors.WafError):
+ pass
+POPFILE='-'
+recursion_limit=150
+go_absolute=False
+standard_includes=['/usr/include']
+if Utils.is_win32:
+ standard_includes=[]
+use_trigraphs=0
+strict_quotes=0
+g_optrans={'not':'!','and':'&&','bitand':'&','and_eq':'&=','or':'||','bitor':'|','or_eq':'|=','xor':'^','xor_eq':'^=','compl':'~',}
+re_lines=re.compile('^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE)
+re_mac=re.compile("^[a-zA-Z_]\w*")
+re_fun=re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]')
+re_pragma_once=re.compile('^\s*once\s*',re.IGNORECASE)
+re_nl=re.compile('\\\\\r*\n',re.MULTILINE)
+re_cpp=re.compile(r"""(/\*[^*]*\*+([^/*][^*]*\*+)*/)|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)""",re.MULTILINE)
+trig_def=[('??'+a,b)for a,b in zip("=-/!'()<>",r'#~\|^[]{}')]
+chr_esc={'0':0,'a':7,'b':8,'t':9,'n':10,'f':11,'v':12,'r':13,'\\':92,"'":39}
+NUM='i'
+OP='O'
+IDENT='T'
+STR='s'
+CHAR='c'
+tok_types=[NUM,STR,IDENT,OP]
+exp_types=[r"""0[xX](?P<hex>[a-fA-F0-9]+)(?P<qual1>[uUlL]*)|L*?'(?P<char>(\\.|[^\\'])+)'|(?P<n1>\d+)[Ee](?P<exp0>[+-]*?\d+)(?P<float0>[fFlL]*)|(?P<n2>\d*\.\d+)([Ee](?P<exp1>[+-]*?\d+))?(?P<float1>[fFlL]*)|(?P<n4>\d+\.\d*)([Ee](?P<exp2>[+-]*?\d+))?(?P<float2>[fFlL]*)|(?P<oct>0*)(?P<n0>\d+)(?P<qual2>[uUlL]*)""",r'L?"([^"\\]|\\.)*"',r'[a-zA-Z_]\w*',r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]',]
+re_clexer=re.compile('|'.join(["(?P<%s>%s)"%(name,part)for name,part in zip(tok_types,exp_types)]),re.M)
+accepted='a'
+ignored='i'
+undefined='u'
+skipped='s'
+def repl(m):
+ s=m.group(1)
+ if s:
+ return' '
+ return m.group(3)or''
+def filter_comments(filename):
+ code=Utils.readf(filename)
+ if use_trigraphs:
+ for(a,b)in trig_def:code=code.split(a).join(b)
+ code=re_nl.sub('',code)
+ code=re_cpp.sub(repl,code)
+ return[(m.group(2),m.group(3))for m in re.finditer(re_lines,code)]
+prec={}
+ops=['* / %','+ -','<< >>','< <= >= >','== !=','& | ^','&& ||',',']
+for x in range(len(ops)):
+ syms=ops[x]
+ for u in syms.split():
+ prec[u]=x
+def trimquotes(s):
+ if not s:return''
+ s=s.rstrip()
+ if s[0]=="'"and s[-1]=="'":return s[1:-1]
+ return s
+def reduce_nums(val_1,val_2,val_op):
+ try:a=0+val_1
+ except TypeError:a=int(val_1)
+ try:b=0+val_2
+ except TypeError:b=int(val_2)
+ d=val_op
+ if d=='%':c=a%b
+ elif d=='+':c=a+b
+ elif d=='-':c=a-b
+ elif d=='*':c=a*b
+ elif d=='/':c=a/b
+ elif d=='^':c=a^b
+ elif d=='|':c=a|b
+ elif d=='||':c=int(a or b)
+ elif d=='&':c=a&b
+ elif d=='&&':c=int(a and b)
+ elif d=='==':c=int(a==b)
+ elif d=='!=':c=int(a!=b)
+ elif d=='<=':c=int(a<=b)
+ elif d=='<':c=int(a<b)
+ elif d=='>':c=int(a>b)
+ elif d=='>=':c=int(a>=b)
+ elif d=='^':c=int(a^b)
+ elif d=='<<':c=a<<b
+ elif d=='>>':c=a>>b
+ else:c=0
+ return c
+def get_num(lst):
+ if not lst:raise PreprocError("empty list for get_num")
+ (p,v)=lst[0]
+ if p==OP:
+ if v=='(':
+ count_par=1
+ i=1
+ while i<len(lst):
+ (p,v)=lst[i]
+ if p==OP:
+ if v==')':
+ count_par-=1
+ if count_par==0:
+ break
+ elif v=='(':
+ count_par+=1
+ i+=1
+ else:
+ raise PreprocError("rparen expected %r"%lst)
+ (num,_)=get_term(lst[1:i])
+ return(num,lst[i+1:])
+ elif v=='+':
+ return get_num(lst[1:])
+ elif v=='-':
+ num,lst=get_num(lst[1:])
+ return(reduce_nums('-1',num,'*'),lst)
+ elif v=='!':
+ num,lst=get_num(lst[1:])
+ return(int(not int(num)),lst)
+ elif v=='~':
+ return(~int(num),lst)
+ else:
+ raise PreprocError("Invalid op token %r for get_num"%lst)
+ elif p==NUM:
+ return v,lst[1:]
+ elif p==IDENT:
+ return 0,lst[1:]
+ else:
+ raise PreprocError("Invalid token %r for get_num"%lst)
+def get_term(lst):
+ if not lst:raise PreprocError("empty list for get_term")
+ num,lst=get_num(lst)
+ if not lst:
+ return(num,[])
+ (p,v)=lst[0]
+ if p==OP:
+ if v=='&&'and not num:
+ return(num,[])
+ elif v=='||'and num:
+ return(num,[])
+ elif v==',':
+ return get_term(lst[1:])
+ elif v=='?':
+ count_par=0
+ i=1
+ while i<len(lst):
+ (p,v)=lst[i]
+ if p==OP:
+ if v==')':
+ count_par-=1
+ elif v=='(':
+ count_par+=1
+ elif v==':':
+ if count_par==0:
+ break
+ i+=1
+ else:
+ raise PreprocError("rparen expected %r"%lst)
+ if int(num):
+ return get_term(lst[1:i])
+ else:
+ return get_term(lst[i+1:])
+ else:
+ num2,lst=get_num(lst[1:])
+ if not lst:
+ num2=reduce_nums(num,num2,v)
+ return get_term([(NUM,num2)]+lst)
+ p2,v2=lst[0]
+ if p2!=OP:
+ raise PreprocError("op expected %r"%lst)
+ if prec[v2]>=prec[v]:
+ num2=reduce_nums(num,num2,v)
+ return get_term([(NUM,num2)]+lst)
+ else:
+ num3,lst=get_num(lst[1:])
+ num3=reduce_nums(num2,num3,v2)
+ return get_term([(NUM,num),(p,v),(NUM,num3)]+lst)
+ raise PreprocError("cannot reduce %r"%lst)
+def reduce_eval(lst):
+ num,lst=get_term(lst)
+ return(NUM,num)
+def stringize(lst):
+ lst=[str(v2)for(p2,v2)in lst]
+ return"".join(lst)
+def paste_tokens(t1,t2):
+ p1=None
+ if t1[0]==OP and t2[0]==OP:
+ p1=OP
+ elif t1[0]==IDENT and(t2[0]==IDENT or t2[0]==NUM):
+ p1=IDENT
+ elif t1[0]==NUM and t2[0]==NUM:
+ p1=NUM
+ if not p1:
+ raise PreprocError('tokens do not make a valid paste %r and %r'%(t1,t2))
+ return(p1,t1[1]+t2[1])
+def reduce_tokens(lst,defs,ban=[]):
+ i=0
+ while i<len(lst):
+ (p,v)=lst[i]
+ if p==IDENT and v=="defined":
+ del lst[i]
+ if i<len(lst):
+ (p2,v2)=lst[i]
+ if p2==IDENT:
+ if v2 in defs:
+ lst[i]=(NUM,1)
+ else:
+ lst[i]=(NUM,0)
+ elif p2==OP and v2=='(':
+ del lst[i]
+ (p2,v2)=lst[i]
+ del lst[i]
+ if v2 in defs:
+ lst[i]=(NUM,1)
+ else:
+ lst[i]=(NUM,0)
+ else:
+ raise PreprocError("Invalid define expression %r"%lst)
+ elif p==IDENT and v in defs:
+ if isinstance(defs[v],str):
+ a,b=extract_macro(defs[v])
+ defs[v]=b
+ macro_def=defs[v]
+ to_add=macro_def[1]
+ if isinstance(macro_def[0],list):
+ del lst[i]
+ for x in range(len(to_add)):
+ lst.insert(i,to_add[x])
+ i+=1
+ else:
+ args=[]
+ del lst[i]
+ if i>=len(lst):
+ raise PreprocError("expected '(' after %r (got nothing)"%v)
+ (p2,v2)=lst[i]
+ if p2!=OP or v2!='(':
+ raise PreprocError("expected '(' after %r"%v)
+ del lst[i]
+ one_param=[]
+ count_paren=0
+ while i<len(lst):
+ p2,v2=lst[i]
+ del lst[i]
+ if p2==OP and count_paren==0:
+ if v2=='(':
+ one_param.append((p2,v2))
+ count_paren+=1
+ elif v2==')':
+ if one_param:args.append(one_param)
+ break
+ elif v2==',':
+ if not one_param:raise PreprocError("empty param in funcall %s"%p)
+ args.append(one_param)
+ one_param=[]
+ else:
+ one_param.append((p2,v2))
+ else:
+ one_param.append((p2,v2))
+ if v2=='(':count_paren+=1
+ elif v2==')':count_paren-=1
+ else:
+ raise PreprocError('malformed macro')
+ accu=[]
+ arg_table=macro_def[0]
+ j=0
+ while j<len(to_add):
+ (p2,v2)=to_add[j]
+ if p2==OP and v2=='#':
+ if j+1<len(to_add)and to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
+ toks=args[arg_table[to_add[j+1][1]]]
+ accu.append((STR,stringize(toks)))
+ j+=1
+ else:
+ accu.append((p2,v2))
+ elif p2==OP and v2=='##':
+ if accu and j+1<len(to_add):
+ t1=accu[-1]
+ if to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
+ toks=args[arg_table[to_add[j+1][1]]]
+ if toks:
+ accu[-1]=paste_tokens(t1,toks[0])
+ accu.extend(toks[1:])
+ else:
+ accu.append((p2,v2))
+ accu.extend(toks)
+ elif to_add[j+1][0]==IDENT and to_add[j+1][1]=='__VA_ARGS__':
+ va_toks=[]
+ st=len(macro_def[0])
+ pt=len(args)
+ for x in args[pt-st+1:]:
+ va_toks.extend(x)
+ va_toks.append((OP,','))
+ if va_toks:va_toks.pop()
+ if len(accu)>1:
+ (p3,v3)=accu[-1]
+ (p4,v4)=accu[-2]
+ if v3=='##':
+ accu.pop()
+ if v4==','and pt<st:
+ accu.pop()
+ accu+=va_toks
+ else:
+ accu[-1]=paste_tokens(t1,to_add[j+1])
+ j+=1
+ else:
+ accu.append((p2,v2))
+ elif p2==IDENT and v2 in arg_table:
+ toks=args[arg_table[v2]]
+ reduce_tokens(toks,defs,ban+[v])
+ accu.extend(toks)
+ else:
+ accu.append((p2,v2))
+ j+=1
+ reduce_tokens(accu,defs,ban+[v])
+ for x in range(len(accu)-1,-1,-1):
+ lst.insert(i,accu[x])
+ i+=1
+def eval_macro(lst,defs):
+ reduce_tokens(lst,defs,[])
+ if not lst:raise PreprocError("missing tokens to evaluate")
+ (p,v)=reduce_eval(lst)
+ return int(v)!=0
+def extract_macro(txt):
+ t=tokenize(txt)
+ if re_fun.search(txt):
+ p,name=t[0]
+ p,v=t[1]
+ if p!=OP:raise PreprocError("expected open parenthesis")
+ i=1
+ pindex=0
+ params={}
+ prev='('
+ while 1:
+ i+=1
+ p,v=t[i]
+ if prev=='(':
+ if p==IDENT:
+ params[v]=pindex
+ pindex+=1
+ prev=p
+ elif p==OP and v==')':
+ break
+ else:
+ raise PreprocError("unexpected token (3)")
+ elif prev==IDENT:
+ if p==OP and v==',':
+ prev=v
+ elif p==OP and v==')':
+ break
+ else:
+ raise PreprocError("comma or ... expected")
+ elif prev==',':
+ if p==IDENT:
+ params[v]=pindex
+ pindex+=1
+ prev=p
+ elif p==OP and v=='...':
+ raise PreprocError("not implemented (1)")
+ else:
+ raise PreprocError("comma or ... expected (2)")
+ elif prev=='...':
+ raise PreprocError("not implemented (2)")
+ else:
+ raise PreprocError("unexpected else")
+ return(name,[params,t[i+1:]])
+ else:
+ (p,v)=t[0]
+ return(v,[[],t[1:]])
+re_include=re.compile('^\s*(<(?P<a>.*)>|"(?P<b>.*)")')
+def extract_include(txt,defs):
+ m=re_include.search(txt)
+ if m:
+ if m.group('a'):return'<',m.group('a')
+ if m.group('b'):return'"',m.group('b')
+ toks=tokenize(txt)
+ reduce_tokens(toks,defs,['waf_include'])
+ if not toks:
+ raise PreprocError("could not parse include %s"%txt)
+ if len(toks)==1:
+ if toks[0][0]==STR:
+ return'"',toks[0][1]
+ else:
+ if toks[0][1]=='<'and toks[-1][1]=='>':
+ return stringize(toks).lstrip('<').rstrip('>')
+ raise PreprocError("could not parse include %s."%txt)
+def parse_char(txt):
+ if not txt:raise PreprocError("attempted to parse a null char")
+ if txt[0]!='\\':
+ return ord(txt)
+ c=txt[1]
+ if c=='x':
+ if len(txt)==4 and txt[3]in string.hexdigits:return int(txt[2:],16)
+ return int(txt[2:],16)
+ elif c.isdigit():
+ if c=='0'and len(txt)==2:return 0
+ for i in 3,2,1:
+ if len(txt)>i and txt[1:1+i].isdigit():
+ return(1+i,int(txt[1:1+i],8))
+ else:
+ try:return chr_esc[c]
+ except KeyError:raise PreprocError("could not parse char literal '%s'"%txt)
+def tokenize(s):
+ ret=[]
+ for match in re_clexer.finditer(s):
+ m=match.group
+ for name in tok_types:
+ v=m(name)
+ if v:
+ if name==IDENT:
+ try:v=g_optrans[v];name=OP
+ except KeyError:
+ if v.lower()=="true":
+ v=1
+ name=NUM
+ elif v.lower()=="false":
+ v=0
+ name=NUM
+ elif name==NUM:
+ if m('oct'):v=int(v,8)
+ elif m('hex'):v=int(m('hex'),16)
+ elif m('n0'):v=m('n0')
+ else:
+ v=m('char')
+ if v:v=parse_char(v)
+ else:v=m('n2')or m('n4')
+ elif name==OP:
+ if v=='%:':v='#'
+ elif v=='%:%:':v='##'
+ elif name==STR:
+ v=v[1:-1]
+ ret.append((name,v))
+ break
+ return ret
+def define_name(line):
+ return re_mac.match(line).group(0)
+class c_parser(object):
+ def __init__(self,nodepaths=None,defines=None):
+ self.lines=[]
+ if defines is None:
+ self.defs={}
+ else:
+ self.defs=dict(defines)
+ self.state=[]
+ self.count_files=0
+ self.currentnode_stack=[]
+ self.nodepaths=nodepaths or[]
+ self.nodes=[]
+ self.names=[]
+ self.curfile=''
+ self.ban_includes=set([])
+ def cached_find_resource(self,node,filename):
+ try:
+ nd=node.ctx.cache_nd
+ except:
+ nd=node.ctx.cache_nd={}
+ tup=(node,filename)
+ try:
+ return nd[tup]
+ except KeyError:
+ ret=node.find_resource(filename)
+ if ret:
+ if getattr(ret,'children',None):
+ ret=None
+ elif ret.is_child_of(node.ctx.bldnode):
+ tmp=node.ctx.srcnode.search(ret.path_from(node.ctx.bldnode))
+ if tmp and getattr(tmp,'children',None):
+ ret=None
+ nd[tup]=ret
+ return ret
+ def tryfind(self,filename):
+ self.curfile=filename
+ found=self.cached_find_resource(self.currentnode_stack[-1],filename)
+ for n in self.nodepaths:
+ if found:
+ break
+ found=self.cached_find_resource(n,filename)
+ if found:
+ self.nodes.append(found)
+ if filename[-4:]!='.moc':
+ self.addlines(found)
+ else:
+ if not filename in self.names:
+ self.names.append(filename)
+ return found
+ def addlines(self,node):
+ self.currentnode_stack.append(node.parent)
+ filepath=node.abspath()
+ self.count_files+=1
+ if self.count_files>recursion_limit:
+ raise PreprocError("recursion limit exceeded")
+ pc=self.parse_cache
+ debug('preproc: reading file %r',filepath)
+ try:
+ lns=pc[filepath]
+ except KeyError:
+ pass
+ else:
+ self.lines.extend(lns)
+ return
+ try:
+ lines=filter_comments(filepath)
+ lines.append((POPFILE,''))
+ lines.reverse()
+ pc[filepath]=lines
+ self.lines.extend(lines)
+ except IOError:
+ raise PreprocError("could not read the file %s"%filepath)
+ except Exception:
+ if Logs.verbose>0:
+ error("parsing %s failed"%filepath)
+ traceback.print_exc()
+ def start(self,node,env):
+ debug('preproc: scanning %s (in %s)',node.name,node.parent.name)
+ bld=node.ctx
+ try:
+ self.parse_cache=bld.parse_cache
+ except AttributeError:
+ bld.parse_cache={}
+ self.parse_cache=bld.parse_cache
+ self.addlines(node)
+ if env['DEFINES']:
+ try:
+ lst=['%s %s'%(x[0],trimquotes('='.join(x[1:])))for x in[y.split('=')for y in env['DEFINES']]]
+ lst.reverse()
+ self.lines.extend([('define',x)for x in lst])
+ except AttributeError:
+ pass
+ while self.lines:
+ (token,line)=self.lines.pop()
+ if token==POPFILE:
+ self.count_files-=1
+ self.currentnode_stack.pop()
+ continue
+ try:
+ ve=Logs.verbose
+ if ve:debug('preproc: line is %s - %s state is %s',token,line,self.state)
+ state=self.state
+ if token[:2]=='if':
+ state.append(undefined)
+ elif token=='endif':
+ state.pop()
+ if token[0]!='e':
+ if skipped in self.state or ignored in self.state:
+ continue
+ if token=='if':
+ ret=eval_macro(tokenize(line),self.defs)
+ if ret:state[-1]=accepted
+ else:state[-1]=ignored
+ elif token=='ifdef':
+ m=re_mac.match(line)
+ if m and m.group(0)in self.defs:state[-1]=accepted
+ else:state[-1]=ignored
+ elif token=='ifndef':
+ m=re_mac.match(line)
+ if m and m.group(0)in self.defs:state[-1]=ignored
+ else:state[-1]=accepted
+ elif token=='include'or token=='import':
+ (kind,inc)=extract_include(line,self.defs)
+ if inc in self.ban_includes:
+ continue
+ if token=='import':self.ban_includes.add(inc)
+ if ve:debug('preproc: include found %s (%s) ',inc,kind)
+ if kind=='"'or not strict_quotes:
+ self.tryfind(inc)
+ elif token=='elif':
+ if state[-1]==accepted:
+ state[-1]=skipped
+ elif state[-1]==ignored:
+ if eval_macro(tokenize(line),self.defs):
+ state[-1]=accepted
+ elif token=='else':
+ if state[-1]==accepted:state[-1]=skipped
+ elif state[-1]==ignored:state[-1]=accepted
+ elif token=='define':
+ try:
+ self.defs[define_name(line)]=line
+ except:
+ raise PreprocError("Invalid define line %s"%line)
+ elif token=='undef':
+ m=re_mac.match(line)
+ if m and m.group(0)in self.defs:
+ self.defs.__delitem__(m.group(0))
+ elif token=='pragma':
+ if re_pragma_once.match(line.lower()):
+ self.ban_includes.add(self.curfile)
+ except Exception ,e:
+ if Logs.verbose:
+ debug('preproc: line parsing failed (%s): %s %s',e,line,Utils.ex_stack())
+def scan(task):
+ global go_absolute
+ try:
+ incn=task.generator.includes_nodes
+ except AttributeError:
+ raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": '%task.generator)
+ if go_absolute:
+ nodepaths=incn+standard_includes
+ else:
+ nodepaths=[x for x in incn if x.is_child_of(x.ctx.srcnode)or x.is_child_of(x.ctx.bldnode)]
+ tmp=c_parser(nodepaths)
+ tmp.start(task.inputs[0],task.env)
+ if Logs.verbose:
+ debug('deps: deps for %r: %r; unresolved %r'%(task.inputs,tmp.nodes,tmp.names))
+ return(tmp.nodes,tmp.names)
+
+Utils.run_once(tokenize)
+Utils.run_once(define_name) \ No newline at end of file
diff --git a/waflib/Tools/c_tests.py b/waflib/Tools/c_tests.py
new file mode 100644
index 0000000..30f92c5
--- /dev/null
+++ b/waflib/Tools/c_tests.py
@@ -0,0 +1,146 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Task
+from waflib.Configure import conf
+from waflib.TaskGen import feature,before_method,after_method
+import sys
+LIB_CODE='''
+#ifdef _MSC_VER
+#define testEXPORT __declspec(dllexport)
+#else
+#define testEXPORT
+#endif
+testEXPORT int lib_func(void) { return 9; }
+'''
+MAIN_CODE='''
+#ifdef _MSC_VER
+#define testEXPORT __declspec(dllimport)
+#else
+#define testEXPORT
+#endif
+testEXPORT int lib_func(void);
+int main(void) {return !(lib_func() == 9);}
+'''
+def link_lib_test_fun(self):
+ def write_test_file(task):
+ task.outputs[0].write(task.generator.code)
+ rpath=[]
+ if getattr(self,'add_rpath',False):
+ rpath=[self.bld.path.get_bld().abspath()]
+ mode=self.mode
+ m='%s %s'%(mode,mode)
+ ex=self.test_exec and'test_exec'or''
+ bld=self.bld
+ bld(rule=write_test_file,target='test.'+mode,code=LIB_CODE)
+ bld(rule=write_test_file,target='main.'+mode,code=MAIN_CODE)
+ bld(features='%sshlib'%m,source='test.'+mode,target='test')
+ bld(features='%sprogram %s'%(m,ex),source='main.'+mode,target='app',use='test',rpath=rpath)
+def check_library(self,mode=None,test_exec=True):
+ if not mode:
+ mode='c'
+ if self.env.CXX:
+ mode='cxx'
+ self.check(compile_filename=[],features='link_lib_test',msg='Checking for libraries',mode=mode,test_exec=test_exec,)
+INLINE_CODE='''
+typedef int foo_t;
+static %s foo_t static_foo () {return 0; }
+%s foo_t foo () {
+ return 0;
+}
+'''
+INLINE_VALUES=['inline','__inline__','__inline']
+def check_inline(self,**kw):
+ self.start_msg('Checking for inline')
+ if not'define_name'in kw:
+ kw['define_name']='INLINE_MACRO'
+ if not'features'in kw:
+ if self.env.CXX:
+ kw['features']=['cxx']
+ else:
+ kw['features']=['c']
+ for x in INLINE_VALUES:
+ kw['fragment']=INLINE_CODE%(x,x)
+ try:
+ self.check(**kw)
+ except self.errors.ConfigurationError:
+ continue
+ else:
+ self.end_msg(x)
+ if x!='inline':
+ self.define('inline',x,quote=False)
+ return x
+ self.fatal('could not use inline functions')
+LARGE_FRAGMENT='#include <unistd.h>\nint main() { return !(sizeof(off_t) >= 8); }\n'
+def check_large_file(self,**kw):
+ if not'define_name'in kw:
+ kw['define_name']='HAVE_LARGEFILE'
+ if not'execute'in kw:
+ kw['execute']=True
+ if not'features'in kw:
+ if self.env.CXX:
+ kw['features']=['cxx','cxxprogram']
+ else:
+ kw['features']=['c','cprogram']
+ kw['fragment']=LARGE_FRAGMENT
+ kw['msg']='Checking for large file support'
+ ret=True
+ try:
+ if self.env.DEST_BINFMT!='pe':
+ ret=self.check(**kw)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ if ret:
+ return True
+ kw['msg']='Checking for -D_FILE_OFFSET_BITS=64'
+ kw['defines']=['_FILE_OFFSET_BITS=64']
+ try:
+ ret=self.check(**kw)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ self.define('_FILE_OFFSET_BITS',64)
+ return ret
+ self.fatal('There is no support for large files')
+ENDIAN_FRAGMENT='''
+short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+}
+short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+}
+extern int foo;
+'''
+class grep_for_endianness(Task.Task):
+ color='PINK'
+ def run(self):
+ txt=self.inputs[0].read(flags='rb').decode('iso8859-1')
+ if txt.find('LiTTleEnDian')>-1:
+ self.generator.tmp.append('little')
+ elif txt.find('BIGenDianSyS')>-1:
+ self.generator.tmp.append('big')
+ else:
+ return-1
+def grep_for_endianness_fun(self):
+ self.create_task('grep_for_endianness',self.compiled_tasks[0].outputs[0])
+def check_endianness(self):
+ tmp=[]
+ def check_msg(self):
+ return tmp[0]
+ self.check(fragment=ENDIAN_FRAGMENT,features='c grep_for_endianness',msg="Checking for endianness",define='ENDIANNESS',tmp=tmp,okmsg=check_msg)
+ return tmp[0]
+
+feature('link_lib_test')(link_lib_test_fun)
+before_method('process_source')(link_lib_test_fun)
+conf(check_library)
+conf(check_inline)
+conf(check_large_file)
+feature('grep_for_endianness')(grep_for_endianness_fun)
+after_method('process_source')(grep_for_endianness_fun)
+conf(check_endianness) \ No newline at end of file
diff --git a/waflib/Tools/ccroot.py b/waflib/Tools/ccroot.py
new file mode 100644
index 0000000..e95f793
--- /dev/null
+++ b/waflib/Tools/ccroot.py
@@ -0,0 +1,375 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+import os,sys,re
+from waflib import TaskGen,Task,Utils,Logs,Build,Options,Node,Errors
+from waflib.Logs import error,debug,warn
+from waflib.TaskGen import after_method,before_method,feature,taskgen_method,extension
+from waflib.Tools import c_aliases,c_preproc,c_config,c_osx,c_tests
+from waflib.Configure import conf
+USELIB_VARS=Utils.defaultdict(set)
+USELIB_VARS['c']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CCDEPS','CFLAGS','ARCH'])
+USELIB_VARS['cxx']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CXXDEPS','CXXFLAGS','ARCH'])
+USELIB_VARS['d']=set(['INCLUDES','DFLAGS'])
+USELIB_VARS['cprogram']=USELIB_VARS['cxxprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH'])
+USELIB_VARS['cshlib']=USELIB_VARS['cxxshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH'])
+USELIB_VARS['cstlib']=USELIB_VARS['cxxstlib']=set(['ARFLAGS','LINKDEPS'])
+USELIB_VARS['dprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+USELIB_VARS['dshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+USELIB_VARS['dstlib']=set(['ARFLAGS','LINKDEPS'])
+USELIB_VARS['go']=set(['GOCFLAGS'])
+USELIB_VARS['goprogram']=set(['GOLFLAGS'])
+USELIB_VARS['asm']=set(['ASFLAGS'])
+def create_compiled_task(self,name,node):
+ out='%s.%d.o'%(node.name,self.idx)
+ task=self.create_task(name,node,node.parent.find_or_declare(out))
+ try:
+ self.compiled_tasks.append(task)
+ except AttributeError:
+ self.compiled_tasks=[task]
+ return task
+def to_incnodes(self,inlst):
+ lst=[]
+ seen=set([])
+ for x in self.to_list(inlst):
+ if x in seen or not x:
+ continue
+ seen.add(x)
+ if isinstance(x,Node.Node):
+ lst.append(x)
+ else:
+ if os.path.isabs(x):
+ lst.append(self.bld.root.make_node(x)or x)
+ else:
+ if x[0]=='#':
+ p=self.bld.bldnode.make_node(x[1:])
+ v=self.bld.srcnode.make_node(x[1:])
+ else:
+ p=self.path.get_bld().make_node(x)
+ v=self.path.make_node(x)
+ if p.is_child_of(self.bld.bldnode):
+ p.mkdir()
+ lst.append(p)
+ lst.append(v)
+ return lst
+def apply_incpaths(self):
+ lst=self.to_incnodes(self.to_list(getattr(self,'includes',[]))+self.env['INCLUDES'])
+ self.includes_nodes=lst
+ self.env['INCPATHS']=[x.abspath()for x in lst]
+class link_task(Task.Task):
+ color='YELLOW'
+ inst_to=None
+ chmod=Utils.O644
+ def add_target(self,target):
+ if isinstance(target,str):
+ pattern=self.env[self.__class__.__name__+'_PATTERN']
+ if not pattern:
+ pattern='%s'
+ folder,name=os.path.split(target)
+ if self.__class__.__name__.find('shlib')>0:
+ if self.env.DEST_BINFMT=='pe'and getattr(self.generator,'vnum',None):
+ name=name+'-'+self.generator.vnum.split('.')[0]
+ tmp=folder+os.sep+pattern%name
+ target=self.generator.path.find_or_declare(tmp)
+ self.set_outputs(target)
+class stlink_task(link_task):
+ run_str='${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}'
+def rm_tgt(cls):
+ old=cls.run
+ def wrap(self):
+ try:os.remove(self.outputs[0].abspath())
+ except OSError:pass
+ return old(self)
+ setattr(cls,'run',wrap)
+rm_tgt(stlink_task)
+def apply_link(self):
+ for x in self.features:
+ if x=='cprogram'and'cxx'in self.features:
+ x='cxxprogram'
+ elif x=='cshlib'and'cxx'in self.features:
+ x='cxxshlib'
+ if x in Task.classes:
+ if issubclass(Task.classes[x],link_task):
+ link=x
+ break
+ else:
+ return
+ objs=[t.outputs[0]for t in getattr(self,'compiled_tasks',[])]
+ self.link_task=self.create_task(link,objs)
+ self.link_task.add_target(self.target)
+ try:
+ inst_to=self.install_path
+ except AttributeError:
+ inst_to=self.link_task.__class__.inst_to
+ if inst_to:
+ self.install_task=self.bld.install_files(inst_to,self.link_task.outputs[:],env=self.env,chmod=self.link_task.chmod)
+def use_rec(self,name,**kw):
+ if name in self.tmp_use_not or name in self.tmp_use_seen:
+ return
+ try:
+ y=self.bld.get_tgen_by_name(name)
+ except Errors.WafError:
+ self.uselib.append(name)
+ self.tmp_use_not.add(name)
+ return
+ self.tmp_use_seen.append(name)
+ y.post()
+ y.tmp_use_objects=objects=kw.get('objects',True)
+ y.tmp_use_stlib=stlib=kw.get('stlib',True)
+ try:
+ link_task=y.link_task
+ except AttributeError:
+ y.tmp_use_var=''
+ else:
+ objects=False
+ if not isinstance(y.link_task,stlink_task):
+ stlib=False
+ y.tmp_use_var='LIB'
+ else:
+ y.tmp_use_var='STLIB'
+ p=self.tmp_use_prec
+ for x in self.to_list(getattr(y,'use',[])):
+ try:
+ p[x].append(name)
+ except:
+ p[x]=[name]
+ self.use_rec(x,objects=objects,stlib=stlib)
+def process_use(self):
+ use_not=self.tmp_use_not=set([])
+ use_seen=self.tmp_use_seen=[]
+ use_prec=self.tmp_use_prec={}
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ self.includes=self.to_list(getattr(self,'includes',[]))
+ names=self.to_list(getattr(self,'use',[]))
+ for x in names:
+ self.use_rec(x)
+ for x in use_not:
+ if x in use_prec:
+ del use_prec[x]
+ out=[]
+ tmp=[]
+ for x in self.tmp_use_seen:
+ for k in use_prec.values():
+ if x in k:
+ break
+ else:
+ tmp.append(x)
+ while tmp:
+ e=tmp.pop()
+ out.append(e)
+ try:
+ nlst=use_prec[e]
+ except KeyError:
+ pass
+ else:
+ del use_prec[e]
+ for x in nlst:
+ for y in use_prec:
+ if x in use_prec[y]:
+ break
+ else:
+ tmp.append(x)
+ if use_prec:
+ raise Errors.WafError('Cycle detected in the use processing %r'%use_prec)
+ out.reverse()
+ link_task=getattr(self,'link_task',None)
+ for x in out:
+ y=self.bld.get_tgen_by_name(x)
+ var=y.tmp_use_var
+ if var and link_task:
+ if var=='LIB'or y.tmp_use_stlib:
+ self.env.append_value(var,[y.target[y.target.rfind(os.sep)+1:]])
+ self.link_task.dep_nodes.extend(y.link_task.outputs)
+ tmp_path=y.link_task.outputs[0].parent.path_from(self.bld.bldnode)
+ self.env.append_value(var+'PATH',[tmp_path])
+ else:
+ if y.tmp_use_objects:
+ self.add_objects_from_tgen(y)
+ if getattr(y,'export_includes',None):
+ self.includes.extend(y.to_incnodes(y.export_includes))
+ for x in names:
+ try:
+ y=self.bld.get_tgen_by_name(x)
+ except:
+ if not self.env['STLIB_'+x]and not x in self.uselib:
+ self.uselib.append(x)
+ else:
+ for k in self.to_list(getattr(y,'uselib',[])):
+ if not self.env['STLIB_'+k]and not k in self.uselib:
+ self.uselib.append(k)
+def add_objects_from_tgen(self,tg):
+ try:
+ link_task=self.link_task
+ except AttributeError:
+ pass
+ else:
+ for tsk in getattr(tg,'compiled_tasks',[]):
+ for x in tsk.outputs:
+ if x.name.endswith('.o')or x.name.endswith('.obj'):
+ link_task.inputs.append(x)
+def get_uselib_vars(self):
+ _vars=set([])
+ for x in self.features:
+ if x in USELIB_VARS:
+ _vars|=USELIB_VARS[x]
+ return _vars
+def propagate_uselib_vars(self):
+ _vars=self.get_uselib_vars()
+ env=self.env
+ for x in _vars:
+ y=x.lower()
+ env.append_unique(x,self.to_list(getattr(self,y,[])))
+ for x in self.features:
+ for var in _vars:
+ compvar='%s_%s'%(var,x)
+ env.append_value(var,env[compvar])
+ for x in self.to_list(getattr(self,'uselib',[])):
+ for v in _vars:
+ env.append_value(v,env[v+'_'+x])
+def apply_implib(self):
+ if not self.env.DEST_BINFMT=='pe':
+ return
+ dll=self.link_task.outputs[0]
+ if isinstance(self.target,Node.Node):
+ name=self.target.name
+ else:
+ name=os.path.split(self.target)[1]
+ implib=self.env['implib_PATTERN']%name
+ implib=dll.parent.find_or_declare(implib)
+ self.env.append_value('LINKFLAGS',self.env['IMPLIB_ST']%implib.bldpath())
+ self.link_task.outputs.append(implib)
+ if getattr(self,'defs',None)and self.env.DEST_BINFMT=='pe':
+ node=self.path.find_resource(self.defs)
+ if not node:
+ raise Errors.WafError('invalid def file %r'%self.defs)
+ if'msvc'in(self.env.CC_NAME,self.env.CXX_NAME):
+ self.env.append_value('LINKFLAGS','/def:%s'%node.path_from(self.bld.bldnode))
+ self.link_task.dep_nodes.append(node)
+ else:
+ self.link_task.inputs.append(node)
+ try:
+ inst_to=self.install_path
+ except AttributeError:
+ inst_to=self.link_task.__class__.inst_to
+ if not inst_to:
+ return
+ self.implib_install_task=self.bld.install_as('${PREFIX}/lib/%s'%implib.name,implib,self.env)
+def apply_vnum(self):
+ if not getattr(self,'vnum','')or os.name!='posix'or self.env.DEST_BINFMT not in('elf','mac-o'):
+ return
+ link=self.link_task
+ nums=self.vnum.split('.')
+ node=link.outputs[0]
+ libname=node.name
+ if libname.endswith('.dylib'):
+ name3=libname.replace('.dylib','.%s.dylib'%self.vnum)
+ name2=libname.replace('.dylib','.%s.dylib'%nums[0])
+ else:
+ name3=libname+'.'+self.vnum
+ name2=libname+'.'+nums[0]
+ if self.env.SONAME_ST:
+ v=self.env.SONAME_ST%name2
+ self.env.append_value('LINKFLAGS',v.split())
+ tsk=self.create_task('vnum',node,[node.parent.find_or_declare(name2),node.parent.find_or_declare(name3)])
+ if getattr(self.bld,'is_install',None):
+ self.install_task.hasrun=Task.SKIP_ME
+ bld=self.bld
+ path=self.install_task.dest
+ t1=bld.install_as(path+os.sep+name3,node,env=self.env,chmod=self.link_task.chmod)
+ t2=bld.symlink_as(path+os.sep+name2,name3)
+ t3=bld.symlink_as(path+os.sep+libname,name3)
+ self.vnum_install_task=(t1,t2,t3)
+ if'-dynamiclib'in self.env['LINKFLAGS']and getattr(self,'install_task',None):
+ path=os.path.join(self.install_task.get_install_path(),self.link_task.outputs[0].name)
+ self.env.append_value('LINKFLAGS',['-install_name',path])
+class vnum(Task.Task):
+ color='CYAN'
+ quient=True
+ ext_in=['.bin']
+ def run(self):
+ for x in self.outputs:
+ path=x.abspath()
+ try:
+ os.remove(path)
+ except OSError:
+ pass
+ try:
+ os.symlink(self.inputs[0].name,path)
+ except OSError:
+ return 1
+class fake_shlib(link_task):
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ for x in self.outputs:
+ x.sig=Utils.h_file(x.abspath())
+ return Task.SKIP_ME
+class fake_stlib(stlink_task):
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ for x in self.outputs:
+ x.sig=Utils.h_file(x.abspath())
+ return Task.SKIP_ME
+def read_shlib(self,name,paths=[]):
+ return self(name=name,features='fake_lib',lib_paths=paths,lib_type='shlib')
+def read_stlib(self,name,paths=[]):
+ return self(name=name,features='fake_lib',lib_paths=paths,lib_type='stlib')
+lib_patterns={'shlib':['lib%s.so','%s.so','lib%s.dll','%s.dll'],'stlib':['lib%s.a','%s.a','lib%s.dll','%s.dll','lib%s.lib','%s.lib'],}
+def process_lib(self):
+ node=None
+ names=[x%self.name for x in lib_patterns[self.lib_type]]
+ for x in self.lib_paths+[self.path,'/usr/lib64','/usr/lib','/usr/local/lib64','/usr/local/lib']:
+ if not isinstance(x,Node.Node):
+ x=self.bld.root.find_node(x)or self.path.find_node(x)
+ if not x:
+ continue
+ for y in names:
+ node=x.find_node(y)
+ if node:
+ node.sig=Utils.h_file(node.abspath())
+ break
+ else:
+ continue
+ break
+ else:
+ raise Errors.WafError('could not find library %r'%self.name)
+ self.link_task=self.create_task('fake_%s'%self.lib_type,[],[node])
+ self.target=self.name
+class fake_o(Task.Task):
+ def runnable_status(self):
+ return Task.SKIP_ME
+def add_those_o_files(self,node):
+ tsk=self.create_task('fake_o',[],node)
+ try:
+ self.compiled_tasks.append(tsk)
+ except AttributeError:
+ self.compiled_tasks=[tsk]
+
+taskgen_method(create_compiled_task)
+taskgen_method(to_incnodes)
+feature('c','cxx','d','go','asm','fc','includes')(apply_incpaths)
+after_method('propagate_uselib_vars','process_source')(apply_incpaths)
+feature('c','cxx','d','go','fc','asm')(apply_link)
+after_method('process_source')(apply_link)
+taskgen_method(use_rec)
+feature('c','cxx','d','use','fc')(process_use)
+before_method('apply_incpaths','propagate_uselib_vars')(process_use)
+after_method('apply_link','process_source')(process_use)
+taskgen_method(add_objects_from_tgen)
+taskgen_method(get_uselib_vars)
+feature('c','cxx','d','fc','javac','cs','uselib')(propagate_uselib_vars)
+after_method('process_use')(propagate_uselib_vars)
+feature('cshlib','cxxshlib','fcshlib')(apply_implib)
+after_method('apply_link')(apply_implib)
+feature('cshlib','cxxshlib','dshlib','fcshlib','vnum')(apply_vnum)
+after_method('apply_link')(apply_vnum)
+conf(read_shlib)
+conf(read_stlib)
+feature('fake_lib')(process_lib)
+extension('.o','.obj')(add_those_o_files) \ No newline at end of file
diff --git a/waflib/Tools/compiler_c.py b/waflib/Tools/compiler_c.py
new file mode 100644
index 0000000..04504fa
--- /dev/null
+++ b/waflib/Tools/compiler_c.py
@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib.Tools import ccroot
+from waflib import Utils,Configure
+from waflib.Logs import debug
+c_compiler={'win32':['msvc','gcc'],'cygwin':['gcc'],'darwin':['gcc'],'aix':['xlc','gcc'],'linux':['gcc','icc'],'sunos':['suncc','gcc'],'irix':['gcc','irixcc'],'hpux':['gcc'],'gnu':['gcc'],'java':['gcc','msvc','icc'],'default':['gcc'],}
+def configure(conf):
+ try:test_for_compiler=conf.options.check_c_compiler
+ except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_c')")
+ for compiler in test_for_compiler.split():
+ conf.env.stash()
+ conf.start_msg('Checking for %r (c compiler)'%compiler)
+ try:
+ conf.load(compiler)
+ except conf.errors.ConfigurationError ,e:
+ conf.env.revert()
+ conf.end_msg(False)
+ debug('compiler_c: %r'%e)
+ else:
+ if conf.env['CC']:
+ conf.end_msg(conf.env.get_flat('CC'))
+ conf.env['COMPILER_CC']=compiler
+ break
+ conf.end_msg(False)
+ else:
+ conf.fatal('could not configure a c compiler!')
+def options(opt):
+ opt.load_special_tools('c_*.py',ban=['c_dumbpreproc.py'])
+ global c_compiler
+ build_platform=Utils.unversioned_sys_platform()
+ possible_compiler_list=c_compiler[build_platform in c_compiler and build_platform or'default']
+ test_for_compiler=' '.join(possible_compiler_list)
+ cc_compiler_opts=opt.add_option_group("C Compiler Options")
+ cc_compiler_opts.add_option('--check-c-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following C-Compiler will be checked by default: "%s"'%(build_platform,test_for_compiler),dest="check_c_compiler")
+ for x in test_for_compiler.split():
+ opt.load('%s'%x)
diff --git a/waflib/Tools/compiler_cxx.py b/waflib/Tools/compiler_cxx.py
new file mode 100644
index 0000000..14b7c7d
--- /dev/null
+++ b/waflib/Tools/compiler_cxx.py
@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib.Tools import ccroot
+from waflib import Utils,Configure
+from waflib.Logs import debug
+cxx_compiler={'win32':['msvc','g++'],'cygwin':['g++'],'darwin':['g++'],'aix':['xlc++','g++'],'linux':['g++','icpc'],'sunos':['sunc++','g++'],'irix':['g++'],'hpux':['g++'],'gnu':['g++'],'java':['g++','msvc','icpc'],'default':['g++']}
+def configure(conf):
+ try:test_for_compiler=conf.options.check_cxx_compiler
+ except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_cxx')")
+ for compiler in test_for_compiler.split():
+ conf.env.stash()
+ conf.start_msg('Checking for %r (c++ compiler)'%compiler)
+ try:
+ conf.load(compiler)
+ except conf.errors.ConfigurationError ,e:
+ conf.env.revert()
+ conf.end_msg(False)
+ debug('compiler_cxx: %r'%e)
+ else:
+ if conf.env['CXX']:
+ conf.end_msg(conf.env.get_flat('CXX'))
+ conf.env['COMPILER_CXX']=compiler
+ break
+ conf.end_msg(False)
+ else:
+ conf.fatal('could not configure a c++ compiler!')
+def options(opt):
+ opt.load_special_tools('cxx_*.py')
+ global cxx_compiler
+ build_platform=Utils.unversioned_sys_platform()
+ possible_compiler_list=cxx_compiler[build_platform in cxx_compiler and build_platform or'default']
+ test_for_compiler=' '.join(possible_compiler_list)
+ cxx_compiler_opts=opt.add_option_group('C++ Compiler Options')
+ cxx_compiler_opts.add_option('--check-cxx-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following C++ Compiler will be checked by default: "%s"'%(build_platform,test_for_compiler),dest="check_cxx_compiler")
+ for x in test_for_compiler.split():
+ opt.load('%s'%x)
diff --git a/waflib/Tools/compiler_d.py b/waflib/Tools/compiler_d.py
new file mode 100644
index 0000000..b5396b0
--- /dev/null
+++ b/waflib/Tools/compiler_d.py
@@ -0,0 +1,30 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib import Utils,Configure,Options,Logs
+def configure(conf):
+ for compiler in conf.options.dcheck.split(','):
+ conf.env.stash()
+ conf.start_msg('Checking for %r (d compiler)'%compiler)
+ try:
+ conf.load(compiler)
+ except conf.errors.ConfigurationError ,e:
+ conf.env.revert()
+ conf.end_msg(False)
+ Logs.debug('compiler_cxx: %r'%e)
+ else:
+ if conf.env.D:
+ conf.end_msg(conf.env.get_flat('D'))
+ conf.env['COMPILER_D']=compiler
+ conf.env.D_COMPILER=conf.env.D
+ break
+ conf.end_msg(False)
+ else:
+ conf.fatal('no suitable d compiler was found')
+def options(opt):
+ d_compiler_opts=opt.add_option_group('D Compiler Options')
+ d_compiler_opts.add_option('--check-d-compiler',default='gdc,dmd',action='store',help='check for the compiler [Default:gdc,dmd]',dest='dcheck')
+ for d_compiler in['gdc','dmd']:
+ opt.load('%s'%d_compiler)
diff --git a/waflib/Tools/compiler_fc.py b/waflib/Tools/compiler_fc.py
new file mode 100644
index 0000000..ec5d2ea
--- /dev/null
+++ b/waflib/Tools/compiler_fc.py
@@ -0,0 +1,43 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib import Utils,Configure,Options,Logs,Errors
+from waflib.Tools import fc
+fc_compiler={'win32':['gfortran','ifort'],'darwin':['gfortran','g95','ifort'],'linux':['gfortran','g95','ifort'],'java':['gfortran','g95','ifort'],'default':['gfortran'],'aix':['gfortran']}
+def __list_possible_compiler(platform):
+ try:
+ return fc_compiler[platform]
+ except KeyError:
+ return fc_compiler["default"]
+def configure(conf):
+ try:test_for_compiler=conf.options.check_fc
+ except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_fc')")
+ for compiler in test_for_compiler.split():
+ conf.env.stash()
+ conf.start_msg('Checking for %r (fortran compiler)'%compiler)
+ try:
+ conf.load(compiler)
+ except conf.errors.ConfigurationError ,e:
+ conf.env.revert()
+ conf.end_msg(False)
+ Logs.debug('compiler_fortran: %r'%e)
+ else:
+ if conf.env['FC']:
+ conf.end_msg(conf.env.get_flat('FC'))
+ conf.env.COMPILER_FORTRAN=compiler
+ break
+ conf.end_msg(False)
+ else:
+ conf.fatal('could not configure a fortran compiler!')
+def options(opt):
+ opt.load_special_tools('fc_*.py')
+ build_platform=Utils.unversioned_sys_platform()
+ detected_platform=Options.platform
+ possible_compiler_list=__list_possible_compiler(detected_platform)
+ test_for_compiler=' '.join(possible_compiler_list)
+ fortran_compiler_opts=opt.add_option_group("Fortran Compiler Options")
+ fortran_compiler_opts.add_option('--check-fortran-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following Fortran Compiler will be checked by default: "%s"'%(detected_platform,test_for_compiler),dest="check_fc")
+ for compiler in test_for_compiler.split():
+ opt.load('%s'%compiler)
diff --git a/waflib/Tools/cs.py b/waflib/Tools/cs.py
new file mode 100644
index 0000000..0fdf761
--- /dev/null
+++ b/waflib/Tools/cs.py
@@ -0,0 +1,98 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+from waflib import Utils,Task,Options,Logs,Errors
+from waflib.TaskGen import before_method,after_method,feature
+from waflib.Tools import ccroot
+from waflib.Configure import conf
+ccroot.USELIB_VARS['cs']=set(['CSFLAGS','ASSEMBLIES','RESOURCES'])
+ccroot.lib_patterns['csshlib']=['%s']
+def apply_cs(self):
+ cs_nodes=[]
+ no_nodes=[]
+ for x in self.to_nodes(self.source):
+ if x.name.endswith('.cs'):
+ cs_nodes.append(x)
+ else:
+ no_nodes.append(x)
+ self.source=no_nodes
+ bintype=getattr(self,'type',self.gen.endswith('.dll')and'library'or'exe')
+ self.cs_task=tsk=self.create_task('mcs',cs_nodes,self.path.find_or_declare(self.gen))
+ tsk.env.CSTYPE='/target:%s'%bintype
+ tsk.env.OUT='/out:%s'%tsk.outputs[0].abspath()
+ inst_to=getattr(self,'install_path',bintype=='exe'and'${BINDIR}'or'${LIBDIR}')
+ if inst_to:
+ mod=getattr(self,'chmod',bintype=='exe'and Utils.O755 or Utils.O644)
+ self.install_task=self.bld.install_files(inst_to,self.cs_task.outputs[:],env=self.env,chmod=mod)
+def use_cs(self):
+ names=self.to_list(getattr(self,'use',[]))
+ get=self.bld.get_tgen_by_name
+ for x in names:
+ try:
+ y=get(x)
+ except Errors.WafError:
+ self.cs_task.env.append_value('CSFLAGS','/reference:%s'%x)
+ continue
+ y.post()
+ tsk=getattr(y,'cs_task',None)or getattr(y,'link_task',None)
+ if not tsk:
+ self.bld.fatal('cs task has no link task for use %r'%self)
+ self.cs_task.dep_nodes.extend(tsk.outputs)
+ self.cs_task.set_run_after(tsk)
+ self.cs_task.env.append_value('CSFLAGS','/reference:%s'%tsk.outputs[0].abspath())
+def debug_cs(self):
+ csdebug=getattr(self,'csdebug',self.env.CSDEBUG)
+ if not csdebug:
+ return
+ node=self.cs_task.outputs[0]
+ if self.env.CS_NAME=='mono':
+ out=node.parent.find_or_declare(node.name+'.mdb')
+ else:
+ out=node.change_ext('.pdb')
+ self.cs_task.outputs.append(out)
+ try:
+ self.install_task.source.append(out)
+ except AttributeError:
+ pass
+ if csdebug=='pdbonly':
+ val=['/debug+','/debug:pdbonly']
+ elif csdebug=='full':
+ val=['/debug+','/debug:full']
+ else:
+ val=['/debug-']
+ self.cs_task.env.append_value('CSFLAGS',val)
+class mcs(Task.Task):
+ color='YELLOW'
+ run_str='${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}'
+def configure(conf):
+ csc=getattr(Options.options,'cscbinary',None)
+ if csc:
+ conf.env.MCS=csc
+ conf.find_program(['csc','mcs','gmcs'],var='MCS')
+ conf.env.ASS_ST='/r:%s'
+ conf.env.RES_ST='/resource:%s'
+ conf.env.CS_NAME='csc'
+ if str(conf.env.MCS).lower().find('mcs')>-1:
+ conf.env.CS_NAME='mono'
+def options(opt):
+ opt.add_option('--with-csc-binary',type='string',dest='cscbinary')
+class fake_csshlib(Task.Task):
+ color='YELLOW'
+ inst_to=None
+ def runnable_status(self):
+ for x in self.outputs:
+ x.sig=Utils.h_file(x.abspath())
+ return Task.SKIP_ME
+def read_csshlib(self,name,paths=[]):
+ return self(name=name,features='fake_lib',lib_paths=paths,lib_type='csshlib')
+
+feature('cs')(apply_cs)
+before_method('process_source')(apply_cs)
+feature('cs')(use_cs)
+after_method('apply_cs')(use_cs)
+feature('cs')(debug_cs)
+after_method('apply_cs','use_cs')(debug_cs)
+conf(read_csshlib) \ No newline at end of file
diff --git a/waflib/Tools/cxx.py b/waflib/Tools/cxx.py
new file mode 100644
index 0000000..e378383
--- /dev/null
+++ b/waflib/Tools/cxx.py
@@ -0,0 +1,27 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import TaskGen,Task,Utils
+from waflib.Tools import c_preproc
+from waflib.Tools.ccroot import link_task,stlink_task
+def cxx_hook(self,node):
+ return self.create_compiled_task('cxx',node)
+TaskGen.extension('.cpp','.cc','.cxx','.C','.c++')(cxx_hook)
+if not'.c'in TaskGen.task_gen.mappings:
+ TaskGen.task_gen.mappings['.c']=TaskGen.task_gen.mappings['.cpp']
+class cxx(Task.Task):
+ run_str='${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT}'
+ vars=['CXXDEPS']
+ ext_in=['.h']
+ scan=c_preproc.scan
+class cxxprogram(link_task):
+ run_str='${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}'
+ vars=['LINKDEPS']
+ ext_out=['.bin']
+ inst_to='${BINDIR}'
+ chmod=Utils.O755
+class cxxshlib(cxxprogram):
+ inst_to='${LIBDIR}'
+class cxxstlib(stlink_task):
+ pass
diff --git a/waflib/Tools/d.py b/waflib/Tools/d.py
new file mode 100644
index 0000000..b56f3dd
--- /dev/null
+++ b/waflib/Tools/d.py
@@ -0,0 +1,56 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Utils,Task,Errors
+from waflib.TaskGen import taskgen_method,feature,extension
+from waflib.Tools import d_scan,d_config
+from waflib.Tools.ccroot import link_task,stlink_task
+class d(Task.Task):
+ color='GREEN'
+ run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_SRC_F:SRC} ${D_TGT_F:TGT}'
+ scan=d_scan.scan
+class d_with_header(d):
+ run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_HDR_F:tgt.outputs[1].bldpath()} ${D_SRC_F:SRC} ${D_TGT_F:tgt.outputs[0].bldpath()}'
+class d_header(Task.Task):
+ color='BLUE'
+ run_str='${D} ${D_HEADER} ${SRC}'
+class dprogram(link_task):
+ run_str='${D_LINKER} ${LINKFLAGS} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F:TGT} ${RPATH_ST:RPATH} ${DSTLIB_MARKER} ${DSTLIBPATH_ST:STLIBPATH} ${DSTLIB_ST:STLIB} ${DSHLIB_MARKER} ${DLIBPATH_ST:LIBPATH} ${DSHLIB_ST:LIB}'
+ inst_to='${BINDIR}'
+ chmod=Utils.O755
+class dshlib(dprogram):
+ inst_to='${LIBDIR}'
+class dstlib(stlink_task):
+ pass
+def d_hook(self,node):
+ ext=Utils.destos_to_binfmt(self.env.DEST_OS)=='pe'and'obj'or'o'
+ out='%s.%d.%s'%(node.name,self.idx,ext)
+ def create_compiled_task(self,name,node):
+ task=self.create_task(name,node,node.parent.find_or_declare(out))
+ try:
+ self.compiled_tasks.append(task)
+ except AttributeError:
+ self.compiled_tasks=[task]
+ return task
+ if getattr(self,'generate_headers',None):
+ tsk=create_compiled_task(self,'d_with_header',node)
+ tsk.outputs.append(node.change_ext(self.env['DHEADER_ext']))
+ else:
+ tsk=create_compiled_task(self,'d',node)
+ return tsk
+def generate_header(self,filename,install_path=None):
+ try:
+ self.header_lst.append([filename,install_path])
+ except AttributeError:
+ self.header_lst=[[filename,install_path]]
+def process_header(self):
+ for i in getattr(self,'header_lst',[]):
+ node=self.path.find_resource(i[0])
+ if not node:
+ raise Errors.WafError('file %r not found on d obj'%i[0])
+ self.create_task('d_header',node,node.change_ext('.di'))
+
+extension('.d','.di','.D')(d_hook)
+taskgen_method(generate_header)
+feature('d')(process_header) \ No newline at end of file
diff --git a/waflib/Tools/d_config.py b/waflib/Tools/d_config.py
new file mode 100644
index 0000000..a61ac80
--- /dev/null
+++ b/waflib/Tools/d_config.py
@@ -0,0 +1,47 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Utils
+from waflib.Configure import conf
+def d_platform_flags(self):
+ v=self.env
+ if not v.DEST_OS:
+ v.DEST_OS=Utils.unversioned_sys_platform()
+ if Utils.destos_to_binfmt(self.env.DEST_OS)=='pe':
+ v['dprogram_PATTERN']='%s.exe'
+ v['dshlib_PATTERN']='lib%s.dll'
+ v['dstlib_PATTERN']='lib%s.a'
+ else:
+ v['dprogram_PATTERN']='%s'
+ v['dshlib_PATTERN']='lib%s.so'
+ v['dstlib_PATTERN']='lib%s.a'
+DLIB='''
+version(D_Version2) {
+ import std.stdio;
+ int main() {
+ writefln("phobos2");
+ return 0;
+ }
+} else {
+ version(Tango) {
+ import tango.stdc.stdio;
+ int main() {
+ printf("tango");
+ return 0;
+ }
+ } else {
+ import std.stdio;
+ int main() {
+ writefln("phobos1");
+ return 0;
+ }
+ }
+}
+'''
+def check_dlibrary(self):
+ ret=self.check_cc(features='d dprogram',fragment=DLIB,compile_filename='test.d',execute=True,define_ret=True)
+ self.env.DLIBRARY=ret.strip()
+
+conf(d_platform_flags)
+conf(check_dlibrary) \ No newline at end of file
diff --git a/waflib/Tools/d_scan.py b/waflib/Tools/d_scan.py
new file mode 100644
index 0000000..ee80c5f
--- /dev/null
+++ b/waflib/Tools/d_scan.py
@@ -0,0 +1,133 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils,Logs
+def filter_comments(filename):
+ txt=Utils.readf(filename)
+ i=0
+ buf=[]
+ max=len(txt)
+ begin=0
+ while i<max:
+ c=txt[i]
+ if c=='"'or c=="'":
+ buf.append(txt[begin:i])
+ delim=c
+ i+=1
+ while i<max:
+ c=txt[i]
+ if c==delim:break
+ elif c=='\\':
+ i+=1
+ i+=1
+ i+=1
+ begin=i
+ elif c=='/':
+ buf.append(txt[begin:i])
+ i+=1
+ if i==max:break
+ c=txt[i]
+ if c=='+':
+ i+=1
+ nesting=1
+ c=None
+ while i<max:
+ prev=c
+ c=txt[i]
+ if prev=='/'and c=='+':
+ nesting+=1
+ c=None
+ elif prev=='+'and c=='/':
+ nesting-=1
+ if nesting==0:break
+ c=None
+ i+=1
+ elif c=='*':
+ i+=1
+ c=None
+ while i<max:
+ prev=c
+ c=txt[i]
+ if prev=='*'and c=='/':break
+ i+=1
+ elif c=='/':
+ i+=1
+ while i<max and txt[i]!='\n':
+ i+=1
+ else:
+ begin=i-1
+ continue
+ i+=1
+ begin=i
+ buf.append(' ')
+ else:
+ i+=1
+ buf.append(txt[begin:])
+ return buf
+class d_parser(object):
+ def __init__(self,env,incpaths):
+ self.allnames=[]
+ self.re_module=re.compile("module\s+([^;]+)")
+ self.re_import=re.compile("import\s+([^;]+)")
+ self.re_import_bindings=re.compile("([^:]+):(.*)")
+ self.re_import_alias=re.compile("[^=]+=(.+)")
+ self.env=env
+ self.nodes=[]
+ self.names=[]
+ self.incpaths=incpaths
+ def tryfind(self,filename):
+ found=0
+ for n in self.incpaths:
+ found=n.find_resource(filename.replace('.','/')+'.d')
+ if found:
+ self.nodes.append(found)
+ self.waiting.append(found)
+ break
+ if not found:
+ if not filename in self.names:
+ self.names.append(filename)
+ def get_strings(self,code):
+ self.module=''
+ lst=[]
+ mod_name=self.re_module.search(code)
+ if mod_name:
+ self.module=re.sub('\s+','',mod_name.group(1))
+ import_iterator=self.re_import.finditer(code)
+ if import_iterator:
+ for import_match in import_iterator:
+ import_match_str=re.sub('\s+','',import_match.group(1))
+ bindings_match=self.re_import_bindings.match(import_match_str)
+ if bindings_match:
+ import_match_str=bindings_match.group(1)
+ matches=import_match_str.split(',')
+ for match in matches:
+ alias_match=self.re_import_alias.match(match)
+ if alias_match:
+ match=alias_match.group(1)
+ lst.append(match)
+ return lst
+ def start(self,node):
+ self.waiting=[node]
+ while self.waiting:
+ nd=self.waiting.pop(0)
+ self.iter(nd)
+ def iter(self,node):
+ path=node.abspath()
+ code="".join(filter_comments(path))
+ names=self.get_strings(code)
+ for x in names:
+ if x in self.allnames:continue
+ self.allnames.append(x)
+ self.tryfind(x)
+def scan(self):
+ env=self.env
+ gruik=d_parser(env,self.generator.includes_nodes)
+ node=self.inputs[0]
+ gruik.start(node)
+ nodes=gruik.nodes
+ names=gruik.names
+ if Logs.verbose:
+ Logs.debug('deps: deps for %s: %r; unresolved %r'%(str(node),nodes,names))
+ return(nodes,names)
diff --git a/waflib/Tools/dbus.py b/waflib/Tools/dbus.py
new file mode 100644
index 0000000..9204da8
--- /dev/null
+++ b/waflib/Tools/dbus.py
@@ -0,0 +1,30 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Task,Errors
+from waflib.TaskGen import taskgen_method,before_method
+def add_dbus_file(self,filename,prefix,mode):
+ if not hasattr(self,'dbus_lst'):
+ self.dbus_lst=[]
+ if not'process_dbus'in self.meths:
+ self.meths.append('process_dbus')
+ self.dbus_lst.append([filename,prefix,mode])
+def process_dbus(self):
+ for filename,prefix,mode in getattr(self,'dbus_lst',[]):
+ node=self.path.find_resource(filename)
+ if not node:
+ raise Errors.WafError('file not found '+filename)
+ tsk=self.create_task('dbus_binding_tool',node,node.change_ext('.h'))
+ tsk.env.DBUS_BINDING_TOOL_PREFIX=prefix
+ tsk.env.DBUS_BINDING_TOOL_MODE=mode
+class dbus_binding_tool(Task.Task):
+ color='BLUE'
+ ext_out=['.h']
+ run_str='${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}'
+ shell=True
+def configure(conf):
+ dbus_binding_tool=conf.find_program('dbus-binding-tool',var='DBUS_BINDING_TOOL')
+
+taskgen_method(add_dbus_file)
+before_method('apply_core')(process_dbus) \ No newline at end of file
diff --git a/waflib/Tools/dmd.py b/waflib/Tools/dmd.py
new file mode 100644
index 0000000..7d3f7df
--- /dev/null
+++ b/waflib/Tools/dmd.py
@@ -0,0 +1,47 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+from waflib.Tools import ar,d
+from waflib.Configure import conf
+def find_dmd(conf):
+ conf.find_program(['dmd','ldc'],var='D')
+def common_flags_ldc(conf):
+ v=conf.env
+ v['DFLAGS']=['-d-version=Posix']
+ v['LINKFLAGS']=[]
+ v['DFLAGS_dshlib']=['-relocation-model=pic']
+def common_flags_dmd(conf):
+ v=conf.env
+ v['D_SRC_F']=['-c']
+ v['D_TGT_F']='-of%s'
+ v['D_LINKER']=v['D']
+ v['DLNK_SRC_F']=''
+ v['DLNK_TGT_F']='-of%s'
+ v['DINC_ST']='-I%s'
+ v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
+ v['DSTLIB_ST']=v['DSHLIB_ST']='-L-l%s'
+ v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L-L%s'
+ v['LINKFLAGS_dprogram']=['-quiet']
+ v['DFLAGS_dshlib']=['-fPIC']
+ v['LINKFLAGS_dshlib']=['-L-shared']
+ v['DHEADER_ext']='.di'
+ v.DFLAGS_d_with_header=['-H','-Hf']
+ v['D_HDR_F']='%s'
+def configure(conf):
+ conf.find_dmd()
+ if sys.platform=='win32':
+ out=conf.cmd_and_log([conf.env.D,'--help'])
+ if out.find("D Compiler v2.")>-1:
+ conf.fatal('dmd2 on Windows is not supported, use gdc or ldc instead')
+ conf.load('ar')
+ conf.load('d')
+ conf.common_flags_dmd()
+ conf.d_platform_flags()
+ if str(conf.env.D).find('ldc')>-1:
+ conf.common_flags_ldc()
+
+conf(find_dmd)
+conf(common_flags_ldc)
+conf(common_flags_dmd) \ No newline at end of file
diff --git a/waflib/Tools/errcheck.py b/waflib/Tools/errcheck.py
new file mode 100644
index 0000000..93cb6c3
--- /dev/null
+++ b/waflib/Tools/errcheck.py
@@ -0,0 +1,161 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+typos={'feature':'features','sources':'source','targets':'target','include':'includes','export_include':'export_includes','define':'defines','importpath':'includes','installpath':'install_path',}
+meths_typos=['__call__','program','shlib','stlib','objects']
+from waflib import Logs,Build,Node,Task,TaskGen,ConfigSet,Errors,Utils
+import waflib.Tools.ccroot
+def check_same_targets(self):
+ mp=Utils.defaultdict(list)
+ uids={}
+ def check_task(tsk):
+ if not isinstance(tsk,Task.Task):
+ return
+ for node in tsk.outputs:
+ mp[node].append(tsk)
+ try:
+ uids[tsk.uid()].append(tsk)
+ except:
+ uids[tsk.uid()]=[tsk]
+ for g in self.groups:
+ for tg in g:
+ try:
+ for tsk in tg.tasks:
+ check_task(tsk)
+ except AttributeError:
+ check_task(tg)
+ dupe=False
+ for(k,v)in mp.items():
+ if len(v)>1:
+ dupe=True
+ msg='* Node %r is created by more than once%s. The task generators are:'%(k,Logs.verbose==1 and" (full message on 'waf -v -v')"or"")
+ Logs.error(msg)
+ for x in v:
+ if Logs.verbose>1:
+ Logs.error(' %d. %r'%(1+v.index(x),x.generator))
+ else:
+ Logs.error(' %d. %r in %r'%(1+v.index(x),x.generator.name,getattr(x.generator,'path',None)))
+ if not dupe:
+ for(k,v)in uids.items():
+ if len(v)>1:
+ Logs.error('* Several tasks use the same identifier. Please check the information on\n http://waf.googlecode.com/git/docs/apidocs/Task.html#waflib.Task.Task.uid')
+ for tsk in v:
+ Logs.error(' - object %r (%r) defined in %r'%(tsk.__class__.__name__,tsk,tsk.generator))
+def check_invalid_constraints(self):
+ feat=set([])
+ for x in list(TaskGen.feats.values()):
+ feat.union(set(x))
+ for(x,y)in TaskGen.task_gen.prec.items():
+ feat.add(x)
+ feat.union(set(y))
+ ext=set([])
+ for x in TaskGen.task_gen.mappings.values():
+ ext.add(x.__name__)
+ invalid=ext&feat
+ if invalid:
+ Logs.error('The methods %r have invalid annotations: @extension <-> @feature/@before_method/@after_method'%list(invalid))
+ for cls in list(Task.classes.values()):
+ for x in('before','after'):
+ for y in Utils.to_list(getattr(cls,x,[])):
+ if not Task.classes.get(y,None):
+ Logs.error('Erroneous order constraint %r=%r on task class %r'%(x,y,cls.__name__))
+ if getattr(cls,'rule',None):
+ Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")'%cls.__name__)
+def replace(m):
+ oldcall=getattr(Build.BuildContext,m)
+ def call(self,*k,**kw):
+ ret=oldcall(self,*k,**kw)
+ for x in typos:
+ if x in kw:
+ err=True
+ Logs.error('Fix the typo %r -> %r on %r'%(x,typos[x],ret))
+ return ret
+ setattr(Build.BuildContext,m,call)
+def enhance_lib():
+ for m in meths_typos:
+ replace(m)
+ def ant_glob(self,*k,**kw):
+ if k:
+ lst=Utils.to_list(k[0])
+ for pat in lst:
+ if'..'in pat.split('/'):
+ Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'"%k[0])
+ if kw.get('remove',True):
+ try:
+ if self.is_child_of(self.ctx.bldnode)and not kw.get('quiet',False):
+ Logs.error('Using ant_glob on the build folder (%r) is dangerous (quiet=True to disable this warning)'%self)
+ except AttributeError:
+ pass
+ return self.old_ant_glob(*k,**kw)
+ Node.Node.old_ant_glob=Node.Node.ant_glob
+ Node.Node.ant_glob=ant_glob
+ old=Task.is_before
+ def is_before(t1,t2):
+ ret=old(t1,t2)
+ if ret and old(t2,t1):
+ Logs.error('Contradictory order constraints in classes %r %r'%(t1,t2))
+ return ret
+ Task.is_before=is_before
+ def check_err_features(self):
+ lst=self.to_list(self.features)
+ if'shlib'in lst:
+ Logs.error('feature shlib -> cshlib, dshlib or cxxshlib')
+ for x in('c','cxx','d','fc'):
+ if not x in lst and lst and lst[0]in[x+y for y in('program','shlib','stlib')]:
+ Logs.error('%r features is probably missing %r'%(self,x))
+ TaskGen.feature('*')(check_err_features)
+ def check_err_order(self):
+ if not hasattr(self,'rule'):
+ for x in('before','after','ext_in','ext_out'):
+ if hasattr(self,x):
+ Logs.warn('Erroneous order constraint %r on non-rule based task generator %r'%(x,self))
+ else:
+ for x in('before','after'):
+ for y in self.to_list(getattr(self,x,[])):
+ if not Task.classes.get(y,None):
+ Logs.error('Erroneous order constraint %s=%r on %r'%(x,y,self))
+ TaskGen.feature('*')(check_err_order)
+ def check_compile(self):
+ check_invalid_constraints(self)
+ try:
+ ret=self.orig_compile()
+ finally:
+ check_same_targets(self)
+ return ret
+ Build.BuildContext.orig_compile=Build.BuildContext.compile
+ Build.BuildContext.compile=check_compile
+ def use_rec(self,name,**kw):
+ try:
+ y=self.bld.get_tgen_by_name(name)
+ except Errors.WafError:
+ pass
+ else:
+ idx=self.bld.get_group_idx(self)
+ odx=self.bld.get_group_idx(y)
+ if odx>idx:
+ msg="Invalid 'use' across build groups:"
+ if Logs.verbose>1:
+ msg+='\n target %r\n uses:\n %r'%(self,y)
+ else:
+ msg+=" %r uses %r (try 'waf -v -v' for the full error)"%(self.name,name)
+ raise Errors.WafError(msg)
+ self.orig_use_rec(name,**kw)
+ TaskGen.task_gen.orig_use_rec=TaskGen.task_gen.use_rec
+ TaskGen.task_gen.use_rec=use_rec
+ def getattri(self,name,default=None):
+ if name=='append'or name=='add':
+ raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique')
+ elif name=='prepend':
+ raise Errors.WafError('env.prepend does not exist: use env.prepend_value')
+ if name in self.__slots__:
+ return object.__getattr__(self,name,default)
+ else:
+ return self[name]
+ ConfigSet.ConfigSet.__getattr__=getattri
+def options(opt):
+ enhance_lib()
+def configure(conf):
+ pass
diff --git a/waflib/Tools/fc.py b/waflib/Tools/fc.py
new file mode 100644
index 0000000..30b1b48
--- /dev/null
+++ b/waflib/Tools/fc.py
@@ -0,0 +1,123 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+import re
+from waflib import Utils,Task,TaskGen,Logs
+from waflib.Tools import ccroot,fc_config,fc_scan
+from waflib.TaskGen import feature,before_method,after_method,extension
+from waflib.Configure import conf
+ccroot.USELIB_VARS['fc']=set(['FCFLAGS','DEFINES','INCLUDES'])
+ccroot.USELIB_VARS['fcprogram_test']=ccroot.USELIB_VARS['fcprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+ccroot.USELIB_VARS['fcshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+ccroot.USELIB_VARS['fcstlib']=set(['ARFLAGS','LINKDEPS'])
+def dummy(self):
+ pass
+def fc_hook(self,node):
+ return self.create_compiled_task('fc',node)
+def modfile(conf,name):
+ return{'lower':name.lower()+'.mod','lower.MOD':name.upper()+'.MOD','UPPER.mod':name.upper()+'.mod','UPPER':name.upper()+'.MOD'}[conf.env.FC_MOD_CAPITALIZATION or'lower']
+def get_fortran_tasks(tsk):
+ bld=tsk.generator.bld
+ tasks=bld.get_tasks_group(bld.get_group_idx(tsk.generator))
+ return[x for x in tasks if isinstance(x,fc)and not getattr(x,'nomod',None)and not getattr(x,'mod_fortran_done',None)]
+class fc(Task.Task):
+ color='GREEN'
+ run_str='${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()}'
+ vars=["FORTRANMODPATHFLAG"]
+ def scan(self):
+ tmp=fc_scan.fortran_parser(self.generator.includes_nodes)
+ tmp.task=self
+ tmp.start(self.inputs[0])
+ if Logs.verbose:
+ Logs.debug('deps: deps for %r: %r; unresolved %r'%(self.inputs,tmp.nodes,tmp.names))
+ return(tmp.nodes,tmp.names)
+ def runnable_status(self):
+ if getattr(self,'mod_fortran_done',None):
+ return super(fc,self).runnable_status()
+ bld=self.generator.bld
+ lst=get_fortran_tasks(self)
+ for tsk in lst:
+ tsk.mod_fortran_done=True
+ for tsk in lst:
+ ret=tsk.runnable_status()
+ if ret==Task.ASK_LATER:
+ for x in lst:
+ x.mod_fortran_done=None
+ return Task.ASK_LATER
+ ins=Utils.defaultdict(set)
+ outs=Utils.defaultdict(set)
+ for tsk in lst:
+ key=tsk.uid()
+ for x in bld.raw_deps[key]:
+ if x.startswith('MOD@'):
+ name=bld.modfile(x.replace('MOD@',''))
+ node=bld.srcnode.find_or_declare(name)
+ tsk.set_outputs(node)
+ outs[id(node)].add(tsk)
+ for tsk in lst:
+ key=tsk.uid()
+ for x in bld.raw_deps[key]:
+ if x.startswith('USE@'):
+ name=bld.modfile(x.replace('USE@',''))
+ node=bld.srcnode.find_resource(name)
+ if node and node not in tsk.outputs:
+ if not node in bld.node_deps[key]:
+ bld.node_deps[key].append(node)
+ ins[id(node)].add(tsk)
+ for k in ins.keys():
+ for a in ins[k]:
+ a.run_after.update(outs[k])
+ tmp=[]
+ for t in outs[k]:
+ tmp.extend(t.outputs)
+ a.dep_nodes.extend(tmp)
+ try:
+ a.dep_nodes.sort(key=lambda x:x.abspath())
+ except:
+ a.dep_nodes.sort(lambda x,y:cmp(x.abspath(),y.abspath()))
+ for tsk in lst:
+ try:
+ delattr(tsk,'cache_sig')
+ except AttributeError:
+ pass
+ return super(fc,self).runnable_status()
+class fcprogram(ccroot.link_task):
+ color='YELLOW'
+ run_str='${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB}'
+ inst_to='${BINDIR}'
+ chmod=Utils.O755
+class fcshlib(fcprogram):
+ inst_to='${LIBDIR}'
+class fcprogram_test(fcprogram):
+ def can_retrieve_cache(self):
+ return False
+ def runnable_status(self):
+ ret=super(fcprogram_test,self).runnable_status()
+ if ret==Task.SKIP_ME:
+ ret=Task.RUN_ME
+ return ret
+ def exec_command(self,cmd,**kw):
+ bld=self.generator.bld
+ kw['shell']=isinstance(cmd,str)
+ kw['stdout']=kw['stderr']=Utils.subprocess.PIPE
+ kw['cwd']=bld.variant_dir
+ bld.out=bld.err=''
+ bld.to_log('command: %s\n'%cmd)
+ kw['output']=0
+ try:
+ (bld.out,bld.err)=bld.cmd_and_log(cmd,**kw)
+ except Exception ,e:
+ return-1
+ if bld.out:
+ bld.to_log("out: %s\n"%bld.out)
+ if bld.err:
+ bld.to_log("err: %s\n"%bld.err)
+class fcstlib(ccroot.stlink_task):
+ pass
+
+feature('fcprogram','fcshlib','fcstlib','fcprogram_test')(dummy)
+extension('.f','.f90','.F','.F90','.for','.FOR')(fc_hook)
+conf(modfile) \ No newline at end of file
diff --git a/waflib/Tools/fc_config.py b/waflib/Tools/fc_config.py
new file mode 100644
index 0000000..f9c97fa
--- /dev/null
+++ b/waflib/Tools/fc_config.py
@@ -0,0 +1,283 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re,shutil,os,sys,string,shlex
+from waflib.Configure import conf
+from waflib.TaskGen import feature,after_method,before_method
+from waflib import Build,Utils
+FC_FRAGMENT=' program main\n end program main\n'
+FC_FRAGMENT2=' PROGRAM MAIN\n END\n'
+def fc_flags(conf):
+ v=conf.env
+ v['FC_SRC_F']=[]
+ v['FC_TGT_F']=['-c','-o']
+ v['FCINCPATH_ST']='-I%s'
+ v['FCDEFINES_ST']='-D%s'
+ if not v['LINK_FC']:v['LINK_FC']=v['FC']
+ v['FCLNK_SRC_F']=[]
+ v['FCLNK_TGT_F']=['-o']
+ v['FCFLAGS_fcshlib']=['-fpic']
+ v['LINKFLAGS_fcshlib']=['-shared']
+ v['fcshlib_PATTERN']='lib%s.so'
+ v['fcstlib_PATTERN']='lib%s.a'
+ v['FCLIB_ST']='-l%s'
+ v['FCLIBPATH_ST']='-L%s'
+ v['FCSTLIB_ST']='-l%s'
+ v['FCSTLIBPATH_ST']='-L%s'
+ v['FCSTLIB_MARKER']='-Wl,-Bstatic'
+ v['FCSHLIB_MARKER']='-Wl,-Bdynamic'
+ v['SONAME_ST']='-Wl,-h,%s'
+def check_fortran(self,*k,**kw):
+ self.check_cc(fragment=FC_FRAGMENT,compile_filename='test.f',features='fc fcprogram',msg='Compiling a simple fortran app')
+def check_fc(self,*k,**kw):
+ kw['compiler']='fc'
+ if not'compile_mode'in kw:
+ kw['compile_mode']='fc'
+ if not'type'in kw:
+ kw['type']='fcprogram'
+ if not'compile_filename'in kw:
+ kw['compile_filename']='test.f90'
+ if not'code'in kw:
+ kw['code']=FC_FRAGMENT
+ return self.check(*k,**kw)
+def fortran_modifier_darwin(conf):
+ v=conf.env
+ v['FCFLAGS_fcshlib']=['-fPIC','-compatibility_version','1','-current_version','1']
+ v['LINKFLAGS_fcshlib']=['-dynamiclib']
+ v['fcshlib_PATTERN']='lib%s.dylib'
+ v['FRAMEWORKPATH_ST']='-F%s'
+ v['FRAMEWORK_ST']='-framework %s'
+ v['LINKFLAGS_fcstlib']=[]
+ v['FCSHLIB_MARKER']=''
+ v['FCSTLIB_MARKER']=''
+ v['SONAME_ST']=''
+def fortran_modifier_win32(conf):
+ v=conf.env
+ v['fcprogram_PATTERN']=v['fcprogram_test_PATTERN']='%s.exe'
+ v['fcshlib_PATTERN']='%s.dll'
+ v['implib_PATTERN']='lib%s.dll.a'
+ v['IMPLIB_ST']='-Wl,--out-implib,%s'
+ v['FCFLAGS_fcshlib']=[]
+ v.append_value('FCFLAGS_fcshlib',['-DDLL_EXPORT'])
+ v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+def fortran_modifier_cygwin(conf):
+ fortran_modifier_win32(conf)
+ v=conf.env
+ v['fcshlib_PATTERN']='cyg%s.dll'
+ v.append_value('LINKFLAGS_fcshlib',['-Wl,--enable-auto-image-base'])
+ v['FCFLAGS_fcshlib']=[]
+def check_fortran_dummy_main(self,*k,**kw):
+ if not self.env.CC:
+ self.fatal('A c compiler is required for check_fortran_dummy_main')
+ lst=['MAIN__','__MAIN','_MAIN','MAIN_','MAIN']
+ lst.extend([m.lower()for m in lst])
+ lst.append('')
+ self.start_msg('Detecting whether we need a dummy main')
+ for main in lst:
+ kw['fortran_main']=main
+ try:
+ self.check_cc(fragment='int %s() { return 0; }\n'%(main or'test'),features='c fcprogram',mandatory=True)
+ if not main:
+ self.env.FC_MAIN=-1
+ self.end_msg('no')
+ else:
+ self.env.FC_MAIN=main
+ self.end_msg('yes %s'%main)
+ break
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ self.end_msg('not found')
+ self.fatal('could not detect whether fortran requires a dummy main, see the config.log')
+GCC_DRIVER_LINE=re.compile('^Driving:')
+POSIX_STATIC_EXT=re.compile('\S+\.a')
+POSIX_LIB_FLAGS=re.compile('-l\S+')
+def is_link_verbose(self,txt):
+ assert isinstance(txt,str)
+ for line in txt.splitlines():
+ if not GCC_DRIVER_LINE.search(line):
+ if POSIX_STATIC_EXT.search(line)or POSIX_LIB_FLAGS.search(line):
+ return True
+ return False
+def check_fortran_verbose_flag(self,*k,**kw):
+ self.start_msg('fortran link verbose flag')
+ for x in['-v','--verbose','-verbose','-V']:
+ try:
+ self.check_cc(features='fc fcprogram_test',fragment=FC_FRAGMENT2,compile_filename='test.f',linkflags=[x],mandatory=True)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ if self.is_link_verbose(self.test_bld.err)or self.is_link_verbose(self.test_bld.out):
+ self.end_msg(x)
+ break
+ else:
+ self.end_msg('failure')
+ self.fatal('Could not obtain the fortran link verbose flag (see config.log)')
+ self.env.FC_VERBOSE_FLAG=x
+ return x
+LINKFLAGS_IGNORED=[r'-lang*',r'-lcrt[a-zA-Z0-9\.]*\.o',r'-lc$',r'-lSystem',r'-libmil',r'-LIST:*',r'-LNO:*']
+if os.name=='nt':
+ LINKFLAGS_IGNORED.extend([r'-lfrt*',r'-luser32',r'-lkernel32',r'-ladvapi32',r'-lmsvcrt',r'-lshell32',r'-lmingw',r'-lmoldname'])
+else:
+ LINKFLAGS_IGNORED.append(r'-lgcc*')
+RLINKFLAGS_IGNORED=[re.compile(f)for f in LINKFLAGS_IGNORED]
+def _match_ignore(line):
+ for i in RLINKFLAGS_IGNORED:
+ if i.match(line):
+ return True
+ return False
+def parse_fortran_link(lines):
+ final_flags=[]
+ for line in lines:
+ if not GCC_DRIVER_LINE.match(line):
+ _parse_flink_line(line,final_flags)
+ return final_flags
+SPACE_OPTS=re.compile('^-[LRuYz]$')
+NOSPACE_OPTS=re.compile('^-[RL]')
+def _parse_flink_line(line,final_flags):
+ lexer=shlex.shlex(line,posix=True)
+ lexer.whitespace_split=True
+ t=lexer.get_token()
+ tmp_flags=[]
+ while t:
+ def parse(token):
+ if _match_ignore(token):
+ pass
+ elif token.startswith('-lkernel32')and sys.platform=='cygwin':
+ tmp_flags.append(token)
+ elif SPACE_OPTS.match(token):
+ t=lexer.get_token()
+ if t.startswith('P,'):
+ t=t[2:]
+ for opt in t.split(os.pathsep):
+ tmp_flags.append('-L%s'%opt)
+ elif NOSPACE_OPTS.match(token):
+ tmp_flags.append(token)
+ elif POSIX_LIB_FLAGS.match(token):
+ tmp_flags.append(token)
+ else:
+ pass
+ t=lexer.get_token()
+ return t
+ t=parse(t)
+ final_flags.extend(tmp_flags)
+ return final_flags
+def check_fortran_clib(self,autoadd=True,*k,**kw):
+ if not self.env.FC_VERBOSE_FLAG:
+ self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?')
+ self.start_msg('Getting fortran runtime link flags')
+ try:
+ self.check_cc(fragment=FC_FRAGMENT2,compile_filename='test.f',features='fc fcprogram_test',linkflags=[self.env.FC_VERBOSE_FLAG])
+ except:
+ self.end_msg(False)
+ if kw.get('mandatory',True):
+ conf.fatal('Could not find the c library flags')
+ else:
+ out=self.test_bld.err
+ flags=parse_fortran_link(out.splitlines())
+ self.end_msg('ok (%s)'%' '.join(flags))
+ self.env.LINKFLAGS_CLIB=flags
+ return flags
+ return[]
+def getoutput(conf,cmd,stdin=False):
+ if stdin:
+ stdin=Utils.subprocess.PIPE
+ else:
+ stdin=None
+ env=conf.env.env or None
+ try:
+ p=Utils.subprocess.Popen(cmd,stdin=stdin,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
+ if stdin:
+ p.stdin.write('\n')
+ stdout,stderr=p.communicate()
+ except:
+ conf.fatal('could not determine the compiler version %r'%cmd)
+ else:
+ if not isinstance(stdout,str):
+ stdout=stdout.decode(sys.stdout.encoding)
+ if not isinstance(stderr,str):
+ stderr=stderr.decode(sys.stdout.encoding)
+ return stdout,stderr
+ROUTINES_CODE="""\
+ subroutine foobar()
+ return
+ end
+ subroutine foo_bar()
+ return
+ end
+"""
+MAIN_CODE="""
+void %(dummy_func_nounder)s(void);
+void %(dummy_func_under)s(void);
+int %(main_func_name)s() {
+ %(dummy_func_nounder)s();
+ %(dummy_func_under)s();
+ return 0;
+}
+"""
+def link_main_routines_tg_method(self):
+ def write_test_file(task):
+ task.outputs[0].write(task.generator.code)
+ bld=self.bld
+ bld(rule=write_test_file,target='main.c',code=MAIN_CODE%self.__dict__)
+ bld(rule=write_test_file,target='test.f',code=ROUTINES_CODE)
+ bld(features='fc fcstlib',source='test.f',target='test')
+ bld(features='c fcprogram',source='main.c',target='app',use='test')
+def mangling_schemes():
+ for u in['_','']:
+ for du in['','_']:
+ for c in["lower","upper"]:
+ yield(u,du,c)
+def mangle_name(u,du,c,name):
+ return getattr(name,c)()+u+(name.find('_')!=-1 and du or'')
+def check_fortran_mangling(self,*k,**kw):
+ if not self.env.CC:
+ self.fatal('A c compiler is required for link_main_routines')
+ if not self.env.FC:
+ self.fatal('A fortran compiler is required for link_main_routines')
+ if not self.env.FC_MAIN:
+ self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)')
+ self.start_msg('Getting fortran mangling scheme')
+ for(u,du,c)in mangling_schemes():
+ try:
+ self.check_cc(compile_filename=[],features='link_main_routines_func',msg='nomsg',errmsg='nomsg',mandatory=True,dummy_func_nounder=mangle_name(u,du,c,"foobar"),dummy_func_under=mangle_name(u,du,c,"foo_bar"),main_func_name=self.env.FC_MAIN)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ self.end_msg("ok ('%s', '%s', '%s-case')"%(u,du,c))
+ self.env.FORTRAN_MANGLING=(u,du,c)
+ break
+ else:
+ self.end_msg(False)
+ self.fatal('mangler not found')
+ return(u,du,c)
+def set_lib_pat(self):
+ self.env['fcshlib_PATTERN']=self.env['pyext_PATTERN']
+def detect_openmp(self):
+ for x in['-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp']:
+ try:
+ self.check_fc(msg='Checking for OpenMP flag %s'%x,fragment='program main\n call omp_get_num_threads()\nend program main',fcflags=x,linkflags=x,uselib_store='OPENMP')
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ break
+ else:
+ self.fatal('Could not find OpenMP')
+
+conf(fc_flags)
+conf(check_fortran)
+conf(check_fc)
+conf(fortran_modifier_darwin)
+conf(fortran_modifier_win32)
+conf(fortran_modifier_cygwin)
+conf(check_fortran_dummy_main)
+conf(is_link_verbose)
+conf(check_fortran_verbose_flag)
+conf(check_fortran_clib)
+feature('link_main_routines_func')(link_main_routines_tg_method)
+before_method('process_source')(link_main_routines_tg_method)
+conf(check_fortran_mangling)
+feature('pyext')(set_lib_pat)
+before_method('propagate_uselib_vars','apply_link')(set_lib_pat)
+conf(detect_openmp) \ No newline at end of file
diff --git a/waflib/Tools/fc_scan.py b/waflib/Tools/fc_scan.py
new file mode 100644
index 0000000..48e06b5
--- /dev/null
+++ b/waflib/Tools/fc_scan.py
@@ -0,0 +1,68 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils,Task,TaskGen,Logs
+from waflib.TaskGen import feature,before_method,after_method,extension
+from waflib.Configure import conf
+INC_REGEX="""(?:^|['">]\s*;)\s*INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])"""
+USE_REGEX="""(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
+MOD_REGEX="""(?:^|;)\s*MODULE(?!\s*PROCEDURE)(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
+re_inc=re.compile(INC_REGEX,re.I)
+re_use=re.compile(USE_REGEX,re.I)
+re_mod=re.compile(MOD_REGEX,re.I)
+class fortran_parser(object):
+ def __init__(self,incpaths):
+ self.seen=[]
+ self.nodes=[]
+ self.names=[]
+ self.incpaths=incpaths
+ def find_deps(self,node):
+ txt=node.read()
+ incs=[]
+ uses=[]
+ mods=[]
+ for line in txt.splitlines():
+ m=re_inc.search(line)
+ if m:
+ incs.append(m.group(1))
+ m=re_use.search(line)
+ if m:
+ uses.append(m.group(1))
+ m=re_mod.search(line)
+ if m:
+ mods.append(m.group(1))
+ return(incs,uses,mods)
+ def start(self,node):
+ self.waiting=[node]
+ while self.waiting:
+ nd=self.waiting.pop(0)
+ self.iter(nd)
+ def iter(self,node):
+ path=node.abspath()
+ incs,uses,mods=self.find_deps(node)
+ for x in incs:
+ if x in self.seen:
+ continue
+ self.seen.append(x)
+ self.tryfind_header(x)
+ for x in uses:
+ name="USE@%s"%x
+ if not name in self.names:
+ self.names.append(name)
+ for x in mods:
+ name="MOD@%s"%x
+ if not name in self.names:
+ self.names.append(name)
+ def tryfind_header(self,filename):
+ found=None
+ for n in self.incpaths:
+ found=n.find_resource(filename)
+ if found:
+ self.nodes.append(found)
+ self.waiting.append(found)
+ break
+ if not found:
+ if not filename in self.names:
+ self.names.append(filename)
diff --git a/waflib/Tools/flex.py b/waflib/Tools/flex.py
new file mode 100644
index 0000000..d5f4367
--- /dev/null
+++ b/waflib/Tools/flex.py
@@ -0,0 +1,27 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import waflib.TaskGen
+def decide_ext(self,node):
+ if'cxx'in self.features:
+ return['.lex.cc']
+ return['.lex.c']
+def flexfun(tsk):
+ env=tsk.env
+ bld=tsk.generator.bld
+ wd=bld.variant_dir
+ def to_list(xx):
+ if isinstance(xx,str):return[xx]
+ return xx
+ tsk.last_cmd=lst=[]
+ lst.extend(to_list(env['FLEX']))
+ lst.extend(to_list(env['FLEXFLAGS']))
+ lst.extend([a.path_from(bld.bldnode)for a in tsk.inputs])
+ lst=[x for x in lst if x]
+ txt=bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0)
+ tsk.outputs[0].write(txt)
+waflib.TaskGen.declare_chain(name='flex',rule=flexfun,ext_in='.l',decider=decide_ext,)
+def configure(conf):
+ conf.find_program('flex',var='FLEX')
+ conf.env.FLEXFLAGS=['-t']
diff --git a/waflib/Tools/g95.py b/waflib/Tools/g95.py
new file mode 100644
index 0000000..a2bb542
--- /dev/null
+++ b/waflib/Tools/g95.py
@@ -0,0 +1,55 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan
+from waflib.Configure import conf
+def find_g95(conf):
+ fc=conf.find_program('g95',var='FC')
+ fc=conf.cmd_to_list(fc)
+ conf.get_g95_version(fc)
+ conf.env.FC_NAME='G95'
+def g95_flags(conf):
+ v=conf.env
+ v['FCFLAGS_fcshlib']=['-fPIC']
+ v['FORTRANMODFLAG']=['-fmod=','']
+ v['FCFLAGS_DEBUG']=['-Werror']
+def g95_modifier_win32(conf):
+ fc_config.fortran_modifier_win32(conf)
+def g95_modifier_cygwin(conf):
+ fc_config.fortran_modifier_cygwin(conf)
+def g95_modifier_darwin(conf):
+ fc_config.fortran_modifier_darwin(conf)
+def g95_modifier_platform(conf):
+ dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
+ g95_modifier_func=getattr(conf,'g95_modifier_'+dest_os,None)
+ if g95_modifier_func:
+ g95_modifier_func()
+def get_g95_version(conf,fc):
+ version_re=re.compile(r"g95\s*(?P<major>\d*)\.(?P<minor>\d*)").search
+ cmd=fc+['--version']
+ out,err=fc_config.getoutput(conf,cmd,stdin=False)
+ if out:
+ match=version_re(out)
+ else:
+ match=version_re(err)
+ if not match:
+ conf.fatal('cannot determine g95 version')
+ k=match.groupdict()
+ conf.env['FC_VERSION']=(k['major'],k['minor'])
+def configure(conf):
+ conf.find_g95()
+ conf.find_ar()
+ conf.fc_flags()
+ conf.g95_flags()
+ conf.g95_modifier_platform()
+
+conf(find_g95)
+conf(g95_flags)
+conf(g95_modifier_win32)
+conf(g95_modifier_cygwin)
+conf(g95_modifier_darwin)
+conf(g95_modifier_platform)
+conf(get_g95_version) \ No newline at end of file
diff --git a/waflib/Tools/gas.py b/waflib/Tools/gas.py
new file mode 100644
index 0000000..0aef0c4
--- /dev/null
+++ b/waflib/Tools/gas.py
@@ -0,0 +1,11 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import waflib.Tools.asm
+from waflib.Tools import ar
+def configure(conf):
+ conf.find_program(['gas','as','gcc'],var='AS')
+ conf.env.AS_TGT_F=['-o']
+ conf.env.ASLNK_TGT_F=['-o']
+ conf.find_ar()
diff --git a/waflib/Tools/gcc.py b/waflib/Tools/gcc.py
new file mode 100644
index 0000000..5734b76
--- /dev/null
+++ b/waflib/Tools/gcc.py
@@ -0,0 +1,98 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Configure,Options,Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+def find_gcc(conf):
+ cc=conf.find_program(['gcc','cc'],var='CC')
+ cc=conf.cmd_to_list(cc)
+ conf.get_cc_version(cc,gcc=True)
+ conf.env.CC_NAME='gcc'
+ conf.env.CC=cc
+def gcc_common_flags(conf):
+ v=conf.env
+ v['CC_SRC_F']=[]
+ v['CC_TGT_F']=['-c','-o']
+ if not v['LINK_CC']:v['LINK_CC']=v['CC']
+ v['CCLNK_SRC_F']=[]
+ v['CCLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['RPATH_ST']='-Wl,-rpath,%s'
+ v['SONAME_ST']='-Wl,-h,%s'
+ v['SHLIB_MARKER']='-Wl,-Bdynamic'
+ v['STLIB_MARKER']='-Wl,-Bstatic'
+ v['cprogram_PATTERN']='%s'
+ v['CFLAGS_cshlib']=['-fPIC']
+ v['LINKFLAGS_cshlib']=['-shared']
+ v['cshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cstlib']=['-Wl,-Bstatic']
+ v['cstlib_PATTERN']='lib%s.a'
+ v['LINKFLAGS_MACBUNDLE']=['-bundle','-undefined','dynamic_lookup']
+ v['CFLAGS_MACBUNDLE']=['-fPIC']
+ v['macbundle_PATTERN']='%s.bundle'
+def gcc_modifier_win32(conf):
+ v=conf.env
+ v['cprogram_PATTERN']='%s.exe'
+ v['cshlib_PATTERN']='%s.dll'
+ v['implib_PATTERN']='lib%s.dll.a'
+ v['IMPLIB_ST']='-Wl,--out-implib,%s'
+ v['CFLAGS_cshlib']=[]
+ v.append_value('CFLAGS_cshlib',['-DDLL_EXPORT'])
+ v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+def gcc_modifier_cygwin(conf):
+ gcc_modifier_win32(conf)
+ v=conf.env
+ v['cshlib_PATTERN']='cyg%s.dll'
+ v.append_value('LINKFLAGS_cshlib',['-Wl,--enable-auto-image-base'])
+ v['CFLAGS_cshlib']=[]
+def gcc_modifier_darwin(conf):
+ v=conf.env
+ v['CFLAGS_cshlib']=['-fPIC','-compatibility_version','1','-current_version','1']
+ v['LINKFLAGS_cshlib']=['-dynamiclib']
+ v['cshlib_PATTERN']='lib%s.dylib'
+ v['FRAMEWORKPATH_ST']='-F%s'
+ v['FRAMEWORK_ST']=['-framework']
+ v['ARCH_ST']=['-arch']
+ v['LINKFLAGS_cstlib']=[]
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['SONAME_ST']=[]
+def gcc_modifier_aix(conf):
+ v=conf.env
+ v['LINKFLAGS_cprogram']=['-Wl,-brtl']
+ v['LINKFLAGS_cshlib']=['-shared','-Wl,-brtl,-bexpfull']
+ v['SHLIB_MARKER']=[]
+def gcc_modifier_hpux(conf):
+ v=conf.env
+ v['SHLIB_MARKER']=[]
+ v['CFLAGS_cshlib']=['-fPIC','-DPIC']
+ v['cshlib_PATTERN']='lib%s.sl'
+def gcc_modifier_platform(conf):
+ gcc_modifier_func=getattr(conf,'gcc_modifier_'+conf.env.DEST_OS,None)
+ if gcc_modifier_func:
+ gcc_modifier_func()
+def configure(conf):
+ conf.find_gcc()
+ conf.find_ar()
+ conf.gcc_common_flags()
+ conf.gcc_modifier_platform()
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
+
+conf(find_gcc)
+conf(gcc_common_flags)
+conf(gcc_modifier_win32)
+conf(gcc_modifier_cygwin)
+conf(gcc_modifier_darwin)
+conf(gcc_modifier_aix)
+conf(gcc_modifier_hpux)
+conf(gcc_modifier_platform) \ No newline at end of file
diff --git a/waflib/Tools/gdc.py b/waflib/Tools/gdc.py
new file mode 100644
index 0000000..ff8a8ab
--- /dev/null
+++ b/waflib/Tools/gdc.py
@@ -0,0 +1,34 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+from waflib.Tools import ar,d
+from waflib.Configure import conf
+def find_gdc(conf):
+ conf.find_program('gdc',var='D')
+def common_flags_gdc(conf):
+ v=conf.env
+ v['DFLAGS']=[]
+ v['D_SRC_F']=['-c']
+ v['D_TGT_F']='-o%s'
+ v['D_LINKER']=v['D']
+ v['DLNK_SRC_F']=''
+ v['DLNK_TGT_F']='-o%s'
+ v['DINC_ST']='-I%s'
+ v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
+ v['DSTLIB_ST']=v['DSHLIB_ST']='-l%s'
+ v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L%s'
+ v['LINKFLAGS_dshlib']=['-shared']
+ v['DHEADER_ext']='.di'
+ v.DFLAGS_d_with_header='-fintfc'
+ v['D_HDR_F']='-fintfc-file=%s'
+def configure(conf):
+ conf.find_gdc()
+ conf.load('ar')
+ conf.load('d')
+ conf.common_flags_gdc()
+ conf.d_platform_flags()
+
+conf(find_gdc)
+conf(common_flags_gdc) \ No newline at end of file
diff --git a/waflib/Tools/gfortran.py b/waflib/Tools/gfortran.py
new file mode 100644
index 0000000..6dc1da1
--- /dev/null
+++ b/waflib/Tools/gfortran.py
@@ -0,0 +1,69 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan
+from waflib.Configure import conf
+def find_gfortran(conf):
+ fc=conf.find_program(['gfortran','g77'],var='FC')
+ fc=conf.cmd_to_list(fc)
+ conf.get_gfortran_version(fc)
+ conf.env.FC_NAME='GFORTRAN'
+def gfortran_flags(conf):
+ v=conf.env
+ v['FCFLAGS_fcshlib']=['-fPIC']
+ v['FORTRANMODFLAG']=['-J','']
+ v['FCFLAGS_DEBUG']=['-Werror']
+def gfortran_modifier_win32(conf):
+ fc_config.fortran_modifier_win32(conf)
+def gfortran_modifier_cygwin(conf):
+ fc_config.fortran_modifier_cygwin(conf)
+def gfortran_modifier_darwin(conf):
+ fc_config.fortran_modifier_darwin(conf)
+def gfortran_modifier_platform(conf):
+ dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
+ gfortran_modifier_func=getattr(conf,'gfortran_modifier_'+dest_os,None)
+ if gfortran_modifier_func:
+ gfortran_modifier_func()
+def get_gfortran_version(conf,fc):
+ version_re=re.compile(r"GNU\s*Fortran",re.I).search
+ cmd=fc+['--version']
+ out,err=fc_config.getoutput(conf,cmd,stdin=False)
+ if out:match=version_re(out)
+ else:match=version_re(err)
+ if not match:
+ conf.fatal('Could not determine the compiler type')
+ cmd=fc+['-dM','-E','-']
+ out,err=fc_config.getoutput(conf,cmd,stdin=True)
+ if out.find('__GNUC__')<0:
+ conf.fatal('Could not determine the compiler type')
+ k={}
+ out=out.split('\n')
+ import shlex
+ for line in out:
+ lst=shlex.split(line)
+ if len(lst)>2:
+ key=lst[1]
+ val=lst[2]
+ k[key]=val
+ def isD(var):
+ return var in k
+ def isT(var):
+ return var in k and k[var]!='0'
+ conf.env['FC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
+def configure(conf):
+ conf.find_gfortran()
+ conf.find_ar()
+ conf.fc_flags()
+ conf.gfortran_flags()
+ conf.gfortran_modifier_platform()
+
+conf(find_gfortran)
+conf(gfortran_flags)
+conf(gfortran_modifier_win32)
+conf(gfortran_modifier_cygwin)
+conf(gfortran_modifier_darwin)
+conf(gfortran_modifier_platform)
+conf(get_gfortran_version) \ No newline at end of file
diff --git a/waflib/Tools/glib2.py b/waflib/Tools/glib2.py
new file mode 100644
index 0000000..0d79e52
--- /dev/null
+++ b/waflib/Tools/glib2.py
@@ -0,0 +1,174 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Task,Utils,Options,Errors,Logs
+from waflib.TaskGen import taskgen_method,before_method,after_method,feature
+def add_marshal_file(self,filename,prefix):
+ if not hasattr(self,'marshal_list'):
+ self.marshal_list=[]
+ self.meths.append('process_marshal')
+ self.marshal_list.append((filename,prefix))
+def process_marshal(self):
+ for f,prefix in getattr(self,'marshal_list',[]):
+ node=self.path.find_resource(f)
+ if not node:
+ raise Errors.WafError('file not found %r'%f)
+ h_node=node.change_ext('.h')
+ c_node=node.change_ext('.c')
+ task=self.create_task('glib_genmarshal',node,[h_node,c_node])
+ task.env.GLIB_GENMARSHAL_PREFIX=prefix
+ self.source=self.to_nodes(getattr(self,'source',[]))
+ self.source.append(c_node)
+class glib_genmarshal(Task.Task):
+ def run(self):
+ bld=self.inputs[0].__class__.ctx
+ get=self.env.get_flat
+ cmd1="%s %s --prefix=%s --header > %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[0].abspath())
+ ret=bld.exec_command(cmd1)
+ if ret:return ret
+ c='''#include "%s"\n'''%self.outputs[0].name
+ self.outputs[1].write(c)
+ cmd2="%s %s --prefix=%s --body >> %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[1].abspath())
+ return bld.exec_command(cmd2)
+ vars=['GLIB_GENMARSHAL_PREFIX','GLIB_GENMARSHAL']
+ color='BLUE'
+ ext_out=['.h']
+def add_enums_from_template(self,source='',target='',template='',comments=''):
+ if not hasattr(self,'enums_list'):
+ self.enums_list=[]
+ self.meths.append('process_enums')
+ self.enums_list.append({'source':source,'target':target,'template':template,'file-head':'','file-prod':'','file-tail':'','enum-prod':'','value-head':'','value-prod':'','value-tail':'','comments':comments})
+def add_enums(self,source='',target='',file_head='',file_prod='',file_tail='',enum_prod='',value_head='',value_prod='',value_tail='',comments=''):
+ if not hasattr(self,'enums_list'):
+ self.enums_list=[]
+ self.meths.append('process_enums')
+ self.enums_list.append({'source':source,'template':'','target':target,'file-head':file_head,'file-prod':file_prod,'file-tail':file_tail,'enum-prod':enum_prod,'value-head':value_head,'value-prod':value_prod,'value-tail':value_tail,'comments':comments})
+def process_enums(self):
+ for enum in getattr(self,'enums_list',[]):
+ task=self.create_task('glib_mkenums')
+ env=task.env
+ inputs=[]
+ source_list=self.to_list(enum['source'])
+ if not source_list:
+ raise Errors.WafError('missing source '+str(enum))
+ source_list=[self.path.find_resource(k)for k in source_list]
+ inputs+=source_list
+ env['GLIB_MKENUMS_SOURCE']=[k.abspath()for k in source_list]
+ if not enum['target']:
+ raise Errors.WafError('missing target '+str(enum))
+ tgt_node=self.path.find_or_declare(enum['target'])
+ if tgt_node.name.endswith('.c'):
+ self.source.append(tgt_node)
+ env['GLIB_MKENUMS_TARGET']=tgt_node.abspath()
+ options=[]
+ if enum['template']:
+ template_node=self.path.find_resource(enum['template'])
+ options.append('--template %s'%(template_node.abspath()))
+ inputs.append(template_node)
+ params={'file-head':'--fhead','file-prod':'--fprod','file-tail':'--ftail','enum-prod':'--eprod','value-head':'--vhead','value-prod':'--vprod','value-tail':'--vtail','comments':'--comments'}
+ for param,option in params.items():
+ if enum[param]:
+ options.append('%s %r'%(option,enum[param]))
+ env['GLIB_MKENUMS_OPTIONS']=' '.join(options)
+ task.set_inputs(inputs)
+ task.set_outputs(tgt_node)
+class glib_mkenums(Task.Task):
+ run_str='${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}'
+ color='PINK'
+ ext_out=['.h']
+def add_settings_schemas(self,filename_list):
+ if not hasattr(self,'settings_schema_files'):
+ self.settings_schema_files=[]
+ if not isinstance(filename_list,list):
+ filename_list=[filename_list]
+ self.settings_schema_files.extend(filename_list)
+def add_settings_enums(self,namespace,filename_list):
+ if hasattr(self,'settings_enum_namespace'):
+ raise Errors.WafError("Tried to add gsettings enums to '%s' more than once"%self.name)
+ self.settings_enum_namespace=namespace
+ if type(filename_list)!='list':
+ filename_list=[filename_list]
+ self.settings_enum_files=filename_list
+def r_change_ext(self,ext):
+ name=self.name
+ k=name.rfind('.')
+ if k>=0:
+ name=name[:k]+ext
+ else:
+ name=name+ext
+ return self.parent.find_or_declare([name])
+def process_settings(self):
+ enums_tgt_node=[]
+ install_files=[]
+ settings_schema_files=getattr(self,'settings_schema_files',[])
+ if settings_schema_files and not self.env['GLIB_COMPILE_SCHEMAS']:
+ raise Errors.WafError("Unable to process GSettings schemas - glib-compile-schemas was not found during configure")
+ if hasattr(self,'settings_enum_files'):
+ enums_task=self.create_task('glib_mkenums')
+ source_list=self.settings_enum_files
+ source_list=[self.path.find_resource(k)for k in source_list]
+ enums_task.set_inputs(source_list)
+ enums_task.env['GLIB_MKENUMS_SOURCE']=[k.abspath()for k in source_list]
+ target=self.settings_enum_namespace+'.enums.xml'
+ tgt_node=self.path.find_or_declare(target)
+ enums_task.set_outputs(tgt_node)
+ enums_task.env['GLIB_MKENUMS_TARGET']=tgt_node.abspath()
+ enums_tgt_node=[tgt_node]
+ install_files.append(tgt_node)
+ options='--comments "<!-- @comment@ -->" --fhead "<schemalist>" --vhead " <@type@ id=\\"%s.@EnumName@\\">" --vprod " <value nick=\\"@valuenick@\\" value=\\"@valuenum@\\"/>" --vtail " </@type@>" --ftail "</schemalist>" '%(self.settings_enum_namespace)
+ enums_task.env['GLIB_MKENUMS_OPTIONS']=options
+ for schema in settings_schema_files:
+ schema_task=self.create_task('glib_validate_schema')
+ schema_node=self.path.find_resource(schema)
+ if not schema_node:
+ raise Errors.WafError("Cannot find the schema file '%s'"%schema)
+ install_files.append(schema_node)
+ source_list=enums_tgt_node+[schema_node]
+ schema_task.set_inputs(source_list)
+ schema_task.env['GLIB_COMPILE_SCHEMAS_OPTIONS']=[("--schema-file="+k.abspath())for k in source_list]
+ target_node=r_change_ext(schema_node,'.xml.valid')
+ schema_task.set_outputs(target_node)
+ schema_task.env['GLIB_VALIDATE_SCHEMA_OUTPUT']=target_node.abspath()
+ def compile_schemas_callback(bld):
+ if not bld.is_install:return
+ Logs.pprint('YELLOW','Updating GSettings schema cache')
+ command=Utils.subst_vars("${GLIB_COMPILE_SCHEMAS} ${GSETTINGSSCHEMADIR}",bld.env)
+ ret=self.bld.exec_command(command)
+ if self.bld.is_install:
+ if not self.env['GSETTINGSSCHEMADIR']:
+ raise Errors.WafError('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)')
+ if install_files:
+ self.bld.install_files(self.env['GSETTINGSSCHEMADIR'],install_files)
+ if not hasattr(self.bld,'_compile_schemas_registered'):
+ self.bld.add_post_fun(compile_schemas_callback)
+ self.bld._compile_schemas_registered=True
+class glib_validate_schema(Task.Task):
+ run_str='rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}'
+ color='PINK'
+def configure(conf):
+ conf.find_program('glib-genmarshal',var='GLIB_GENMARSHAL')
+ conf.find_perl_program('glib-mkenums',var='GLIB_MKENUMS')
+ conf.find_program('glib-compile-schemas',var='GLIB_COMPILE_SCHEMAS',mandatory=False)
+ def getstr(varname):
+ return getattr(Options.options,varname,getattr(conf.env,varname,''))
+ gsettingsschemadir=getstr('GSETTINGSSCHEMADIR')
+ if not gsettingsschemadir:
+ datadir=getstr('DATADIR')
+ if not datadir:
+ prefix=conf.env['PREFIX']
+ datadir=os.path.join(prefix,'share')
+ gsettingsschemadir=os.path.join(datadir,'glib-2.0','schemas')
+ conf.env['GSETTINGSSCHEMADIR']=gsettingsschemadir
+def options(opt):
+ opt.add_option('--gsettingsschemadir',help='GSettings schema location [Default: ${datadir}/glib-2.0/schemas]',default='',dest='GSETTINGSSCHEMADIR')
+
+taskgen_method(add_marshal_file)
+before_method('process_source')(process_marshal)
+taskgen_method(add_enums_from_template)
+taskgen_method(add_enums)
+before_method('process_source')(process_enums)
+taskgen_method(add_settings_schemas)
+taskgen_method(add_settings_enums)
+feature('glib2')(process_settings) \ No newline at end of file
diff --git a/waflib/Tools/gnu_dirs.py b/waflib/Tools/gnu_dirs.py
new file mode 100644
index 0000000..e698170
--- /dev/null
+++ b/waflib/Tools/gnu_dirs.py
@@ -0,0 +1,65 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils,Options,Context
+_options=[x.split(', ')for x in'''
+bindir, user executables, ${EXEC_PREFIX}/bin
+sbindir, system admin executables, ${EXEC_PREFIX}/sbin
+libexecdir, program executables, ${EXEC_PREFIX}/libexec
+sysconfdir, read-only single-machine data, ${PREFIX}/etc
+sharedstatedir, modifiable architecture-independent data, ${PREFIX}/com
+localstatedir, modifiable single-machine data, ${PREFIX}/var
+libdir, object code libraries, ${EXEC_PREFIX}/lib
+includedir, C header files, ${PREFIX}/include
+oldincludedir, C header files for non-gcc, /usr/include
+datarootdir, read-only arch.-independent data root, ${PREFIX}/share
+datadir, read-only architecture-independent data, ${DATAROOTDIR}
+infodir, info documentation, ${DATAROOTDIR}/info
+localedir, locale-dependent data, ${DATAROOTDIR}/locale
+mandir, man documentation, ${DATAROOTDIR}/man
+docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE}
+htmldir, html documentation, ${DOCDIR}
+dvidir, dvi documentation, ${DOCDIR}
+pdfdir, pdf documentation, ${DOCDIR}
+psdir, ps documentation, ${DOCDIR}
+'''.split('\n')if x]
+def configure(conf):
+ def get_param(varname,default):
+ return getattr(Options.options,varname,'')or default
+ env=conf.env
+ conf.env.LIBDIR=conf.env.BINDIR=[]
+ env['EXEC_PREFIX']=get_param('EXEC_PREFIX',env['PREFIX'])
+ env['PACKAGE']=getattr(Context.g_module,'APPNAME',None)or env['PACKAGE']
+ complete=False
+ iter=0
+ while not complete and iter<len(_options)+1:
+ iter+=1
+ complete=True
+ for name,help,default in _options:
+ name=name.upper()
+ if not env[name]:
+ try:
+ env[name]=Utils.subst_vars(get_param(name,default).replace('/',os.sep),env)
+ except TypeError:
+ complete=False
+ if not complete:
+ lst=[name for name,_,_ in _options if not env[name.upper()]]
+ raise conf.errors.WafError('Variable substitution failure %r'%lst)
+def options(opt):
+ inst_dir=opt.add_option_group('Installation directories','By default, "waf install" will put the files in\
+ "/usr/local/bin", "/usr/local/lib" etc. An installation prefix other\
+ than "/usr/local" can be given using "--prefix", for example "--prefix=$HOME"')
+ for k in('--prefix','--destdir'):
+ option=opt.parser.get_option(k)
+ if option:
+ opt.parser.remove_option(k)
+ inst_dir.add_option(option)
+ inst_dir.add_option('--exec-prefix',help='installation prefix [Default: ${PREFIX}]',default='',dest='EXEC_PREFIX')
+ dirs_options=opt.add_option_group('Pre-defined installation directories','')
+ for name,help,default in _options:
+ option_name='--'+name
+ str_default=default
+ str_help='%s [Default: %s]'%(help,str_default)
+ dirs_options.add_option(option_name,help=str_help,default='',dest=name.upper())
diff --git a/waflib/Tools/gxx.py b/waflib/Tools/gxx.py
new file mode 100644
index 0000000..647008d
--- /dev/null
+++ b/waflib/Tools/gxx.py
@@ -0,0 +1,98 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Configure,Options,Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+def find_gxx(conf):
+ cxx=conf.find_program(['g++','c++'],var='CXX')
+ cxx=conf.cmd_to_list(cxx)
+ conf.get_cc_version(cxx,gcc=True)
+ conf.env.CXX_NAME='gcc'
+ conf.env.CXX=cxx
+def gxx_common_flags(conf):
+ v=conf.env
+ v['CXX_SRC_F']=[]
+ v['CXX_TGT_F']=['-c','-o']
+ if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+ v['CXXLNK_SRC_F']=[]
+ v['CXXLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['RPATH_ST']='-Wl,-rpath,%s'
+ v['SONAME_ST']='-Wl,-h,%s'
+ v['SHLIB_MARKER']='-Wl,-Bdynamic'
+ v['STLIB_MARKER']='-Wl,-Bstatic'
+ v['cxxprogram_PATTERN']='%s'
+ v['CXXFLAGS_cxxshlib']=['-fPIC']
+ v['LINKFLAGS_cxxshlib']=['-shared']
+ v['cxxshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cxxstlib']=['-Wl,-Bstatic']
+ v['cxxstlib_PATTERN']='lib%s.a'
+ v['LINKFLAGS_MACBUNDLE']=['-bundle','-undefined','dynamic_lookup']
+ v['CXXFLAGS_MACBUNDLE']=['-fPIC']
+ v['macbundle_PATTERN']='%s.bundle'
+def gxx_modifier_win32(conf):
+ v=conf.env
+ v['cxxprogram_PATTERN']='%s.exe'
+ v['cxxshlib_PATTERN']='%s.dll'
+ v['implib_PATTERN']='lib%s.dll.a'
+ v['IMPLIB_ST']='-Wl,--out-implib,%s'
+ v['CXXFLAGS_cxxshlib']=[]
+ v.append_value('CXXFLAGS_cxxshlib',['-DDLL_EXPORT'])
+ v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+def gxx_modifier_cygwin(conf):
+ gxx_modifier_win32(conf)
+ v=conf.env
+ v['cxxshlib_PATTERN']='cyg%s.dll'
+ v.append_value('LINKFLAGS_cxxshlib',['-Wl,--enable-auto-image-base'])
+ v['CXXFLAGS_cxxshlib']=[]
+def gxx_modifier_darwin(conf):
+ v=conf.env
+ v['CXXFLAGS_cxxshlib']=['-fPIC','-compatibility_version','1','-current_version','1']
+ v['LINKFLAGS_cxxshlib']=['-dynamiclib']
+ v['cxxshlib_PATTERN']='lib%s.dylib'
+ v['FRAMEWORKPATH_ST']='-F%s'
+ v['FRAMEWORK_ST']=['-framework']
+ v['ARCH_ST']=['-arch']
+ v['LINKFLAGS_cxxstlib']=[]
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['SONAME_ST']=[]
+def gxx_modifier_aix(conf):
+ v=conf.env
+ v['LINKFLAGS_cxxprogram']=['-Wl,-brtl']
+ v['LINKFLAGS_cxxshlib']=['-shared','-Wl,-brtl,-bexpfull']
+ v['SHLIB_MARKER']=[]
+def gxx_modifier_hpux(conf):
+ v=conf.env
+ v['SHLIB_MARKER']=[]
+ v['CFLAGS_cxxshlib']=['-fPIC','-DPIC']
+ v['cxxshlib_PATTERN']='lib%s.sl'
+def gxx_modifier_platform(conf):
+ gxx_modifier_func=getattr(conf,'gxx_modifier_'+conf.env.DEST_OS,None)
+ if gxx_modifier_func:
+ gxx_modifier_func()
+def configure(conf):
+ conf.find_gxx()
+ conf.find_ar()
+ conf.gxx_common_flags()
+ conf.gxx_modifier_platform()
+ conf.cxx_load_tools()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
+
+conf(find_gxx)
+conf(gxx_common_flags)
+conf(gxx_modifier_win32)
+conf(gxx_modifier_cygwin)
+conf(gxx_modifier_darwin)
+conf(gxx_modifier_aix)
+conf(gxx_modifier_hpux)
+conf(gxx_modifier_platform) \ No newline at end of file
diff --git a/waflib/Tools/icc.py b/waflib/Tools/icc.py
new file mode 100644
index 0000000..eaac1cd
--- /dev/null
+++ b/waflib/Tools/icc.py
@@ -0,0 +1,31 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib.Tools import ccroot,ar,gcc
+from waflib.Configure import conf
+def find_icc(conf):
+ if sys.platform=='cygwin':
+ conf.fatal('The Intel compiler does not work on Cygwin')
+ v=conf.env
+ cc=None
+ if v['CC']:cc=v['CC']
+ elif'CC'in conf.environ:cc=conf.environ['CC']
+ if not cc:cc=conf.find_program('icc',var='CC')
+ if not cc:cc=conf.find_program('ICL',var='CC')
+ if not cc:conf.fatal('Intel C Compiler (icc) was not found')
+ cc=conf.cmd_to_list(cc)
+ conf.get_cc_version(cc,icc=True)
+ v['CC']=cc
+ v['CC_NAME']='icc'
+def configure(conf):
+ conf.find_icc()
+ conf.find_ar()
+ conf.gcc_common_flags()
+ conf.gcc_modifier_platform()
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
+
+conf(find_icc) \ No newline at end of file
diff --git a/waflib/Tools/icpc.py b/waflib/Tools/icpc.py
new file mode 100644
index 0000000..6a222ff
--- /dev/null
+++ b/waflib/Tools/icpc.py
@@ -0,0 +1,30 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib.Tools import ccroot,ar,gxx
+from waflib.Configure import conf
+def find_icpc(conf):
+ if sys.platform=='cygwin':
+ conf.fatal('The Intel compiler does not work on Cygwin')
+ v=conf.env
+ cxx=None
+ if v['CXX']:cxx=v['CXX']
+ elif'CXX'in conf.environ:cxx=conf.environ['CXX']
+ if not cxx:cxx=conf.find_program('icpc',var='CXX')
+ if not cxx:conf.fatal('Intel C++ Compiler (icpc) was not found')
+ cxx=conf.cmd_to_list(cxx)
+ conf.get_cc_version(cxx,icc=True)
+ v['CXX']=cxx
+ v['CXX_NAME']='icc'
+def configure(conf):
+ conf.find_icpc()
+ conf.find_ar()
+ conf.gxx_common_flags()
+ conf.gxx_modifier_platform()
+ conf.cxx_load_tools()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
+
+conf(find_icpc) \ No newline at end of file
diff --git a/waflib/Tools/ifort.py b/waflib/Tools/ifort.py
new file mode 100644
index 0000000..e9ad686
--- /dev/null
+++ b/waflib/Tools/ifort.py
@@ -0,0 +1,49 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan
+from waflib.Configure import conf
+def find_ifort(conf):
+ fc=conf.find_program('ifort',var='FC')
+ fc=conf.cmd_to_list(fc)
+ conf.get_ifort_version(fc)
+ conf.env.FC_NAME='IFORT'
+def ifort_modifier_cygwin(conf):
+ raise NotImplementedError("Ifort on cygwin not yet implemented")
+def ifort_modifier_win32(conf):
+ fc_config.fortran_modifier_win32(conf)
+def ifort_modifier_darwin(conf):
+ fc_config.fortran_modifier_darwin(conf)
+def ifort_modifier_platform(conf):
+ dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
+ ifort_modifier_func=getattr(conf,'ifort_modifier_'+dest_os,None)
+ if ifort_modifier_func:
+ ifort_modifier_func()
+def get_ifort_version(conf,fc):
+ version_re=re.compile(r"ifort\s*\(IFORT\)\s*(?P<major>\d*)\.(?P<minor>\d*)",re.I).search
+ cmd=fc+['--version']
+ out,err=fc_config.getoutput(conf,cmd,stdin=False)
+ if out:
+ match=version_re(out)
+ else:
+ match=version_re(err)
+ if not match:
+ conf.fatal('cannot determine ifort version.')
+ k=match.groupdict()
+ conf.env['FC_VERSION']=(k['major'],k['minor'])
+def configure(conf):
+ conf.find_ifort()
+ conf.find_program('xiar',var='AR')
+ conf.env.ARFLAGS='rcs'
+ conf.fc_flags()
+ conf.ifort_modifier_platform()
+
+conf(find_ifort)
+conf(ifort_modifier_cygwin)
+conf(ifort_modifier_win32)
+conf(ifort_modifier_darwin)
+conf(ifort_modifier_platform)
+conf(get_ifort_version) \ No newline at end of file
diff --git a/waflib/Tools/intltool.py b/waflib/Tools/intltool.py
new file mode 100644
index 0000000..54cb3a2
--- /dev/null
+++ b/waflib/Tools/intltool.py
@@ -0,0 +1,78 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Configure,TaskGen,Task,Utils,Runner,Options,Build,Logs
+import waflib.Tools.ccroot
+from waflib.TaskGen import feature,before_method
+from waflib.Logs import error
+def apply_intltool_in_f(self):
+ try:self.meths.remove('process_source')
+ except ValueError:pass
+ if not self.env.LOCALEDIR:
+ self.env.LOCALEDIR=self.env.PREFIX+'/share/locale'
+ for i in self.to_list(self.source):
+ node=self.path.find_resource(i)
+ podir=getattr(self,'podir','po')
+ podirnode=self.path.find_dir(podir)
+ if not podirnode:
+ error("could not find the podir %r"%podir)
+ continue
+ cache=getattr(self,'intlcache','.intlcache')
+ self.env['INTLCACHE']=os.path.join(self.path.bldpath(),podir,cache)
+ self.env['INTLPODIR']=podirnode.bldpath()
+ self.env['INTLFLAGS']=getattr(self,'flags',['-q','-u','-c'])
+ task=self.create_task('intltool',node,node.change_ext(''))
+ inst=getattr(self,'install_path','${LOCALEDIR}')
+ if inst:
+ self.bld.install_files(inst,task.outputs)
+def apply_intltool_po(self):
+ try:self.meths.remove('process_source')
+ except ValueError:pass
+ if not self.env.LOCALEDIR:
+ self.env.LOCALEDIR=self.env.PREFIX+'/share/locale'
+ appname=getattr(self,'appname','set_your_app_name')
+ podir=getattr(self,'podir','')
+ inst=getattr(self,'install_path','${LOCALEDIR}')
+ linguas=self.path.find_node(os.path.join(podir,'LINGUAS'))
+ if linguas:
+ file=open(linguas.abspath())
+ langs=[]
+ for line in file.readlines():
+ if not line.startswith('#'):
+ langs+=line.split()
+ file.close()
+ re_linguas=re.compile('[-a-zA-Z_@.]+')
+ for lang in langs:
+ if re_linguas.match(lang):
+ node=self.path.find_resource(os.path.join(podir,re_linguas.match(lang).group()+'.po'))
+ task=self.create_task('po',node,node.change_ext('.mo'))
+ if inst:
+ filename=task.outputs[0].name
+ (langname,ext)=os.path.splitext(filename)
+ inst_file=inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+appname+'.mo'
+ self.bld.install_as(inst_file,task.outputs[0],chmod=getattr(self,'chmod',Utils.O644),env=task.env)
+ else:
+ Logs.pprint('RED',"Error no LINGUAS file found in po directory")
+class po(Task.Task):
+ run_str='${MSGFMT} -o ${TGT} ${SRC}'
+ color='BLUE'
+class intltool(Task.Task):
+ run_str='${INTLTOOL} ${INTLFLAGS} ${INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}'
+ color='BLUE'
+def configure(conf):
+ conf.find_program('msgfmt',var='MSGFMT')
+ conf.find_perl_program('intltool-merge',var='INTLTOOL')
+ prefix=conf.env.PREFIX
+ datadir=conf.env.DATADIR
+ if not datadir:
+ datadir=os.path.join(prefix,'share')
+ conf.define('LOCALEDIR',os.path.join(datadir,'locale').replace('\\','\\\\'))
+ conf.define('DATADIR',datadir.replace('\\','\\\\'))
+ if conf.env.CC or conf.env.CXX:
+ conf.check(header_name='locale.h')
+
+before_method('process_source')(apply_intltool_in_f)
+feature('intltool_in')(apply_intltool_in_f)
+feature('intltool_po')(apply_intltool_po) \ No newline at end of file
diff --git a/waflib/Tools/irixcc.py b/waflib/Tools/irixcc.py
new file mode 100644
index 0000000..bae88c9
--- /dev/null
+++ b/waflib/Tools/irixcc.py
@@ -0,0 +1,49 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+def find_irixcc(conf):
+ v=conf.env
+ cc=None
+ if v['CC']:cc=v['CC']
+ elif'CC'in conf.environ:cc=conf.environ['CC']
+ if not cc:cc=conf.find_program('cc',var='CC')
+ if not cc:conf.fatal('irixcc was not found')
+ cc=conf.cmd_to_list(cc)
+ try:
+ conf.cmd_and_log(cc+['-version'])
+ except:
+ conf.fatal('%r -version could not be executed'%cc)
+ v['CC']=cc
+ v['CC_NAME']='irix'
+def irixcc_common_flags(conf):
+ v=conf.env
+ v['CC_SRC_F']=''
+ v['CC_TGT_F']=['-c','-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ if not v['LINK_CC']:v['LINK_CC']=v['CC']
+ v['CCLNK_SRC_F']=''
+ v['CCLNK_TGT_F']=['-o']
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['cprogram_PATTERN']='%s'
+ v['cshlib_PATTERN']='lib%s.so'
+ v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+ conf.find_irixcc()
+ conf.find_cpp()
+ conf.find_ar()
+ conf.irixcc_common_flags()
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
+
+conf(find_irixcc)
+conf(irixcc_common_flags) \ No newline at end of file
diff --git a/waflib/Tools/javaw.py b/waflib/Tools/javaw.py
new file mode 100644
index 0000000..26ff560
--- /dev/null
+++ b/waflib/Tools/javaw.py
@@ -0,0 +1,275 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+import os,re,tempfile,shutil
+from waflib.Configure import conf
+from waflib import TaskGen,Task,Utils,Options,Build,Errors,Node,Logs
+from waflib.TaskGen import feature,before_method,after_method
+from waflib.Tools import ccroot
+ccroot.USELIB_VARS['javac']=set(['CLASSPATH','JAVACFLAGS'])
+SOURCE_RE='**/*.java'
+JAR_RE='**/*'
+class_check_source='''
+public class Test {
+ public static void main(String[] argv) {
+ Class lib;
+ if (argv.length < 1) {
+ System.err.println("Missing argument");
+ System.exit(77);
+ }
+ try {
+ lib = Class.forName(argv[0]);
+ } catch (ClassNotFoundException e) {
+ System.err.println("ClassNotFoundException");
+ System.exit(1);
+ }
+ lib = null;
+ System.exit(0);
+ }
+}
+'''
+def apply_java(self):
+ Utils.def_attrs(self,jarname='',classpath='',sourcepath='.',srcdir='.',jar_mf_attributes={},jar_mf_classpath=[])
+ nodes_lst=[]
+ outdir=getattr(self,'outdir',None)
+ if outdir:
+ if not isinstance(outdir,Node.Node):
+ outdir=self.path.get_bld().make_node(self.outdir)
+ else:
+ outdir=self.path.get_bld()
+ outdir.mkdir()
+ self.outdir=outdir
+ self.env['OUTDIR']=outdir.abspath()
+ self.javac_task=tsk=self.create_task('javac')
+ tmp=[]
+ srcdir=getattr(self,'srcdir','')
+ if isinstance(srcdir,Node.Node):
+ srcdir=[srcdir]
+ for x in Utils.to_list(srcdir):
+ if isinstance(x,Node.Node):
+ y=x
+ else:
+ y=self.path.find_dir(x)
+ if not y:
+ self.bld.fatal('Could not find the folder %s from %s'%(x,self.path))
+ tmp.append(y)
+ tsk.srcdir=tmp
+ if getattr(self,'compat',None):
+ tsk.env.append_value('JAVACFLAGS',['-source',self.compat])
+ if hasattr(self,'sourcepath'):
+ fold=[isinstance(x,Node.Node)and x or self.path.find_dir(x)for x in self.to_list(self.sourcepath)]
+ names=os.pathsep.join([x.srcpath()for x in fold])
+ else:
+ names=[x.srcpath()for x in tsk.srcdir]
+ if names:
+ tsk.env.append_value('JAVACFLAGS',['-sourcepath',names])
+def use_javac_files(self):
+ lst=[]
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ names=self.to_list(getattr(self,'use',[]))
+ get=self.bld.get_tgen_by_name
+ for x in names:
+ try:
+ y=get(x)
+ except:
+ self.uselib.append(x)
+ else:
+ y.post()
+ lst.append(y.jar_task.outputs[0].abspath())
+ self.javac_task.set_run_after(y.jar_task)
+ if lst:
+ self.env.append_value('CLASSPATH',lst)
+def set_classpath(self):
+ self.env.append_value('CLASSPATH',getattr(self,'classpath',[]))
+ for x in self.tasks:
+ x.env.CLASSPATH=os.pathsep.join(self.env.CLASSPATH)+os.pathsep
+def jar_files(self):
+ destfile=getattr(self,'destfile','test.jar')
+ jaropts=getattr(self,'jaropts',[])
+ manifest=getattr(self,'manifest',None)
+ basedir=getattr(self,'basedir',None)
+ if basedir:
+ if not isinstance(self.basedir,Node.Node):
+ basedir=self.path.get_bld().make_node(basedir)
+ else:
+ basedir=self.path.get_bld()
+ if not basedir:
+ self.bld.fatal('Could not find the basedir %r for %r'%(self.basedir,self))
+ self.jar_task=tsk=self.create_task('jar_create')
+ if manifest:
+ jarcreate=getattr(self,'jarcreate','cfm')
+ node=self.path.find_node(manifest)
+ tsk.dep_nodes.append(node)
+ jaropts.insert(0,node.abspath())
+ else:
+ jarcreate=getattr(self,'jarcreate','cf')
+ if not isinstance(destfile,Node.Node):
+ destfile=self.path.find_or_declare(destfile)
+ if not destfile:
+ self.bld.fatal('invalid destfile %r for %r'%(destfile,self))
+ tsk.set_outputs(destfile)
+ tsk.basedir=basedir
+ jaropts.append('-C')
+ jaropts.append(basedir.bldpath())
+ jaropts.append('.')
+ tsk.env['JAROPTS']=jaropts
+ tsk.env['JARCREATE']=jarcreate
+ if getattr(self,'javac_task',None):
+ tsk.set_run_after(self.javac_task)
+def use_jar_files(self):
+ lst=[]
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ names=self.to_list(getattr(self,'use',[]))
+ get=self.bld.get_tgen_by_name
+ for x in names:
+ try:
+ y=get(x)
+ except:
+ self.uselib.append(x)
+ else:
+ y.post()
+ self.jar_task.run_after.update(y.tasks)
+class jar_create(Task.Task):
+ color='GREEN'
+ run_str='${JAR} ${JARCREATE} ${TGT} ${JAROPTS}'
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ if not self.inputs:
+ global JAR_RE
+ try:
+ self.inputs=[x for x in self.basedir.ant_glob(JAR_RE,remove=False)if id(x)!=id(self.outputs[0])]
+ except:
+ raise Errors.WafError('Could not find the basedir %r for %r'%(self.basedir,self))
+ return super(jar_create,self).runnable_status()
+class javac(Task.Task):
+ color='BLUE'
+ nocache=True
+ vars=['CLASSPATH','JAVACFLAGS','JAVAC','OUTDIR']
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ if not self.inputs:
+ global SOURCE_RE
+ self.inputs=[]
+ for x in self.srcdir:
+ self.inputs.extend(x.ant_glob(SOURCE_RE,remove=False))
+ return super(javac,self).runnable_status()
+ def run(self):
+ env=self.env
+ gen=self.generator
+ bld=gen.bld
+ wd=bld.bldnode.abspath()
+ def to_list(xx):
+ if isinstance(xx,str):return[xx]
+ return xx
+ cmd=[]
+ cmd.extend(to_list(env['JAVAC']))
+ cmd.extend(['-classpath'])
+ cmd.extend(to_list(env['CLASSPATH']))
+ cmd.extend(['-d'])
+ cmd.extend(to_list(env['OUTDIR']))
+ cmd.extend(to_list(env['JAVACFLAGS']))
+ files=[a.path_from(bld.bldnode)for a in self.inputs]
+ tmp=None
+ try:
+ if len(str(files))+len(str(cmd))>8192:
+ (fd,tmp)=tempfile.mkstemp(dir=bld.bldnode.abspath())
+ try:
+ os.write(fd,'\n'.join(files))
+ finally:
+ if tmp:
+ os.close(fd)
+ if Logs.verbose:
+ Logs.debug('runner: %r'%(cmd+files))
+ cmd.append('@'+tmp)
+ else:
+ cmd+=files
+ ret=self.exec_command(cmd,cwd=wd,env=env.env or None)
+ finally:
+ if tmp:
+ os.unlink(tmp)
+ return ret
+ def post_run(self):
+ for n in self.generator.outdir.ant_glob('**/*.class'):
+ n.sig=Utils.h_file(n.abspath())
+ self.generator.bld.task_sigs[self.uid()]=self.cache_sig
+def configure(self):
+ java_path=self.environ['PATH'].split(os.pathsep)
+ v=self.env
+ if'JAVA_HOME'in self.environ:
+ java_path=[os.path.join(self.environ['JAVA_HOME'],'bin')]+java_path
+ self.env['JAVA_HOME']=[self.environ['JAVA_HOME']]
+ for x in'javac java jar'.split():
+ self.find_program(x,var=x.upper(),path_list=java_path)
+ self.env[x.upper()]=self.cmd_to_list(self.env[x.upper()])
+ if'CLASSPATH'in self.environ:
+ v['CLASSPATH']=self.environ['CLASSPATH']
+ if not v['JAR']:self.fatal('jar is required for making java packages')
+ if not v['JAVAC']:self.fatal('javac is required for compiling java classes')
+ v['JARCREATE']='cf'
+ v['JAVACFLAGS']=[]
+def check_java_class(self,classname,with_classpath=None):
+ javatestdir='.waf-javatest'
+ classpath=javatestdir
+ if self.env['CLASSPATH']:
+ classpath+=os.pathsep+self.env['CLASSPATH']
+ if isinstance(with_classpath,str):
+ classpath+=os.pathsep+with_classpath
+ shutil.rmtree(javatestdir,True)
+ os.mkdir(javatestdir)
+ java_file=open(os.path.join(javatestdir,'Test.java'),'w')
+ java_file.write(class_check_source)
+ java_file.close()
+ self.exec_command(self.env['JAVAC']+[os.path.join(javatestdir,'Test.java')],shell=False)
+ cmd=self.env['JAVA']+['-cp',classpath,'Test',classname]
+ self.to_log("%s\n"%str(cmd))
+ found=self.exec_command(cmd,shell=False)
+ self.msg('Checking for java class %s'%classname,not found)
+ shutil.rmtree(javatestdir,True)
+ return found
+def check_jni_headers(conf):
+ if not conf.env.CC_NAME and not conf.env.CXX_NAME:
+ conf.fatal('load a compiler first (gcc, g++, ..)')
+ if not conf.env.JAVA_HOME:
+ conf.fatal('set JAVA_HOME in the system environment')
+ javaHome=conf.env['JAVA_HOME'][0]
+ dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/include')
+ if dir is None:
+ conf.fatal('JAVA_HOME does not seem to be set properly')
+ f=dir.ant_glob('**/(jni|jni_md).h')
+ incDirs=[x.parent.abspath()for x in f]
+ dir=conf.root.find_dir(conf.env.JAVA_HOME[0])
+ f=dir.ant_glob('**/*jvm.(so|dll|dylib)')
+ libDirs=[x.parent.abspath()for x in f]or[javaHome]
+ f=dir.ant_glob('**/*jvm.(lib)')
+ if f:
+ libDirs=[[x,y.parent.abspath()]for x in libDirs for y in f]
+ for d in libDirs:
+ try:
+ conf.check(header_name='jni.h',define_name='HAVE_JNI_H',lib='jvm',libpath=d,includes=incDirs,uselib_store='JAVA',uselib='JAVA')
+ except:
+ pass
+ else:
+ break
+ else:
+ conf.fatal('could not find lib jvm in %r (see config.log)'%libDirs)
+
+feature('javac')(apply_java)
+before_method('process_source')(apply_java)
+feature('javac')(use_javac_files)
+after_method('apply_java')(use_javac_files)
+feature('javac')(set_classpath)
+after_method('apply_java','propagate_uselib_vars','use_javac_files')(set_classpath)
+feature('jar')(jar_files)
+after_method('apply_java','use_javac_files')(jar_files)
+before_method('process_source')(jar_files)
+feature('jar')(use_jar_files)
+after_method('jar_files')(use_jar_files)
+conf(check_java_class)
+conf(check_jni_headers) \ No newline at end of file
diff --git a/waflib/Tools/kde4.py b/waflib/Tools/kde4.py
new file mode 100644
index 0000000..e4a8a92
--- /dev/null
+++ b/waflib/Tools/kde4.py
@@ -0,0 +1,49 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,re
+from waflib import Options,TaskGen,Task,Utils
+from waflib.TaskGen import feature,after_method
+def apply_msgfmt(self):
+ for lang in self.to_list(self.langs):
+ node=self.path.find_resource(lang+'.po')
+ task=self.create_task('msgfmt',node,node.change_ext('.mo'))
+ langname=lang.split('/')
+ langname=langname[-1]
+ inst=getattr(self,'install_path','${KDE4_LOCALE_INSTALL_DIR}')
+ self.bld.install_as(inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+getattr(self,'appname','set_your_appname')+'.mo',task.outputs[0],chmod=getattr(self,'chmod',Utils.O644))
+class msgfmt(Task.Task):
+ color='BLUE'
+ run_str='${MSGFMT} ${SRC} -o ${TGT}'
+def configure(self):
+ kdeconfig=self.find_program('kde4-config')
+ prefix=self.cmd_and_log('%s --prefix'%kdeconfig).strip()
+ fname='%s/share/apps/cmake/modules/KDELibsDependencies.cmake'%prefix
+ try:os.stat(fname)
+ except OSError:
+ fname='%s/share/kde4/apps/cmake/modules/KDELibsDependencies.cmake'%prefix
+ try:os.stat(fname)
+ except OSError:self.fatal('could not open %s'%fname)
+ try:
+ txt=Utils.readf(fname)
+ except(OSError,IOError):
+ self.fatal('could not read %s'%fname)
+ txt=txt.replace('\\\n','\n')
+ fu=re.compile('#(.*)\n')
+ txt=fu.sub('',txt)
+ setregexp=re.compile('([sS][eE][tT]\s*\()\s*([^\s]+)\s+\"([^"]+)\"\)')
+ found=setregexp.findall(txt)
+ for(_,key,val)in found:
+ self.env[key]=val
+ self.env['LIB_KDECORE']=['kdecore']
+ self.env['LIB_KDEUI']=['kdeui']
+ self.env['LIB_KIO']=['kio']
+ self.env['LIB_KHTML']=['khtml']
+ self.env['LIB_KPARTS']=['kparts']
+ self.env['LIBPATH_KDECORE']=[self.env['KDE4_LIB_INSTALL_DIR']]
+ self.env['INCLUDES_KDECORE']=[self.env['KDE4_INCLUDE_INSTALL_DIR']]
+ self.env.append_value('INCLUDES_KDECORE',[self.env['KDE4_INCLUDE_INSTALL_DIR']+os.sep+'KDE'])
+ self.find_program('msgfmt',var='MSGFMT')
+
+feature('msgfmt')(apply_msgfmt) \ No newline at end of file
diff --git a/waflib/Tools/lua.py b/waflib/Tools/lua.py
new file mode 100644
index 0000000..0d48d4f
--- /dev/null
+++ b/waflib/Tools/lua.py
@@ -0,0 +1,19 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.TaskGen import extension
+from waflib import Task,Utils
+def add_lua(self,node):
+ tsk=self.create_task('luac',node,node.change_ext('.luac'))
+ inst_to=getattr(self,'install_path',self.env.LUADIR and'${LUADIR}'or None)
+ if inst_to:
+ self.bld.install_files(inst_to,tsk.outputs)
+ return tsk
+class luac(Task.Task):
+ run_str='${LUAC} -s -o ${TGT} ${SRC}'
+ color='PINK'
+def configure(conf):
+ conf.find_program('luac',var='LUAC')
+
+extension('.lua')(add_lua) \ No newline at end of file
diff --git a/waflib/Tools/msvc.py b/waflib/Tools/msvc.py
new file mode 100644
index 0000000..1ec9bb6
--- /dev/null
+++ b/waflib/Tools/msvc.py
@@ -0,0 +1,654 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,re,tempfile
+try:
+ import _winreg
+except:
+ try:
+ import winreg as _winreg
+ except:
+ _winreg=None
+from waflib import Utils,TaskGen,Runner,Configure,Task,Options
+from waflib.Logs import debug,info,warn,error
+from waflib.TaskGen import after_method,before_method,feature
+from waflib.Configure import conf
+from waflib.Tools import ccroot,c,cxx,ar,winres
+g_msvc_systemlibs='''
+aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet
+cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs
+credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d
+ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp
+faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid
+gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop
+kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi
+mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree
+msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm
+netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp
+odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32
+osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu
+ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm
+rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32
+shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32
+traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg
+version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm
+wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp
+'''.split()
+all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64')]
+all_wince_platforms=[('armv4','arm'),('armv4i','arm'),('mipsii','mips'),('mipsii_fp','mips'),('mipsiv','mips'),('mipsiv_fp','mips'),('sh4','sh'),('x86','cex86')]
+all_icl_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')]
+def options(opt):
+ opt.add_option('--msvc_version',type='string',help='msvc version, eg: "msvc 10.0,msvc 9.0"',default='')
+ opt.add_option('--msvc_targets',type='string',help='msvc targets, eg: "x64,arm"',default='')
+def setup_msvc(conf,versions):
+ platforms=getattr(Options.options,'msvc_targets','').split(',')
+ if platforms==['']:
+ platforms=Utils.to_list(conf.env['MSVC_TARGETS'])or[i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms]
+ desired_versions=getattr(Options.options,'msvc_version','').split(',')
+ if desired_versions==['']:
+ desired_versions=conf.env['MSVC_VERSIONS']or[v for v,_ in versions][::-1]
+ versiondict=dict(versions)
+ for version in desired_versions:
+ try:
+ targets=dict(versiondict[version])
+ for target in platforms:
+ try:
+ arch,(p1,p2,p3)=targets[target]
+ compiler,revision=version.rsplit(' ',1)
+ return compiler,revision,p1,p2,p3
+ except KeyError:continue
+ except KeyError:continue
+ conf.fatal('msvc: Impossible to find a valid architecture for building (in setup_msvc)')
+def get_msvc_version(conf,compiler,version,target,vcvars):
+ debug('msvc: get_msvc_version: %r %r %r',compiler,version,target)
+ batfile=conf.bldnode.make_node('waf-print-msvc.bat')
+ batfile.write("""@echo off
+set INCLUDE=
+set LIB=
+call "%s" %s
+echo PATH=%%PATH%%
+echo INCLUDE=%%INCLUDE%%
+echo LIB=%%LIB%%
+"""%(vcvars,target))
+ sout=conf.cmd_and_log(['cmd','/E:on','/V:on','/C',batfile.abspath()])
+ lines=sout.splitlines()
+ if not lines[0]:lines=lines[1:]
+ for x in('Setting environment','Setting SDK environment','Intel(R) C++ Compiler','Intel Parallel Studio'):
+ if lines[0].find(x)!=-1:
+ break
+ else:
+ debug('msvc: get_msvc_version: %r %r %r -> not found',compiler,version,target)
+ conf.fatal('msvc: Impossible to find a valid architecture for building (in get_msvc_version)')
+ for line in lines[1:]:
+ if line.startswith('PATH='):
+ path=line[5:]
+ MSVC_PATH=path.split(';')
+ elif line.startswith('INCLUDE='):
+ MSVC_INCDIR=[i for i in line[8:].split(';')if i]
+ elif line.startswith('LIB='):
+ MSVC_LIBDIR=[i for i in line[4:].split(';')if i]
+ env={}
+ env.update(os.environ)
+ env.update(PATH=path)
+ compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
+ cxx=conf.find_program(compiler_name,path_list=MSVC_PATH)
+ cxx=conf.cmd_to_list(cxx)
+ if'CL'in env:
+ del(env['CL'])
+ try:
+ try:
+ conf.cmd_and_log(cxx+['/help'],env=env)
+ except Exception ,e:
+ debug('msvc: get_msvc_version: %r %r %r -> failure'%(compiler,version,target))
+ debug(str(e))
+ conf.fatal('msvc: cannot run the compiler (in get_msvc_version)')
+ else:
+ debug('msvc: get_msvc_version: %r %r %r -> OK',compiler,version,target)
+ finally:
+ conf.env[compiler_name]=''
+ return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
+def gather_wsdk_versions(conf,versions):
+ version_pattern=re.compile('^v..?.?\...?.?')
+ try:
+ all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows')
+ except WindowsError:
+ try:
+ all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows')
+ except WindowsError:
+ return
+ index=0
+ while 1:
+ try:
+ version=_winreg.EnumKey(all_versions,index)
+ except WindowsError:
+ break
+ index=index+1
+ if not version_pattern.match(version):
+ continue
+ try:
+ msvc_version=_winreg.OpenKey(all_versions,version)
+ path,type=_winreg.QueryValueEx(msvc_version,'InstallationFolder')
+ except WindowsError:
+ continue
+ if os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')):
+ targets=[]
+ for target,arch in all_msvc_platforms:
+ try:
+ targets.append((target,(arch,conf.get_msvc_version('wsdk',version,'/'+target,os.path.join(path,'bin','SetEnv.cmd')))))
+ except conf.errors.ConfigurationError:
+ pass
+ versions.append(('wsdk '+version[1:],targets))
+def gather_wince_supported_platforms():
+ supported_wince_platforms=[]
+ try:
+ ce_sdk=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs')
+ except WindowsError:
+ try:
+ ce_sdk=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs')
+ except WindowsError:
+ ce_sdk=''
+ if not ce_sdk:
+ return supported_wince_platforms
+ ce_index=0
+ while 1:
+ try:
+ sdk_device=_winreg.EnumKey(ce_sdk,ce_index)
+ except WindowsError:
+ break
+ ce_index=ce_index+1
+ sdk=_winreg.OpenKey(ce_sdk,sdk_device)
+ try:
+ path,type=_winreg.QueryValueEx(sdk,'SDKRootDir')
+ except WindowsError:
+ try:
+ path,type=_winreg.QueryValueEx(sdk,'SDKInformation')
+ path,xml=os.path.split(path)
+ except WindowsError:
+ continue
+ path=str(path)
+ path,device=os.path.split(path)
+ if not device:
+ path,device=os.path.split(path)
+ for arch,compiler in all_wince_platforms:
+ platforms=[]
+ if os.path.isdir(os.path.join(path,device,'Lib',arch)):
+ platforms.append((arch,compiler,os.path.join(path,device,'Include',arch),os.path.join(path,device,'Lib',arch)))
+ if platforms:
+ supported_wince_platforms.append((device,platforms))
+ return supported_wince_platforms
+def gather_msvc_detected_versions():
+ version_pattern=re.compile('^(\d\d?\.\d\d?)(Exp)?$')
+ detected_versions=[]
+ for vcver,vcvar in[('VCExpress','Exp'),('VisualStudio','')]:
+ try:
+ prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
+ all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,prefix)
+ except WindowsError:
+ try:
+ prefix='SOFTWARE\\Microsoft\\'+vcver
+ all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,prefix)
+ except WindowsError:
+ continue
+ index=0
+ while 1:
+ try:
+ version=_winreg.EnumKey(all_versions,index)
+ except WindowsError:
+ break
+ index=index+1
+ match=version_pattern.match(version)
+ if not match:
+ continue
+ else:
+ versionnumber=float(match.group(1))
+ detected_versions.append((versionnumber,version+vcvar,prefix+"\\"+version))
+ def fun(tup):
+ return tup[0]
+ try:
+ detected_versions.sort(key=fun)
+ except:
+ detected_versions.sort(lambda x,y:cmp(x[0],y[0]))
+ return detected_versions
+def gather_msvc_targets(conf,versions,version,vc_path):
+ targets=[]
+ if os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')):
+ for target,realtarget in all_msvc_platforms[::-1]:
+ try:
+ targets.append((target,(realtarget,conf.get_msvc_version('msvc',version,target,os.path.join(vc_path,'vcvarsall.bat')))))
+ except conf.errors.ConfigurationError:
+ pass
+ elif os.path.isfile(os.path.join(vc_path,'Common7','Tools','vsvars32.bat')):
+ try:
+ targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'x86',os.path.join(vc_path,'Common7','Tools','vsvars32.bat')))))
+ except conf.errors.ConfigurationError:
+ pass
+ elif os.path.isfile(os.path.join(vc_path,'Bin','vcvars32.bat')):
+ try:
+ targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'',os.path.join(vc_path,'Bin','vcvars32.bat')))))
+ except conf.errors.ConfigurationError:
+ pass
+ versions.append(('msvc '+version,targets))
+def gather_wince_targets(conf,versions,version,vc_path,vsvars,supported_platforms):
+ for device,platforms in supported_platforms:
+ cetargets=[]
+ for platform,compiler,include,lib in platforms:
+ winCEpath=os.path.join(vc_path,'ce')
+ if not os.path.isdir(winCEpath):
+ continue
+ try:
+ common_bindirs,_1,_2=conf.get_msvc_version('msvc',version,'x86',vsvars)
+ except conf.errors.ConfigurationError:
+ continue
+ if os.path.isdir(os.path.join(winCEpath,'lib',platform)):
+ bindirs=[os.path.join(winCEpath,'bin',compiler),os.path.join(winCEpath,'bin','x86_'+compiler)]+common_bindirs
+ incdirs=[os.path.join(winCEpath,'include'),os.path.join(winCEpath,'atlmfc','include'),include]
+ libdirs=[os.path.join(winCEpath,'lib',platform),os.path.join(winCEpath,'atlmfc','lib',platform),lib]
+ cetargets.append((platform,(platform,(bindirs,incdirs,libdirs))))
+ if cetargets:
+ versions.append((device+' '+version,cetargets))
+def gather_msvc_versions(conf,versions):
+ vc_paths=[]
+ for(v,version,reg)in gather_msvc_detected_versions():
+ try:
+ try:
+ msvc_version=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\VC")
+ except WindowsError:
+ msvc_version=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\Microsoft Visual C++")
+ path,type=_winreg.QueryValueEx(msvc_version,'ProductDir')
+ vc_paths.append((version,os.path.abspath(str(path))))
+ except WindowsError:
+ continue
+ wince_supported_platforms=gather_wince_supported_platforms()
+ for version,vc_path in vc_paths:
+ vs_path=os.path.dirname(vc_path)
+ vsvars=os.path.join(vs_path,'Common7','Tools','vsvars32.bat')
+ if wince_supported_platforms and os.path.isfile(vsvars):
+ conf.gather_wince_targets(versions,version,vc_path,vsvars,wince_supported_platforms)
+ for version,vc_path in vc_paths:
+ vs_path=os.path.dirname(vc_path)
+ conf.gather_msvc_targets(versions,version,vc_path)
+def gather_icl_versions(conf,versions):
+ version_pattern=re.compile('^...?.?\....?.?')
+ try:
+ all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++')
+ except WindowsError:
+ try:
+ all_versions=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\C++')
+ except WindowsError:
+ return
+ index=0
+ while 1:
+ try:
+ version=_winreg.EnumKey(all_versions,index)
+ except WindowsError:
+ break
+ index=index+1
+ if not version_pattern.match(version):
+ continue
+ targets=[]
+ for target,arch in all_icl_platforms:
+ try:
+ if target=='intel64':targetDir='EM64T_NATIVE'
+ else:targetDir=target
+ _winreg.OpenKey(all_versions,version+'\\'+targetDir)
+ icl_version=_winreg.OpenKey(all_versions,version)
+ path,type=_winreg.QueryValueEx(icl_version,'ProductDir')
+ if os.path.isfile(os.path.join(path,'bin','iclvars.bat')):
+ try:
+ targets.append((target,(arch,conf.get_msvc_version('intel',version,target,os.path.join(path,'bin','iclvars.bat')))))
+ except conf.errors.ConfigurationError:
+ pass
+ except WindowsError:
+ pass
+ for target,arch in all_icl_platforms:
+ try:
+ icl_version=_winreg.OpenKey(all_versions,version+'\\'+target)
+ path,type=_winreg.QueryValueEx(icl_version,'ProductDir')
+ if os.path.isfile(os.path.join(path,'bin','iclvars.bat')):
+ try:
+ targets.append((target,(arch,conf.get_msvc_version('intel',version,target,os.path.join(path,'bin','iclvars.bat')))))
+ except conf.errors.ConfigurationError:
+ pass
+ except WindowsError:
+ continue
+ major=version[0:2]
+ versions.append(('intel '+major,targets))
+def get_msvc_versions(conf):
+ if not conf.env['MSVC_INSTALLED_VERSIONS']:
+ lst=[]
+ conf.gather_icl_versions(lst)
+ conf.gather_wsdk_versions(lst)
+ conf.gather_msvc_versions(lst)
+ conf.env['MSVC_INSTALLED_VERSIONS']=lst
+ return conf.env['MSVC_INSTALLED_VERSIONS']
+def print_all_msvc_detected(conf):
+ for version,targets in conf.env['MSVC_INSTALLED_VERSIONS']:
+ info(version)
+ for target,l in targets:
+ info("\t"+target)
+def detect_msvc(conf):
+ versions=get_msvc_versions(conf)
+ return setup_msvc(conf,versions)
+def find_lt_names_msvc(self,libname,is_static=False):
+ lt_names=['lib%s.la'%libname,'%s.la'%libname,]
+ for path in self.env['LIBPATH']:
+ for la in lt_names:
+ laf=os.path.join(path,la)
+ dll=None
+ if os.path.exists(laf):
+ ltdict=Utils.read_la_file(laf)
+ lt_libdir=None
+ if ltdict.get('libdir',''):
+ lt_libdir=ltdict['libdir']
+ if not is_static and ltdict.get('library_names',''):
+ dllnames=ltdict['library_names'].split()
+ dll=dllnames[0].lower()
+ dll=re.sub('\.dll$','',dll)
+ return(lt_libdir,dll,False)
+ elif ltdict.get('old_library',''):
+ olib=ltdict['old_library']
+ if os.path.exists(os.path.join(path,olib)):
+ return(path,olib,True)
+ elif lt_libdir!=''and os.path.exists(os.path.join(lt_libdir,olib)):
+ return(lt_libdir,olib,True)
+ else:
+ return(None,olib,True)
+ else:
+ raise self.errors.WafError('invalid libtool object file: %s'%laf)
+ return(None,None,None)
+def libname_msvc(self,libname,is_static=False):
+ lib=libname.lower()
+ lib=re.sub('\.lib$','',lib)
+ if lib in g_msvc_systemlibs:
+ return lib
+ lib=re.sub('^lib','',lib)
+ if lib=='m':
+ return None
+ (lt_path,lt_libname,lt_static)=self.find_lt_names_msvc(lib,is_static)
+ if lt_path!=None and lt_libname!=None:
+ if lt_static==True:
+ return os.path.join(lt_path,lt_libname)
+ if lt_path!=None:
+ _libpaths=[lt_path]+self.env['LIBPATH']
+ else:
+ _libpaths=self.env['LIBPATH']
+ static_libs=['lib%ss.lib'%lib,'lib%s.lib'%lib,'%ss.lib'%lib,'%s.lib'%lib,]
+ dynamic_libs=['lib%s.dll.lib'%lib,'lib%s.dll.a'%lib,'%s.dll.lib'%lib,'%s.dll.a'%lib,'lib%s_d.lib'%lib,'%s_d.lib'%lib,'%s.lib'%lib,]
+ libnames=static_libs
+ if not is_static:
+ libnames=dynamic_libs+static_libs
+ for path in _libpaths:
+ for libn in libnames:
+ if os.path.exists(os.path.join(path,libn)):
+ debug('msvc: lib found: %s'%os.path.join(path,libn))
+ return re.sub('\.lib$','',libn)
+ self.fatal("The library %r could not be found"%libname)
+ return re.sub('\.lib$','',libname)
+def check_lib_msvc(self,libname,is_static=False,uselib_store=None):
+ libn=self.libname_msvc(libname,is_static)
+ if not uselib_store:
+ uselib_store=libname.upper()
+ if False and is_static:
+ self.env['STLIB_'+uselib_store]=[libn]
+ else:
+ self.env['LIB_'+uselib_store]=[libn]
+def check_libs_msvc(self,libnames,is_static=False):
+ for libname in Utils.to_list(libnames):
+ self.check_lib_msvc(libname,is_static)
+def configure(conf):
+ conf.autodetect()
+ conf.find_msvc()
+ conf.msvc_common_flags()
+ conf.cc_load_tools()
+ conf.cxx_load_tools()
+ conf.cc_add_flags()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
+ conf.visual_studio_add_flags()
+def no_autodetect(conf):
+ conf.env.NO_MSVC_DETECT=1
+ configure(conf)
+def autodetect(conf):
+ v=conf.env
+ if v.NO_MSVC_DETECT:
+ return
+ compiler,version,path,includes,libdirs=conf.detect_msvc()
+ v['PATH']=path
+ v['INCLUDES']=includes
+ v['LIBPATH']=libdirs
+ v['MSVC_COMPILER']=compiler
+ try:
+ v['MSVC_VERSION']=float(version)
+ except:
+ v['MSVC_VERSION']=float(version[:-3])
+def _get_prog_names(conf,compiler):
+ if compiler=='intel':
+ compiler_name='ICL'
+ linker_name='XILINK'
+ lib_name='XILIB'
+ else:
+ compiler_name='CL'
+ linker_name='LINK'
+ lib_name='LIB'
+ return compiler_name,linker_name,lib_name
+def find_msvc(conf):
+ if sys.platform=='cygwin':
+ conf.fatal('MSVC module does not work under cygwin Python!')
+ v=conf.env
+ path=v['PATH']
+ compiler=v['MSVC_COMPILER']
+ version=v['MSVC_VERSION']
+ compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
+ v.MSVC_MANIFEST=(compiler=='msvc'and version>=8)or(compiler=='wsdk'and version>=6)or(compiler=='intel'and version>=11)
+ cxx=None
+ if v['CXX']:cxx=v['CXX']
+ elif'CXX'in conf.environ:cxx=conf.environ['CXX']
+ cxx=conf.find_program(compiler_name,var='CXX',path_list=path)
+ cxx=conf.cmd_to_list(cxx)
+ env=dict(conf.environ)
+ if path:env.update(PATH=';'.join(path))
+ if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env):
+ conf.fatal('the msvc compiler could not be identified')
+ v['CC']=v['CXX']=cxx
+ v['CC_NAME']=v['CXX_NAME']='msvc'
+ if not v['LINK_CXX']:
+ link=conf.find_program(linker_name,path_list=path)
+ if link:v['LINK_CXX']=link
+ else:conf.fatal('%s was not found (linker)'%linker_name)
+ v['LINK']=link
+ if not v['LINK_CC']:
+ v['LINK_CC']=v['LINK_CXX']
+ if not v['AR']:
+ stliblink=conf.find_program(lib_name,path_list=path,var='AR')
+ if not stliblink:return
+ v['ARFLAGS']=['/NOLOGO']
+ if v.MSVC_MANIFEST:
+ mt=conf.find_program('MT',path_list=path,var='MT')
+ v['MTFLAGS']=['/NOLOGO']
+ conf.load('winres')
+ if not conf.env['WINRC']:
+ warn('Resource compiler not found. Compiling resource file is disabled')
+def visual_studio_add_flags(self):
+ v=self.env
+ try:v.prepend_value('INCLUDES',self.environ['INCLUDE'].split(';'))
+ except:pass
+ try:v.prepend_value('LIBPATH',self.environ['LIB'].split(';'))
+ except:pass
+def msvc_common_flags(conf):
+ v=conf.env
+ v['DEST_BINFMT']='pe'
+ v.append_value('CFLAGS',['/nologo'])
+ v.append_value('CXXFLAGS',['/nologo'])
+ v['DEFINES_ST']='/D%s'
+ v['CC_SRC_F']=''
+ v['CC_TGT_F']=['/c','/Fo']
+ if v['MSVC_VERSION']>=8:
+ v['CC_TGT_F']=['/FC']+v['CC_TGT_F']
+ v['CXX_SRC_F']=''
+ v['CXX_TGT_F']=['/c','/Fo']
+ if v['MSVC_VERSION']>=8:
+ v['CXX_TGT_F']=['/FC']+v['CXX_TGT_F']
+ v['CPPPATH_ST']='/I%s'
+ v['AR_TGT_F']=v['CCLNK_TGT_F']=v['CXXLNK_TGT_F']='/OUT:'
+ v['CFLAGS_CONSOLE']=v['CXXFLAGS_CONSOLE']=['/SUBSYSTEM:CONSOLE']
+ v['CFLAGS_NATIVE']=v['CXXFLAGS_NATIVE']=['/SUBSYSTEM:NATIVE']
+ v['CFLAGS_POSIX']=v['CXXFLAGS_POSIX']=['/SUBSYSTEM:POSIX']
+ v['CFLAGS_WINDOWS']=v['CXXFLAGS_WINDOWS']=['/SUBSYSTEM:WINDOWS']
+ v['CFLAGS_WINDOWSCE']=v['CXXFLAGS_WINDOWSCE']=['/SUBSYSTEM:WINDOWSCE']
+ v['CFLAGS_CRT_MULTITHREADED']=v['CXXFLAGS_CRT_MULTITHREADED']=['/MT']
+ v['CFLAGS_CRT_MULTITHREADED_DLL']=v['CXXFLAGS_CRT_MULTITHREADED_DLL']=['/MD']
+ v['CFLAGS_CRT_MULTITHREADED_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DBG']=['/MTd']
+ v['CFLAGS_CRT_MULTITHREADED_DLL_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DLL_DBG']=['/MDd']
+ v['LIB_ST']='%s.lib'
+ v['LIBPATH_ST']='/LIBPATH:%s'
+ v['STLIB_ST']='lib%s.lib'
+ v['STLIBPATH_ST']='/LIBPATH:%s'
+ v.append_value('LINKFLAGS',['/NOLOGO'])
+ if v['MSVC_MANIFEST']:
+ v.append_value('LINKFLAGS',['/MANIFEST'])
+ v['CFLAGS_cshlib']=[]
+ v['CXXFLAGS_cxxshlib']=[]
+ v['LINKFLAGS_cshlib']=v['LINKFLAGS_cxxshlib']=['/DLL']
+ v['cshlib_PATTERN']=v['cxxshlib_PATTERN']='%s.dll'
+ v['implib_PATTERN']='%s.lib'
+ v['IMPLIB_ST']='/IMPLIB:%s'
+ v['LINKFLAGS_cstlib']=[]
+ v['cstlib_PATTERN']=v['cxxstlib_PATTERN']='lib%s.lib'
+ v['cprogram_PATTERN']=v['cxxprogram_PATTERN']='%s.exe'
+def apply_flags_msvc(self):
+ if self.env.CC_NAME!='msvc'or not getattr(self,'link_task',None):
+ return
+ is_static=isinstance(self.link_task,ccroot.stlink_task)
+ subsystem=getattr(self,'subsystem','')
+ if subsystem:
+ subsystem='/subsystem:%s'%subsystem
+ flags=is_static and'ARFLAGS'or'LINKFLAGS'
+ self.env.append_value(flags,subsystem)
+ if not is_static:
+ for f in self.env.LINKFLAGS:
+ d=f.lower()
+ if d[1:]=='debug':
+ pdbnode=self.link_task.outputs[0].change_ext('.pdb')
+ self.link_task.outputs.append(pdbnode)
+ try:
+ self.install_task.source.append(pdbnode)
+ except AttributeError:
+ pass
+ break
+def apply_manifest(self):
+ if self.env.CC_NAME=='msvc'and self.env.MSVC_MANIFEST and getattr(self,'link_task',None):
+ out_node=self.link_task.outputs[0]
+ man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
+ self.link_task.outputs.append(man_node)
+ self.link_task.do_manifest=True
+def exec_mf(self):
+ env=self.env
+ mtool=env['MT']
+ if not mtool:
+ return 0
+ self.do_manifest=False
+ outfile=self.outputs[0].abspath()
+ manifest=None
+ for out_node in self.outputs:
+ if out_node.name.endswith('.manifest'):
+ manifest=out_node.abspath()
+ break
+ if manifest is None:
+ return 0
+ mode=''
+ if'cprogram'in self.generator.features or'cxxprogram'in self.generator.features:
+ mode='1'
+ elif'cshlib'in self.generator.features or'cxxshlib'in self.generator.features:
+ mode='2'
+ debug('msvc: embedding manifest in mode %r'%mode)
+ lst=[]
+ lst.append(env['MT'])
+ lst.extend(Utils.to_list(env['MTFLAGS']))
+ lst.extend(['-manifest',manifest])
+ lst.append('-outputresource:%s;%s'%(outfile,mode))
+ lst=[lst]
+ return self.exec_command(*lst)
+def quote_response_command(self,flag):
+ if flag.find(' ')>-1:
+ for x in('/LIBPATH:','/IMPLIB:','/OUT:','/I'):
+ if flag.startswith(x):
+ flag='%s"%s"'%(x,flag[len(x):])
+ break
+ else:
+ flag='"%s"'%flag
+ return flag
+def exec_response_command(self,cmd,**kw):
+ try:
+ tmp=None
+ if sys.platform.startswith('win')and isinstance(cmd,list)and len(' '.join(cmd))>=8192:
+ program=cmd[0]
+ cmd=[self.quote_response_command(x)for x in cmd]
+ (fd,tmp)=tempfile.mkstemp()
+ os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
+ os.close(fd)
+ cmd=[program,'@'+tmp]
+ ret=self.generator.bld.exec_command(cmd,**kw)
+ finally:
+ if tmp:
+ try:
+ os.remove(tmp)
+ except:
+ pass
+ return ret
+def exec_command_msvc(self,*k,**kw):
+ if self.env['CC_NAME']=='msvc':
+ if isinstance(k[0],list):
+ lst=[]
+ carry=''
+ for a in k[0]:
+ if a=='/Fo'or a=='/doc'or a[-1]==':':
+ carry=a
+ else:
+ lst.append(carry+a)
+ carry=''
+ k=[lst]
+ if self.env['PATH']:
+ env=dict(os.environ)
+ env.update(PATH=';'.join(self.env['PATH']))
+ kw['env']=env
+ bld=self.generator.bld
+ try:
+ if not kw.get('cwd',None):
+ kw['cwd']=bld.cwd
+ except AttributeError:
+ bld.cwd=kw['cwd']=bld.variant_dir
+ ret=self.exec_response_command(k[0],**kw)
+ if not ret and getattr(self,'do_manifest',None):
+ ret=self.exec_mf()
+ return ret
+for k in'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split():
+ cls=Task.classes.get(k,None)
+ if cls:
+ cls.exec_command=exec_command_msvc
+ cls.exec_response_command=exec_response_command
+ cls.quote_response_command=quote_response_command
+ cls.exec_mf=exec_mf
+
+conf(get_msvc_version)
+conf(gather_wsdk_versions)
+conf(gather_msvc_targets)
+conf(gather_wince_targets)
+conf(gather_msvc_versions)
+conf(gather_icl_versions)
+conf(get_msvc_versions)
+conf(print_all_msvc_detected)
+conf(detect_msvc)
+conf(find_lt_names_msvc)
+conf(libname_msvc)
+conf(check_lib_msvc)
+conf(check_libs_msvc)
+conf(no_autodetect)
+conf(autodetect)
+conf(find_msvc)
+conf(visual_studio_add_flags)
+conf(msvc_common_flags)
+after_method('apply_link')(apply_flags_msvc)
+feature('c','cxx')(apply_flags_msvc)
+feature('cprogram','cshlib','cxxprogram','cxxshlib')(apply_manifest)
+after_method('apply_link')(apply_manifest) \ No newline at end of file
diff --git a/waflib/Tools/nasm.py b/waflib/Tools/nasm.py
new file mode 100644
index 0000000..22717d3
--- /dev/null
+++ b/waflib/Tools/nasm.py
@@ -0,0 +1,14 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import waflib.Tools.asm
+from waflib.TaskGen import feature
+def apply_nasm_vars(self):
+ self.env.append_value('ASFLAGS',self.to_list(getattr(self,'nasm_flags',[])))
+def configure(conf):
+ nasm=conf.find_program(['nasm','yasm'],var='AS')
+ conf.env.AS_TGT_F=['-o']
+ conf.env.ASLNK_TGT_F=['-o']
+
+feature('asm')(apply_nasm_vars) \ No newline at end of file
diff --git a/waflib/Tools/perl.py b/waflib/Tools/perl.py
new file mode 100644
index 0000000..0f66333
--- /dev/null
+++ b/waflib/Tools/perl.py
@@ -0,0 +1,81 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Task,Options,Utils
+from waflib.Configure import conf
+from waflib.TaskGen import extension,feature,before_method
+def init_perlext(self):
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ if not'PERLEXT'in self.uselib:self.uselib.append('PERLEXT')
+ self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['perlext_PATTERN']
+def xsubpp_file(self,node):
+ outnode=node.change_ext('.c')
+ self.create_task('xsubpp',node,outnode)
+ self.source.append(outnode)
+class xsubpp(Task.Task):
+ run_str='${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}'
+ color='BLUE'
+ ext_out=['.h']
+def check_perl_version(self,minver=None):
+ res=True
+ if minver:
+ cver='.'.join(map(str,minver))
+ else:
+ cver=''
+ self.start_msg('Checking for minimum perl version %s'%cver)
+ perl=getattr(Options.options,'perlbinary',None)
+ if not perl:
+ perl=self.find_program('perl',var='PERL')
+ if not perl:
+ self.end_msg("Perl not found",color="YELLOW")
+ return False
+ self.env['PERL']=perl
+ version=self.cmd_and_log([perl,"-e",'printf \"%vd\", $^V'])
+ if not version:
+ res=False
+ version="Unknown"
+ elif not minver is None:
+ ver=tuple(map(int,version.split(".")))
+ if ver<minver:
+ res=False
+ self.end_msg(version,color=res and"GREEN"or"YELLOW")
+ return res
+def check_perl_module(self,module):
+ cmd=[self.env['PERL'],'-e','use %s'%module]
+ self.start_msg('perl module %s'%module)
+ try:
+ r=self.cmd_and_log(cmd)
+ except:
+ self.end_msg(False)
+ return None
+ self.end_msg(r or True)
+ return r
+def check_perl_ext_devel(self):
+ env=self.env
+ perl=env.PERL
+ if not perl:
+ self.fatal('find perl first')
+ def read_out(cmd):
+ return Utils.to_list(self.cmd_and_log(perl+cmd))
+ env['LINKFLAGS_PERLEXT']=read_out(" -MConfig -e'print $Config{lddlflags}'")
+ env['INCLUDES_PERLEXT']=read_out(" -MConfig -e'print \"$Config{archlib}/CORE\"'")
+ env['CFLAGS_PERLEXT']=read_out(" -MConfig -e'print \"$Config{ccflags} $Config{cccdlflags}\"'")
+ env['XSUBPP']=read_out(" -MConfig -e'print \"$Config{privlib}/ExtUtils/xsubpp$Config{exe_ext}\"'")
+ env['EXTUTILS_TYPEMAP']=read_out(" -MConfig -e'print \"$Config{privlib}/ExtUtils/typemap\"'")
+ if not getattr(Options.options,'perlarchdir',None):
+ env['ARCHDIR_PERL']=self.cmd_and_log(perl+" -MConfig -e'print $Config{sitearch}'")
+ else:
+ env['ARCHDIR_PERL']=getattr(Options.options,'perlarchdir')
+ env['perlext_PATTERN']='%s.'+self.cmd_and_log(perl+" -MConfig -e'print $Config{dlext}'")
+def options(opt):
+ opt.add_option('--with-perl-binary',type='string',dest='perlbinary',help='Specify alternate perl binary',default=None)
+ opt.add_option('--with-perl-archdir',type='string',dest='perlarchdir',help='Specify directory where to install arch specific files',default=None)
+
+before_method('apply_incpaths','apply_link','propagate_uselib_vars')(init_perlext)
+feature('perlext')(init_perlext)
+extension('.xs')(xsubpp_file)
+conf(check_perl_version)
+conf(check_perl_module)
+conf(check_perl_ext_devel) \ No newline at end of file
diff --git a/waflib/Tools/python.py b/waflib/Tools/python.py
new file mode 100644
index 0000000..cdaff84
--- /dev/null
+++ b/waflib/Tools/python.py
@@ -0,0 +1,336 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Utils,Options,Errors
+from waflib.Logs import debug,warn,info,error
+from waflib.TaskGen import extension,before_method,after_method,feature
+from waflib.Configure import conf
+FRAG='''
+#include <Python.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void Py_Initialize(void);
+ void Py_Finalize(void);
+#ifdef __cplusplus
+}
+#endif
+int main()
+{
+ Py_Initialize();
+ Py_Finalize();
+ return 0;
+}
+'''
+INST='''
+import sys, py_compile
+py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3])
+'''
+DISTUTILS_IMP=['from distutils.sysconfig import get_config_var, get_python_lib']
+def process_py(self,node):
+ try:
+ if not self.bld.is_install:
+ return
+ except:
+ return
+ try:
+ if not self.install_path:
+ return
+ except AttributeError:
+ self.install_path='${PYTHONDIR}'
+ def inst_py(ctx):
+ install_from=getattr(self,'install_from',None)
+ if install_from:
+ install_from=self.path.find_dir(install_from)
+ install_pyfile(self,node,install_from)
+ self.bld.add_post_fun(inst_py)
+def install_pyfile(self,node,install_from=None):
+ from_node=install_from or node.parent
+ tsk=self.bld.install_as(self.install_path+'/'+node.path_from(from_node),node,postpone=False)
+ path=tsk.get_install_path()
+ if self.bld.is_install<0:
+ info("+ removing byte compiled python files")
+ for x in'co':
+ try:
+ os.remove(path+x)
+ except OSError:
+ pass
+ if self.bld.is_install>0:
+ try:
+ st1=os.stat(path)
+ except:
+ error('The python file is missing, this should not happen')
+ for x in['c','o']:
+ do_inst=self.env['PY'+x.upper()]
+ try:
+ st2=os.stat(path+x)
+ except OSError:
+ pass
+ else:
+ if st1.st_mtime<=st2.st_mtime:
+ do_inst=False
+ if do_inst:
+ lst=(x=='o')and[self.env['PYFLAGS_OPT']]or[]
+ (a,b,c)=(path,path+x,tsk.get_install_path(destdir=False)+x)
+ argv=self.env['PYTHON']+lst+['-c',INST,a,b,c]
+ info('+ byte compiling %r'%(path+x))
+ env=self.env.env or None
+ ret=Utils.subprocess.Popen(argv,env=env).wait()
+ if ret:
+ raise Errors.WafError('py%s compilation failed %r'%(x,path))
+def feature_py(self):
+ pass
+def init_pyext(self):
+ try:
+ if not self.install_path:
+ return
+ except AttributeError:
+ self.install_path='${PYTHONARCHDIR}'
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ if not'PYEXT'in self.uselib:
+ self.uselib.append('PYEXT')
+ self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['macbundle_PATTERN']=self.env['pyext_PATTERN']
+def set_bundle(self):
+ if Utils.unversioned_sys_platform()=='darwin':
+ self.mac_bundle=True
+def init_pyembed(self):
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ if not'PYEMBED'in self.uselib:
+ self.uselib.append('PYEMBED')
+def get_python_variables(self,variables,imports=None):
+ if not imports:
+ try:
+ imports=self.python_imports
+ except AttributeError:
+ imports=DISTUTILS_IMP
+ program=list(imports)
+ program.append('')
+ for v in variables:
+ program.append("print(repr(%s))"%v)
+ os_env=dict(os.environ)
+ try:
+ del os_env['MACOSX_DEPLOYMENT_TARGET']
+ except KeyError:
+ pass
+ try:
+ out=self.cmd_and_log(self.env.PYTHON+['-c','\n'.join(program)],env=os_env)
+ except Errors.WafError:
+ self.fatal('The distutils module is unusable: install "python-devel"?')
+ return_values=[]
+ for s in out.split('\n'):
+ s=s.strip()
+ if not s:
+ continue
+ if s=='None':
+ return_values.append(None)
+ elif s[0]=="'"and s[-1]=="'":
+ return_values.append(s[1:-1])
+ elif s[0].isdigit():
+ return_values.append(int(s))
+ else:break
+ return return_values
+def check_python_headers(conf):
+ if not conf.env['CC_NAME']and not conf.env['CXX_NAME']:
+ conf.fatal('load a compiler first (gcc, g++, ..)')
+ if not conf.env['PYTHON_VERSION']:
+ conf.check_python_version()
+ env=conf.env
+ pybin=conf.env.PYTHON
+ if not pybin:
+ conf.fatal('could not find the python executable')
+ v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS'.split()
+ try:
+ lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v])
+ except RuntimeError:
+ conf.fatal("Python development headers not found (-v for details).")
+ vals=['%s = %r'%(x,y)for(x,y)in zip(v,lst)]
+ conf.to_log("Configuration returned from %r:\n%r\n"%(pybin,'\n'.join(vals)))
+ dct=dict(zip(v,lst))
+ x='MACOSX_DEPLOYMENT_TARGET'
+ if dct[x]:
+ conf.env[x]=conf.environ[x]=dct[x]
+ env['pyext_PATTERN']='%s'+dct['SO']
+ all_flags=dct['LDFLAGS']+' '+dct['CFLAGS']
+ conf.parse_flags(all_flags,'PYEMBED')
+ all_flags=dct['LDFLAGS']+' '+dct['LDSHARED']+' '+dct['CFLAGS']
+ conf.parse_flags(all_flags,'PYEXT')
+ result=None
+ for name in('python'+env['PYTHON_VERSION'],'python'+env['PYTHON_VERSION'].replace('.','')):
+ if not result and env['LIBPATH_PYEMBED']:
+ path=env['LIBPATH_PYEMBED']
+ conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n"%path)
+ result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBPATH_PYEMBED'%name)
+ if not result and dct['LIBDIR']:
+ path=[dct['LIBDIR']]
+ conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n"%path)
+ result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBDIR'%name)
+ if not result and dct['LIBPL']:
+ path=[dct['LIBPL']]
+ conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n")
+ result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in python_LIBPL'%name)
+ if not result:
+ path=[os.path.join(dct['prefix'],"libs")]
+ conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
+ result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in $prefix/libs'%name)
+ if result:
+ break
+ if result:
+ env['LIBPATH_PYEMBED']=path
+ env.append_value('LIB_PYEMBED',[name])
+ else:
+ conf.to_log("\n\n### LIB NOT FOUND\n")
+ if(Utils.is_win32 or sys.platform.startswith('os2')or dct['Py_ENABLE_SHARED']):
+ env['LIBPATH_PYEXT']=env['LIBPATH_PYEMBED']
+ env['LIB_PYEXT']=env['LIB_PYEMBED']
+ num='.'.join(env['PYTHON_VERSION'].split('.')[:2])
+ conf.find_program(['python%s-config'%num,'python-config-%s'%num,'python%sm-config'%num],var='PYTHON_CONFIG',mandatory=False)
+ includes=[]
+ if conf.env.PYTHON_CONFIG:
+ for incstr in conf.cmd_and_log([conf.env.PYTHON_CONFIG,'--includes']).strip().split():
+ if(incstr.startswith('-I')or incstr.startswith('/I')):
+ incstr=incstr[2:]
+ if incstr not in includes:
+ includes.append(incstr)
+ conf.to_log("Include path for Python extensions (found via python-config --includes): %r\n"%(includes,))
+ env['INCLUDES_PYEXT']=includes
+ env['INCLUDES_PYEMBED']=includes
+ else:
+ conf.to_log("Include path for Python extensions ""(found via distutils module): %r\n"%(dct['INCLUDEPY'],))
+ env['INCLUDES_PYEXT']=[dct['INCLUDEPY']]
+ env['INCLUDES_PYEMBED']=[dct['INCLUDEPY']]
+ if env['CC_NAME']=='gcc':
+ env.append_value('CFLAGS_PYEMBED',['-fno-strict-aliasing'])
+ env.append_value('CFLAGS_PYEXT',['-fno-strict-aliasing'])
+ if env['CXX_NAME']=='gcc':
+ env.append_value('CXXFLAGS_PYEMBED',['-fno-strict-aliasing'])
+ env.append_value('CXXFLAGS_PYEXT',['-fno-strict-aliasing'])
+ if env.CC_NAME=="msvc":
+ from distutils.msvccompiler import MSVCCompiler
+ dist_compiler=MSVCCompiler()
+ dist_compiler.initialize()
+ env.append_value('CFLAGS_PYEXT',dist_compiler.compile_options)
+ env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options)
+ env.append_value('LINKFLAGS_PYEXT',dist_compiler.ldflags_shared)
+ try:
+ conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',uselib='PYEMBED',fragment=FRAG,errmsg='Could not find the python development headers')
+ except conf.errors.ConfigurationError:
+ conf.check_cfg(path=conf.env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=['--cflags','--libs'])
+ conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',msg='Getting the python flags from python-config',uselib='PYEMBED',fragment=FRAG,errmsg='Could not find the python development headers elsewhere')
+def check_python_version(conf,minver=None):
+ assert minver is None or isinstance(minver,tuple)
+ pybin=conf.env['PYTHON']
+ if not pybin:
+ conf.fatal('could not find the python executable')
+ cmd=pybin+['-c','import sys\nfor x in sys.version_info: print(str(x))']
+ debug('python: Running python command %r'%cmd)
+ lines=conf.cmd_and_log(cmd).split()
+ assert len(lines)==5,"found %i lines, expected 5: %r"%(len(lines),lines)
+ pyver_tuple=(int(lines[0]),int(lines[1]),int(lines[2]),lines[3],int(lines[4]))
+ result=(minver is None)or(pyver_tuple>=minver)
+ if result:
+ pyver='.'.join([str(x)for x in pyver_tuple[:2]])
+ conf.env['PYTHON_VERSION']=pyver
+ if'PYTHONDIR'in conf.environ:
+ pydir=conf.environ['PYTHONDIR']
+ else:
+ if Utils.is_win32:
+ (python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
+ else:
+ python_LIBDEST=None
+ (pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
+ if python_LIBDEST is None:
+ if conf.env['LIBDIR']:
+ python_LIBDEST=os.path.join(conf.env['LIBDIR'],"python"+pyver)
+ else:
+ python_LIBDEST=os.path.join(conf.env['PREFIX'],"lib","python"+pyver)
+ if'PYTHONARCHDIR'in conf.environ:
+ pyarchdir=conf.environ['PYTHONARCHDIR']
+ else:
+ (pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
+ if not pyarchdir:
+ pyarchdir=pydir
+ if hasattr(conf,'define'):
+ conf.define('PYTHONDIR',pydir)
+ conf.define('PYTHONARCHDIR',pyarchdir)
+ conf.env['PYTHONDIR']=pydir
+ conf.env['PYTHONARCHDIR']=pyarchdir
+ pyver_full='.'.join(map(str,pyver_tuple[:3]))
+ if minver is None:
+ conf.msg('Checking for python version',pyver_full)
+ else:
+ minver_str='.'.join(map(str,minver))
+ conf.msg('Checking for python version',pyver_tuple,">= %s"%(minver_str,)and'GREEN'or'YELLOW')
+ if not result:
+ conf.fatal('The python version is too old, expecting %r'%(minver,))
+PYTHON_MODULE_TEMPLATE='''
+import %s as current_module
+version = getattr(current_module, '__version__', None)
+if version is not None:
+ print(str(version))
+else:
+ print('unknown version')
+'''
+def check_python_module(conf,module_name,condition=''):
+ msg='Python module %s'%module_name
+ if condition:
+ msg='%s (%s)'%(msg,condition)
+ conf.start_msg(msg)
+ try:
+ ret=conf.cmd_and_log(conf.env['PYTHON']+['-c',PYTHON_MODULE_TEMPLATE%module_name])
+ except Exception:
+ conf.end_msg(False)
+ conf.fatal('Could not find the python module %r'%module_name)
+ ret=ret.strip()
+ if condition:
+ conf.end_msg(ret)
+ if ret=='unknown version':
+ conf.fatal('Could not check the %s version'%module_name)
+ from distutils.version import LooseVersion
+ def num(*k):
+ if isinstance(k[0],int):
+ return LooseVersion('.'.join([str(x)for x in k]))
+ else:
+ return LooseVersion(k[0])
+ d={'num':num,'ver':LooseVersion(ret)}
+ ev=eval(condition,{},d)
+ if not ev:
+ conf.fatal('The %s version does not satisfy the requirements'%module_name)
+ else:
+ if ret=='unknown version':
+ conf.end_msg(True)
+ else:
+ conf.end_msg(ret)
+def configure(conf):
+ try:
+ conf.find_program('python',var='PYTHON')
+ except conf.errors.ConfigurationError:
+ warn("could not find a python executable, setting to sys.executable '%s'"%sys.executable)
+ conf.env.PYTHON=sys.executable
+ if conf.env.PYTHON!=sys.executable:
+ warn("python executable '%s' different from sys.executable '%s'"%(conf.env.PYTHON,sys.executable))
+ conf.env.PYTHON=conf.cmd_to_list(conf.env.PYTHON)
+ v=conf.env
+ v['PYCMD']='"import sys, py_compile;py_compile.compile(sys.argv[1], sys.argv[2])"'
+ v['PYFLAGS']=''
+ v['PYFLAGS_OPT']='-O'
+ v['PYC']=getattr(Options.options,'pyc',1)
+ v['PYO']=getattr(Options.options,'pyo',1)
+def options(opt):
+ opt.add_option('--nopyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]',dest='pyc')
+ opt.add_option('--nopyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]',dest='pyo')
+
+extension('.py')(process_py)
+feature('py')(feature_py)
+feature('pyext')(init_pyext)
+before_method('propagate_uselib_vars','apply_link')(init_pyext)
+after_method('apply_bundle')(init_pyext)
+feature('pyext')(set_bundle)
+before_method('apply_link','apply_bundle')(set_bundle)
+before_method('propagate_uselib_vars')(init_pyembed)
+feature('pyembed')(init_pyembed)
+conf(get_python_variables)
+conf(check_python_headers)
+conf(check_python_version)
+conf(check_python_module) \ No newline at end of file
diff --git a/waflib/Tools/qt4.py b/waflib/Tools/qt4.py
new file mode 100644
index 0000000..1ee9724
--- /dev/null
+++ b/waflib/Tools/qt4.py
@@ -0,0 +1,434 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+try:
+ from xml.sax import make_parser
+ from xml.sax.handler import ContentHandler
+except ImportError:
+ has_xml=False
+ ContentHandler=object
+else:
+ has_xml=True
+import os,sys
+from waflib.Tools import c_preproc,cxx
+from waflib import Task,Utils,Options,Errors
+from waflib.TaskGen import feature,after_method,extension
+from waflib.Configure import conf
+from waflib import Logs
+MOC_H=['.h','.hpp','.hxx','.hh']
+EXT_RCC=['.qrc']
+EXT_UI=['.ui']
+EXT_QT4=['.cpp','.cc','.cxx','.C']
+QT4_LIBS="QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtXmlPatterns QtWebKit Qt3Support QtHelp QtScript QtDeclarative"
+class qxx(cxx.cxx):
+ def __init__(self,*k,**kw):
+ Task.Task.__init__(self,*k,**kw)
+ self.moc_done=0
+ def scan(self):
+ (nodes,names)=c_preproc.scan(self)
+ for x in nodes:
+ if x.name.endswith('.moc'):
+ nodes.remove(x)
+ names.append(x.path_from(self.inputs[0].parent.get_bld()))
+ return(nodes,names)
+ def runnable_status(self):
+ if self.moc_done:
+ return Task.Task.runnable_status(self)
+ else:
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ self.add_moc_tasks()
+ return Task.Task.runnable_status(self)
+ def add_moc_tasks(self):
+ node=self.inputs[0]
+ bld=self.generator.bld
+ try:
+ self.signature()
+ except KeyError:
+ pass
+ else:
+ delattr(self,'cache_sig')
+ moctasks=[]
+ mocfiles=[]
+ try:
+ tmp_lst=bld.raw_deps[self.uid()]
+ bld.raw_deps[self.uid()]=[]
+ except KeyError:
+ tmp_lst=[]
+ for d in tmp_lst:
+ if not d.endswith('.moc'):
+ continue
+ if d in mocfiles:
+ Logs.error("paranoia owns")
+ continue
+ mocfiles.append(d)
+ h_node=None
+ try:ext=Options.options.qt_header_ext.split()
+ except AttributeError:pass
+ if not ext:ext=MOC_H
+ base2=d[:-4]
+ for x in[node.parent]+self.generator.includes_nodes:
+ for e in ext:
+ h_node=x.find_node(base2+e)
+ if h_node:
+ break
+ if h_node:
+ m_node=h_node.change_ext('.moc')
+ break
+ else:
+ for k in EXT_QT4:
+ if base2.endswith(k):
+ for x in[node.parent]+self.generator.includes_nodes:
+ h_node=x.find_node(base2)
+ if h_node:
+ break
+ if h_node:
+ m_node=h_node.change_ext(k+'.moc')
+ break
+ if not h_node:
+ raise Errors.WafError('no header found for %r which is a moc file'%d)
+ bld.node_deps[(self.inputs[0].parent.abspath(),m_node.name)]=h_node
+ task=Task.classes['moc'](env=self.env,generator=self.generator)
+ task.set_inputs(h_node)
+ task.set_outputs(m_node)
+ gen=bld.producer
+ gen.outstanding.insert(0,task)
+ gen.total+=1
+ moctasks.append(task)
+ tmp_lst=bld.raw_deps[self.uid()]=mocfiles
+ lst=bld.node_deps.get(self.uid(),())
+ for d in lst:
+ name=d.name
+ if name.endswith('.moc'):
+ task=Task.classes['moc'](env=self.env,generator=self.generator)
+ task.set_inputs(bld.node_deps[(self.inputs[0].parent.abspath(),name)])
+ task.set_outputs(d)
+ gen=bld.producer
+ gen.outstanding.insert(0,task)
+ gen.total+=1
+ moctasks.append(task)
+ self.run_after.update(set(moctasks))
+ self.moc_done=1
+ run=Task.classes['cxx'].__dict__['run']
+class trans_update(Task.Task):
+ run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}'
+ color='BLUE'
+Task.update_outputs(trans_update)
+class XMLHandler(ContentHandler):
+ def __init__(self):
+ self.buf=[]
+ self.files=[]
+ def startElement(self,name,attrs):
+ if name=='file':
+ self.buf=[]
+ def endElement(self,name):
+ if name=='file':
+ self.files.append(str(''.join(self.buf)))
+ def characters(self,cars):
+ self.buf.append(cars)
+def create_rcc_task(self,node):
+ rcnode=node.change_ext('_rc.cpp')
+ rcctask=self.create_task('rcc',node,rcnode)
+ cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o'))
+ try:
+ self.compiled_tasks.append(cpptask)
+ except AttributeError:
+ self.compiled_tasks=[cpptask]
+ return cpptask
+def create_uic_task(self,node):
+ uictask=self.create_task('ui4',node)
+ uictask.outputs=[self.path.find_or_declare(self.env['ui_PATTERN']%node.name[:-3])]
+def add_lang(self,node):
+ self.lang=self.to_list(getattr(self,'lang',[]))+[node]
+def apply_qt4(self):
+ if getattr(self,'lang',None):
+ qmtasks=[]
+ for x in self.to_list(self.lang):
+ if isinstance(x,str):
+ x=self.path.find_resource(x+'.ts')
+ qmtasks.append(self.create_task('ts2qm',x,x.change_ext('.qm')))
+ if getattr(self,'update',None)and Options.options.trans_qt4:
+ cxxnodes=[a.inputs[0]for a in self.compiled_tasks]+[a.inputs[0]for a in self.tasks if getattr(a,'inputs',None)and a.inputs[0].name.endswith('.ui')]
+ for x in qmtasks:
+ self.create_task('trans_update',cxxnodes,x.inputs)
+ if getattr(self,'langname',None):
+ qmnodes=[x.outputs[0]for x in qmtasks]
+ rcnode=self.langname
+ if isinstance(rcnode,str):
+ rcnode=self.path.find_or_declare(rcnode+'.qrc')
+ t=self.create_task('qm2rcc',qmnodes,rcnode)
+ k=create_rcc_task(self,t.outputs[0])
+ self.link_task.inputs.append(k.outputs[0])
+ lst=[]
+ for flag in self.to_list(self.env['CXXFLAGS']):
+ if len(flag)<2:continue
+ f=flag[0:2]
+ if f in['-D','-I','/D','/I']:
+ if(f[0]=='/'):
+ lst.append('-'+flag[1:])
+ else:
+ lst.append(flag)
+ self.env['MOC_FLAGS']=lst
+def cxx_hook(self,node):
+ return self.create_compiled_task('qxx',node)
+class rcc(Task.Task):
+ color='BLUE'
+ run_str='${QT_RCC} -name ${SRC[0].name} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
+ ext_out=['.h']
+ def scan(self):
+ node=self.inputs[0]
+ if not has_xml:
+ Logs.error('no xml support was found, the rcc dependencies will be incomplete!')
+ return([],[])
+ parser=make_parser()
+ curHandler=XMLHandler()
+ parser.setContentHandler(curHandler)
+ fi=open(self.inputs[0].abspath())
+ parser.parse(fi)
+ fi.close()
+ nodes=[]
+ names=[]
+ root=self.inputs[0].parent
+ for x in curHandler.files:
+ nd=root.find_resource(x)
+ if nd:nodes.append(nd)
+ else:names.append(x)
+ return(nodes,names)
+class moc(Task.Task):
+ color='BLUE'
+ run_str='${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
+class ui4(Task.Task):
+ color='BLUE'
+ run_str='${QT_UIC} ${SRC} -o ${TGT}'
+ ext_out=['.h']
+class ts2qm(Task.Task):
+ color='BLUE'
+ run_str='${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
+class qm2rcc(Task.Task):
+ color='BLUE'
+ after='ts2qm'
+ def run(self):
+ txt='\n'.join(['<file>%s</file>'%k.path_from(self.outputs[0].parent)for k in self.inputs])
+ code='<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>'%txt
+ self.outputs[0].write(code)
+def configure(self):
+ self.find_qt4_binaries()
+ self.set_qt4_libs_to_check()
+ self.find_qt4_libraries()
+ self.add_qt4_rpath()
+ self.simplify_qt4_libs()
+def find_qt4_binaries(self):
+ env=self.env
+ opt=Options.options
+ qtdir=getattr(opt,'qtdir','')
+ qtbin=getattr(opt,'qtbin','')
+ paths=[]
+ if qtdir:
+ qtbin=os.path.join(qtdir,'bin')
+ if not qtdir:
+ qtdir=self.environ.get('QT4_ROOT','')
+ qtbin=os.path.join(qtdir,'bin')
+ if qtbin:
+ paths=[qtbin]
+ if not qtdir:
+ paths=os.environ.get('PATH','').split(os.pathsep)
+ paths.append('/usr/share/qt4/bin/')
+ try:
+ lst=Utils.listdir('/usr/local/Trolltech/')
+ except OSError:
+ pass
+ else:
+ if lst:
+ lst.sort()
+ lst.reverse()
+ qtdir='/usr/local/Trolltech/%s/'%lst[0]
+ qtbin=os.path.join(qtdir,'bin')
+ paths.append(qtbin)
+ cand=None
+ prev_ver=['4','0','0']
+ for qmk in['qmake-qt4','qmake4','qmake']:
+ try:
+ qmake=self.find_program(qmk,path_list=paths)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ try:
+ version=self.cmd_and_log([qmake,'-query','QT_VERSION']).strip()
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ if version:
+ new_ver=version.split('.')
+ if new_ver>prev_ver:
+ cand=qmake
+ prev_ver=new_ver
+ if cand:
+ self.env.QMAKE=cand
+ else:
+ self.fatal('Could not find qmake for qt4')
+ qtbin=self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_BINS']).strip()+os.sep
+ def find_bin(lst,var):
+ for f in lst:
+ try:
+ ret=self.find_program(f,path_list=paths)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ env[var]=ret
+ break
+ find_bin(['uic-qt3','uic3'],'QT_UIC3')
+ find_bin(['uic-qt4','uic'],'QT_UIC')
+ if not env['QT_UIC']:
+ self.fatal('cannot find the uic compiler for qt4')
+ try:
+ uicver=self.cmd_and_log(env['QT_UIC']+" -version 2>&1").strip()
+ except self.errors.ConfigurationError:
+ self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
+ uicver=uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt','')
+ self.msg('Checking for uic version','%s'%uicver)
+ if uicver.find(' 3.')!=-1:
+ self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
+ find_bin(['moc-qt4','moc'],'QT_MOC')
+ find_bin(['rcc'],'QT_RCC')
+ find_bin(['lrelease-qt4','lrelease'],'QT_LRELEASE')
+ find_bin(['lupdate-qt4','lupdate'],'QT_LUPDATE')
+ env['UIC3_ST']='%s -o %s'
+ env['UIC_ST']='%s -o %s'
+ env['MOC_ST']='-o'
+ env['ui_PATTERN']='ui_%s.h'
+ env['QT_LRELEASE_FLAGS']=['-silent']
+ env.MOCCPPPATH_ST='-I%s'
+ env.MOCDEFINES_ST='-D%s'
+def find_qt4_libraries(self):
+ qtlibs=getattr(Options.options,'qtlibs','')
+ if not qtlibs:
+ try:
+ qtlibs=self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_LIBS']).strip()
+ except Errors.WafError:
+ qtdir=self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_PREFIX']).strip()+os.sep
+ qtlibs=os.path.join(qtdir,'lib')
+ self.msg('Found the Qt4 libraries in',qtlibs)
+ qtincludes=self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_HEADERS']).strip()
+ env=self.env
+ if not'PKG_CONFIG_PATH'in os.environ:
+ os.environ['PKG_CONFIG_PATH']='%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib'%(qtlibs,qtlibs)
+ try:
+ self.check_cfg(atleast_pkgconfig_version='0.1')
+ except self.errors.ConfigurationError:
+ for i in self.qt4_vars:
+ uselib=i.upper()
+ if Utils.unversioned_sys_platform()=="darwin":
+ frameworkName=i+".framework"
+ qtDynamicLib=os.path.join(qtlibs,frameworkName,i)
+ if os.path.exists(qtDynamicLib):
+ env.append_unique('FRAMEWORK_'+uselib,i)
+ self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtlibs,frameworkName,'Headers'))
+ elif sys.platform!="win32":
+ qtDynamicLib=os.path.join(qtlibs,"lib"+i+".so")
+ qtStaticLib=os.path.join(qtlibs,"lib"+i+".a")
+ if os.path.exists(qtDynamicLib):
+ env.append_unique('LIB_'+uselib,i)
+ self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
+ elif os.path.exists(qtStaticLib):
+ env.append_unique('LIB_'+uselib,i)
+ self.msg('Checking for %s'%i,qtStaticLib,'GREEN')
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('LIBPATH_'+uselib,qtlibs)
+ env.append_unique('INCLUDES_'+uselib,qtincludes)
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+ else:
+ for k in("lib%s.a","lib%s4.a","%s.lib","%s4.lib"):
+ lib=os.path.join(qtlibs,k%i)
+ if os.path.exists(lib):
+ env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
+ self.msg('Checking for %s'%i,lib,'GREEN')
+ break
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('LIBPATH_'+uselib,qtlibs)
+ env.append_unique('INCLUDES_'+uselib,qtincludes)
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+ uselib=i.upper()+"_debug"
+ for k in("lib%sd.a","lib%sd4.a","%sd.lib","%sd4.lib"):
+ lib=os.path.join(qtlibs,k%i)
+ if os.path.exists(lib):
+ env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
+ self.msg('Checking for %s'%i,lib,'GREEN')
+ break
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('LIBPATH_'+uselib,qtlibs)
+ env.append_unique('INCLUDES_'+uselib,qtincludes)
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+ else:
+ for i in self.qt4_vars_debug+self.qt4_vars:
+ self.check_cfg(package=i,args='--cflags --libs',mandatory=False)
+def simplify_qt4_libs(self):
+ env=self.env
+ def process_lib(vars_,coreval):
+ for d in vars_:
+ var=d.upper()
+ if var=='QTCORE':
+ continue
+ value=env['LIBPATH_'+var]
+ if value:
+ core=env[coreval]
+ accu=[]
+ for lib in value:
+ if lib in core:
+ continue
+ accu.append(lib)
+ env['LIBPATH_'+var]=accu
+ process_lib(self.qt4_vars,'LIBPATH_QTCORE')
+ process_lib(self.qt4_vars_debug,'LIBPATH_QTCORE_DEBUG')
+def add_qt4_rpath(self):
+ env=self.env
+ if Options.options.want_rpath:
+ def process_rpath(vars_,coreval):
+ for d in vars_:
+ var=d.upper()
+ value=env['LIBPATH_'+var]
+ if value:
+ core=env[coreval]
+ accu=[]
+ for lib in value:
+ if var!='QTCORE':
+ if lib in core:
+ continue
+ accu.append('-Wl,--rpath='+lib)
+ env['RPATH_'+var]=accu
+ process_rpath(self.qt4_vars,'LIBPATH_QTCORE')
+ process_rpath(self.qt4_vars_debug,'LIBPATH_QTCORE_DEBUG')
+def set_qt4_libs_to_check(self):
+ if not hasattr(self,'qt4_vars'):
+ self.qt4_vars=QT4_LIBS
+ self.qt4_vars=Utils.to_list(self.qt4_vars)
+ if not hasattr(self,'qt4_vars_debug'):
+ self.qt4_vars_debug=[a+'_debug'for a in self.qt4_vars]
+ self.qt4_vars_debug=Utils.to_list(self.qt4_vars_debug)
+def options(opt):
+ opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries')
+ opt.add_option('--header-ext',type='string',default='',help='header extension for moc files',dest='qt_header_ext')
+ for i in'qtdir qtbin qtlibs'.split():
+ opt.add_option('--'+i,type='string',default='',dest=i)
+ opt.add_option('--translate',action="store_true",help="collect translation strings",dest="trans_qt4",default=False)
+
+extension(*EXT_RCC)(create_rcc_task)
+extension(*EXT_UI)(create_uic_task)
+extension('.ts')(add_lang)
+feature('qt4')(apply_qt4)
+after_method('apply_link')(apply_qt4)
+extension(*EXT_QT4)(cxx_hook)
+conf(find_qt4_binaries)
+conf(find_qt4_libraries)
+conf(simplify_qt4_libs)
+conf(add_qt4_rpath)
+conf(set_qt4_libs_to_check) \ No newline at end of file
diff --git a/waflib/Tools/ruby.py b/waflib/Tools/ruby.py
new file mode 100644
index 0000000..df21a31
--- /dev/null
+++ b/waflib/Tools/ruby.py
@@ -0,0 +1,104 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Task,Options,Utils
+from waflib.TaskGen import before_method,feature,after_method,Task,extension
+from waflib.Configure import conf
+def init_rubyext(self):
+ self.install_path='${ARCHDIR_RUBY}'
+ self.uselib=self.to_list(getattr(self,'uselib',''))
+ if not'RUBY'in self.uselib:
+ self.uselib.append('RUBY')
+ if not'RUBYEXT'in self.uselib:
+ self.uselib.append('RUBYEXT')
+def apply_ruby_so_name(self):
+ self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['rubyext_PATTERN']
+def check_ruby_version(self,minver=()):
+ if Options.options.rubybinary:
+ self.env.RUBY=Options.options.rubybinary
+ else:
+ self.find_program('ruby',var='RUBY')
+ ruby=self.env.RUBY
+ try:
+ version=self.cmd_and_log([ruby,'-e','puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip()
+ except:
+ self.fatal('could not determine ruby version')
+ self.env.RUBY_VERSION=version
+ try:
+ ver=tuple(map(int,version.split(".")))
+ except:
+ self.fatal('unsupported ruby version %r'%version)
+ cver=''
+ if minver:
+ if ver<minver:
+ self.fatal('ruby is too old %r'%ver)
+ cver='.'.join([str(x)for x in minver])
+ else:
+ cver=ver
+ self.msg('Checking for ruby version %s'%str(minver or''),cver)
+def check_ruby_ext_devel(self):
+ if not self.env.RUBY:
+ self.fatal('ruby detection is required first')
+ if not self.env.CC_NAME and not self.env.CXX_NAME:
+ self.fatal('load a c/c++ compiler first')
+ version=tuple(map(int,self.env.RUBY_VERSION.split(".")))
+ def read_out(cmd):
+ return Utils.to_list(self.cmd_and_log([self.env.RUBY,'-rrbconfig','-e',cmd]))
+ def read_config(key):
+ return read_out('puts Config::CONFIG[%r]'%key)
+ ruby=self.env['RUBY']
+ archdir=read_config('archdir')
+ cpppath=archdir
+ if version>=(1,9,0):
+ ruby_hdrdir=read_config('rubyhdrdir')
+ cpppath+=ruby_hdrdir
+ cpppath+=[os.path.join(ruby_hdrdir[0],read_config('arch')[0])]
+ self.check(header_name='ruby.h',includes=cpppath,errmsg='could not find ruby header file')
+ self.env.LIBPATH_RUBYEXT=read_config('libdir')
+ self.env.LIBPATH_RUBYEXT+=archdir
+ self.env.INCLUDES_RUBYEXT=cpppath
+ self.env.CFLAGS_RUBYEXT=read_config('CCDLFLAGS')
+ self.env.rubyext_PATTERN='%s.'+read_config('DLEXT')[0]
+ flags=read_config('LDSHARED')
+ while flags and flags[0][0]!='-':
+ flags=flags[1:]
+ if len(flags)>1 and flags[1]=="ppc":
+ flags=flags[2:]
+ self.env.LINKFLAGS_RUBYEXT=flags
+ self.env.LINKFLAGS_RUBYEXT+=read_config('LIBS')
+ self.env.LINKFLAGS_RUBYEXT+=read_config('LIBRUBYARG_SHARED')
+ if Options.options.rubyarchdir:
+ self.env.ARCHDIR_RUBY=Options.options.rubyarchdir
+ else:
+ self.env.ARCHDIR_RUBY=read_config('sitearchdir')[0]
+ if Options.options.rubylibdir:
+ self.env.LIBDIR_RUBY=Options.options.rubylibdir
+ else:
+ self.env.LIBDIR_RUBY=read_config('sitelibdir')[0]
+def check_ruby_module(self,module_name):
+ self.start_msg('Ruby module %s'%module_name)
+ try:
+ self.cmd_and_log([self.env['RUBY'],'-e','require \'%s\';puts 1'%module_name])
+ except:
+ self.end_msg(False)
+ self.fatal('Could not find the ruby module %r'%module_name)
+ self.end_msg(True)
+def process(self,node):
+ tsk=self.create_task('run_ruby',node)
+class run_ruby(Task.Task):
+ run_str='${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}'
+def options(opt):
+ opt.add_option('--with-ruby-archdir',type='string',dest='rubyarchdir',help='Specify directory where to install arch specific files')
+ opt.add_option('--with-ruby-libdir',type='string',dest='rubylibdir',help='Specify alternate ruby library path')
+ opt.add_option('--with-ruby-binary',type='string',dest='rubybinary',help='Specify alternate ruby binary')
+
+feature('rubyext')(init_rubyext)
+before_method('apply_incpaths','apply_lib_vars','apply_bundle','apply_link')(init_rubyext)
+feature('rubyext')(apply_ruby_so_name)
+before_method('apply_link','propagate_uselib')(apply_ruby_so_name)
+conf(check_ruby_version)
+conf(check_ruby_ext_devel)
+conf(check_ruby_module)
+extension('.rb')(process) \ No newline at end of file
diff --git a/waflib/Tools/suncc.py b/waflib/Tools/suncc.py
new file mode 100644
index 0000000..fcc61d1
--- /dev/null
+++ b/waflib/Tools/suncc.py
@@ -0,0 +1,54 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+def find_scc(conf):
+ v=conf.env
+ cc=None
+ if v['CC']:cc=v['CC']
+ elif'CC'in conf.environ:cc=conf.environ['CC']
+ if not cc:cc=conf.find_program('cc',var='CC')
+ if not cc:conf.fatal('Could not find a Sun C compiler')
+ cc=conf.cmd_to_list(cc)
+ try:
+ conf.cmd_and_log(cc+['-flags'])
+ except:
+ conf.fatal('%r is not a Sun compiler'%cc)
+ v['CC']=cc
+ v['CC_NAME']='sun'
+def scc_common_flags(conf):
+ v=conf.env
+ v['CC_SRC_F']=[]
+ v['CC_TGT_F']=['-c','-o']
+ if not v['LINK_CC']:v['LINK_CC']=v['CC']
+ v['CCLNK_SRC_F']=''
+ v['CCLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['SONAME_ST']='-Wl,-h,%s'
+ v['SHLIB_MARKER']='-Bdynamic'
+ v['STLIB_MARKER']='-Bstatic'
+ v['cprogram_PATTERN']='%s'
+ v['CFLAGS_cshlib']=['-Kpic','-DPIC']
+ v['LINKFLAGS_cshlib']=['-G']
+ v['cshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cstlib']=['-Bstatic']
+ v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+ conf.find_scc()
+ conf.find_ar()
+ conf.scc_common_flags()
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
+
+conf(find_scc)
+conf(scc_common_flags) \ No newline at end of file
diff --git a/waflib/Tools/suncxx.py b/waflib/Tools/suncxx.py
new file mode 100644
index 0000000..c604cd2
--- /dev/null
+++ b/waflib/Tools/suncxx.py
@@ -0,0 +1,55 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+def find_sxx(conf):
+ v=conf.env
+ cc=None
+ if v['CXX']:cc=v['CXX']
+ elif'CXX'in conf.environ:cc=conf.environ['CXX']
+ if not cc:cc=conf.find_program('CC',var='CXX')
+ if not cc:cc=conf.find_program('c++',var='CXX')
+ if not cc:conf.fatal('Could not find a Sun C++ compiler')
+ cc=conf.cmd_to_list(cc)
+ try:
+ conf.cmd_and_log(cc+['-flags'])
+ except:
+ conf.fatal('%r is not a Sun compiler'%cc)
+ v['CXX']=cc
+ v['CXX_NAME']='sun'
+def sxx_common_flags(conf):
+ v=conf.env
+ v['CXX_SRC_F']=[]
+ v['CXX_TGT_F']=['-c','-o']
+ if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+ v['CXXLNK_SRC_F']=[]
+ v['CXXLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['SONAME_ST']='-Wl,-h,%s'
+ v['SHLIB_MARKER']='-Bdynamic'
+ v['STLIB_MARKER']='-Bstatic'
+ v['cxxprogram_PATTERN']='%s'
+ v['CXXFLAGS_cxxshlib']=['-Kpic','-DPIC']
+ v['LINKFLAGS_cxxshlib']=['-G']
+ v['cxxshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cxxstlib']=['-Bstatic']
+ v['cxxstlib_PATTERN']='lib%s.a'
+def configure(conf):
+ conf.find_sxx()
+ conf.find_ar()
+ conf.sxx_common_flags()
+ conf.cxx_load_tools()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
+
+conf(find_sxx)
+conf(sxx_common_flags) \ No newline at end of file
diff --git a/waflib/Tools/tex.py b/waflib/Tools/tex.py
new file mode 100644
index 0000000..4a26c43
--- /dev/null
+++ b/waflib/Tools/tex.py
@@ -0,0 +1,242 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Utils,Task,Errors
+from waflib.TaskGen import feature,before_method
+from waflib.Logs import error,warn,debug
+re_bibunit=re.compile(r'\\(?P<type>putbib)\[(?P<file>[^\[\]]*)\]',re.M)
+def bibunitscan(self):
+ node=self.inputs[0]
+ nodes=[]
+ if not node:return nodes
+ code=Utils.readf(node.abspath())
+ for match in re_bibunit.finditer(code):
+ path=match.group('file')
+ if path:
+ for k in['','.bib']:
+ debug('tex: trying %s%s'%(path,k))
+ fi=node.parent.find_resource(path+k)
+ if fi:
+ nodes.append(fi)
+ else:
+ debug('tex: could not find %s'%path)
+ debug("tex: found the following bibunit files: %s"%nodes)
+ return nodes
+exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps']
+exts_tex=['.ltx','.tex']
+re_tex=re.compile(r'\\(?P<type>include|bibliography|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
+g_bibtex_re=re.compile('bibdata',re.M)
+class tex(Task.Task):
+ bibtex_fun,_=Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False)
+ bibtex_fun.__doc__="""
+ Execute the program **bibtex**
+ """
+ makeindex_fun,_=Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}',shell=False)
+ makeindex_fun.__doc__="""
+ Execute the program **makeindex**
+ """
+ def scan_aux(self,node):
+ nodes=[node]
+ re_aux=re.compile(r'\\@input{(?P<file>[^{}]*)}',re.M)
+ def parse_node(node):
+ code=node.read()
+ for match in re_aux.finditer(code):
+ path=match.group('file')
+ found=node.parent.find_or_declare(path)
+ if found and found not in nodes:
+ debug('tex: found aux node '+found.abspath())
+ nodes.append(found)
+ parse_node(found)
+ parse_node(node)
+ return nodes
+ def scan(self):
+ node=self.inputs[0]
+ nodes=[]
+ names=[]
+ seen=[]
+ if not node:return(nodes,names)
+ def parse_node(node):
+ if node in seen:
+ return
+ seen.append(node)
+ code=node.read()
+ global re_tex
+ for match in re_tex.finditer(code):
+ for path in match.group('file').split(','):
+ if path:
+ add_name=True
+ found=None
+ for k in exts_deps_tex:
+ debug('tex: trying %s%s'%(path,k))
+ found=node.parent.find_resource(path+k)
+ if found and not found in self.outputs:
+ nodes.append(found)
+ add_name=False
+ for ext in exts_tex:
+ if found.name.endswith(ext):
+ parse_node(found)
+ break
+ if add_name:
+ names.append(path)
+ parse_node(node)
+ for x in nodes:
+ x.parent.get_bld().mkdir()
+ debug("tex: found the following : %s and names %s"%(nodes,names))
+ return(nodes,names)
+ def check_status(self,msg,retcode):
+ if retcode!=0:
+ raise Errors.WafError("%r command exit status %r"%(msg,retcode))
+ def bibfile(self):
+ need_bibtex=False
+ try:
+ for aux_node in self.aux_nodes:
+ ct=aux_node.read()
+ if g_bibtex_re.findall(ct):
+ need_bibtex=True
+ break
+ except(OSError,IOError):
+ error('error bibtex scan')
+ else:
+ if need_bibtex:
+ warn('calling bibtex')
+ self.env.env={}
+ self.env.env.update(os.environ)
+ self.env.env.update({'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS})
+ self.env.SRCFILE=self.aux_nodes[0].name[:-4]
+ self.check_status('error when calling bibtex',self.bibtex_fun())
+ def bibunits(self):
+ try:
+ bibunits=bibunitscan(self)
+ except FSError:
+ error('error bibunitscan')
+ else:
+ if bibunits:
+ fn=['bu'+str(i)for i in xrange(1,len(bibunits)+1)]
+ if fn:
+ warn('calling bibtex on bibunits')
+ for f in fn:
+ self.env.env={'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS}
+ self.env.SRCFILE=f
+ self.check_status('error when calling bibtex',self.bibtex_fun())
+ def makeindex(self):
+ try:
+ idx_path=self.idx_node.abspath()
+ os.stat(idx_path)
+ except OSError:
+ warn('index file %s absent, not calling makeindex'%idx_path)
+ else:
+ warn('calling makeindex')
+ self.env.SRCFILE=self.idx_node.name
+ self.env.env={}
+ self.check_status('error when calling makeindex %s'%idx_path,self.makeindex_fun())
+ def run(self):
+ env=self.env
+ if not env['PROMPT_LATEX']:
+ env.append_value('LATEXFLAGS','-interaction=batchmode')
+ env.append_value('PDFLATEXFLAGS','-interaction=batchmode')
+ env.append_value('XELATEXFLAGS','-interaction=batchmode')
+ fun=self.texfun
+ node=self.inputs[0]
+ srcfile=node.abspath()
+ texinputs=self.env.TEXINPUTS or''
+ self.TEXINPUTS=node.parent.get_bld().abspath()+os.pathsep+node.parent.get_src().abspath()+os.pathsep+texinputs+os.pathsep
+ self.aux_node=node.change_ext('.aux')
+ self.cwd=self.inputs[0].parent.get_bld().abspath()
+ warn('first pass on %s'%self.__class__.__name__)
+ self.env.env={}
+ self.env.env.update(os.environ)
+ self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
+ self.env.SRCFILE=srcfile
+ self.check_status('error when calling latex',fun())
+ self.aux_nodes=self.scan_aux(node.change_ext('.aux'))
+ self.idx_node=node.change_ext('.idx')
+ self.bibfile()
+ self.bibunits()
+ self.makeindex()
+ hash=''
+ for i in range(10):
+ prev_hash=hash
+ try:
+ hashes=[Utils.h_file(x.abspath())for x in self.aux_nodes]
+ hash=Utils.h_list(hashes)
+ except(OSError,IOError):
+ error('could not read aux.h')
+ pass
+ if hash and hash==prev_hash:
+ break
+ warn('calling %s'%self.__class__.__name__)
+ self.env.env={}
+ self.env.env.update(os.environ)
+ self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
+ self.env.SRCFILE=srcfile
+ self.check_status('error when calling %s'%self.__class__.__name__,fun())
+class latex(tex):
+ texfun,vars=Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False)
+class pdflatex(tex):
+ texfun,vars=Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}',shell=False)
+class xelatex(tex):
+ texfun,vars=Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}',shell=False)
+class dvips(Task.Task):
+ run_str='${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}'
+ color='BLUE'
+ after=['latex','pdflatex','xelatex']
+class dvipdf(Task.Task):
+ run_str='${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}'
+ color='BLUE'
+ after=['latex','pdflatex','xelatex']
+class pdf2ps(Task.Task):
+ run_str='${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}'
+ color='BLUE'
+ after=['latex','pdflatex','xelatex']
+def apply_tex(self):
+ if not getattr(self,'type',None)in['latex','pdflatex','xelatex']:
+ self.type='pdflatex'
+ tree=self.bld
+ outs=Utils.to_list(getattr(self,'outs',[]))
+ self.env['PROMPT_LATEX']=getattr(self,'prompt',1)
+ deps_lst=[]
+ if getattr(self,'deps',None):
+ deps=self.to_list(self.deps)
+ for filename in deps:
+ n=self.path.find_resource(filename)
+ if not n in deps_lst:deps_lst.append(n)
+ for node in self.to_nodes(self.source):
+ if self.type=='latex':
+ task=self.create_task('latex',node,node.change_ext('.dvi'))
+ elif self.type=='pdflatex':
+ task=self.create_task('pdflatex',node,node.change_ext('.pdf'))
+ elif self.type=='xelatex':
+ task=self.create_task('xelatex',node,node.change_ext('.pdf'))
+ task.env=self.env
+ if deps_lst:
+ try:
+ lst=tree.node_deps[task.uid()]
+ for n in deps_lst:
+ if not n in lst:
+ lst.append(n)
+ except KeyError:
+ tree.node_deps[task.uid()]=deps_lst
+ if self.type=='latex':
+ if'ps'in outs:
+ tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps'))
+ tsk.env.env={'TEXINPUTS':node.parent.abspath()+os.pathsep+self.path.abspath()+os.pathsep+self.path.get_bld().abspath()}
+ if'pdf'in outs:
+ tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf'))
+ tsk.env.env={'TEXINPUTS':node.parent.abspath()+os.pathsep+self.path.abspath()+os.pathsep+self.path.get_bld().abspath()}
+ elif self.type=='pdflatex':
+ if'ps'in outs:
+ self.create_task('pdf2ps',task.outputs,node.change_ext('.ps'))
+ self.source=[]
+def configure(self):
+ v=self.env
+ for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split():
+ try:
+ self.find_program(p,var=p.upper())
+ except self.errors.ConfigurationError:
+ pass
+ v['DVIPSFLAGS']='-Ppdf'
+
+feature('tex')(apply_tex)
+before_method('process_source')(apply_tex) \ No newline at end of file
diff --git a/waflib/Tools/vala.py b/waflib/Tools/vala.py
new file mode 100644
index 0000000..ff422ef
--- /dev/null
+++ b/waflib/Tools/vala.py
@@ -0,0 +1,216 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os.path,shutil,re
+from waflib import Context,Task,Utils,Logs,Options,Errors
+from waflib.TaskGen import extension
+from waflib.Configure import conf
+class valac(Task.Task):
+ vars=["VALAC","VALAC_VERSION","VALAFLAGS"]
+ ext_out=['.h']
+ def run(self):
+ env=self.env
+ cmd=[env['VALAC'],'-C','--quiet']
+ cmd.extend(Utils.to_list(env['VALAFLAGS']))
+ if self.threading:
+ cmd.append('--thread')
+ if self.profile:
+ cmd.append('--profile=%s'%self.profile)
+ if self.target_glib:
+ cmd.append('--target-glib=%s'%self.target_glib)
+ if self.is_lib:
+ cmd.append('--library='+self.target)
+ for x in self.outputs:
+ if x.name.endswith('.h'):
+ cmd.append('--header='+x.name)
+ if self.gir:
+ cmd.append('--gir=%s.gir'%self.gir)
+ for vapi_dir in self.vapi_dirs:
+ cmd.append('--vapidir=%s'%vapi_dir)
+ for package in self.packages:
+ cmd.append('--pkg=%s'%package)
+ for package in self.packages_private:
+ cmd.append('--pkg=%s'%package)
+ for define in self.vala_defines:
+ cmd.append('--define=%s'%define)
+ cmd.extend([a.abspath()for a in self.inputs])
+ ret=self.exec_command(cmd,cwd=self.outputs[0].parent.abspath())
+ if ret:
+ return ret
+ for x in self.outputs:
+ if id(x.parent)!=id(self.outputs[0].parent):
+ shutil.move(self.outputs[0].parent.abspath()+os.sep+x.name,x.abspath())
+ if self.packages and getattr(self,'deps_node',None):
+ self.deps_node.write('\n'.join(self.packages))
+ return ret
+def vala_file(self,node):
+ valatask=getattr(self,"valatask",None)
+ if not valatask:
+ def _get_api_version():
+ api_version='1.0'
+ if hasattr(Context.g_module,'API_VERSION'):
+ version=Context.g_module.API_VERSION.split(".")
+ if version[0]=="0":
+ api_version="0."+version[1]
+ else:
+ api_version=version[0]+".0"
+ return api_version
+ valatask=self.create_task('valac')
+ self.valatask=valatask
+ self.includes=Utils.to_list(getattr(self,'includes',[]))
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ valatask.packages=[]
+ valatask.packages_private=Utils.to_list(getattr(self,'packages_private',[]))
+ valatask.vapi_dirs=[]
+ valatask.target=self.target
+ valatask.threading=False
+ valatask.install_path=getattr(self,'install_path','')
+ valatask.profile=getattr(self,'profile','gobject')
+ valatask.vala_defines=getattr(self,'vala_defines',[])
+ valatask.target_glib=None
+ valatask.gir=getattr(self,'gir',None)
+ valatask.gir_path=getattr(self,'gir_path','${DATAROOTDIR}/gir-1.0')
+ valatask.vapi_path=getattr(self,'vapi_path','${DATAROOTDIR}/vala/vapi')
+ valatask.pkg_name=getattr(self,'pkg_name',self.env['PACKAGE'])
+ valatask.header_path=getattr(self,'header_path','${INCLUDEDIR}/%s-%s'%(valatask.pkg_name,_get_api_version()))
+ valatask.install_binding=getattr(self,'install_binding',True)
+ valatask.is_lib=False
+ if not'cprogram'in self.features:
+ valatask.is_lib=True
+ packages=Utils.to_list(getattr(self,'packages',[]))
+ vapi_dirs=Utils.to_list(getattr(self,'vapi_dirs',[]))
+ includes=[]
+ if hasattr(self,'use'):
+ local_packages=Utils.to_list(self.use)[:]
+ seen=[]
+ while len(local_packages)>0:
+ package=local_packages.pop()
+ if package in seen:
+ continue
+ seen.append(package)
+ try:
+ package_obj=self.bld.get_tgen_by_name(package)
+ except Errors.WafError:
+ continue
+ package_name=package_obj.target
+ package_node=package_obj.path
+ package_dir=package_node.path_from(self.path)
+ for task in package_obj.tasks:
+ for output in task.outputs:
+ if output.name==package_name+".vapi":
+ valatask.set_run_after(task)
+ if package_name not in packages:
+ packages.append(package_name)
+ if package_dir not in vapi_dirs:
+ vapi_dirs.append(package_dir)
+ if package_dir not in includes:
+ includes.append(package_dir)
+ if hasattr(package_obj,'use'):
+ lst=self.to_list(package_obj.use)
+ lst.reverse()
+ local_packages=[pkg for pkg in lst if pkg not in seen]+local_packages
+ valatask.packages=packages
+ for vapi_dir in vapi_dirs:
+ try:
+ valatask.vapi_dirs.append(self.path.find_dir(vapi_dir).abspath())
+ valatask.vapi_dirs.append(self.path.find_dir(vapi_dir).get_bld().abspath())
+ except AttributeError:
+ Logs.warn("Unable to locate Vala API directory: '%s'"%vapi_dir)
+ self.includes.append(self.bld.srcnode.abspath())
+ self.includes.append(self.bld.bldnode.abspath())
+ for include in includes:
+ try:
+ self.includes.append(self.path.find_dir(include).abspath())
+ self.includes.append(self.path.find_dir(include).get_bld().abspath())
+ except AttributeError:
+ Logs.warn("Unable to locate include directory: '%s'"%include)
+ if valatask.profile=='gobject':
+ if hasattr(self,'target_glib'):
+ Logs.warn('target_glib on vala tasks is not supported --vala-target-glib=MAJOR.MINOR from the vala tool options')
+ if getattr(Options.options,'vala_target_glib',None):
+ valatask.target_glib=Options.options.vala_target_glib
+ if not'GOBJECT'in self.uselib:
+ self.uselib.append('GOBJECT')
+ if hasattr(self,'threading'):
+ if valatask.profile=='gobject':
+ valatask.threading=self.threading
+ if not'GTHREAD'in self.uselib:
+ self.uselib.append('GTHREAD')
+ else:
+ Logs.warn("Profile %s does not have threading support"%valatask.profile)
+ if valatask.is_lib:
+ valatask.outputs.append(self.path.find_or_declare('%s.h'%self.target))
+ valatask.outputs.append(self.path.find_or_declare('%s.vapi'%self.target))
+ if valatask.gir:
+ valatask.outputs.append(self.path.find_or_declare('%s.gir'%self.gir))
+ if valatask.packages:
+ d=self.path.find_or_declare('%s.deps'%self.target)
+ valatask.outputs.append(d)
+ valatask.deps_node=d
+ valatask.inputs.append(node)
+ c_node=node.change_ext('.c')
+ valatask.outputs.append(c_node)
+ self.source.append(c_node)
+ if valatask.is_lib and valatask.install_binding:
+ headers_list=[o for o in valatask.outputs if o.suffix()==".h"]
+ try:
+ self.install_vheader.source=headers_list
+ except AttributeError:
+ self.install_vheader=self.bld.install_files(valatask.header_path,headers_list,self.env)
+ vapi_list=[o for o in valatask.outputs if(o.suffix()in(".vapi",".deps"))]
+ try:
+ self.install_vapi.source=vapi_list
+ except AttributeError:
+ self.install_vapi=self.bld.install_files(valatask.vapi_path,vapi_list,self.env)
+ gir_list=[o for o in valatask.outputs if o.suffix()==".gir"]
+ try:
+ self.install_gir.source=gir_list
+ except AttributeError:
+ self.install_gir=self.bld.install_files(valatask.gir_path,gir_list,self.env)
+valac=Task.update_outputs(valac)
+def find_valac(self,valac_name,min_version):
+ valac=self.find_program(valac_name,var='VALAC')
+ try:
+ output=self.cmd_and_log(valac+' --version')
+ except Exception:
+ valac_version=None
+ else:
+ ver=re.search(r'\d+.\d+.\d+',output).group(0).split('.')
+ valac_version=tuple([int(x)for x in ver])
+ self.msg('Checking for %s version >= %r'%(valac_name,min_version),valac_version,valac_version and valac_version>=min_version)
+ if valac and valac_version<min_version:
+ self.fatal("%s version %r is too old, need >= %r"%(valac_name,valac_version,min_version))
+ self.env['VALAC_VERSION']=valac_version
+ return valac
+def check_vala(self,min_version=(0,8,0),branch=None):
+ if not branch:
+ branch=min_version[:2]
+ try:
+ find_valac(self,'valac-%d.%d'%(branch[0],branch[1]),min_version)
+ except self.errors.ConfigurationError:
+ find_valac(self,'valac',min_version)
+def check_vala_deps(self):
+ if not self.env['HAVE_GOBJECT']:
+ pkg_args={'package':'gobject-2.0','uselib_store':'GOBJECT','args':'--cflags --libs'}
+ if getattr(Options.options,'vala_target_glib',None):
+ pkg_args['atleast_version']=Options.options.vala_target_glib
+ self.check_cfg(**pkg_args)
+ if not self.env['HAVE_GTHREAD']:
+ pkg_args={'package':'gthread-2.0','uselib_store':'GTHREAD','args':'--cflags --libs'}
+ if getattr(Options.options,'vala_target_glib',None):
+ pkg_args['atleast_version']=Options.options.vala_target_glib
+ self.check_cfg(**pkg_args)
+def configure(self):
+ self.load('gnu_dirs')
+ self.check_vala_deps()
+ self.check_vala()
+def options(opt):
+ opt.load('gnu_dirs')
+ valaopts=opt.add_option_group('Vala Compiler Options')
+ valaopts.add_option('--vala-target-glib',default=None,dest='vala_target_glib',metavar='MAJOR.MINOR',help='Target version of glib for Vala GObject code generation')
+
+extension('.vala','.gs')(vala_file)
+conf(find_valac)
+conf(check_vala)
+conf(check_vala_deps) \ No newline at end of file
diff --git a/waflib/Tools/waf_unit_test.py b/waflib/Tools/waf_unit_test.py
new file mode 100644
index 0000000..850e713
--- /dev/null
+++ b/waflib/Tools/waf_unit_test.py
@@ -0,0 +1,79 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib.TaskGen import feature,after_method
+from waflib import Utils,Task,Logs,Options
+testlock=Utils.threading.Lock()
+def make_test(self):
+ if getattr(self,'link_task',None):
+ self.create_task('utest',self.link_task.outputs)
+class utest(Task.Task):
+ color='PINK'
+ after=['vnum','inst']
+ vars=[]
+ def runnable_status(self):
+ ret=super(utest,self).runnable_status()
+ if ret==Task.SKIP_ME:
+ if getattr(Options.options,'all_tests',False):
+ return Task.RUN_ME
+ return ret
+ def run(self):
+ filename=self.inputs[0].abspath()
+ self.ut_exec=getattr(self,'ut_exec',[filename])
+ if getattr(self.generator,'ut_fun',None):
+ self.generator.ut_fun(self)
+ try:
+ fu=getattr(self.generator.bld,'all_test_paths')
+ except AttributeError:
+ fu=os.environ.copy()
+ self.generator.bld.all_test_paths=fu
+ lst=[]
+ for g in self.generator.bld.groups:
+ for tg in g:
+ if getattr(tg,'link_task',None):
+ lst.append(tg.link_task.outputs[0].parent.abspath())
+ def add_path(dct,path,var):
+ dct[var]=os.pathsep.join(Utils.to_list(path)+[os.environ.get(var,'')])
+ if Utils.is_win32:
+ add_path(fu,lst,'PATH')
+ elif Utils.unversioned_sys_platform()=='darwin':
+ add_path(fu,lst,'DYLD_LIBRARY_PATH')
+ add_path(fu,lst,'LD_LIBRARY_PATH')
+ else:
+ add_path(fu,lst,'LD_LIBRARY_PATH')
+ cwd=getattr(self.generator,'ut_cwd','')or self.inputs[0].parent.abspath()
+ proc=Utils.subprocess.Popen(self.ut_exec,cwd=cwd,env=fu,stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE)
+ (stdout,stderr)=proc.communicate()
+ tup=(filename,proc.returncode,stdout,stderr)
+ self.generator.utest_result=tup
+ testlock.acquire()
+ try:
+ bld=self.generator.bld
+ Logs.debug("ut: %r",tup)
+ try:
+ bld.utest_results.append(tup)
+ except AttributeError:
+ bld.utest_results=[tup]
+ finally:
+ testlock.release()
+def summary(bld):
+ lst=getattr(bld,'utest_results',[])
+ if lst:
+ Logs.pprint('CYAN','execution summary')
+ total=len(lst)
+ tfail=len([x for x in lst if x[1]])
+ Logs.pprint('CYAN',' tests that pass %d/%d'%(total-tfail,total))
+ for(f,code,out,err)in lst:
+ if not code:
+ Logs.pprint('CYAN',' %s'%f)
+ Logs.pprint('CYAN',' tests that fail %d/%d'%(tfail,total))
+ for(f,code,out,err)in lst:
+ if code:
+ Logs.pprint('CYAN',' %s'%f)
+def options(opt):
+ opt.add_option('--alltests',action='store_true',default=False,help='Exec all unit tests',dest='all_tests')
+
+feature('test')(make_test)
+after_method('apply_link')(make_test) \ No newline at end of file
diff --git a/waflib/Tools/winres.py b/waflib/Tools/winres.py
new file mode 100644
index 0000000..93dd4f2
--- /dev/null
+++ b/waflib/Tools/winres.py
@@ -0,0 +1,34 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Task
+from waflib.TaskGen import extension
+def rc_file(self,node):
+ obj_ext='.rc.o'
+ if self.env['WINRC_TGT_F']=='/fo':
+ obj_ext='.res'
+ rctask=self.create_task('winrc',node,node.change_ext(obj_ext))
+ try:
+ self.compiled_tasks.append(rctask)
+ except AttributeError:
+ self.compiled_tasks=[rctask]
+class winrc(Task.Task):
+ run_str='${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}'
+ color='BLUE'
+def configure(conf):
+ v=conf.env
+ v['WINRC_TGT_F']='-o'
+ v['WINRC_SRC_F']='-i'
+ if not conf.env.WINRC:
+ if v.CC_NAME=='msvc':
+ conf.find_program('RC',var='WINRC',path_list=v['PATH'])
+ v['WINRC_TGT_F']='/fo'
+ v['WINRC_SRC_F']=''
+ else:
+ conf.find_program('windres',var='WINRC',path_list=v['PATH'])
+ if not conf.env.WINRC:
+ conf.fatal('winrc was not found!')
+ v['WINRCFLAGS']=[]
+
+extension('.rc')(rc_file) \ No newline at end of file
diff --git a/waflib/Tools/xlc.py b/waflib/Tools/xlc.py
new file mode 100644
index 0000000..c2a9982
--- /dev/null
+++ b/waflib/Tools/xlc.py
@@ -0,0 +1,46 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+def find_xlc(conf):
+ cc=conf.find_program(['xlc_r','xlc'],var='CC')
+ cc=conf.cmd_to_list(cc)
+ conf.get_xlc_version(cc)
+ conf.env.CC_NAME='xlc'
+ conf.env.CC=cc
+def xlc_common_flags(conf):
+ v=conf.env
+ v['CC_SRC_F']=[]
+ v['CC_TGT_F']=['-c','-o']
+ if not v['LINK_CC']:v['LINK_CC']=v['CC']
+ v['CCLNK_SRC_F']=[]
+ v['CCLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['RPATH_ST']='-Wl,-rpath,%s'
+ v['SONAME_ST']=[]
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['LINKFLAGS_cprogram']=['-Wl,-brtl']
+ v['cprogram_PATTERN']='%s'
+ v['CFLAGS_cshlib']=['-fPIC']
+ v['LINKFLAGS_cshlib']=['-G','-Wl,-brtl,-bexpfull']
+ v['cshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cstlib']=[]
+ v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+ conf.find_xlc()
+ conf.find_ar()
+ conf.xlc_common_flags()
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
+
+conf(find_xlc)
+conf(xlc_common_flags) \ No newline at end of file
diff --git a/waflib/Tools/xlcxx.py b/waflib/Tools/xlcxx.py
new file mode 100644
index 0000000..bfbe01e
--- /dev/null
+++ b/waflib/Tools/xlcxx.py
@@ -0,0 +1,46 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+def find_xlcxx(conf):
+ cxx=conf.find_program(['xlc++_r','xlc++'],var='CXX')
+ cxx=conf.cmd_to_list(cxx)
+ conf.get_xlc_version(cxx)
+ conf.env.CXX_NAME='xlc++'
+ conf.env.CXX=cxx
+def xlcxx_common_flags(conf):
+ v=conf.env
+ v['CXX_SRC_F']=[]
+ v['CXX_TGT_F']=['-c','-o']
+ if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+ v['CXXLNK_SRC_F']=[]
+ v['CXXLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['RPATH_ST']='-Wl,-rpath,%s'
+ v['SONAME_ST']=[]
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['LINKFLAGS_cxxprogram']=['-Wl,-brtl']
+ v['cxxprogram_PATTERN']='%s'
+ v['CXXFLAGS_cxxshlib']=['-fPIC']
+ v['LINKFLAGS_cxxshlib']=['-G','-Wl,-brtl,-bexpfull']
+ v['cxxshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cxxstlib']=[]
+ v['cxxstlib_PATTERN']='lib%s.a'
+def configure(conf):
+ conf.find_xlcxx()
+ conf.find_ar()
+ conf.xlcxx_common_flags()
+ conf.cxx_load_tools()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
+
+conf(find_xlcxx)
+conf(xlcxx_common_flags) \ No newline at end of file
diff --git a/waflib/Utils.py b/waflib/Utils.py
new file mode 100644
index 0000000..25fa3f0
--- /dev/null
+++ b/waflib/Utils.py
@@ -0,0 +1,336 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,errno,traceback,inspect,re,shutil,datetime,gc
+try:
+ import subprocess
+except:
+ try:
+ import waflib.extras.subprocess as subprocess
+ except:
+ print("The subprocess module is missing (python2.3?):\n try calling 'waf update --files=subprocess'\n or add a copy of subprocess.py to the python libraries")
+try:
+ from collections import deque
+except ImportError:
+ class deque(list):
+ def popleft(self):
+ return self.pop(0)
+try:
+ import _winreg as winreg
+except:
+ try:
+ import winreg
+ except:
+ winreg=None
+from waflib import Errors
+try:
+ from collections import UserDict
+except:
+ from UserDict import UserDict
+try:
+ from hashlib import md5
+except:
+ try:
+ from md5 import md5
+ except:
+ pass
+try:
+ import threading
+except:
+ class threading(object):
+ pass
+ class Lock(object):
+ def acquire(self):
+ pass
+ def release(self):
+ pass
+ threading.Lock=threading.Thread=Lock
+else:
+ run_old=threading.Thread.run
+ def run(*args,**kwargs):
+ try:
+ run_old(*args,**kwargs)
+ except(KeyboardInterrupt,SystemExit):
+ raise
+ except:
+ sys.excepthook(*sys.exc_info())
+ threading.Thread.run=run
+SIG_NIL='iluvcuteoverload'
+O644=420
+O755=493
+rot_chr=['\\','|','/','-']
+rot_idx=0
+try:
+ from collections import defaultdict
+except ImportError:
+ class defaultdict(dict):
+ def __init__(self,default_factory):
+ super(defaultdict,self).__init__()
+ self.default_factory=default_factory
+ def __getitem__(self,key):
+ try:
+ return super(defaultdict,self).__getitem__(key)
+ except KeyError:
+ value=self.default_factory()
+ self[key]=value
+ return value
+is_win32=sys.platform in('win32','cli')
+indicator='\x1b[K%s%s%s\r'
+if is_win32 and'NOCOLOR'in os.environ:
+ indicator='%s%s%s\r'
+def readf(fname,m='r'):
+ f=open(fname,m)
+ try:
+ txt=f.read()
+ finally:
+ f.close()
+ return txt
+def h_file(filename):
+ f=open(filename,'rb')
+ m=md5()
+ try:
+ while filename:
+ filename=f.read(100000)
+ m.update(filename)
+ finally:
+ f.close()
+ return m.digest()
+try:
+ x=''.encode('hex')
+except:
+ import binascii
+ def to_hex(s):
+ ret=binascii.hexlify(s)
+ if not isinstance(ret,str):
+ ret=ret.decode('utf-8')
+ return ret
+else:
+ def to_hex(s):
+ return s.encode('hex')
+to_hex.__doc__="""
+Return the hexadecimal representation of a string
+
+:param s: string to convert
+:type s: string
+"""
+listdir=os.listdir
+if is_win32:
+ def listdir_win32(s):
+ if not s:
+ try:
+ import ctypes
+ except:
+ return[x+':\\'for x in list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')]
+ else:
+ dlen=4
+ maxdrives=26
+ buf=ctypes.create_string_buffer(maxdrives*dlen)
+ ndrives=ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives,ctypes.byref(buf))
+ return[buf.raw[4*i:4*i+3].decode('ascii')for i in range(int(ndrives/dlen))]
+ if len(s)==2 and s[1]==":":
+ s+=os.sep
+ if not os.path.isdir(s):
+ e=OSError()
+ e.errno=errno.ENOENT
+ raise e
+ return os.listdir(s)
+ listdir=listdir_win32
+def num2ver(ver):
+ if isinstance(ver,str):
+ ver=tuple(ver.split('.'))
+ if isinstance(ver,tuple):
+ ret=0
+ for i in range(4):
+ if i<len(ver):
+ ret+=256**(3-i)*int(ver[i])
+ return ret
+ return ver
+def ex_stack():
+ exc_type,exc_value,tb=sys.exc_info()
+ exc_lines=traceback.format_exception(exc_type,exc_value,tb)
+ return''.join(exc_lines)
+def to_list(sth):
+ if isinstance(sth,str):
+ return sth.split()
+ else:
+ return sth
+re_nl=re.compile('\r*\n',re.M)
+def str_to_dict(txt):
+ tbl={}
+ lines=re_nl.split(txt)
+ for x in lines:
+ x=x.strip()
+ if not x or x.startswith('#')or x.find('=')<0:
+ continue
+ tmp=x.split('=')
+ tbl[tmp[0].strip()]='='.join(tmp[1:]).strip()
+ return tbl
+def split_path(path):
+ return path.split('/')
+def split_path_cygwin(path):
+ if path.startswith('//'):
+ ret=path.split('/')[2:]
+ ret[0]='/'+ret[0]
+ return ret
+ return path.split('/')
+re_sp=re.compile('[/\\\\]')
+def split_path_win32(path):
+ if path.startswith('\\\\'):
+ ret=re.split(re_sp,path)[2:]
+ ret[0]='\\'+ret[0]
+ return ret
+ return re.split(re_sp,path)
+if sys.platform=='cygwin':
+ split_path=split_path_cygwin
+elif is_win32:
+ split_path=split_path_win32
+split_path.__doc__="""
+Split a path by / or \\. This function is not like os.path.split
+
+:type path: string
+:param path: path to split
+:return: list of strings
+"""
+def check_dir(path):
+ if not os.path.isdir(path):
+ try:
+ os.makedirs(path)
+ except OSError ,e:
+ if not os.path.isdir(path):
+ raise Errors.WafError('Cannot create the folder %r'%path,ex=e)
+def def_attrs(cls,**kw):
+ for k,v in kw.items():
+ if not hasattr(cls,k):
+ setattr(cls,k,v)
+def quote_define_name(s):
+ fu=re.compile("[^a-zA-Z0-9]").sub("_",s)
+ fu=fu.upper()
+ return fu
+def h_list(lst):
+ m=md5()
+ m.update(str(lst))
+ return m.digest()
+def h_fun(fun):
+ try:
+ return fun.code
+ except AttributeError:
+ try:
+ h=inspect.getsource(fun)
+ except IOError:
+ h="nocode"
+ try:
+ fun.code=h
+ except AttributeError:
+ pass
+ return h
+reg_subst=re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}")
+def subst_vars(expr,params):
+ def repl_var(m):
+ if m.group(1):
+ return'\\'
+ if m.group(2):
+ return'$'
+ try:
+ return params.get_flat(m.group(3))
+ except AttributeError:
+ return params[m.group(3)]
+ return reg_subst.sub(repl_var,expr)
+def destos_to_binfmt(key):
+ if key=='darwin':
+ return'mac-o'
+ elif key in('win32','cygwin','uwin','msys'):
+ return'pe'
+ return'elf'
+def unversioned_sys_platform():
+ s=sys.platform
+ if s=='java':
+ from java.lang import System
+ s=System.getProperty('os.name')
+ if s=='Mac OS X':
+ return'darwin'
+ elif s.startswith('Windows '):
+ return'win32'
+ elif s=='OS/2':
+ return'os2'
+ elif s=='HP-UX':
+ return'hpux'
+ elif s in('SunOS','Solaris'):
+ return'sunos'
+ else:s=s.lower()
+ if s=='powerpc':
+ return'darwin'
+ if s=='win32'or s.endswith('os2')and s!='sunos2':return s
+ return re.split('\d+$',s)[0]
+def nada(*k,**kw):
+ pass
+class Timer(object):
+ def __init__(self):
+ self.start_time=datetime.datetime.utcnow()
+ def __str__(self):
+ delta=datetime.datetime.utcnow()-self.start_time
+ days=int(delta.days)
+ hours=delta.seconds//3600
+ minutes=(delta.seconds-hours*3600)//60
+ seconds=delta.seconds-hours*3600-minutes*60+float(delta.microseconds)/1000/1000
+ result=''
+ if days:
+ result+='%dd'%days
+ if days or hours:
+ result+='%dh'%hours
+ if days or hours or minutes:
+ result+='%dm'%minutes
+ return'%s%.3fs'%(result,seconds)
+if is_win32:
+ old=shutil.copy2
+ def copy2(src,dst):
+ old(src,dst)
+ shutil.copystat(src,dst)
+ setattr(shutil,'copy2',copy2)
+if os.name=='java':
+ try:
+ gc.disable()
+ gc.enable()
+ except NotImplementedError:
+ gc.disable=gc.enable
+def read_la_file(path):
+ sp=re.compile(r'^([^=]+)=\'(.*)\'$')
+ dc={}
+ for line in readf(path).splitlines():
+ try:
+ _,left,right,_=sp.split(line.strip())
+ dc[left]=right
+ except ValueError:
+ pass
+ return dc
+def nogc(fun):
+ def f(*k,**kw):
+ try:
+ gc.disable()
+ ret=fun(*k,**kw)
+ finally:
+ gc.enable()
+ return ret
+ f.__doc__=fun.__doc__
+ return f
+def run_once(fun):
+ cache={}
+ def wrap(k):
+ try:
+ return cache[k]
+ except KeyError:
+ ret=fun(k)
+ cache[k]=ret
+ return ret
+ wrap.__cache__=cache
+ return wrap
+def get_registry_app_path(key,filename):
+ if not winreg:
+ return None
+ try:
+ result=winreg.QueryValue(key,"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe"%filename[0])
+ except WindowsError:
+ pass
+ else:
+ if os.path.isfile(result):
+ return result
diff --git a/waflib/__init__.py b/waflib/__init__.py
new file mode 100644
index 0000000..efeed79
--- /dev/null
+++ b/waflib/__init__.py
@@ -0,0 +1,4 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
diff --git a/waflib/ansiterm.py b/waflib/ansiterm.py
new file mode 100644
index 0000000..485d033
--- /dev/null
+++ b/waflib/ansiterm.py
@@ -0,0 +1,177 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys,os
+try:
+ if not(sys.stderr.isatty()and sys.stdout.isatty()):
+ raise ValueError('not a tty')
+ from ctypes import*
+ class COORD(Structure):
+ _fields_=[("X",c_short),("Y",c_short)]
+ class SMALL_RECT(Structure):
+ _fields_=[("Left",c_short),("Top",c_short),("Right",c_short),("Bottom",c_short)]
+ class CONSOLE_SCREEN_BUFFER_INFO(Structure):
+ _fields_=[("Size",COORD),("CursorPosition",COORD),("Attributes",c_short),("Window",SMALL_RECT),("MaximumWindowSize",COORD)]
+ class CONSOLE_CURSOR_INFO(Structure):
+ _fields_=[('dwSize',c_ulong),('bVisible',c_int)]
+ sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+ csinfo=CONSOLE_CURSOR_INFO()
+ hconsole=windll.kernel32.GetStdHandle(-11)
+ windll.kernel32.GetConsoleScreenBufferInfo(hconsole,byref(sbinfo))
+ if sbinfo.Size.X<9 or sbinfo.Size.Y<9:raise ValueError('small console')
+ windll.kernel32.GetConsoleCursorInfo(hconsole,byref(csinfo))
+except Exception:
+ pass
+else:
+ import re,threading
+ is_vista=getattr(sys,"getwindowsversion",None)and sys.getwindowsversion()[0]>=6
+ try:
+ _type=unicode
+ except:
+ _type=str
+ to_int=lambda number,default:number and int(number)or default
+ wlock=threading.Lock()
+ STD_OUTPUT_HANDLE=-11
+ STD_ERROR_HANDLE=-12
+ class AnsiTerm(object):
+ def __init__(self):
+ self.encoding=sys.stdout.encoding
+ self.hconsole=windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
+ self.cursor_history=[]
+ self.orig_sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+ self.orig_csinfo=CONSOLE_CURSOR_INFO()
+ windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self.orig_sbinfo))
+ windll.kernel32.GetConsoleCursorInfo(hconsole,byref(self.orig_csinfo))
+ def screen_buffer_info(self):
+ sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+ windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(sbinfo))
+ return sbinfo
+ def clear_line(self,param):
+ mode=param and int(param)or 0
+ sbinfo=self.screen_buffer_info()
+ if mode==1:
+ line_start=COORD(0,sbinfo.CursorPosition.Y)
+ line_length=sbinfo.Size.X
+ elif mode==2:
+ line_start=COORD(sbinfo.CursorPosition.X,sbinfo.CursorPosition.Y)
+ line_length=sbinfo.Size.X-sbinfo.CursorPosition.X
+ else:
+ line_start=sbinfo.CursorPosition
+ line_length=sbinfo.Size.X-sbinfo.CursorPosition.X
+ chars_written=c_int()
+ windll.kernel32.FillConsoleOutputCharacterA(self.hconsole,c_wchar(' '),line_length,line_start,byref(chars_written))
+ windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,line_length,line_start,byref(chars_written))
+ def clear_screen(self,param):
+ mode=to_int(param,0)
+ sbinfo=self.screen_buffer_info()
+ if mode==1:
+ clear_start=COORD(0,0)
+ clear_length=sbinfo.CursorPosition.X*sbinfo.CursorPosition.Y
+ elif mode==2:
+ clear_start=COORD(0,0)
+ clear_length=sbinfo.Size.X*sbinfo.Size.Y
+ windll.kernel32.SetConsoleCursorPosition(self.hconsole,clear_start)
+ else:
+ clear_start=sbinfo.CursorPosition
+ clear_length=((sbinfo.Size.X-sbinfo.CursorPosition.X)+sbinfo.Size.X*(sbinfo.Size.Y-sbinfo.CursorPosition.Y))
+ chars_written=c_int()
+ windll.kernel32.FillConsoleOutputCharacterA(self.hconsole,c_wchar(' '),clear_length,clear_start,byref(chars_written))
+ windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,clear_length,clear_start,byref(chars_written))
+ def push_cursor(self,param):
+ sbinfo=self.screen_buffer_info()
+ self.cursor_history.append(sbinfo.CursorPosition)
+ def pop_cursor(self,param):
+ if self.cursor_history:
+ old_pos=self.cursor_history.pop()
+ windll.kernel32.SetConsoleCursorPosition(self.hconsole,old_pos)
+ def set_cursor(self,param):
+ y,sep,x=param.partition(';')
+ x=to_int(x,1)-1
+ y=to_int(y,1)-1
+ sbinfo=self.screen_buffer_info()
+ new_pos=COORD(min(max(0,x),sbinfo.Size.X),min(max(0,y),sbinfo.Size.Y))
+ windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
+ def set_column(self,param):
+ x=to_int(param,1)-1
+ sbinfo=self.screen_buffer_info()
+ new_pos=COORD(min(max(0,x),sbinfo.Size.X),sbinfo.CursorPosition.Y)
+ windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
+ def move_cursor(self,x_offset=0,y_offset=0):
+ sbinfo=self.screen_buffer_info()
+ new_pos=COORD(min(max(0,sbinfo.CursorPosition.X+x_offset),sbinfo.Size.X),min(max(0,sbinfo.CursorPosition.Y+y_offset),sbinfo.Size.Y))
+ windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
+ def move_up(self,param):
+ self.move_cursor(y_offset=-to_int(param,1))
+ def move_down(self,param):
+ self.move_cursor(y_offset=to_int(param,1))
+ def move_left(self,param):
+ self.move_cursor(x_offset=-to_int(param,1))
+ def move_right(self,param):
+ self.move_cursor(x_offset=to_int(param,1))
+ def next_line(self,param):
+ sbinfo=self.screen_buffer_info()
+ self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=to_int(param,1))
+ def prev_line(self,param):
+ sbinfo=self.screen_buffer_info()
+ self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=-to_int(param,1))
+ def rgb2bgr(self,c):
+ return((c&1)<<2)|(c&2)|((c&4)>>2)
+ def set_color(self,param):
+ cols=param.split(';')
+ sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+ windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(sbinfo))
+ attr=sbinfo.Attributes
+ for c in cols:
+ if is_vista:
+ c=int(c)
+ else:
+ c=to_int(c,0)
+ if c in range(30,38):
+ attr=(attr&0xfff0)|self.rgb2bgr(c-30)
+ elif c in range(40,48):
+ attr=(attr&0xff0f)|(self.rgb2bgr(c-40)<<4)
+ elif c==0:
+ attr=self.orig_sbinfo.Attributes
+ elif c==1:
+ attr|=0x08
+ elif c==4:
+ attr|=0x80
+ elif c==7:
+ attr=(attr&0xff88)|((attr&0x70)>>4)|((attr&0x07)<<4)
+ windll.kernel32.SetConsoleTextAttribute(self.hconsole,attr)
+ def show_cursor(self,param):
+ csinfo.bVisible=1
+ windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(csinfo))
+ def hide_cursor(self,param):
+ csinfo.bVisible=0
+ windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(csinfo))
+ ansi_command_table={'A':move_up,'B':move_down,'C':move_right,'D':move_left,'E':next_line,'F':prev_line,'G':set_column,'H':set_cursor,'f':set_cursor,'J':clear_screen,'K':clear_line,'h':show_cursor,'l':hide_cursor,'m':set_color,'s':push_cursor,'u':pop_cursor,}
+ ansi_tokens=re.compile('(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))')
+ def write(self,text):
+ try:
+ wlock.acquire()
+ for param,cmd,txt in self.ansi_tokens.findall(text):
+ if cmd:
+ cmd_func=self.ansi_command_table.get(cmd)
+ if cmd_func:
+ cmd_func(self,param)
+ else:
+ self.writeconsole(txt)
+ finally:
+ wlock.release()
+ def writeconsole(self,txt):
+ chars_written=c_int()
+ writeconsole=windll.kernel32.WriteConsoleA
+ if isinstance(txt,_type):
+ writeconsole=windll.kernel32.WriteConsoleW
+ TINY_STEP=3000
+ for x in range(0,len(txt),TINY_STEP):
+ tiny=txt[x:x+TINY_STEP]
+ writeconsole(self.hconsole,tiny,len(tiny),byref(chars_written),None)
+ def flush(self):
+ pass
+ def isatty(self):
+ return True
+ sys.stderr=sys.stdout=AnsiTerm()
+ os.environ['TERM']='vt100'
diff --git a/waflib/extras/__init__.py b/waflib/extras/__init__.py
new file mode 100644
index 0000000..efeed79
--- /dev/null
+++ b/waflib/extras/__init__.py
@@ -0,0 +1,4 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
diff --git a/waflib/extras/compat15.py b/waflib/extras/compat15.py
new file mode 100644
index 0000000..76851a2
--- /dev/null
+++ b/waflib/extras/compat15.py
@@ -0,0 +1,223 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+if sys.hexversion < 0x020400f0: from sets import Set as set
+import sys
+from waflib import ConfigSet,Logs,Options,Scripting,Task,Build,Configure,Node,Runner,TaskGen,Utils,Errors,Context
+sys.modules['Environment']=ConfigSet
+ConfigSet.Environment=ConfigSet.ConfigSet
+sys.modules['Logs']=Logs
+sys.modules['Options']=Options
+sys.modules['Scripting']=Scripting
+sys.modules['Task']=Task
+sys.modules['Build']=Build
+sys.modules['Configure']=Configure
+sys.modules['Node']=Node
+sys.modules['Runner']=Runner
+sys.modules['TaskGen']=TaskGen
+sys.modules['Utils']=Utils
+from waflib.Tools import c_preproc
+sys.modules['preproc']=c_preproc
+from waflib.Tools import c_config
+sys.modules['config_c']=c_config
+ConfigSet.ConfigSet.copy=ConfigSet.ConfigSet.derive
+ConfigSet.ConfigSet.set_variant=Utils.nada
+Build.BuildContext.add_subdirs=Build.BuildContext.recurse
+Build.BuildContext.new_task_gen=Build.BuildContext.__call__
+Build.BuildContext.is_install=0
+Node.Node.relpath_gen=Node.Node.path_from
+def name_to_obj(self,s,env=None):
+ Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"')
+ return self.get_tgen_by_name(s)
+Build.BuildContext.name_to_obj=name_to_obj
+def env_of_name(self,name):
+ try:
+ return self.all_envs[name]
+ except KeyError:
+ Logs.error('no such environment: '+name)
+ return None
+Build.BuildContext.env_of_name=env_of_name
+def set_env_name(self,name,env):
+ self.all_envs[name]=env
+ return env
+Configure.ConfigurationContext.set_env_name=set_env_name
+def retrieve(self,name,fromenv=None):
+ try:
+ env=self.all_envs[name]
+ except KeyError:
+ env=ConfigSet.ConfigSet()
+ self.prepare_env(env)
+ self.all_envs[name]=env
+ else:
+ if fromenv:Logs.warn("The environment %s may have been configured already"%name)
+ return env
+Configure.ConfigurationContext.retrieve=retrieve
+Configure.ConfigurationContext.sub_config=Configure.ConfigurationContext.recurse
+Configure.ConfigurationContext.check_tool=Configure.ConfigurationContext.load
+Configure.conftest=Configure.conf
+Configure.ConfigurationError=Errors.ConfigurationError
+Options.OptionsContext.sub_options=Options.OptionsContext.recurse
+Options.OptionsContext.tool_options=Context.Context.load
+Options.Handler=Options.OptionsContext
+Task.simple_task_type=Task.task_type_from_func=Task.task_factory
+Task.TaskBase.classes=Task.classes
+def setitem(self,key,value):
+ if key.startswith('CCFLAGS'):
+ key=key[1:]
+ self.table[key]=value
+ConfigSet.ConfigSet.__setitem__=setitem
+def old_importpaths(self):
+ if getattr(self,'importpaths',[]):
+ self.includes=self.importpaths
+from waflib import Context
+eld=Context.load_tool
+def load_tool(*k,**kw):
+ ret=eld(*k,**kw)
+ if'set_options'in ret.__dict__:
+ Logs.warn('compat: rename "set_options" to options')
+ ret.options=ret.set_options
+ if'detect'in ret.__dict__:
+ Logs.warn('compat: rename "detect" to "configure"')
+ ret.configure=ret.detect
+ return ret
+Context.load_tool=load_tool
+rev=Context.load_module
+def load_module(path):
+ ret=rev(path)
+ if'set_options'in ret.__dict__:
+ Logs.warn('compat: rename "set_options" to "options" (%r)'%path)
+ ret.options=ret.set_options
+ if'srcdir'in ret.__dict__:
+ Logs.warn('compat: rename "srcdir" to "top" (%r)'%path)
+ ret.top=ret.srcdir
+ if'blddir'in ret.__dict__:
+ Logs.warn('compat: rename "blddir" to "out" (%r)'%path)
+ ret.out=ret.blddir
+ return ret
+Context.load_module=load_module
+old_post=TaskGen.task_gen.post
+def post(self):
+ self.features=self.to_list(self.features)
+ if'cc'in self.features:
+ Logs.warn('compat: the feature cc does not exist anymore (use "c")')
+ self.features.remove('cc')
+ self.features.append('c')
+ if'cstaticlib'in self.features:
+ Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")')
+ self.features.remove('cstaticlib')
+ self.features.append(('cxx'in self.features)and'cxxstlib'or'cstlib')
+ if getattr(self,'ccflags',None):
+ Logs.warn('compat: "ccflags" was renamed to "cflags"')
+ self.cflags=self.ccflags
+ return old_post(self)
+TaskGen.task_gen.post=post
+def waf_version(*k,**kw):
+ Logs.warn('wrong version (waf_version was removed in waf 1.6)')
+Utils.waf_version=waf_version
+import os
+def apply_uselib_local(self):
+ env=self.env
+ from waflib.Tools.ccroot import stlink_task
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ self.includes=self.to_list(getattr(self,'includes',[]))
+ names=self.to_list(getattr(self,'uselib_local',[]))
+ get=self.bld.get_tgen_by_name
+ seen=set([])
+ tmp=Utils.deque(names)
+ if tmp:
+ Logs.warn('compat: "uselib_local" is deprecated, replace by "use"')
+ while tmp:
+ lib_name=tmp.popleft()
+ if lib_name in seen:
+ continue
+ y=get(lib_name)
+ y.post()
+ seen.add(lib_name)
+ if getattr(y,'uselib_local',None):
+ for x in self.to_list(getattr(y,'uselib_local',[])):
+ obj=get(x)
+ obj.post()
+ if getattr(obj,'link_task',None):
+ if not isinstance(obj.link_task,stlink_task):
+ tmp.append(x)
+ if getattr(y,'link_task',None):
+ link_name=y.target[y.target.rfind(os.sep)+1:]
+ if isinstance(y.link_task,stlink_task):
+ env.append_value('STLIB',[link_name])
+ else:
+ env.append_value('LIB',[link_name])
+ self.link_task.set_run_after(y.link_task)
+ self.link_task.dep_nodes+=y.link_task.outputs
+ tmp_path=y.link_task.outputs[0].parent.bldpath()
+ if not tmp_path in env['LIBPATH']:
+ env.prepend_value('LIBPATH',[tmp_path])
+ for v in self.to_list(getattr(y,'uselib',[])):
+ if not env['STLIB_'+v]:
+ if not v in self.uselib:
+ self.uselib.insert(0,v)
+ if getattr(y,'export_includes',None):
+ self.includes.extend(y.to_incnodes(y.export_includes))
+def apply_objdeps(self):
+ names=getattr(self,'add_objects',[])
+ if not names:
+ return
+ names=self.to_list(names)
+ get=self.bld.get_tgen_by_name
+ seen=[]
+ while names:
+ x=names[0]
+ if x in seen:
+ names=names[1:]
+ continue
+ y=get(x)
+ if getattr(y,'add_objects',None):
+ added=0
+ lst=y.to_list(y.add_objects)
+ lst.reverse()
+ for u in lst:
+ if u in seen:continue
+ added=1
+ names=[u]+names
+ if added:continue
+ y.post()
+ seen.append(x)
+ for t in getattr(y,'compiled_tasks',[]):
+ self.link_task.inputs.extend(t.outputs)
+def process_obj_files(self):
+ if not hasattr(self,'obj_files'):
+ return
+ for x in self.obj_files:
+ node=self.path.find_resource(x)
+ self.link_task.inputs.append(node)
+def add_obj_file(self,file):
+ if not hasattr(self,'obj_files'):self.obj_files=[]
+ if not'process_obj_files'in self.meths:self.meths.append('process_obj_files')
+ self.obj_files.append(file)
+old_define=Configure.ConfigurationContext.__dict__['define']
+def define(self,key,val,quote=True):
+ old_define(self,key,val,quote)
+ if key.startswith('HAVE_'):
+ self.env[key]=1
+old_undefine=Configure.ConfigurationContext.__dict__['undefine']
+def undefine(self,key):
+ old_undefine(self,key)
+ if key.startswith('HAVE_'):
+ self.env[key]=0
+def set_incdirs(self,val):
+ Logs.warn('compat: change "export_incdirs" by "export_includes"')
+ self.export_includes=val
+TaskGen.task_gen.export_incdirs=property(None,set_incdirs)
+
+TaskGen.feature('d')(old_importpaths)
+TaskGen.before('apply_incpaths')(old_importpaths)
+TaskGen.feature('c','cxx','d')(apply_uselib_local)
+TaskGen.before('apply_incpaths','propagate_uselib_vars')(apply_uselib_local)
+TaskGen.after('apply_link','process_source')(apply_uselib_local)
+TaskGen.feature('cprogram','cxxprogram','cstlib','cxxstlib','cshlib','cxxshlib','dprogram','dstlib','dshlib')(apply_objdeps)
+TaskGen.after('apply_link')(apply_objdeps)
+TaskGen.after('apply_link')(process_obj_files)
+TaskGen.taskgen_method(add_obj_file)
+Configure.conf(define)
+Configure.conf(undefine) \ No newline at end of file
diff --git a/waflib/fixpy2.py b/waflib/fixpy2.py
new file mode 100644
index 0000000..2e6962b
--- /dev/null
+++ b/waflib/fixpy2.py
@@ -0,0 +1,50 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+all_modifs={}
+def fixdir(dir):
+ global all_modifs
+ for k in all_modifs:
+ for v in all_modifs[k]:
+ modif(os.path.join(dir,'waflib'),k,v)
+def modif(dir,name,fun):
+ if name=='*':
+ lst=[]
+ for y in'. Tools extras'.split():
+ for x in os.listdir(os.path.join(dir,y)):
+ if x.endswith('.py'):
+ lst.append(y+os.sep+x)
+ for x in lst:
+ modif(dir,x,fun)
+ return
+ filename=os.path.join(dir,name)
+ f=open(filename,'r')
+ txt=f.read()
+ f.close()
+ txt=fun(txt)
+ f=open(filename,'w')
+ f.write(txt)
+ f.close()
+def subst(*k):
+ def do_subst(fun):
+ global all_modifs
+ for x in k:
+ try:
+ all_modifs[x].append(fun)
+ except KeyError:
+ all_modifs[x]=[fun]
+ return fun
+ return do_subst
+def r1(code):
+ code=code.replace(',e:',',e:')
+ code=code.replace("",'')
+ code=code.replace('','')
+ return code
+def r4(code):
+ code=code.replace('next(self.biter)','self.biter.next()')
+ return code
+
+subst('*')(r1)
+subst('Runner.py')(r4) \ No newline at end of file
diff --git a/wscript b/wscript
new file mode 100644
index 0000000..11e7d51
--- /dev/null
+++ b/wscript
@@ -0,0 +1,172 @@
+import commands
+import subprocess
+import os
+import Options
+import Scripting
+from waflib import Context
+
+out = 'build'
+top = '.'
+
+VERSION = '2012.12'
+APPNAME = 'glmark2'
+
+def options(opt):
+ opt.tool_options('gnu_dirs')
+ opt.tool_options('compiler_cc')
+ opt.tool_options('compiler_cxx')
+
+ opt.add_option('--enable-gl', action='store_true', dest = 'gl',
+ default = False, help='build using OpenGL 2.0')
+ opt.add_option('--enable-glesv2', action='store_true', dest = 'glesv2',
+ default = False, help='build using OpenGL ES 2.0')
+ opt.add_option('--enable-gl-drm', action='store_true', dest = 'gl_drm',
+ default = False, help='build using OpenGL 2.0 without X')
+ opt.add_option('--enable-glesv2-drm', action='store_true',
+ dest = 'glesv2_drm',
+ default = False, help='build using OpenGL ES 2.0 without X')
+ opt.add_option('--no-debug', action='store_false', dest = 'debug',
+ default = True, help='disable compiler debug information')
+ opt.add_option('--no-opt', action='store_false', dest = 'opt',
+ default = True, help='disable compiler optimizations')
+ opt.add_option('--data-path', action='store', dest = 'data_path',
+ help='path to main data (also see --data(root)dir)')
+ opt.add_option('--extras-path', action='store', dest = 'extras_path',
+ help='path to additional data (models, shaders, textures)')
+
+def configure(ctx):
+ if not Options.options.gl and not Options.options.glesv2 and \
+ not Options.options.gl_drm and not Options.options.glesv2_drm:
+ ctx.fatal("You must configure using at least one of --enable-gl, " +
+ "--enable-glesv2, --enable-gl-drm, --enable-glesv2-drm")
+
+ ctx.check_tool('gnu_dirs')
+ ctx.check_tool('compiler_cc')
+ ctx.check_tool('compiler_cxx')
+
+ # Check required headers
+ req_headers = ['stdlib.h', 'string.h', 'unistd.h', 'stdint.h', 'stdio.h', 'jpeglib.h']
+ for header in req_headers:
+ ctx.check_cxx(header_name = header, auto_add_header_name = True, mandatory = True)
+
+ # Check for required libs
+ req_libs = [('m', 'm'), ('jpeg', 'jpeg')]
+ for (lib, uselib) in req_libs:
+ ctx.check_cxx(lib = lib, uselib_store = uselib)
+
+ # Check required functions
+ req_funcs = [('memset', 'string.h', []) ,('sqrt', 'math.h', ['m'])]
+ for func, header, uselib in req_funcs:
+ ctx.check_cxx(function_name = func, header_name = header,
+ uselib = uselib, mandatory = True)
+
+ # Check required packages
+ req_pkgs = [('libpng12', 'libpng12')]
+ for (pkg, uselib) in req_pkgs:
+ ctx.check_cfg(package = pkg, uselib_store = uselib,
+ args = '--cflags --libs', mandatory = True)
+
+ # Check optional packages
+ opt_pkgs = [('x11', 'x11', Options.options.gl or Options.options.glesv2),
+ ('gl', 'gl', Options.options.gl or Options.options.gl_drm),
+ ('egl', 'egl', Options.options.glesv2 or
+ Options.options.glesv2_drm),
+ ('glesv2', 'glesv2', Options.options.glesv2 or
+ Options.options.glesv2_drm),
+ ('libdrm','drm', Options.options.gl_drm or
+ Options.options.glesv2_drm),
+ ('gbm','gbm', Options.options.gl_drm or
+ Options.options.glesv2_drm)]
+ for (pkg, uselib, mandatory) in opt_pkgs:
+ ctx.check_cfg(package = pkg, uselib_store = uselib,
+ args = '--cflags --libs', mandatory = mandatory)
+
+ ctx.env.append_unique('CXXFLAGS', '-Werror -Wall -Wextra -Wnon-virtual-dtor'.split(' '))
+
+ # Prepend -O# and -g flags so that they can be overriden by the
+ # CFLAGS environment variable
+ if Options.options.opt:
+ ctx.env.prepend_value('CXXFLAGS', '-O2')
+ if Options.options.debug:
+ ctx.env.prepend_value('CXXFLAGS', '-g')
+
+ ctx.env.HAVE_EXTRAS = False
+ if Options.options.extras_path is not None:
+ ctx.env.HAVE_EXTRAS = True
+ ctx.env.append_unique('GLMARK_EXTRAS_PATH', Options.options.extras_path)
+ ctx.env.append_unique('DEFINES', 'GLMARK_EXTRAS_PATH="%s"' % Options.options.extras_path)
+
+ if Options.options.data_path is not None:
+ data_path = Options.options.data_path
+ else:
+ data_path = os.path.join(ctx.env.DATADIR, 'glmark2')
+
+ ctx.env.append_unique('GLMARK_DATA_PATH', data_path)
+ ctx.env.append_unique('DEFINES', 'GLMARK_DATA_PATH="%s"' % data_path)
+ ctx.env.append_unique('DEFINES', 'GLMARK_VERSION="%s"' % VERSION)
+ ctx.env.GLMARK2_VERSION = VERSION
+
+ ctx.env.USE_GL = Options.options.gl
+ ctx.env.USE_GLESv2 = Options.options.glesv2
+ ctx.env.USE_GL_DRM = Options.options.gl_drm
+ ctx.env.USE_GLESv2_DRM = Options.options.glesv2_drm
+
+ ctx.msg("Prefix", ctx.env.PREFIX, color = 'PINK')
+ ctx.msg("Data path", data_path, color = 'PINK')
+ ctx.msg("Including extras", "Yes" if ctx.env.HAVE_EXTRAS else "No",
+ color = 'PINK');
+ if ctx.env.HAVE_EXTRAS:
+ ctx.msg("Extras path", Options.options.extras_path, color = 'PINK')
+ ctx.msg("Building X11 GL2 version", "Yes" if ctx.env.USE_GL else "No",
+ color = 'PINK')
+ ctx.msg("Building X11 GLESv2 version", "Yes" if ctx.env.USE_GLESv2 else "No",
+ color = 'PINK')
+ ctx.msg("Building DRM GL2 version", "Yes" if ctx.env.USE_GL_DRM else "No",
+ color = 'PINK')
+ ctx.msg("Building DRM GLESv2 version", "Yes" if ctx.env.USE_GLESv2_DRM else "No",
+ color = 'PINK')
+
+def build(ctx):
+ ctx.recurse('src')
+ ctx.recurse('data')
+ ctx.recurse('doc')
+
+class Glmark2Dist(Context.Context):
+ """ Custom dist command that preserves symbolic links"""
+
+ cmd = "dist"
+
+ def execute(self):
+ self.recurse([os.path.dirname(Context.g_module.root_path)])
+ self.archive()
+
+ def get_files(self):
+ import fnmatch
+ files = []
+ excludes = ['*.bzr', '*~', './.*waf*', './build*', '*.swp', '*.pyc', '*glmark2-*.tar.gz']
+ for (dirpath, dirnames, filenames) in os.walk(top):
+ names_to_remove = []
+ names = dirnames + filenames
+ for n in names:
+ for exclude in excludes:
+ if fnmatch.fnmatch(os.path.join(dirpath, n), exclude):
+ names_to_remove.append(n)
+ break
+
+ for d in names_to_remove:
+ if d in dirnames:
+ dirnames.remove(d)
+ if d in filenames:
+ filenames.remove(d)
+
+ files.extend([os.path.join(dirpath, d) for d in dirnames])
+ files.extend([os.path.join(dirpath, f) for f in filenames])
+
+ return files
+
+ def archive(self):
+ import tarfile
+ tar = tarfile.open(APPNAME + '-' + VERSION + '.tar.gz', 'w:gz')
+ for f in self.get_files():
+ tar.add(f, arcname = APPNAME + '-' + VERSION + '/' + f, recursive = False)
+ tar.close()